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 |