Index: media/base/video_frame.cc |
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc |
index 089af93c0c88d11e68e5583fc94ac5163a9f6cca..272d41dc4c691597a227abbaab023a31a86fc98d 100644 |
--- a/media/base/video_frame.cc |
+++ b/media/base/video_frame.cc |
@@ -36,6 +36,8 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrame( |
// request does not line up on sample boundaries. |
gfx::Size new_coded_size(coded_size); |
switch (format) { |
+ case VideoFrame::YV24: |
+ break; |
case VideoFrame::YV12: |
case VideoFrame::YV12A: |
case VideoFrame::I420: |
@@ -45,7 +47,12 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrame( |
case VideoFrame::YV16: |
new_coded_size.set_width((new_coded_size.width() + 1) / 2 * 2); |
break; |
- default: |
+ case VideoFrame::UNKNOWN: |
+ case VideoFrame::NV12: |
+#if defined(VIDEO_HOLE) |
+ case VideoFrame::HOLE: |
+#endif // defined(VIDEO_HOLE) |
+ case VideoFrame::NATIVE_TEXTURE: |
LOG(FATAL) << "Only YUV formats supported: " << format; |
return NULL; |
} |
@@ -85,6 +92,8 @@ std::string VideoFrame::FormatToString(VideoFrame::Format format) { |
return "YV12J"; |
case VideoFrame::NV12: |
return "NV12"; |
+ case VideoFrame::YV24: |
+ return "YV24"; |
} |
NOTREACHED() << "Invalid videoframe format provided: " << format; |
return ""; |
@@ -112,12 +121,14 @@ bool VideoFrame::IsValidConfig(VideoFrame::Format format, |
case VideoFrame::UNKNOWN: |
return (coded_size.IsEmpty() && visible_rect.IsEmpty() && |
natural_size.IsEmpty()); |
+ case VideoFrame::YV24: |
+ break; |
case VideoFrame::YV12: |
case VideoFrame::YV12J: |
case VideoFrame::I420: |
case VideoFrame::YV12A: |
case VideoFrame::NV12: |
- // YUV formats have width/height requirements due to chroma subsampling. |
+ // Subsampled YUV formats have width/height requirements. |
if (static_cast<size_t>(coded_size.height()) < |
RoundUp(visible_rect.bottom(), 2)) |
return false; |
@@ -186,7 +197,7 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalPackedMemory( |
return NULL; |
switch (format) { |
- case I420: { |
+ case VideoFrame::I420: { |
scoped_refptr<VideoFrame> frame( |
new VideoFrame(format, |
coded_size, |
@@ -390,6 +401,7 @@ size_t VideoFrame::NumPlanes(Format format) { |
case VideoFrame::YV16: |
case VideoFrame::I420: |
case VideoFrame::YV12J: |
+ case VideoFrame::YV24: |
return 3; |
case VideoFrame::YV12A: |
return 4; |
@@ -413,12 +425,25 @@ 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) { |
+ // 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: { |
+ case VideoFrame::I420: |
switch (plane) { |
case VideoFrame::kYPlane: |
return gfx::Size(width, height); |
@@ -428,8 +453,8 @@ gfx::Size VideoFrame::PlaneSize(Format format, |
default: |
break; |
} |
- } |
- case VideoFrame::YV12A: { |
+ break; |
+ case VideoFrame::YV12A: |
switch (plane) { |
case VideoFrame::kYPlane: |
case VideoFrame::kAPlane: |
@@ -440,8 +465,8 @@ gfx::Size VideoFrame::PlaneSize(Format format, |
default: |
break; |
} |
- } |
- case VideoFrame::YV16: { |
+ break; |
+ case VideoFrame::YV16: |
switch (plane) { |
case VideoFrame::kYPlane: |
return gfx::Size(width, height); |
@@ -451,8 +476,8 @@ gfx::Size VideoFrame::PlaneSize(Format format, |
default: |
break; |
} |
- } |
- case VideoFrame::NV12: { |
+ break; |
+ case VideoFrame::NV12: |
switch (plane) { |
case VideoFrame::kYPlane: |
return gfx::Size(width, height); |
@@ -461,7 +486,7 @@ gfx::Size VideoFrame::PlaneSize(Format format, |
default: |
break; |
} |
- } |
+ break; |
case VideoFrame::UNKNOWN: |
case VideoFrame::NATIVE_TEXTURE: |
#if defined(VIDEO_HOLE) |
@@ -484,14 +509,20 @@ size_t VideoFrame::PlaneAllocationSize(Format format, |
// static |
int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) { |
switch (format) { |
- case VideoFrame::YV12A: |
- if (plane == kAPlane) |
- return 8; |
- // fallthrough |
+ 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: { |
+ case VideoFrame::YV12J: |
switch (plane) { |
case kYPlane: |
return 8; |
@@ -501,9 +532,20 @@ int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) { |
default: |
break; |
} |
- } |
- |
- case VideoFrame::NV12: { |
+ 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; |
@@ -512,12 +554,16 @@ int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) { |
default: |
break; |
} |
- } |
- default: |
+ 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: " << format; |
+ NOTREACHED() << "Unsupported video frame format/plane: " |
+ << format << "/" << plane; |
return 0; |
} |
@@ -530,7 +576,7 @@ 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::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 |
@@ -541,11 +587,11 @@ void VideoFrame::AllocateYUV() { |
// 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(). |
@@ -628,32 +674,60 @@ int VideoFrame::row_bytes(size_t plane) const { |
DCHECK(IsValidPlane(plane)); |
int width = coded_size_.width(); |
switch (format_) { |
- // Planar, 8bpp. |
- case YV12A: |
- if (plane == kAPlane) |
- return width; |
- // Fallthrough. |
- case YV12: |
- case YV16: |
- case I420: |
- case YV12J: |
- if (plane == kYPlane) |
- return width; |
- else if (plane <= kVPlane) |
- return RoundUp(width, 2) / 2; |
+ case VideoFrame::YV24: |
+ switch (plane) { |
+ case kYPlane: |
+ case kUPlane: |
+ case kVPlane: |
+ return width; |
+ default: |
+ break; |
+ } |
break; |
- |
- case NV12: |
- if (plane <= kUVPlane) |
- return width; |
+ 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; |
- |
- default: |
+ 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; |
} |
- |
- // Intentionally leave out non-production formats. |
- NOTREACHED() << "Unsupported video frame format: " << format_; |
+ NOTREACHED() << "Unsupported video frame format/plane: " |
+ << format_ << "/" << plane; |
return 0; |
} |
@@ -661,35 +735,61 @@ int VideoFrame::rows(size_t plane) const { |
DCHECK(IsValidPlane(plane)); |
int height = coded_size_.height(); |
switch (format_) { |
- case YV16: |
- return height; |
- |
- case YV12A: |
- if (plane == kAPlane) |
- return height; |
- // Fallthrough. |
- case YV12: |
- case YV12J: |
- case I420: |
- if (plane == kYPlane) |
- return height; |
- else if (plane <= kVPlane) |
- return RoundUp(height, 2) / 2; |
+ case VideoFrame::YV24: |
+ case VideoFrame::YV16: |
+ switch (plane) { |
+ case kYPlane: |
+ case kUPlane: |
+ case kVPlane: |
+ return height; |
+ default: |
+ break; |
+ } |
break; |
- |
- case NV12: |
- if (plane == kYPlane) |
- return height; |
- else if (plane == kUVPlane) |
- return RoundUp(height, 2) / 2; |
+ 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; |
- |
- default: |
+ 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; |
} |
- |
- // Intentionally leave out non-production formats. |
- NOTREACHED() << "Unsupported video frame format: " << format_; |
+ NOTREACHED() << "Unsupported video frame format/plane: " |
+ << format_ << "/" << plane; |
return 0; |
} |