Skip to content

Commit

Permalink
Refactor video analyzer injection helper
Browse files Browse the repository at this point in the history
Separate renderer part into steps and make it easier to add more steps
as separate interceptors.

Bug: webrtc:10138
Change-Id: I667fc85d0da4fb59090e69caa4c32bd4afc3bd05
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/151645
Commit-Queue: Artem Titov <[email protected]>
Reviewed-by: Ilya Nikolaevskiy <[email protected]>
Reviewed-by: Mirko Bonadei <[email protected]>
Cr-Commit-Position: refs/heads/master@{#29082}
  • Loading branch information
Artem Titov authored and Commit Bot committed Sep 5, 2019
1 parent d4e6904 commit bbbae42
Showing 1 changed file with 58 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,63 @@ namespace webrtc_pc_e2e {

namespace {

class VideoFrameInterceptor {
public:
virtual ~VideoFrameInterceptor() = default;

// Performs desired actions with video frame. It may change video frame.
virtual void OnVideoFrame(VideoFrame* frame) = 0;
};

class VideoAnalyzerCapturingInterceptor : public VideoFrameInterceptor {
public:
VideoAnalyzerCapturingInterceptor(std::string stream_label,
VideoQualityAnalyzerInterface* analyzer)
: stream_label_(std::move(stream_label)), analyzer_(analyzer) {
RTC_DCHECK(analyzer_);
}
~VideoAnalyzerCapturingInterceptor() override = default;

void OnVideoFrame(VideoFrame* frame) override {
uint16_t frame_id = analyzer_->OnFrameCaptured(stream_label_, *frame);
frame->set_id(frame_id);
}

private:
const std::string stream_label_;
VideoQualityAnalyzerInterface* analyzer_;
};

class VideoWriterInterceptor : public VideoFrameInterceptor {
public:
VideoWriterInterceptor(test::VideoFrameWriter* video_writer)
: video_writer_(video_writer) {}
~VideoWriterInterceptor() override = default;

void OnVideoFrame(VideoFrame* frame) override {
bool result = video_writer_->WriteFrame(*frame);
RTC_CHECK(result) << "Failed to write frame";
}

private:
test::VideoFrameWriter* video_writer_;
};

// 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 test::FrameGenerator {
public:
InterceptingFrameGenerator(std::string stream_label,
std::unique_ptr<test::FrameGenerator> delegate,
VideoQualityAnalyzerInterface* analyzer,
test::VideoFrameWriter* video_writer)
: stream_label_(std::move(stream_label)),
delegate_(std::move(delegate)),
analyzer_(analyzer),
video_writer_(video_writer) {
RTC_DCHECK(analyzer_);
}
InterceptingFrameGenerator(
std::unique_ptr<test::FrameGenerator> delegate,
std::vector<std::unique_ptr<VideoFrameInterceptor>> interceptors)
: delegate_(std::move(delegate)),
interceptors_(std::move(interceptors)) {}
~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";
for (auto& interceptor : interceptors_) {
interceptor->OnVideoFrame(frame);
}
return frame;
}
Expand All @@ -54,10 +88,8 @@ class InterceptingFrameGenerator : public test::FrameGenerator {
}

private:
std::string stream_label_;
std::unique_ptr<test::FrameGenerator> delegate_;
VideoQualityAnalyzerInterface* analyzer_;
test::VideoFrameWriter* video_writer_;
std::vector<std::unique_ptr<VideoFrameInterceptor>> interceptors_;
};

// Implements the video sink, that forwards rendered frames to the video quality
Expand Down Expand Up @@ -130,8 +162,14 @@ VideoQualityAnalyzerInjectionHelper::WrapFrameGenerator(
std::string stream_label,
std::unique_ptr<test::FrameGenerator> delegate,
test::VideoFrameWriter* writer) const {
return absl::make_unique<InterceptingFrameGenerator>(
std::move(stream_label), std::move(delegate), analyzer_.get(), writer);
std::vector<std::unique_ptr<VideoFrameInterceptor>> interceptors;
interceptors.push_back(absl::make_unique<VideoAnalyzerCapturingInterceptor>(
std::move(stream_label), analyzer_.get()));
if (writer) {
interceptors.push_back(absl::make_unique<VideoWriterInterceptor>(writer));
}
return absl::make_unique<InterceptingFrameGenerator>(std::move(delegate),
std::move(interceptors));
}

std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>
Expand Down

0 comments on commit bbbae42

Please sign in to comment.