Add support for multiple peers in SingleProcessEncodedImageDataInjector
Bug: webrtc:11779 Change-Id: Ie59e39e7fa903432ec13400b1c3e0e1456e812fc Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/180127 Reviewed-by: Andrey Logvin <landrey@webrtc.org> Commit-Queue: Artem Titov <titovartem@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31790}
This commit is contained in:
parent
4fd830acab
commit
d5f42bdced
@ -63,6 +63,8 @@ class DefaultEncodedImageDataInjector : public EncodedImageDataInjector,
|
||||
bool discard,
|
||||
const EncodedImage& source,
|
||||
int /*coding_entity_id*/) override;
|
||||
|
||||
void Start(int expected_receivers_count) override {}
|
||||
EncodedImageExtractionResult ExtractData(const EncodedImage& source,
|
||||
int coding_entity_id) override;
|
||||
};
|
||||
|
||||
@ -32,6 +32,7 @@ rtc::Buffer CreateBufferOfSizeNFilledWithValuesFromX(size_t n, uint8_t x) {
|
||||
|
||||
TEST(DefaultEncodedImageDataInjector, InjectExtractDiscardFalse) {
|
||||
DefaultEncodedImageDataInjector injector;
|
||||
injector.Start(1);
|
||||
|
||||
rtc::Buffer buffer = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
|
||||
@ -50,6 +51,7 @@ TEST(DefaultEncodedImageDataInjector, InjectExtractDiscardFalse) {
|
||||
|
||||
TEST(DefaultEncodedImageDataInjector, InjectExtractDiscardTrue) {
|
||||
DefaultEncodedImageDataInjector injector;
|
||||
injector.Start(1);
|
||||
|
||||
rtc::Buffer buffer = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
|
||||
@ -65,6 +67,7 @@ TEST(DefaultEncodedImageDataInjector, InjectExtractDiscardTrue) {
|
||||
|
||||
TEST(DefaultEncodedImageDataInjector, Inject3Extract3) {
|
||||
DefaultEncodedImageDataInjector injector;
|
||||
injector.Start(1);
|
||||
|
||||
rtc::Buffer buffer1 = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
rtc::Buffer buffer2 = CreateBufferOfSizeNFilledWithValuesFromX(10, 11);
|
||||
@ -108,6 +111,7 @@ TEST(DefaultEncodedImageDataInjector, Inject3Extract3) {
|
||||
|
||||
TEST(DefaultEncodedImageDataInjector, InjectExtractFromConcatenated) {
|
||||
DefaultEncodedImageDataInjector injector;
|
||||
injector.Start(1);
|
||||
|
||||
rtc::Buffer buffer1 = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
rtc::Buffer buffer2 = CreateBufferOfSizeNFilledWithValuesFromX(10, 11);
|
||||
@ -151,6 +155,7 @@ TEST(DefaultEncodedImageDataInjector, InjectExtractFromConcatenated) {
|
||||
TEST(DefaultEncodedImageDataInjector,
|
||||
InjectExtractFromConcatenatedAllDiscarded) {
|
||||
DefaultEncodedImageDataInjector injector;
|
||||
injector.Start(1);
|
||||
|
||||
rtc::Buffer buffer1 = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
rtc::Buffer buffer2 = CreateBufferOfSizeNFilledWithValuesFromX(10, 11);
|
||||
|
||||
@ -47,6 +47,11 @@ class EncodedImageDataExtractor {
|
||||
public:
|
||||
virtual ~EncodedImageDataExtractor() = default;
|
||||
|
||||
// Invoked by framework before any image will come to the extractor.
|
||||
// |expected_receivers_count| is the expected amount of receivers for each
|
||||
// encoded image.
|
||||
virtual void Start(int expected_receivers_count) = 0;
|
||||
|
||||
// Returns encoded image id, extracted from payload and also encoded image
|
||||
// with its original payload. For concatenated spatial layers it should be the
|
||||
// same id. |coding_entity_id| is unique id of decoder or encoder.
|
||||
|
||||
@ -95,16 +95,17 @@ EncodedImageExtractionResult SingleProcessEncodedImageDataInjector::ExtractData(
|
||||
{
|
||||
MutexLock lock(&lock_);
|
||||
auto ext_vector_it = extraction_cache_.find(next_id);
|
||||
// TODO(titovartem) add support for receiving single frame multiple times
|
||||
// when in simulcast key frame for another spatial stream can be received.
|
||||
RTC_CHECK(ext_vector_it != extraction_cache_.end())
|
||||
<< "Unknown frame_id=" << next_id;
|
||||
|
||||
auto info_it = ext_vector_it->second.infos.find(sub_id);
|
||||
RTC_CHECK(info_it != ext_vector_it->second.infos.end())
|
||||
<< "Unknown sub_id=" << sub_id << " for frame_id=" << next_id;
|
||||
info_it->second.received_count++;
|
||||
info = info_it->second;
|
||||
ext_vector_it->second.infos.erase(info_it);
|
||||
if (info.received_count == expected_receivers_count_) {
|
||||
ext_vector_it->second.infos.erase(info_it);
|
||||
}
|
||||
}
|
||||
// We need to discard encoded image only if all concatenated encoded images
|
||||
// have to be discarded.
|
||||
|
||||
@ -50,6 +50,11 @@ class SingleProcessEncodedImageDataInjector : public EncodedImageDataInjector,
|
||||
bool discard,
|
||||
const EncodedImage& source,
|
||||
int coding_entity_id) override;
|
||||
|
||||
void Start(int expected_receivers_count) override {
|
||||
MutexLock crit(&lock_);
|
||||
expected_receivers_count_ = expected_receivers_count;
|
||||
}
|
||||
EncodedImageExtractionResult ExtractData(const EncodedImage& source,
|
||||
int coding_entity_id) override;
|
||||
|
||||
@ -67,6 +72,8 @@ class SingleProcessEncodedImageDataInjector : public EncodedImageDataInjector,
|
||||
bool discard;
|
||||
// Data from first 3 bytes of origin encoded image's payload.
|
||||
uint8_t origin_data[ExtractionInfo::kUsedBufferSize];
|
||||
// Count of how many times this frame was received.
|
||||
int received_count = 0;
|
||||
};
|
||||
|
||||
struct ExtractionInfoVector {
|
||||
@ -79,6 +86,7 @@ class SingleProcessEncodedImageDataInjector : public EncodedImageDataInjector,
|
||||
};
|
||||
|
||||
Mutex lock_;
|
||||
int expected_receivers_count_ RTC_GUARDED_BY(lock_);
|
||||
// Stores a mapping from frame id to extraction info for spatial layers
|
||||
// for this frame id. There can be a lot of them, because if frame was
|
||||
// dropped we can't clean it up, because we won't receive a signal on
|
||||
|
||||
@ -28,10 +28,9 @@ rtc::Buffer CreateBufferOfSizeNFilledWithValuesFromX(size_t n, uint8_t x) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(SingleProcessEncodedImageDataInjector, InjectExtractDiscardFalse) {
|
||||
SingleProcessEncodedImageDataInjector injector;
|
||||
injector.Start(1);
|
||||
|
||||
rtc::Buffer buffer = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
|
||||
@ -52,6 +51,7 @@ TEST(SingleProcessEncodedImageDataInjector, InjectExtractDiscardFalse) {
|
||||
|
||||
TEST(SingleProcessEncodedImageDataInjector, InjectExtractDiscardTrue) {
|
||||
SingleProcessEncodedImageDataInjector injector;
|
||||
injector.Start(1);
|
||||
|
||||
rtc::Buffer buffer = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
|
||||
@ -69,6 +69,7 @@ TEST(SingleProcessEncodedImageDataInjector, InjectExtractDiscardTrue) {
|
||||
|
||||
TEST(SingleProcessEncodedImageDataInjector, InjectWithUnsetSpatialLayerSizes) {
|
||||
SingleProcessEncodedImageDataInjector injector;
|
||||
injector.Start(1);
|
||||
|
||||
rtc::Buffer buffer = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
|
||||
@ -94,6 +95,7 @@ TEST(SingleProcessEncodedImageDataInjector, InjectWithUnsetSpatialLayerSizes) {
|
||||
|
||||
TEST(SingleProcessEncodedImageDataInjector, InjectWithZeroSpatialLayerSizes) {
|
||||
SingleProcessEncodedImageDataInjector injector;
|
||||
injector.Start(1);
|
||||
|
||||
rtc::Buffer buffer = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
|
||||
@ -122,6 +124,7 @@ TEST(SingleProcessEncodedImageDataInjector, InjectWithZeroSpatialLayerSizes) {
|
||||
|
||||
TEST(SingleProcessEncodedImageDataInjector, Inject3Extract3) {
|
||||
SingleProcessEncodedImageDataInjector injector;
|
||||
injector.Start(1);
|
||||
|
||||
rtc::Buffer buffer1 = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
rtc::Buffer buffer2 = CreateBufferOfSizeNFilledWithValuesFromX(10, 11);
|
||||
@ -171,6 +174,7 @@ TEST(SingleProcessEncodedImageDataInjector, Inject3Extract3) {
|
||||
|
||||
TEST(SingleProcessEncodedImageDataInjector, InjectExtractFromConcatenated) {
|
||||
SingleProcessEncodedImageDataInjector injector;
|
||||
injector.Start(1);
|
||||
|
||||
rtc::Buffer buffer1 = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
rtc::Buffer buffer2 = CreateBufferOfSizeNFilledWithValuesFromX(10, 11);
|
||||
@ -223,6 +227,7 @@ TEST(SingleProcessEncodedImageDataInjector, InjectExtractFromConcatenated) {
|
||||
TEST(SingleProcessEncodedImageDataInjector,
|
||||
InjectExtractFromConcatenatedAllDiscarded) {
|
||||
SingleProcessEncodedImageDataInjector injector;
|
||||
injector.Start(1);
|
||||
|
||||
rtc::Buffer buffer1 = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
rtc::Buffer buffer2 = CreateBufferOfSizeNFilledWithValuesFromX(10, 11);
|
||||
@ -268,5 +273,72 @@ TEST(SingleProcessEncodedImageDataInjector,
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SingleProcessEncodedImageDataInjector, InjectOnceExtractTwice) {
|
||||
SingleProcessEncodedImageDataInjector injector;
|
||||
injector.Start(2);
|
||||
|
||||
rtc::Buffer buffer = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
|
||||
EncodedImage source(buffer.data(), 10, 10);
|
||||
source.SetTimestamp(123456789);
|
||||
|
||||
EncodedImageExtractionResult out =
|
||||
injector.ExtractData(injector.InjectData(/*id=*/512, /*discard=*/false,
|
||||
source, /*coding_entity_id=*/1),
|
||||
/*coding_entity_id=*/2);
|
||||
EXPECT_EQ(out.id, 512);
|
||||
EXPECT_FALSE(out.discard);
|
||||
EXPECT_EQ(out.image.size(), 10ul);
|
||||
EXPECT_EQ(out.image.capacity(), 10ul);
|
||||
EXPECT_EQ(out.image.SpatialLayerFrameSize(0).value_or(0), 0ul);
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
EXPECT_EQ(out.image.data()[i], i + 1);
|
||||
}
|
||||
out =
|
||||
injector.ExtractData(injector.InjectData(/*id=*/512, /*discard=*/false,
|
||||
source, /*coding_entity_id=*/1),
|
||||
2);
|
||||
EXPECT_EQ(out.id, 512);
|
||||
EXPECT_FALSE(out.discard);
|
||||
EXPECT_EQ(out.image.size(), 10ul);
|
||||
EXPECT_EQ(out.image.capacity(), 10ul);
|
||||
EXPECT_EQ(out.image.SpatialLayerFrameSize(0).value_or(0), 0ul);
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
EXPECT_EQ(out.image.data()[i], i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Death tests.
|
||||
// Disabled on Android because death tests misbehave on Android, see
|
||||
// base/test/gtest_util.h.
|
||||
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
||||
EncodedImage DeepCopyEncodedImage(const EncodedImage& source) {
|
||||
EncodedImage copy = source;
|
||||
copy.SetEncodedData(EncodedImageBuffer::Create(source.size()));
|
||||
memcpy(copy.data(), source.data(), source.size());
|
||||
return copy;
|
||||
}
|
||||
|
||||
TEST(SingleProcessEncodedImageDataInjector, InjectOnceExtractMoreThenExpected) {
|
||||
SingleProcessEncodedImageDataInjector injector;
|
||||
injector.Start(2);
|
||||
|
||||
rtc::Buffer buffer = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
|
||||
|
||||
EncodedImage source(buffer.data(), 10, 10);
|
||||
source.SetTimestamp(123456789);
|
||||
|
||||
EncodedImage modified = injector.InjectData(/*id=*/512, /*discard=*/false,
|
||||
source, /*coding_entity_id=*/1);
|
||||
|
||||
injector.ExtractData(DeepCopyEncodedImage(modified), /*coding_entity_id=*/2);
|
||||
injector.ExtractData(DeepCopyEncodedImage(modified), /*coding_entity_id=*/2);
|
||||
EXPECT_DEATH(injector.ExtractData(DeepCopyEncodedImage(modified),
|
||||
/*coding_entity_id=*/2),
|
||||
"Unknown sub_id=0 for frame_id=512");
|
||||
}
|
||||
#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc_pc_e2e
|
||||
} // namespace webrtc
|
||||
|
||||
@ -149,6 +149,7 @@ void VideoQualityAnalyzerInjectionHelper::Start(
|
||||
rtc::ArrayView<const std::string> peer_names,
|
||||
int max_threads_count) {
|
||||
analyzer_->Start(std::move(test_case_name), peer_names, max_threads_count);
|
||||
extractor_->Start(peer_names.size());
|
||||
}
|
||||
|
||||
void VideoQualityAnalyzerInjectionHelper::OnStatsReports(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user