Commit e6123d99 authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Android video thumbnail: Fix allocation size for vpx thumbnails.

When serializing the in-memory vpx video frame into
MojoSharedBufferVideoFrame, we currently don't consider the padding in
each plane in YUV frame, but we pass the strides, which will trigger a
DCHECK.

This CL also allocates the padding in each plane into the shared memory.

Alternatively, we may remove the padding when copying data.


Bug: 891794
Change-Id: I6a81c8f8afcd8ff063f90523773ba07aac2eb7fa
Reviewed-on: https://chromium-review.googlesource.com/c/1260007Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Commit-Queue: Xing Liu <xingliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#596441}
parent 7248878f
...@@ -61,40 +61,38 @@ scoped_refptr<MojoSharedBufferVideoFrame> ...@@ -61,40 +61,38 @@ scoped_refptr<MojoSharedBufferVideoFrame>
MojoSharedBufferVideoFrame::CreateFromYUVFrame(const VideoFrame& frame) { MojoSharedBufferVideoFrame::CreateFromYUVFrame(const VideoFrame& frame) {
DCHECK_EQ(VideoFrame::NumPlanes(frame.format()), 3u); DCHECK_EQ(VideoFrame::NumPlanes(frame.format()), 3u);
// The data from |frame| may not be consecutive between planes. Copy data const size_t y_stride = frame.stride(VideoFrame::kYPlane);
// into a shared memory buffer which is tightly packed. const size_t u_stride = frame.stride(VideoFrame::kUPlane);
size_t allocation_size = const size_t v_stride = frame.stride(VideoFrame::kVPlane);
VideoFrame::AllocationSize(frame.format(), frame.coded_size());
mojo::ScopedSharedBufferHandle handle =
mojo::SharedBufferHandle::Create(allocation_size);
const size_t y_size = const size_t y_size =
VideoFrame::PlaneSize(frame.format(), VideoFrame::kYPlane, VideoFrame::Rows(kYPlane, frame.format(), frame.coded_size().height()) *
frame.coded_size()) y_stride;
.GetArea();
const size_t u_size = const size_t u_size =
VideoFrame::PlaneSize(frame.format(), VideoFrame::kUPlane, VideoFrame::Rows(kUPlane, frame.format(), frame.coded_size().height()) *
frame.coded_size()) u_stride;
.GetArea();
const size_t v_size = const size_t v_size =
VideoFrame::PlaneSize(frame.format(), VideoFrame::kVPlane, VideoFrame::Rows(kVPlane, frame.format(), frame.coded_size().height()) *
frame.coded_size()) v_stride;
.GetArea();
size_t allocation_size = y_size + u_size + v_size;
mojo::ScopedSharedBufferHandle handle =
mojo::SharedBufferHandle::Create(allocation_size);
// Computes the offset of planes in shared memory buffer. // Computes the offset of planes in shared memory buffer.
const size_t y_offset = 0u; const size_t y_offset = 0u;
const size_t u_offset = y_offset + y_size; const size_t u_offset = y_offset + y_size;
const size_t v_offset = y_offset + y_size + u_size; const size_t v_offset = y_offset + y_size + u_size;
// Create a mojo video frame backed by shared memory, so it can be sent to // The data from |frame| may not be consecutive between planes. Copy data into
// the browser process. // a shared memory buffer which is tightly packed. Padding inside each planes
// are preserved.
scoped_refptr<MojoSharedBufferVideoFrame> mojo_frame = scoped_refptr<MojoSharedBufferVideoFrame> mojo_frame =
MojoSharedBufferVideoFrame::Create( MojoSharedBufferVideoFrame::Create(
frame.format(), frame.coded_size(), frame.visible_rect(), frame.format(), frame.coded_size(), frame.visible_rect(),
frame.natural_size(), std::move(handle), allocation_size, y_offset, frame.natural_size(), std::move(handle), allocation_size, y_offset,
u_offset, v_offset, frame.stride(VideoFrame::kYPlane), u_offset, v_offset, y_stride, u_stride, v_stride, frame.timestamp());
frame.stride(VideoFrame::kUPlane), frame.stride(VideoFrame::kVPlane),
frame.timestamp());
// Copy Y plane. // Copy Y plane.
memcpy(mojo_frame->shared_buffer_data(), memcpy(mojo_frame->shared_buffer_data(),
......
...@@ -229,24 +229,25 @@ TEST(MojoSharedBufferVideoFrameTest, YUVFrameToMojoFrame) { ...@@ -229,24 +229,25 @@ TEST(MojoSharedBufferVideoFrameTest, YUVFrameToMojoFrame) {
std::vector<uint8_t> data = std::vector<uint8_t>(12, 1u); std::vector<uint8_t> data = std::vector<uint8_t>(12, 1u);
const auto pixel_format = VideoPixelFormat::PIXEL_FORMAT_I420; const auto pixel_format = VideoPixelFormat::PIXEL_FORMAT_I420;
const auto size = gfx::Size(1, 1); const auto size = gfx::Size(1, 1);
const int32_t stride = 3;
// The YUV frame only has 1 pixel. But each plane are not in consecutive
// memory block, also stride is 3 bytes that contains 1 byte image data and 2
// bytes padding.
scoped_refptr<VideoFrame> frame = VideoFrame::WrapExternalYuvData( scoped_refptr<VideoFrame> frame = VideoFrame::WrapExternalYuvData(
pixel_format, size, gfx::Rect(1, 1), size, 4, 4, 4, &data[0], &data[4], pixel_format, size, gfx::Rect(1, 1), size, stride, stride, stride,
&data[8], base::TimeDelta()); &data[0], &data[4], &data[8], base::TimeDelta());
auto mojo_frame = MojoSharedBufferVideoFrame::CreateFromYUVFrame(*frame); auto mojo_frame = MojoSharedBufferVideoFrame::CreateFromYUVFrame(*frame);
EXPECT_TRUE(mojo_frame); EXPECT_TRUE(mojo_frame);
const size_t u_offset = const size_t y_stride = frame->stride(VideoFrame::kYPlane);
VideoFrame::PlaneSize(pixel_format, VideoFrame::kYPlane, size).GetArea(); const size_t u_stride = frame->stride(VideoFrame::kUPlane);
const size_t v_offset =
u_offset +
VideoFrame::PlaneSize(pixel_format, VideoFrame::kUPlane, size).GetArea();
// Verifies mapped size and offset. // Verifies mapped size and offset.
EXPECT_EQ(mojo_frame->MappedSize(), EXPECT_EQ(mojo_frame->MappedSize(), static_cast<size_t>(3 * stride));
frame->AllocationSize(pixel_format, size));
EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kYPlane), 0u); EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kYPlane), 0u);
EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kUPlane), u_offset); EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kUPlane), y_stride);
EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kVPlane), v_offset); EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kVPlane), y_stride + u_stride);
} }
} // namespace media } // namespace media
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment