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

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: 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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 DCHECK(!media_codec_); 339 DCHECK(!media_codec_);
340 DCHECK(thread_checker_.CalledOnValidThread()); 340 DCHECK(thread_checker_.CalledOnValidThread());
341 TRACE_EVENT0("media", "AVDA::Initialize"); 341 TRACE_EVENT0("media", "AVDA::Initialize");
342
343 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString(); 342 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 NOTREACHED() << "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 NOTREACHED() << "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
366 bool profile_supported = codec_config_->codec_ == media::kCodecVP8 ||
367 codec_config_->codec_ == media::kCodecVP9 ||
368 codec_config_->codec_ == media::kCodecH264;
371 if (!profile_supported) { 369 if (!profile_supported) {
372 LOG(ERROR) << "Unsupported profile: " << config.profile; 370 LOG(ERROR) << "Unsupported profile: " << config.profile;
373 return false; 371 return false;
374 } 372 }
375 373
376 // For encrypted streams we postpone configuration until MediaCrypto is
377 // available.
378 DCHECK(!is_encrypted_ || deferred_initialization_pending_);
watk 2016/05/09 23:39:59 DCHECK is below now
379
380 // Only use MediaCodec for VP8/9 if it's likely backed by hardware 374 // Only use MediaCodec for VP8/9 if it's likely backed by hardware
381 // or if the stream is encrypted. 375 // or if the stream is encrypted.
382 if ((codec_config_->codec_ == media::kCodecVP8 || 376 if ((codec_config_->codec_ == media::kCodecVP8 ||
383 codec_config_->codec_ == media::kCodecVP9) && 377 codec_config_->codec_ == media::kCodecVP9) &&
384 !is_encrypted_ && 378 !is_encrypted_ &&
385 media::VideoCodecBridge::IsKnownUnaccelerated( 379 media::VideoCodecBridge::IsKnownUnaccelerated(
386 codec_config_->codec_, media::MEDIA_CODEC_DECODER)) { 380 codec_config_->codec_, media::MEDIA_CODEC_DECODER)) {
387 DVLOG(1) << "Initialization failed: " 381 DVLOG(1) << "Initialization failed: "
388 << (codec_config_->codec_ == media::kCodecVP8 ? "vp8" : "vp9") 382 << (codec_config_->codec_ == media::kCodecVP8 ? "vp8" : "vp9")
389 << " is not hardware accelerated"; 383 << " is not hardware accelerated";
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 scoped_refptr<gfx::SurfaceTexture> surface_texture = 420 scoped_refptr<gfx::SurfaceTexture> surface_texture =
427 strategy_->GetSurfaceTexture(); 421 strategy_->GetSurfaceTexture();
428 if (surface_texture) { 422 if (surface_texture) {
429 on_frame_available_handler_ = 423 on_frame_available_handler_ =
430 new OnFrameAvailableHandler(this, surface_texture); 424 new OnFrameAvailableHandler(this, surface_texture);
431 } 425 }
432 426
433 // Start the thread for async configuration, even if we don't need it now. 427 // Start the thread for async configuration, even if we don't need it now.
434 // ResetCodecState might rebuild the codec later, for example. 428 // ResetCodecState might rebuild the codec later, for example.
435 if (!g_avda_timer.Pointer()->StartThread(this)) { 429 if (!g_avda_timer.Pointer()->StartThread(this)) {
436 LOG(ERROR) << "Failed to start thread for AVDA timer"; 430 LOG(ERROR) << "Failed to start AVDA thread";
watk 2016/05/09 23:39:59 The timer doesn't run on that thread.
437 return false; 431 return false;
438 } 432 }
439 433
440 // If we are encrypted, then we aren't able to create the codec yet. 434 // If we are encrypted, then we aren't able to create the codec yet.
441 if (is_encrypted_) 435 if (is_encrypted_) {
436 DCHECK(deferred_initialization_pending_);
sandersd (OOO until July 31) 2016/05/10 00:09:54 We should handle this case gracefully (return fals
437 InitializeCdm(config.cdm_id);
442 return true; 438 return true;
439 }
443 440
444 if (deferred_initialization_pending_) { 441 if (deferred_initialization_pending_) {
445 ConfigureMediaCodecAsynchronously(); 442 ConfigureMediaCodecAsynchronously();
446 return true; 443 return true;
447 } 444 }
448 445
449 // If the client doesn't support deferred initialization (WebRTC), then we 446 // If the client doesn't support deferred initialization (WebRTC), then we
450 // should complete it now and return a meaningful result. 447 // should complete it now and return a meaningful result.
451 return ConfigureMediaCodecSynchronously(); 448 return ConfigureMediaCodecSynchronously();
452 } 449 }
453 450
454 void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) {
watk 2016/05/09 23:39:59 I moved this block because it's now in the private
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) { 451 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) {
504 DCHECK(thread_checker_.CalledOnValidThread()); 452 DCHECK(thread_checker_.CalledOnValidThread());
505 TRACE_EVENT0("media", "AVDA::DoIOTask"); 453 TRACE_EVENT0("media", "AVDA::DoIOTask");
506 if (state_ == ERROR || state_ == WAITING_FOR_CODEC) 454 if (state_ == ERROR || state_ == WAITING_FOR_CODEC)
507 return; 455 return;
508 456
509 strategy_->MaybeRenderEarly(); 457 strategy_->MaybeRenderEarly();
510 bool did_work = false, did_input = false, did_output = false; 458 bool did_work = false, did_input = false, did_output = false;
511 do { 459 do {
512 did_input = QueueInput(); 460 did_input = QueueInput();
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 const ::tracked_objects::Location& from_here, 1239 const ::tracked_objects::Location& from_here,
1292 media::VideoDecodeAccelerator::Error error) { 1240 media::VideoDecodeAccelerator::Error error) {
1293 base::MessageLoop::current()->PostDelayedTask( 1241 base::MessageLoop::current()->PostDelayedTask(
1294 from_here, 1242 from_here,
1295 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, 1243 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError,
1296 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_), 1244 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_),
1297 (defer_errors_ ? ErrorPostingDelay() : base::TimeDelta())); 1245 (defer_errors_ ? ErrorPostingDelay() : base::TimeDelta()));
1298 state_ = ERROR; 1246 state_ = ERROR;
1299 } 1247 }
1300 1248
1249 void AndroidVideoDecodeAccelerator::InitializeCdm(int cdm_id) {
1250 DVLOG(2) << __FUNCTION__ << ": " << cdm_id;
1251
1252 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
1253 NOTIMPLEMENTED();
1254 NotifyInitializationComplete(false);
1255 #else
1256 // Store the CDM to hold a reference to it.
1257 cdm_for_reference_holding_only_ = media::MojoCdmService::LegacyGetCdm(cdm_id);
1258 DCHECK(cdm_for_reference_holding_only_);
1259
1260 // On Android platform the CdmContext must be a MediaDrmBridgeCdmContext.
1261 media_drm_bridge_cdm_context_ = static_cast<media::MediaDrmBridgeCdmContext*>(
1262 cdm_for_reference_holding_only_->GetCdmContext());
1263 DCHECK(media_drm_bridge_cdm_context_);
1264
1265 // Register CDM callbacks. The callbacks registered will be posted back to
1266 // this thread via BindToCurrentLoop.
1267
1268 // Since |this| holds a reference to the |cdm_|, by the time the CDM is
1269 // destructed, UnregisterPlayer() must have been called and |this| has been
1270 // destructed as well. So the |cdm_unset_cb| will never have a chance to be
1271 // called.
1272 // TODO(xhwang): Remove |cdm_unset_cb| after it's not used on all platforms.
1273 cdm_registration_id_ = media_drm_bridge_cdm_context_->RegisterPlayer(
1274 media::BindToCurrentLoop(
1275 base::Bind(&AndroidVideoDecodeAccelerator::OnKeyAdded,
1276 weak_this_factory_.GetWeakPtr())),
1277 base::Bind(&base::DoNothing));
1278
1279 // Deferred initialization will continue in OnMediaCryptoReady().
1280 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB(media::BindToCurrentLoop(
1281 base::Bind(&AndroidVideoDecodeAccelerator::OnMediaCryptoReady,
1282 weak_this_factory_.GetWeakPtr())));
1283 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
1284 }
1285
1301 void AndroidVideoDecodeAccelerator::OnMediaCryptoReady( 1286 void AndroidVideoDecodeAccelerator::OnMediaCryptoReady(
1302 media::MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto, 1287 media::MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto,
1303 bool needs_protected_surface) { 1288 bool needs_protected_surface) {
1304 DVLOG(1) << __FUNCTION__; 1289 DVLOG(1) << __FUNCTION__;
1305 1290
1306 if (!media_crypto) { 1291 if (!media_crypto) {
1307 LOG(ERROR) << "MediaCrypto is not available, can't play encrypted stream."; 1292 LOG(ERROR) << "MediaCrypto is not available, can't play encrypted stream.";
1308 cdm_for_reference_holding_only_ = nullptr; 1293 cdm_for_reference_holding_only_ = nullptr;
1309 media_drm_bridge_cdm_context_ = nullptr; 1294 media_drm_bridge_cdm_context_ = nullptr;
1310 NotifyInitializationComplete(false); 1295 NotifyInitializationComplete(false);
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { 1447 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) {
1463 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: 1448 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities::
1464 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1449 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1465 } 1450 }
1466 } 1451 }
1467 1452
1468 return capabilities; 1453 return capabilities;
1469 } 1454 }
1470 1455
1471 } // namespace media 1456 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698