Introduce VideoQualityAnalyzerInjectionHelper.
VideoQualityAnalyzerInjectionHelper will be used to provide all required entities to inject video quality analyzer into peer connection pipeline. Bug: webrtc:10138 Change-Id: Iea7cf453311d809619839d5cf94b78a020ce9167 Reviewed-on: https://webrtc-review.googlesource.com/c/119642 Commit-Queue: Artem Titov <titovartem@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Peter Slatala <psla@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26395}
This commit is contained in:
parent
3ea55d56eb
commit
f50c6c2fb4
@ -467,6 +467,10 @@ bool FrameForwarder::has_sinks() const {
|
||||
return sink_ != nullptr;
|
||||
}
|
||||
|
||||
void FrameGenerator::ChangeResolution(size_t width, size_t height) {
|
||||
RTC_NOTREACHED();
|
||||
}
|
||||
|
||||
std::unique_ptr<FrameGenerator> FrameGenerator::CreateSquareGenerator(
|
||||
int width,
|
||||
int height,
|
||||
|
||||
@ -29,7 +29,7 @@ namespace test {
|
||||
class FrameForwarder : public rtc::VideoSourceInterface<VideoFrame> {
|
||||
public:
|
||||
FrameForwarder();
|
||||
virtual ~FrameForwarder();
|
||||
~FrameForwarder() override;
|
||||
// Forwards |video_frame| to the registered |sink_|.
|
||||
virtual void IncomingCapturedFrame(const VideoFrame& video_frame);
|
||||
rtc::VideoSinkWants sink_wants() const;
|
||||
@ -56,9 +56,7 @@ class FrameGenerator {
|
||||
virtual VideoFrame* NextFrame() = 0;
|
||||
|
||||
// Change the capture resolution.
|
||||
virtual void ChangeResolution(size_t width, size_t height) {
|
||||
RTC_NOTREACHED();
|
||||
}
|
||||
virtual void ChangeResolution(size_t width, size_t height);
|
||||
|
||||
enum class OutputType { I420, I420A, I010 };
|
||||
|
||||
|
||||
@ -20,6 +20,9 @@ group("e2e") {
|
||||
":quality_analyzing_video_encoder",
|
||||
":single_process_encoded_image_id_injector",
|
||||
]
|
||||
if (rtc_include_tests) {
|
||||
deps += [ ":video_quality_analyzer_injection_helper" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (rtc_include_tests) {
|
||||
@ -127,6 +130,27 @@ rtc_source_set("quality_analyzing_video_encoder") {
|
||||
}
|
||||
|
||||
if (rtc_include_tests) {
|
||||
rtc_source_set("video_quality_analyzer_injection_helper") {
|
||||
visibility = [ "*" ]
|
||||
testonly = true
|
||||
sources = [
|
||||
"analyzer/video/video_quality_analyzer_injection_helper.cc",
|
||||
"analyzer/video/video_quality_analyzer_injection_helper.h",
|
||||
]
|
||||
deps = [
|
||||
":encoded_image_id_injector_api",
|
||||
":id_generator",
|
||||
":quality_analyzing_video_decoder",
|
||||
":quality_analyzing_video_encoder",
|
||||
"../../../api/video:video_frame",
|
||||
"../../../api/video_codecs:video_codecs_api",
|
||||
"../../../test:video_test_common",
|
||||
"../../../test:video_test_support",
|
||||
"api:video_quality_analyzer_api",
|
||||
"//third_party/abseil-cpp/absl/memory:memory",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("single_process_encoded_image_id_injector_unittest") {
|
||||
testonly = true
|
||||
sources = [
|
||||
|
||||
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h"
|
||||
#include "test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
namespace {
|
||||
|
||||
// Intercepts generated frames and passes them also to video quality analyzer
|
||||
// and into video frame writer, if the last one is provided.
|
||||
class InterceptingFrameGenerator : public FrameGenerator {
|
||||
public:
|
||||
InterceptingFrameGenerator(std::string stream_label,
|
||||
std::unique_ptr<FrameGenerator> delegate,
|
||||
VideoQualityAnalyzerInterface* analyzer,
|
||||
VideoFrameWriter* video_writer)
|
||||
: stream_label_(std::move(stream_label)),
|
||||
delegate_(std::move(delegate)),
|
||||
analyzer_(analyzer),
|
||||
video_writer_(video_writer) {
|
||||
RTC_DCHECK(analyzer_);
|
||||
}
|
||||
~InterceptingFrameGenerator() override = default;
|
||||
|
||||
VideoFrame* NextFrame() override {
|
||||
VideoFrame* frame = delegate_->NextFrame();
|
||||
uint16_t frame_id = analyzer_->OnFrameCaptured(stream_label_, *frame);
|
||||
frame->set_id(frame_id);
|
||||
if (video_writer_) {
|
||||
bool result = video_writer_->WriteFrame(*frame);
|
||||
RTC_CHECK(result) << "Failed to write frame";
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
void ChangeResolution(size_t width, size_t height) override {
|
||||
delegate_->ChangeResolution(width, height);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string stream_label_;
|
||||
std::unique_ptr<FrameGenerator> delegate_;
|
||||
VideoQualityAnalyzerInterface* analyzer_;
|
||||
VideoFrameWriter* video_writer_;
|
||||
};
|
||||
|
||||
// Implements the video sink, that forwards rendered frames to the video quality
|
||||
// analyzer and to the video frame writer, if the last one is provided.
|
||||
class AnalyzingVideoSink : public rtc::VideoSinkInterface<VideoFrame> {
|
||||
public:
|
||||
AnalyzingVideoSink(VideoQualityAnalyzerInterface* analyzer,
|
||||
VideoFrameWriter* video_writer)
|
||||
: analyzer_(analyzer), video_writer_(video_writer) {
|
||||
RTC_DCHECK(analyzer_);
|
||||
}
|
||||
~AnalyzingVideoSink() override = default;
|
||||
|
||||
void OnFrame(const VideoFrame& frame) override {
|
||||
analyzer_->OnFrameRendered(frame);
|
||||
if (video_writer_) {
|
||||
bool result = video_writer_->WriteFrame(frame);
|
||||
RTC_CHECK(result) << "Failed to write frame";
|
||||
}
|
||||
}
|
||||
void OnDiscardedFrame() override {}
|
||||
|
||||
private:
|
||||
VideoQualityAnalyzerInterface* analyzer_;
|
||||
VideoFrameWriter* video_writer_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
VideoQualityAnalyzerInjectionHelper::VideoQualityAnalyzerInjectionHelper(
|
||||
std::unique_ptr<VideoQualityAnalyzerInterface> analyzer,
|
||||
EncodedImageIdInjector* injector,
|
||||
EncodedImageIdExtractor* extractor)
|
||||
: analyzer_(std::move(analyzer)),
|
||||
injector_(injector),
|
||||
extractor_(extractor),
|
||||
encoding_entities_id_generator_(absl::make_unique<IntIdGenerator>(1)) {
|
||||
RTC_DCHECK(injector_);
|
||||
RTC_DCHECK(extractor_);
|
||||
}
|
||||
VideoQualityAnalyzerInjectionHelper::~VideoQualityAnalyzerInjectionHelper() =
|
||||
default;
|
||||
|
||||
std::unique_ptr<VideoEncoderFactory>
|
||||
VideoQualityAnalyzerInjectionHelper::WrapVideoEncoderFactory(
|
||||
std::unique_ptr<VideoEncoderFactory> delegate) const {
|
||||
return absl::make_unique<QualityAnalyzingVideoEncoderFactory>(
|
||||
std::move(delegate), encoding_entities_id_generator_.get(), injector_,
|
||||
analyzer_.get());
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoDecoderFactory>
|
||||
VideoQualityAnalyzerInjectionHelper::WrapVideoDecoderFactory(
|
||||
std::unique_ptr<VideoDecoderFactory> delegate) const {
|
||||
return absl::make_unique<QualityAnalyzingVideoDecoderFactory>(
|
||||
std::move(delegate), encoding_entities_id_generator_.get(), extractor_,
|
||||
analyzer_.get());
|
||||
}
|
||||
|
||||
std::unique_ptr<FrameGenerator>
|
||||
VideoQualityAnalyzerInjectionHelper::WrapFrameGenerator(
|
||||
std::string stream_label,
|
||||
std::unique_ptr<FrameGenerator> delegate,
|
||||
VideoFrameWriter* writer) const {
|
||||
return absl::make_unique<InterceptingFrameGenerator>(
|
||||
std::move(stream_label), std::move(delegate), analyzer_.get(), writer);
|
||||
}
|
||||
|
||||
std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>
|
||||
VideoQualityAnalyzerInjectionHelper::CreateVideoSink(
|
||||
VideoFrameWriter* writer) const {
|
||||
return absl::make_unique<AnalyzingVideoSink>(analyzer_.get(), writer);
|
||||
}
|
||||
|
||||
void VideoQualityAnalyzerInjectionHelper::Stop() {
|
||||
analyzer_->Stop();
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef TEST_PC_E2E_ANALYZER_VIDEO_VIDEO_QUALITY_ANALYZER_INJECTION_HELPER_H_
|
||||
#define TEST_PC_E2E_ANALYZER_VIDEO_VIDEO_QUALITY_ANALYZER_INJECTION_HELPER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "api/video/video_frame.h"
|
||||
#include "api/video/video_sink_interface.h"
|
||||
#include "api/video_codecs/video_decoder_factory.h"
|
||||
#include "api/video_codecs/video_encoder_factory.h"
|
||||
#include "test/frame_generator.h"
|
||||
#include "test/pc/e2e/analyzer/video/encoded_image_id_injector.h"
|
||||
#include "test/pc/e2e/analyzer/video/id_generator.h"
|
||||
#include "test/pc/e2e/api/video_quality_analyzer_interface.h"
|
||||
#include "test/testsupport/video_frame_writer.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
// Provides factory methods for components, that will be used to inject
|
||||
// VideoQualityAnalyzerInterface into PeerConnection pipeline.
|
||||
class VideoQualityAnalyzerInjectionHelper {
|
||||
public:
|
||||
VideoQualityAnalyzerInjectionHelper(
|
||||
std::unique_ptr<VideoQualityAnalyzerInterface> analyzer,
|
||||
EncodedImageIdInjector* injector,
|
||||
EncodedImageIdExtractor* extractor);
|
||||
~VideoQualityAnalyzerInjectionHelper();
|
||||
|
||||
// Wraps video encoder factory to give video quality analyzer access to frames
|
||||
// before encoding and encoded images after.
|
||||
std::unique_ptr<VideoEncoderFactory> WrapVideoEncoderFactory(
|
||||
std::unique_ptr<VideoEncoderFactory> delegate) const;
|
||||
// Wraps video decoder factory to give video quality analyzer access to
|
||||
// received encoded images and frames, that were decoded from them.
|
||||
std::unique_ptr<VideoDecoderFactory> WrapVideoDecoderFactory(
|
||||
std::unique_ptr<VideoDecoderFactory> delegate) const;
|
||||
|
||||
// Wraps frame generator, so video quality analyzer will gain access to the
|
||||
// captured frames. If |writer| in not nullptr, will dump captured frames
|
||||
// with provided writer.
|
||||
std::unique_ptr<FrameGenerator> WrapFrameGenerator(
|
||||
std::string stream_label,
|
||||
std::unique_ptr<FrameGenerator> delegate,
|
||||
VideoFrameWriter* writer) const;
|
||||
// Creates sink, that will allow video quality analyzer to get access to the
|
||||
// rendered frames. If |writer| in not nullptr, will dump rendered frames
|
||||
// with provided writer.
|
||||
std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>> CreateVideoSink(
|
||||
VideoFrameWriter* writer) const;
|
||||
|
||||
// Stops VideoQualityAnalyzerInterface to populate final data and metrics.
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
std::unique_ptr<VideoQualityAnalyzerInterface> analyzer_;
|
||||
EncodedImageIdInjector* injector_;
|
||||
EncodedImageIdExtractor* extractor_;
|
||||
|
||||
std::unique_ptr<IdGenerator<int>> encoding_entities_id_generator_;
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // TEST_PC_E2E_ANALYZER_VIDEO_VIDEO_QUALITY_ANALYZER_INJECTION_HELPER_H_
|
||||
Loading…
x
Reference in New Issue
Block a user