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