Line data Source code
1 : /*
2 : * Copyright (c) 2012 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/voice_engine/coder.h"
12 :
13 : #include "webrtc/common_types.h"
14 : #include "webrtc/modules/audio_coding/codecs/audio_format_conversion.h"
15 : #include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h"
16 : #include "webrtc/modules/include/module_common_types.h"
17 :
18 : namespace webrtc {
19 : namespace {
20 0 : AudioCodingModule::Config GetAcmConfig(uint32_t id) {
21 0 : AudioCodingModule::Config config;
22 : // This class does not handle muted output.
23 0 : config.neteq_config.enable_muted_state = false;
24 0 : config.id = id;
25 0 : config.decoder_factory = CreateBuiltinAudioDecoderFactory();
26 0 : return config;
27 : }
28 : } // namespace
29 :
30 0 : AudioCoder::AudioCoder(uint32_t instance_id)
31 0 : : acm_(AudioCodingModule::Create(GetAcmConfig(instance_id))),
32 : receive_codec_(),
33 : encode_timestamp_(0),
34 : encoded_data_(nullptr),
35 : encoded_length_in_bytes_(0),
36 0 : decode_timestamp_(0) {
37 0 : acm_->InitializeReceiver();
38 0 : acm_->RegisterTransportCallback(this);
39 0 : }
40 :
41 0 : AudioCoder::~AudioCoder() {}
42 :
43 0 : int32_t AudioCoder::SetEncodeCodec(const CodecInst& codec_inst) {
44 0 : const bool success = codec_manager_.RegisterEncoder(codec_inst) &&
45 0 : codec_manager_.MakeEncoder(&rent_a_codec_, acm_.get());
46 0 : return success ? 0 : -1;
47 : }
48 :
49 0 : int32_t AudioCoder::SetDecodeCodec(const CodecInst& codec_inst) {
50 0 : if (!acm_->RegisterReceiveCodec(codec_inst.pltype,
51 0 : CodecInstToSdp(codec_inst))) {
52 0 : return -1;
53 : }
54 0 : memcpy(&receive_codec_, &codec_inst, sizeof(CodecInst));
55 0 : return 0;
56 : }
57 :
58 0 : int32_t AudioCoder::Decode(AudioFrame* decoded_audio,
59 : uint32_t samp_freq_hz,
60 : const int8_t* incoming_payload,
61 : size_t payload_length) {
62 0 : if (payload_length > 0) {
63 0 : const uint8_t payload_type = receive_codec_.pltype;
64 0 : decode_timestamp_ += receive_codec_.pacsize;
65 0 : if (acm_->IncomingPayload((const uint8_t*)incoming_payload, payload_length,
66 0 : payload_type, decode_timestamp_) == -1) {
67 0 : return -1;
68 : }
69 : }
70 : bool muted;
71 : int32_t ret =
72 0 : acm_->PlayoutData10Ms((uint16_t)samp_freq_hz, decoded_audio, &muted);
73 0 : RTC_DCHECK(!muted);
74 0 : return ret;
75 : }
76 :
77 0 : int32_t AudioCoder::PlayoutData(AudioFrame* decoded_audio,
78 : uint16_t samp_freq_hz) {
79 : bool muted;
80 0 : int32_t ret = acm_->PlayoutData10Ms(samp_freq_hz, decoded_audio, &muted);
81 0 : RTC_DCHECK(!muted);
82 0 : return ret;
83 : }
84 :
85 0 : int32_t AudioCoder::Encode(const AudioFrame& audio,
86 : int8_t* encoded_data,
87 : size_t* encoded_length_in_bytes) {
88 : // Fake a timestamp in case audio doesn't contain a correct timestamp.
89 : // Make a local copy of the audio frame since audio is const
90 0 : AudioFrame audio_frame;
91 0 : audio_frame.CopyFrom(audio);
92 0 : audio_frame.timestamp_ = encode_timestamp_;
93 0 : encode_timestamp_ += static_cast<uint32_t>(audio_frame.samples_per_channel_);
94 :
95 : // For any codec with a frame size that is longer than 10 ms the encoded
96 : // length in bytes should be zero until a a full frame has been encoded.
97 0 : encoded_length_in_bytes_ = 0;
98 0 : if (acm_->Add10MsData((AudioFrame&)audio_frame) == -1) {
99 0 : return -1;
100 : }
101 0 : encoded_data_ = encoded_data;
102 0 : *encoded_length_in_bytes = encoded_length_in_bytes_;
103 0 : return 0;
104 : }
105 :
106 0 : int32_t AudioCoder::SendData(FrameType /* frame_type */,
107 : uint8_t /* payload_type */,
108 : uint32_t /* time_stamp */,
109 : const uint8_t* payload_data,
110 : size_t payload_size,
111 : const RTPFragmentationHeader* /* fragmentation*/) {
112 0 : memcpy(encoded_data_, payload_data, sizeof(uint8_t) * payload_size);
113 0 : encoded_length_in_bytes_ = payload_size;
114 0 : return 0;
115 : }
116 :
117 : } // namespace webrtc
|