Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(891)

Side by Side Diff: content/common/gpu/media/gpu_video_decode_accelerator.cc

Issue 185403020: Make VEA client of command buffer; move sync. IPC to VDA/VEA::Initialize() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 7da5b6ec Rebase. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 24 matching lines...) Expand all
35 #elif defined(OS_ANDROID) 35 #elif defined(OS_ANDROID)
36 #include "content/common/gpu/media/android_video_decode_accelerator.h" 36 #include "content/common/gpu/media/android_video_decode_accelerator.h"
37 #endif 37 #endif
38 38
39 #include "ui/gfx/size.h" 39 #include "ui/gfx/size.h"
40 40
41 namespace content { 41 namespace content {
42 42
43 static bool MakeDecoderContextCurrent( 43 static bool MakeDecoderContextCurrent(
44 const base::WeakPtr<GpuCommandBufferStub> stub) { 44 const base::WeakPtr<GpuCommandBufferStub> stub) {
45 if (!stub.get()) { 45 if (!stub) {
46 DLOG(ERROR) << "Stub is gone; won't MakeCurrent()."; 46 DLOG(ERROR) << "Stub is gone; won't MakeCurrent().";
47 return false; 47 return false;
48 } 48 }
49 49
50 if (!stub->decoder()->MakeCurrent()) { 50 if (!stub->decoder()->MakeCurrent()) {
51 DLOG(ERROR) << "Failed to MakeCurrent()"; 51 DLOG(ERROR) << "Failed to MakeCurrent()";
52 return false; 52 return false;
53 } 53 }
54 54
55 return true; 55 return true;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 GpuVideoDecodeAccelerator* owner_; 113 GpuVideoDecodeAccelerator* owner_;
114 int32 host_route_id_; 114 int32 host_route_id_;
115 // The channel to which this filter was added. 115 // The channel to which this filter was added.
116 IPC::Channel* channel_; 116 IPC::Channel* channel_;
117 }; 117 };
118 118
119 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( 119 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator(
120 int32 host_route_id, 120 int32 host_route_id,
121 GpuCommandBufferStub* stub, 121 GpuCommandBufferStub* stub,
122 const scoped_refptr<base::MessageLoopProxy>& io_message_loop) 122 const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
123 : init_done_msg_(NULL), 123 : host_route_id_(host_route_id),
124 host_route_id_(host_route_id),
125 stub_(stub), 124 stub_(stub),
126 texture_target_(0), 125 texture_target_(0),
127 filter_removed_(true, false), 126 filter_removed_(true, false),
128 io_message_loop_(io_message_loop), 127 io_message_loop_(io_message_loop),
129 weak_factory_for_io_(this) { 128 weak_factory_for_io_(this) {
130 DCHECK(stub_); 129 DCHECK(stub_);
131 stub_->AddDestructionObserver(this); 130 stub_->AddDestructionObserver(this);
132 stub_->channel()->AddRoute(host_route_id_, this); 131 stub_->channel()->AddRoute(host_route_id_, this);
133 child_message_loop_ = base::MessageLoopProxy::current(); 132 child_message_loop_ = base::MessageLoopProxy::current();
134 make_context_current_ = 133 make_context_current_ =
135 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); 134 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr());
136 } 135 }
137 136
138 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { 137 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() {
139 // This class can only be self-deleted from OnWillDestroyStub(), which means 138 // This class can only be self-deleted from OnWillDestroyStub(), which means
140 // the VDA has already been destroyed in there. 139 // the VDA has already been destroyed in there.
141 CHECK(!video_decode_accelerator_.get()); 140 DCHECK(!video_decode_accelerator_);
142 } 141 }
143 142
144 bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { 143 bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) {
145 if (!video_decode_accelerator_) 144 if (!video_decode_accelerator_)
146 return false; 145 return false;
147 146
148 bool handled = true; 147 bool handled = true;
149 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg) 148 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg)
150 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode) 149 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode)
151 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignPictureBuffers, 150 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignPictureBuffers,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( 209 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady(
211 host_route_id_, 210 host_route_id_,
212 picture.picture_buffer_id(), 211 picture.picture_buffer_id(),
213 picture.bitstream_buffer_id()))) { 212 picture.bitstream_buffer_id()))) {
214 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; 213 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed";
215 } 214 }
216 } 215 }
217 216
218 void GpuVideoDecodeAccelerator::NotifyError( 217 void GpuVideoDecodeAccelerator::NotifyError(
219 media::VideoDecodeAccelerator::Error error) { 218 media::VideoDecodeAccelerator::Error error) {
220 if (init_done_msg_) {
221 // If we get an error while we're initializing, NotifyInitializeDone won't
222 // be called, so we need to send the reply (with an error) here.
223 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(
224 init_done_msg_, -1);
225 if (!Send(init_done_msg_))
226 DLOG(ERROR) << "Send(init_done_msg_) failed";
227 init_done_msg_ = NULL;
228 return;
229 }
230 if (!Send(new AcceleratedVideoDecoderHostMsg_ErrorNotification( 219 if (!Send(new AcceleratedVideoDecoderHostMsg_ErrorNotification(
231 host_route_id_, error))) { 220 host_route_id_, error))) {
232 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ErrorNotification) " 221 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ErrorNotification) "
233 << "failed"; 222 << "failed";
234 } 223 }
235 } 224 }
236 225
237 void GpuVideoDecodeAccelerator::Initialize( 226 void GpuVideoDecodeAccelerator::Initialize(
238 const media::VideoCodecProfile profile, 227 const media::VideoCodecProfile profile,
239 IPC::Message* init_done_msg) { 228 IPC::Message* init_done_msg) {
240 DCHECK(!video_decode_accelerator_.get()); 229 DCHECK(!video_decode_accelerator_.get());
241 DCHECK(!init_done_msg_);
242 DCHECK(init_done_msg);
243 init_done_msg_ = init_done_msg;
244 230
245 #if !defined(OS_WIN) 231 #if !defined(OS_WIN)
246 // Ensure we will be able to get a GL context at all before initializing 232 // Ensure we will be able to get a GL context at all before initializing
247 // non-Windows VDAs. 233 // non-Windows VDAs.
248 if (!make_context_current_.Run()) { 234 if (!make_context_current_.Run()) {
249 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 235 SendCreateDecoderReply(init_done_msg, MSG_ROUTING_NONE);
250 return; 236 return;
251 } 237 }
252 #endif 238 #endif
253 239
254 #if defined(OS_WIN) 240 #if defined(OS_WIN)
255 if (base::win::GetVersion() < base::win::VERSION_WIN7) { 241 if (base::win::GetVersion() < base::win::VERSION_WIN7) {
256 NOTIMPLEMENTED() << "HW video decode acceleration not available."; 242 NOTIMPLEMENTED() << "HW video decode acceleration not available.";
257 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 243 SendCreateDecoderReply(init_done_msg, MSG_ROUTING_NONE);
258 return; 244 return;
259 } 245 }
260 DVLOG(0) << "Initializing DXVA HW decoder for windows."; 246 DVLOG(0) << "Initializing DXVA HW decoder for windows.";
261 video_decode_accelerator_.reset( 247 video_decode_accelerator_.reset(
262 new DXVAVideoDecodeAccelerator(make_context_current_)); 248 new DXVAVideoDecodeAccelerator(make_context_current_));
263 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) 249 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
264 scoped_ptr<V4L2Device> device = 250 scoped_ptr<V4L2Device> device =
265 V4L2Device::Create(stub_->decoder()->GetGLContext()->GetHandle()); 251 V4L2Device::Create(stub_->decoder()->GetGLContext()->GetHandle());
266 if (!device.get()) { 252 if (!device.get()) {
267 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 253 SendCreateDecoderReply(init_done_msg, MSG_ROUTING_NONE);
268 return; 254 return;
269 } 255 }
270 video_decode_accelerator_.reset( 256 video_decode_accelerator_.reset(
271 new V4L2VideoDecodeAccelerator(gfx::GLSurfaceEGL::GetHardwareDisplay(), 257 new V4L2VideoDecodeAccelerator(gfx::GLSurfaceEGL::GetHardwareDisplay(),
272 weak_factory_for_io_.GetWeakPtr(), 258 weak_factory_for_io_.GetWeakPtr(),
273 make_context_current_, 259 make_context_current_,
274 device.Pass(), 260 device.Pass(),
275 io_message_loop_)); 261 io_message_loop_));
276 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) 262 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11)
277 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) { 263 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
278 VLOG(1) << "HW video decode acceleration not available without " 264 VLOG(1) << "HW video decode acceleration not available without "
279 "DesktopGL (GLX)."; 265 "DesktopGL (GLX).";
280 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 266 SendCreateDecoderReply(init_done_msg, MSG_ROUTING_NONE);
281 return; 267 return;
282 } 268 }
283 gfx::GLContextGLX* glx_context = 269 gfx::GLContextGLX* glx_context =
284 static_cast<gfx::GLContextGLX*>(stub_->decoder()->GetGLContext()); 270 static_cast<gfx::GLContextGLX*>(stub_->decoder()->GetGLContext());
285 video_decode_accelerator_.reset(new VaapiVideoDecodeAccelerator( 271 video_decode_accelerator_.reset(new VaapiVideoDecodeAccelerator(
286 glx_context->display(), make_context_current_)); 272 glx_context->display(), make_context_current_));
287 #elif defined(OS_ANDROID) 273 #elif defined(OS_ANDROID)
288 video_decode_accelerator_.reset(new AndroidVideoDecodeAccelerator( 274 video_decode_accelerator_.reset(new AndroidVideoDecodeAccelerator(
289 stub_->decoder()->AsWeakPtr(), 275 stub_->decoder()->AsWeakPtr(),
290 make_context_current_)); 276 make_context_current_));
291 #else 277 #else
292 NOTIMPLEMENTED() << "HW video decode acceleration not available."; 278 NOTIMPLEMENTED() << "HW video decode acceleration not available.";
293 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 279 SendCreateDecoderReply(init_done_msg, MSG_ROUTING_NONE);
294 return; 280 return;
295 #endif 281 #endif
296 282
297 if (video_decode_accelerator_->CanDecodeOnIOThread()) { 283 if (video_decode_accelerator_->CanDecodeOnIOThread()) {
298 filter_ = new MessageFilter(this, host_route_id_); 284 filter_ = new MessageFilter(this, host_route_id_);
299 stub_->channel()->AddFilter(filter_.get()); 285 stub_->channel()->AddFilter(filter_.get());
300 } 286 }
301 287
302 if (!video_decode_accelerator_->Initialize(profile, this)) 288 if (!video_decode_accelerator_->Initialize(profile, this)) {
303 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 289 SendCreateDecoderReply(init_done_msg, MSG_ROUTING_NONE);
290 return;
291 }
292
293 SendCreateDecoderReply(init_done_msg, host_route_id_);
304 } 294 }
305 295
306 // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is 296 // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is
307 // true, otherwise on the main thread. 297 // true, otherwise on the main thread.
308 void GpuVideoDecodeAccelerator::OnDecode( 298 void GpuVideoDecodeAccelerator::OnDecode(
309 base::SharedMemoryHandle handle, int32 id, uint32 size) { 299 base::SharedMemoryHandle handle, int32 id, uint32 size) {
310 DCHECK(video_decode_accelerator_.get()); 300 DCHECK(video_decode_accelerator_.get());
311 if (id < 0) { 301 if (id < 0) {
312 DLOG(ERROR) << "BitstreamBuffer id " << id << " out of range"; 302 DLOG(ERROR) << "BitstreamBuffer id " << id << " out of range";
313 if (child_message_loop_->BelongsToCurrentThread()) { 303 if (child_message_loop_->BelongsToCurrentThread()) {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( 420 void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
431 int32 bitstream_buffer_id) { 421 int32 bitstream_buffer_id) {
432 if (!Send(new AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed( 422 if (!Send(new AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed(
433 host_route_id_, bitstream_buffer_id))) { 423 host_route_id_, bitstream_buffer_id))) {
434 DLOG(ERROR) 424 DLOG(ERROR)
435 << "Send(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed) " 425 << "Send(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed) "
436 << "failed"; 426 << "failed";
437 } 427 }
438 } 428 }
439 429
440 void GpuVideoDecodeAccelerator::NotifyInitializeDone() {
441 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(
442 init_done_msg_, host_route_id_);
443 if (!Send(init_done_msg_))
444 DLOG(ERROR) << "Send(init_done_msg_) failed";
445 init_done_msg_ = NULL;
446 }
447
448 void GpuVideoDecodeAccelerator::NotifyFlushDone() { 430 void GpuVideoDecodeAccelerator::NotifyFlushDone() {
449 if (!Send(new AcceleratedVideoDecoderHostMsg_FlushDone(host_route_id_))) 431 if (!Send(new AcceleratedVideoDecoderHostMsg_FlushDone(host_route_id_)))
450 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_FlushDone) failed"; 432 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_FlushDone) failed";
451 } 433 }
452 434
453 void GpuVideoDecodeAccelerator::NotifyResetDone() { 435 void GpuVideoDecodeAccelerator::NotifyResetDone() {
454 if (!Send(new AcceleratedVideoDecoderHostMsg_ResetDone(host_route_id_))) 436 if (!Send(new AcceleratedVideoDecoderHostMsg_ResetDone(host_route_id_)))
455 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ResetDone) failed"; 437 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ResetDone) failed";
456 } 438 }
457 439
(...skipping 13 matching lines...) Expand all
471 453
472 stub_->channel()->RemoveRoute(host_route_id_); 454 stub_->channel()->RemoveRoute(host_route_id_);
473 stub_->RemoveDestructionObserver(this); 455 stub_->RemoveDestructionObserver(this);
474 456
475 if (video_decode_accelerator_) 457 if (video_decode_accelerator_)
476 video_decode_accelerator_.release()->Destroy(); 458 video_decode_accelerator_.release()->Destroy();
477 459
478 delete this; 460 delete this;
479 } 461 }
480 462
481 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) {
482 if (filter_.get() && io_message_loop_->BelongsToCurrentThread())
483 return filter_->SendOnIOThread(message);
484 DCHECK(child_message_loop_->BelongsToCurrentThread());
485 return stub_->channel()->Send(message);
486 }
487
488 void GpuVideoDecodeAccelerator::SetTextureCleared( 463 void GpuVideoDecodeAccelerator::SetTextureCleared(
489 const media::Picture& picture) { 464 const media::Picture& picture) {
490 DCHECK(child_message_loop_->BelongsToCurrentThread()); 465 DCHECK(child_message_loop_->BelongsToCurrentThread());
491 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); 466 DebugAutoLock auto_lock(debug_uncleared_textures_lock_);
492 std::map<int32, scoped_refptr<gpu::gles2::TextureRef> >::iterator it; 467 std::map<int32, scoped_refptr<gpu::gles2::TextureRef> >::iterator it;
493 it = uncleared_textures_.find(picture.picture_buffer_id()); 468 it = uncleared_textures_.find(picture.picture_buffer_id());
494 if (it == uncleared_textures_.end()) 469 if (it == uncleared_textures_.end())
495 return; // the texture has been cleared 470 return; // the texture has been cleared
496 471
497 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second; 472 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second;
498 GLenum target = texture_ref->texture()->target(); 473 GLenum target = texture_ref->texture()->target();
499 gpu::gles2::TextureManager* texture_manager = 474 gpu::gles2::TextureManager* texture_manager =
500 stub_->decoder()->GetContextGroup()->texture_manager(); 475 stub_->decoder()->GetContextGroup()->texture_manager();
501 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0)); 476 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0));
502 texture_manager->SetLevelCleared(texture_ref, target, 0, true); 477 texture_manager->SetLevelCleared(texture_ref, target, 0, true);
503 uncleared_textures_.erase(it); 478 uncleared_textures_.erase(it);
504 } 479 }
505 480
481 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) {
482 if (filter_.get() && io_message_loop_->BelongsToCurrentThread())
483 return filter_->SendOnIOThread(message);
484 DCHECK(child_message_loop_->BelongsToCurrentThread());
485 return stub_->channel()->Send(message);
486 }
487
488 void GpuVideoDecodeAccelerator::SendCreateDecoderReply(IPC::Message* message,
489 int32 route_id) {
490 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(message, route_id);
491 Send(message);
492 }
493
506 } // namespace content 494 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/gpu_video_decode_accelerator.h ('k') | content/common/gpu/media/gpu_video_encode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698