diff options
author | sheu@chromium.org <sheu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-09 08:04:35 +0000 |
---|---|---|
committer | sheu@chromium.org <sheu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-09 08:04:35 +0000 |
commit | 638a259cd8565892bb55deacc1c4d95471eafcf9 (patch) | |
tree | 816cb7adea147f05cccacbfa561f5a9ed04892f7 /media | |
parent | f0ce8ff800781911bc55cbe5f9c2921ba45a0404 (diff) | |
download | chromium_src-638a259cd8565892bb55deacc1c4d95471eafcf9.zip chromium_src-638a259cd8565892bb55deacc1c4d95471eafcf9.tar.gz chromium_src-638a259cd8565892bb55deacc1c4d95471eafcf9.tar.bz2 |
media::VideoFrame::WrapExternalSharedMemory
Add WrapExternalSharedMemory() for wrapping base::SharedMemory-backed buffers
in a media::VideoFrame
Also: add support for I420 in YUV handling paths for media::VideoFrame.
BUG=None
TEST=local build, run, unittests on desktop Linux
Review URL: https://chromiumcodereview.appspot.com/22645005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216641 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/base/video_frame.cc | 69 | ||||
-rw-r--r-- | media/base/video_frame.h | 18 | ||||
-rw-r--r-- | media/base/video_util.cc | 3 |
3 files changed, 75 insertions, 15 deletions
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index 10ad051..08e7e1a 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc @@ -34,6 +34,7 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrame( case VideoFrame::YV12: case VideoFrame::YV12A: case VideoFrame::YV16: + case VideoFrame::I420: frame->AllocateYUV(); break; default: @@ -117,20 +118,52 @@ void VideoFrame::ReadPixelsFromNativeTexture(const SkBitmap& pixels) { } // static +scoped_refptr<VideoFrame> VideoFrame::WrapExternalSharedMemory( + Format format, + const gfx::Size& coded_size, + const gfx::Rect& visible_rect, + const gfx::Size& natural_size, + uint8* data, + base::SharedMemoryHandle handle, + base::TimeDelta timestamp, + const base::Closure& no_longer_needed_cb) { + switch (format) { + case I420: { + scoped_refptr<VideoFrame> frame(new VideoFrame( + format, coded_size, visible_rect, natural_size, timestamp)); + frame->shared_memory_handle_ = handle; + frame->strides_[kYPlane] = coded_size.width(); + frame->strides_[kUPlane] = coded_size.width() / 2; + frame->strides_[kVPlane] = coded_size.width() / 2; + frame->data_[kYPlane] = data; + frame->data_[kUPlane] = data + coded_size.GetArea(); + frame->data_[kVPlane] = data + (coded_size.GetArea() * 5 / 4); + frame->no_longer_needed_cb_ = no_longer_needed_cb; + return frame; + } + default: + NOTIMPLEMENTED(); + return NULL; + } +} + +// static scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData( Format format, const gfx::Size& coded_size, const gfx::Rect& visible_rect, const gfx::Size& natural_size, - int32 y_stride, int32 u_stride, int32 v_stride, - uint8* y_data, uint8* u_data, uint8* v_data, + int32 y_stride, + int32 u_stride, + int32 v_stride, + uint8* y_data, + uint8* u_data, + uint8* v_data, base::TimeDelta timestamp, - base::SharedMemoryHandle shm_handle, const base::Closure& no_longer_needed_cb) { DCHECK(format == YV12 || format == YV16 || format == I420) << format; scoped_refptr<VideoFrame> frame(new VideoFrame( format, coded_size, visible_rect, natural_size, timestamp)); - frame->shared_memory_handle_ = shm_handle; frame->strides_[kYPlane] = y_stride; frame->strides_[kUPlane] = u_stride; frame->strides_[kVPlane] = v_stride; @@ -198,11 +231,11 @@ size_t VideoFrame::NumPlanes(Format format) { return 1; case VideoFrame::YV12: case VideoFrame::YV16: + case VideoFrame::I420: return 3; case VideoFrame::YV12A: return 4; case VideoFrame::EMPTY: - case VideoFrame::I420: case VideoFrame::INVALID: break; } @@ -239,7 +272,7 @@ void VideoFrame::AllocateRGB(size_t bytes_per_pixel) { void VideoFrame::AllocateYUV() { DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 || - format_ == VideoFrame::YV12A); + format_ == VideoFrame::YV12A || format_ == VideoFrame::I420); // Align Y rows at least at 16 byte boundaries. The stride for both // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in @@ -259,9 +292,11 @@ void VideoFrame::AllocateYUV() { // and then the size needs to be a multiple of two macroblocks (vertically). // See libavcodec/utils.c:avcodec_align_dimensions2(). size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2); - size_t uv_height = (format_ == VideoFrame::YV12 || - format_ == VideoFrame::YV12A) ? - y_height / 2 : y_height; + size_t uv_height = + (format_ == VideoFrame::YV12 || format_ == VideoFrame::YV12A || + format_ == VideoFrame::I420) + ? y_height / 2 + : y_height; size_t y_bytes = y_height * y_stride; size_t uv_bytes = uv_height * uv_stride; size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0; @@ -327,10 +362,14 @@ int VideoFrame::row_bytes(size_t plane) const { return width * 4; // Planar, 8bpp. + case YV12A: + if (plane == kAPlane) + return width; + // Fallthrough. case YV12: case YV16: - case YV12A: - if (plane == kYPlane || plane == kAPlane) + case I420: + if (plane == kYPlane) return width; return RoundUp(width, 2) / 2; @@ -351,9 +390,13 @@ int VideoFrame::rows(size_t plane) const { case YV16: return height; - case YV12: case YV12A: - if (plane == kYPlane || plane == kAPlane) + if (plane == kAPlane) + return height; + // Fallthrough. + case YV12: + case I420: + if (plane == kYPlane) return height; return RoundUp(height, 2) / 2; diff --git a/media/base/video_frame.h b/media/base/video_frame.h index 8207d9b..82a08a9 100644 --- a/media/base/video_frame.h +++ b/media/base/video_frame.h @@ -137,9 +137,26 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { // least as large as 4*visible_rect().width()*visible_rect().height(). void ReadPixelsFromNativeTexture(const SkBitmap& pixels); + // Wraps image data in a buffer backed by a base::SharedMemoryHandle with a + // VideoFrame. The image data resides in |data| and is assumed to be packed + // tightly in a buffer of logical dimensions |coded_size| with the appropriate + // bit depth and plane count as given by |format|. When the frame is + // destroyed |no_longer_needed_cb.Run()| will be called. + static scoped_refptr<VideoFrame> WrapExternalSharedMemory( + Format format, + const gfx::Size& coded_size, + const gfx::Rect& visible_rect, + const gfx::Size& natural_size, + uint8* data, + base::SharedMemoryHandle handle, + base::TimeDelta timestamp, + const base::Closure& no_longer_needed_cb); + // Wraps external YUV data of the given parameters with a VideoFrame. // The returned VideoFrame does not own the data passed in. When the frame // is destroyed |no_longer_needed_cb.Run()| will be called. + // TODO(sheu): merge this into WrapExternalSharedMemory(). + // http://crbug.com/270217 static scoped_refptr<VideoFrame> WrapExternalYuvData( Format format, const gfx::Size& coded_size, @@ -152,7 +169,6 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { uint8* u_data, uint8* v_data, base::TimeDelta timestamp, - base::SharedMemoryHandle shm_handle, // may be NULLHandle() const base::Closure& no_longer_needed_cb); // Creates a frame with format equals to VideoFrame::EMPTY, width, height, diff --git a/media/base/video_util.cc b/media/base/video_util.cc index 9da651f..fda758e 100644 --- a/media/base/video_util.cc +++ b/media/base/video_util.cc @@ -143,7 +143,8 @@ void LetterboxYUV(VideoFrame* frame, const gfx::Rect& view_area) { DCHECK(!(view_area.y() & 1)); DCHECK(!(view_area.width() & 1)); DCHECK(!(view_area.height() & 1)); - DCHECK_EQ(frame->format(), VideoFrame::YV12); + DCHECK(frame->format() == VideoFrame::YV12 || + frame->format() == VideoFrame::I420); LetterboxPlane(frame, VideoFrame::kYPlane, view_area, 0x00); gfx::Rect half_view_area(view_area.x() / 2, view_area.y() / 2, |