Remove length from SingleProcessEncodedImageDataInjector::ExtractionInfo, use SpatialLayerFrameSize instead

Bug: webrtc:11632
Change-Id: I8fea71e130df9894f26287ce94cd8bb05da3a69a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176331
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Commit-Queue: Andrey Logvin <landrey@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31398}
This commit is contained in:
Andrey Logvin 2020-06-01 14:14:22 +00:00 committed by Commit Bot
parent 00b172a6fa
commit fce28fa091
3 changed files with 112 additions and 26 deletions

View file

@ -40,7 +40,6 @@ EncodedImage SingleProcessEncodedImageDataInjector::InjectData(
RTC_CHECK(source.size() >= kUsedBufferSize); RTC_CHECK(source.size() >= kUsedBufferSize);
ExtractionInfo info; ExtractionInfo info;
info.length = source.size();
info.discard = discard; info.discard = discard;
size_t insertion_pos = source.size() - kUsedBufferSize; size_t insertion_pos = source.size() - kUsedBufferSize;
memcpy(info.origin_data, &source.data()[insertion_pos], kUsedBufferSize); memcpy(info.origin_data, &source.data()[insertion_pos], kUsedBufferSize);
@ -69,15 +68,26 @@ EncodedImageExtractionResult SingleProcessEncodedImageDataInjector::ExtractData(
uint8_t* buffer = out.data(); uint8_t* buffer = out.data();
size_t size = out.size(); size_t size = out.size();
// |pos| is pointing to end of current encoded image. std::vector<size_t> frame_sizes;
size_t pos = size - 1; std::vector<size_t> frame_sl_index;
size_t max_spatial_index = out.SpatialIndex().value_or(0);
for (size_t i = 0; i <= max_spatial_index; ++i) {
auto frame_size = source.SpatialLayerFrameSize(i);
if (frame_size.value_or(0)) {
frame_sl_index.push_back(i);
frame_sizes.push_back(frame_size.value());
}
}
if (frame_sizes.empty()) {
frame_sizes.push_back(size);
}
size_t prev_frames_size = 0;
absl::optional<uint16_t> id = absl::nullopt; absl::optional<uint16_t> id = absl::nullopt;
bool discard = true; bool discard = true;
std::vector<ExtractionInfo> extraction_infos; std::vector<ExtractionInfo> extraction_infos;
// Go through whole buffer and find all related extraction infos in for (size_t frame_size : frame_sizes) {
// order from 1st encoded image to the last. size_t insertion_pos = prev_frames_size + frame_size - kUsedBufferSize;
while (true) {
size_t insertion_pos = pos - kUsedBufferSize + 1;
// Extract frame id from first 2 bytes starting from insertion pos. // Extract frame id from first 2 bytes starting from insertion pos.
uint16_t next_id = buffer[insertion_pos] + (buffer[insertion_pos + 1] << 8); uint16_t next_id = buffer[insertion_pos] + (buffer[insertion_pos + 1] << 8);
// Extract frame sub id from second 3 byte starting from insertion pos. // Extract frame sub id from second 3 byte starting from insertion pos.
@ -99,41 +109,45 @@ EncodedImageExtractionResult SingleProcessEncodedImageDataInjector::ExtractData(
info = info_it->second; info = info_it->second;
ext_vector_it->second.infos.erase(info_it); ext_vector_it->second.infos.erase(info_it);
} }
extraction_infos.push_back(info);
// We need to discard encoded image only if all concatenated encoded images // We need to discard encoded image only if all concatenated encoded images
// have to be discarded. // have to be discarded.
discard = discard && info.discard; discard = discard && info.discard;
if (pos < info.length) {
break; extraction_infos.push_back(info);
} prev_frames_size += frame_size;
pos -= info.length;
} }
RTC_CHECK(id); RTC_CHECK(id);
std::reverse(extraction_infos.begin(), extraction_infos.end());
if (discard) { if (discard) {
out.set_size(0); out.set_size(0);
for (size_t i = 0; i <= max_spatial_index; ++i) {
out.SetSpatialLayerFrameSize(i, 0);
}
return EncodedImageExtractionResult{*id, out, true}; return EncodedImageExtractionResult{*id, out, true};
} }
// Make a pass from begin to end to restore origin payload and erase discarded // Make a pass from begin to end to restore origin payload and erase discarded
// encoded images. // encoded images.
pos = 0; size_t pos = 0;
auto extraction_infos_it = extraction_infos.begin(); for (size_t frame_index = 0; frame_index < frame_sizes.size();
while (pos < size) { ++frame_index) {
RTC_DCHECK(extraction_infos_it != extraction_infos.end()); RTC_CHECK(pos < size);
const ExtractionInfo& info = *extraction_infos_it; const size_t frame_size = frame_sizes[frame_index];
const ExtractionInfo& info = extraction_infos[frame_index];
if (info.discard) { if (info.discard) {
// If this encoded image is marked to be discarded - erase it's payload // If this encoded image is marked to be discarded - erase it's payload
// from the buffer. // from the buffer.
memmove(&buffer[pos], &buffer[pos + info.length], memmove(&buffer[pos], &buffer[pos + frame_size], size - pos - frame_size);
size - pos - info.length); RTC_CHECK_LT(frame_index, frame_sl_index.size())
size -= info.length; << "codec doesn't support discard option or the image, that was "
"supposed to be discarded, is lost";
out.SetSpatialLayerFrameSize(frame_sl_index[frame_index], 0);
size -= frame_size;
} else { } else {
memcpy(&buffer[pos + info.length - kUsedBufferSize], info.origin_data, memcpy(&buffer[pos + frame_size - kUsedBufferSize], info.origin_data,
kUsedBufferSize); kUsedBufferSize);
pos += info.length; pos += frame_size;
} }
++extraction_infos_it;
} }
out.set_size(pos); out.set_size(pos);

View file

@ -59,8 +59,6 @@ class SingleProcessEncodedImageDataInjector : public EncodedImageDataInjector,
struct ExtractionInfo { struct ExtractionInfo {
// Frame sub id to distinguish encoded images for different spatial layers. // Frame sub id to distinguish encoded images for different spatial layers.
uint8_t sub_id; uint8_t sub_id;
// Length of the origin buffer encoded image.
size_t length;
// Flag to show is this encoded images should be discarded by analyzing // Flag to show is this encoded images should be discarded by analyzing
// decoder because of not required spatial layer/simulcast stream. // decoder because of not required spatial layer/simulcast stream.
bool discard; bool discard;

View file

@ -44,6 +44,7 @@ TEST(SingleProcessEncodedImageDataInjector, InjectExtractDiscardFalse) {
EXPECT_FALSE(out.discard); EXPECT_FALSE(out.discard);
EXPECT_EQ(out.image.size(), 10ul); EXPECT_EQ(out.image.size(), 10ul);
EXPECT_EQ(out.image.capacity(), 10ul); EXPECT_EQ(out.image.capacity(), 10ul);
EXPECT_EQ(out.image.SpatialLayerFrameSize(0).value_or(0), 0ul);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
EXPECT_EQ(out.image.data()[i], i + 1); EXPECT_EQ(out.image.data()[i], i + 1);
} }
@ -63,6 +64,60 @@ TEST(SingleProcessEncodedImageDataInjector, InjectExtractDiscardTrue) {
EXPECT_TRUE(out.discard); EXPECT_TRUE(out.discard);
EXPECT_EQ(out.image.size(), 0ul); EXPECT_EQ(out.image.size(), 0ul);
EXPECT_EQ(out.image.capacity(), 10ul); EXPECT_EQ(out.image.capacity(), 10ul);
EXPECT_EQ(out.image.SpatialLayerFrameSize(0).value_or(0), 0ul);
}
TEST(SingleProcessEncodedImageDataInjector, InjectWithUnsetSpatialLayerSizes) {
SingleProcessEncodedImageDataInjector injector;
rtc::Buffer buffer = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
EncodedImage source(buffer.data(), 10, 10);
source.SetTimestamp(123456789);
EncodedImage intermediate = injector.InjectData(512, false, source, 1);
intermediate.SetSpatialIndex(2);
EncodedImageExtractionResult out = injector.ExtractData(intermediate, 2);
EXPECT_EQ(out.id, 512);
EXPECT_FALSE(out.discard);
EXPECT_EQ(out.image.size(), 10ul);
EXPECT_EQ(out.image.capacity(), 10ul);
for (int i = 0; i < 10; ++i) {
EXPECT_EQ(out.image.data()[i], i + 1);
}
EXPECT_EQ(out.image.SpatialIndex().value_or(0), 2);
for (int i = 0; i < 3; ++i) {
EXPECT_EQ(out.image.SpatialLayerFrameSize(i).value_or(0), 0ul);
}
}
TEST(SingleProcessEncodedImageDataInjector, InjectWithZeroSpatialLayerSizes) {
SingleProcessEncodedImageDataInjector injector;
rtc::Buffer buffer = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
EncodedImage source(buffer.data(), 10, 10);
source.SetTimestamp(123456789);
EncodedImage intermediate = injector.InjectData(512, false, source, 1);
intermediate.SetSpatialIndex(2);
intermediate.SetSpatialLayerFrameSize(0, 0);
intermediate.SetSpatialLayerFrameSize(1, 0);
intermediate.SetSpatialLayerFrameSize(2, 0);
EncodedImageExtractionResult out = injector.ExtractData(intermediate, 2);
EXPECT_EQ(out.id, 512);
EXPECT_FALSE(out.discard);
EXPECT_EQ(out.image.size(), 10ul);
EXPECT_EQ(out.image.capacity(), 10ul);
for (int i = 0; i < 10; ++i) {
EXPECT_EQ(out.image.data()[i], i + 1);
}
EXPECT_EQ(out.image.SpatialIndex().value_or(0), 2);
for (int i = 0; i < 3; ++i) {
EXPECT_EQ(out.image.SpatialLayerFrameSize(i).value_or(0), 0ul);
}
} }
TEST(SingleProcessEncodedImageDataInjector, Inject3Extract3) { TEST(SingleProcessEncodedImageDataInjector, Inject3Extract3) {
@ -95,6 +150,7 @@ TEST(SingleProcessEncodedImageDataInjector, Inject3Extract3) {
EXPECT_FALSE(out1.discard); EXPECT_FALSE(out1.discard);
EXPECT_EQ(out1.image.size(), 10ul); EXPECT_EQ(out1.image.size(), 10ul);
EXPECT_EQ(out1.image.capacity(), 10ul); EXPECT_EQ(out1.image.capacity(), 10ul);
EXPECT_EQ(out1.image.SpatialLayerFrameSize(0).value_or(0), 0ul);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
EXPECT_EQ(out1.image.data()[i], i + 1); EXPECT_EQ(out1.image.data()[i], i + 1);
} }
@ -102,10 +158,12 @@ TEST(SingleProcessEncodedImageDataInjector, Inject3Extract3) {
EXPECT_TRUE(out2.discard); EXPECT_TRUE(out2.discard);
EXPECT_EQ(out2.image.size(), 0ul); EXPECT_EQ(out2.image.size(), 0ul);
EXPECT_EQ(out2.image.capacity(), 10ul); EXPECT_EQ(out2.image.capacity(), 10ul);
EXPECT_EQ(out2.image.SpatialLayerFrameSize(0).value_or(0), 0ul);
EXPECT_EQ(out3.id, 520); EXPECT_EQ(out3.id, 520);
EXPECT_FALSE(out3.discard); EXPECT_FALSE(out3.discard);
EXPECT_EQ(out3.image.size(), 10ul); EXPECT_EQ(out3.image.size(), 10ul);
EXPECT_EQ(out3.image.capacity(), 10ul); EXPECT_EQ(out3.image.capacity(), 10ul);
EXPECT_EQ(out3.image.SpatialLayerFrameSize(0).value_or(0), 0ul);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
EXPECT_EQ(out3.image.data()[i], i + 21); EXPECT_EQ(out3.image.data()[i], i + 21);
} }
@ -140,6 +198,10 @@ TEST(SingleProcessEncodedImageDataInjector, InjectExtractFromConcatenated) {
concatenated_buffer.AppendData(intermediate3.data(), intermediate3.size()); concatenated_buffer.AppendData(intermediate3.data(), intermediate3.size());
EncodedImage concatenated(concatenated_buffer.data(), concatenated_length, EncodedImage concatenated(concatenated_buffer.data(), concatenated_length,
concatenated_length); concatenated_length);
concatenated.SetSpatialIndex(2);
concatenated.SetSpatialLayerFrameSize(0, intermediate1.size());
concatenated.SetSpatialLayerFrameSize(1, intermediate2.size());
concatenated.SetSpatialLayerFrameSize(2, intermediate3.size());
// Extract frame id from concatenated image // Extract frame id from concatenated image
EncodedImageExtractionResult out = injector.ExtractData(concatenated, 2); EncodedImageExtractionResult out = injector.ExtractData(concatenated, 2);
@ -152,6 +214,10 @@ TEST(SingleProcessEncodedImageDataInjector, InjectExtractFromConcatenated) {
EXPECT_EQ(out.image.data()[i], i + 1); EXPECT_EQ(out.image.data()[i], i + 1);
EXPECT_EQ(out.image.data()[i + 10], i + 21); EXPECT_EQ(out.image.data()[i + 10], i + 21);
} }
EXPECT_EQ(out.image.SpatialIndex().value_or(0), 2);
EXPECT_EQ(out.image.SpatialLayerFrameSize(0).value_or(0), 10ul);
EXPECT_EQ(out.image.SpatialLayerFrameSize(1).value_or(0), 0ul);
EXPECT_EQ(out.image.SpatialLayerFrameSize(2).value_or(0), 10ul);
} }
TEST(SingleProcessEncodedImageDataInjector, TEST(SingleProcessEncodedImageDataInjector,
@ -184,6 +250,10 @@ TEST(SingleProcessEncodedImageDataInjector,
concatenated_buffer.AppendData(intermediate3.data(), intermediate3.size()); concatenated_buffer.AppendData(intermediate3.data(), intermediate3.size());
EncodedImage concatenated(concatenated_buffer.data(), concatenated_length, EncodedImage concatenated(concatenated_buffer.data(), concatenated_length,
concatenated_length); concatenated_length);
concatenated.SetSpatialIndex(2);
concatenated.SetSpatialLayerFrameSize(0, intermediate1.size());
concatenated.SetSpatialLayerFrameSize(1, intermediate2.size());
concatenated.SetSpatialLayerFrameSize(2, intermediate3.size());
// Extract frame id from concatenated image // Extract frame id from concatenated image
EncodedImageExtractionResult out = injector.ExtractData(concatenated, 2); EncodedImageExtractionResult out = injector.ExtractData(concatenated, 2);
@ -192,6 +262,10 @@ TEST(SingleProcessEncodedImageDataInjector,
EXPECT_TRUE(out.discard); EXPECT_TRUE(out.discard);
EXPECT_EQ(out.image.size(), 0ul); EXPECT_EQ(out.image.size(), 0ul);
EXPECT_EQ(out.image.capacity(), 3 * 10ul); EXPECT_EQ(out.image.capacity(), 3 * 10ul);
EXPECT_EQ(out.image.SpatialIndex().value_or(0), 2);
for (int i = 0; i < 3; ++i) {
EXPECT_EQ(out.image.SpatialLayerFrameSize(i).value_or(0), 0ul);
}
} }
} // namespace webrtc_pc_e2e } // namespace webrtc_pc_e2e