We changed Encode() and EncodeInternal() return type from bool to void in this issue:

https://webrtc-codereview.appspot.com/38279004/
Now we don't have to pass EncodedInfo as output parameter, but can return it instead. This also adds the benefit of making clear that EncodeInternal() needs to fill in this info.

R=kwiberg@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/43839004

Cr-Commit-Position: refs/heads/master@{#8749}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8749 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
jmarusic@webrtc.org
2015-03-17 12:12:17 +00:00
parent 73d763e71f
commit 0cb612b43b
21 changed files with 222 additions and 237 deletions

View File

@ -60,48 +60,48 @@ void AudioEncoderCopyRed::SetProjectedPacketLossRate(double fraction) {
speech_encoder_->SetProjectedPacketLossRate(fraction);
}
void AudioEncoderCopyRed::EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
EncodedInfo* info) {
speech_encoder_->Encode(rtp_timestamp, audio,
static_cast<size_t>(SampleRateHz() / 100),
max_encoded_bytes, encoded, info);
AudioEncoder::EncodedInfo AudioEncoderCopyRed::EncodeInternal(
uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded) {
EncodedInfo info = speech_encoder_->Encode(
rtp_timestamp, audio, static_cast<size_t>(SampleRateHz() / 100),
max_encoded_bytes, encoded);
CHECK_GE(max_encoded_bytes,
info->encoded_bytes + secondary_info_.encoded_bytes);
CHECK(info->redundant.empty()) << "Cannot use nested redundant encoders.";
info.encoded_bytes + secondary_info_.encoded_bytes);
CHECK(info.redundant.empty()) << "Cannot use nested redundant encoders.";
if (info->encoded_bytes > 0) {
if (info.encoded_bytes > 0) {
// |info| will be implicitly cast to an EncodedInfoLeaf struct, effectively
// discarding the (empty) vector of redundant information. This is
// intentional.
info->redundant.push_back(*info);
DCHECK_EQ(info->redundant.size(), 1u);
info.redundant.push_back(info);
DCHECK_EQ(info.redundant.size(), 1u);
if (secondary_info_.encoded_bytes > 0) {
memcpy(&encoded[info->encoded_bytes], secondary_encoded_.get(),
memcpy(&encoded[info.encoded_bytes], secondary_encoded_.get(),
secondary_info_.encoded_bytes);
info->redundant.push_back(secondary_info_);
DCHECK_EQ(info->redundant.size(), 2u);
info.redundant.push_back(secondary_info_);
DCHECK_EQ(info.redundant.size(), 2u);
}
// Save primary to secondary.
if (secondary_allocated_ < info->encoded_bytes) {
secondary_encoded_.reset(new uint8_t[info->encoded_bytes]);
secondary_allocated_ = info->encoded_bytes;
if (secondary_allocated_ < info.encoded_bytes) {
secondary_encoded_.reset(new uint8_t[info.encoded_bytes]);
secondary_allocated_ = info.encoded_bytes;
}
CHECK(secondary_encoded_);
memcpy(secondary_encoded_.get(), encoded, info->encoded_bytes);
secondary_info_ = *info;
DCHECK_EQ(info->speech, info->redundant[0].speech);
memcpy(secondary_encoded_.get(), encoded, info.encoded_bytes);
secondary_info_ = info;
DCHECK_EQ(info.speech, info.redundant[0].speech);
}
// Update main EncodedInfo.
info->payload_type = red_payload_type_;
info->encoded_bytes = 0;
for (std::vector<EncodedInfoLeaf>::const_iterator it =
info->redundant.begin();
it != info->redundant.end(); ++it) {
info->encoded_bytes += it->encoded_bytes;
info.payload_type = red_payload_type_;
info.encoded_bytes = 0;
for (std::vector<EncodedInfoLeaf>::const_iterator it = info.redundant.begin();
it != info.redundant.end(); ++it) {
info.encoded_bytes += it->encoded_bytes;
}
return info;
}
} // namespace webrtc

View File

@ -45,11 +45,10 @@ class AudioEncoderCopyRed : public AudioEncoder {
void SetProjectedPacketLossRate(double fraction) override;
protected:
void EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
EncodedInfo* info) override;
EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded) override;
private:
AudioEncoder* speech_encoder_;

View File

@ -60,9 +60,8 @@ class AudioEncoderCopyRedTest : public ::testing::Test {
void Encode() {
ASSERT_TRUE(red_.get() != NULL);
encoded_info_ = AudioEncoder::EncodedInfo();
red_->Encode(timestamp_, audio_, num_audio_samples_10ms,
encoded_.size(), &encoded_[0], &encoded_info_);
encoded_info_ = red_->Encode(timestamp_, audio_, num_audio_samples_10ms,
encoded_.size(), &encoded_[0]);
timestamp_ += num_audio_samples_10ms;
}
@ -83,18 +82,16 @@ class MockEncodeHelper {
memset(&info_, 0, sizeof(info_));
}
void Encode(uint32_t timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded,
AudioEncoder::EncodedInfo* info) {
AudioEncoder::EncodedInfo Encode(uint32_t timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded) {
if (write_payload_) {
CHECK(encoded);
CHECK_LE(info_.encoded_bytes, max_encoded_bytes);
memcpy(encoded, payload_, info_.encoded_bytes);
}
CHECK(info);
*info = info_;
return info_;
}
AudioEncoder::EncodedInfo info_;
@ -144,7 +141,8 @@ TEST_F(AudioEncoderCopyRedTest, CheckImmediateEncode) {
InSequence s;
MockFunction<void(int check_point_id)> check;
for (int i = 1; i <= 6; ++i) {
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _, _));
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _))
.WillRepeatedly(Return(AudioEncoder::kZeroEncodedBytes));
EXPECT_CALL(check, Call(i));
Encode();
check.Call(i);
@ -153,13 +151,13 @@ TEST_F(AudioEncoderCopyRedTest, CheckImmediateEncode) {
// Checks that no output is produced if the underlying codec doesn't emit any
// new data, even if the RED codec is loaded with a secondary encoding.
TEST_F(AudioEncoderCopyRedTest, CheckNoOuput) {
TEST_F(AudioEncoderCopyRedTest, CheckNoOutput) {
// Start with one Encode() call that will produce output.
static const size_t kEncodedSize = 17;
AudioEncoder::EncodedInfo info;
info.encoded_bytes = kEncodedSize;
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _, _))
.WillOnce(SetArgPointee<4>(info));
AudioEncoder::EncodedInfo nonZeroEncodedBytes;
nonZeroEncodedBytes.encoded_bytes = kEncodedSize;
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _))
.WillOnce(Return(nonZeroEncodedBytes));
Encode();
// First call is a special case, since it does not include a secondary
// payload.
@ -167,16 +165,14 @@ TEST_F(AudioEncoderCopyRedTest, CheckNoOuput) {
EXPECT_EQ(kEncodedSize, encoded_info_.encoded_bytes);
// Next call to the speech encoder will not produce any output.
info.encoded_bytes = 0;
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _, _))
.WillOnce(SetArgPointee<4>(info));
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _))
.WillOnce(Return(AudioEncoder::kZeroEncodedBytes));
Encode();
EXPECT_EQ(0u, encoded_info_.encoded_bytes);
// Final call to the speech encoder will produce output.
info.encoded_bytes = kEncodedSize;
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _, _))
.WillOnce(SetArgPointee<4>(info));
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _))
.WillOnce(Return(nonZeroEncodedBytes));
Encode();
EXPECT_EQ(2 * kEncodedSize, encoded_info_.encoded_bytes);
ASSERT_EQ(2u, encoded_info_.redundant.size());
@ -192,8 +188,8 @@ TEST_F(AudioEncoderCopyRedTest, CheckPayloadSizes) {
for (int encode_size = 1; encode_size <= kNumPackets; ++encode_size) {
AudioEncoder::EncodedInfo info;
info.encoded_bytes = encode_size;
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _, _))
.WillOnce(SetArgPointee<4>(info));
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _))
.WillOnce(Return(info));
}
// First call is a special case, since it does not include a secondary
@ -218,7 +214,7 @@ TEST_F(AudioEncoderCopyRedTest, CheckTimestamps) {
helper.info_.encoded_bytes = 17;
helper.info_.encoded_timestamp = timestamp_;
uint32_t primary_timestamp = timestamp_;
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _, _))
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _))
.WillRepeatedly(Invoke(&helper, &MockEncodeHelper::Encode));
// First call is a special case, since it does not include a secondary
@ -249,7 +245,7 @@ TEST_F(AudioEncoderCopyRedTest, CheckPayloads) {
payload[i] = i;
}
helper.payload_ = payload;
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _, _))
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _))
.WillRepeatedly(Invoke(&helper, &MockEncodeHelper::Encode));
// First call is a special case, since it does not include a secondary
@ -286,7 +282,7 @@ TEST_F(AudioEncoderCopyRedTest, CheckPayloadType) {
helper.info_.encoded_bytes = 17;
const int primary_payload_type = red_payload_type_ + 1;
helper.info_.payload_type = primary_payload_type;
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _, _))
EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _))
.WillRepeatedly(Invoke(&helper, &MockEncodeHelper::Encode));
// First call is a special case, since it does not include a secondary