| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |