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

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

Issue 1438063002: media: Support SetCdm() on VideoDecodeAccelerator interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments addressed Created 5 years, 1 month 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
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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 make_context_current_ = 144 make_context_current_ =
145 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); 145 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr());
146 } 146 }
147 147
148 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { 148 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() {
149 // This class can only be self-deleted from OnWillDestroyStub(), which means 149 // This class can only be self-deleted from OnWillDestroyStub(), which means
150 // the VDA has already been destroyed in there. 150 // the VDA has already been destroyed in there.
151 DCHECK(!video_decode_accelerator_); 151 DCHECK(!video_decode_accelerator_);
152 } 152 }
153 153
154 // static
155 gpu::VideoDecodeAcceleratorSupportedProfiles
xhwang 2015/11/13 01:16:55 here and below, non-cdm methods are moved to fix t
dcheng 2015/11/13 19:54:53 In the future, maybe just do this in a separate pa
xhwang 2015/11/13 20:06:22 Acknowledged.
156 GpuVideoDecodeAccelerator::GetSupportedProfiles() {
157 media::VideoDecodeAccelerator::SupportedProfiles profiles;
158 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
159 if (cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode))
160 return gpu::VideoDecodeAcceleratorSupportedProfiles();
161
162 // Query supported profiles for each VDA. The order of querying VDAs should
163 // be the same as the order of initializing VDAs. Then the returned profile
164 // can be initialized by corresponding VDA successfully.
165 #if defined(OS_WIN)
166 profiles = DXVAVideoDecodeAccelerator::GetSupportedProfiles();
167 #elif defined(OS_CHROMEOS)
168 media::VideoDecodeAccelerator::SupportedProfiles vda_profiles;
169 #if defined(USE_V4L2_CODEC)
170 vda_profiles = V4L2VideoDecodeAccelerator::GetSupportedProfiles();
171 GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(vda_profiles, &profiles);
172 vda_profiles = V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles();
173 GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(vda_profiles, &profiles);
174 #endif
175 #if defined(ARCH_CPU_X86_FAMILY)
176 vda_profiles = VaapiVideoDecodeAccelerator::GetSupportedProfiles();
177 GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(vda_profiles, &profiles);
178 #endif
179 #elif defined(OS_MACOSX)
180 profiles = VTVideoDecodeAccelerator::GetSupportedProfiles();
181 #elif defined(OS_ANDROID)
182 profiles = AndroidVideoDecodeAccelerator::GetSupportedProfiles();
183 #endif
184 return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeProfiles(profiles);
185 }
186
154 bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { 187 bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) {
155 if (!video_decode_accelerator_) 188 if (!video_decode_accelerator_)
156 return false; 189 return false;
157 190
158 bool handled = true; 191 bool handled = true;
159 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg) 192 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg)
193 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_SetCdm, OnSetCdm)
160 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode) 194 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode)
161 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignPictureBuffers, 195 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignPictureBuffers,
162 OnAssignPictureBuffers) 196 OnAssignPictureBuffers)
163 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_ReusePictureBuffer, 197 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_ReusePictureBuffer,
164 OnReusePictureBuffer) 198 OnReusePictureBuffer)
165 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Flush, OnFlush) 199 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Flush, OnFlush)
166 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Reset, OnReset) 200 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Reset, OnReset)
167 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Destroy, OnDestroy) 201 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Destroy, OnDestroy)
168 IPC_MESSAGE_UNHANDLED(handled = false) 202 IPC_MESSAGE_UNHANDLED(handled = false)
169 IPC_END_MESSAGE_MAP() 203 IPC_END_MESSAGE_MAP()
170 return handled; 204 return handled;
171 } 205 }
172 206
207 void GpuVideoDecodeAccelerator::NotifyCdmAttached(bool success) {
208 if (!Send(new AcceleratedVideoDecoderHostMsg_CdmAttached(host_route_id_,
209 success)))
210 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_CdmAttached) failed";
211 }
212
173 void GpuVideoDecodeAccelerator::ProvidePictureBuffers( 213 void GpuVideoDecodeAccelerator::ProvidePictureBuffers(
174 uint32 requested_num_of_buffers, 214 uint32 requested_num_of_buffers,
175 const gfx::Size& dimensions, 215 const gfx::Size& dimensions,
176 uint32 texture_target) { 216 uint32 texture_target) {
177 if (dimensions.width() > media::limits::kMaxDimension || 217 if (dimensions.width() > media::limits::kMaxDimension ||
178 dimensions.height() > media::limits::kMaxDimension || 218 dimensions.height() > media::limits::kMaxDimension ||
179 dimensions.GetArea() > media::limits::kMaxCanvas) { 219 dimensions.GetArea() > media::limits::kMaxCanvas) {
180 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 220 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
181 return; 221 return;
182 } 222 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 } 258 }
219 259
220 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( 260 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady(
221 host_route_id_, picture.picture_buffer_id(), 261 host_route_id_, picture.picture_buffer_id(),
222 picture.bitstream_buffer_id(), picture.visible_rect(), 262 picture.bitstream_buffer_id(), picture.visible_rect(),
223 picture.allow_overlay()))) { 263 picture.allow_overlay()))) {
224 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; 264 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed";
225 } 265 }
226 } 266 }
227 267
268 void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
269 int32 bitstream_buffer_id) {
270 if (!Send(new AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed(
271 host_route_id_, bitstream_buffer_id))) {
272 DLOG(ERROR)
273 << "Send(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed) "
274 << "failed";
275 }
276 }
277
278 void GpuVideoDecodeAccelerator::NotifyFlushDone() {
279 if (!Send(new AcceleratedVideoDecoderHostMsg_FlushDone(host_route_id_)))
280 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_FlushDone) failed";
281 }
282
283 void GpuVideoDecodeAccelerator::NotifyResetDone() {
284 if (!Send(new AcceleratedVideoDecoderHostMsg_ResetDone(host_route_id_)))
285 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ResetDone) failed";
286 }
287
228 void GpuVideoDecodeAccelerator::NotifyError( 288 void GpuVideoDecodeAccelerator::NotifyError(
229 media::VideoDecodeAccelerator::Error error) { 289 media::VideoDecodeAccelerator::Error error) {
230 if (!Send(new AcceleratedVideoDecoderHostMsg_ErrorNotification( 290 if (!Send(new AcceleratedVideoDecoderHostMsg_ErrorNotification(
231 host_route_id_, error))) { 291 host_route_id_, error))) {
232 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ErrorNotification) " 292 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ErrorNotification) "
233 << "failed"; 293 << "failed";
234 } 294 }
235 } 295 }
236 296
297 void GpuVideoDecodeAccelerator::OnWillDestroyStub() {
298 // The stub is going away, so we have to stop and destroy VDA here, before
299 // returning, because the VDA may need the GL context to run and/or do its
300 // cleanup. We cannot destroy the VDA before the IO thread message filter is
301 // removed however, since we cannot service incoming messages with VDA gone.
302 // We cannot simply check for existence of VDA on IO thread though, because
303 // we don't want to synchronize the IO thread with the ChildThread.
304 // So we have to wait for the RemoveFilter callback here instead and remove
305 // the VDA after it arrives and before returning.
306 if (filter_.get()) {
dcheng 2015/11/13 19:54:53 No .get() (unless you end up moving this code in a
xhwang 2015/11/13 20:06:22 Done.
307 stub_->channel()->RemoveFilter(filter_.get());
308 filter_removed_.Wait();
309 }
310
311 stub_->channel()->RemoveRoute(host_route_id_);
312 stub_->RemoveDestructionObserver(this);
313
314 video_decode_accelerator_.reset();
315 delete this;
316 }
317
318 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) {
319 if (filter_.get() && io_task_runner_->BelongsToCurrentThread())
dcheng 2015/11/13 19:54:53 Ditto
xhwang 2015/11/13 20:06:22 Done.
320 return filter_->SendOnIOThread(message);
321 DCHECK(child_task_runner_->BelongsToCurrentThread());
322 return stub_->channel()->Send(message);
323 }
324
237 void GpuVideoDecodeAccelerator::Initialize( 325 void GpuVideoDecodeAccelerator::Initialize(
238 const media::VideoCodecProfile profile, 326 const media::VideoCodecProfile profile,
239 IPC::Message* init_done_msg) { 327 IPC::Message* init_done_msg) {
240 DCHECK(!video_decode_accelerator_.get()); 328 DCHECK(!video_decode_accelerator_.get());
241 329
242 if (!stub_->channel()->AddRoute(host_route_id_, this)) { 330 if (!stub_->channel()->AddRoute(host_route_id_, this)) {
243 DLOG(ERROR) << "Initialize(): failed to add route"; 331 DLOG(ERROR) << "Initialize(): failed to add route";
244 SendCreateDecoderReply(init_done_msg, false); 332 SendCreateDecoderReply(init_done_msg, false);
245 } 333 }
246 334
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) 478 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID)
391 new AndroidDeferredRenderingBackingStrategy() 479 new AndroidDeferredRenderingBackingStrategy()
392 #else 480 #else
393 new AndroidCopyingBackingStrategy() 481 new AndroidCopyingBackingStrategy()
394 #endif 482 #endif
395 ))); 483 )));
396 #endif 484 #endif
397 return decoder.Pass(); 485 return decoder.Pass();
398 } 486 }
399 487
400 // static 488 void GpuVideoDecodeAccelerator::OnSetCdm(int cdm_id) {
401 gpu::VideoDecodeAcceleratorSupportedProfiles 489 DCHECK(video_decode_accelerator_.get());
dcheng 2015/11/13 19:54:53 No .get()
xhwang 2015/11/13 20:06:22 Done.
402 GpuVideoDecodeAccelerator::GetSupportedProfiles() { 490 video_decode_accelerator_->SetCdm(cdm_id);
403 media::VideoDecodeAccelerator::SupportedProfiles profiles;
404 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
405 if (cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode))
406 return gpu::VideoDecodeAcceleratorSupportedProfiles();
407
408 // Query supported profiles for each VDA. The order of querying VDAs should
409 // be the same as the order of initializing VDAs. Then the returned profile
410 // can be initialized by corresponding VDA successfully.
411 #if defined(OS_WIN)
412 profiles = DXVAVideoDecodeAccelerator::GetSupportedProfiles();
413 #elif defined(OS_CHROMEOS)
414 media::VideoDecodeAccelerator::SupportedProfiles vda_profiles;
415 #if defined(USE_V4L2_CODEC)
416 vda_profiles = V4L2VideoDecodeAccelerator::GetSupportedProfiles();
417 GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(vda_profiles, &profiles);
418 vda_profiles = V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles();
419 GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(vda_profiles, &profiles);
420 #endif
421 #if defined(ARCH_CPU_X86_FAMILY)
422 vda_profiles = VaapiVideoDecodeAccelerator::GetSupportedProfiles();
423 GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(vda_profiles, &profiles);
424 #endif
425 #elif defined(OS_MACOSX)
426 profiles = VTVideoDecodeAccelerator::GetSupportedProfiles();
427 #elif defined(OS_ANDROID)
428 profiles = AndroidVideoDecodeAccelerator::GetSupportedProfiles();
429 #endif
430 return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeProfiles(profiles);
431 } 491 }
432 492
433 // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is 493 // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is
434 // true, otherwise on the main thread. 494 // true, otherwise on the main thread.
435 void GpuVideoDecodeAccelerator::OnDecode( 495 void GpuVideoDecodeAccelerator::OnDecode(
436 const AcceleratedVideoDecoderMsg_Decode_Params& params) { 496 const AcceleratedVideoDecoderMsg_Decode_Params& params) {
437 DCHECK(video_decode_accelerator_.get()); 497 DCHECK(video_decode_accelerator_.get());
438 if (params.bitstream_buffer_id < 0) { 498 if (params.bitstream_buffer_id < 0) {
439 DLOG(ERROR) << "BitstreamBuffer id " << params.bitstream_buffer_id 499 DLOG(ERROR) << "BitstreamBuffer id " << params.bitstream_buffer_id
440 << " out of range"; 500 << " out of range";
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 DCHECK(video_decode_accelerator_.get()); 613 DCHECK(video_decode_accelerator_.get());
554 OnWillDestroyStub(); 614 OnWillDestroyStub();
555 } 615 }
556 616
557 void GpuVideoDecodeAccelerator::OnFilterRemoved() { 617 void GpuVideoDecodeAccelerator::OnFilterRemoved() {
558 // We're destroying; cancel all callbacks. 618 // We're destroying; cancel all callbacks.
559 weak_factory_for_io_.InvalidateWeakPtrs(); 619 weak_factory_for_io_.InvalidateWeakPtrs();
560 filter_removed_.Signal(); 620 filter_removed_.Signal();
561 } 621 }
562 622
563 void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
564 int32 bitstream_buffer_id) {
565 if (!Send(new AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed(
566 host_route_id_, bitstream_buffer_id))) {
567 DLOG(ERROR)
568 << "Send(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed) "
569 << "failed";
570 }
571 }
572
573 void GpuVideoDecodeAccelerator::NotifyFlushDone() {
574 if (!Send(new AcceleratedVideoDecoderHostMsg_FlushDone(host_route_id_)))
575 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_FlushDone) failed";
576 }
577
578 void GpuVideoDecodeAccelerator::NotifyResetDone() {
579 if (!Send(new AcceleratedVideoDecoderHostMsg_ResetDone(host_route_id_)))
580 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ResetDone) failed";
581 }
582
583 void GpuVideoDecodeAccelerator::OnWillDestroyStub() {
584 // The stub is going away, so we have to stop and destroy VDA here, before
585 // returning, because the VDA may need the GL context to run and/or do its
586 // cleanup. We cannot destroy the VDA before the IO thread message filter is
587 // removed however, since we cannot service incoming messages with VDA gone.
588 // We cannot simply check for existence of VDA on IO thread though, because
589 // we don't want to synchronize the IO thread with the ChildThread.
590 // So we have to wait for the RemoveFilter callback here instead and remove
591 // the VDA after it arrives and before returning.
592 if (filter_.get()) {
593 stub_->channel()->RemoveFilter(filter_.get());
594 filter_removed_.Wait();
595 }
596
597 stub_->channel()->RemoveRoute(host_route_id_);
598 stub_->RemoveDestructionObserver(this);
599
600 video_decode_accelerator_.reset();
601 delete this;
602 }
603
604 void GpuVideoDecodeAccelerator::SetTextureCleared( 623 void GpuVideoDecodeAccelerator::SetTextureCleared(
605 const media::Picture& picture) { 624 const media::Picture& picture) {
606 DCHECK(child_task_runner_->BelongsToCurrentThread()); 625 DCHECK(child_task_runner_->BelongsToCurrentThread());
607 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); 626 DebugAutoLock auto_lock(debug_uncleared_textures_lock_);
608 std::map<int32, scoped_refptr<gpu::gles2::TextureRef> >::iterator it; 627 std::map<int32, scoped_refptr<gpu::gles2::TextureRef> >::iterator it;
609 it = uncleared_textures_.find(picture.picture_buffer_id()); 628 it = uncleared_textures_.find(picture.picture_buffer_id());
610 if (it == uncleared_textures_.end()) 629 if (it == uncleared_textures_.end())
611 return; // the texture has been cleared 630 return; // the texture has been cleared
612 631
613 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second; 632 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second;
614 GLenum target = texture_ref->texture()->target(); 633 GLenum target = texture_ref->texture()->target();
615 gpu::gles2::TextureManager* texture_manager = 634 gpu::gles2::TextureManager* texture_manager =
616 stub_->decoder()->GetContextGroup()->texture_manager(); 635 stub_->decoder()->GetContextGroup()->texture_manager();
617 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0)); 636 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0));
618 texture_manager->SetLevelCleared(texture_ref.get(), target, 0, true); 637 texture_manager->SetLevelCleared(texture_ref.get(), target, 0, true);
619 uncleared_textures_.erase(it); 638 uncleared_textures_.erase(it);
620 } 639 }
621 640
622 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) {
623 if (filter_.get() && io_task_runner_->BelongsToCurrentThread())
624 return filter_->SendOnIOThread(message);
625 DCHECK(child_task_runner_->BelongsToCurrentThread());
626 return stub_->channel()->Send(message);
627 }
628
629 void GpuVideoDecodeAccelerator::SendCreateDecoderReply(IPC::Message* message, 641 void GpuVideoDecodeAccelerator::SendCreateDecoderReply(IPC::Message* message,
630 bool succeeded) { 642 bool succeeded) {
631 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(message, succeeded); 643 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(message, succeeded);
632 Send(message); 644 Send(message);
633 } 645 }
634 646
635 } // namespace content 647 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698