Add support for NV12 frame generation for tests

This can be used in the future to test NV12 video frames with encoders, both
from unittests and from tools like video_loopback.

Tested using video_loopback with generator NV12.

Bug: webrtc:11978
Change-Id: I0d24ae3ebab2267f076703cbda81e99cec465ec8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/185045
Commit-Queue: Evan Shrubsole <eshr@google.com>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32206}
This commit is contained in:
Evan Shrubsole 2020-09-28 10:16:00 +02:00 committed by Commit Bot
parent 111de34102
commit 55c178693c
6 changed files with 27 additions and 2 deletions

View File

@ -32,7 +32,7 @@ class FrameGeneratorInterface {
absl::optional<VideoFrame::UpdateRect> update_rect;
};
enum class OutputType { kI420, kI420A, kI010 };
enum class OutputType { kI420, kI420A, kI010, kNV12 };
virtual ~FrameGeneratorInterface() = default;

View File

@ -60,6 +60,19 @@ rtc::scoped_refptr<NV12Buffer> NV12Buffer::Create(int width,
stride_uv);
}
// static
rtc::scoped_refptr<NV12Buffer> NV12Buffer::Copy(
const I420BufferInterface& i420_buffer) {
rtc::scoped_refptr<NV12Buffer> buffer =
NV12Buffer::Create(i420_buffer.width(), i420_buffer.height());
libyuv::I420ToNV12(
i420_buffer.DataY(), i420_buffer.StrideY(), i420_buffer.DataU(),
i420_buffer.StrideU(), i420_buffer.DataV(), i420_buffer.StrideV(),
buffer->MutableDataY(), buffer->StrideY(), buffer->MutableDataUV(),
buffer->StrideUV(), buffer->width(), buffer->height());
return buffer;
}
rtc::scoped_refptr<I420BufferInterface> NV12Buffer::ToI420() {
rtc::scoped_refptr<I420Buffer> i420_buffer =
I420Buffer::Create(width(), height());

View File

@ -31,6 +31,8 @@ class RTC_EXPORT NV12Buffer : public NV12BufferInterface {
int height,
int stride_y,
int stride_uv);
static rtc::scoped_refptr<NV12Buffer> Copy(
const I420BufferInterface& i420_buffer);
rtc::scoped_refptr<I420BufferInterface> ToI420() override;

View File

@ -53,6 +53,7 @@ rtc_library("frame_generator_impl") {
"../api/video:video_frame",
"../api/video:video_frame_i010",
"../api/video:video_frame_i420",
"../api/video:video_frame_nv12",
"../api/video:video_rtp_headers",
"../api/video_codecs:video_codecs_api",
"../common_video",

View File

@ -16,6 +16,7 @@
#include <memory>
#include "api/video/i010_buffer.h"
#include "api/video/nv12_buffer.h"
#include "api/video/video_rotation.h"
#include "common_video/include/video_frame_buffer.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
@ -70,7 +71,8 @@ FrameGeneratorInterface::VideoFrameData SquareGenerator::NextFrame() {
rtc::scoped_refptr<VideoFrameBuffer> buffer = nullptr;
switch (type_) {
case OutputType::kI420:
case OutputType::kI010: {
case OutputType::kI010:
case OutputType::kNV12: {
buffer = CreateI420Buffer(width_, height_);
break;
}
@ -96,6 +98,8 @@ FrameGeneratorInterface::VideoFrameData SquareGenerator::NextFrame() {
if (type_ == OutputType::kI010) {
buffer = I010Buffer::Copy(*buffer->ToI420());
} else if (type_ == OutputType::kNV12) {
buffer = NV12Buffer::Copy(*buffer->ToI420());
}
return VideoFrameData(buffer, absl::nullopt);

View File

@ -1104,6 +1104,11 @@ void VideoQualityTest::CreateCapturers() {
static_cast<int>(params_.video[video_idx].width),
static_cast<int>(params_.video[video_idx].height),
test::FrameGeneratorInterface::OutputType::kI010, absl::nullopt);
} else if (params_.video[video_idx].clip_path == "GeneratorNV12") {
frame_generator = test::CreateSquareFrameGenerator(
static_cast<int>(params_.video[video_idx].width),
static_cast<int>(params_.video[video_idx].height),
test::FrameGeneratorInterface::OutputType::kNV12, absl::nullopt);
} else if (params_.video[video_idx].clip_path.empty()) {
video_sources_[video_idx] = test::CreateVideoCapturer(
params_.video[video_idx].width, params_.video[video_idx].height,