Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(403)

Unified Diff: media/base/video_frame.cc

Issue 604743005: VideoCapture: Remove deep frame copy in the border to libJingle (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: scherkus@s comments Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/video_frame.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/video_frame.cc
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 5f0d7282c6e01aedfe0861ee90e55e2cb319b7c1..abea883446669be3e88c1b27bf6c5a4a22d5a277 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -14,6 +14,7 @@
#include "gpu/command_buffer/common/mailbox_holder.h"
#include "media/base/limits.h"
#include "media/base/video_util.h"
+#include "ui/gfx/point.h"
#if !defined(MEDIA_FOR_CAST_IOS)
#include "third_party/skia/include/core/SkBitmap.h"
@@ -21,30 +22,84 @@
namespace media {
+static bool IsPowerOfTwo(size_t x) {
+ return x != 0 && (x & (x - 1)) == 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)));
+ DCHECK(IsPowerOfTwo(alignment));
return ((value + (alignment - 1)) & ~(alignment - 1));
}
+static inline size_t RoundDown(size_t value, size_t alignment) {
+ DCHECK(IsPowerOfTwo(alignment));
+ return value & ~(alignment - 1);
+}
+
+// Returns the pixel size per element for given |plane| and |format|. E.g. 2x2
+// for the U-plane in I420.
+static gfx::Size SampleSize(VideoFrame::Format format, size_t plane) {
+ DCHECK(VideoFrame::IsValidPlane(plane, format));
+
+ switch (plane) {
+ case VideoFrame::kYPlane:
+ case VideoFrame::kAPlane:
+ return gfx::Size(1, 1);
+
+ case VideoFrame::kUPlane: // and VideoFrame::kUVPlane:
+ case VideoFrame::kVPlane:
+ switch (format) {
+ case VideoFrame::YV24:
+ return gfx::Size(1, 1);
+
+ case VideoFrame::YV16:
+ return gfx::Size(2, 1);
+
+ case VideoFrame::YV12:
+ case VideoFrame::YV12J:
+ case VideoFrame::I420:
+ case VideoFrame::YV12A:
+ case VideoFrame::NV12:
+ return gfx::Size(2, 2);
+
+ case VideoFrame::UNKNOWN:
+#if defined(VIDEO_HOLE)
+ case VideoFrame::HOLE:
+#endif // defined(VIDEO_HOLE)
+ case VideoFrame::NATIVE_TEXTURE:
+ break;
+ }
+ }
+ NOTREACHED();
+ return gfx::Size();
+}
+
+// Return the alignment for the whole frame, calculated as the max of the
+// alignment for each individual plane.
+static gfx::Size CommonAlignment(VideoFrame::Format format) {
+ int max_sample_width = 0;
+ int max_sample_height = 0;
+ for (size_t plane = 0; plane < VideoFrame::NumPlanes(format); ++plane) {
+ const gfx::Size sample_size = SampleSize(format, plane);
+ max_sample_width = std::max(max_sample_width, sample_size.width());
+ max_sample_height = std::max(max_sample_height, sample_size.height());
+ }
+ return gfx::Size(max_sample_width, max_sample_height);
+}
+
+// Returns the number of bytes per element for given |plane| and |format|. E.g.
+// 2 for the UV plane in NV12.
+static int BytesPerElement(VideoFrame::Format format, size_t plane) {
+ DCHECK(VideoFrame::IsValidPlane(plane, format));
+ return (format == VideoFrame::NV12 && plane == VideoFrame::kUVPlane) ? 2 : 1;
+}
+
// Rounds up |coded_size| if necessary for |format|.
static gfx::Size AdjustCodedSize(VideoFrame::Format format,
const gfx::Size& coded_size) {
- gfx::Size new_coded_size(coded_size);
- switch (format) {
- case VideoFrame::YV12:
- case VideoFrame::YV12A:
- case VideoFrame::I420:
- case VideoFrame::YV12J:
- new_coded_size.set_height(RoundUp(new_coded_size.height(), 2));
- // Fallthrough.
- case VideoFrame::YV16:
- new_coded_size.set_width(RoundUp(new_coded_size.width(), 2));
- break;
- default:
- break;
- }
- return new_coded_size;
+ const gfx::Size alignment = CommonAlignment(format);
+ return gfx::Size(RoundUp(coded_size.width(), alignment.width()),
+ RoundUp(coded_size.height(), alignment.height()));
}
// static
@@ -64,7 +119,7 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrame(
// Since we're creating a new YUV frame (and allocating memory for it
// ourselves), we can pad the requested |coded_size| if necessary if the
// request does not line up on sample boundaries.
- gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
+ const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
DCHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size));
scoped_refptr<VideoFrame> frame(
@@ -131,35 +186,35 @@ bool VideoFrame::IsValidConfig(VideoFrame::Format format,
case VideoFrame::UNKNOWN:
return (coded_size.IsEmpty() && visible_rect.IsEmpty() &&
natural_size.IsEmpty());
+
+ // NATIVE_TEXTURE and HOLE have no software-allocated buffers and are
+ // allowed to skip the below check.
+ case VideoFrame::NATIVE_TEXTURE:
+#if defined(VIDEO_HOLE)
+ case VideoFrame::HOLE:
+#endif // defined(VIDEO_HOLE)
+ return true;
+
case VideoFrame::YV24:
- break;
case VideoFrame::YV12:
case VideoFrame::YV12J:
case VideoFrame::I420:
case VideoFrame::YV12A:
case VideoFrame::NV12:
- // Subsampled YUV formats have width/height requirements.
- if (static_cast<size_t>(coded_size.height()) <
- RoundUp(visible_rect.bottom(), 2))
- return false;
- // Fallthrough.
case VideoFrame::YV16:
- if (static_cast<size_t>(coded_size.width()) <
- RoundUp(visible_rect.right(), 2))
- return false;
- break;
- case VideoFrame::NATIVE_TEXTURE:
-#if defined(VIDEO_HOLE)
- case VideoFrame::HOLE:
-#endif // defined(VIDEO_HOLE)
- // NATIVE_TEXTURE and HOLE have no software-allocated buffers and are
- // allowed to skip the below check and be empty.
- return true;
+ // Check that software-allocated buffer formats are aligned correctly and
+ // not empty.
+ const gfx::Size alignment = CommonAlignment(format);
+ return RoundUp(visible_rect.right(), alignment.width()) <=
+ static_cast<size_t>(coded_size.width()) &&
+ RoundUp(visible_rect.bottom(), alignment.height()) <=
+ static_cast<size_t>(coded_size.height()) &&
+ !coded_size.IsEmpty() && !visible_rect.IsEmpty() &&
+ !natural_size.IsEmpty();
}
- // Check that software-allocated buffer formats are not empty.
- return (!coded_size.IsEmpty() && !visible_rect.IsEmpty() &&
- !natural_size.IsEmpty());
+ NOTREACHED();
+ return false;
}
// static
@@ -203,7 +258,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalPackedMemory(
base::SharedMemoryHandle handle,
base::TimeDelta timestamp,
const base::Closure& no_longer_needed_cb) {
- gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
+ const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
if (!IsValidConfig(format, new_coded_size, visible_rect, natural_size))
return NULL;
@@ -291,7 +346,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapCVPixelBuffer(
DCHECK(cv_pixel_buffer);
DCHECK(CFGetTypeID(cv_pixel_buffer) == CVPixelBufferGetTypeID());
- OSType cv_format = CVPixelBufferGetPixelFormatType(cv_pixel_buffer);
+ const OSType cv_format = CVPixelBufferGetPixelFormatType(cv_pixel_buffer);
Format format;
// There are very few compatible CV pixel formats, so just check each.
if (cv_format == kCVPixelFormatType_420YpCbCr8Planar) {
@@ -307,9 +362,9 @@ scoped_refptr<VideoFrame> VideoFrame::WrapCVPixelBuffer(
return NULL;
}
- gfx::Size coded_size(CVImageBufferGetEncodedSize(cv_pixel_buffer));
- gfx::Rect visible_rect(CVImageBufferGetCleanRect(cv_pixel_buffer));
- gfx::Size natural_size(CVImageBufferGetDisplaySize(cv_pixel_buffer));
+ const gfx::Size coded_size(CVImageBufferGetEncodedSize(cv_pixel_buffer));
+ const gfx::Rect visible_rect(CVImageBufferGetCleanRect(cv_pixel_buffer));
+ const gfx::Size natural_size(CVImageBufferGetDisplaySize(cv_pixel_buffer));
if (!IsValidConfig(format, coded_size, visible_rect, natural_size))
return NULL;
@@ -342,7 +397,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData(
uint8* v_data,
base::TimeDelta timestamp,
const base::Closure& no_longer_needed_cb) {
- gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
+ const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
CHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size));
scoped_refptr<VideoFrame> frame(
@@ -497,78 +552,19 @@ size_t VideoFrame::AllocationSize(Format format, const gfx::Size& coded_size) {
gfx::Size VideoFrame::PlaneSize(Format format,
size_t plane,
const gfx::Size& coded_size) {
+ DCHECK(IsValidPlane(plane, format));
+
// Align to multiple-of-two size overall. This ensures that non-subsampled
// planes can be addressed by pixel with the same scaling as the subsampled
// planes.
const int width = RoundUp(coded_size.width(), 2);
const int height = RoundUp(coded_size.height(), 2);
- switch (format) {
- case VideoFrame::YV24:
- switch (plane) {
- case VideoFrame::kYPlane:
- case VideoFrame::kUPlane:
- case VideoFrame::kVPlane:
- return gfx::Size(width, height);
- default:
- break;
- }
- break;
- case VideoFrame::YV12:
- case VideoFrame::YV12J:
- case VideoFrame::I420:
- switch (plane) {
- case VideoFrame::kYPlane:
- return gfx::Size(width, height);
- case VideoFrame::kUPlane:
- case VideoFrame::kVPlane:
- return gfx::Size(width / 2, height / 2);
- default:
- break;
- }
- break;
- case VideoFrame::YV12A:
- switch (plane) {
- case VideoFrame::kYPlane:
- case VideoFrame::kAPlane:
- return gfx::Size(width, height);
- case VideoFrame::kUPlane:
- case VideoFrame::kVPlane:
- return gfx::Size(width / 2, height / 2);
- default:
- break;
- }
- break;
- case VideoFrame::YV16:
- switch (plane) {
- case VideoFrame::kYPlane:
- return gfx::Size(width, height);
- case VideoFrame::kUPlane:
- case VideoFrame::kVPlane:
- return gfx::Size(width / 2, height);
- default:
- break;
- }
- break;
- case VideoFrame::NV12:
- switch (plane) {
- case VideoFrame::kYPlane:
- return gfx::Size(width, height);
- case VideoFrame::kUVPlane:
- return gfx::Size(width, height / 2);
- default:
- break;
- }
- break;
- case VideoFrame::UNKNOWN:
- case VideoFrame::NATIVE_TEXTURE:
-#if defined(VIDEO_HOLE)
- case VideoFrame::HOLE:
-#endif // defined(VIDEO_HOLE)
- break;
- }
- NOTREACHED() << "Unsupported video frame format/plane: "
- << format << "/" << plane;
- return gfx::Size();
+
+ const gfx::Size subsample = SampleSize(format, plane);
+ DCHECK(width % subsample.width() == 0);
+ DCHECK(height % subsample.height() == 0);
+ return gfx::Size(BytesPerElement(format, plane) * width / subsample.width(),
+ height / subsample.height());
}
size_t VideoFrame::PlaneAllocationSize(Format format,
@@ -580,63 +576,11 @@ size_t VideoFrame::PlaneAllocationSize(Format format,
// static
int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) {
- switch (format) {
- case VideoFrame::YV24:
- switch (plane) {
- case kYPlane:
- case kUPlane:
- case kVPlane:
- return 8;
- default:
- break;
- }
- break;
- case VideoFrame::YV12:
- case VideoFrame::YV16:
- case VideoFrame::I420:
- case VideoFrame::YV12J:
- switch (plane) {
- case kYPlane:
- return 8;
- case kUPlane:
- case kVPlane:
- return 2;
- default:
- break;
- }
- break;
- case VideoFrame::YV12A:
- switch (plane) {
- case kYPlane:
- case kAPlane:
- return 8;
- case kUPlane:
- case kVPlane:
- return 2;
- default:
- break;
- }
- break;
- case VideoFrame::NV12:
- switch (plane) {
- case kYPlane:
- return 8;
- case kUVPlane:
- return 4;
- default:
- break;
- }
- break;
- case VideoFrame::UNKNOWN:
-#if defined(VIDEO_HOLE)
- case VideoFrame::HOLE:
-#endif // defined(VIDEO_HOLE)
- case VideoFrame::NATIVE_TEXTURE:
- break;
- }
- NOTREACHED() << "Unsupported video frame format/plane: "
- << format << "/" << plane;
- return 0;
+ DCHECK(IsValidPlane(plane, format));
+ const int bits_per_element = 8 * BytesPerElement(format, plane);
+ const int pixels_per_element = SampleSize(format, plane).GetArea();
+ DCHECK(bits_per_element % pixels_per_element == 0);
+ return bits_per_element / pixels_per_element;
}
// Release data allocated by AllocateYUV().
@@ -646,60 +590,40 @@ static void ReleaseData(uint8* data) {
}
void VideoFrame::AllocateYUV() {
- DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 ||
- format_ == VideoFrame::YV12A || format_ == VideoFrame::I420 ||
- format_ == VideoFrame::YV12J || format_ == VideoFrame::YV24);
- // 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
- // the case of YV12 the strides are identical for the same width surface, but
- // the number of bytes allocated for YV12 is 1/2 the amount for U & V as
- // YV16. We also round the height of the surface allocated to be an even
- // number to avoid any potential of faulting by code that attempts to access
- // the Y values of the final row, but assumes that the last row of U & V
- // applies to a full two rows of Y. YV12A is the same as YV12, but with an
- // additional alpha plane that has the same size and alignment as the Y plane.
- size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane),
- kFrameSizeAlignment);
- size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane),
- kFrameSizeAlignment);
-
- // The *2 here is because some formats (e.g. h264) allow interlaced coding,
- // 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 ||
- 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;
+ DCHECK(format_ == YV12 || format_ == YV16 || format_ == YV12A ||
+ format_ == I420 || format_ == YV12J || format_ == YV24);
+ COMPILE_ASSERT(0 == kYPlane, y_plane_data_must_be_index_0);
+
+ size_t data_size = 0;
+ size_t offset[kMaxPlanes];
+ for (size_t plane = 0; plane < VideoFrame::NumPlanes(format_); ++plane) {
+ // The *2 in alignment for height is because some formats (e.g. h264) allow
+ // interlaced coding, and then the size needs to be a multiple of two
+ // macroblocks (vertically). See
+ // libavcodec/utils.c:avcodec_align_dimensions2().
+ const size_t height = RoundUp(rows(plane), kFrameSizeAlignment * 2);
+ strides_[plane] = RoundUp(row_bytes(plane), kFrameSizeAlignment);
+ offset[plane] = data_size;
+ data_size += height * strides_[plane];
+ }
// 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().
- const size_t data_size =
- y_bytes + (uv_bytes * 2 + uv_stride) + a_bytes + kFrameSizePadding;
- uint8* data = reinterpret_cast<uint8*>(
- base::AlignedAlloc(data_size, kFrameAddressAlignment));
+ DCHECK(IsValidPlane(kUPlane, format_));
+ data_size += strides_[kUPlane] + kFrameSizePadding;
+
// FFmpeg expects the initialize allocation to be zero-initialized. Failure
// to do so can lead to unitialized value usage. See http://crbug.com/390941
+ uint8* data = reinterpret_cast<uint8*>(
+ base::AlignedAlloc(data_size, kFrameAddressAlignment));
memset(data, 0, data_size);
+
+ for (size_t plane = 0; plane < VideoFrame::NumPlanes(format_); ++plane)
+ data_[plane] = data + offset[plane];
+
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;
- data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes;
- strides_[VideoFrame::kYPlane] = y_stride;
- strides_[VideoFrame::kUPlane] = uv_stride;
- strides_[VideoFrame::kVPlane] = uv_stride;
- if (format_ == YV12A) {
- data_[VideoFrame::kAPlane] = data + y_bytes + (2 * uv_bytes);
- strides_[VideoFrame::kAPlane] = y_stride;
- }
}
VideoFrame::VideoFrame(VideoFrame::Format format,
@@ -750,65 +674,11 @@ int VideoFrame::stride(size_t plane) const {
}
// static
-size_t VideoFrame::RowBytes(size_t plane, VideoFrame::Format format,
+size_t VideoFrame::RowBytes(size_t plane,
+ VideoFrame::Format format,
int width) {
DCHECK(IsValidPlane(plane, format));
- switch (format) {
- case VideoFrame::YV24:
- switch (plane) {
- case kYPlane:
- case kUPlane:
- case kVPlane:
- return width;
- default:
- break;
- }
- break;
- case VideoFrame::YV12:
- case VideoFrame::YV16:
- case VideoFrame::I420:
- case VideoFrame::YV12J:
- switch (plane) {
- case kYPlane:
- return width;
- case kUPlane:
- case kVPlane:
- return RoundUp(width, 2) / 2;
- default:
- break;
- }
- break;
- case VideoFrame::YV12A:
- switch (plane) {
- case kYPlane:
- case kAPlane:
- return width;
- case kUPlane:
- case kVPlane:
- return RoundUp(width, 2) / 2;
- default:
- break;
- }
- break;
- case VideoFrame::NV12:
- switch (plane) {
- case kYPlane:
- case kUVPlane:
- return width;
- default:
- break;
- }
- break;
- case VideoFrame::UNKNOWN:
-#if defined(VIDEO_HOLE)
- case VideoFrame::HOLE:
-#endif // defined(VIDEO_HOLE)
- case VideoFrame::NATIVE_TEXTURE:
- break;
- }
- NOTREACHED() << "Unsupported video frame format/plane: " << format << "/"
- << plane;
- return 0;
+ return BytesPerElement(format, plane) * Columns(plane, format, width);
}
int VideoFrame::row_bytes(size_t plane) const {
@@ -818,74 +688,53 @@ int VideoFrame::row_bytes(size_t plane) const {
// static
size_t VideoFrame::Rows(size_t plane, VideoFrame::Format format, int height) {
DCHECK(IsValidPlane(plane, format));
- switch (format) {
- case VideoFrame::YV24:
- case VideoFrame::YV16:
- switch (plane) {
- case kYPlane:
- case kUPlane:
- case kVPlane:
- return height;
- default:
- break;
- }
- break;
- case VideoFrame::YV12:
- case VideoFrame::YV12J:
- case VideoFrame::I420:
- switch (plane) {
- case kYPlane:
- return height;
- case kUPlane:
- case kVPlane:
- return RoundUp(height, 2) / 2;
- default:
- break;
- }
- break;
- case VideoFrame::YV12A:
- switch (plane) {
- case kYPlane:
- case kAPlane:
- return height;
- case kUPlane:
- case kVPlane:
- return RoundUp(height, 2) / 2;
- default:
- break;
- }
- break;
- case VideoFrame::NV12:
- switch (plane) {
- case kYPlane:
- return height;
- case kUVPlane:
- return RoundUp(height, 2) / 2;
- default:
- break;
- }
- break;
- case VideoFrame::UNKNOWN:
-#if defined(VIDEO_HOLE)
- case VideoFrame::HOLE:
-#endif // defined(VIDEO_HOLE)
- case VideoFrame::NATIVE_TEXTURE:
- break;
- }
- NOTREACHED() << "Unsupported video frame format/plane: " << format << "/"
- << plane;
- return 0;
+ const int sample_height = SampleSize(format, plane).height();
+ return RoundUp(height, sample_height) / sample_height;
+}
+
+// static
+size_t VideoFrame::Columns(size_t plane, Format format, int width) {
+ DCHECK(IsValidPlane(plane, format));
+ const int sample_width = SampleSize(format, plane).width();
+ return RoundUp(width, sample_width) / sample_width;
}
int VideoFrame::rows(size_t plane) const {
return Rows(plane, format_, coded_size_.height());
}
-uint8* VideoFrame::data(size_t plane) const {
+const uint8* VideoFrame::data(size_t plane) const {
DCHECK(IsValidPlane(plane, format_));
return data_[plane];
}
+uint8* VideoFrame::data(size_t plane) {
+ DCHECK(IsValidPlane(plane, format_));
+ return data_[plane];
+}
+
+const uint8* VideoFrame::visible_data(size_t plane) const {
+ DCHECK(IsValidPlane(plane, format_));
+
+ // Calculate an offset that is properly aligned for all planes.
+ const gfx::Size alignment = CommonAlignment(format_);
+ const gfx::Point offset(RoundDown(visible_rect_.x(), alignment.width()),
+ RoundDown(visible_rect_.y(), alignment.height()));
+
+ const gfx::Size subsample = SampleSize(format_, plane);
+ DCHECK(offset.x() % subsample.width() == 0);
+ DCHECK(offset.y() % subsample.height() == 0);
+ return data(plane) +
+ stride(plane) * (offset.y() / subsample.height()) + // Row offset.
+ BytesPerElement(format_, plane) * // Column offset.
+ (offset.x() / subsample.width());
+}
+
+uint8* VideoFrame::visible_data(size_t plane) {
+ return const_cast<uint8*>(
+ static_cast<const VideoFrame*>(this)->visible_data(plane));
+}
+
const gpu::MailboxHolder* VideoFrame::mailbox_holder() const {
DCHECK_EQ(format_, NATIVE_TEXTURE);
return mailbox_holder_.get();
@@ -919,9 +768,7 @@ CVPixelBufferRef VideoFrame::cv_pixel_buffer() const {
#endif
void VideoFrame::HashFrameForTesting(base::MD5Context* context) {
- for (int plane = 0; plane < kMaxPlanes; ++plane) {
- if (!IsValidPlane(plane, format_))
- break;
+ for (size_t plane = 0; plane < NumPlanes(format_); ++plane) {
for (int row = 0; row < rows(plane); ++row) {
base::MD5Update(context, base::StringPiece(
reinterpret_cast<char*>(data(plane) + stride(plane) * row),
« no previous file with comments | « media/base/video_frame.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698