Update I420Buffer to new VideoFrameBuffer interface

This is a follow-up cleanup for CL https://codereview.webrtc.org/2847383002/.

BUG=webrtc:7632
TBR=stefan

Review-Url: https://codereview.webrtc.org/2906053002
Cr-Commit-Position: refs/heads/master@{#18388}
This commit is contained in:
magjed
2017-06-01 10:02:26 -07:00
committed by Commit Bot
parent c757293f15
commit 3f075498a3
20 changed files with 143 additions and 122 deletions

View File

@ -77,7 +77,7 @@ rtc::scoped_refptr<I420Buffer> I420Buffer::Create(int width,
// static
rtc::scoped_refptr<I420Buffer> I420Buffer::Copy(
const VideoFrameBuffer& source) {
const I420BufferInterface& source) {
return Copy(source.width(), source.height(),
source.DataY(), source.StrideY(),
source.DataU(), source.StrideU(),
@ -104,7 +104,8 @@ rtc::scoped_refptr<I420Buffer> I420Buffer::Copy(
// static
rtc::scoped_refptr<I420Buffer> I420Buffer::Rotate(
const VideoFrameBuffer& src, VideoRotation rotation) {
const I420BufferInterface& src,
VideoRotation rotation) {
RTC_CHECK(src.DataY());
RTC_CHECK(src.DataU());
RTC_CHECK(src.DataV());
@ -183,12 +184,11 @@ void I420Buffer::SetBlack(I420Buffer* buffer) {
0, 128, 128) == 0);
}
void I420Buffer::CropAndScaleFrom(
const VideoFrameBuffer& src,
int offset_x,
int offset_y,
int crop_width,
int crop_height) {
void I420Buffer::CropAndScaleFrom(const I420BufferInterface& src,
int offset_x,
int offset_y,
int crop_width,
int crop_height) {
RTC_CHECK_LE(crop_width, src.width());
RTC_CHECK_LE(crop_height, src.height());
RTC_CHECK_LE(crop_width + offset_x, src.width());
@ -220,8 +220,7 @@ void I420Buffer::CropAndScaleFrom(
RTC_DCHECK_EQ(res, 0);
}
void I420Buffer::CropAndScaleFrom(
const VideoFrameBuffer& src) {
void I420Buffer::CropAndScaleFrom(const I420BufferInterface& src) {
const int crop_width =
std::min(src.width(), width() * src.height() / height());
const int crop_height =
@ -233,7 +232,7 @@ void I420Buffer::CropAndScaleFrom(
crop_width, crop_height);
}
void I420Buffer::ScaleFrom(const VideoFrameBuffer& src) {
void I420Buffer::ScaleFrom(const I420BufferInterface& src) {
CropAndScaleFrom(src, 0, 0, src.width(), src.height());
}

View File

@ -30,7 +30,11 @@ class I420Buffer : public I420BufferInterface {
int stride_v);
// Create a new buffer and copy the pixel data.
static rtc::scoped_refptr<I420Buffer> Copy(const VideoFrameBuffer& buffer);
static rtc::scoped_refptr<I420Buffer> Copy(const I420BufferInterface& buffer);
// Deprecated.
static rtc::scoped_refptr<I420Buffer> Copy(const VideoFrameBuffer& buffer) {
return Copy(*buffer.GetI420());
}
static rtc::scoped_refptr<I420Buffer> Copy(
int width, int height,
@ -39,8 +43,13 @@ class I420Buffer : public I420BufferInterface {
const uint8_t* data_v, int stride_v);
// Returns a rotated copy of |src|.
static rtc::scoped_refptr<I420Buffer> Rotate(const VideoFrameBuffer& src,
static rtc::scoped_refptr<I420Buffer> Rotate(const I420BufferInterface& src,
VideoRotation rotation);
// Deprecated.
static rtc::scoped_refptr<I420Buffer> Rotate(const VideoFrameBuffer& src,
VideoRotation rotation) {
return Rotate(*src.GetI420(), rotation);
}
// Sets the buffer to all black.
static void SetBlack(I420Buffer* buffer);
@ -69,7 +78,7 @@ class I420Buffer : public I420BufferInterface {
// Scale the cropped area of |src| to the size of |this| buffer, and
// write the result into |this|.
void CropAndScaleFrom(const VideoFrameBuffer& src,
void CropAndScaleFrom(const I420BufferInterface& src,
int offset_x,
int offset_y,
int crop_width,
@ -77,10 +86,10 @@ class I420Buffer : public I420BufferInterface {
// The common case of a center crop, when needed to adjust the
// aspect ratio without distorting the image.
void CropAndScaleFrom(const VideoFrameBuffer& src);
void CropAndScaleFrom(const I420BufferInterface& src);
// Scale all of |src| to the size of |this| buffer, with no cropping.
void ScaleFrom(const VideoFrameBuffer& src);
void ScaleFrom(const I420BufferInterface& src);
protected:
I420Buffer(int width, int height);

View File

@ -98,7 +98,7 @@ class VideoFrame {
// TODO(nisse): Deprecated.
// Return true if the frame is stored in a texture.
bool is_texture() const {
return video_frame_buffer()->native_handle() != nullptr;
return video_frame_buffer()->type() == VideoFrameBuffer::Type::kNative;
}
private:

View File

@ -26,7 +26,7 @@ namespace {
// VideoFrameBuffer) vs ToI420 (returns I420BufferInterface).
class I420InterfaceAdapter : public I420BufferInterface {
public:
explicit I420InterfaceAdapter(rtc::scoped_refptr<VideoFrameBuffer> buffer)
explicit I420InterfaceAdapter(const VideoFrameBuffer* buffer)
: buffer_(buffer) {}
int width() const override { return buffer_->width(); }
@ -41,7 +41,7 @@ class I420InterfaceAdapter : public I420BufferInterface {
int StrideV() const override { return buffer_->StrideV(); }
private:
rtc::scoped_refptr<VideoFrameBuffer> buffer_;
rtc::scoped_refptr<const VideoFrameBuffer> buffer_;
};
} // namespace
@ -54,28 +54,28 @@ VideoFrameBuffer::Type VideoFrameBuffer::type() const {
}
const uint8_t* VideoFrameBuffer::DataY() const {
return const_cast<VideoFrameBuffer*>(this)->GetI420()->DataY();
return GetI420()->DataY();
}
const uint8_t* VideoFrameBuffer::DataU() const {
return const_cast<VideoFrameBuffer*>(this)->GetI420()->DataU();
return GetI420()->DataU();
}
const uint8_t* VideoFrameBuffer::DataV() const {
return const_cast<VideoFrameBuffer*>(this)->GetI420()->DataV();
return GetI420()->DataV();
}
// Returns the number of bytes between successive rows for a given plane.
int VideoFrameBuffer::StrideY() const {
return const_cast<VideoFrameBuffer*>(this)->GetI420()->StrideY();
return GetI420()->StrideY();
}
int VideoFrameBuffer::StrideU() const {
return const_cast<VideoFrameBuffer*>(this)->GetI420()->StrideU();
return GetI420()->StrideU();
}
int VideoFrameBuffer::StrideV() const {
return const_cast<VideoFrameBuffer*>(this)->GetI420()->StrideV();
return GetI420()->StrideV();
}
void* VideoFrameBuffer::native_handle() const {
@ -98,11 +98,24 @@ rtc::scoped_refptr<I420BufferInterface> VideoFrameBuffer::GetI420() {
return new rtc::RefCountedObject<I420InterfaceAdapter>(this);
}
rtc::scoped_refptr<I444BufferInterface> VideoFrameBuffer::GetI444() {
rtc::scoped_refptr<const I420BufferInterface> VideoFrameBuffer::GetI420()
const {
RTC_CHECK(type() == Type::kI420);
// TODO(magjed): static_cast to I420BufferInterface instead once external
// clients are updated.
return new rtc::RefCountedObject<I420InterfaceAdapter>(this);
}
I444BufferInterface* VideoFrameBuffer::GetI444() {
RTC_CHECK(type() == Type::kI444);
return static_cast<I444BufferInterface*>(this);
}
const I444BufferInterface* VideoFrameBuffer::GetI444() const {
RTC_CHECK(type() == Type::kI444);
return static_cast<const I444BufferInterface*>(this);
}
VideoFrameBuffer::Type I420BufferInterface::type() const {
return Type::kI420;
}

View File

@ -63,8 +63,12 @@ class VideoFrameBuffer : public rtc::RefCountInterface {
// These functions should only be called if type() is of the correct type.
// Calling with a different type will result in a crash.
// TODO(magjed): Return raw pointers for GetI420 once deprecated interface is
// removed.
rtc::scoped_refptr<I420BufferInterface> GetI420();
rtc::scoped_refptr<I444BufferInterface> GetI444();
rtc::scoped_refptr<const I420BufferInterface> GetI420() const;
I444BufferInterface* GetI444();
const I444BufferInterface* GetI444() const;
// Deprecated - use ToI420() first instead.
// Returns pointer to the pixel data for a given plane. The memory is owned by

View File

@ -17,7 +17,7 @@ namespace webrtc {
TEST(TestI420BufferPool, SimpleFrameReuse) {
I420BufferPool pool;
rtc::scoped_refptr<VideoFrameBuffer> buffer = pool.CreateBuffer(16, 16);
rtc::scoped_refptr<I420BufferInterface> buffer = pool.CreateBuffer(16, 16);
EXPECT_EQ(16, buffer->width());
EXPECT_EQ(16, buffer->height());
// Extract non-refcounted pointers for testing.
@ -37,7 +37,7 @@ TEST(TestI420BufferPool, SimpleFrameReuse) {
TEST(TestI420BufferPool, FailToReuse) {
I420BufferPool pool;
rtc::scoped_refptr<VideoFrameBuffer> buffer = pool.CreateBuffer(16, 16);
rtc::scoped_refptr<I420BufferInterface> buffer = pool.CreateBuffer(16, 16);
// Extract non-refcounted pointers for testing.
const uint8_t* u_ptr = buffer->DataU();
const uint8_t* v_ptr = buffer->DataV();
@ -65,7 +65,7 @@ TEST(TestI420BufferPool, FrameValidAfterPoolDestruction) {
TEST(TestI420BufferPool, MaxNumberOfBuffers) {
I420BufferPool pool(false, 1);
rtc::scoped_refptr<VideoFrameBuffer> buffer1 = pool.CreateBuffer(16, 16);
rtc::scoped_refptr<I420BufferInterface> buffer1 = pool.CreateBuffer(16, 16);
EXPECT_NE(nullptr, buffer1.get());
EXPECT_EQ(nullptr, pool.CreateBuffer(16, 16).get());
}

View File

@ -33,8 +33,8 @@ rtc::scoped_refptr<I420Buffer> CreateGradient(int width, int height) {
128 * (x * height + y * width) / (width * height);
}
}
int chroma_width = (width + 1) / 2;
int chroma_height = (height + 1) / 2;
int chroma_width = buffer->ChromaWidth();
int chroma_height = buffer->ChromaHeight();
for (int x = 0; x < chroma_width; x++) {
for (int y = 0; y < chroma_height; y++) {
buffer->MutableDataU()[x + y * chroma_width] =
@ -49,7 +49,7 @@ rtc::scoped_refptr<I420Buffer> CreateGradient(int width, int height) {
// The offsets and sizes describe the rectangle extracted from the
// original (gradient) frame, in relative coordinates where the
// original frame correspond to the unit square, 0.0 <= x, y < 1.0.
void CheckCrop(const webrtc::VideoFrameBuffer& frame,
void CheckCrop(const webrtc::I420BufferInterface& frame,
double offset_x,
double offset_y,
double rel_width,
@ -78,8 +78,10 @@ void CheckCrop(const webrtc::VideoFrameBuffer& frame,
}
}
void CheckRotate(int width, int height, webrtc::VideoRotation rotation,
const webrtc::VideoFrameBuffer& rotated) {
void CheckRotate(int width,
int height,
webrtc::VideoRotation rotation,
const webrtc::I420BufferInterface& rotated) {
int rotated_width = width;
int rotated_height = height;
@ -160,12 +162,13 @@ TEST(TestVideoFrame, ShallowCopy) {
VideoFrame frame2(frame1);
EXPECT_EQ(frame1.video_frame_buffer(), frame2.video_frame_buffer());
EXPECT_EQ(frame1.video_frame_buffer()->DataY(),
frame2.video_frame_buffer()->DataY());
EXPECT_EQ(frame1.video_frame_buffer()->DataU(),
frame2.video_frame_buffer()->DataU());
EXPECT_EQ(frame1.video_frame_buffer()->DataV(),
frame2.video_frame_buffer()->DataV());
rtc::scoped_refptr<I420BufferInterface> yuv1 =
frame1.video_frame_buffer()->GetI420();
rtc::scoped_refptr<I420BufferInterface> yuv2 =
frame2.video_frame_buffer()->GetI420();
EXPECT_EQ(yuv1->DataY(), yuv2->DataY());
EXPECT_EQ(yuv1->DataU(), yuv2->DataU());
EXPECT_EQ(yuv1->DataV(), yuv2->DataV());
EXPECT_EQ(frame2.timestamp(), frame1.timestamp());
EXPECT_EQ(frame2.ntp_time_ms(), frame1.ntp_time_ms());
@ -280,8 +283,8 @@ class TestI420BufferRotate
: public ::testing::TestWithParam<webrtc::VideoRotation> {};
TEST_P(TestI420BufferRotate, Rotates) {
rtc::scoped_refptr<VideoFrameBuffer> buffer = CreateGradient(640, 480);
rtc::scoped_refptr<VideoFrameBuffer> rotated_buffer =
rtc::scoped_refptr<I420BufferInterface> buffer = CreateGradient(640, 480);
rtc::scoped_refptr<I420BufferInterface> rotated_buffer =
I420Buffer::Rotate(*buffer, GetParam());
CheckRotate(640, 480, GetParam(), *rotated_buffer);
}

View File

@ -50,9 +50,9 @@ size_t CalcBufferSize(VideoType type, int width, int height);
// already open for writing.
// Return value: 0 if OK, < 0 otherwise.
int PrintVideoFrame(const VideoFrame& frame, FILE* file);
int PrintVideoFrame(const VideoFrameBuffer& frame, FILE* file);
int PrintVideoFrame(const I420BufferInterface& frame, FILE* file);
// Extract buffer from VideoFrame or VideoFrameBuffer (consecutive
// Extract buffer from VideoFrame or I420BufferInterface (consecutive
// planes, no stride)
// Input:
// - frame : Reference to video frame.
@ -60,7 +60,7 @@ int PrintVideoFrame(const VideoFrameBuffer& frame, FILE* file);
// insufficient, an error will be returned.
// - buffer : Pointer to buffer
// Return value: length of buffer if OK, < 0 otherwise.
int ExtractBuffer(const rtc::scoped_refptr<VideoFrameBuffer>& input_frame,
int ExtractBuffer(const rtc::scoped_refptr<I420BufferInterface>& input_frame,
size_t size,
uint8_t* buffer);
int ExtractBuffer(const VideoFrame& input_frame, size_t size, uint8_t* buffer);
@ -108,13 +108,13 @@ int ConvertFromI420(const VideoFrame& src_frame,
// Compute PSNR for an I420 frame (all planes).
// Returns the PSNR in decibel, to a maximum of kInfinitePSNR.
double I420PSNR(const VideoFrame* ref_frame, const VideoFrame* test_frame);
double I420PSNR(const VideoFrameBuffer& ref_buffer,
const VideoFrameBuffer& test_buffer);
double I420PSNR(const I420BufferInterface& ref_buffer,
const I420BufferInterface& test_buffer);
// Compute SSIM for an I420 frame (all planes).
double I420SSIM(const VideoFrame* ref_frame, const VideoFrame* test_frame);
double I420SSIM(const VideoFrameBuffer& ref_buffer,
const VideoFrameBuffer& test_buffer);
double I420SSIM(const I420BufferInterface& ref_buffer,
const I420BufferInterface& test_buffer);
// Helper function for scaling NV12 to NV12.
void NV12Scale(std::vector<uint8_t>* tmp_buffer,

View File

@ -62,7 +62,7 @@ void TestLibYuv::SetUp() {
ASSERT_TRUE(source_file_ != NULL) << "Cannot read file: "<<
input_file_name << "\n";
rtc::scoped_refptr<VideoFrameBuffer> buffer(
rtc::scoped_refptr<I420BufferInterface> buffer(
test::ReadI420Buffer(width_, height_, source_file_));
orig_frame_.reset(new VideoFrame(buffer, kVideoRotation_0, 0));
@ -89,8 +89,8 @@ TEST_F(TestLibYuv, ConvertTest) {
double psnr = 0.0;
rtc::scoped_refptr<I420Buffer> res_i420_buffer = I420Buffer::Create(
width_, height_, width_, (width_ + 1) / 2, (width_ + 1) / 2);
rtc::scoped_refptr<I420Buffer> res_i420_buffer =
I420Buffer::Create(width_, height_);
printf("\nConvert #%d I420 <-> I420 \n", j);
std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]);
@ -103,7 +103,8 @@ TEST_F(TestLibYuv, ConvertTest) {
if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) {
return;
}
psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer);
psnr =
I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
EXPECT_EQ(48.0, psnr);
j++;
@ -125,7 +126,8 @@ TEST_F(TestLibYuv, ConvertTest) {
if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) {
return;
}
psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer);
psnr =
I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
// Optimization Speed- quality trade-off => 45 dB only (platform dependant).
EXPECT_GT(ceil(psnr), 44);
@ -138,7 +140,8 @@ TEST_F(TestLibYuv, ConvertTest) {
EXPECT_EQ(0,
ConvertToI420(VideoType::kUYVY, out_uyvy_buffer.get(), 0, 0, width_,
height_, 0, kVideoRotation_0, res_i420_buffer.get()));
psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer);
psnr =
I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
EXPECT_EQ(48.0, psnr);
if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) {
return;
@ -158,7 +161,8 @@ TEST_F(TestLibYuv, ConvertTest) {
return;
}
psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer);
psnr =
I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
EXPECT_EQ(48.0, psnr);
printf("\nConvert #%d I420 <-> RGB565\n", j);
@ -175,7 +179,8 @@ TEST_F(TestLibYuv, ConvertTest) {
}
j++;
psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer);
psnr =
I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
// TODO(leozwang) Investigate the right psnr should be set for I420ToRGB565,
// Another example is I420ToRGB24, the psnr is 44
// TODO(mikhal): Add psnr for RGB565, 1555, 4444, convert to ARGB.
@ -195,7 +200,8 @@ TEST_F(TestLibYuv, ConvertTest) {
return;
}
psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer);
psnr =
I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
// TODO(leozwang) Investigate the right psnr should be set for
// I420ToARGB8888,
EXPECT_GT(ceil(psnr), 42);
@ -228,7 +234,8 @@ TEST_F(TestLibYuv, ConvertAlignedFrame) {
if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) {
return;
}
psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer);
psnr =
I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
EXPECT_EQ(48.0, psnr);
}
@ -241,7 +248,8 @@ TEST_F(TestLibYuv, RotateTest) {
int stride_uv;
// Assume compact layout, no padding.
const uint8_t *orig_buffer = orig_frame_->video_frame_buffer()->DataY();
const uint8_t* orig_buffer =
orig_frame_->video_frame_buffer()->GetI420()->DataY();
Calc16ByteAlignedStride(rotated_width, &stride_y, &stride_uv);
rtc::scoped_refptr<I420Buffer> rotated_res_i420_buffer = I420Buffer::Create(
@ -252,8 +260,7 @@ TEST_F(TestLibYuv, RotateTest) {
EXPECT_EQ(
0, ConvertToI420(VideoType::kI420, orig_buffer, 0, 0, width_, height_, 0,
kVideoRotation_270, rotated_res_i420_buffer.get()));
rotated_res_i420_buffer = I420Buffer::Create(
width_, height_, width_, (width_ + 1) / 2, (width_ + 1) / 2);
rotated_res_i420_buffer = I420Buffer::Create(width_, height_);
EXPECT_EQ(
0, ConvertToI420(VideoType::kI420, orig_buffer, 0, 0, width_, height_, 0,
kVideoRotation_180, rotated_res_i420_buffer.get()));

View File

@ -70,11 +70,11 @@ static int PrintPlane(const uint8_t* buf,
}
// TODO(nisse): Belongs with the test code?
int PrintVideoFrame(const VideoFrameBuffer& frame, FILE* file) {
int PrintVideoFrame(const I420BufferInterface& frame, FILE* file) {
int width = frame.width();
int height = frame.height();
int chroma_width = (width + 1) / 2;
int chroma_height = (height + 1) / 2;
int chroma_width = frame.ChromaWidth();
int chroma_height = frame.ChromaHeight();
if (PrintPlane(frame.DataY(), width, height,
frame.StrideY(), file) < 0) {
@ -94,10 +94,10 @@ int PrintVideoFrame(const VideoFrameBuffer& frame, FILE* file) {
}
int PrintVideoFrame(const VideoFrame& frame, FILE* file) {
return PrintVideoFrame(*frame.video_frame_buffer(), file);
return PrintVideoFrame(*frame.video_frame_buffer()->ToI420(), file);
}
int ExtractBuffer(const rtc::scoped_refptr<VideoFrameBuffer>& input_frame,
int ExtractBuffer(const rtc::scoped_refptr<I420BufferInterface>& input_frame,
size_t size,
uint8_t* buffer) {
RTC_DCHECK(buffer);
@ -110,8 +110,8 @@ int ExtractBuffer(const rtc::scoped_refptr<VideoFrameBuffer>& input_frame,
return -1;
}
int chroma_width = (width + 1) / 2;
int chroma_height = (height + 1) / 2;
int chroma_width = input_frame->ChromaWidth();
int chroma_height = input_frame->ChromaHeight();
libyuv::I420Copy(input_frame->DataY(),
input_frame->StrideY(),
@ -129,7 +129,8 @@ int ExtractBuffer(const rtc::scoped_refptr<VideoFrameBuffer>& input_frame,
}
int ExtractBuffer(const VideoFrame& input_frame, size_t size, uint8_t* buffer) {
return ExtractBuffer(input_frame.video_frame_buffer(), size, buffer);
return ExtractBuffer(input_frame.video_frame_buffer()->ToI420(), size,
buffer);
}
int ConvertNV12ToRGB565(const uint8_t* src_frame,
@ -240,21 +241,18 @@ int ConvertFromI420(const VideoFrame& src_frame,
VideoType dst_video_type,
int dst_sample_size,
uint8_t* dst_frame) {
rtc::scoped_refptr<I420BufferInterface> i420_buffer =
src_frame.video_frame_buffer()->ToI420();
return libyuv::ConvertFromI420(
src_frame.video_frame_buffer()->DataY(),
src_frame.video_frame_buffer()->StrideY(),
src_frame.video_frame_buffer()->DataU(),
src_frame.video_frame_buffer()->StrideU(),
src_frame.video_frame_buffer()->DataV(),
src_frame.video_frame_buffer()->StrideV(),
dst_frame, dst_sample_size,
src_frame.width(), src_frame.height(),
i420_buffer->DataY(), i420_buffer->StrideY(), i420_buffer->DataU(),
i420_buffer->StrideU(), i420_buffer->DataV(), i420_buffer->StrideV(),
dst_frame, dst_sample_size, src_frame.width(), src_frame.height(),
ConvertVideoType(dst_video_type));
}
// Compute PSNR for an I420 frame (all planes). Can upscale test frame.
double I420PSNR(const VideoFrameBuffer& ref_buffer,
const VideoFrameBuffer& test_buffer) {
double I420PSNR(const I420BufferInterface& ref_buffer,
const I420BufferInterface& test_buffer) {
RTC_DCHECK_GE(ref_buffer.width(), test_buffer.width());
RTC_DCHECK_GE(ref_buffer.height(), test_buffer.height());
if ((ref_buffer.width() != test_buffer.width()) ||
@ -279,13 +277,13 @@ double I420PSNR(const VideoFrameBuffer& ref_buffer,
double I420PSNR(const VideoFrame* ref_frame, const VideoFrame* test_frame) {
if (!ref_frame || !test_frame)
return -1;
return I420PSNR(*ref_frame->video_frame_buffer(),
*test_frame->video_frame_buffer());
return I420PSNR(*ref_frame->video_frame_buffer()->ToI420(),
*test_frame->video_frame_buffer()->ToI420());
}
// Compute SSIM for an I420 frame (all planes). Can upscale test_buffer.
double I420SSIM(const VideoFrameBuffer& ref_buffer,
const VideoFrameBuffer& test_buffer) {
double I420SSIM(const I420BufferInterface& ref_buffer,
const I420BufferInterface& test_buffer) {
RTC_DCHECK_GE(ref_buffer.width(), test_buffer.width());
RTC_DCHECK_GE(ref_buffer.height(), test_buffer.height());
if ((ref_buffer.width() != test_buffer.width()) ||
@ -305,8 +303,8 @@ double I420SSIM(const VideoFrameBuffer& ref_buffer,
double I420SSIM(const VideoFrame* ref_frame, const VideoFrame* test_frame) {
if (!ref_frame || !test_frame)
return -1;
return I420SSIM(*ref_frame->video_frame_buffer(),
*test_frame->video_frame_buffer());
return I420SSIM(*ref_frame->video_frame_buffer()->ToI420(),
*test_frame->video_frame_buffer()->ToI420());
}
void NV12Scale(std::vector<uint8_t>* tmp_buffer,

View File

@ -523,8 +523,8 @@ void GtkMainWnd::VideoRenderer::OnFrame(
const webrtc::VideoFrame& video_frame) {
gdk_threads_enter();
rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer(
video_frame.video_frame_buffer());
rtc::scoped_refptr<webrtc::I420BufferInterface> buffer(
video_frame.video_frame_buffer()->ToI420());
if (video_frame.rotation() != webrtc::kVideoRotation_0) {
buffer = webrtc::I420Buffer::Rotate(*buffer, video_frame.rotation());
}

View File

@ -606,8 +606,8 @@ void MainWnd::VideoRenderer::OnFrame(
{
AutoLock<VideoRenderer> lock(this);
rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer(
video_frame.video_frame_buffer());
rtc::scoped_refptr<webrtc::I420BufferInterface> buffer(
video_frame.video_frame_buffer()->ToI420());
if (video_frame.rotation() != webrtc::kVideoRotation_0) {
buffer = webrtc::I420Buffer::Rotate(*buffer, video_frame.rotation());
}

View File

@ -45,12 +45,11 @@ void AdaptedVideoTrackSource::OnFrame(const webrtc::VideoFrame& frame) {
true was just added. The VideoBroadcaster enforces
synchronization for us in this case, by not passing the frame on
to sinks which don't want it. */
if (apply_rotation() &&
frame.rotation() != webrtc::kVideoRotation_0 &&
!buffer->native_handle()) {
if (apply_rotation() && frame.rotation() != webrtc::kVideoRotation_0 &&
buffer->type() == webrtc::VideoFrameBuffer::Type::kI420) {
/* Apply pending rotation. */
broadcaster_.OnFrame(webrtc::VideoFrame(
webrtc::I420Buffer::Rotate(*buffer, frame.rotation()),
webrtc::I420Buffer::Rotate(*buffer->GetI420(), frame.rotation()),
webrtc::kVideoRotation_0, frame.timestamp_us()));
} else {
broadcaster_.OnFrame(frame);

View File

@ -205,17 +205,17 @@ void VideoCapturer::OnFrame(const webrtc::VideoFrame& frame,
if (apply_rotation_ && frame.rotation() != webrtc::kVideoRotation_0) {
rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer(
frame.video_frame_buffer());
if (buffer->native_handle()) {
// Sources producing native frames must handle apply_rotation
if (buffer->type() != webrtc::VideoFrameBuffer::Type::kI420) {
// Sources producing non-I420 frames must handle apply_rotation
// themselves. But even if they do, we may occasionally end up
// in this case, for frames in flight at the time
// applied_rotation is set to true. In that case, we just drop
// the frame.
LOG(LS_WARNING) << "Native frame requiring rotation. Discarding.";
LOG(LS_WARNING) << "Non-I420 frame requiring rotation. Discarding.";
return;
}
broadcaster_.OnFrame(webrtc::VideoFrame(
webrtc::I420Buffer::Rotate(*buffer, frame.rotation()),
webrtc::I420Buffer::Rotate(*buffer->GetI420(), frame.rotation()),
webrtc::kVideoRotation_0, frame.timestamp_us()));
} else {
broadcaster_.OnFrame(frame);

View File

@ -256,7 +256,7 @@ bool VideoProcessorImpl::ProcessFrame(int frame_number) {
<< "Must process frames without gaps.";
RTC_DCHECK(initialized_) << "Attempting to use uninitialized VideoProcessor";
rtc::scoped_refptr<VideoFrameBuffer> buffer(
rtc::scoped_refptr<I420BufferInterface> buffer(
analysis_frame_reader_->ReadFrame());
if (!buffer) {
@ -483,12 +483,7 @@ void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) {
rtc::scoped_refptr<I420Buffer> scaled_buffer(I420Buffer::Create(
config_.codec_settings->width, config_.codec_settings->height));
// Should be the same aspect ratio, no cropping needed.
if (image.video_frame_buffer()->native_handle()) {
scaled_buffer->ScaleFrom(
*image.video_frame_buffer()->NativeToI420Buffer());
} else {
scaled_buffer->ScaleFrom(*image.video_frame_buffer());
}
scaled_buffer->ScaleFrom(*image.video_frame_buffer()->ToI420());
size_t length = CalcBufferSize(VideoType::kI420, scaled_buffer->width(),
scaled_buffer->height());
@ -500,14 +495,8 @@ void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) {
size_t length =
CalcBufferSize(VideoType::kI420, image.width(), image.height());
extracted_buffer.SetSize(length);
if (image.video_frame_buffer()->native_handle()) {
extracted_length =
ExtractBuffer(image.video_frame_buffer()->NativeToI420Buffer(),
length, extracted_buffer.data());
} else {
extracted_length = ExtractBuffer(image.video_frame_buffer(), length,
extracted_buffer.data());
}
extracted_length = ExtractBuffer(image.video_frame_buffer()->ToI420(),
length, extracted_buffer.data());
}
RTC_DCHECK_EQ(extracted_length, analysis_frame_writer_->FrameLength());

View File

@ -157,7 +157,7 @@ class TestVp8Impl : public ::testing::Test {
// Processing only one frame.
source_file_ = fopen(test::ResourcePath("paris_qcif", "yuv").c_str(), "rb");
ASSERT_TRUE(source_file_ != nullptr);
rtc::scoped_refptr<VideoFrameBuffer> compact_buffer(
rtc::scoped_refptr<I420BufferInterface> compact_buffer(
test::ReadI420Buffer(kWidth, kHeight, source_file_));
ASSERT_TRUE(compact_buffer);
codec_settings_.width = kWidth;

View File

@ -160,8 +160,7 @@ void AVFoundationVideoCapturer::CaptureSampleBuffer(
// Applying rotation is only supported for legacy reasons and performance is
// not critical here.
if (apply_rotation() && rotation != kVideoRotation_0) {
buffer = I420Buffer::Rotate(*buffer->NativeToI420Buffer(),
rotation);
buffer = I420Buffer::Rotate(*buffer->ToI420(), rotation);
if (rotation == kVideoRotation_90 || rotation == kVideoRotation_270) {
std::swap(captured_width, captured_height);
}

View File

@ -53,7 +53,8 @@ void ObjcVideoTrackSource::OnCapturedFrame(RTCVideoFrame* frame) {
// Adapted I420 frame.
// TODO(magjed): Optimize this I420 path.
rtc::scoped_refptr<I420Buffer> i420_buffer = I420Buffer::Create(adapted_width, adapted_height);
i420_buffer->CropAndScaleFrom(*frame.videoBuffer, crop_x, crop_y, crop_width, crop_height);
i420_buffer->CropAndScaleFrom(
*frame.videoBuffer->ToI420(), crop_x, crop_y, crop_width, crop_height);
buffer = i420_buffer;
}
@ -61,7 +62,7 @@ void ObjcVideoTrackSource::OnCapturedFrame(RTCVideoFrame* frame) {
// not critical here.
webrtc::VideoRotation rotation = static_cast<webrtc::VideoRotation>(frame.rotation);
if (apply_rotation() && rotation != kVideoRotation_0) {
buffer = I420Buffer::Rotate(*buffer->NativeToI420Buffer(), rotation);
buffer = I420Buffer::Rotate(*buffer->ToI420(), rotation);
rotation = kVideoRotation_0;
}

View File

@ -38,8 +38,8 @@ enum VideoMetricsType { kPSNR, kSSIM, kBoth };
// Calculates metrics for a frame and adds statistics to the result for it.
void CalculateFrame(VideoMetricsType video_metrics_type,
const VideoFrameBuffer& ref,
const VideoFrameBuffer& test,
const I420BufferInterface& ref,
const I420BufferInterface& test,
int frame_number,
QualityMetricsResult* result) {
FrameResult frame_result = {0, 0};

View File

@ -37,7 +37,7 @@ rtc::Optional<VideoFrame> VideoCapturer::AdaptFrame(const VideoFrame& frame) {
// return scaled version.
rtc::scoped_refptr<I420Buffer> scaled_buffer =
I420Buffer::Create(out_width, out_height);
scaled_buffer->ScaleFrom(*frame.video_frame_buffer().get());
scaled_buffer->ScaleFrom(*frame.video_frame_buffer()->ToI420());
out_frame.emplace(
VideoFrame(scaled_buffer, kVideoRotation_0, frame.timestamp_us()));
} else {