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

Side by Side 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: Try that again. Created 6 years, 6 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
« no previous file with comments | « media/base/video_frame.h ('k') | media/ffmpeg/ffmpeg_common.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 18 matching lines...) Expand all
29 VideoFrame::Format format, 29 VideoFrame::Format format,
30 const gfx::Size& coded_size, 30 const gfx::Size& coded_size,
31 const gfx::Rect& visible_rect, 31 const gfx::Rect& visible_rect,
32 const gfx::Size& natural_size, 32 const gfx::Size& natural_size,
33 base::TimeDelta timestamp) { 33 base::TimeDelta timestamp) {
34 // Since we're creating a new YUV frame (and allocating memory for it 34 // Since we're creating a new YUV frame (and allocating memory for it
35 // ourselves), we can pad the requested |coded_size| if necessary if the 35 // ourselves), we can pad the requested |coded_size| if necessary if the
36 // request does not line up on sample boundaries. 36 // request does not line up on sample boundaries.
37 gfx::Size new_coded_size(coded_size); 37 gfx::Size new_coded_size(coded_size);
38 switch (format) { 38 switch (format) {
39 case VideoFrame::YV24:
40 break;
39 case VideoFrame::YV12: 41 case VideoFrame::YV12:
40 case VideoFrame::YV12A: 42 case VideoFrame::YV12A:
41 case VideoFrame::I420: 43 case VideoFrame::I420:
42 case VideoFrame::YV12J: 44 case VideoFrame::YV12J:
43 new_coded_size.set_height((new_coded_size.height() + 1) / 2 * 2); 45 new_coded_size.set_height((new_coded_size.height() + 1) / 2 * 2);
44 // Fallthrough. 46 // Fallthrough.
45 case VideoFrame::YV16: 47 case VideoFrame::YV16:
46 new_coded_size.set_width((new_coded_size.width() + 1) / 2 * 2); 48 new_coded_size.set_width((new_coded_size.width() + 1) / 2 * 2);
47 break; 49 break;
48 default: 50 case VideoFrame::UNKNOWN:
51 case VideoFrame::NV12:
52 #if defined(VIDEO_HOLE)
53 case VideoFrame::HOLE:
54 #endif // defined(VIDEO_HOLE)
55 case VideoFrame::NATIVE_TEXTURE:
49 LOG(FATAL) << "Only YUV formats supported: " << format; 56 LOG(FATAL) << "Only YUV formats supported: " << format;
50 return NULL; 57 return NULL;
51 } 58 }
52 DCHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size)); 59 DCHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size));
53 scoped_refptr<VideoFrame> frame( 60 scoped_refptr<VideoFrame> frame(
54 new VideoFrame(format, 61 new VideoFrame(format,
55 new_coded_size, 62 new_coded_size,
56 visible_rect, 63 visible_rect,
57 natural_size, 64 natural_size,
58 scoped_ptr<gpu::MailboxHolder>(), 65 scoped_ptr<gpu::MailboxHolder>(),
(...skipping 19 matching lines...) Expand all
78 #if defined(VIDEO_HOLE) 85 #if defined(VIDEO_HOLE)
79 case VideoFrame::HOLE: 86 case VideoFrame::HOLE:
80 return "HOLE"; 87 return "HOLE";
81 #endif // defined(VIDEO_HOLE) 88 #endif // defined(VIDEO_HOLE)
82 case VideoFrame::YV12A: 89 case VideoFrame::YV12A:
83 return "YV12A"; 90 return "YV12A";
84 case VideoFrame::YV12J: 91 case VideoFrame::YV12J:
85 return "YV12J"; 92 return "YV12J";
86 case VideoFrame::NV12: 93 case VideoFrame::NV12:
87 return "NV12"; 94 return "NV12";
95 case VideoFrame::YV24:
96 return "YV24";
88 } 97 }
89 NOTREACHED() << "Invalid videoframe format provided: " << format; 98 NOTREACHED() << "Invalid videoframe format provided: " << format;
90 return ""; 99 return "";
91 } 100 }
92 101
93 // static 102 // static
94 bool VideoFrame::IsValidConfig(VideoFrame::Format format, 103 bool VideoFrame::IsValidConfig(VideoFrame::Format format,
95 const gfx::Size& coded_size, 104 const gfx::Size& coded_size,
96 const gfx::Rect& visible_rect, 105 const gfx::Rect& visible_rect,
97 const gfx::Size& natural_size) { 106 const gfx::Size& natural_size) {
98 // Check maximum limits for all formats. 107 // Check maximum limits for all formats.
99 if (coded_size.GetArea() > limits::kMaxCanvas || 108 if (coded_size.GetArea() > limits::kMaxCanvas ||
100 coded_size.width() > limits::kMaxDimension || 109 coded_size.width() > limits::kMaxDimension ||
101 coded_size.height() > limits::kMaxDimension || 110 coded_size.height() > limits::kMaxDimension ||
102 visible_rect.x() < 0 || visible_rect.y() < 0 || 111 visible_rect.x() < 0 || visible_rect.y() < 0 ||
103 visible_rect.right() > coded_size.width() || 112 visible_rect.right() > coded_size.width() ||
104 visible_rect.bottom() > coded_size.height() || 113 visible_rect.bottom() > coded_size.height() ||
105 natural_size.GetArea() > limits::kMaxCanvas || 114 natural_size.GetArea() > limits::kMaxCanvas ||
106 natural_size.width() > limits::kMaxDimension || 115 natural_size.width() > limits::kMaxDimension ||
107 natural_size.height() > limits::kMaxDimension) 116 natural_size.height() > limits::kMaxDimension)
108 return false; 117 return false;
109 118
110 // Check format-specific width/height requirements. 119 // Check format-specific width/height requirements.
111 switch (format) { 120 switch (format) {
112 case VideoFrame::UNKNOWN: 121 case VideoFrame::UNKNOWN:
113 return (coded_size.IsEmpty() && visible_rect.IsEmpty() && 122 return (coded_size.IsEmpty() && visible_rect.IsEmpty() &&
114 natural_size.IsEmpty()); 123 natural_size.IsEmpty());
124 case VideoFrame::YV24:
125 break;
115 case VideoFrame::YV12: 126 case VideoFrame::YV12:
116 case VideoFrame::YV12J: 127 case VideoFrame::YV12J:
117 case VideoFrame::I420: 128 case VideoFrame::I420:
118 case VideoFrame::YV12A: 129 case VideoFrame::YV12A:
119 case VideoFrame::NV12: 130 case VideoFrame::NV12:
120 // YUV formats have width/height requirements due to chroma subsampling. 131 // Subsampled YUV formats have width/height requirements.
121 if (static_cast<size_t>(coded_size.height()) < 132 if (static_cast<size_t>(coded_size.height()) <
122 RoundUp(visible_rect.bottom(), 2)) 133 RoundUp(visible_rect.bottom(), 2))
123 return false; 134 return false;
124 // Fallthrough. 135 // Fallthrough.
125 case VideoFrame::YV16: 136 case VideoFrame::YV16:
126 if (static_cast<size_t>(coded_size.width()) < 137 if (static_cast<size_t>(coded_size.width()) <
127 RoundUp(visible_rect.right(), 2)) 138 RoundUp(visible_rect.right(), 2))
128 return false; 139 return false;
129 break; 140 break;
130 case VideoFrame::NATIVE_TEXTURE: 141 case VideoFrame::NATIVE_TEXTURE:
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 size_t data_size, 190 size_t data_size,
180 base::SharedMemoryHandle handle, 191 base::SharedMemoryHandle handle,
181 base::TimeDelta timestamp, 192 base::TimeDelta timestamp,
182 const base::Closure& no_longer_needed_cb) { 193 const base::Closure& no_longer_needed_cb) {
183 if (!IsValidConfig(format, coded_size, visible_rect, natural_size)) 194 if (!IsValidConfig(format, coded_size, visible_rect, natural_size))
184 return NULL; 195 return NULL;
185 if (data_size < AllocationSize(format, coded_size)) 196 if (data_size < AllocationSize(format, coded_size))
186 return NULL; 197 return NULL;
187 198
188 switch (format) { 199 switch (format) {
189 case I420: { 200 case VideoFrame::I420: {
190 scoped_refptr<VideoFrame> frame( 201 scoped_refptr<VideoFrame> frame(
191 new VideoFrame(format, 202 new VideoFrame(format,
192 coded_size, 203 coded_size,
193 visible_rect, 204 visible_rect,
194 natural_size, 205 natural_size,
195 scoped_ptr<gpu::MailboxHolder>(), 206 scoped_ptr<gpu::MailboxHolder>(),
196 timestamp, 207 timestamp,
197 false)); 208 false));
198 frame->shared_memory_handle_ = handle; 209 frame->shared_memory_handle_ = handle;
199 frame->strides_[kYPlane] = coded_size.width(); 210 frame->strides_[kYPlane] = coded_size.width();
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 #if defined(VIDEO_HOLE) 394 #if defined(VIDEO_HOLE)
384 case VideoFrame::HOLE: 395 case VideoFrame::HOLE:
385 #endif // defined(VIDEO_HOLE) 396 #endif // defined(VIDEO_HOLE)
386 return 0; 397 return 0;
387 case VideoFrame::NV12: 398 case VideoFrame::NV12:
388 return 2; 399 return 2;
389 case VideoFrame::YV12: 400 case VideoFrame::YV12:
390 case VideoFrame::YV16: 401 case VideoFrame::YV16:
391 case VideoFrame::I420: 402 case VideoFrame::I420:
392 case VideoFrame::YV12J: 403 case VideoFrame::YV12J:
404 case VideoFrame::YV24:
393 return 3; 405 return 3;
394 case VideoFrame::YV12A: 406 case VideoFrame::YV12A:
395 return 4; 407 return 4;
396 case VideoFrame::UNKNOWN: 408 case VideoFrame::UNKNOWN:
397 break; 409 break;
398 } 410 }
399 NOTREACHED() << "Unsupported video frame format: " << format; 411 NOTREACHED() << "Unsupported video frame format: " << format;
400 return 0; 412 return 0;
401 } 413 }
402 414
403 415
404 // static 416 // static
405 size_t VideoFrame::AllocationSize(Format format, const gfx::Size& coded_size) { 417 size_t VideoFrame::AllocationSize(Format format, const gfx::Size& coded_size) {
406 size_t total = 0; 418 size_t total = 0;
407 for (size_t i = 0; i < NumPlanes(format); ++i) 419 for (size_t i = 0; i < NumPlanes(format); ++i)
408 total += PlaneAllocationSize(format, i, coded_size); 420 total += PlaneAllocationSize(format, i, coded_size);
409 return total; 421 return total;
410 } 422 }
411 423
412 // static 424 // static
413 gfx::Size VideoFrame::PlaneSize(Format format, 425 gfx::Size VideoFrame::PlaneSize(Format format,
414 size_t plane, 426 size_t plane,
415 const gfx::Size& coded_size) { 427 const gfx::Size& coded_size) {
428 // Align to multiple-of-two size overall. This ensures that non-subsampled
429 // planes can be addressed by pixel with the same scaling as the subsampled
430 // planes.
416 const int width = RoundUp(coded_size.width(), 2); 431 const int width = RoundUp(coded_size.width(), 2);
417 const int height = RoundUp(coded_size.height(), 2); 432 const int height = RoundUp(coded_size.height(), 2);
418 switch (format) { 433 switch (format) {
434 case VideoFrame::YV24:
435 switch (plane) {
436 case VideoFrame::kYPlane:
437 case VideoFrame::kUPlane:
438 case VideoFrame::kVPlane:
439 return gfx::Size(width, height);
440 default:
441 break;
442 }
443 break;
419 case VideoFrame::YV12: 444 case VideoFrame::YV12:
420 case VideoFrame::YV12J: 445 case VideoFrame::YV12J:
421 case VideoFrame::I420: { 446 case VideoFrame::I420:
422 switch (plane) { 447 switch (plane) {
423 case VideoFrame::kYPlane: 448 case VideoFrame::kYPlane:
424 return gfx::Size(width, height); 449 return gfx::Size(width, height);
425 case VideoFrame::kUPlane: 450 case VideoFrame::kUPlane:
426 case VideoFrame::kVPlane: 451 case VideoFrame::kVPlane:
427 return gfx::Size(width / 2, height / 2); 452 return gfx::Size(width / 2, height / 2);
428 default: 453 default:
429 break; 454 break;
430 } 455 }
431 } 456 break;
432 case VideoFrame::YV12A: { 457 case VideoFrame::YV12A:
433 switch (plane) { 458 switch (plane) {
434 case VideoFrame::kYPlane: 459 case VideoFrame::kYPlane:
435 case VideoFrame::kAPlane: 460 case VideoFrame::kAPlane:
436 return gfx::Size(width, height); 461 return gfx::Size(width, height);
437 case VideoFrame::kUPlane: 462 case VideoFrame::kUPlane:
438 case VideoFrame::kVPlane: 463 case VideoFrame::kVPlane:
439 return gfx::Size(width / 2, height / 2); 464 return gfx::Size(width / 2, height / 2);
440 default: 465 default:
441 break; 466 break;
442 } 467 }
443 } 468 break;
444 case VideoFrame::YV16: { 469 case VideoFrame::YV16:
445 switch (plane) { 470 switch (plane) {
446 case VideoFrame::kYPlane: 471 case VideoFrame::kYPlane:
447 return gfx::Size(width, height); 472 return gfx::Size(width, height);
448 case VideoFrame::kUPlane: 473 case VideoFrame::kUPlane:
449 case VideoFrame::kVPlane: 474 case VideoFrame::kVPlane:
450 return gfx::Size(width / 2, height); 475 return gfx::Size(width / 2, height);
451 default: 476 default:
452 break; 477 break;
453 } 478 }
454 } 479 break;
455 case VideoFrame::NV12: { 480 case VideoFrame::NV12:
456 switch (plane) { 481 switch (plane) {
457 case VideoFrame::kYPlane: 482 case VideoFrame::kYPlane:
458 return gfx::Size(width, height); 483 return gfx::Size(width, height);
459 case VideoFrame::kUVPlane: 484 case VideoFrame::kUVPlane:
460 return gfx::Size(width, height / 2); 485 return gfx::Size(width, height / 2);
461 default: 486 default:
462 break; 487 break;
463 } 488 }
464 } 489 break;
465 case VideoFrame::UNKNOWN: 490 case VideoFrame::UNKNOWN:
466 case VideoFrame::NATIVE_TEXTURE: 491 case VideoFrame::NATIVE_TEXTURE:
467 #if defined(VIDEO_HOLE) 492 #if defined(VIDEO_HOLE)
468 case VideoFrame::HOLE: 493 case VideoFrame::HOLE:
469 #endif // defined(VIDEO_HOLE) 494 #endif // defined(VIDEO_HOLE)
470 break; 495 break;
471 } 496 }
472 NOTREACHED() << "Unsupported video frame format/plane: " 497 NOTREACHED() << "Unsupported video frame format/plane: "
473 << format << "/" << plane; 498 << format << "/" << plane;
474 return gfx::Size(); 499 return gfx::Size();
475 } 500 }
476 501
477 size_t VideoFrame::PlaneAllocationSize(Format format, 502 size_t VideoFrame::PlaneAllocationSize(Format format,
478 size_t plane, 503 size_t plane,
479 const gfx::Size& coded_size) { 504 const gfx::Size& coded_size) {
480 // VideoFrame formats are (so far) all YUV and 1 byte per sample. 505 // VideoFrame formats are (so far) all YUV and 1 byte per sample.
481 return PlaneSize(format, plane, coded_size).GetArea(); 506 return PlaneSize(format, plane, coded_size).GetArea();
482 } 507 }
483 508
484 // static 509 // static
485 int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) { 510 int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) {
486 switch (format) { 511 switch (format) {
487 case VideoFrame::YV12A: 512 case VideoFrame::YV24:
488 if (plane == kAPlane) 513 switch (plane) {
489 return 8; 514 case kYPlane:
490 // fallthrough 515 case kUPlane:
516 case kVPlane:
517 return 8;
518 default:
519 break;
520 }
521 break;
491 case VideoFrame::YV12: 522 case VideoFrame::YV12:
492 case VideoFrame::YV16: 523 case VideoFrame::YV16:
493 case VideoFrame::I420: 524 case VideoFrame::I420:
494 case VideoFrame::YV12J: { 525 case VideoFrame::YV12J:
495 switch (plane) { 526 switch (plane) {
496 case kYPlane: 527 case kYPlane:
497 return 8; 528 return 8;
498 case kUPlane: 529 case kUPlane:
499 case kVPlane: 530 case kVPlane:
500 return 2; 531 return 2;
501 default: 532 default:
502 break; 533 break;
503 } 534 }
504 } 535 break;
505 536 case VideoFrame::YV12A:
506 case VideoFrame::NV12: { 537 switch (plane) {
538 case kYPlane:
539 case kAPlane:
540 return 8;
541 case kUPlane:
542 case kVPlane:
543 return 2;
544 default:
545 break;
546 }
547 break;
548 case VideoFrame::NV12:
507 switch (plane) { 549 switch (plane) {
508 case kYPlane: 550 case kYPlane:
509 return 8; 551 return 8;
510 case kUVPlane: 552 case kUVPlane:
511 return 4; 553 return 4;
512 default: 554 default:
513 break; 555 break;
514 } 556 }
515 } 557 break;
516 default: 558 case VideoFrame::UNKNOWN:
559 #if defined(VIDEO_HOLE)
560 case VideoFrame::HOLE:
561 #endif // defined(VIDEO_HOLE)
562 case VideoFrame::NATIVE_TEXTURE:
517 break; 563 break;
518 } 564 }
519 565 NOTREACHED() << "Unsupported video frame format/plane: "
520 NOTREACHED() << "Unsupported video frame format: " << format; 566 << format << "/" << plane;
521 return 0; 567 return 0;
522 } 568 }
523 569
524 // Release data allocated by AllocateYUV(). 570 // Release data allocated by AllocateYUV().
525 static void ReleaseData(uint8* data) { 571 static void ReleaseData(uint8* data) {
526 DCHECK(data); 572 DCHECK(data);
527 base::AlignedFree(data); 573 base::AlignedFree(data);
528 } 574 }
529 575
530 void VideoFrame::AllocateYUV() { 576 void VideoFrame::AllocateYUV() {
531 DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 || 577 DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 ||
532 format_ == VideoFrame::YV12A || format_ == VideoFrame::I420 || 578 format_ == VideoFrame::YV12A || format_ == VideoFrame::I420 ||
533 format_ == VideoFrame::YV12J); 579 format_ == VideoFrame::YV12J || format_ == VideoFrame::YV24);
534 // Align Y rows at least at 16 byte boundaries. The stride for both 580 // Align Y rows at least at 16 byte boundaries. The stride for both
535 // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for 581 // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for
536 // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in 582 // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in
537 // the case of YV12 the strides are identical for the same width surface, but 583 // the case of YV12 the strides are identical for the same width surface, but
538 // the number of bytes allocated for YV12 is 1/2 the amount for U & V as 584 // the number of bytes allocated for YV12 is 1/2 the amount for U & V as
539 // YV16. We also round the height of the surface allocated to be an even 585 // YV16. We also round the height of the surface allocated to be an even
540 // number to avoid any potential of faulting by code that attempts to access 586 // number to avoid any potential of faulting by code that attempts to access
541 // the Y values of the final row, but assumes that the last row of U & V 587 // the Y values of the final row, but assumes that the last row of U & V
542 // applies to a full two rows of Y. YV12A is the same as YV12, but with an 588 // applies to a full two rows of Y. YV12A is the same as YV12, but with an
543 // additional alpha plane that has the same size and alignment as the Y plane. 589 // additional alpha plane that has the same size and alignment as the Y plane.
544
545 size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane), 590 size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane),
546 kFrameSizeAlignment); 591 kFrameSizeAlignment);
547 size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane), 592 size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane),
548 kFrameSizeAlignment); 593 kFrameSizeAlignment);
594
549 // The *2 here is because some formats (e.g. h264) allow interlaced coding, 595 // The *2 here is because some formats (e.g. h264) allow interlaced coding,
550 // and then the size needs to be a multiple of two macroblocks (vertically). 596 // and then the size needs to be a multiple of two macroblocks (vertically).
551 // See libavcodec/utils.c:avcodec_align_dimensions2(). 597 // See libavcodec/utils.c:avcodec_align_dimensions2().
552 size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2); 598 size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2);
553 size_t uv_height = 599 size_t uv_height =
554 (format_ == VideoFrame::YV12 || format_ == VideoFrame::YV12A || 600 (format_ == VideoFrame::YV12 || format_ == VideoFrame::YV12A ||
555 format_ == VideoFrame::I420) 601 format_ == VideoFrame::I420)
556 ? y_height / 2 602 ? y_height / 2
557 : y_height; 603 : y_height;
558 size_t y_bytes = y_height * y_stride; 604 size_t y_bytes = y_height * y_stride;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 667
622 int VideoFrame::stride(size_t plane) const { 668 int VideoFrame::stride(size_t plane) const {
623 DCHECK(IsValidPlane(plane)); 669 DCHECK(IsValidPlane(plane));
624 return strides_[plane]; 670 return strides_[plane];
625 } 671 }
626 672
627 int VideoFrame::row_bytes(size_t plane) const { 673 int VideoFrame::row_bytes(size_t plane) const {
628 DCHECK(IsValidPlane(plane)); 674 DCHECK(IsValidPlane(plane));
629 int width = coded_size_.width(); 675 int width = coded_size_.width();
630 switch (format_) { 676 switch (format_) {
631 // Planar, 8bpp. 677 case VideoFrame::YV24:
632 case YV12A: 678 switch (plane) {
633 if (plane == kAPlane) 679 case kYPlane:
634 return width; 680 case kUPlane:
635 // Fallthrough. 681 case kVPlane:
636 case YV12: 682 return width;
637 case YV16: 683 default:
638 case I420: 684 break;
639 case YV12J: 685 }
640 if (plane == kYPlane)
641 return width;
642 else if (plane <= kVPlane)
643 return RoundUp(width, 2) / 2;
644 break; 686 break;
645 687 case VideoFrame::YV12:
646 case NV12: 688 case VideoFrame::YV16:
647 if (plane <= kUVPlane) 689 case VideoFrame::I420:
648 return width; 690 case VideoFrame::YV12J:
691 switch (plane) {
692 case kYPlane:
693 return width;
694 case kUPlane:
695 case kVPlane:
696 return RoundUp(width, 2) / 2;
697 default:
698 break;
699 }
649 break; 700 break;
650 701 case VideoFrame::YV12A:
651 default: 702 switch (plane) {
703 case kYPlane:
704 case kAPlane:
705 return width;
706 case kUPlane:
707 case kVPlane:
708 return RoundUp(width, 2) / 2;
709 default:
710 break;
711 }
712 break;
713 case VideoFrame::NV12:
714 switch (plane) {
715 case kYPlane:
716 case kUVPlane:
717 return width;
718 default:
719 break;
720 }
721 break;
722 case VideoFrame::UNKNOWN:
723 #if defined(VIDEO_HOLE)
724 case VideoFrame::HOLE:
725 #endif // defined(VIDEO_HOLE)
726 case VideoFrame::NATIVE_TEXTURE:
652 break; 727 break;
653 } 728 }
654 729 NOTREACHED() << "Unsupported video frame format/plane: "
655 // Intentionally leave out non-production formats. 730 << format_ << "/" << plane;
656 NOTREACHED() << "Unsupported video frame format: " << format_;
657 return 0; 731 return 0;
658 } 732 }
659 733
660 int VideoFrame::rows(size_t plane) const { 734 int VideoFrame::rows(size_t plane) const {
661 DCHECK(IsValidPlane(plane)); 735 DCHECK(IsValidPlane(plane));
662 int height = coded_size_.height(); 736 int height = coded_size_.height();
663 switch (format_) { 737 switch (format_) {
664 case YV16: 738 case VideoFrame::YV24:
665 return height; 739 case VideoFrame::YV16:
666 740 switch (plane) {
667 case YV12A: 741 case kYPlane:
668 if (plane == kAPlane) 742 case kUPlane:
669 return height; 743 case kVPlane:
670 // Fallthrough. 744 return height;
671 case YV12: 745 default:
672 case YV12J: 746 break;
673 case I420: 747 }
674 if (plane == kYPlane)
675 return height;
676 else if (plane <= kVPlane)
677 return RoundUp(height, 2) / 2;
678 break; 748 break;
679 749 case VideoFrame::YV12:
680 case NV12: 750 case VideoFrame::YV12J:
681 if (plane == kYPlane) 751 case VideoFrame::I420:
682 return height; 752 switch (plane) {
683 else if (plane == kUVPlane) 753 case kYPlane:
684 return RoundUp(height, 2) / 2; 754 return height;
755 case kUPlane:
756 case kVPlane:
757 return RoundUp(height, 2) / 2;
758 default:
759 break;
760 }
685 break; 761 break;
686 762 case VideoFrame::YV12A:
687 default: 763 switch (plane) {
764 case kYPlane:
765 case kAPlane:
766 return height;
767 case kUPlane:
768 case kVPlane:
769 return RoundUp(height, 2) / 2;
770 default:
771 break;
772 }
773 break;
774 case VideoFrame::NV12:
775 switch (plane) {
776 case kYPlane:
777 return height;
778 case kUVPlane:
779 return RoundUp(height, 2) / 2;
780 default:
781 break;
782 }
783 break;
784 case VideoFrame::UNKNOWN:
785 #if defined(VIDEO_HOLE)
786 case VideoFrame::HOLE:
787 #endif // defined(VIDEO_HOLE)
788 case VideoFrame::NATIVE_TEXTURE:
688 break; 789 break;
689 } 790 }
690 791 NOTREACHED() << "Unsupported video frame format/plane: "
691 // Intentionally leave out non-production formats. 792 << format_ << "/" << plane;
692 NOTREACHED() << "Unsupported video frame format: " << format_;
693 return 0; 793 return 0;
694 } 794 }
695 795
696 uint8* VideoFrame::data(size_t plane) const { 796 uint8* VideoFrame::data(size_t plane) const {
697 DCHECK(IsValidPlane(plane)); 797 DCHECK(IsValidPlane(plane));
698 return data_[plane]; 798 return data_[plane];
699 } 799 }
700 800
701 const gpu::MailboxHolder* VideoFrame::mailbox_holder() const { 801 const gpu::MailboxHolder* VideoFrame::mailbox_holder() const {
702 DCHECK_EQ(format_, NATIVE_TEXTURE); 802 DCHECK_EQ(format_, NATIVE_TEXTURE);
(...skipping 24 matching lines...) Expand all
727 break; 827 break;
728 for (int row = 0; row < rows(plane); ++row) { 828 for (int row = 0; row < rows(plane); ++row) {
729 base::MD5Update(context, base::StringPiece( 829 base::MD5Update(context, base::StringPiece(
730 reinterpret_cast<char*>(data(plane) + stride(plane) * row), 830 reinterpret_cast<char*>(data(plane) + stride(plane) * row),
731 row_bytes(plane))); 831 row_bytes(plane)));
732 } 832 }
733 } 833 }
734 } 834 }
735 835
736 } // namespace media 836 } // namespace media
OLDNEW
« no previous file with comments | « media/base/video_frame.h ('k') | media/ffmpeg/ffmpeg_common.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698