| 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 #include <climits> | 8 #include <climits> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 return new VideoFrame(format, storage, coded_size, visible_rect, natural_size, | 272 return new VideoFrame(format, storage, coded_size, visible_rect, natural_size, |
| 273 mailbox_holders, mailbox_holder_release_cb, timestamp); | 273 mailbox_holders, mailbox_holder_release_cb, timestamp); |
| 274 } | 274 } |
| 275 | 275 |
| 276 // static | 276 // static |
| 277 scoped_refptr<VideoFrame> VideoFrame::WrapExternalData( | 277 scoped_refptr<VideoFrame> VideoFrame::WrapExternalData( |
| 278 VideoPixelFormat format, | 278 VideoPixelFormat format, |
| 279 const gfx::Size& coded_size, | 279 const gfx::Size& coded_size, |
| 280 const gfx::Rect& visible_rect, | 280 const gfx::Rect& visible_rect, |
| 281 const gfx::Size& natural_size, | 281 const gfx::Size& natural_size, |
| 282 uint8* data, | 282 uint8_t* data, |
| 283 size_t data_size, | 283 size_t data_size, |
| 284 base::TimeDelta timestamp) { | 284 base::TimeDelta timestamp) { |
| 285 return WrapExternalStorage(format, STORAGE_UNOWNED_MEMORY, coded_size, | 285 return WrapExternalStorage(format, STORAGE_UNOWNED_MEMORY, coded_size, |
| 286 visible_rect, natural_size, data, data_size, | 286 visible_rect, natural_size, data, data_size, |
| 287 timestamp, base::SharedMemory::NULLHandle(), 0); | 287 timestamp, base::SharedMemory::NULLHandle(), 0); |
| 288 } | 288 } |
| 289 | 289 |
| 290 // static | 290 // static |
| 291 scoped_refptr<VideoFrame> VideoFrame::WrapExternalSharedMemory( | 291 scoped_refptr<VideoFrame> VideoFrame::WrapExternalSharedMemory( |
| 292 VideoPixelFormat format, | 292 VideoPixelFormat format, |
| 293 const gfx::Size& coded_size, | 293 const gfx::Size& coded_size, |
| 294 const gfx::Rect& visible_rect, | 294 const gfx::Rect& visible_rect, |
| 295 const gfx::Size& natural_size, | 295 const gfx::Size& natural_size, |
| 296 uint8* data, | 296 uint8_t* data, |
| 297 size_t data_size, | 297 size_t data_size, |
| 298 base::SharedMemoryHandle handle, | 298 base::SharedMemoryHandle handle, |
| 299 size_t data_offset, | 299 size_t data_offset, |
| 300 base::TimeDelta timestamp) { | 300 base::TimeDelta timestamp) { |
| 301 return WrapExternalStorage(format, STORAGE_SHMEM, coded_size, visible_rect, | 301 return WrapExternalStorage(format, STORAGE_SHMEM, coded_size, visible_rect, |
| 302 natural_size, data, data_size, timestamp, handle, | 302 natural_size, data, data_size, timestamp, handle, |
| 303 data_offset); | 303 data_offset); |
| 304 } | 304 } |
| 305 | 305 |
| 306 // static | 306 // static |
| 307 scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData( | 307 scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData( |
| 308 VideoPixelFormat format, | 308 VideoPixelFormat format, |
| 309 const gfx::Size& coded_size, | 309 const gfx::Size& coded_size, |
| 310 const gfx::Rect& visible_rect, | 310 const gfx::Rect& visible_rect, |
| 311 const gfx::Size& natural_size, | 311 const gfx::Size& natural_size, |
| 312 int32 y_stride, | 312 int32_t y_stride, |
| 313 int32 u_stride, | 313 int32_t u_stride, |
| 314 int32 v_stride, | 314 int32_t v_stride, |
| 315 uint8* y_data, | 315 uint8_t* y_data, |
| 316 uint8* u_data, | 316 uint8_t* u_data, |
| 317 uint8* v_data, | 317 uint8_t* v_data, |
| 318 base::TimeDelta timestamp) { | 318 base::TimeDelta timestamp) { |
| 319 const StorageType storage = STORAGE_UNOWNED_MEMORY; | 319 const StorageType storage = STORAGE_UNOWNED_MEMORY; |
| 320 if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { | 320 if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { |
| 321 DLOG(ERROR) << __FUNCTION__ << " Invalid config." | 321 DLOG(ERROR) << __FUNCTION__ << " Invalid config." |
| 322 << ConfigToString(format, storage, coded_size, visible_rect, | 322 << ConfigToString(format, storage, coded_size, visible_rect, |
| 323 natural_size); | 323 natural_size); |
| 324 return nullptr; | 324 return nullptr; |
| 325 } | 325 } |
| 326 | 326 |
| 327 scoped_refptr<VideoFrame> frame(new VideoFrame( | 327 scoped_refptr<VideoFrame> frame(new VideoFrame( |
| 328 format, storage, coded_size, visible_rect, natural_size, timestamp)); | 328 format, storage, coded_size, visible_rect, natural_size, timestamp)); |
| 329 frame->strides_[kYPlane] = y_stride; | 329 frame->strides_[kYPlane] = y_stride; |
| 330 frame->strides_[kUPlane] = u_stride; | 330 frame->strides_[kUPlane] = u_stride; |
| 331 frame->strides_[kVPlane] = v_stride; | 331 frame->strides_[kVPlane] = v_stride; |
| 332 frame->data_[kYPlane] = y_data; | 332 frame->data_[kYPlane] = y_data; |
| 333 frame->data_[kUPlane] = u_data; | 333 frame->data_[kUPlane] = u_data; |
| 334 frame->data_[kVPlane] = v_data; | 334 frame->data_[kVPlane] = v_data; |
| 335 return frame; | 335 return frame; |
| 336 } | 336 } |
| 337 | 337 |
| 338 // static | 338 // static |
| 339 scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvGpuMemoryBuffers( | 339 scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvGpuMemoryBuffers( |
| 340 VideoPixelFormat format, | 340 VideoPixelFormat format, |
| 341 const gfx::Size& coded_size, | 341 const gfx::Size& coded_size, |
| 342 const gfx::Rect& visible_rect, | 342 const gfx::Rect& visible_rect, |
| 343 const gfx::Size& natural_size, | 343 const gfx::Size& natural_size, |
| 344 int32 y_stride, | 344 int32_t y_stride, |
| 345 int32 u_stride, | 345 int32_t u_stride, |
| 346 int32 v_stride, | 346 int32_t v_stride, |
| 347 uint8* y_data, | 347 uint8_t* y_data, |
| 348 uint8* u_data, | 348 uint8_t* u_data, |
| 349 uint8* v_data, | 349 uint8_t* v_data, |
| 350 const gfx::GpuMemoryBufferHandle& y_handle, | 350 const gfx::GpuMemoryBufferHandle& y_handle, |
| 351 const gfx::GpuMemoryBufferHandle& u_handle, | 351 const gfx::GpuMemoryBufferHandle& u_handle, |
| 352 const gfx::GpuMemoryBufferHandle& v_handle, | 352 const gfx::GpuMemoryBufferHandle& v_handle, |
| 353 base::TimeDelta timestamp) { | 353 base::TimeDelta timestamp) { |
| 354 const StorageType storage = STORAGE_GPU_MEMORY_BUFFERS; | 354 const StorageType storage = STORAGE_GPU_MEMORY_BUFFERS; |
| 355 if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { | 355 if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { |
| 356 DLOG(ERROR) << __FUNCTION__ << " Invalid config." | 356 DLOG(ERROR) << __FUNCTION__ << " Invalid config." |
| 357 << ConfigToString(format, storage, coded_size, visible_rect, | 357 << ConfigToString(format, storage, coded_size, visible_rect, |
| 358 natural_size); | 358 natural_size); |
| 359 return nullptr; | 359 return nullptr; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 scoped_refptr<VideoFrame> frame = | 503 scoped_refptr<VideoFrame> frame = |
| 504 new VideoFrame(PIXEL_FORMAT_UNKNOWN, STORAGE_UNKNOWN, gfx::Size(), | 504 new VideoFrame(PIXEL_FORMAT_UNKNOWN, STORAGE_UNKNOWN, gfx::Size(), |
| 505 gfx::Rect(), gfx::Size(), kNoTimestamp()); | 505 gfx::Rect(), gfx::Size(), kNoTimestamp()); |
| 506 frame->metadata()->SetBoolean(VideoFrameMetadata::END_OF_STREAM, true); | 506 frame->metadata()->SetBoolean(VideoFrameMetadata::END_OF_STREAM, true); |
| 507 return frame; | 507 return frame; |
| 508 } | 508 } |
| 509 | 509 |
| 510 // static | 510 // static |
| 511 scoped_refptr<VideoFrame> VideoFrame::CreateColorFrame( | 511 scoped_refptr<VideoFrame> VideoFrame::CreateColorFrame( |
| 512 const gfx::Size& size, | 512 const gfx::Size& size, |
| 513 uint8 y, uint8 u, uint8 v, | 513 uint8_t y, |
| 514 uint8_t u, |
| 515 uint8_t v, |
| 514 base::TimeDelta timestamp) { | 516 base::TimeDelta timestamp) { |
| 515 scoped_refptr<VideoFrame> frame = | 517 scoped_refptr<VideoFrame> frame = |
| 516 CreateFrame(PIXEL_FORMAT_YV12, size, gfx::Rect(size), size, timestamp); | 518 CreateFrame(PIXEL_FORMAT_YV12, size, gfx::Rect(size), size, timestamp); |
| 517 FillYUV(frame.get(), y, u, v); | 519 FillYUV(frame.get(), y, u, v); |
| 518 return frame; | 520 return frame; |
| 519 } | 521 } |
| 520 | 522 |
| 521 // static | 523 // static |
| 522 scoped_refptr<VideoFrame> VideoFrame::CreateBlackFrame(const gfx::Size& size) { | 524 scoped_refptr<VideoFrame> VideoFrame::CreateBlackFrame(const gfx::Size& size) { |
| 523 const uint8 kBlackY = 0x00; | 525 const uint8_t kBlackY = 0x00; |
| 524 const uint8 kBlackUV = 0x80; | 526 const uint8_t kBlackUV = 0x80; |
| 525 const base::TimeDelta kZero; | 527 const base::TimeDelta kZero; |
| 526 return CreateColorFrame(size, kBlackY, kBlackUV, kBlackUV, kZero); | 528 return CreateColorFrame(size, kBlackY, kBlackUV, kBlackUV, kZero); |
| 527 } | 529 } |
| 528 | 530 |
| 529 // static | 531 // static |
| 530 scoped_refptr<VideoFrame> VideoFrame::CreateTransparentFrame( | 532 scoped_refptr<VideoFrame> VideoFrame::CreateTransparentFrame( |
| 531 const gfx::Size& size) { | 533 const gfx::Size& size) { |
| 532 const uint8 kBlackY = 0x00; | 534 const uint8_t kBlackY = 0x00; |
| 533 const uint8 kBlackUV = 0x00; | 535 const uint8_t kBlackUV = 0x00; |
| 534 const uint8 kTransparentA = 0x00; | 536 const uint8_t kTransparentA = 0x00; |
| 535 const base::TimeDelta kZero; | 537 const base::TimeDelta kZero; |
| 536 scoped_refptr<VideoFrame> frame = | 538 scoped_refptr<VideoFrame> frame = |
| 537 CreateFrame(PIXEL_FORMAT_YV12A, size, gfx::Rect(size), size, kZero); | 539 CreateFrame(PIXEL_FORMAT_YV12A, size, gfx::Rect(size), size, kZero); |
| 538 FillYUVA(frame.get(), kBlackY, kBlackUV, kBlackUV, kTransparentA); | 540 FillYUVA(frame.get(), kBlackY, kBlackUV, kBlackUV, kTransparentA); |
| 539 return frame; | 541 return frame; |
| 540 } | 542 } |
| 541 | 543 |
| 542 #if defined(VIDEO_HOLE) | 544 #if defined(VIDEO_HOLE) |
| 543 // This block and other blocks wrapped around #if defined(VIDEO_HOLE) is not | 545 // This block and other blocks wrapped around #if defined(VIDEO_HOLE) is not |
| 544 // maintained by the general compositor team. Please contact | 546 // maintained by the general compositor team. Please contact |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 } | 690 } |
| 689 | 691 |
| 690 int VideoFrame::row_bytes(size_t plane) const { | 692 int VideoFrame::row_bytes(size_t plane) const { |
| 691 return RowBytes(plane, format_, coded_size_.width()); | 693 return RowBytes(plane, format_, coded_size_.width()); |
| 692 } | 694 } |
| 693 | 695 |
| 694 int VideoFrame::rows(size_t plane) const { | 696 int VideoFrame::rows(size_t plane) const { |
| 695 return Rows(plane, format_, coded_size_.height()); | 697 return Rows(plane, format_, coded_size_.height()); |
| 696 } | 698 } |
| 697 | 699 |
| 698 const uint8* VideoFrame::data(size_t plane) const { | 700 const uint8_t* VideoFrame::data(size_t plane) const { |
| 699 DCHECK(IsValidPlane(plane, format_)); | 701 DCHECK(IsValidPlane(plane, format_)); |
| 700 DCHECK(IsMappable()); | 702 DCHECK(IsMappable()); |
| 701 return data_[plane]; | 703 return data_[plane]; |
| 702 } | 704 } |
| 703 | 705 |
| 704 uint8* VideoFrame::data(size_t plane) { | 706 uint8_t* VideoFrame::data(size_t plane) { |
| 705 DCHECK(IsValidPlane(plane, format_)); | 707 DCHECK(IsValidPlane(plane, format_)); |
| 706 DCHECK(IsMappable()); | 708 DCHECK(IsMappable()); |
| 707 return data_[plane]; | 709 return data_[plane]; |
| 708 } | 710 } |
| 709 | 711 |
| 710 const uint8* VideoFrame::visible_data(size_t plane) const { | 712 const uint8_t* VideoFrame::visible_data(size_t plane) const { |
| 711 DCHECK(IsValidPlane(plane, format_)); | 713 DCHECK(IsValidPlane(plane, format_)); |
| 712 DCHECK(IsMappable()); | 714 DCHECK(IsMappable()); |
| 713 | 715 |
| 714 // Calculate an offset that is properly aligned for all planes. | 716 // Calculate an offset that is properly aligned for all planes. |
| 715 const gfx::Size alignment = CommonAlignment(format_); | 717 const gfx::Size alignment = CommonAlignment(format_); |
| 716 const gfx::Point offset(RoundDown(visible_rect_.x(), alignment.width()), | 718 const gfx::Point offset(RoundDown(visible_rect_.x(), alignment.width()), |
| 717 RoundDown(visible_rect_.y(), alignment.height())); | 719 RoundDown(visible_rect_.y(), alignment.height())); |
| 718 | 720 |
| 719 const gfx::Size subsample = SampleSize(format_, plane); | 721 const gfx::Size subsample = SampleSize(format_, plane); |
| 720 DCHECK(offset.x() % subsample.width() == 0); | 722 DCHECK(offset.x() % subsample.width() == 0); |
| 721 DCHECK(offset.y() % subsample.height() == 0); | 723 DCHECK(offset.y() % subsample.height() == 0); |
| 722 return data(plane) + | 724 return data(plane) + |
| 723 stride(plane) * (offset.y() / subsample.height()) + // Row offset. | 725 stride(plane) * (offset.y() / subsample.height()) + // Row offset. |
| 724 BytesPerElement(format_, plane) * // Column offset. | 726 BytesPerElement(format_, plane) * // Column offset. |
| 725 (offset.x() / subsample.width()); | 727 (offset.x() / subsample.width()); |
| 726 } | 728 } |
| 727 | 729 |
| 728 uint8* VideoFrame::visible_data(size_t plane) { | 730 uint8_t* VideoFrame::visible_data(size_t plane) { |
| 729 return const_cast<uint8*>( | 731 return const_cast<uint8_t*>( |
| 730 static_cast<const VideoFrame*>(this)->visible_data(plane)); | 732 static_cast<const VideoFrame*>(this)->visible_data(plane)); |
| 731 } | 733 } |
| 732 | 734 |
| 733 const gpu::MailboxHolder& | 735 const gpu::MailboxHolder& |
| 734 VideoFrame::mailbox_holder(size_t texture_index) const { | 736 VideoFrame::mailbox_holder(size_t texture_index) const { |
| 735 DCHECK(HasTextures()); | 737 DCHECK(HasTextures()); |
| 736 DCHECK(IsValidPlane(texture_index, format_)); | 738 DCHECK(IsValidPlane(texture_index, format_)); |
| 737 return mailbox_holders_[texture_index]; | 739 return mailbox_holders_[texture_index]; |
| 738 } | 740 } |
| 739 | 741 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 client->GenerateSyncToken(&release_sync_token_); | 820 client->GenerateSyncToken(&release_sync_token_); |
| 819 } | 821 } |
| 820 | 822 |
| 821 // static | 823 // static |
| 822 scoped_refptr<VideoFrame> VideoFrame::WrapExternalStorage( | 824 scoped_refptr<VideoFrame> VideoFrame::WrapExternalStorage( |
| 823 VideoPixelFormat format, | 825 VideoPixelFormat format, |
| 824 StorageType storage_type, | 826 StorageType storage_type, |
| 825 const gfx::Size& coded_size, | 827 const gfx::Size& coded_size, |
| 826 const gfx::Rect& visible_rect, | 828 const gfx::Rect& visible_rect, |
| 827 const gfx::Size& natural_size, | 829 const gfx::Size& natural_size, |
| 828 uint8* data, | 830 uint8_t* data, |
| 829 size_t data_size, | 831 size_t data_size, |
| 830 base::TimeDelta timestamp, | 832 base::TimeDelta timestamp, |
| 831 base::SharedMemoryHandle handle, | 833 base::SharedMemoryHandle handle, |
| 832 size_t data_offset) { | 834 size_t data_offset) { |
| 833 DCHECK(IsStorageTypeMappable(storage_type)); | 835 DCHECK(IsStorageTypeMappable(storage_type)); |
| 834 | 836 |
| 835 // TODO(miu): This function should support any pixel format. | 837 // TODO(miu): This function should support any pixel format. |
| 836 // http://crbug.com/555909 | 838 // http://crbug.com/555909 |
| 837 if (format != PIXEL_FORMAT_I420) { | 839 if (format != PIXEL_FORMAT_I420) { |
| 838 DLOG(ERROR) << "Only PIXEL_FORMAT_I420 format supported: " | 840 DLOG(ERROR) << "Only PIXEL_FORMAT_I420 format supported: " |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 data_size += height * strides_[plane]; | 1001 data_size += height * strides_[plane]; |
| 1000 } | 1002 } |
| 1001 | 1003 |
| 1002 // The extra line of UV being allocated is because h264 chroma MC | 1004 // The extra line of UV being allocated is because h264 chroma MC |
| 1003 // overreads by one line in some cases, see libavcodec/utils.c: | 1005 // overreads by one line in some cases, see libavcodec/utils.c: |
| 1004 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: | 1006 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: |
| 1005 // put_h264_chroma_mc4_ssse3(). | 1007 // put_h264_chroma_mc4_ssse3(). |
| 1006 DCHECK(IsValidPlane(kUPlane, format_)); | 1008 DCHECK(IsValidPlane(kUPlane, format_)); |
| 1007 data_size += strides_[kUPlane] + kFrameSizePadding; | 1009 data_size += strides_[kUPlane] + kFrameSizePadding; |
| 1008 | 1010 |
| 1009 uint8* data = reinterpret_cast<uint8*>( | 1011 uint8_t* data = reinterpret_cast<uint8_t*>( |
| 1010 base::AlignedAlloc(data_size, kFrameAddressAlignment)); | 1012 base::AlignedAlloc(data_size, kFrameAddressAlignment)); |
| 1011 if (zero_initialize_memory) | 1013 if (zero_initialize_memory) |
| 1012 memset(data, 0, data_size); | 1014 memset(data, 0, data_size); |
| 1013 | 1015 |
| 1014 for (size_t plane = 0; plane < NumPlanes(format_); ++plane) | 1016 for (size_t plane = 0; plane < NumPlanes(format_); ++plane) |
| 1015 data_[plane] = data + offset[plane]; | 1017 data_[plane] = data + offset[plane]; |
| 1016 | 1018 |
| 1017 AddDestructionObserver(base::Bind(&base::AlignedFree, data)); | 1019 AddDestructionObserver(base::Bind(&base::AlignedFree, data)); |
| 1018 } | 1020 } |
| 1019 | 1021 |
| 1020 } // namespace media | 1022 } // namespace media |
| OLD | NEW |