| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/renderer/pepper_platform_video_decoder_impl.h" | 5 #include "content/renderer/pepper_platform_video_decoder_impl.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "content/common/child_process.h" | 11 #include "content/common/child_process.h" |
| 12 #include "content/renderer/gpu/gpu_channel_host.h" | 12 #include "content/renderer/gpu/gpu_channel_host.h" |
| 13 #include "content/renderer/gpu/gpu_video_decode_accelerator_host.h" | 13 #include "content/renderer/gpu/gpu_video_decode_accelerator_host.h" |
| 14 #include "content/renderer/gpu/gpu_video_service_host.h" | 14 #include "content/renderer/gpu/gpu_video_service_host.h" |
| 15 #include "content/renderer/render_thread.h" | 15 #include "content/renderer/render_thread.h" |
| 16 | 16 |
| 17 using media::BitstreamBuffer; | 17 using media::BitstreamBuffer; |
| 18 | 18 |
| 19 PlatformVideoDecoderImpl::PlatformVideoDecoderImpl( | 19 PlatformVideoDecoderImpl::PlatformVideoDecoderImpl( |
| 20 VideoDecodeAccelerator::Client* client, uint32 command_buffer_route_id) | 20 VideoDecodeAccelerator::Client* client, |
| 21 int32 command_buffer_route_id, |
| 22 gpu::CommandBufferHelper* cmd_buffer_helper) |
| 21 : client_(client), | 23 : client_(client), |
| 22 command_buffer_route_id_(command_buffer_route_id), | 24 command_buffer_route_id_(command_buffer_route_id), |
| 23 decoder_(NULL), | 25 cmd_buffer_helper_(cmd_buffer_helper), |
| 24 message_loop_(NULL) { | 26 decoder_(NULL) { |
| 25 DCHECK(client); | 27 DCHECK(client); |
| 26 } | 28 } |
| 27 | 29 |
| 28 PlatformVideoDecoderImpl::~PlatformVideoDecoderImpl() {} | 30 PlatformVideoDecoderImpl::~PlatformVideoDecoderImpl() {} |
| 29 | 31 |
| 30 bool PlatformVideoDecoderImpl::GetConfigs( | 32 bool PlatformVideoDecoderImpl::GetConfigs( |
| 31 const std::vector<uint32>& requested_configs, | 33 const std::vector<uint32>& requested_configs, |
| 32 std::vector<uint32>* matched_configs) { | 34 std::vector<uint32>* matched_configs) { |
| 33 // TODO(vrk): Implement. | 35 // TODO(vrk): Implement. |
| 34 NOTIMPLEMENTED(); | 36 NOTIMPLEMENTED(); |
| 35 return true; | 37 return true; |
| 36 } | 38 } |
| 37 | 39 |
| 38 bool PlatformVideoDecoderImpl::Initialize(const std::vector<uint32>& config) { | 40 bool PlatformVideoDecoderImpl::Initialize(const std::vector<uint32>& config) { |
| 39 // TODO(vrk): Support multiple decoders. | 41 // TODO(vrk): Support multiple decoders. |
| 40 if (decoder_.get()) | 42 if (decoder_.get()) |
| 41 return true; | 43 return true; |
| 42 | 44 |
| 43 RenderThread* render_thread = RenderThread::current(); | 45 RenderThread* render_thread = RenderThread::current(); |
| 44 DCHECK(render_thread); | 46 DCHECK(render_thread); |
| 45 message_loop_ = MessageLoop::current(); | |
| 46 DCHECK(message_loop_); | |
| 47 | 47 |
| 48 channel_ = render_thread->EstablishGpuChannelSync( | 48 channel_ = render_thread->EstablishGpuChannelSync( |
| 49 content::CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE); | 49 content::CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE); |
| 50 | 50 |
| 51 if (!channel_.get()) | 51 if (!channel_.get()) |
| 52 return false; | 52 return false; |
| 53 | 53 |
| 54 DCHECK_EQ(channel_->state(), GpuChannelHost::kConnected); | 54 DCHECK_EQ(channel_->state(), GpuChannelHost::kConnected); |
| 55 | 55 |
| 56 // Set a callback to ensure decoder is only initialized after channel is | 56 // Set a callback to ensure decoder is only initialized after channel is |
| 57 // connected and GpuVidoServiceHost message filter is added to channel. | 57 // connected and GpuVidoServiceHost message filter is added to channel. |
| 58 base::Closure initialize = base::Bind( | 58 base::Closure initialize = base::Bind( |
| 59 &PlatformVideoDecoderImpl::InitializeDecoder, | 59 &PlatformVideoDecoderImpl::InitializeDecoder, |
| 60 base::Unretained(this), | 60 base::Unretained(this), |
| 61 config); | 61 config); |
| 62 | 62 |
| 63 GpuVideoServiceHost* video_service = channel_->gpu_video_service_host(); | 63 GpuVideoServiceHost* video_service = channel_->gpu_video_service_host(); |
| 64 video_service->SetOnInitialized(initialize); | 64 video_service->SetOnInitialized(initialize); |
| 65 return true; | 65 return true; |
| 66 } | 66 } |
| 67 | 67 |
| 68 void PlatformVideoDecoderImpl::InitializeDecoder( | 68 void PlatformVideoDecoderImpl::InitializeDecoder( |
| 69 const std::vector<uint32>& configs) { | 69 const std::vector<uint32>& configs) { |
| 70 // Only create GpuVideoDecodeAcceleratorHost on IO thread. | 70 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current()); |
| 71 if (ChildProcess::current()->io_message_loop() != MessageLoop::current() ) { | |
| 72 ChildProcess::current()->io_message_loop()-> | |
| 73 PostTask(FROM_HERE, base::Bind( | |
| 74 &PlatformVideoDecoderImpl::InitializeDecoder, | |
| 75 base::Unretained(this), | |
| 76 configs)); | |
| 77 return; | |
| 78 } | |
| 79 GpuVideoServiceHost* video_service = channel_->gpu_video_service_host(); | 71 GpuVideoServiceHost* video_service = channel_->gpu_video_service_host(); |
| 80 decoder_.reset(video_service->CreateVideoAccelerator( | 72 decoder_.reset(video_service->CreateVideoAccelerator( |
| 81 this, command_buffer_route_id_)); | 73 this, command_buffer_route_id_, cmd_buffer_helper_)); |
| 82 | 74 |
| 83 // Send IPC message to initialize decoder in GPU process. | 75 // Send IPC message to initialize decoder in GPU process. |
| 84 decoder_->Initialize(configs); | 76 decoder_->Initialize(configs); |
| 85 } | 77 } |
| 86 | 78 |
| 87 bool PlatformVideoDecoderImpl::Decode(const BitstreamBuffer& bitstream_buffer) { | 79 void PlatformVideoDecoderImpl::Decode(const BitstreamBuffer& bitstream_buffer) { |
| 88 DCHECK(decoder_.get()); | 80 DCHECK(decoder_.get()); |
| 89 return decoder_->Decode(bitstream_buffer); | 81 decoder_->Decode(bitstream_buffer); |
| 90 } | 82 } |
| 91 | 83 |
| 92 void PlatformVideoDecoderImpl::AssignGLESBuffers( | 84 void PlatformVideoDecoderImpl::AssignGLESBuffers( |
| 93 const std::vector<media::GLESBuffer>& buffers) { | 85 const std::vector<media::GLESBuffer>& buffers) { |
| 94 DCHECK(decoder_.get()); | 86 DCHECK(decoder_.get()); |
| 95 decoder_->AssignGLESBuffers(buffers); | 87 decoder_->AssignGLESBuffers(buffers); |
| 96 } | 88 } |
| 97 | 89 |
| 98 void PlatformVideoDecoderImpl::AssignSysmemBuffers( | 90 void PlatformVideoDecoderImpl::AssignSysmemBuffers( |
| 99 const std::vector<media::SysmemBuffer>& buffers) { | 91 const std::vector<media::SysmemBuffer>& buffers) { |
| 100 DCHECK(decoder_.get()); | 92 DCHECK(decoder_.get()); |
| 101 decoder_->AssignSysmemBuffers(buffers); | 93 decoder_->AssignSysmemBuffers(buffers); |
| 102 } | 94 } |
| 103 | 95 |
| 104 void PlatformVideoDecoderImpl::ReusePictureBuffer( | 96 void PlatformVideoDecoderImpl::ReusePictureBuffer( |
| 105 int32 picture_buffer_id) { | 97 int32 picture_buffer_id) { |
| 106 DCHECK(decoder_.get()); | 98 DCHECK(decoder_.get()); |
| 107 decoder_->ReusePictureBuffer(picture_buffer_id); | 99 decoder_->ReusePictureBuffer(picture_buffer_id); |
| 108 } | 100 } |
| 109 | 101 |
| 110 bool PlatformVideoDecoderImpl::Flush() { | 102 void PlatformVideoDecoderImpl::Flush() { |
| 111 DCHECK(decoder_.get()); | 103 DCHECK(decoder_.get()); |
| 112 return decoder_->Flush(); | 104 decoder_->Flush(); |
| 113 } | 105 } |
| 114 | 106 |
| 115 bool PlatformVideoDecoderImpl::Abort() { | 107 void PlatformVideoDecoderImpl::Abort() { |
| 116 DCHECK(decoder_.get()); | 108 DCHECK(decoder_.get()); |
| 117 return decoder_->Abort(); | 109 decoder_->Abort(); |
| 118 } | 110 } |
| 119 | 111 |
| 120 void PlatformVideoDecoderImpl::NotifyEndOfStream() { | 112 void PlatformVideoDecoderImpl::NotifyEndOfStream() { |
| 121 DCHECK(message_loop_); | 113 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current()); |
| 122 message_loop_-> | 114 client_->NotifyEndOfStream(); |
| 123 PostTask(FROM_HERE, base::Bind( | |
| 124 &VideoDecodeAccelerator::Client::NotifyEndOfStream, | |
| 125 base::Unretained(client_))); | |
| 126 } | 115 } |
| 127 | 116 |
| 128 void PlatformVideoDecoderImpl::NotifyError( | 117 void PlatformVideoDecoderImpl::NotifyError( |
| 129 VideoDecodeAccelerator::Error error) { | 118 VideoDecodeAccelerator::Error error) { |
| 130 DCHECK(message_loop_); | 119 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current()); |
| 131 message_loop_-> | 120 client_->NotifyError(error); |
| 132 PostTask(FROM_HERE, base::Bind( | |
| 133 &VideoDecodeAccelerator::Client::NotifyError, | |
| 134 base::Unretained(client_), | |
| 135 error)); | |
| 136 } | 121 } |
| 137 | 122 |
| 138 void PlatformVideoDecoderImpl::ProvidePictureBuffers( | 123 void PlatformVideoDecoderImpl::ProvidePictureBuffers( |
| 139 uint32 requested_num_of_buffers, | 124 uint32 requested_num_of_buffers, |
| 140 const gfx::Size& dimensions, | 125 const gfx::Size& dimensions, |
| 141 media::VideoDecodeAccelerator::MemoryType type) { | 126 media::VideoDecodeAccelerator::MemoryType type) { |
| 142 DCHECK(message_loop_); | 127 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current()); |
| 143 message_loop_-> | 128 client_->ProvidePictureBuffers(requested_num_of_buffers, dimensions, type); |
| 144 PostTask(FROM_HERE, base::Bind( | |
| 145 &VideoDecodeAccelerator::Client::ProvidePictureBuffers, | |
| 146 base::Unretained(client_), | |
| 147 requested_num_of_buffers, | |
| 148 dimensions, | |
| 149 type)); | |
| 150 } | 129 } |
| 151 | 130 |
| 152 void PlatformVideoDecoderImpl::DismissPictureBuffer(int32 picture_buffer_id) { | 131 void PlatformVideoDecoderImpl::DismissPictureBuffer(int32 picture_buffer_id) { |
| 153 DCHECK(message_loop_); | 132 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current()); |
| 154 message_loop_-> | 133 client_->DismissPictureBuffer(picture_buffer_id); |
| 155 PostTask(FROM_HERE, base::Bind( | |
| 156 &VideoDecodeAccelerator::Client::DismissPictureBuffer, | |
| 157 base::Unretained(client_), | |
| 158 picture_buffer_id)); | |
| 159 } | 134 } |
| 160 | 135 |
| 161 void PlatformVideoDecoderImpl::PictureReady(const media::Picture& picture) { | 136 void PlatformVideoDecoderImpl::PictureReady(const media::Picture& picture) { |
| 162 DCHECK(message_loop_); | 137 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current()); |
| 163 message_loop_-> | 138 client_->PictureReady(picture); |
| 164 PostTask(FROM_HERE, base::Bind( | |
| 165 &VideoDecodeAccelerator::Client::PictureReady, | |
| 166 base::Unretained(client_), | |
| 167 picture)); | |
| 168 } | 139 } |
| 169 | 140 |
| 170 void PlatformVideoDecoderImpl::NotifyInitializeDone() { | 141 void PlatformVideoDecoderImpl::NotifyInitializeDone() { |
| 171 DCHECK(message_loop_); | 142 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current()); |
| 172 message_loop_-> | 143 client_->NotifyInitializeDone(); |
| 173 PostTask(FROM_HERE, base::Bind( | |
| 174 &VideoDecodeAccelerator::Client::NotifyInitializeDone, | |
| 175 base::Unretained(client_))); | |
| 176 } | 144 } |
| 177 | 145 |
| 178 void PlatformVideoDecoderImpl::NotifyEndOfBitstreamBuffer( | 146 void PlatformVideoDecoderImpl::NotifyEndOfBitstreamBuffer( |
| 179 int32 bitstream_buffer_id) { | 147 int32 bitstream_buffer_id) { |
| 180 DCHECK(message_loop_); | 148 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current()); |
| 181 message_loop_-> | 149 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id); |
| 182 PostTask(FROM_HERE, base::Bind( | |
| 183 &VideoDecodeAccelerator::Client::NotifyEndOfBitstreamBuffer, | |
| 184 base::Unretained(client_), | |
| 185 bitstream_buffer_id)); | |
| 186 } | 150 } |
| 187 | 151 |
| 188 void PlatformVideoDecoderImpl::NotifyFlushDone() { | 152 void PlatformVideoDecoderImpl::NotifyFlushDone() { |
| 189 DCHECK(message_loop_); | 153 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current()); |
| 190 message_loop_-> | 154 client_->NotifyFlushDone(); |
| 191 PostTask(FROM_HERE, base::Bind( | |
| 192 &VideoDecodeAccelerator::Client::NotifyFlushDone, | |
| 193 base::Unretained(client_))); | |
| 194 } | 155 } |
| 195 | 156 |
| 196 void PlatformVideoDecoderImpl::NotifyAbortDone() { | 157 void PlatformVideoDecoderImpl::NotifyAbortDone() { |
| 197 DCHECK(message_loop_); | 158 DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current()); |
| 198 message_loop_-> | 159 client_->NotifyAbortDone(); |
| 199 PostTask(FROM_HERE, base::Bind( | |
| 200 &VideoDecodeAccelerator::Client::NotifyAbortDone, | |
| 201 base::Unretained(client_))); | |
| 202 } | 160 } |
| OLD | NEW |