Index: media/video/gpu_memory_buffer_video_frame_pool.cc |
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc |
index 9e5e5161ec7387da1d8bc55084a43e01fa4e338d..038cd108154da7b01d6198b064c6838955866a20 100644 |
--- a/media/video/gpu_memory_buffer_video_frame_pool.cc |
+++ b/media/video/gpu_memory_buffer_video_frame_pool.cc |
@@ -79,21 +79,6 @@ inline size_t RoundUp(size_t value, size_t alignment) { |
return ((value + (alignment - 1)) & ~(alignment - 1)); |
} |
-gfx::Size CodedSize(const gfx::Size& size, VideoPixelFormat format) { |
- switch (format) { |
- case PIXEL_FORMAT_I420: |
- case PIXEL_FORMAT_YV12: |
- case PIXEL_FORMAT_YV12A: |
- case PIXEL_FORMAT_NV12: |
- return gfx::Size(RoundUp(size.width(), 2), RoundUp(size.height(), 2)); |
- case PIXEL_FORMAT_UYVY: |
- return gfx::Size(RoundUp(size.width(), 2), size.height()); |
- default: |
- NOTREACHED(); |
- } |
- return gfx::Size(); |
-} |
- |
// All the resources needed to compose a frame. |
class FrameResources : public base::RefCountedThreadSafe<FrameResources> { |
public: |
@@ -481,12 +466,16 @@ class GpuMemoryBufferVideoFramePool::PoolImpl |
// null if a GL context is not available. |
PoolImpl(const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, |
GpuVideoAcceleratorFactories* gpu_factories) |
- : media_task_runner_(media_task_runner), gpu_factories_(gpu_factories) { |
+ : media_task_runner_(media_task_runner), |
+ gpu_factories_(gpu_factories), |
+ usage_(GpuMemoryBufferVideoFramePool::Usage::GENERIC) { |
DCHECK(media_task_runner_); |
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
this, "GpuMemoryBufferVideoFramePool", media_task_runner_); |
} |
+ void SetUsage(GpuMemoryBufferVideoFramePool::Usage usage) { usage_ = usage; } |
+ |
std::unique_ptr<VideoFrameFuture> CreateFrame(VideoPixelFormat format, |
const gfx::Size& coded_size, |
const gfx::Rect& visible_rect, |
@@ -593,12 +582,45 @@ class GpuMemoryBufferVideoFramePool::PoolImpl |
} |
} |
+ gfx::Size CodedSize(const gfx::Size& size, VideoPixelFormat format) { |
+ static const int kFrameSizeAlignment = 16; |
+ if (usage_ == GpuMemoryBufferVideoFramePool::Usage::FFMPEG) { |
+ // libavcodec requires to access areas outside 0,0 - width,height, please |
+ // see libavcodec/utils.c:avcodec_align_dimensions2(). |
+ int width = RoundUp(size.width(), kFrameSizeAlignment); |
+ // H.264 uses edge emulation which requires at least 32. |
+ width = std::max(width, kFrameSizeAlignment * 2); |
+ // The *2 in alignment for height is because some formats (e.g. h264) |
+ // allow interlaced coding, and then the size needs to be a multiple of |
+ // two macroblocks (vertically). |
+ int height = RoundUp(size.height(), kFrameSizeAlignment * 2); |
+ // some of the optimized chroma MC needs two more rows. |
+ height += 2; |
+ return gfx::Size(width, height); |
+ } |
+ |
+ switch (format) { |
+ case PIXEL_FORMAT_I420: |
+ case PIXEL_FORMAT_YV12: |
+ case PIXEL_FORMAT_YV12A: |
+ case PIXEL_FORMAT_NV12: |
+ return gfx::Size(RoundUp(size.width(), 2), RoundUp(size.height(), 2)); |
+ case PIXEL_FORMAT_UYVY: |
+ return gfx::Size(RoundUp(size.width(), 2), size.height()); |
+ default: |
+ NOTREACHED(); |
+ } |
+ return gfx::Size(); |
+ } |
+ |
// Task runner associated to the GL context provided by |gpu_factories_|. |
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; |
// Interface to GPU related operations. |
GpuVideoAcceleratorFactories* gpu_factories_; |
+ GpuMemoryBufferVideoFramePool::Usage usage_; |
+ |
// Pool of resources. |
std::list<scoped_refptr<FrameResources>> resources_pool_; |
@@ -623,6 +645,10 @@ std::unique_ptr<VideoFrameFuture> GpuMemoryBufferVideoFramePool::CreateFrame( |
timestamp); |
} |
+void GpuMemoryBufferVideoFramePool::SetUsage(Usage usage) { |
+ pool_impl_->SetUsage(usage); |
+} |
+ |
// static |
size_t GpuMemoryBufferVideoFramePool::PlanesPerCopy(VideoPixelFormat format, |
size_t plane) { |