blob: f2ae43eb108a939f261ae17646a05c26fd307643 [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
pbos@webrtc.org8b062002013-07-12 08:28:10 +000011#include "webrtc/common_types.h"
ossue3525782016-05-25 07:37:43 -070012#include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010013#include "webrtc/modules/include/module_common_types.h"
kwibergc8c71f42016-08-15 11:43:51 -070014#include "webrtc/modules/utility/source/coder.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000015
niklase@google.com470e71d2011-07-07 08:21:25 +000016namespace webrtc {
henrik.lundind4ccb002016-05-17 12:21:55 -070017namespace {
18AudioCodingModule::Config GetAcmConfig(uint32_t id) {
19 AudioCodingModule::Config config;
20 // This class does not handle muted output.
21 config.neteq_config.enable_muted_state = false;
22 config.id = id;
ossue3525782016-05-25 07:37:43 -070023 config.decoder_factory = CreateBuiltinAudioDecoderFactory();
henrik.lundind4ccb002016-05-17 12:21:55 -070024 return config;
25}
26} // namespace
kwiberg73987c92016-05-04 05:12:19 -070027
kwiberg8a707142016-05-11 04:26:39 -070028AudioCoder::AudioCoder(uint32_t instance_id)
henrik.lundind4ccb002016-05-17 12:21:55 -070029 : acm_(AudioCodingModule::Create(GetAcmConfig(instance_id))),
kwiberg8a707142016-05-11 04:26:39 -070030 receive_codec_(),
31 encode_timestamp_(0),
32 encoded_data_(nullptr),
33 encoded_length_in_bytes_(0),
34 decode_timestamp_(0) {
35 acm_->InitializeReceiver();
36 acm_->RegisterTransportCallback(this);
niklase@google.com470e71d2011-07-07 08:21:25 +000037}
38
kwiberg73987c92016-05-04 05:12:19 -070039AudioCoder::~AudioCoder() {}
niklase@google.com470e71d2011-07-07 08:21:25 +000040
kwiberg8a707142016-05-11 04:26:39 -070041int32_t AudioCoder::SetEncodeCodec(const CodecInst& codec_inst) {
42 const bool success = codec_manager_.RegisterEncoder(codec_inst) &&
43 codec_manager_.MakeEncoder(&rent_a_codec_, acm_.get());
kwibergc8d071e2016-04-06 12:22:38 -070044 return success ? 0 : -1;
niklase@google.com470e71d2011-07-07 08:21:25 +000045}
46
kwiberg8a707142016-05-11 04:26:39 -070047int32_t AudioCoder::SetDecodeCodec(const CodecInst& codec_inst) {
kwibergabe95ba2016-06-02 02:58:59 -070048 if (acm_->RegisterReceiveCodec(codec_inst, [&] {
49 return rent_a_codec_.RentIsacDecoder(codec_inst.plfreq);
50 }) == -1) {
kwibergc8d071e2016-04-06 12:22:38 -070051 return -1;
52 }
kwiberg8a707142016-05-11 04:26:39 -070053 memcpy(&receive_codec_, &codec_inst, sizeof(CodecInst));
kwibergc8d071e2016-04-06 12:22:38 -070054 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000055}
56
kwiberg8a707142016-05-11 04:26:39 -070057int32_t AudioCoder::Decode(AudioFrame& decoded_audio,
58 uint32_t samp_freq_hz,
59 const int8_t* incoming_payload,
60 size_t payload_length) {
61 if (payload_length > 0) {
62 const uint8_t payload_type = receive_codec_.pltype;
63 decode_timestamp_ += receive_codec_.pacsize;
64 if (acm_->IncomingPayload((const uint8_t*)incoming_payload, payload_length,
65 payload_type, decode_timestamp_) == -1) {
kwiberg73987c92016-05-04 05:12:19 -070066 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +000067 }
kwiberg73987c92016-05-04 05:12:19 -070068 }
henrik.lundind4ccb002016-05-17 12:21:55 -070069 bool muted;
70 int32_t ret =
71 acm_->PlayoutData10Ms((uint16_t)samp_freq_hz, &decoded_audio, &muted);
72 RTC_DCHECK(!muted);
73 return ret;
niklase@google.com470e71d2011-07-07 08:21:25 +000074}
75
kwiberg8a707142016-05-11 04:26:39 -070076int32_t AudioCoder::PlayoutData(AudioFrame& decoded_audio,
77 uint16_t& samp_freq_hz) {
henrik.lundind4ccb002016-05-17 12:21:55 -070078 bool muted;
79 int32_t ret = acm_->PlayoutData10Ms(samp_freq_hz, &decoded_audio, &muted);
80 RTC_DCHECK(!muted);
81 return ret;
niklase@google.com470e71d2011-07-07 08:21:25 +000082}
83
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +000084int32_t AudioCoder::Encode(const AudioFrame& audio,
kwiberg8a707142016-05-11 04:26:39 -070085 int8_t* encoded_data,
86 size_t& encoded_length_in_bytes) {
kwiberg73987c92016-05-04 05:12:19 -070087 // Fake a timestamp in case audio doesn't contain a correct timestamp.
88 // Make a local copy of the audio frame since audio is const
kwiberg8a707142016-05-11 04:26:39 -070089 AudioFrame audio_frame;
90 audio_frame.CopyFrom(audio);
91 audio_frame.timestamp_ = encode_timestamp_;
92 encode_timestamp_ += static_cast<uint32_t>(audio_frame.samples_per_channel_);
niklase@google.com470e71d2011-07-07 08:21:25 +000093
kwiberg73987c92016-05-04 05:12:19 -070094 // For any codec with a frame size that is longer than 10 ms the encoded
95 // length in bytes should be zero until a a full frame has been encoded.
kwiberg8a707142016-05-11 04:26:39 -070096 encoded_length_in_bytes_ = 0;
97 if (acm_->Add10MsData((AudioFrame&)audio_frame) == -1) {
kwiberg73987c92016-05-04 05:12:19 -070098 return -1;
99 }
kwiberg8a707142016-05-11 04:26:39 -0700100 encoded_data_ = encoded_data;
101 encoded_length_in_bytes = encoded_length_in_bytes_;
kwiberg73987c92016-05-04 05:12:19 -0700102 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000103}
104
kwiberg8a707142016-05-11 04:26:39 -0700105int32_t AudioCoder::SendData(FrameType /* frame_type */,
106 uint8_t /* payload_type */,
107 uint32_t /* time_stamp */,
108 const uint8_t* payload_data,
109 size_t payload_size,
kwiberg73987c92016-05-04 05:12:19 -0700110 const RTPFragmentationHeader* /* fragmentation*/) {
kwiberg8a707142016-05-11 04:26:39 -0700111 memcpy(encoded_data_, payload_data, sizeof(uint8_t) * payload_size);
112 encoded_length_in_bytes_ = payload_size;
kwiberg73987c92016-05-04 05:12:19 -0700113 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000114}
kwiberg73987c92016-05-04 05:12:19 -0700115
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000116} // namespace webrtc