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:
@ -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,8 +184,7 @@ void I420Buffer::SetBlack(I420Buffer* buffer) {
|
||||
0, 128, 128) == 0);
|
||||
}
|
||||
|
||||
void I420Buffer::CropAndScaleFrom(
|
||||
const VideoFrameBuffer& src,
|
||||
void I420Buffer::CropAndScaleFrom(const I420BufferInterface& src,
|
||||
int offset_x,
|
||||
int offset_y,
|
||||
int crop_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());
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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()));
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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(),
|
||||
extracted_length = ExtractBuffer(image.video_frame_buffer()->ToI420(),
|
||||
length, extracted_buffer.data());
|
||||
} else {
|
||||
extracted_length = ExtractBuffer(image.video_frame_buffer(), length,
|
||||
extracted_buffer.data());
|
||||
}
|
||||
}
|
||||
|
||||
RTC_DCHECK_EQ(extracted_length, analysis_frame_writer_->FrameLength());
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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};
|
||||
|
||||
@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user