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 |