Home | History | Annotate | Download | only in acm2
      1 /*
      2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.h"
     12 
     13 #include <assert.h>
     14 #include <stdio.h>
     15 #include <string.h>
     16 
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 #include "webrtc/base/checks.h"
     19 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
     20 #include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
     21 #include "webrtc/modules/audio_coding/neteq/tools/packet.h"
     22 
     23 namespace webrtc {
     24 namespace test {
     25 
     26 AcmSendTestOldApi::AcmSendTestOldApi(InputAudioFile* audio_source,
     27                                      int source_rate_hz,
     28                                      int test_duration_ms)
     29     : clock_(0),
     30       acm_(webrtc::AudioCodingModule::Create(0, &clock_)),
     31       audio_source_(audio_source),
     32       source_rate_hz_(source_rate_hz),
     33       input_block_size_samples_(source_rate_hz_ * kBlockSizeMs / 1000),
     34       codec_registered_(false),
     35       test_duration_ms_(test_duration_ms),
     36       frame_type_(kAudioFrameSpeech),
     37       payload_type_(0),
     38       timestamp_(0),
     39       sequence_number_(0) {
     40   input_frame_.sample_rate_hz_ = source_rate_hz_;
     41   input_frame_.num_channels_ = 1;
     42   input_frame_.samples_per_channel_ = input_block_size_samples_;
     43   assert(input_block_size_samples_ * input_frame_.num_channels_ <=
     44          AudioFrame::kMaxDataSizeSamples);
     45   acm_->RegisterTransportCallback(this);
     46 }
     47 
     48 bool AcmSendTestOldApi::RegisterCodec(const char* payload_name,
     49                                       int sampling_freq_hz,
     50                                       int channels,
     51                                       int payload_type,
     52                                       int frame_size_samples) {
     53   CHECK_EQ(0,
     54            AudioCodingModule::Codec(
     55                payload_name, &codec_, sampling_freq_hz, channels));
     56   codec_.pltype = payload_type;
     57   codec_.pacsize = frame_size_samples;
     58   codec_registered_ = (acm_->RegisterSendCodec(codec_) == 0);
     59   input_frame_.num_channels_ = channels;
     60   assert(input_block_size_samples_ * input_frame_.num_channels_ <=
     61          AudioFrame::kMaxDataSizeSamples);
     62   return codec_registered_;
     63 }
     64 
     65 Packet* AcmSendTestOldApi::NextPacket() {
     66   assert(codec_registered_);
     67   if (filter_.test(payload_type_)) {
     68     // This payload type should be filtered out. Since the payload type is the
     69     // same throughout the whole test run, no packet at all will be delivered.
     70     // We can just as well signal that the test is over by returning NULL.
     71     return NULL;
     72   }
     73   // Insert audio and process until one packet is produced.
     74   while (clock_.TimeInMilliseconds() < test_duration_ms_) {
     75     clock_.AdvanceTimeMilliseconds(kBlockSizeMs);
     76     CHECK(audio_source_->Read(input_block_size_samples_, input_frame_.data_));
     77     if (input_frame_.num_channels_ > 1) {
     78       InputAudioFile::DuplicateInterleaved(input_frame_.data_,
     79                                            input_block_size_samples_,
     80                                            input_frame_.num_channels_,
     81                                            input_frame_.data_);
     82     }
     83     CHECK_EQ(0, acm_->Add10MsData(input_frame_));
     84     input_frame_.timestamp_ += input_block_size_samples_;
     85     int32_t encoded_bytes = acm_->Process();
     86     if (encoded_bytes > 0) {
     87       // Encoded packet received.
     88       return CreatePacket();
     89     }
     90   }
     91   // Test ended.
     92   return NULL;
     93 }
     94 
     95 // This method receives the callback from ACM when a new packet is produced.
     96 int32_t AcmSendTestOldApi::SendData(
     97     FrameType frame_type,
     98     uint8_t payload_type,
     99     uint32_t timestamp,
    100     const uint8_t* payload_data,
    101     uint16_t payload_len_bytes,
    102     const RTPFragmentationHeader* fragmentation) {
    103   // Store the packet locally.
    104   frame_type_ = frame_type;
    105   payload_type_ = payload_type;
    106   timestamp_ = timestamp;
    107   last_payload_vec_.assign(payload_data, payload_data + payload_len_bytes);
    108   assert(last_payload_vec_.size() == payload_len_bytes);
    109   return 0;
    110 }
    111 
    112 Packet* AcmSendTestOldApi::CreatePacket() {
    113   const size_t kRtpHeaderSize = 12;
    114   size_t allocated_bytes = last_payload_vec_.size() + kRtpHeaderSize;
    115   uint8_t* packet_memory = new uint8_t[allocated_bytes];
    116   // Populate the header bytes.
    117   packet_memory[0] = 0x80;
    118   packet_memory[1] = payload_type_;
    119   packet_memory[2] = (sequence_number_ >> 8) & 0xFF;
    120   packet_memory[3] = (sequence_number_) & 0xFF;
    121   packet_memory[4] = (timestamp_ >> 24) & 0xFF;
    122   packet_memory[5] = (timestamp_ >> 16) & 0xFF;
    123   packet_memory[6] = (timestamp_ >> 8) & 0xFF;
    124   packet_memory[7] = timestamp_ & 0xFF;
    125   // Set SSRC to 0x12345678.
    126   packet_memory[8] = 0x12;
    127   packet_memory[9] = 0x34;
    128   packet_memory[10] = 0x56;
    129   packet_memory[11] = 0x78;
    130 
    131   ++sequence_number_;
    132 
    133   // Copy the payload data.
    134   memcpy(packet_memory + kRtpHeaderSize,
    135          &last_payload_vec_[0],
    136          last_payload_vec_.size());
    137   Packet* packet =
    138       new Packet(packet_memory, allocated_bytes, clock_.TimeInMilliseconds());
    139   assert(packet);
    140   assert(packet->valid_header());
    141   return packet;
    142 }
    143 
    144 }  // namespace test
    145 }  // namespace webrtc
    146