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>
MojoSharedBufferVideoFrame::CreateFromYUVFrame(const VideoFrame& frame) {
DCHECK_EQ(VideoFrame::NumPlanes(frame.format()), 3u);
// The data from |frame| may not be consecutive between planes. Copy data
// into a shared memory buffer which is tightly packed.
size_t allocation_size =
VideoFrame::AllocationSize(frame.format(), frame.coded_size());
mojo::ScopedSharedBufferHandle handle =
mojo::SharedBufferHandle::Create(allocation_size);
const size_t y_stride = frame.stride(VideoFrame::kYPlane);
const size_t u_stride = frame.stride(VideoFrame::kUPlane);
const size_t v_stride = frame.stride(VideoFrame::kVPlane);
const size_t y_size =
VideoFrame::PlaneSize(frame.format(), VideoFrame::kYPlane,
frame.coded_size())
.GetArea();
VideoFrame::Rows(kYPlane, frame.format(), frame.coded_size().height()) *
y_stride;
const size_t u_size =
VideoFrame::PlaneSize(frame.format(), VideoFrame::kUPlane,
frame.coded_size())
.GetArea();
VideoFrame::Rows(kUPlane, frame.format(), frame.coded_size().height()) *
u_stride;
const size_t v_size =
VideoFrame::PlaneSize(frame.format(), VideoFrame::kVPlane,
frame.coded_size())
.GetArea();
VideoFrame::Rows(kVPlane, frame.format(), frame.coded_size().height()) *
v_stride;
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.
const size_t y_offset = 0u;
const size_t u_offset = y_offset + y_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 browser process.
// The data from |frame| may not be consecutive between planes. Copy data into
// a shared memory buffer which is tightly packed. Padding inside each planes
// are preserved.
scoped_refptr<MojoSharedBufferVideoFrame> mojo_frame =
MojoSharedBufferVideoFrame::Create(
frame.format(), frame.coded_size(), frame.visible_rect(),
frame.natural_size(), std::move(handle), allocation_size, y_offset,
u_offset, v_offset, frame.stride(VideoFrame::kYPlane),
frame.stride(VideoFrame::kUPlane), frame.stride(VideoFrame::kVPlane),
frame.timestamp());
u_offset, v_offset, y_stride, u_stride, v_stride, frame.timestamp());
// Copy Y plane.
memcpy(mojo_frame->shared_buffer_data(),
......
......@@ -229,24 +229,25 @@ TEST(MojoSharedBufferVideoFrameTest, YUVFrameToMojoFrame) {
std::vector<uint8_t> data = std::vector<uint8_t>(12, 1u);
const auto pixel_format = VideoPixelFormat::PIXEL_FORMAT_I420;
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(
pixel_format, size, gfx::Rect(1, 1), size, 4, 4, 4, &data[0], &data[4],
&data[8], base::TimeDelta());
pixel_format, size, gfx::Rect(1, 1), size, stride, stride, stride,
&data[0], &data[4], &data[8], base::TimeDelta());
auto mojo_frame = MojoSharedBufferVideoFrame::CreateFromYUVFrame(*frame);
EXPECT_TRUE(mojo_frame);
const size_t u_offset =
VideoFrame::PlaneSize(pixel_format, VideoFrame::kYPlane, size).GetArea();
const size_t v_offset =
u_offset +
VideoFrame::PlaneSize(pixel_format, VideoFrame::kUPlane, size).GetArea();
const size_t y_stride = frame->stride(VideoFrame::kYPlane);
const size_t u_stride = frame->stride(VideoFrame::kUPlane);
// Verifies mapped size and offset.
EXPECT_EQ(mojo_frame->MappedSize(),
frame->AllocationSize(pixel_format, size));
EXPECT_EQ(mojo_frame->MappedSize(), static_cast<size_t>(3 * stride));
EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kYPlane), 0u);
EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kUPlane), u_offset);
EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kVPlane), v_offset);
EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kUPlane), y_stride);
EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kVPlane), y_stride + u_stride);
}
} // 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