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/common_types.h"
12#include "webrtc/modules/include/module_common_types.h"
13#include "webrtc/modules/utility/source/coder.h"
14
15namespace webrtc {
16AudioCoder::AudioCoder(uint32_t instanceID)
17    : _acm(AudioCodingModule::Create(instanceID)),
18      _receiveCodec(),
19      _encodeTimestamp(0),
20      _encodedData(NULL),
21      _encodedLengthInBytes(0),
22      _decodeTimestamp(0)
23{
24    _acm->InitializeReceiver();
25    _acm->RegisterTransportCallback(this);
26}
27
28AudioCoder::~AudioCoder()
29{
30}
31
32int32_t AudioCoder::SetEncodeCodec(const CodecInst& codecInst)
33{
34    if(_acm->RegisterSendCodec((CodecInst&)codecInst) == -1)
35    {
36        return -1;
37    }
38    return 0;
39}
40
41int32_t AudioCoder::SetDecodeCodec(const CodecInst& codecInst)
42{
43    if(_acm->RegisterReceiveCodec((CodecInst&)codecInst) == -1)
44    {
45        return -1;
46    }
47    memcpy(&_receiveCodec,&codecInst,sizeof(CodecInst));
48    return 0;
49}
50
51int32_t AudioCoder::Decode(AudioFrame& decodedAudio,
52                           uint32_t sampFreqHz,
53                           const int8_t*  incomingPayload,
54                           size_t  payloadLength)
55{
56    if (payloadLength > 0)
57    {
58        const uint8_t payloadType = _receiveCodec.pltype;
59        _decodeTimestamp += _receiveCodec.pacsize;
60        if(_acm->IncomingPayload((const uint8_t*) incomingPayload,
61                                 payloadLength,
62                                 payloadType,
63                                 _decodeTimestamp) == -1)
64        {
65            return -1;
66        }
67    }
68    return _acm->PlayoutData10Ms((uint16_t)sampFreqHz, &decodedAudio);
69}
70
71int32_t AudioCoder::PlayoutData(AudioFrame& decodedAudio,
72                                uint16_t& sampFreqHz)
73{
74    return _acm->PlayoutData10Ms(sampFreqHz, &decodedAudio);
75}
76
77int32_t AudioCoder::Encode(const AudioFrame& audio,
78                           int8_t* encodedData,
79                           size_t& encodedLengthInBytes)
80{
81    // Fake a timestamp in case audio doesn't contain a correct timestamp.
82    // Make a local copy of the audio frame since audio is const
83    AudioFrame audioFrame;
84    audioFrame.CopyFrom(audio);
85    audioFrame.timestamp_ = _encodeTimestamp;
86    _encodeTimestamp += static_cast<uint32_t>(audioFrame.samples_per_channel_);
87
88    // For any codec with a frame size that is longer than 10 ms the encoded
89    // length in bytes should be zero until a a full frame has been encoded.
90    _encodedLengthInBytes = 0;
91    if(_acm->Add10MsData((AudioFrame&)audioFrame) == -1)
92    {
93        return -1;
94    }
95    _encodedData = encodedData;
96    encodedLengthInBytes = _encodedLengthInBytes;
97    return 0;
98}
99
100int32_t AudioCoder::SendData(
101    FrameType /* frameType */,
102    uint8_t   /* payloadType */,
103    uint32_t  /* timeStamp */,
104    const uint8_t*  payloadData,
105    size_t  payloadSize,
106    const RTPFragmentationHeader* /* fragmentation*/)
107{
108    memcpy(_encodedData,payloadData,sizeof(uint8_t) * payloadSize);
109    _encodedLengthInBytes = payloadSize;
110    return 0;
111}
112}  // namespace webrtc
113