1 /*
2  *  Copyright (c) 2014 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/modules/audio_coding/codecs/red/audio_encoder_copy_red.h"
12 
13 #include <string.h>
14 
15 #include "webrtc/base/checks.h"
16 
17 namespace webrtc {
18 
AudioEncoderCopyRed(const Config & config)19 AudioEncoderCopyRed::AudioEncoderCopyRed(const Config& config)
20     : speech_encoder_(config.speech_encoder),
21       red_payload_type_(config.payload_type) {
22   RTC_CHECK(speech_encoder_) << "Speech encoder not provided.";
23 }
24 
25 AudioEncoderCopyRed::~AudioEncoderCopyRed() = default;
26 
MaxEncodedBytes() const27 size_t AudioEncoderCopyRed::MaxEncodedBytes() const {
28   return 2 * speech_encoder_->MaxEncodedBytes();
29 }
30 
SampleRateHz() const31 int AudioEncoderCopyRed::SampleRateHz() const {
32   return speech_encoder_->SampleRateHz();
33 }
34 
NumChannels() const35 size_t AudioEncoderCopyRed::NumChannels() const {
36   return speech_encoder_->NumChannels();
37 }
38 
RtpTimestampRateHz() const39 int AudioEncoderCopyRed::RtpTimestampRateHz() const {
40   return speech_encoder_->RtpTimestampRateHz();
41 }
42 
Num10MsFramesInNextPacket() const43 size_t AudioEncoderCopyRed::Num10MsFramesInNextPacket() const {
44   return speech_encoder_->Num10MsFramesInNextPacket();
45 }
46 
Max10MsFramesInAPacket() const47 size_t AudioEncoderCopyRed::Max10MsFramesInAPacket() const {
48   return speech_encoder_->Max10MsFramesInAPacket();
49 }
50 
GetTargetBitrate() const51 int AudioEncoderCopyRed::GetTargetBitrate() const {
52   return speech_encoder_->GetTargetBitrate();
53 }
54 
EncodeInternal(uint32_t rtp_timestamp,rtc::ArrayView<const int16_t> audio,size_t max_encoded_bytes,uint8_t * encoded)55 AudioEncoder::EncodedInfo AudioEncoderCopyRed::EncodeInternal(
56     uint32_t rtp_timestamp,
57     rtc::ArrayView<const int16_t> audio,
58     size_t max_encoded_bytes,
59     uint8_t* encoded) {
60   EncodedInfo info =
61       speech_encoder_->Encode(rtp_timestamp, audio, max_encoded_bytes, encoded);
62   RTC_CHECK_GE(max_encoded_bytes,
63                info.encoded_bytes + secondary_info_.encoded_bytes);
64   RTC_CHECK(info.redundant.empty()) << "Cannot use nested redundant encoders.";
65 
66   if (info.encoded_bytes > 0) {
67     // |info| will be implicitly cast to an EncodedInfoLeaf struct, effectively
68     // discarding the (empty) vector of redundant information. This is
69     // intentional.
70     info.redundant.push_back(info);
71     RTC_DCHECK_EQ(info.redundant.size(), 1u);
72     if (secondary_info_.encoded_bytes > 0) {
73       memcpy(&encoded[info.encoded_bytes], secondary_encoded_.data(),
74              secondary_info_.encoded_bytes);
75       info.redundant.push_back(secondary_info_);
76       RTC_DCHECK_EQ(info.redundant.size(), 2u);
77     }
78     // Save primary to secondary.
79     secondary_encoded_.SetData(encoded, info.encoded_bytes);
80     secondary_info_ = info;
81     RTC_DCHECK_EQ(info.speech, info.redundant[0].speech);
82   }
83   // Update main EncodedInfo.
84   info.payload_type = red_payload_type_;
85   info.encoded_bytes = 0;
86   for (std::vector<EncodedInfoLeaf>::const_iterator it = info.redundant.begin();
87        it != info.redundant.end(); ++it) {
88     info.encoded_bytes += it->encoded_bytes;
89   }
90   return info;
91 }
92 
Reset()93 void AudioEncoderCopyRed::Reset() {
94   speech_encoder_->Reset();
95   secondary_encoded_.Clear();
96   secondary_info_.encoded_bytes = 0;
97 }
98 
SetFec(bool enable)99 bool AudioEncoderCopyRed::SetFec(bool enable) {
100   return speech_encoder_->SetFec(enable);
101 }
102 
SetDtx(bool enable)103 bool AudioEncoderCopyRed::SetDtx(bool enable) {
104   return speech_encoder_->SetDtx(enable);
105 }
106 
SetApplication(Application application)107 bool AudioEncoderCopyRed::SetApplication(Application application) {
108   return speech_encoder_->SetApplication(application);
109 }
110 
SetMaxPlaybackRate(int frequency_hz)111 void AudioEncoderCopyRed::SetMaxPlaybackRate(int frequency_hz) {
112   speech_encoder_->SetMaxPlaybackRate(frequency_hz);
113 }
114 
SetProjectedPacketLossRate(double fraction)115 void AudioEncoderCopyRed::SetProjectedPacketLossRate(double fraction) {
116   speech_encoder_->SetProjectedPacketLossRate(fraction);
117 }
118 
SetTargetBitrate(int bits_per_second)119 void AudioEncoderCopyRed::SetTargetBitrate(int bits_per_second) {
120   speech_encoder_->SetTargetBitrate(bits_per_second);
121 }
122 
123 }  // namespace webrtc
124