| 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 <GLES2/gl2.h> | 7 #include <GLES2/gl2.h> |
| 8 #include <GLES2/gl2ext.h> | 8 #include <GLES2/gl2ext.h> |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 #include <stdint.h> | 10 #include <stdint.h> |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 // |worker_task_runner| is a task runner used to asynchronously copy | 42 // |worker_task_runner| is a task runner used to asynchronously copy |
| 43 // video frame's planes. | 43 // video frame's planes. |
| 44 // |gpu_factories| is an interface to GPU related operation and can be | 44 // |gpu_factories| is an interface to GPU related operation and can be |
| 45 // null if a GL context is not available. | 45 // null if a GL context is not available. |
| 46 PoolImpl(const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, | 46 PoolImpl(const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, |
| 47 const scoped_refptr<base::TaskRunner>& worker_task_runner, | 47 const scoped_refptr<base::TaskRunner>& worker_task_runner, |
| 48 GpuVideoAcceleratorFactories* gpu_factories) | 48 GpuVideoAcceleratorFactories* gpu_factories) |
| 49 : media_task_runner_(media_task_runner), | 49 : media_task_runner_(media_task_runner), |
| 50 worker_task_runner_(worker_task_runner), | 50 worker_task_runner_(worker_task_runner), |
| 51 gpu_factories_(gpu_factories), | 51 gpu_factories_(gpu_factories), |
| 52 texture_target_(gpu_factories->ImageTextureTarget()), | |
| 53 output_format_(PIXEL_FORMAT_UNKNOWN) { | 52 output_format_(PIXEL_FORMAT_UNKNOWN) { |
| 54 DCHECK(media_task_runner_); | 53 DCHECK(media_task_runner_); |
| 55 DCHECK(worker_task_runner_); | 54 DCHECK(worker_task_runner_); |
| 56 } | 55 } |
| 57 | 56 |
| 58 // Takes a software VideoFrame and calls |frame_ready_cb| with a VideoFrame | 57 // Takes a software VideoFrame and calls |frame_ready_cb| with a VideoFrame |
| 59 // backed by native textures if possible. | 58 // backed by native textures if possible. |
| 60 // The data contained in video_frame is copied into the returned frame | 59 // The data contained in video_frame is copied into the returned frame |
| 61 // asynchronously posting tasks to |worker_task_runner_|, while | 60 // asynchronously posting tasks to |worker_task_runner_|, while |
| 62 // |frame_ready_cb| will be called on |media_task_runner_| once all the data | 61 // |frame_ready_cb| will be called on |media_task_runner_| once all the data |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; | 141 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; |
| 143 // Task runner used to asynchronously copy planes. | 142 // Task runner used to asynchronously copy planes. |
| 144 scoped_refptr<base::TaskRunner> worker_task_runner_; | 143 scoped_refptr<base::TaskRunner> worker_task_runner_; |
| 145 | 144 |
| 146 // Interface to GPU related operations. | 145 // Interface to GPU related operations. |
| 147 GpuVideoAcceleratorFactories* gpu_factories_; | 146 GpuVideoAcceleratorFactories* gpu_factories_; |
| 148 | 147 |
| 149 // Pool of resources. | 148 // Pool of resources. |
| 150 std::list<FrameResources*> resources_pool_; | 149 std::list<FrameResources*> resources_pool_; |
| 151 | 150 |
| 152 const unsigned texture_target_; | |
| 153 // TODO(dcastagna): change the following type from VideoPixelFormat to | 151 // TODO(dcastagna): change the following type from VideoPixelFormat to |
| 154 // BufferFormat. | 152 // BufferFormat. |
| 155 VideoPixelFormat output_format_; | 153 VideoPixelFormat output_format_; |
| 156 | 154 |
| 157 DISALLOW_COPY_AND_ASSIGN(PoolImpl); | 155 DISALLOW_COPY_AND_ASSIGN(PoolImpl); |
| 158 }; | 156 }; |
| 159 | 157 |
| 160 namespace { | 158 namespace { |
| 161 | 159 |
| 162 // VideoFrame copies to GpuMemoryBuffers will be split in copies where the | 160 // VideoFrame copies to GpuMemoryBuffers will be split in copies where the |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 } | 531 } |
| 534 gpu::gles2::GLES2Interface* gles2 = lock->ContextGL(); | 532 gpu::gles2::GLES2Interface* gles2 = lock->ContextGL(); |
| 535 | 533 |
| 536 const size_t num_planes = VideoFrame::NumPlanes(output_format_); | 534 const size_t num_planes = VideoFrame::NumPlanes(output_format_); |
| 537 const size_t planes_per_copy = PlanesPerCopy(output_format_); | 535 const size_t planes_per_copy = PlanesPerCopy(output_format_); |
| 538 const gfx::Size coded_size = CodedSize(video_frame, output_format_); | 536 const gfx::Size coded_size = CodedSize(video_frame, output_format_); |
| 539 gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; | 537 gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; |
| 540 // Set up the planes creating the mailboxes needed to refer to the textures. | 538 // Set up the planes creating the mailboxes needed to refer to the textures. |
| 541 for (size_t i = 0; i < num_planes; i += planes_per_copy) { | 539 for (size_t i = 0; i < num_planes; i += planes_per_copy) { |
| 542 PlaneResource& plane_resource = frame_resources->plane_resources[i]; | 540 PlaneResource& plane_resource = frame_resources->plane_resources[i]; |
| 541 const gfx::BufferFormat buffer_format = |
| 542 GpuMemoryBufferFormat(output_format_, i); |
| 543 unsigned texture_target = gpu_factories_->ImageTextureTarget(buffer_format); |
| 543 // Bind the texture and create or rebind the image. | 544 // Bind the texture and create or rebind the image. |
| 544 gles2->BindTexture(texture_target_, plane_resource.texture_id); | 545 gles2->BindTexture(texture_target, plane_resource.texture_id); |
| 545 | 546 |
| 546 if (plane_resource.gpu_memory_buffer && !plane_resource.image_id) { | 547 if (plane_resource.gpu_memory_buffer && !plane_resource.image_id) { |
| 547 const size_t width = | 548 const size_t width = |
| 548 VideoFrame::Columns(i, output_format_, coded_size.width()); | 549 VideoFrame::Columns(i, output_format_, coded_size.width()); |
| 549 const size_t height = | 550 const size_t height = |
| 550 VideoFrame::Rows(i, output_format_, coded_size.height()); | 551 VideoFrame::Rows(i, output_format_, coded_size.height()); |
| 551 plane_resource.image_id = gles2->CreateImageCHROMIUM( | 552 plane_resource.image_id = gles2->CreateImageCHROMIUM( |
| 552 plane_resource.gpu_memory_buffer->AsClientBuffer(), width, height, | 553 plane_resource.gpu_memory_buffer->AsClientBuffer(), width, height, |
| 553 ImageInternalFormat(output_format_, i)); | 554 ImageInternalFormat(output_format_, i)); |
| 554 } else if (plane_resource.image_id) { | 555 } else if (plane_resource.image_id) { |
| 555 gles2->ReleaseTexImage2DCHROMIUM(texture_target_, | 556 gles2->ReleaseTexImage2DCHROMIUM(texture_target, plane_resource.image_id); |
| 556 plane_resource.image_id); | |
| 557 } | 557 } |
| 558 if (plane_resource.image_id) | 558 if (plane_resource.image_id) |
| 559 gles2->BindTexImage2DCHROMIUM(texture_target_, plane_resource.image_id); | 559 gles2->BindTexImage2DCHROMIUM(texture_target, plane_resource.image_id); |
| 560 mailbox_holders[i] = gpu::MailboxHolder(plane_resource.mailbox, | 560 mailbox_holders[i] = gpu::MailboxHolder(plane_resource.mailbox, |
| 561 gpu::SyncToken(), texture_target_); | 561 gpu::SyncToken(), texture_target); |
| 562 } | 562 } |
| 563 | 563 |
| 564 // Insert a sync_token, this is needed to make sure that the textures the | 564 // Insert a sync_token, this is needed to make sure that the textures the |
| 565 // mailboxes refer to will be used only after all the previous commands posted | 565 // mailboxes refer to will be used only after all the previous commands posted |
| 566 // in the command buffer have been processed. | 566 // in the command buffer have been processed. |
| 567 gpu::SyncToken sync_token(gles2->InsertSyncPointCHROMIUM()); | 567 gpu::SyncToken sync_token(gles2->InsertSyncPointCHROMIUM()); |
| 568 for (size_t i = 0; i < num_planes; i += planes_per_copy) | 568 for (size_t i = 0; i < num_planes; i += planes_per_copy) |
| 569 mailbox_holders[i].sync_token = sync_token; | 569 mailbox_holders[i].sync_token = sync_token; |
| 570 | 570 |
| 571 scoped_refptr<VideoFrame> frame; | 571 scoped_refptr<VideoFrame> frame; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 PlaneResource& plane_resource = frame_resources->plane_resources[i]; | 659 PlaneResource& plane_resource = frame_resources->plane_resources[i]; |
| 660 const size_t width = VideoFrame::Columns(i, format, size.width()); | 660 const size_t width = VideoFrame::Columns(i, format, size.width()); |
| 661 const size_t height = VideoFrame::Rows(i, format, size.height()); | 661 const size_t height = VideoFrame::Rows(i, format, size.height()); |
| 662 plane_resource.size = gfx::Size(width, height); | 662 plane_resource.size = gfx::Size(width, height); |
| 663 | 663 |
| 664 const gfx::BufferFormat buffer_format = GpuMemoryBufferFormat(format, i); | 664 const gfx::BufferFormat buffer_format = GpuMemoryBufferFormat(format, i); |
| 665 plane_resource.gpu_memory_buffer = gpu_factories_->AllocateGpuMemoryBuffer( | 665 plane_resource.gpu_memory_buffer = gpu_factories_->AllocateGpuMemoryBuffer( |
| 666 plane_resource.size, buffer_format, | 666 plane_resource.size, buffer_format, |
| 667 gfx::BufferUsage::GPU_READ_CPU_READ_WRITE); | 667 gfx::BufferUsage::GPU_READ_CPU_READ_WRITE); |
| 668 | 668 |
| 669 unsigned texture_target = gpu_factories_->ImageTextureTarget(buffer_format); |
| 669 gles2->GenTextures(1, &plane_resource.texture_id); | 670 gles2->GenTextures(1, &plane_resource.texture_id); |
| 670 gles2->BindTexture(texture_target_, plane_resource.texture_id); | 671 gles2->BindTexture(texture_target, plane_resource.texture_id); |
| 671 gles2->TexParameteri(texture_target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 672 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 672 gles2->TexParameteri(texture_target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 673 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 673 gles2->TexParameteri(texture_target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 674 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 674 gles2->TexParameteri(texture_target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 675 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 675 gles2->GenMailboxCHROMIUM(plane_resource.mailbox.name); | 676 gles2->GenMailboxCHROMIUM(plane_resource.mailbox.name); |
| 676 gles2->ProduceTextureCHROMIUM(texture_target_, plane_resource.mailbox.name); | 677 gles2->ProduceTextureCHROMIUM(texture_target, plane_resource.mailbox.name); |
| 677 } | 678 } |
| 678 return frame_resources; | 679 return frame_resources; |
| 679 } | 680 } |
| 680 | 681 |
| 681 // static | 682 // static |
| 682 void GpuMemoryBufferVideoFramePool::PoolImpl::DeleteFrameResources( | 683 void GpuMemoryBufferVideoFramePool::PoolImpl::DeleteFrameResources( |
| 683 GpuVideoAcceleratorFactories* gpu_factories, | 684 GpuVideoAcceleratorFactories* gpu_factories, |
| 684 FrameResources* frame_resources) { | 685 FrameResources* frame_resources) { |
| 685 // TODO(dcastagna): As soon as the context lost is dealt with in media, | 686 // TODO(dcastagna): As soon as the context lost is dealt with in media, |
| 686 // make sure that we won't execute this callback (use a weak pointer to | 687 // make sure that we won't execute this callback (use a weak pointer to |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 } | 742 } |
| 742 | 743 |
| 743 void GpuMemoryBufferVideoFramePool::MaybeCreateHardwareFrame( | 744 void GpuMemoryBufferVideoFramePool::MaybeCreateHardwareFrame( |
| 744 const scoped_refptr<VideoFrame>& video_frame, | 745 const scoped_refptr<VideoFrame>& video_frame, |
| 745 const FrameReadyCB& frame_ready_cb) { | 746 const FrameReadyCB& frame_ready_cb) { |
| 746 DCHECK(video_frame); | 747 DCHECK(video_frame); |
| 747 pool_impl_->CreateHardwareFrame(video_frame, frame_ready_cb); | 748 pool_impl_->CreateHardwareFrame(video_frame, frame_ready_cb); |
| 748 } | 749 } |
| 749 | 750 |
| 750 } // namespace media | 751 } // namespace media |
| OLD | NEW |