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

Side by Side Diff: media/base/video_frame.cc

Issue 839523002: V4L2VDA: Generalize EGLImage import and query driver for output formats. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/video_frame.h" 5 #include "media/base/video_frame.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 case VideoFrame::I420: 60 case VideoFrame::I420:
61 case VideoFrame::YV12A: 61 case VideoFrame::YV12A:
62 case VideoFrame::NV12: 62 case VideoFrame::NV12:
63 return gfx::Size(2, 2); 63 return gfx::Size(2, 2);
64 64
65 case VideoFrame::UNKNOWN: 65 case VideoFrame::UNKNOWN:
66 #if defined(VIDEO_HOLE) 66 #if defined(VIDEO_HOLE)
67 case VideoFrame::HOLE: 67 case VideoFrame::HOLE:
68 #endif // defined(VIDEO_HOLE) 68 #endif // defined(VIDEO_HOLE)
69 case VideoFrame::NATIVE_TEXTURE: 69 case VideoFrame::NATIVE_TEXTURE:
70 case VideoFrame::ARGB:
70 break; 71 break;
71 } 72 }
72 } 73 }
73 NOTREACHED(); 74 NOTREACHED();
74 return gfx::Size(); 75 return gfx::Size();
75 } 76 }
76 77
77 // Return the alignment for the whole frame, calculated as the max of the 78 // Return the alignment for the whole frame, calculated as the max of the
78 // alignment for each individual plane. 79 // alignment for each individual plane.
79 static gfx::Size CommonAlignment(VideoFrame::Format format) { 80 static gfx::Size CommonAlignment(VideoFrame::Format format) {
80 int max_sample_width = 0; 81 int max_sample_width = 0;
81 int max_sample_height = 0; 82 int max_sample_height = 0;
82 for (size_t plane = 0; plane < VideoFrame::NumPlanes(format); ++plane) { 83 for (size_t plane = 0; plane < VideoFrame::NumPlanes(format); ++plane) {
83 const gfx::Size sample_size = SampleSize(format, plane); 84 const gfx::Size sample_size = SampleSize(format, plane);
84 max_sample_width = std::max(max_sample_width, sample_size.width()); 85 max_sample_width = std::max(max_sample_width, sample_size.width());
85 max_sample_height = std::max(max_sample_height, sample_size.height()); 86 max_sample_height = std::max(max_sample_height, sample_size.height());
86 } 87 }
87 return gfx::Size(max_sample_width, max_sample_height); 88 return gfx::Size(max_sample_width, max_sample_height);
88 } 89 }
89 90
90 // Returns the number of bytes per element for given |plane| and |format|. E.g. 91 // Returns the number of bytes per element for given |plane| and |format|. E.g.
91 // 2 for the UV plane in NV12. 92 // 2 for the UV plane in NV12.
92 static int BytesPerElement(VideoFrame::Format format, size_t plane) { 93 static int BytesPerElement(VideoFrame::Format format, size_t plane) {
93 DCHECK(VideoFrame::IsValidPlane(plane, format)); 94 DCHECK(VideoFrame::IsValidPlane(plane, format));
94 return (format == VideoFrame::NV12 && plane == VideoFrame::kUVPlane) ? 2 : 1; 95 if (format == VideoFrame::ARGB)
96 return 4;
97 else if (format == VideoFrame::NV12 && plane == VideoFrame::kUVPlane)
98 return 2;
99 else
100 return 1;
95 } 101 }
96 102
97 // Rounds up |coded_size| if necessary for |format|. 103 // Rounds up |coded_size| if necessary for |format|.
98 static gfx::Size AdjustCodedSize(VideoFrame::Format format, 104 static gfx::Size AdjustCodedSize(VideoFrame::Format format,
99 const gfx::Size& coded_size) { 105 const gfx::Size& coded_size) {
100 const gfx::Size alignment = CommonAlignment(format); 106 const gfx::Size alignment = CommonAlignment(format);
101 return gfx::Size(RoundUp(coded_size.width(), alignment.width()), 107 return gfx::Size(RoundUp(coded_size.width(), alignment.width()),
102 RoundUp(coded_size.height(), alignment.height())); 108 RoundUp(coded_size.height(), alignment.height()));
103 } 109 }
104 110
105 // static 111 // static
106 scoped_refptr<VideoFrame> VideoFrame::CreateFrame( 112 scoped_refptr<VideoFrame> VideoFrame::CreateFrame(
107 VideoFrame::Format format, 113 VideoFrame::Format format,
108 const gfx::Size& coded_size, 114 const gfx::Size& coded_size,
109 const gfx::Rect& visible_rect, 115 const gfx::Rect& visible_rect,
110 const gfx::Size& natural_size, 116 const gfx::Size& natural_size,
111 base::TimeDelta timestamp) { 117 base::TimeDelta timestamp) {
112 DCHECK(format != VideoFrame::UNKNOWN && 118 switch (format) {
113 format != VideoFrame::NV12 && 119 case VideoFrame::UNKNOWN:
114 format != VideoFrame::NATIVE_TEXTURE); 120 case VideoFrame::NV12:
121 case VideoFrame::NATIVE_TEXTURE:
115 #if defined(VIDEO_HOLE) 122 #if defined(VIDEO_HOLE)
116 DCHECK(format != VideoFrame::HOLE); 123 case VideoFrame::HOLE:
117 #endif // defined(VIDEO_HOLE) 124 #endif // defined(VIDEO_HOLE)
125 case VideoFrame::ARGB:
126 NOTIMPLEMENTED();
127 return nullptr;
128 default:
129 break;
130 }
118 131
119 // Since we're creating a new YUV frame (and allocating memory for it 132 // Since we're creating a new YUV frame (and allocating memory for it
120 // ourselves), we can pad the requested |coded_size| if necessary if the 133 // ourselves), we can pad the requested |coded_size| if necessary if the
121 // request does not line up on sample boundaries. 134 // request does not line up on sample boundaries.
122 const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size); 135 const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
123 DCHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size)); 136 DCHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size));
124 137
125 scoped_refptr<VideoFrame> frame( 138 scoped_refptr<VideoFrame> frame(
126 new VideoFrame(format, 139 new VideoFrame(format,
127 new_coded_size, 140 new_coded_size,
(...skipping 24 matching lines...) Expand all
152 return "HOLE"; 165 return "HOLE";
153 #endif // defined(VIDEO_HOLE) 166 #endif // defined(VIDEO_HOLE)
154 case VideoFrame::YV12A: 167 case VideoFrame::YV12A:
155 return "YV12A"; 168 return "YV12A";
156 case VideoFrame::YV12J: 169 case VideoFrame::YV12J:
157 return "YV12J"; 170 return "YV12J";
158 case VideoFrame::NV12: 171 case VideoFrame::NV12:
159 return "NV12"; 172 return "NV12";
160 case VideoFrame::YV24: 173 case VideoFrame::YV24:
161 return "YV24"; 174 return "YV24";
175 case VideoFrame::ARGB:
176 return "ARGB";
162 } 177 }
163 NOTREACHED() << "Invalid videoframe format provided: " << format; 178 NOTREACHED() << "Invalid videoframe format provided: " << format;
164 return ""; 179 return "";
165 } 180 }
166 181
167 // static 182 // static
168 bool VideoFrame::IsValidConfig(VideoFrame::Format format, 183 bool VideoFrame::IsValidConfig(VideoFrame::Format format,
169 const gfx::Size& coded_size, 184 const gfx::Size& coded_size,
170 const gfx::Rect& visible_rect, 185 const gfx::Rect& visible_rect,
171 const gfx::Size& natural_size) { 186 const gfx::Size& natural_size) {
(...skipping 23 matching lines...) Expand all
195 #endif // defined(VIDEO_HOLE) 210 #endif // defined(VIDEO_HOLE)
196 return true; 211 return true;
197 212
198 case VideoFrame::YV24: 213 case VideoFrame::YV24:
199 case VideoFrame::YV12: 214 case VideoFrame::YV12:
200 case VideoFrame::YV12J: 215 case VideoFrame::YV12J:
201 case VideoFrame::I420: 216 case VideoFrame::I420:
202 case VideoFrame::YV12A: 217 case VideoFrame::YV12A:
203 case VideoFrame::NV12: 218 case VideoFrame::NV12:
204 case VideoFrame::YV16: 219 case VideoFrame::YV16:
220 case VideoFrame::ARGB:
205 // Check that software-allocated buffer formats are aligned correctly and 221 // Check that software-allocated buffer formats are aligned correctly and
206 // not empty. 222 // not empty.
207 const gfx::Size alignment = CommonAlignment(format); 223 const gfx::Size alignment = CommonAlignment(format);
208 return RoundUp(visible_rect.right(), alignment.width()) <= 224 return RoundUp(visible_rect.right(), alignment.width()) <=
209 static_cast<size_t>(coded_size.width()) && 225 static_cast<size_t>(coded_size.width()) &&
210 RoundUp(visible_rect.bottom(), alignment.height()) <= 226 RoundUp(visible_rect.bottom(), alignment.height()) <=
211 static_cast<size_t>(coded_size.height()) && 227 static_cast<size_t>(coded_size.height()) &&
212 !coded_size.IsEmpty() && !visible_rect.IsEmpty() && 228 !coded_size.IsEmpty() && !visible_rect.IsEmpty() &&
213 !natural_size.IsEmpty(); 229 !natural_size.IsEmpty();
214 } 230 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 Format format, 313 Format format,
298 const gfx::Size& coded_size, 314 const gfx::Size& coded_size,
299 const gfx::Rect& visible_rect, 315 const gfx::Rect& visible_rect,
300 const gfx::Size& natural_size, 316 const gfx::Size& natural_size,
301 const std::vector<int> dmabuf_fds, 317 const std::vector<int> dmabuf_fds,
302 base::TimeDelta timestamp, 318 base::TimeDelta timestamp,
303 const base::Closure& no_longer_needed_cb) { 319 const base::Closure& no_longer_needed_cb) {
304 if (!IsValidConfig(format, coded_size, visible_rect, natural_size)) 320 if (!IsValidConfig(format, coded_size, visible_rect, natural_size))
305 return NULL; 321 return NULL;
306 322
323 // TODO(posciak): This is not exactly correct, it's possible for one
324 // buffer to contain more than one plane.
307 if (dmabuf_fds.size() != NumPlanes(format)) { 325 if (dmabuf_fds.size() != NumPlanes(format)) {
308 LOG(FATAL) << "Not enough dmabuf fds provided!"; 326 LOG(FATAL) << "Not enough dmabuf fds provided!";
309 return NULL; 327 return NULL;
310 } 328 }
311 329
312 scoped_refptr<VideoFrame> frame( 330 scoped_refptr<VideoFrame> frame(
313 new VideoFrame(format, 331 new VideoFrame(format,
314 coded_size, 332 coded_size,
315 visible_rect, 333 visible_rect,
316 natural_size, 334 natural_size,
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 #endif // defined(VIDEO_HOLE) 533 #endif // defined(VIDEO_HOLE)
516 534
517 // static 535 // static
518 size_t VideoFrame::NumPlanes(Format format) { 536 size_t VideoFrame::NumPlanes(Format format) {
519 switch (format) { 537 switch (format) {
520 case VideoFrame::NATIVE_TEXTURE: 538 case VideoFrame::NATIVE_TEXTURE:
521 #if defined(VIDEO_HOLE) 539 #if defined(VIDEO_HOLE)
522 case VideoFrame::HOLE: 540 case VideoFrame::HOLE:
523 #endif // defined(VIDEO_HOLE) 541 #endif // defined(VIDEO_HOLE)
524 return 0; 542 return 0;
543 case VideoFrame::ARGB:
544 return 1;
525 case VideoFrame::NV12: 545 case VideoFrame::NV12:
526 return 2; 546 return 2;
527 case VideoFrame::YV12: 547 case VideoFrame::YV12:
528 case VideoFrame::YV16: 548 case VideoFrame::YV16:
529 case VideoFrame::I420: 549 case VideoFrame::I420:
530 case VideoFrame::YV12J: 550 case VideoFrame::YV12J:
531 case VideoFrame::YV24: 551 case VideoFrame::YV24:
532 return 3; 552 return 3;
533 case VideoFrame::YV12A: 553 case VideoFrame::YV12A:
534 return 4; 554 return 4;
(...skipping 12 matching lines...) Expand all
547 total += PlaneAllocationSize(format, i, coded_size); 567 total += PlaneAllocationSize(format, i, coded_size);
548 return total; 568 return total;
549 } 569 }
550 570
551 // static 571 // static
552 gfx::Size VideoFrame::PlaneSize(Format format, 572 gfx::Size VideoFrame::PlaneSize(Format format,
553 size_t plane, 573 size_t plane,
554 const gfx::Size& coded_size) { 574 const gfx::Size& coded_size) {
555 DCHECK(IsValidPlane(plane, format)); 575 DCHECK(IsValidPlane(plane, format));
556 576
557 // Align to multiple-of-two size overall. This ensures that non-subsampled 577 int width = RoundUp(coded_size.width(), 2);
kcwu 2015/01/06 08:28:52 Looks like you want to round up conditionally. Did
Pawel Osciak 2015/01/06 13:09:58 Done.
558 // planes can be addressed by pixel with the same scaling as the subsampled 578 int height = RoundUp(coded_size.height(), 2);
559 // planes. 579 if (format != VideoFrame::ARGB) {
560 const int width = RoundUp(coded_size.width(), 2); 580 // Align to multiple-of-two size overall. This ensures that non-subsampled
561 const int height = RoundUp(coded_size.height(), 2); 581 // planes can be addressed by pixel with the same scaling as the subsampled
582 // planes.
583 width = RoundUp(width, 2);
584 height = RoundUp(height, 2);
585 }
562 586
563 const gfx::Size subsample = SampleSize(format, plane); 587 const gfx::Size subsample = SampleSize(format, plane);
564 DCHECK(width % subsample.width() == 0); 588 DCHECK(width % subsample.width() == 0);
565 DCHECK(height % subsample.height() == 0); 589 DCHECK(height % subsample.height() == 0);
566 return gfx::Size(BytesPerElement(format, plane) * width / subsample.width(), 590 return gfx::Size(BytesPerElement(format, plane) * width / subsample.width(),
567 height / subsample.height()); 591 height / subsample.height());
568 } 592 }
569 593
570 size_t VideoFrame::PlaneAllocationSize(Format format, 594 size_t VideoFrame::PlaneAllocationSize(Format format,
571 size_t plane, 595 size_t plane,
572 const gfx::Size& coded_size) { 596 const gfx::Size& coded_size) {
573 // VideoFrame formats are (so far) all YUV and 1 byte per sample.
574 return PlaneSize(format, plane, coded_size).GetArea(); 597 return PlaneSize(format, plane, coded_size).GetArea();
575 } 598 }
576 599
577 // static 600 // static
578 int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) { 601 int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) {
579 DCHECK(IsValidPlane(plane, format)); 602 DCHECK(IsValidPlane(plane, format));
580 const int bits_per_element = 8 * BytesPerElement(format, plane); 603 const int bits_per_element = 8 * BytesPerElement(format, plane);
581 const int pixels_per_element = SampleSize(format, plane).width(); 604 const int horiz_pixels_per_element = SampleSize(format, plane).width();
582 DCHECK(bits_per_element % pixels_per_element == 0); 605 DCHECK_EQ(bits_per_element % horiz_pixels_per_element, 0);
583 return bits_per_element / pixels_per_element; 606 return bits_per_element / horiz_pixels_per_element;
584 } 607 }
585 608
586 // static 609 // static
587 int VideoFrame::PlaneBitsPerPixel(Format format, size_t plane) { 610 int VideoFrame::PlaneBitsPerPixel(Format format, size_t plane) {
588 DCHECK(IsValidPlane(plane, format)); 611 DCHECK(IsValidPlane(plane, format));
589 return PlaneHorizontalBitsPerPixel(format, plane) / 612 return PlaneHorizontalBitsPerPixel(format, plane) /
590 SampleSize(format, plane).height(); 613 SampleSize(format, plane).height();
591 } 614 }
592 615
593 // Release data allocated by AllocateYUV(). 616 // Release data allocated by AllocateYUV().
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 for (size_t plane = 0; plane < NumPlanes(format_); ++plane) { 801 for (size_t plane = 0; plane < NumPlanes(format_); ++plane) {
779 for (int row = 0; row < rows(plane); ++row) { 802 for (int row = 0; row < rows(plane); ++row) {
780 base::MD5Update(context, base::StringPiece( 803 base::MD5Update(context, base::StringPiece(
781 reinterpret_cast<char*>(data(plane) + stride(plane) * row), 804 reinterpret_cast<char*>(data(plane) + stride(plane) * row),
782 row_bytes(plane))); 805 row_bytes(plane)));
783 } 806 }
784 } 807 }
785 } 808 }
786 809
787 } // namespace media 810 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698