1 /*
2  *  Copyright (c) 2015 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 "modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h"
12 
13 #include <memory>
14 #include <utility>
15 
16 #include "modules/audio_coding/codecs/ilbc/ilbc.h"
17 #include "modules/audio_coding/codecs/legacy_encoded_audio_frame.h"
18 #include "rtc_base/checks.h"
19 #include "rtc_base/logging.h"
20 
21 namespace webrtc {
22 
AudioDecoderIlbcImpl()23 AudioDecoderIlbcImpl::AudioDecoderIlbcImpl() {
24   WebRtcIlbcfix_DecoderCreate(&dec_state_);
25   WebRtcIlbcfix_Decoderinit30Ms(dec_state_);
26 }
27 
~AudioDecoderIlbcImpl()28 AudioDecoderIlbcImpl::~AudioDecoderIlbcImpl() {
29   WebRtcIlbcfix_DecoderFree(dec_state_);
30 }
31 
HasDecodePlc() const32 bool AudioDecoderIlbcImpl::HasDecodePlc() const {
33   return true;
34 }
35 
DecodeInternal(const uint8_t * encoded,size_t encoded_len,int sample_rate_hz,int16_t * decoded,SpeechType * speech_type)36 int AudioDecoderIlbcImpl::DecodeInternal(const uint8_t* encoded,
37                                          size_t encoded_len,
38                                          int sample_rate_hz,
39                                          int16_t* decoded,
40                                          SpeechType* speech_type) {
41   RTC_DCHECK_EQ(sample_rate_hz, 8000);
42   int16_t temp_type = 1;  // Default is speech.
43   int ret = WebRtcIlbcfix_Decode(dec_state_, encoded, encoded_len, decoded,
44                                  &temp_type);
45   *speech_type = ConvertSpeechType(temp_type);
46   return ret;
47 }
48 
DecodePlc(size_t num_frames,int16_t * decoded)49 size_t AudioDecoderIlbcImpl::DecodePlc(size_t num_frames, int16_t* decoded) {
50   return WebRtcIlbcfix_NetEqPlc(dec_state_, decoded, num_frames);
51 }
52 
Reset()53 void AudioDecoderIlbcImpl::Reset() {
54   WebRtcIlbcfix_Decoderinit30Ms(dec_state_);
55 }
56 
ParsePayload(rtc::Buffer && payload,uint32_t timestamp)57 std::vector<AudioDecoder::ParseResult> AudioDecoderIlbcImpl::ParsePayload(
58     rtc::Buffer&& payload,
59     uint32_t timestamp) {
60   std::vector<ParseResult> results;
61   size_t bytes_per_frame;
62   int timestamps_per_frame;
63   if (payload.size() >= 950) {
64     RTC_LOG(LS_WARNING)
65         << "AudioDecoderIlbcImpl::ParsePayload: Payload too large";
66     return results;
67   }
68   if (payload.size() % 38 == 0) {
69     // 20 ms frames.
70     bytes_per_frame = 38;
71     timestamps_per_frame = 160;
72   } else if (payload.size() % 50 == 0) {
73     // 30 ms frames.
74     bytes_per_frame = 50;
75     timestamps_per_frame = 240;
76   } else {
77     RTC_LOG(LS_WARNING)
78         << "AudioDecoderIlbcImpl::ParsePayload: Invalid payload";
79     return results;
80   }
81 
82   RTC_DCHECK_EQ(0, payload.size() % bytes_per_frame);
83   if (payload.size() == bytes_per_frame) {
84     std::unique_ptr<EncodedAudioFrame> frame(
85         new LegacyEncodedAudioFrame(this, std::move(payload)));
86     results.emplace_back(timestamp, 0, std::move(frame));
87   } else {
88     size_t byte_offset;
89     uint32_t timestamp_offset;
90     for (byte_offset = 0, timestamp_offset = 0; byte_offset < payload.size();
91          byte_offset += bytes_per_frame,
92         timestamp_offset += timestamps_per_frame) {
93       std::unique_ptr<EncodedAudioFrame> frame(new LegacyEncodedAudioFrame(
94           this, rtc::Buffer(payload.data() + byte_offset, bytes_per_frame)));
95       results.emplace_back(timestamp + timestamp_offset, 0, std::move(frame));
96     }
97   }
98 
99   return results;
100 }
101 
SampleRateHz() const102 int AudioDecoderIlbcImpl::SampleRateHz() const {
103   return 8000;
104 }
105 
Channels() const106 size_t AudioDecoderIlbcImpl::Channels() const {
107   return 1;
108 }
109 
110 }  // namespace webrtc
111