| 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/common/gpu/media/gpu_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/gpu_video_decode_accelerator.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 "base/stl_util-inl.h" | 11 #include "base/stl_util-inl.h" |
| 12 #include "gpu/command_buffer/common/command_buffer.h" | 12 #include "gpu/command_buffer/common/command_buffer.h" |
| 13 #include "ipc/ipc_message_macros.h" | 13 #include "ipc/ipc_message_macros.h" |
| 14 #include "ipc/ipc_message_utils.h" | 14 #include "ipc/ipc_message_utils.h" |
| 15 #include "content/common/gpu/gpu_channel.h" | 15 #include "content/common/gpu/gpu_channel.h" |
| 16 #include "content/common/gpu/gpu_command_buffer_stub.h" | 16 #include "content/common/gpu/gpu_command_buffer_stub.h" |
| 17 #include "content/common/gpu/gpu_messages.h" | 17 #include "content/common/gpu/gpu_messages.h" |
| 18 #include "content/common/gpu/media/gpu_video_service.h" | 18 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
| 19 #include "content/common/gpu/media/omx_video_decode_accelerator.h" |
| 20 #include "ui/gfx/gl/gl_surface_egl.h" |
| 21 #endif |
| 19 #include "ui/gfx/size.h" | 22 #include "ui/gfx/size.h" |
| 20 | 23 |
| 21 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( | 24 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( |
| 22 IPC::Message::Sender* sender, | 25 IPC::Message::Sender* sender, |
| 23 int32 host_route_id, | 26 int32 host_route_id, |
| 24 int32 decoder_route_id, | |
| 25 GpuCommandBufferStub* stub) | 27 GpuCommandBufferStub* stub) |
| 26 : sender_(sender), | 28 : sender_(sender), |
| 27 host_route_id_(host_route_id), | 29 host_route_id_(host_route_id), |
| 28 decoder_route_id_(decoder_route_id), | |
| 29 stub_(stub), | 30 stub_(stub), |
| 30 video_decode_accelerator_(NULL) { | 31 video_decode_accelerator_(NULL) { |
| 32 // stub_ owns and will always outlive this object. |
| 31 stub_->AddSetTokenCallback(base::Bind( | 33 stub_->AddSetTokenCallback(base::Bind( |
| 32 &GpuVideoDecodeAccelerator::OnSetToken, this)); | 34 &GpuVideoDecodeAccelerator::OnSetToken, base::Unretained(this))); |
| 33 } | 35 } |
| 34 | 36 |
| 35 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { | 37 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { |
| 36 STLDeleteElements(&deferred_messages_); | 38 STLDeleteElements(&deferred_messages_); |
| 39 // TODO(fischman/vrk): We need to synchronously wait for the OMX decoder |
| 40 // to finish shutting down. |
| 37 } | 41 } |
| 38 | 42 |
| 39 void GpuVideoDecodeAccelerator::OnSetToken(int32 token) { | 43 void GpuVideoDecodeAccelerator::OnSetToken(int32 token) { |
| 40 // Note: this always retries all deferred messages on every token arrival. | 44 // Note: this always retries all deferred messages on every token arrival. |
| 41 // There's an optimization to be done here by only trying messages which are | 45 // There's an optimization to be done here by only trying messages which are |
| 42 // waiting for tokens which are earlier than |token|. | 46 // waiting for tokens which are earlier than |token|. |
| 43 std::vector<IPC::Message*> deferred_messages_copy; | 47 std::vector<IPC::Message*> deferred_messages_copy; |
| 44 std::swap(deferred_messages_copy, deferred_messages_); | 48 std::swap(deferred_messages_copy, deferred_messages_); |
| 45 for (size_t i = 0; i < deferred_messages_copy.size(); ++i) | 49 for (size_t i = 0; i < deferred_messages_copy.size(); ++i) |
| 46 OnMessageReceived(*deferred_messages_copy[i]); | 50 OnMessageReceived(*deferred_messages_copy[i]); |
| 47 STLDeleteElements(&deferred_messages_copy); | 51 STLDeleteElements(&deferred_messages_copy); |
| 48 } | 52 } |
| 49 | 53 |
| 50 bool GpuVideoDecodeAccelerator::DeferMessageIfNeeded( | 54 bool GpuVideoDecodeAccelerator::DeferMessageIfNeeded( |
| 51 const IPC::Message& msg, bool* deferred) { | 55 const IPC::Message& msg, bool* deferred) { |
| 52 // Only consider deferring for message types that need it. | 56 // Only consider deferring for message types that need it. |
| 53 switch (msg.type()) { | 57 switch (msg.type()) { |
| 54 case AcceleratedVideoDecoderMsg_GetConfigs::ID: | 58 case AcceleratedVideoDecoderMsg_GetConfigs::ID: |
| 55 case AcceleratedVideoDecoderMsg_Initialize::ID: | |
| 56 case AcceleratedVideoDecoderMsg_Decode::ID: | 59 case AcceleratedVideoDecoderMsg_Decode::ID: |
| 57 case AcceleratedVideoDecoderMsg_AssignTextures::ID: | 60 case AcceleratedVideoDecoderMsg_AssignGLESBuffers::ID: |
| 58 case AcceleratedVideoDecoderMsg_AssignSysmemBuffers::ID: | 61 case AcceleratedVideoDecoderMsg_AssignSysmemBuffers::ID: |
| 59 case AcceleratedVideoDecoderMsg_ReusePictureBuffer::ID: | 62 case AcceleratedVideoDecoderMsg_ReusePictureBuffer::ID: |
| 60 case AcceleratedVideoDecoderMsg_Flush::ID: | 63 case AcceleratedVideoDecoderMsg_Flush::ID: |
| 61 case AcceleratedVideoDecoderMsg_Abort::ID: | 64 case AcceleratedVideoDecoderMsg_Abort::ID: |
| 62 break; | 65 break; |
| 63 default: | 66 default: |
| 64 return false; | 67 return false; |
| 65 } | 68 } |
| 66 | 69 |
| 67 gpu::ReadWriteTokens tokens; | 70 gpu::ReadWriteTokens tokens; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 80 bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { | 83 bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { |
| 81 bool deferred = false; | 84 bool deferred = false; |
| 82 if (!DeferMessageIfNeeded(msg, &deferred)) | 85 if (!DeferMessageIfNeeded(msg, &deferred)) |
| 83 return false; | 86 return false; |
| 84 if (deferred) | 87 if (deferred) |
| 85 return true; | 88 return true; |
| 86 | 89 |
| 87 bool handled = true; | 90 bool handled = true; |
| 88 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg) | 91 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg) |
| 89 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_GetConfigs, OnGetConfigs) | 92 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_GetConfigs, OnGetConfigs) |
| 90 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Initialize, OnInitialize) | |
| 91 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode) | 93 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode) |
| 92 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignTextures, | 94 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignGLESBuffers, |
| 93 OnAssignTextures) | 95 OnAssignGLESBuffers) |
| 94 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignSysmemBuffers, | 96 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignSysmemBuffers, |
| 95 OnAssignSysmemBuffers) | 97 OnAssignSysmemBuffers) |
| 96 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_ReusePictureBuffer, | 98 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_ReusePictureBuffer, |
| 97 OnReusePictureBuffer) | 99 OnReusePictureBuffer) |
| 98 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Flush, OnFlush) | 100 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Flush, OnFlush) |
| 99 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Abort, OnAbort) | 101 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Abort, OnAbort) |
| 100 IPC_MESSAGE_UNHANDLED(handled = false) | 102 IPC_MESSAGE_UNHANDLED(handled = false) |
| 101 IPC_END_MESSAGE_MAP() | 103 IPC_END_MESSAGE_MAP() |
| 102 return handled; | 104 return handled; |
| 103 } | 105 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 void GpuVideoDecodeAccelerator::OnGetConfigs( | 161 void GpuVideoDecodeAccelerator::OnGetConfigs( |
| 160 const gpu::ReadWriteTokens& /* tokens */, | 162 const gpu::ReadWriteTokens& /* tokens */, |
| 161 const std::vector<uint32>& requested, std::vector<uint32>* matched) { | 163 const std::vector<uint32>& requested, std::vector<uint32>* matched) { |
| 162 // TODO(fischman,vrk): this is borked; can't have a VDA before calling | 164 // TODO(fischman,vrk): this is borked; can't have a VDA before calling |
| 163 // Initialize, but can't call Initialize until we have some configs! | 165 // Initialize, but can't call Initialize until we have some configs! |
| 164 if (!video_decode_accelerator_.get()) | 166 if (!video_decode_accelerator_.get()) |
| 165 return; | 167 return; |
| 166 video_decode_accelerator_->GetConfigs(requested, matched); | 168 video_decode_accelerator_->GetConfigs(requested, matched); |
| 167 } | 169 } |
| 168 | 170 |
| 169 void GpuVideoDecodeAccelerator::OnInitialize( | 171 void GpuVideoDecodeAccelerator::Initialize(const std::vector<uint32>& configs) { |
| 170 const gpu::ReadWriteTokens& /* tokens */, | |
| 171 const std::vector<uint32>& configs) { | |
| 172 DCHECK(!video_decode_accelerator_.get()); | 172 DCHECK(!video_decode_accelerator_.get()); |
| 173 GpuVideoService::GetInstance()->InitializeVideoDecoder(decoder_route_id_); | 173 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
| 174 DCHECK(video_decode_accelerator_.get()); | 174 DCHECK(stub_ && stub_->scheduler()); |
| 175 OmxVideoDecodeAccelerator* omx_decoder = new OmxVideoDecodeAccelerator(this); |
| 176 omx_decoder->SetEglState( |
| 177 gfx::GLSurfaceEGL::GetDisplay(), |
| 178 stub_->scheduler()->decoder()->GetGLContext()->GetHandle()); |
| 179 video_decode_accelerator_.reset(omx_decoder); |
| 175 video_decode_accelerator_->Initialize(configs); | 180 video_decode_accelerator_->Initialize(configs); |
| 181 #else |
| 182 NOTIMPLEMENTED() << "HW video decode acceleration not available."; |
| 183 #endif // defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
| 176 } | 184 } |
| 177 | 185 |
| 178 void GpuVideoDecodeAccelerator::OnDecode( | 186 void GpuVideoDecodeAccelerator::OnDecode( |
| 179 const gpu::ReadWriteTokens&, /* tokens */ | 187 const gpu::ReadWriteTokens&, /* tokens */ |
| 180 base::SharedMemoryHandle handle, int32 id, int32 size) { | 188 base::SharedMemoryHandle handle, int32 id, int32 size) { |
| 181 DCHECK(video_decode_accelerator_.get()); | 189 DCHECK(video_decode_accelerator_.get()); |
| 182 video_decode_accelerator_->Decode(media::BitstreamBuffer(id, handle, size)); | 190 video_decode_accelerator_->Decode(media::BitstreamBuffer(id, handle, size)); |
| 183 } | 191 } |
| 184 | 192 |
| 185 void GpuVideoDecodeAccelerator::AssignGLESBuffers( | 193 void GpuVideoDecodeAccelerator::OnAssignGLESBuffers( |
| 186 const std::vector<media::GLESBuffer>& buffers) { | 194 const gpu::ReadWriteTokens& /* tokens */, |
| 187 // TODO(fischman,vrk): it's wonky that we handle the AssignTextures message by | 195 const std::vector<int32>& buffer_ids, |
| 188 // handing its contents to GpuVideoService which then turns around and calls | 196 const std::vector<uint32>& texture_ids, |
| 189 // this (public) method. Instead we should make GpuVideoService vend the | 197 const std::vector<gfx::Size>& sizes) { |
| 190 // translation method we need and use it directly. | 198 DCHECK(stub_ && stub_->scheduler()); // Ensure already Initialize()'d. |
| 191 DCHECK(video_decode_accelerator_.get()); | 199 gpu::gles2::GLES2Decoder* command_decoder = stub_->scheduler()->decoder(); |
| 200 |
| 201 std::vector<media::GLESBuffer> buffers; |
| 202 for (uint32 i = 0; i < buffer_ids.size(); ++i) { |
| 203 uint32 service_texture_id; |
| 204 if (!command_decoder->GetServiceTextureId( |
| 205 texture_ids[i], &service_texture_id)) { |
| 206 // TODO(vrk): Send an error for invalid GLES buffers. |
| 207 LOG(DFATAL) << "Failed to translate texture!"; |
| 208 return; |
| 209 } |
| 210 buffers.push_back(media::GLESBuffer( |
| 211 buffer_ids[i], sizes[i], service_texture_id)); |
| 212 } |
| 192 video_decode_accelerator_->AssignGLESBuffers(buffers); | 213 video_decode_accelerator_->AssignGLESBuffers(buffers); |
| 193 } | 214 } |
| 194 | 215 |
| 195 void GpuVideoDecodeAccelerator::OnAssignTextures( | |
| 196 const gpu::ReadWriteTokens& /* tokens */, | |
| 197 const std::vector<int32>& buffer_ids, | |
| 198 const std::vector<uint32>& texture_ids, | |
| 199 const std::vector<gfx::Size>& sizes) { | |
| 200 GpuVideoService* service = GpuVideoService::GetInstance(); | |
| 201 service->AssignTexturesToDecoder( | |
| 202 decoder_route_id_, buffer_ids, texture_ids, sizes); | |
| 203 } | |
| 204 | |
| 205 void GpuVideoDecodeAccelerator::OnAssignSysmemBuffers( | 216 void GpuVideoDecodeAccelerator::OnAssignSysmemBuffers( |
| 206 const gpu::ReadWriteTokens& /* tokens */, | 217 const gpu::ReadWriteTokens& /* tokens */, |
| 207 const std::vector<int32> buffer_ids, | 218 const std::vector<int32> buffer_ids, |
| 208 const std::vector<base::SharedMemoryHandle> data, | 219 const std::vector<base::SharedMemoryHandle> data, |
| 209 const std::vector<gfx::Size> sizes) { | 220 const std::vector<gfx::Size> sizes) { |
| 210 // TODO(vrk): Implement. | 221 // TODO(vrk): Implement. |
| 211 NOTIMPLEMENTED(); | 222 NOTIMPLEMENTED(); |
| 212 } | 223 } |
| 213 | 224 |
| 214 void GpuVideoDecodeAccelerator::OnReusePictureBuffer( | 225 void GpuVideoDecodeAccelerator::OnReusePictureBuffer( |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 | 263 |
| 253 void GpuVideoDecodeAccelerator::NotifyAbortDone() { | 264 void GpuVideoDecodeAccelerator::NotifyAbortDone() { |
| 254 if (!Send(new AcceleratedVideoDecoderHostMsg_AbortDone(host_route_id_))) | 265 if (!Send(new AcceleratedVideoDecoderHostMsg_AbortDone(host_route_id_))) |
| 255 LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_AbortDone) failed"; | 266 LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_AbortDone) failed"; |
| 256 } | 267 } |
| 257 | 268 |
| 258 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { | 269 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { |
| 259 DCHECK(sender_); | 270 DCHECK(sender_); |
| 260 return sender_->Send(message); | 271 return sender_->Send(message); |
| 261 } | 272 } |
| OLD | NEW |