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 |