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

Unified Diff: media/base/video_frame.cc

Issue 289373011: Support for YUV 4:4:4 subsampling. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Software path. Created 6 years, 7 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
Index: media/base/video_frame.cc
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 089af93c0c88d11e68e5583fc94ac5163a9f6cca..4df8dff2c3453c25dec707cca57ecd06f7a81e60 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::I444:
+ break;
case VideoFrame::YV12:
case VideoFrame::YV12A:
case VideoFrame::I420:
@@ -85,6 +87,8 @@ std::string VideoFrame::FormatToString(VideoFrame::Format format) {
return "YV12J";
case VideoFrame::NV12:
return "NV12";
+ case VideoFrame::I444:
+ return "I444";
}
NOTREACHED() << "Invalid videoframe format provided: " << format;
return "";
@@ -112,12 +116,14 @@ bool VideoFrame::IsValidConfig(VideoFrame::Format format,
case VideoFrame::UNKNOWN:
return (coded_size.IsEmpty() && visible_rect.IsEmpty() &&
natural_size.IsEmpty());
+ case VideoFrame::I444:
+ 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;
@@ -390,6 +396,7 @@ size_t VideoFrame::NumPlanes(Format format) {
case VideoFrame::YV16:
case VideoFrame::I420:
case VideoFrame::YV12J:
+ case VideoFrame::I444:
return 3;
case VideoFrame::YV12A:
return 4;
@@ -413,12 +420,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::I444:
+ 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 +448,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 +460,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 +471,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 +481,7 @@ gfx::Size VideoFrame::PlaneSize(Format format,
default:
break;
}
- }
+ break;
case VideoFrame::UNKNOWN:
case VideoFrame::NATIVE_TEXTURE:
#if defined(VIDEO_HOLE)
@@ -484,14 +504,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::I444:
+ 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 +527,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 +549,12 @@ int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) {
default:
break;
}
- }
+ break;
default:
scherkus (not reviewing) 2014/05/22 23:45:11 can you replace the default cases w/ the other for
sandersd (OOO until July 31) 2014/05/23 00:45:22 Done.
break;
}
-
- NOTREACHED() << "Unsupported video frame format: " << format;
+ NOTREACHED() << "Unsupported video frame format/plane: "
+ << format << "/" << plane;
return 0;
}
@@ -530,7 +567,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::I444);
// 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 +578,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().
@@ -627,69 +664,117 @@ int VideoFrame::stride(size_t plane) const {
int VideoFrame::row_bytes(size_t plane) const {
DCHECK(IsValidPlane(plane));
int width = coded_size_.width();
+ // Intentionally leave out non-production formats.
switch (format_) {
- // Planar, 8bpp.
- case YV12A:
- if (plane == kAPlane)
- return width;
- // Fallthrough.
+ case I444:
+ switch (plane) {
+ case kYPlane:
+ case kUPlane:
+ case kVPlane:
+ return width;
+ default:
+ break;
+ }
+ break;
case YV12:
case YV16:
case I420:
case YV12J:
- if (plane == kYPlane)
- return width;
- else if (plane <= kVPlane)
- return RoundUp(width, 2) / 2;
+ switch (plane) {
+ case kYPlane:
+ return width;
+ case kUPlane:
+ case kVPlane:
+ return RoundUp(width, 2) / 2;
+ default:
+ break;
+ }
+ break;
+ case YV12A:
+ switch (plane) {
+ case kYPlane:
+ case kAPlane:
+ return width;
+ case kUPlane:
+ case kVPlane:
+ return RoundUp(width, 2) / 2;
+ default:
+ break;
+ }
break;
-
case NV12:
- if (plane <= kUVPlane)
- return width;
+ switch (plane) {
+ case kYPlane:
+ case kUVPlane:
+ return width;
+ default:
+ break;
+ }
break;
-
default:
scherkus (not reviewing) 2014/05/22 23:45:11 ditto -- and remove the comment about intentionall
sandersd (OOO until July 31) 2014/05/23 00:45:22 Done.
break;
}
-
- // Intentionally leave out non-production formats.
- NOTREACHED() << "Unsupported video frame format: " << format_;
+ NOTREACHED() << "Unsupported video frame format/plane: "
+ << format_ << "/" << plane;
return 0;
}
int VideoFrame::rows(size_t plane) const {
DCHECK(IsValidPlane(plane));
int height = coded_size_.height();
+ // Intentionally leave out non-production formats.
switch (format_) {
+ case I444:
case YV16:
- return height;
-
- case YV12A:
- if (plane == kAPlane)
- return height;
- // Fallthrough.
+ switch (plane) {
+ case kYPlane:
+ case kUPlane:
+ case kVPlane:
+ return height;
+ default:
+ break;
+ }
+ break;
case YV12:
case YV12J:
case I420:
- if (plane == kYPlane)
- return height;
- else if (plane <= kVPlane)
- return RoundUp(height, 2) / 2;
+ switch (plane) {
+ case kYPlane:
+ return height;
+ case kUPlane:
+ case kVPlane:
+ return RoundUp(height, 2) / 2;
+ default:
+ break;
+ }
+ break;
+ case YV12A:
+ switch (plane) {
+ case kYPlane:
+ case kAPlane:
+ return height;
+ case kUPlane:
+ case kVPlane:
+ return RoundUp(height, 2) / 2;
+ default:
+ break;
+ }
break;
-
case NV12:
- if (plane == kYPlane)
- return height;
- else if (plane == kUVPlane)
- return RoundUp(height, 2) / 2;
+ switch (plane) {
+ case kYPlane:
+ return height;
+ case kUVPlane:
+ return RoundUp(height, 2) / 2;
+ default:
+ break;
+ }
break;
-
default:
scherkus (not reviewing) 2014/05/22 23:45:11 ditto
sandersd (OOO until July 31) 2014/05/23 00:45:22 Done.
break;
}
-
- // Intentionally leave out non-production formats.
- NOTREACHED() << "Unsupported video frame format: " << format_;
+ NOTREACHED() << "Unsupported video frame format/plane: "
+ << format_ << "/" << plane;
return 0;
}

Powered by Google App Engine
This is Rietveld 408576698