blob: ab724e5cece9e0d8aa74526801fcafc189e8eb36 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
tina.legrand@webrtc.org16b6b902012-04-12 11:02:38 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
kwibergdc65ea22016-08-15 10:36:32 -070011#include "webrtc/voice_engine/coder.h"
12
pbos@webrtc.org8b062002013-07-12 08:28:10 +000013#include "webrtc/common_types.h"
ossue3525782016-05-25 07:37:43 -070014#include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010015#include "webrtc/modules/include/module_common_types.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000016
niklase@google.com470e71d2011-07-07 08:21:25 +000017namespace webrtc {
henrik.lundind4ccb002016-05-17 12:21:55 -070018namespace {
19AudioCodingModule::Config GetAcmConfig(uint32_t id) {
20 AudioCodingModule::Config config;
21 // This class does not handle muted output.
22 config.neteq_config.enable_muted_state = false;
23 config.id = id;
ossue3525782016-05-25 07:37:43 -070024 config.decoder_factory = CreateBuiltinAudioDecoderFactory();
henrik.lundind4ccb002016-05-17 12:21:55 -070025 return config;
26}
27} // namespace
kwiberg73987c92016-05-04 05:12:19 -070028
kwiberg8a707142016-05-11 04:26:39 -070029AudioCoder::AudioCoder(uint32_t instance_id)
henrik.lundind4ccb002016-05-17 12:21:55 -070030 : acm_(AudioCodingModule::Create(GetAcmConfig(instance_id))),
kwiberg8a707142016-05-11 04:26:39 -070031 receive_codec_(),
32 encode_timestamp_(0),
33 encoded_data_(nullptr),
34 encoded_length_in_bytes_(0),
35 decode_timestamp_(0) {
36 acm_->InitializeReceiver();
37 acm_->RegisterTransportCallback(this);
niklase@google.com470e71d2011-07-07 08:21:25 +000038}
39
kwiberg73987c92016-05-04 05:12:19 -070040AudioCoder::~AudioCoder() {}
niklase@google.com470e71d2011-07-07 08:21:25 +000041
kwiberg8a707142016-05-11 04:26:39 -070042int32_t AudioCoder::SetEncodeCodec(const CodecInst& codec_inst) {
43 const bool success = codec_manager_.RegisterEncoder(codec_inst) &&
44 codec_manager_.MakeEncoder(&rent_a_codec_, acm_.get());
kwibergc8d071e2016-04-06 12:22:38 -070045 return success ? 0 : -1;
niklase@google.com470e71d2011-07-07 08:21:25 +000046}
47
kwiberg8a707142016-05-11 04:26:39 -070048int32_t AudioCoder::SetDecodeCodec(const CodecInst& codec_inst) {
kwibergabe95ba2016-06-02 02:58:59 -070049 if (acm_->RegisterReceiveCodec(codec_inst, [&] {
50 return rent_a_codec_.RentIsacDecoder(codec_inst.plfreq);
51 }) == -1) {
kwibergc8d071e2016-04-06 12:22:38 -070052 return -1;
53 }
kwiberg8a707142016-05-11 04:26:39 -070054 memcpy(&receive_codec_, &codec_inst, sizeof(CodecInst));
kwibergc8d071e2016-04-06 12:22:38 -070055 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000056}
57
kwiberg8a707142016-05-11 04:26:39 -070058int32_t AudioCoder::Decode(AudioFrame& decoded_audio,
59 uint32_t samp_freq_hz,
60 const int8_t* incoming_payload,
61 size_t payload_length) {
62 if (payload_length > 0) {
63 const uint8_t payload_type = receive_codec_.pltype;
64 decode_timestamp_ += receive_codec_.pacsize;
65 if (acm_->IncomingPayload((const uint8_t*)incoming_payload, payload_length,
66 payload_type, decode_timestamp_) == -1) {
kwiberg73987c92016-05-04 05:12:19 -070067 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +000068 }
kwiberg73987c92016-05-04 05:12:19 -070069 }
henrik.lundind4ccb002016-05-17 12:21:55 -070070 bool muted;
71 int32_t ret =
72 acm_->PlayoutData10Ms((uint16_t)samp_freq_hz, &decoded_audio, &muted);
73 RTC_DCHECK(!muted);
74 return ret;
niklase@google.com470e71d2011-07-07 08:21:25 +000075}
76
kwiberg8a707142016-05-11 04:26:39 -070077int32_t AudioCoder::PlayoutData(AudioFrame& decoded_audio,
78 uint16_t& samp_freq_hz) {
henrik.lundind4ccb002016-05-17 12:21:55 -070079 bool muted;
80 int32_t ret = acm_->PlayoutData10Ms(samp_freq_hz, &decoded_audio, &muted);
81 RTC_DCHECK(!muted);
82 return ret;
niklase@google.com470e71d2011-07-07 08:21:25 +000083}
84
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +000085int32_t AudioCoder::Encode(const AudioFrame& audio,
kwiberg8a707142016-05-11 04:26:39 -070086 int8_t* encoded_data,
87 size_t& encoded_length_in_bytes) {
kwiberg73987c92016-05-04 05:12:19 -070088 // 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
kwiberg8a707142016-05-11 04:26:39 -070090 AudioFrame audio_frame;
91 audio_frame.CopyFrom(audio);
92 audio_frame.timestamp_ = encode_timestamp_;
93 encode_timestamp_ += static_cast<uint32_t>(audio_frame.samples_per_channel_);
niklase@google.com470e71d2011-07-07 08:21:25 +000094
kwiberg73987c92016-05-04 05:12:19 -070095 // 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.
kwiberg8a707142016-05-11 04:26:39 -070097 encoded_length_in_bytes_ = 0;
98 if (acm_->Add10MsData((AudioFrame&)audio_frame) == -1) {
kwiberg73987c92016-05-04 05:12:19 -070099 return -1;
100 }
kwiberg8a707142016-05-11 04:26:39 -0700101 encoded_data_ = encoded_data;
102 encoded_length_in_bytes = encoded_length_in_bytes_;
kwiberg73987c92016-05-04 05:12:19 -0700103 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000104}
105
kwiberg8a707142016-05-11 04:26:39 -0700106int32_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,
kwiberg73987c92016-05-04 05:12:19 -0700111 const RTPFragmentationHeader* /* fragmentation*/) {
kwiberg8a707142016-05-11 04:26:39 -0700112 memcpy(encoded_data_, payload_data, sizeof(uint8_t) * payload_size);
113 encoded_length_in_bytes_ = payload_size;
kwiberg73987c92016-05-04 05:12:19 -0700114 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000115}
kwiberg73987c92016-05-04 05:12:19 -0700116
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000117} // namespace webrtc