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

Side by Side Diff: media/gpu/android_video_decode_accelerator.cc

Issue 1963903002: Remove VideoDecodeAccelerator::SetCdm() and pass the cdm in Initialize() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add cdm_id to paramtraits Created 4 years, 7 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "media/gpu/android_video_decode_accelerator.h" 5 #include "media/gpu/android_video_decode_accelerator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 if (!media_drm_bridge_cdm_context_) 329 if (!media_drm_bridge_cdm_context_)
330 return; 330 return;
331 331
332 DCHECK(cdm_registration_id_); 332 DCHECK(cdm_registration_id_);
333 media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_); 333 media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_);
334 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 334 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
335 } 335 }
336 336
337 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, 337 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config,
338 Client* client) { 338 Client* client) {
339 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString();
340 TRACE_EVENT0("media", "AVDA::Initialize");
339 DCHECK(!media_codec_); 341 DCHECK(!media_codec_);
340 DCHECK(thread_checker_.CalledOnValidThread()); 342 DCHECK(thread_checker_.CalledOnValidThread());
341 TRACE_EVENT0("media", "AVDA::Initialize");
342
343 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString();
344 343
345 if (make_context_current_cb_.is_null() || get_gles2_decoder_cb_.is_null()) { 344 if (make_context_current_cb_.is_null() || get_gles2_decoder_cb_.is_null()) {
346 NOTREACHED() << "GL callbacks are required for this VDA"; 345 DLOG(ERROR) << "GL callbacks are required for this VDA";
347 return false; 346 return false;
348 } 347 }
349 348
350 if (config.output_mode != Config::OutputMode::ALLOCATE) { 349 if (config.output_mode != Config::OutputMode::ALLOCATE) {
351 NOTREACHED() << "Only ALLOCATE OutputMode is supported by this VDA"; 350 DLOG(ERROR) << "Only ALLOCATE OutputMode is supported by this VDA";
352 return false; 351 return false;
353 } 352 }
354 353
355 DCHECK(client); 354 DCHECK(client);
356 client_ = client; 355 client_ = client;
357 codec_config_ = new CodecConfig(); 356 codec_config_ = new CodecConfig();
358 codec_config_->codec_ = VideoCodecProfileToVideoCodec(config.profile); 357 codec_config_->codec_ = VideoCodecProfileToVideoCodec(config.profile);
359 codec_config_->initial_expected_coded_size_ = 358 codec_config_->initial_expected_coded_size_ =
360 config.initial_expected_coded_size; 359 config.initial_expected_coded_size;
361 is_encrypted_ = config.is_encrypted; 360 is_encrypted_ = config.is_encrypted;
362 361
363 bool profile_supported = codec_config_->codec_ == media::kCodecVP8 ||
364 codec_config_->codec_ == media::kCodecVP9 ||
365 codec_config_->codec_ == media::kCodecH264;
366
367 // We signalled that we support deferred initialization, so see if the client 362 // We signalled that we support deferred initialization, so see if the client
368 // does also. 363 // does also.
369 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; 364 deferred_initialization_pending_ = config.is_deferred_initialization_allowed;
370 365
371 if (!profile_supported) { 366 if (is_encrypted_ && !deferred_initialization_pending_) {
367 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams";
368 return false;
369 }
370
371 if (codec_config_->codec_ != media::kCodecVP8 &&
372 codec_config_->codec_ != media::kCodecVP9 &&
373 codec_config_->codec_ != media::kCodecH264) {
372 LOG(ERROR) << "Unsupported profile: " << config.profile; 374 LOG(ERROR) << "Unsupported profile: " << config.profile;
373 return false; 375 return false;
374 } 376 }
375 377
376 // For encrypted streams we postpone configuration until MediaCrypto is
377 // available.
378 DCHECK(!is_encrypted_ || deferred_initialization_pending_);
379
380 // Only use MediaCodec for VP8/9 if it's likely backed by hardware 378 // Only use MediaCodec for VP8/9 if it's likely backed by hardware
381 // or if the stream is encrypted. 379 // or if the stream is encrypted.
382 if ((codec_config_->codec_ == media::kCodecVP8 || 380 if ((codec_config_->codec_ == media::kCodecVP8 ||
383 codec_config_->codec_ == media::kCodecVP9) && 381 codec_config_->codec_ == media::kCodecVP9) &&
384 !is_encrypted_ && 382 !is_encrypted_ &&
385 media::VideoCodecBridge::IsKnownUnaccelerated( 383 media::VideoCodecBridge::IsKnownUnaccelerated(
386 codec_config_->codec_, media::MEDIA_CODEC_DECODER)) { 384 codec_config_->codec_, media::MEDIA_CODEC_DECODER)) {
387 DVLOG(1) << "Initialization failed: " 385 DVLOG(1) << "Initialization failed: "
388 << (codec_config_->codec_ == media::kCodecVP8 ? "vp8" : "vp9") 386 << (codec_config_->codec_ == media::kCodecVP8 ? "vp8" : "vp9")
389 << " is not hardware accelerated"; 387 << " is not hardware accelerated";
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 scoped_refptr<gfx::SurfaceTexture> surface_texture = 424 scoped_refptr<gfx::SurfaceTexture> surface_texture =
427 strategy_->GetSurfaceTexture(); 425 strategy_->GetSurfaceTexture();
428 if (surface_texture) { 426 if (surface_texture) {
429 on_frame_available_handler_ = 427 on_frame_available_handler_ =
430 new OnFrameAvailableHandler(this, surface_texture); 428 new OnFrameAvailableHandler(this, surface_texture);
431 } 429 }
432 430
433 // Start the thread for async configuration, even if we don't need it now. 431 // Start the thread for async configuration, even if we don't need it now.
434 // ResetCodecState might rebuild the codec later, for example. 432 // ResetCodecState might rebuild the codec later, for example.
435 if (!g_avda_timer.Pointer()->StartThread(this)) { 433 if (!g_avda_timer.Pointer()->StartThread(this)) {
436 LOG(ERROR) << "Failed to start thread for AVDA timer"; 434 LOG(ERROR) << "Failed to start AVDA thread";
437 return false; 435 return false;
438 } 436 }
439 437
440 // If we are encrypted, then we aren't able to create the codec yet. 438 // If we are encrypted, then we aren't able to create the codec yet.
441 if (is_encrypted_) 439 if (is_encrypted_) {
440 InitializeCdm(config.cdm_id);
442 return true; 441 return true;
442 }
443 443
444 if (deferred_initialization_pending_) { 444 if (deferred_initialization_pending_) {
445 ConfigureMediaCodecAsynchronously(); 445 ConfigureMediaCodecAsynchronously();
446 return true; 446 return true;
447 } 447 }
448 448
449 // If the client doesn't support deferred initialization (WebRTC), then we 449 // If the client doesn't support deferred initialization (WebRTC), then we
450 // should complete it now and return a meaningful result. 450 // should complete it now and return a meaningful result.
451 return ConfigureMediaCodecSynchronously(); 451 return ConfigureMediaCodecSynchronously();
452 } 452 }
453 453
454 void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) {
455 DVLOG(2) << __FUNCTION__ << ": " << cdm_id;
456
457 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
458 DCHECK(client_) << "SetCdm() must be called after Initialize().";
459
460 if (media_drm_bridge_cdm_context_) {
461 NOTREACHED() << "We do not support resetting CDM.";
462 NotifyInitializationComplete(false);
463 return;
464 }
465
466 // Store the CDM to hold a reference to it.
467 cdm_for_reference_holding_only_ = media::MojoCdmService::LegacyGetCdm(cdm_id);
468 DCHECK(cdm_for_reference_holding_only_);
469
470 // On Android platform the CdmContext must be a MediaDrmBridgeCdmContext.
471 media_drm_bridge_cdm_context_ = static_cast<media::MediaDrmBridgeCdmContext*>(
472 cdm_for_reference_holding_only_->GetCdmContext());
473 DCHECK(media_drm_bridge_cdm_context_);
474
475 // Register CDM callbacks. The callbacks registered will be posted back to
476 // this thread via BindToCurrentLoop.
477
478 // Since |this| holds a reference to the |cdm_|, by the time the CDM is
479 // destructed, UnregisterPlayer() must have been called and |this| has been
480 // destructed as well. So the |cdm_unset_cb| will never have a chance to be
481 // called.
482 // TODO(xhwang): Remove |cdm_unset_cb| after it's not used on all platforms.
483 cdm_registration_id_ = media_drm_bridge_cdm_context_->RegisterPlayer(
484 media::BindToCurrentLoop(
485 base::Bind(&AndroidVideoDecodeAccelerator::OnKeyAdded,
486 weak_this_factory_.GetWeakPtr())),
487 base::Bind(&base::DoNothing));
488
489 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB(media::BindToCurrentLoop(
490 base::Bind(&AndroidVideoDecodeAccelerator::OnMediaCryptoReady,
491 weak_this_factory_.GetWeakPtr())));
492
493 // Postpone NotifyInitializationComplete() call till we create the MediaCodec
494 // after OnMediaCryptoReady().
495 #else
496
497 NOTIMPLEMENTED();
498 NotifyInitializationComplete(false);
499
500 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
501 }
502
503 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { 454 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) {
504 DCHECK(thread_checker_.CalledOnValidThread()); 455 DCHECK(thread_checker_.CalledOnValidThread());
505 TRACE_EVENT0("media", "AVDA::DoIOTask"); 456 TRACE_EVENT0("media", "AVDA::DoIOTask");
506 if (state_ == ERROR || state_ == WAITING_FOR_CODEC) 457 if (state_ == ERROR || state_ == WAITING_FOR_CODEC)
507 return; 458 return;
508 459
509 strategy_->MaybeRenderEarly(); 460 strategy_->MaybeRenderEarly();
510 bool did_work = false, did_input = false, did_output = false; 461 bool did_work = false, did_input = false, did_output = false;
511 do { 462 do {
512 did_input = QueueInput(); 463 did_input = QueueInput();
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 const ::tracked_objects::Location& from_here, 1242 const ::tracked_objects::Location& from_here,
1292 media::VideoDecodeAccelerator::Error error) { 1243 media::VideoDecodeAccelerator::Error error) {
1293 base::MessageLoop::current()->PostDelayedTask( 1244 base::MessageLoop::current()->PostDelayedTask(
1294 from_here, 1245 from_here,
1295 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, 1246 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError,
1296 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_), 1247 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_),
1297 (defer_errors_ ? ErrorPostingDelay() : base::TimeDelta())); 1248 (defer_errors_ ? ErrorPostingDelay() : base::TimeDelta()));
1298 state_ = ERROR; 1249 state_ = ERROR;
1299 } 1250 }
1300 1251
1252 void AndroidVideoDecodeAccelerator::InitializeCdm(int cdm_id) {
1253 DVLOG(2) << __FUNCTION__ << ": " << cdm_id;
1254
1255 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
1256 NOTIMPLEMENTED();
1257 NotifyInitializationComplete(false);
1258 #else
1259 // Store the CDM to hold a reference to it.
1260 cdm_for_reference_holding_only_ = media::MojoCdmService::LegacyGetCdm(cdm_id);
1261 DCHECK(cdm_for_reference_holding_only_);
1262
1263 // On Android platform the CdmContext must be a MediaDrmBridgeCdmContext.
1264 media_drm_bridge_cdm_context_ = static_cast<media::MediaDrmBridgeCdmContext*>(
1265 cdm_for_reference_holding_only_->GetCdmContext());
1266 DCHECK(media_drm_bridge_cdm_context_);
1267
1268 // Register CDM callbacks. The callbacks registered will be posted back to
1269 // this thread via BindToCurrentLoop.
1270
1271 // Since |this| holds a reference to the |cdm_|, by the time the CDM is
1272 // destructed, UnregisterPlayer() must have been called and |this| has been
1273 // destructed as well. So the |cdm_unset_cb| will never have a chance to be
1274 // called.
1275 // TODO(xhwang): Remove |cdm_unset_cb| after it's not used on all platforms.
1276 cdm_registration_id_ = media_drm_bridge_cdm_context_->RegisterPlayer(
1277 media::BindToCurrentLoop(
1278 base::Bind(&AndroidVideoDecodeAccelerator::OnKeyAdded,
1279 weak_this_factory_.GetWeakPtr())),
1280 base::Bind(&base::DoNothing));
1281
1282 // Deferred initialization will continue in OnMediaCryptoReady().
1283 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB(media::BindToCurrentLoop(
1284 base::Bind(&AndroidVideoDecodeAccelerator::OnMediaCryptoReady,
1285 weak_this_factory_.GetWeakPtr())));
1286 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
1287 }
1288
1301 void AndroidVideoDecodeAccelerator::OnMediaCryptoReady( 1289 void AndroidVideoDecodeAccelerator::OnMediaCryptoReady(
1302 media::MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto, 1290 media::MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto,
1303 bool needs_protected_surface) { 1291 bool needs_protected_surface) {
1304 DVLOG(1) << __FUNCTION__; 1292 DVLOG(1) << __FUNCTION__;
1305 1293
1306 if (!media_crypto) { 1294 if (!media_crypto) {
1307 LOG(ERROR) << "MediaCrypto is not available, can't play encrypted stream."; 1295 LOG(ERROR) << "MediaCrypto is not available, can't play encrypted stream.";
1308 cdm_for_reference_holding_only_ = nullptr; 1296 cdm_for_reference_holding_only_ = nullptr;
1309 media_drm_bridge_cdm_context_ = nullptr; 1297 media_drm_bridge_cdm_context_ = nullptr;
1310 NotifyInitializationComplete(false); 1298 NotifyInitializationComplete(false);
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { 1450 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) {
1463 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: 1451 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities::
1464 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1452 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1465 } 1453 }
1466 } 1454 }
1467 1455
1468 return capabilities; 1456 return capabilities;
1469 } 1457 }
1470 1458
1471 } // namespace media 1459 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | media/gpu/ipc/client/gpu_video_decode_accelerator_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698