| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/video/gpu_memory_buffer_video_frame_pool.h" | 5 #include "media/video/gpu_memory_buffer_video_frame_pool.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <list> | 8 #include <list> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 | 72 |
| 73 bool IsPowerOfTwo(size_t x) { | 73 bool IsPowerOfTwo(size_t x) { |
| 74 return x != 0 && (x & (x - 1)) == 0; | 74 return x != 0 && (x & (x - 1)) == 0; |
| 75 } | 75 } |
| 76 | 76 |
| 77 inline size_t RoundUp(size_t value, size_t alignment) { | 77 inline size_t RoundUp(size_t value, size_t alignment) { |
| 78 DCHECK(IsPowerOfTwo(alignment)); | 78 DCHECK(IsPowerOfTwo(alignment)); |
| 79 return ((value + (alignment - 1)) & ~(alignment - 1)); | 79 return ((value + (alignment - 1)) & ~(alignment - 1)); |
| 80 } | 80 } |
| 81 | 81 |
| 82 gfx::Size CodedSize(const gfx::Size& size, VideoPixelFormat format) { | |
| 83 switch (format) { | |
| 84 case PIXEL_FORMAT_I420: | |
| 85 case PIXEL_FORMAT_YV12: | |
| 86 case PIXEL_FORMAT_YV12A: | |
| 87 case PIXEL_FORMAT_NV12: | |
| 88 return gfx::Size(RoundUp(size.width(), 2), RoundUp(size.height(), 2)); | |
| 89 case PIXEL_FORMAT_UYVY: | |
| 90 return gfx::Size(RoundUp(size.width(), 2), size.height()); | |
| 91 default: | |
| 92 NOTREACHED(); | |
| 93 } | |
| 94 return gfx::Size(); | |
| 95 } | |
| 96 | |
| 97 // All the resources needed to compose a frame. | 82 // All the resources needed to compose a frame. |
| 98 class FrameResources : public base::RefCountedThreadSafe<FrameResources> { | 83 class FrameResources : public base::RefCountedThreadSafe<FrameResources> { |
| 99 public: | 84 public: |
| 100 static scoped_refptr<FrameResources> Create( | 85 static scoped_refptr<FrameResources> Create( |
| 101 GpuVideoAcceleratorFactories* gpu_factories, | 86 GpuVideoAcceleratorFactories* gpu_factories, |
| 102 VideoPixelFormat format, | 87 VideoPixelFormat format, |
| 103 const gfx::Size& size) { | 88 const gfx::Size& size) { |
| 104 // Create the resources. | 89 // Create the resources. |
| 105 scoped_ptr<GpuVideoAcceleratorFactories::ScopedGLContextLock> lock( | 90 scoped_ptr<GpuVideoAcceleratorFactories::ScopedGLContextLock> lock( |
| 106 gpu_factories->GetGLContextLock()); | 91 gpu_factories->GetGLContextLock()); |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 : public base::RefCountedThreadSafe< | 459 : public base::RefCountedThreadSafe< |
| 475 GpuMemoryBufferVideoFramePool::PoolImpl>, | 460 GpuMemoryBufferVideoFramePool::PoolImpl>, |
| 476 public base::trace_event::MemoryDumpProvider { | 461 public base::trace_event::MemoryDumpProvider { |
| 477 public: | 462 public: |
| 478 // |media_task_runner| is the media task runner associated with the | 463 // |media_task_runner| is the media task runner associated with the |
| 479 // GL context provided by |gpu_factories| | 464 // GL context provided by |gpu_factories| |
| 480 // |gpu_factories| is an interface to GPU related operation and can be | 465 // |gpu_factories| is an interface to GPU related operation and can be |
| 481 // null if a GL context is not available. | 466 // null if a GL context is not available. |
| 482 PoolImpl(const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, | 467 PoolImpl(const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, |
| 483 GpuVideoAcceleratorFactories* gpu_factories) | 468 GpuVideoAcceleratorFactories* gpu_factories) |
| 484 : media_task_runner_(media_task_runner), gpu_factories_(gpu_factories) { | 469 : media_task_runner_(media_task_runner), |
| 470 gpu_factories_(gpu_factories), |
| 471 usage_(GpuMemoryBufferVideoFramePool::Usage::GENERIC) { |
| 485 DCHECK(media_task_runner_); | 472 DCHECK(media_task_runner_); |
| 486 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( | 473 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
| 487 this, "GpuMemoryBufferVideoFramePool", media_task_runner_); | 474 this, "GpuMemoryBufferVideoFramePool", media_task_runner_); |
| 488 } | 475 } |
| 489 | 476 |
| 477 void SetUsage(GpuMemoryBufferVideoFramePool::Usage usage) { usage_ = usage; } |
| 478 |
| 490 std::unique_ptr<VideoFrameFuture> CreateFrame(VideoPixelFormat format, | 479 std::unique_ptr<VideoFrameFuture> CreateFrame(VideoPixelFormat format, |
| 491 const gfx::Size& coded_size, | 480 const gfx::Size& coded_size, |
| 492 const gfx::Rect& visible_rect, | 481 const gfx::Rect& visible_rect, |
| 493 const gfx::Size& natural_size, | 482 const gfx::Size& natural_size, |
| 494 base::TimeDelta timestamp) { | 483 base::TimeDelta timestamp) { |
| 495 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 484 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 496 if (!IsSupported(format)) { | 485 if (!IsSupported(format)) { |
| 497 NOTREACHED(); | 486 NOTREACHED(); |
| 498 return nullptr; | 487 return nullptr; |
| 499 } | 488 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 case PIXEL_FORMAT_YV12: | 575 case PIXEL_FORMAT_YV12: |
| 587 case PIXEL_FORMAT_YV12A: | 576 case PIXEL_FORMAT_YV12A: |
| 588 case PIXEL_FORMAT_NV12: | 577 case PIXEL_FORMAT_NV12: |
| 589 case PIXEL_FORMAT_UYVY: | 578 case PIXEL_FORMAT_UYVY: |
| 590 return true; | 579 return true; |
| 591 default: | 580 default: |
| 592 return false; | 581 return false; |
| 593 } | 582 } |
| 594 } | 583 } |
| 595 | 584 |
| 585 gfx::Size CodedSize(const gfx::Size& size, VideoPixelFormat format) { |
| 586 static const int kFrameSizeAlignment = 16; |
| 587 if (usage_ == GpuMemoryBufferVideoFramePool::Usage::FFMPEG) { |
| 588 // libavcodec requires to access areas outside 0,0 - width,height, please |
| 589 // see libavcodec/utils.c:avcodec_align_dimensions2(). |
| 590 int width = RoundUp(size.width(), kFrameSizeAlignment); |
| 591 // H.264 uses edge emulation which requires at least 32. |
| 592 width = std::max(width, kFrameSizeAlignment * 2); |
| 593 // The *2 in alignment for height is because some formats (e.g. h264) |
| 594 // allow interlaced coding, and then the size needs to be a multiple of |
| 595 // two macroblocks (vertically). |
| 596 int height = RoundUp(size.height(), kFrameSizeAlignment * 2); |
| 597 // some of the optimized chroma MC needs two more rows. |
| 598 height += 2; |
| 599 return gfx::Size(width, height); |
| 600 } |
| 601 |
| 602 switch (format) { |
| 603 case PIXEL_FORMAT_I420: |
| 604 case PIXEL_FORMAT_YV12: |
| 605 case PIXEL_FORMAT_YV12A: |
| 606 case PIXEL_FORMAT_NV12: |
| 607 return gfx::Size(RoundUp(size.width(), 2), RoundUp(size.height(), 2)); |
| 608 case PIXEL_FORMAT_UYVY: |
| 609 return gfx::Size(RoundUp(size.width(), 2), size.height()); |
| 610 default: |
| 611 NOTREACHED(); |
| 612 } |
| 613 return gfx::Size(); |
| 614 } |
| 615 |
| 596 // Task runner associated to the GL context provided by |gpu_factories_|. | 616 // Task runner associated to the GL context provided by |gpu_factories_|. |
| 597 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; | 617 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; |
| 598 | 618 |
| 599 // Interface to GPU related operations. | 619 // Interface to GPU related operations. |
| 600 GpuVideoAcceleratorFactories* gpu_factories_; | 620 GpuVideoAcceleratorFactories* gpu_factories_; |
| 601 | 621 |
| 622 GpuMemoryBufferVideoFramePool::Usage usage_; |
| 623 |
| 602 // Pool of resources. | 624 // Pool of resources. |
| 603 std::list<scoped_refptr<FrameResources>> resources_pool_; | 625 std::list<scoped_refptr<FrameResources>> resources_pool_; |
| 604 | 626 |
| 605 DISALLOW_COPY_AND_ASSIGN(PoolImpl); | 627 DISALLOW_COPY_AND_ASSIGN(PoolImpl); |
| 606 }; | 628 }; |
| 607 | 629 |
| 608 GpuMemoryBufferVideoFramePool::GpuMemoryBufferVideoFramePool( | 630 GpuMemoryBufferVideoFramePool::GpuMemoryBufferVideoFramePool( |
| 609 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, | 631 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, |
| 610 GpuVideoAcceleratorFactories* gpu_factories) | 632 GpuVideoAcceleratorFactories* gpu_factories) |
| 611 : pool_impl_(new PoolImpl(media_task_runner, gpu_factories)) {} | 633 : pool_impl_(new PoolImpl(media_task_runner, gpu_factories)) {} |
| 612 | 634 |
| 613 GpuMemoryBufferVideoFramePool::~GpuMemoryBufferVideoFramePool() { | 635 GpuMemoryBufferVideoFramePool::~GpuMemoryBufferVideoFramePool() { |
| 614 } | 636 } |
| 615 | 637 |
| 616 std::unique_ptr<VideoFrameFuture> GpuMemoryBufferVideoFramePool::CreateFrame( | 638 std::unique_ptr<VideoFrameFuture> GpuMemoryBufferVideoFramePool::CreateFrame( |
| 617 VideoPixelFormat format, | 639 VideoPixelFormat format, |
| 618 const gfx::Size& coded_size, | 640 const gfx::Size& coded_size, |
| 619 const gfx::Rect& visible_rect, | 641 const gfx::Rect& visible_rect, |
| 620 const gfx::Size& natural_size, | 642 const gfx::Size& natural_size, |
| 621 base::TimeDelta timestamp) { | 643 base::TimeDelta timestamp) { |
| 622 return pool_impl_->CreateFrame(format, coded_size, visible_rect, natural_size, | 644 return pool_impl_->CreateFrame(format, coded_size, visible_rect, natural_size, |
| 623 timestamp); | 645 timestamp); |
| 624 } | 646 } |
| 625 | 647 |
| 648 void GpuMemoryBufferVideoFramePool::SetUsage(Usage usage) { |
| 649 pool_impl_->SetUsage(usage); |
| 650 } |
| 651 |
| 626 // static | 652 // static |
| 627 size_t GpuMemoryBufferVideoFramePool::PlanesPerCopy(VideoPixelFormat format, | 653 size_t GpuMemoryBufferVideoFramePool::PlanesPerCopy(VideoPixelFormat format, |
| 628 size_t plane) { | 654 size_t plane) { |
| 629 return gfx::NumberOfPlanesForBufferFormat( | 655 return gfx::NumberOfPlanesForBufferFormat( |
| 630 GpuMemoryBufferFormat(format, plane)); | 656 GpuMemoryBufferFormat(format, plane)); |
| 631 } | 657 } |
| 632 | 658 |
| 633 } // namespace media | 659 } // namespace media |
| OLD | NEW |