Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 GpuVideoDecodeAccelerator* owner_; | 123 GpuVideoDecodeAccelerator* owner_; |
| 124 int32 host_route_id_; | 124 int32 host_route_id_; |
| 125 // The channel to which this filter was added. | 125 // The channel to which this filter was added. |
| 126 IPC::Channel* channel_; | 126 IPC::Channel* channel_; |
| 127 }; | 127 }; |
| 128 | 128 |
| 129 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( | 129 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( |
| 130 int32 host_route_id, | 130 int32 host_route_id, |
| 131 GpuCommandBufferStub* stub, | 131 GpuCommandBufferStub* stub, |
| 132 const scoped_refptr<base::MessageLoopProxy>& io_message_loop) | 132 const scoped_refptr<base::MessageLoopProxy>& io_message_loop) |
| 133 : init_done_msg_(NULL), | 133 : host_route_id_(host_route_id), |
| 134 host_route_id_(host_route_id), | |
| 135 stub_(stub), | 134 stub_(stub), |
| 136 texture_target_(0), | 135 texture_target_(0), |
| 137 filter_removed_(true, false), | 136 filter_removed_(true, false), |
| 138 io_message_loop_(io_message_loop), | 137 io_message_loop_(io_message_loop), |
| 139 weak_factory_for_io_(this) { | 138 weak_factory_for_io_(this) { |
| 140 DCHECK(stub_); | 139 DCHECK(stub_); |
| 141 stub_->AddDestructionObserver(this); | 140 stub_->AddDestructionObserver(this); |
| 142 stub_->channel()->AddRoute(host_route_id_, this); | 141 stub_->channel()->AddRoute(host_route_id_, this); |
| 143 child_message_loop_ = base::MessageLoopProxy::current(); | 142 child_message_loop_ = base::MessageLoopProxy::current(); |
| 144 make_context_current_ = | 143 make_context_current_ = |
| 145 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); | 144 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); |
| 146 } | 145 } |
| 147 | 146 |
| 148 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { | 147 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { |
| 149 // This class can only be self-deleted from OnWillDestroyStub(), which means | 148 // This class can only be self-deleted from OnWillDestroyStub(), which means |
| 150 // the VDA has already been destroyed in there. | 149 // the VDA has already been destroyed in there. |
| 151 CHECK(!video_decode_accelerator_.get()); | 150 DCHECK(!video_decode_accelerator_); |
| 152 } | 151 } |
| 153 | 152 |
| 154 bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { | 153 bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { |
| 155 if (!video_decode_accelerator_) | 154 if (!video_decode_accelerator_) |
| 156 return false; | 155 return false; |
| 157 | 156 |
| 158 bool handled = true; | 157 bool handled = true; |
| 159 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg) | 158 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg) |
| 160 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode) | 159 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode) |
| 161 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignPictureBuffers, | 160 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignPictureBuffers, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( | 221 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( |
| 223 host_route_id_, | 222 host_route_id_, |
| 224 picture.picture_buffer_id(), | 223 picture.picture_buffer_id(), |
| 225 picture.bitstream_buffer_id()))) { | 224 picture.bitstream_buffer_id()))) { |
| 226 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; | 225 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; |
| 227 } | 226 } |
| 228 } | 227 } |
| 229 | 228 |
| 230 void GpuVideoDecodeAccelerator::NotifyError( | 229 void GpuVideoDecodeAccelerator::NotifyError( |
| 231 media::VideoDecodeAccelerator::Error error) { | 230 media::VideoDecodeAccelerator::Error error) { |
| 232 if (init_done_msg_) { | |
| 233 // If we get an error while we're initializing, NotifyInitializeDone won't | |
| 234 // be called, so we need to send the reply (with an error) here. | |
| 235 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams( | |
| 236 init_done_msg_, -1); | |
| 237 if (!Send(init_done_msg_)) | |
| 238 DLOG(ERROR) << "Send(init_done_msg_) failed"; | |
| 239 init_done_msg_ = NULL; | |
| 240 return; | |
| 241 } | |
| 242 if (!Send(new AcceleratedVideoDecoderHostMsg_ErrorNotification( | 231 if (!Send(new AcceleratedVideoDecoderHostMsg_ErrorNotification( |
| 243 host_route_id_, error))) { | 232 host_route_id_, error))) { |
| 244 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ErrorNotification) " | 233 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ErrorNotification) " |
| 245 << "failed"; | 234 << "failed"; |
| 246 } | 235 } |
| 247 } | 236 } |
| 248 | 237 |
| 249 void GpuVideoDecodeAccelerator::Initialize( | 238 void GpuVideoDecodeAccelerator::Initialize( |
| 250 const media::VideoCodecProfile profile, | 239 const media::VideoCodecProfile profile, |
| 251 IPC::Message* init_done_msg) { | 240 IPC::Message* init_done_msg) { |
| 252 DCHECK(!video_decode_accelerator_.get()); | 241 DCHECK(!video_decode_accelerator_.get()); |
| 253 DCHECK(!init_done_msg_); | |
| 254 DCHECK(init_done_msg); | |
| 255 init_done_msg_ = init_done_msg; | |
| 256 | 242 |
| 257 #if !defined(OS_WIN) | 243 #if !defined(OS_WIN) |
| 258 // Ensure we will be able to get a GL context at all before initializing | 244 // Ensure we will be able to get a GL context at all before initializing |
| 259 // non-Windows VDAs. | 245 // non-Windows VDAs. |
| 260 if (!make_context_current_.Run()) { | 246 if (!make_context_current_.Run()) { |
| 261 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 247 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(init_done_msg, -1); |
| 248 Send(init_done_msg); | |
|
Pawel Osciak
2014/03/13 06:18:13
These seem to beg for a common define/method...
sheu
2014/03/13 22:39:52
Guess I could macro-ize this.
| |
| 262 return; | 249 return; |
| 263 } | 250 } |
| 264 #endif | 251 #endif |
| 265 | 252 |
| 266 #if defined(OS_WIN) | 253 #if defined(OS_WIN) |
| 267 if (base::win::GetVersion() < base::win::VERSION_WIN7) { | 254 if (base::win::GetVersion() < base::win::VERSION_WIN7) { |
| 268 NOTIMPLEMENTED() << "HW video decode acceleration not available."; | 255 NOTIMPLEMENTED() << "HW video decode acceleration not available."; |
| 269 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 256 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(init_done_msg, -1); |
| 257 Send(init_done_msg); | |
| 270 return; | 258 return; |
| 271 } | 259 } |
| 272 DVLOG(0) << "Initializing DXVA HW decoder for windows."; | 260 DVLOG(0) << "Initializing DXVA HW decoder for windows."; |
| 273 video_decode_accelerator_.reset( | 261 video_decode_accelerator_.reset( |
| 274 new DXVAVideoDecodeAccelerator(make_context_current_)); | 262 new DXVAVideoDecodeAccelerator(make_context_current_)); |
| 275 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) | 263 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) |
| 276 scoped_ptr<V4L2Device> device = V4L2Device::Create(); | 264 scoped_ptr<V4L2Device> device = V4L2Device::Create(); |
| 277 if (!device.get()) { | 265 if (!device.get()) { |
| 278 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 266 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(init_done_msg, -1); |
| 267 Send(init_done_msg); | |
| 279 return; | 268 return; |
| 280 } | 269 } |
| 281 video_decode_accelerator_.reset( | 270 video_decode_accelerator_.reset( |
| 282 new V4L2VideoDecodeAccelerator(gfx::GLSurfaceEGL::GetHardwareDisplay(), | 271 new V4L2VideoDecodeAccelerator(gfx::GLSurfaceEGL::GetHardwareDisplay(), |
| 283 weak_factory_for_io_.GetWeakPtr(), | 272 weak_factory_for_io_.GetWeakPtr(), |
| 284 make_context_current_, | 273 make_context_current_, |
| 285 device.Pass(), | 274 device.Pass(), |
| 286 io_message_loop_)); | 275 io_message_loop_)); |
| 287 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) | 276 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) |
| 288 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) { | 277 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) { |
| 289 VLOG(1) << "HW video decode acceleration not available without " | 278 VLOG(1) << "HW video decode acceleration not available without " |
| 290 "DesktopGL (GLX)."; | 279 "DesktopGL (GLX)."; |
| 291 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 280 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(init_done_msg, -1); |
| 281 Send(init_done_msg); | |
| 292 return; | 282 return; |
| 293 } | 283 } |
| 294 gfx::GLContextGLX* glx_context = | 284 gfx::GLContextGLX* glx_context = |
| 295 static_cast<gfx::GLContextGLX*>(stub_->decoder()->GetGLContext()); | 285 static_cast<gfx::GLContextGLX*>(stub_->decoder()->GetGLContext()); |
| 296 video_decode_accelerator_.reset(new VaapiVideoDecodeAccelerator( | 286 video_decode_accelerator_.reset(new VaapiVideoDecodeAccelerator( |
| 297 glx_context->display(), make_context_current_)); | 287 glx_context->display(), make_context_current_)); |
| 298 #elif defined(OS_ANDROID) | 288 #elif defined(OS_ANDROID) |
| 299 video_decode_accelerator_.reset(new AndroidVideoDecodeAccelerator( | 289 video_decode_accelerator_.reset(new AndroidVideoDecodeAccelerator( |
| 300 stub_->decoder()->AsWeakPtr(), | 290 stub_->decoder()->AsWeakPtr(), |
| 301 make_context_current_)); | 291 make_context_current_)); |
| 302 #else | 292 #else |
| 303 NOTIMPLEMENTED() << "HW video decode acceleration not available."; | 293 NOTIMPLEMENTED() << "HW video decode acceleration not available."; |
| 304 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 294 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(init_done_msg, -1); |
| 295 Send(init_done_msg); | |
| 305 return; | 296 return; |
| 306 #endif | 297 #endif |
| 307 | 298 |
| 308 if (video_decode_accelerator_->CanDecodeOnIOThread()) { | 299 if (video_decode_accelerator_->CanDecodeOnIOThread()) { |
| 309 filter_ = new MessageFilter(this, host_route_id_); | 300 filter_ = new MessageFilter(this, host_route_id_); |
| 310 stub_->channel()->AddFilter(filter_.get()); | 301 stub_->channel()->AddFilter(filter_.get()); |
| 311 } | 302 } |
| 312 | 303 |
| 313 if (!video_decode_accelerator_->Initialize(profile, this)) | 304 if (!video_decode_accelerator_->Initialize(profile, this)) { |
| 314 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 305 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(init_done_msg, -1); |
| 306 Send(init_done_msg); | |
| 307 return; | |
| 308 } | |
| 309 | |
| 310 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(init_done_msg, | |
| 311 host_route_id_); | |
| 312 Send(init_done_msg); | |
| 315 } | 313 } |
| 316 | 314 |
| 317 // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is | 315 // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is |
| 318 // true, otherwise on the main thread. | 316 // true, otherwise on the main thread. |
| 319 void GpuVideoDecodeAccelerator::OnDecode( | 317 void GpuVideoDecodeAccelerator::OnDecode( |
| 320 base::SharedMemoryHandle handle, int32 id, uint32 size) { | 318 base::SharedMemoryHandle handle, int32 id, uint32 size) { |
| 321 DCHECK(video_decode_accelerator_.get()); | 319 DCHECK(video_decode_accelerator_.get()); |
| 322 if (id < 0) { | 320 if (id < 0) { |
| 323 DLOG(ERROR) << "BitstreamBuffer id " << id << " out of range"; | 321 DLOG(ERROR) << "BitstreamBuffer id " << id << " out of range"; |
| 324 if (child_message_loop_->BelongsToCurrentThread()) { | 322 if (child_message_loop_->BelongsToCurrentThread()) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 441 void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( | 439 void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( |
| 442 int32 bitstream_buffer_id) { | 440 int32 bitstream_buffer_id) { |
| 443 if (!Send(new AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed( | 441 if (!Send(new AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed( |
| 444 host_route_id_, bitstream_buffer_id))) { | 442 host_route_id_, bitstream_buffer_id))) { |
| 445 DLOG(ERROR) | 443 DLOG(ERROR) |
| 446 << "Send(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed) " | 444 << "Send(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed) " |
| 447 << "failed"; | 445 << "failed"; |
| 448 } | 446 } |
| 449 } | 447 } |
| 450 | 448 |
| 451 void GpuVideoDecodeAccelerator::NotifyInitializeDone() { | |
| 452 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams( | |
| 453 init_done_msg_, host_route_id_); | |
| 454 if (!Send(init_done_msg_)) | |
| 455 DLOG(ERROR) << "Send(init_done_msg_) failed"; | |
| 456 init_done_msg_ = NULL; | |
| 457 } | |
| 458 | |
| 459 void GpuVideoDecodeAccelerator::NotifyFlushDone() { | 449 void GpuVideoDecodeAccelerator::NotifyFlushDone() { |
| 460 if (!Send(new AcceleratedVideoDecoderHostMsg_FlushDone(host_route_id_))) | 450 if (!Send(new AcceleratedVideoDecoderHostMsg_FlushDone(host_route_id_))) |
| 461 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_FlushDone) failed"; | 451 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_FlushDone) failed"; |
| 462 } | 452 } |
| 463 | 453 |
| 464 void GpuVideoDecodeAccelerator::NotifyResetDone() { | 454 void GpuVideoDecodeAccelerator::NotifyResetDone() { |
| 465 if (!Send(new AcceleratedVideoDecoderHostMsg_ResetDone(host_route_id_))) | 455 if (!Send(new AcceleratedVideoDecoderHostMsg_ResetDone(host_route_id_))) |
| 466 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ResetDone) failed"; | 456 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ResetDone) failed"; |
| 467 } | 457 } |
| 468 | 458 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 508 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second; | 498 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second; |
| 509 GLenum target = texture_ref->texture()->target(); | 499 GLenum target = texture_ref->texture()->target(); |
| 510 gpu::gles2::TextureManager* texture_manager = | 500 gpu::gles2::TextureManager* texture_manager = |
| 511 stub_->decoder()->GetContextGroup()->texture_manager(); | 501 stub_->decoder()->GetContextGroup()->texture_manager(); |
| 512 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0)); | 502 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0)); |
| 513 texture_manager->SetLevelCleared(texture_ref, target, 0, true); | 503 texture_manager->SetLevelCleared(texture_ref, target, 0, true); |
| 514 uncleared_textures_.erase(it); | 504 uncleared_textures_.erase(it); |
| 515 } | 505 } |
| 516 | 506 |
| 517 } // namespace content | 507 } // namespace content |
| OLD | NEW |