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 "modules/audio_coding/codecs/red/audio_encoder_copy_red.h"
12 
13 #include <string.h>
14 
15 #include <utility>
16 
17 #include "rtc_base/checks.h"
18 
19 namespace webrtc {
20 
21 AudioEncoderCopyRed::Config::Config() = default;
22 AudioEncoderCopyRed::Config::Config(Config&&) = default;
23 AudioEncoderCopyRed::Config::~Config() = default;
24 
AudioEncoderCopyRed(Config && config)25 AudioEncoderCopyRed::AudioEncoderCopyRed(Config&& config)
26     : speech_encoder_(std::move(config.speech_encoder)),
27       red_payload_type_(config.payload_type) {
28   RTC_CHECK(speech_encoder_) << "Speech encoder not provided.";
29 }
30 
31 AudioEncoderCopyRed::~AudioEncoderCopyRed() = default;
32 
SampleRateHz() const33 int AudioEncoderCopyRed::SampleRateHz() const {
34   return speech_encoder_->SampleRateHz();
35 }
36 
NumChannels() const37 size_t AudioEncoderCopyRed::NumChannels() const {
38   return speech_encoder_->NumChannels();
39 }
40 
RtpTimestampRateHz() const41 int AudioEncoderCopyRed::RtpTimestampRateHz() const {
42   return speech_encoder_->RtpTimestampRateHz();
43 }
44 
Num10MsFramesInNextPacket() const45 size_t AudioEncoderCopyRed::Num10MsFramesInNextPacket() const {
46   return speech_encoder_->Num10MsFramesInNextPacket();
47 }
48 
Max10MsFramesInAPacket() const49 size_t AudioEncoderCopyRed::Max10MsFramesInAPacket() const {
50   return speech_encoder_->Max10MsFramesInAPacket();
51 }
52 
GetTargetBitrate() const53 int AudioEncoderCopyRed::GetTargetBitrate() const {
54   return speech_encoder_->GetTargetBitrate();
55 }
56 
EncodeImpl(uint32_t rtp_timestamp,rtc::ArrayView<const int16_t> audio,rtc::Buffer * encoded)57 AudioEncoder::EncodedInfo AudioEncoderCopyRed::EncodeImpl(
58     uint32_t rtp_timestamp,
59     rtc::ArrayView<const int16_t> audio,
60     rtc::Buffer* encoded) {
61 
62   const size_t primary_offset = encoded->size();
63   EncodedInfo info =
64       speech_encoder_->Encode(rtp_timestamp, audio, encoded);
65 
66   RTC_CHECK(info.redundant.empty()) << "Cannot use nested redundant encoders.";
67   RTC_DCHECK_EQ(encoded->size() - primary_offset, info.encoded_bytes);
68 
69   if (info.encoded_bytes > 0) {
70     // |info| will be implicitly cast to an EncodedInfoLeaf struct, effectively
71     // discarding the (empty) vector of redundant information. This is
72     // intentional.
73     info.redundant.push_back(info);
74     RTC_DCHECK_EQ(info.redundant.size(), 1);
75     if (secondary_info_.encoded_bytes > 0) {
76       encoded->AppendData(secondary_encoded_);
77       info.redundant.push_back(secondary_info_);
78       RTC_DCHECK_EQ(info.redundant.size(), 2);
79     }
80     // Save primary to secondary.
81     secondary_encoded_.SetData(encoded->data() + primary_offset,
82                                info.encoded_bytes);
83     secondary_info_ = info;
84     RTC_DCHECK_EQ(info.speech, info.redundant[0].speech);
85   }
86   // Update main EncodedInfo.
87   info.payload_type = red_payload_type_;
88   info.encoded_bytes = 0;
89   for (std::vector<EncodedInfoLeaf>::const_iterator it = info.redundant.begin();
90        it != info.redundant.end(); ++it) {
91     info.encoded_bytes += it->encoded_bytes;
92   }
93   return info;
94 }
95 
Reset()96 void AudioEncoderCopyRed::Reset() {
97   speech_encoder_->Reset();
98   secondary_encoded_.Clear();
99   secondary_info_.encoded_bytes = 0;
100 }
101 
SetFec(bool enable)102 bool AudioEncoderCopyRed::SetFec(bool enable) {
103   return speech_encoder_->SetFec(enable);
104 }
105 
SetDtx(bool enable)106 bool AudioEncoderCopyRed::SetDtx(bool enable) {
107   return speech_encoder_->SetDtx(enable);
108 }
109 
SetApplication(Application application)110 bool AudioEncoderCopyRed::SetApplication(Application application) {
111   return speech_encoder_->SetApplication(application);
112 }
113 
SetMaxPlaybackRate(int frequency_hz)114 void AudioEncoderCopyRed::SetMaxPlaybackRate(int frequency_hz) {
115   speech_encoder_->SetMaxPlaybackRate(frequency_hz);
116 }
117 
118 rtc::ArrayView<std::unique_ptr<AudioEncoder>>
ReclaimContainedEncoders()119 AudioEncoderCopyRed::ReclaimContainedEncoders() {
120   return rtc::ArrayView<std::unique_ptr<AudioEncoder>>(&speech_encoder_, 1);
121 }
122 
OnReceivedUplinkPacketLossFraction(float uplink_packet_loss_fraction)123 void AudioEncoderCopyRed::OnReceivedUplinkPacketLossFraction(
124     float uplink_packet_loss_fraction) {
125   speech_encoder_->OnReceivedUplinkPacketLossFraction(
126       uplink_packet_loss_fraction);
127 }
128 
OnReceivedUplinkRecoverablePacketLossFraction(float uplink_recoverable_packet_loss_fraction)129 void AudioEncoderCopyRed::OnReceivedUplinkRecoverablePacketLossFraction(
130     float uplink_recoverable_packet_loss_fraction) {
131   speech_encoder_->OnReceivedUplinkRecoverablePacketLossFraction(
132       uplink_recoverable_packet_loss_fraction);
133 }
134 
OnReceivedUplinkBandwidth(int target_audio_bitrate_bps,rtc::Optional<int64_t> bwe_period_ms)135 void AudioEncoderCopyRed::OnReceivedUplinkBandwidth(
136     int target_audio_bitrate_bps,
137     rtc::Optional<int64_t> bwe_period_ms) {
138   speech_encoder_->OnReceivedUplinkBandwidth(target_audio_bitrate_bps,
139                                              bwe_period_ms);
140 }
141 
142 }  // namespace webrtc
143