diff options
author | Torne (Richard Coles) <torne@google.com> | 2013-03-28 15:31:22 +0000 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2013-03-28 15:31:22 +0000 |
commit | 2a99a7e74a7f215066514fe81d2bfa6639d9eddd (patch) | |
tree | 7c2d04841fcd599fd83b0f0bb1100e1c89a35bae /media/base/video_frame.cc | |
parent | 61c449bbbb53310a8c041d8cefdd6b01a126cc7e (diff) | |
download | chromium_org-2a99a7e74a7f215066514fe81d2bfa6639d9eddd.tar.gz |
Merge from Chromium at DEPS revision r190564
This commit was generated by merge_to_master.py.
Change-Id: Icadecbce29854b8fa25fd335b2c1949b5ca5d170
Diffstat (limited to 'media/base/video_frame.cc')
-rw-r--r-- | media/base/video_frame.cc | 152 |
1 files changed, 89 insertions, 63 deletions
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index 3d764103f1..70b77fb5ec 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc @@ -4,15 +4,15 @@ #include "media/base/video_frame.h" +#include <algorithm> + +#include "base/bind.h" +#include "base/callback_helpers.h" #include "base/logging.h" +#include "base/memory/aligned_memory.h" #include "base/string_piece.h" #include "media/base/limits.h" #include "media/base/video_util.h" -#if !defined(OS_ANDROID) -#include "media/ffmpeg/ffmpeg_common.h" -#endif - -#include <algorithm> namespace media { @@ -69,14 +69,13 @@ scoped_refptr<VideoFrame> VideoFrame::WrapNativeTexture( const gfx::Size& natural_size, base::TimeDelta timestamp, const ReadPixelsCB& read_pixels_cb, - const base::Closure& no_longer_needed) { - scoped_refptr<VideoFrame> frame( - new VideoFrame(NATIVE_TEXTURE, coded_size, visible_rect, natural_size, - timestamp)); + const base::Closure& no_longer_needed_cb) { + scoped_refptr<VideoFrame> frame(new VideoFrame( + NATIVE_TEXTURE, coded_size, visible_rect, natural_size, timestamp)); frame->texture_id_ = texture_id; frame->texture_target_ = texture_target; frame->read_pixels_cb_ = read_pixels_cb; - frame->texture_no_longer_needed_ = no_longer_needed; + frame->no_longer_needed_cb_ = no_longer_needed_cb; return frame; } @@ -87,6 +86,29 @@ void VideoFrame::ReadPixelsFromNativeTexture(void* pixels) { } // 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, + base::TimeDelta timestamp, + 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->strides_[kYPlane] = y_stride; + frame->strides_[kUPlane] = u_stride; + frame->strides_[kVPlane] = v_stride; + frame->data_[kYPlane] = y_data; + frame->data_[kUPlane] = u_data; + frame->data_[kVPlane] = v_data; + frame->no_longer_needed_cb_ = no_longer_needed_cb; + return frame; +} + +// static scoped_refptr<VideoFrame> VideoFrame::CreateEmptyFrame() { return new VideoFrame( VideoFrame::EMPTY, gfx::Size(), gfx::Rect(), gfx::Size(), @@ -113,15 +135,57 @@ scoped_refptr<VideoFrame> VideoFrame::CreateBlackFrame(const gfx::Size& size) { return CreateColorFrame(size, kBlackY, kBlackUV, kBlackUV, kZero); } +#if defined(GOOGLE_TV) +// This block and other blocks wrapped around #if defined(GOOGLE_TV) is not +// maintained by the general compositor team. Please contact the following +// people instead: +// +// wonsik@chromium.org +// ycheo@chromium.org + +// static +scoped_refptr<VideoFrame> VideoFrame::CreateHoleFrame( + const gfx::Size& size) { + DCHECK(IsValidConfig(VideoFrame::HOLE, size, gfx::Rect(size), size)); + scoped_refptr<VideoFrame> frame(new VideoFrame( + VideoFrame::HOLE, size, gfx::Rect(size), size, base::TimeDelta())); + return frame; +} +#endif + +// static +size_t VideoFrame::NumPlanes(Format format) { + switch (format) { + case VideoFrame::NATIVE_TEXTURE: +#if defined(GOOGLE_TV) + case VideoFrame::HOLE: +#endif + return 0; + case VideoFrame::RGB32: + return 1; + case VideoFrame::YV12: + case VideoFrame::YV16: + return 3; + case VideoFrame::EMPTY: + case VideoFrame::I420: + case VideoFrame::INVALID: + break; + } + NOTREACHED() << "Unsupported video frame format: " << format; + return 0; +} + static inline size_t RoundUp(size_t value, size_t alignment) { // Check that |alignment| is a power of 2. DCHECK((alignment + (alignment - 1)) == (alignment | (alignment - 1))); return ((value + (alignment - 1)) & ~(alignment-1)); } -static const int kFrameSizeAlignment = 16; -// Allows faster SIMD YUV convert. Also, FFmpeg overreads/-writes occasionally. -static const int kFramePadBytes = 15; +// Release data allocated by AllocateRGB() or AllocateYUV(). +static void ReleaseData(uint8* data) { + DCHECK(data); + base::AlignedFree(data); +} void VideoFrame::AllocateRGB(size_t bytes_per_pixel) { // Round up to align at least at a 16-byte boundary for each row. @@ -130,14 +194,10 @@ void VideoFrame::AllocateRGB(size_t bytes_per_pixel) { kFrameSizeAlignment) * bytes_per_pixel; size_t aligned_height = RoundUp(coded_size_.height(), kFrameSizeAlignment); strides_[VideoFrame::kRGBPlane] = bytes_per_row; -#if !defined(OS_ANDROID) - // TODO(dalecurtis): use DataAligned or so, so this #ifdef hackery - // doesn't need to be repeated in every single user of aligned data. data_[VideoFrame::kRGBPlane] = reinterpret_cast<uint8*>( - av_malloc(bytes_per_row * aligned_height + kFramePadBytes)); -#else - data_[VideoFrame::kRGBPlane] = new uint8_t[bytes_per_row * aligned_height]; -#endif + base::AlignedAlloc(bytes_per_row * aligned_height + kFrameSizePadding, + kFrameAddressAlignment)); + no_longer_needed_cb_ = base::Bind(&ReleaseData, data_[VideoFrame::kRGBPlane]); DCHECK(!(reinterpret_cast<intptr_t>(data_[VideoFrame::kRGBPlane]) & 7)); COMPILE_ASSERT(0 == VideoFrame::kRGBPlane, RGB_data_must_be_index_0); } @@ -165,18 +225,15 @@ void VideoFrame::AllocateYUV() { size_t y_bytes = y_height * y_stride; size_t uv_bytes = uv_height * uv_stride; -#if !defined(OS_ANDROID) - // TODO(dalecurtis): use DataAligned or so, so this #ifdef hackery - // doesn't need to be repeated in every single user of aligned data. // The extra line of UV being allocated is because h264 chroma MC // overreads by one line in some cases, see libavcodec/utils.c: // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: // put_h264_chroma_mc4_ssse3(). uint8* data = reinterpret_cast<uint8*>( - av_malloc(y_bytes + (uv_bytes * 2 + uv_stride) + kFramePadBytes)); -#else - uint8* data = new uint8_t[y_bytes + (uv_bytes * 2)]; -#endif + base::AlignedAlloc( + y_bytes + (uv_bytes * 2 + uv_stride) + kFrameSizePadding, + kFrameAddressAlignment)); + no_longer_needed_cb_ = base::Bind(&ReleaseData, data); COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0); data_[VideoFrame::kYPlane] = data; data_[VideoFrame::kUPlane] = data + y_bytes; @@ -203,43 +260,12 @@ VideoFrame::VideoFrame(VideoFrame::Format format, } VideoFrame::~VideoFrame() { - if (format_ == NATIVE_TEXTURE && !texture_no_longer_needed_.is_null()) { - texture_no_longer_needed_.Run(); - texture_no_longer_needed_.Reset(); - } - - // In multi-plane allocations, only a single block of memory is allocated - // on the heap, and other |data| pointers point inside the same, single block - // so just delete index 0. - if (data_[0]) { -#if !defined(OS_ANDROID) - av_free(data_[0]); -#else - delete[] data_[0]; -#endif - } + if (!no_longer_needed_cb_.is_null()) + base::ResetAndReturn(&no_longer_needed_cb_).Run(); } bool VideoFrame::IsValidPlane(size_t plane) const { - switch (format_) { - case RGB32: - return plane == kRGBPlane; - - case YV12: - case YV16: - return plane == kYPlane || plane == kUPlane || plane == kVPlane; - - case NATIVE_TEXTURE: - NOTREACHED() << "NATIVE_TEXTUREs don't use plane-related methods!"; - return false; - - default: - break; - } - - // Intentionally leave out non-production formats. - NOTREACHED() << "Unsupported video frame format: " << format_; - return false; + return (plane < NumPlanes(format_)); } int VideoFrame::stride(size_t plane) const { @@ -313,10 +339,10 @@ bool VideoFrame::IsEndOfStream() const { } void VideoFrame::HashFrameForTesting(base::MD5Context* context) { - for(int plane = 0; plane < kMaxPlanes; plane++) { + for (int plane = 0; plane < kMaxPlanes; ++plane) { if (!IsValidPlane(plane)) break; - for(int row = 0; row < rows(plane); row++) { + for (int row = 0; row < rows(plane); ++row) { base::MD5Update(context, base::StringPiece( reinterpret_cast<char*>(data(plane) + stride(plane) * row), row_bytes(plane))); |