Commit db8ef289 authored by Sergey Ulanov's avatar Sergey Ulanov Committed by Commit Bot

Allow custom VideoFrameLayout when wrapping VideoFrame

FuchsiaVideoDecoder needs to be able to return frames with stride != width.
Previously VideoFrameLayout::Wrap*() functions didn't allow to wrap such
frames. This CL adds VideoFrame::WrapExternalDataWithLayout() which allows
to pass frame layout explicitly. FuchsiaVideoDecoder uses the new function
to create VideoFrame instances it returns.

Bug: 876519
Change-Id: I2deaa15e5311dafd1c30a80a525530e2d70ee8e9
Reviewed-on: https://chromium-review.googlesource.com/c/1303965
Commit-Queue: Sergey Ulanov <sergeyu@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604639}
parent baab4569
This diff is collapsed.
...@@ -164,6 +164,14 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { ...@@ -164,6 +164,14 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
size_t data_size, size_t data_size,
base::TimeDelta timestamp); base::TimeDelta timestamp);
static scoped_refptr<VideoFrame> WrapExternalDataWithLayout(
const VideoFrameLayout& layout,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
uint8_t* data,
size_t data_size,
base::TimeDelta timestamp);
// Same as WrapExternalData() with a ReadOnlySharedMemoryRegion and its // Same as WrapExternalData() with a ReadOnlySharedMemoryRegion and its
// offset. Neither |region| nor |data| are owned by this VideoFrame. The // offset. Neither |region| nor |data| are owned by this VideoFrame. The
// region and mapping which back |data| must outlive this instance; a // region and mapping which back |data| must outlive this instance; a
...@@ -531,9 +539,8 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { ...@@ -531,9 +539,8 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
private: private:
static scoped_refptr<VideoFrame> WrapExternalStorage( static scoped_refptr<VideoFrame> WrapExternalStorage(
VideoPixelFormat format,
StorageType storage_type, StorageType storage_type,
const gfx::Size& coded_size, const VideoFrameLayout& layout,
const gfx::Rect& visible_rect, const gfx::Rect& visible_rect,
const gfx::Size& natural_size, const gfx::Size& natural_size,
uint8_t* data, uint8_t* data,
......
...@@ -554,16 +554,37 @@ void FuchsiaVideoDecoder::OnOutputPacket( ...@@ -554,16 +554,37 @@ void FuchsiaVideoDecoder::OnOutputPacket(
fuchsia::mediacodec::CodecPacket output_packet, fuchsia::mediacodec::CodecPacket output_packet,
bool error_detected_before, bool error_detected_before,
bool error_detected_during) { bool error_detected_during) {
VideoPixelFormat pixel_format; if (output_packet.header.buffer_lifetime_ordinal !=
output_buffer_lifetime_ordinal_) {
return;
}
auto coded_size = gfx::Size(output_format_.primary_width_pixels,
output_format_.primary_height_pixels);
base::Optional<VideoFrameLayout> layout;
switch (output_format_.fourcc) { switch (output_format_.fourcc) {
case libyuv::FOURCC_NV12: case libyuv::FOURCC_NV12:
pixel_format = PIXEL_FORMAT_NV12; layout = VideoFrameLayout::CreateWithPlanes(
PIXEL_FORMAT_NV12, coded_size,
std::vector<VideoFrameLayout::Plane>{
VideoFrameLayout::Plane(output_format_.primary_line_stride_bytes,
output_format_.primary_start_offset),
VideoFrameLayout::Plane(
output_format_.secondary_line_stride_bytes,
output_format_.secondary_start_offset)});
DCHECK(layout);
break; break;
default: default:
LOG(ERROR) << "unknown fourcc: " LOG(ERROR) << "unknown fourcc: "
<< std::string(reinterpret_cast<char*>(&output_format_.fourcc), << std::string(reinterpret_cast<char*>(&output_format_.fourcc),
4); 4);
return; }
if (!layout) {
codec_->RecycleOutputPacket(output_packet.header);
return;
} }
base::TimeDelta timestamp; base::TimeDelta timestamp;
...@@ -588,14 +609,10 @@ void FuchsiaVideoDecoder::OnOutputPacket( ...@@ -588,14 +609,10 @@ void FuchsiaVideoDecoder::OnOutputPacket(
auto display_rect = gfx::Rect(output_format_.primary_display_width_pixels, auto display_rect = gfx::Rect(output_format_.primary_display_width_pixels,
output_format_.primary_display_height_pixels); output_format_.primary_display_height_pixels);
// TODO(sergeyu): Returned frame is correct only when stride=width, which // TODO(sergeyu): Create ReadOnlySharedMemoryRegion for the VMO and pass
// is not always the case. Currently VideoFrame::WrapExternalData() doesn't // it to the frame.
// allow custom frame layout. auto frame = VideoFrame::WrapExternalDataWithLayout(
auto frame = VideoFrame::WrapExternalData( *layout, display_rect, GetNaturalSize(display_rect, pixel_aspect_ratio),
pixel_format,
gfx::Size(output_format_.primary_width_pixels,
output_format_.primary_height_pixels),
display_rect, GetNaturalSize(display_rect, pixel_aspect_ratio),
const_cast<uint8_t*>(buffer->mapped_memory()) + const_cast<uint8_t*>(buffer->mapped_memory()) +
output_format_.primary_start_offset, output_format_.primary_start_offset,
buffer->buffer().size() - output_format_.primary_start_offset, timestamp); buffer->buffer().size() - output_format_.primary_start_offset, timestamp);
......
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