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.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 AcmSendTest::AcmSendTest(InputAudioFile* audio_source,
     27                          int source_rate_hz,
     28                          int test_duration_ms)
     29     : clock_(0),
     30       audio_source_(audio_source),
     31       source_rate_hz_(source_rate_hz),
     32       input_block_size_samples_(source_rate_hz_ * kBlockSizeMs / 1000),
     33       codec_registered_(false),
     34       test_duration_ms_(test_duration_ms),
     35       frame_type_(kAudioFrameSpeech),
     36       payload_type_(0),
     37       timestamp_(0),
     38       sequence_number_(0) {
     39   webrtc::AudioCoding::Config config;
     40   config.clock = &clock_;
     41   config.transport = this;
     42   acm_.reset(webrtc::AudioCoding::Create(config));
     43   input_frame_.sample_rate_hz_ = source_rate_hz_;
     44   input_frame_.num_channels_ = 1;
     45   input_frame_.samples_per_channel_ = input_block_size_samples_;
     46   assert(input_block_size_samples_ * input_frame_.num_channels_ <=
     47          AudioFrame::kMaxDataSizeSamples);
     48 }
     49 
     50 bool AcmSendTest::RegisterCodec(int codec_type,
     51                                 int channels,
     52                                 int payload_type,
     53                                 int frame_size_samples) {
     54   codec_registered_ =
     55       acm_->RegisterSendCodec(codec_type, payload_type, frame_size_samples);
     56   input_frame_.num_channels_ = channels;
     57   assert(input_block_size_samples_ * input_frame_.num_channels_ <=
     58          AudioFrame::kMaxDataSizeSamples);
     59   return codec_registered_;
     60 }
     61 
     62 Packet* AcmSendTest::NextPacket() {
     63   assert(codec_registered_);
     64   if (filter_.test(payload_type_)) {
     65     // This payload type should be filtered out. Since the payload type is the
     66     // same throughout the whole test run, no packet at all will be delivered.
     67     // We can just as well signal that the test is over by returning NULL.
     68     return NULL;
     69   }
     70   // Insert audio and process until one packet is produced.
     71   while (clock_.TimeInMilliseconds() < test_duration_ms_) {
     72     clock_.AdvanceTimeMilliseconds(kBlockSizeMs);
     73     CHECK(audio_source_->Read(input_block_size_samples_, input_frame_.data_));
     74     if (input_frame_.num_channels_ > 1) {
     75       InputAudioFile::DuplicateInterleaved(input_frame_.data_,
     76                                            input_block_size_samples_,
     77                                            input_frame_.num_channels_,
     78                                            input_frame_.data_);
     79     }
     80     int32_t encoded_bytes = acm_->Add10MsAudio(input_frame_);
     81     EXPECT_GE(encoded_bytes, 0);
     82     input_frame_.timestamp_ += input_block_size_samples_;
     83     if (encoded_bytes > 0) {
     84       // Encoded packet received.
     85       return CreatePacket();
     86     }
     87   }
     88   // Test ended.
     89   return NULL;
     90 }
     91 
     92 // This method receives the callback from ACM when a new packet is produced.
     93 int32_t AcmSendTest::SendData(FrameType frame_type,
     94                               uint8_t payload_type,
     95                               uint32_t timestamp,
     96                               const uint8_t* payload_data,
     97                               uint16_t payload_len_bytes,
     98                               const RTPFragmentationHeader* fragmentation) {
     99   // Store the packet locally.
    100   frame_type_ = frame_type;
    101   payload_type_ = payload_type;
    102   timestamp_ = timestamp;
    103   last_payload_vec_.assign(payload_data, payload_data + payload_len_bytes);
    104   assert(last_payload_vec_.size() == payload_len_bytes);
    105   return 0;
    106 }
    107 
    108 Packet* AcmSendTest::CreatePacket() {
    109   const size_t kRtpHeaderSize = 12;
    110   size_t allocated_bytes = last_payload_vec_.size() + kRtpHeaderSize;
    111   uint8_t* packet_memory = new uint8_t[allocated_bytes];
    112   // Populate the header bytes.
    113   packet_memory[0] = 0x80;
    114   packet_memory[1] = payload_type_;
    115   packet_memory[2] = (sequence_number_ >> 8) & 0xFF;
    116   packet_memory[3] = (sequence_number_) & 0xFF;
    117   packet_memory[4] = (timestamp_ >> 24) & 0xFF;
    118   packet_memory[5] = (timestamp_ >> 16) & 0xFF;
    119   packet_memory[6] = (timestamp_ >> 8) & 0xFF;
    120   packet_memory[7] = timestamp_ & 0xFF;
    121   // Set SSRC to 0x12345678.
    122   packet_memory[8] = 0x12;
    123   packet_memory[9] = 0x34;
    124   packet_memory[10] = 0x56;
    125   packet_memory[11] = 0x78;
    126 
    127   ++sequence_number_;
    128 
    129   // Copy the payload data.
    130   memcpy(packet_memory + kRtpHeaderSize,
    131          &last_payload_vec_[0],
    132          last_payload_vec_.size());
    133   Packet* packet =
    134       new Packet(packet_memory, allocated_bytes, clock_.TimeInMilliseconds());
    135   assert(packet);
    136   assert(packet->valid_header());
    137   return packet;
    138 }
    139 
    140 }  // namespace test
    141 }  // namespace webrtc
    142