| OLD | NEW |
| 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 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 io_timer_.Stop(); | 242 io_timer_.Stop(); |
| 243 } | 243 } |
| 244 | 244 |
| 245 // Eventually, we should run the timer on this thread. For now, we just keep | 245 // Eventually, we should run the timer on this thread. For now, we just keep |
| 246 // it as a convenience for construction. | 246 // it as a convenience for construction. |
| 247 scoped_refptr<base::SingleThreadTaskRunner> ConstructionTaskRunner() { | 247 scoped_refptr<base::SingleThreadTaskRunner> ConstructionTaskRunner() { |
| 248 DCHECK(thread_checker_.CalledOnValidThread()); | 248 DCHECK(thread_checker_.CalledOnValidThread()); |
| 249 return construction_thread_.task_runner(); | 249 return construction_thread_.task_runner(); |
| 250 } | 250 } |
| 251 | 251 |
| 252 // |avda| would like to use |surface_id|. If it is not busy, then mark it |
| 253 // as busy and return true. If it is busy, then replace any existing waiter, |
| 254 // make |avda| the current waiter, and return false. Any existing waiter |
| 255 // is assumed to be on the way out, so we fail its allocation request. |
| 256 bool AllocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) { |
| 257 // Nobody has to wait for no surface. |
| 258 if (surface_id == AndroidVideoDecodeAccelerator::Config::kNoSurfaceID) |
| 259 return true; |
| 260 |
| 261 auto iter = surface_waiter_map_.find(surface_id); |
| 262 if (iter == surface_waiter_map_.end()) { |
| 263 // SurfaceView isn't allocated. Succeed. |
| 264 surface_waiter_map_[surface_id].owner = avda; |
| 265 return true; |
| 266 } |
| 267 |
| 268 // SurfaceView is already allocated. |
| 269 if (iter->second.waiter) { |
| 270 // Some other AVDA is waiting. |avda| will replace it, so notify it |
| 271 // that it will fail. |
| 272 iter->second.waiter->OnSurfaceAvailable(false); |
| 273 iter->second.waiter = nullptr; |
| 274 } |
| 275 |
| 276 // |avda| is now waiting. |
| 277 iter->second.waiter = avda; |
| 278 return false; |
| 279 } |
| 280 |
| 281 // Clear any waiting request for |surface_id| by |avda|. It is okay if |
| 282 // |waiter| is not waiting and/or isn't the owner of |surface_id|. |
| 283 void DeallocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) { |
| 284 SurfaceWaiterMap::iterator iter = surface_waiter_map_.find(surface_id); |
| 285 if (iter == surface_waiter_map_.end()) |
| 286 return; |
| 287 |
| 288 // If |avda| was waiting, then remove it without OnSurfaceAvailable. |
| 289 if (iter->second.waiter == avda) |
| 290 iter->second.waiter = nullptr; |
| 291 |
| 292 // If |avda| is the owner, then let the waiter have it. |
| 293 if (iter->second.owner != avda) |
| 294 return; |
| 295 |
| 296 AndroidVideoDecodeAccelerator* waiter = iter->second.waiter; |
| 297 if (!waiter) { |
| 298 // No waiter -- remove the record and return explicitly since |iter| is |
| 299 // no longer valid. |
| 300 surface_waiter_map_.erase(iter); |
| 301 return; |
| 302 } |
| 303 |
| 304 // Promote |waiter| to be the owner. |
| 305 iter->second.owner = waiter; |
| 306 iter->second.waiter = nullptr; |
| 307 waiter->OnSurfaceAvailable(true); |
| 308 } |
| 309 |
| 252 private: | 310 private: |
| 253 friend struct base::DefaultLazyInstanceTraits<AVDATimerManager>; | 311 friend struct base::DefaultLazyInstanceTraits<AVDATimerManager>; |
| 254 | 312 |
| 255 AVDATimerManager() : construction_thread_("AVDAThread") {} | 313 AVDATimerManager() : construction_thread_("AVDAThread") {} |
| 256 ~AVDATimerManager() { NOTREACHED(); } | 314 ~AVDATimerManager() { NOTREACHED(); } |
| 257 | 315 |
| 258 void RunTimer() { | 316 void RunTimer() { |
| 259 { | 317 { |
| 260 // Call out to all AVDA instances, some of which may attempt to remove | 318 // Call out to all AVDA instances, some of which may attempt to remove |
| 261 // themselves from the list during this operation; those removals will be | 319 // themselves from the list during this operation; those removals will be |
| (...skipping 11 matching lines...) Expand all Loading... |
| 273 // TODO(dalecurtis): We may want to consider chunking this if task execution | 331 // TODO(dalecurtis): We may want to consider chunking this if task execution |
| 274 // takes too long for the combined timer. | 332 // takes too long for the combined timer. |
| 275 } | 333 } |
| 276 | 334 |
| 277 // All AVDA instances that would like us to poll DoIOTask. | 335 // All AVDA instances that would like us to poll DoIOTask. |
| 278 std::set<AndroidVideoDecodeAccelerator*> timer_avda_instances_; | 336 std::set<AndroidVideoDecodeAccelerator*> timer_avda_instances_; |
| 279 | 337 |
| 280 // All AVDA instances that might like to use the construction thread. | 338 // All AVDA instances that might like to use the construction thread. |
| 281 std::set<AndroidVideoDecodeAccelerator*> thread_avda_instances_; | 339 std::set<AndroidVideoDecodeAccelerator*> thread_avda_instances_; |
| 282 | 340 |
| 341 struct OwnerRecord { |
| 342 AndroidVideoDecodeAccelerator* owner = nullptr; |
| 343 AndroidVideoDecodeAccelerator* waiter = nullptr; |
| 344 }; |
| 345 // [surface id] = OwnerRecord for that surface. |
| 346 using SurfaceWaiterMap = std::map<int, OwnerRecord>; |
| 347 SurfaceWaiterMap surface_waiter_map_; |
| 348 |
| 283 // Since we can't delete while iterating when using a set, defer erasure until | 349 // Since we can't delete while iterating when using a set, defer erasure until |
| 284 // after iteration complete. | 350 // after iteration complete. |
| 285 bool timer_running_ = false; | 351 bool timer_running_ = false; |
| 286 std::set<AndroidVideoDecodeAccelerator*> pending_erase_; | 352 std::set<AndroidVideoDecodeAccelerator*> pending_erase_; |
| 287 | 353 |
| 288 // Repeating timer responsible for draining pending IO to the codecs. | 354 // Repeating timer responsible for draining pending IO to the codecs. |
| 289 base::RepeatingTimer io_timer_; | 355 base::RepeatingTimer io_timer_; |
| 290 | 356 |
| 291 base::Thread construction_thread_; | 357 base::Thread construction_thread_; |
| 292 | 358 |
| 293 base::ThreadChecker thread_checker_; | 359 base::ThreadChecker thread_checker_; |
| 294 | 360 |
| 295 DISALLOW_COPY_AND_ASSIGN(AVDATimerManager); | 361 DISALLOW_COPY_AND_ASSIGN(AVDATimerManager); |
| 296 }; | 362 }; |
| 297 | 363 |
| 298 static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer = | 364 static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer = |
| 299 LAZY_INSTANCE_INITIALIZER; | 365 LAZY_INSTANCE_INITIALIZER; |
| 300 | 366 |
| 301 AndroidVideoDecodeAccelerator::CodecConfig::CodecConfig() {} | 367 AndroidVideoDecodeAccelerator::CodecConfig::CodecConfig() {} |
| 302 | 368 |
| 303 AndroidVideoDecodeAccelerator::CodecConfig::~CodecConfig() {} | 369 AndroidVideoDecodeAccelerator::CodecConfig::~CodecConfig() {} |
| 304 | 370 |
| 305 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( | 371 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( |
| 306 const MakeGLContextCurrentCallback& make_context_current_cb, | 372 const MakeGLContextCurrentCallback& make_context_current_cb, |
| 307 const GetGLES2DecoderCallback& get_gles2_decoder_cb) | 373 const GetGLES2DecoderCallback& get_gles2_decoder_cb) |
| 308 : client_(NULL), | 374 : client_(NULL), |
| 309 make_context_current_cb_(make_context_current_cb), | 375 make_context_current_cb_(make_context_current_cb), |
| 310 get_gles2_decoder_cb_(get_gles2_decoder_cb), | 376 get_gles2_decoder_cb_(get_gles2_decoder_cb), |
| 311 is_encrypted_(false), | |
| 312 state_(NO_ERROR), | 377 state_(NO_ERROR), |
| 313 picturebuffers_requested_(false), | 378 picturebuffers_requested_(false), |
| 314 drain_type_(DRAIN_TYPE_NONE), | 379 drain_type_(DRAIN_TYPE_NONE), |
| 315 media_drm_bridge_cdm_context_(nullptr), | 380 media_drm_bridge_cdm_context_(nullptr), |
| 316 cdm_registration_id_(0), | 381 cdm_registration_id_(0), |
| 317 pending_input_buf_index_(-1), | 382 pending_input_buf_index_(-1), |
| 318 error_sequence_token_(0), | 383 error_sequence_token_(0), |
| 319 defer_errors_(false), | 384 defer_errors_(false), |
| 320 deferred_initialization_pending_(false), | 385 deferred_initialization_pending_(false), |
| 321 surface_id_(media::VideoDecodeAccelerator::Config::kNoSurfaceID), | |
| 322 weak_this_factory_(this) {} | 386 weak_this_factory_(this) {} |
| 323 | 387 |
| 324 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 388 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 325 DCHECK(thread_checker_.CalledOnValidThread()); | 389 DCHECK(thread_checker_.CalledOnValidThread()); |
| 326 g_avda_timer.Pointer()->StopTimer(this); | 390 g_avda_timer.Pointer()->StopTimer(this); |
| 327 g_avda_timer.Pointer()->StopThread(this); | 391 g_avda_timer.Pointer()->StopThread(this); |
| 328 | 392 |
| 329 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 393 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 330 if (!media_drm_bridge_cdm_context_) | 394 if (!media_drm_bridge_cdm_context_) |
| 331 return; | 395 return; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 347 return false; | 411 return false; |
| 348 } | 412 } |
| 349 | 413 |
| 350 if (config.output_mode != Config::OutputMode::ALLOCATE) { | 414 if (config.output_mode != Config::OutputMode::ALLOCATE) { |
| 351 DLOG(ERROR) << "Only ALLOCATE OutputMode is supported by this VDA"; | 415 DLOG(ERROR) << "Only ALLOCATE OutputMode is supported by this VDA"; |
| 352 return false; | 416 return false; |
| 353 } | 417 } |
| 354 | 418 |
| 355 DCHECK(client); | 419 DCHECK(client); |
| 356 client_ = client; | 420 client_ = client; |
| 421 config_ = config; |
| 357 codec_config_ = new CodecConfig(); | 422 codec_config_ = new CodecConfig(); |
| 358 codec_config_->codec_ = VideoCodecProfileToVideoCodec(config.profile); | 423 codec_config_->codec_ = VideoCodecProfileToVideoCodec(config.profile); |
| 359 codec_config_->initial_expected_coded_size_ = | 424 codec_config_->initial_expected_coded_size_ = |
| 360 config.initial_expected_coded_size; | 425 config.initial_expected_coded_size; |
| 361 is_encrypted_ = config.is_encrypted; | |
| 362 | 426 |
| 363 // We signalled that we support deferred initialization, so see if the client | 427 // We signalled that we support deferred initialization, so see if the client |
| 364 // does also. | 428 // does also. |
| 365 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; | 429 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; |
| 366 | 430 |
| 367 if (is_encrypted_ && !deferred_initialization_pending_) { | 431 if (config_.is_encrypted && !deferred_initialization_pending_) { |
| 368 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; | 432 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; |
| 369 return false; | 433 return false; |
| 370 } | 434 } |
| 371 | 435 |
| 372 if (codec_config_->codec_ != media::kCodecVP8 && | 436 if (codec_config_->codec_ != media::kCodecVP8 && |
| 373 codec_config_->codec_ != media::kCodecVP9 && | 437 codec_config_->codec_ != media::kCodecVP9 && |
| 374 codec_config_->codec_ != media::kCodecH264) { | 438 codec_config_->codec_ != media::kCodecH264) { |
| 375 LOG(ERROR) << "Unsupported profile: " << config.profile; | 439 LOG(ERROR) << "Unsupported profile: " << config.profile; |
| 376 return false; | 440 return false; |
| 377 } | 441 } |
| 378 | 442 |
| 379 // Only use MediaCodec for VP8/9 if it's likely backed by hardware | 443 // Only use MediaCodec for VP8/9 if it's likely backed by hardware |
| 380 // or if the stream is encrypted. | 444 // or if the stream is encrypted. |
| 381 if ((codec_config_->codec_ == media::kCodecVP8 || | 445 if ((codec_config_->codec_ == media::kCodecVP8 || |
| 382 codec_config_->codec_ == media::kCodecVP9) && | 446 codec_config_->codec_ == media::kCodecVP9) && |
| 383 !is_encrypted_ && | 447 !config_.is_encrypted && |
| 384 media::VideoCodecBridge::IsKnownUnaccelerated( | 448 media::VideoCodecBridge::IsKnownUnaccelerated( |
| 385 codec_config_->codec_, media::MEDIA_CODEC_DECODER)) { | 449 codec_config_->codec_, media::MEDIA_CODEC_DECODER)) { |
| 386 DVLOG(1) << "Initialization failed: " | 450 DVLOG(1) << "Initialization failed: " |
| 387 << (codec_config_->codec_ == media::kCodecVP8 ? "vp8" : "vp9") | 451 << (codec_config_->codec_ == media::kCodecVP8 ? "vp8" : "vp9") |
| 388 << " is not hardware accelerated"; | 452 << " is not hardware accelerated"; |
| 389 return false; | 453 return false; |
| 390 } | 454 } |
| 391 | 455 |
| 392 auto gles_decoder = get_gles2_decoder_cb_.Run(); | 456 auto gles_decoder = get_gles2_decoder_cb_.Run(); |
| 393 if (!gles_decoder) { | 457 if (!gles_decoder) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 407 } else { | 471 } else { |
| 408 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; | 472 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; |
| 409 strategy_.reset(new AndroidCopyingBackingStrategy(this)); | 473 strategy_.reset(new AndroidCopyingBackingStrategy(this)); |
| 410 } | 474 } |
| 411 | 475 |
| 412 if (!make_context_current_cb_.Run()) { | 476 if (!make_context_current_cb_.Run()) { |
| 413 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 477 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 414 return false; | 478 return false; |
| 415 } | 479 } |
| 416 | 480 |
| 417 surface_id_ = config.surface_id; | 481 if (g_avda_timer.Pointer()->AllocateSurface(config_.surface_id, this)) { |
| 418 codec_config_->surface_ = strategy_->Initialize(surface_id_); | 482 // We have succesfully owned the surface, so finish initialization now. |
| 483 return InitializeStrategy(); |
| 484 } |
| 485 |
| 486 // We have to wait for some other AVDA instance to free up the surface. |
| 487 // OnSurfaceAvailable will be called when it's available. |
| 488 return true; |
| 489 } |
| 490 |
| 491 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { |
| 492 DCHECK(deferred_initialization_pending_); |
| 493 |
| 494 if (!success || !InitializeStrategy()) { |
| 495 NotifyInitializationComplete(false); |
| 496 deferred_initialization_pending_ = false; |
| 497 } |
| 498 } |
| 499 |
| 500 bool AndroidVideoDecodeAccelerator::InitializeStrategy() { |
| 501 codec_config_->surface_ = strategy_->Initialize(config_.surface_id); |
| 419 if (codec_config_->surface_.IsEmpty()) { | 502 if (codec_config_->surface_.IsEmpty()) { |
| 420 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " | 503 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " |
| 421 "Java surface is empty."; | 504 "Java surface is empty."; |
| 422 return false; | 505 return false; |
| 423 } | 506 } |
| 424 | 507 |
| 425 on_destroying_surface_cb_ = | 508 on_destroying_surface_cb_ = |
| 426 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, | 509 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, |
| 427 weak_this_factory_.GetWeakPtr()); | 510 weak_this_factory_.GetWeakPtr()); |
| 428 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( | 511 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( |
| 429 on_destroying_surface_cb_); | 512 on_destroying_surface_cb_); |
| 430 | 513 |
| 431 // TODO(watk,liberato): move this into the strategy. | 514 // TODO(watk,liberato): move this into the strategy. |
| 432 scoped_refptr<gfx::SurfaceTexture> surface_texture = | 515 scoped_refptr<gfx::SurfaceTexture> surface_texture = |
| 433 strategy_->GetSurfaceTexture(); | 516 strategy_->GetSurfaceTexture(); |
| 434 if (surface_texture) { | 517 if (surface_texture) { |
| 435 on_frame_available_handler_ = | 518 on_frame_available_handler_ = |
| 436 new OnFrameAvailableHandler(this, surface_texture); | 519 new OnFrameAvailableHandler(this, surface_texture); |
| 437 } | 520 } |
| 438 | 521 |
| 439 // Start the thread for async configuration, even if we don't need it now. | 522 // Start the thread for async configuration, even if we don't need it now. |
| 440 // ResetCodecState might rebuild the codec later, for example. | 523 // ResetCodecState might rebuild the codec later, for example. |
| 441 if (!g_avda_timer.Pointer()->StartThread(this)) { | 524 if (!g_avda_timer.Pointer()->StartThread(this)) { |
| 442 LOG(ERROR) << "Failed to start AVDA thread"; | 525 LOG(ERROR) << "Failed to start AVDA thread"; |
| 443 return false; | 526 return false; |
| 444 } | 527 } |
| 445 | 528 |
| 446 // If we are encrypted, then we aren't able to create the codec yet. | 529 // If we are encrypted, then we aren't able to create the codec yet. |
| 447 if (is_encrypted_) { | 530 if (config_.is_encrypted) { |
| 448 InitializeCdm(config.cdm_id); | 531 InitializeCdm(); |
| 449 return true; | 532 return true; |
| 450 } | 533 } |
| 451 | 534 |
| 452 if (deferred_initialization_pending_) { | 535 if (deferred_initialization_pending_) { |
| 453 ConfigureMediaCodecAsynchronously(); | 536 ConfigureMediaCodecAsynchronously(); |
| 454 return true; | 537 return true; |
| 455 } | 538 } |
| 456 | 539 |
| 457 // If the client doesn't support deferred initialization (WebRTC), then we | 540 // If the client doesn't support deferred initialization (WebRTC), then we |
| 458 // should complete it now and return a meaningful result. | 541 // should complete it now and return a meaningful result. Note that it would |
| 542 // be nice if we didn't have to worry about starting codec configuration at |
| 543 // all (::Initialize or the wrapper can do it), but then they have to remember |
| 544 // not to start codec config if we have to wait for the cdm. It's somewhat |
| 545 // clearer for us to handle both cases. |
| 459 return ConfigureMediaCodecSynchronously(); | 546 return ConfigureMediaCodecSynchronously(); |
| 460 } | 547 } |
| 461 | 548 |
| 462 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { | 549 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { |
| 463 DCHECK(thread_checker_.CalledOnValidThread()); | 550 DCHECK(thread_checker_.CalledOnValidThread()); |
| 464 TRACE_EVENT0("media", "AVDA::DoIOTask"); | 551 TRACE_EVENT0("media", "AVDA::DoIOTask"); |
| 465 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || | 552 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || |
| 466 state_ == SURFACE_DESTROYED) { | 553 state_ == SURFACE_DESTROYED) { |
| 467 return; | 554 return; |
| 468 } | 555 } |
| (...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1197 | 1284 |
| 1198 void AndroidVideoDecodeAccelerator::ActualDestroy() { | 1285 void AndroidVideoDecodeAccelerator::ActualDestroy() { |
| 1199 DVLOG(1) << __FUNCTION__; | 1286 DVLOG(1) << __FUNCTION__; |
| 1200 DCHECK(thread_checker_.CalledOnValidThread()); | 1287 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1201 | 1288 |
| 1202 if (!on_destroying_surface_cb_.is_null()) { | 1289 if (!on_destroying_surface_cb_.is_null()) { |
| 1203 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( | 1290 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( |
| 1204 on_destroying_surface_cb_); | 1291 on_destroying_surface_cb_); |
| 1205 } | 1292 } |
| 1206 | 1293 |
| 1294 // We no longer care about |surface_id|, in case we did before. It's okay |
| 1295 // if we have no surface and/or weren't the owner or a waiter. |
| 1296 g_avda_timer.Pointer()->DeallocateSurface(config_.surface_id, this); |
| 1297 |
| 1207 // Note that async codec construction might still be in progress. In that | 1298 // Note that async codec construction might still be in progress. In that |
| 1208 // case, the codec will be deleted when it completes once we invalidate all | 1299 // case, the codec will be deleted when it completes once we invalidate all |
| 1209 // our weak refs. | 1300 // our weak refs. |
| 1210 weak_this_factory_.InvalidateWeakPtrs(); | 1301 weak_this_factory_.InvalidateWeakPtrs(); |
| 1211 if (media_codec_) { | 1302 if (media_codec_) { |
| 1212 g_avda_timer.Pointer()->StopTimer(this); | 1303 g_avda_timer.Pointer()->StopTimer(this); |
| 1213 media_codec_.reset(); | 1304 media_codec_.reset(); |
| 1214 } | 1305 } |
| 1215 delete this; | 1306 delete this; |
| 1216 } | 1307 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1255 nullptr); | 1346 nullptr); |
| 1256 | 1347 |
| 1257 return texture_ref; | 1348 return texture_ref; |
| 1258 } | 1349 } |
| 1259 | 1350 |
| 1260 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { | 1351 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { |
| 1261 DCHECK(thread_checker_.CalledOnValidThread()); | 1352 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1262 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); | 1353 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); |
| 1263 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; | 1354 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; |
| 1264 | 1355 |
| 1265 if (surface_id != surface_id_) | 1356 if (surface_id != config_.surface_id) |
| 1266 return; | 1357 return; |
| 1267 | 1358 |
| 1268 // If we're currently asynchronously configuring a codec, it will be destroyed | 1359 // If we're currently asynchronously configuring a codec, it will be destroyed |
| 1269 // when configuration completes and it notices that |state_| has changed to | 1360 // when configuration completes and it notices that |state_| has changed to |
| 1270 // SURFACE_DESTROYED. | 1361 // SURFACE_DESTROYED. |
| 1271 state_ = SURFACE_DESTROYED; | 1362 state_ = SURFACE_DESTROYED; |
| 1272 if (media_codec_) { | 1363 if (media_codec_) { |
| 1273 media_codec_.reset(); | 1364 media_codec_.reset(); |
| 1274 strategy_->CodecChanged(media_codec_.get()); | 1365 strategy_->CodecChanged(media_codec_.get()); |
| 1275 } | 1366 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1289 const ::tracked_objects::Location& from_here, | 1380 const ::tracked_objects::Location& from_here, |
| 1290 media::VideoDecodeAccelerator::Error error) { | 1381 media::VideoDecodeAccelerator::Error error) { |
| 1291 base::MessageLoop::current()->PostDelayedTask( | 1382 base::MessageLoop::current()->PostDelayedTask( |
| 1292 from_here, | 1383 from_here, |
| 1293 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, | 1384 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, |
| 1294 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_), | 1385 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_), |
| 1295 (defer_errors_ ? ErrorPostingDelay() : base::TimeDelta())); | 1386 (defer_errors_ ? ErrorPostingDelay() : base::TimeDelta())); |
| 1296 state_ = ERROR; | 1387 state_ = ERROR; |
| 1297 } | 1388 } |
| 1298 | 1389 |
| 1299 void AndroidVideoDecodeAccelerator::InitializeCdm(int cdm_id) { | 1390 void AndroidVideoDecodeAccelerator::InitializeCdm() { |
| 1300 DVLOG(2) << __FUNCTION__ << ": " << cdm_id; | 1391 DVLOG(2) << __FUNCTION__ << ": " << config_.cdm_id; |
| 1301 | 1392 |
| 1302 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 1393 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 1303 NOTIMPLEMENTED(); | 1394 NOTIMPLEMENTED(); |
| 1304 NotifyInitializationComplete(false); | 1395 NotifyInitializationComplete(false); |
| 1305 #else | 1396 #else |
| 1306 // Store the CDM to hold a reference to it. | 1397 // Store the CDM to hold a reference to it. |
| 1307 cdm_for_reference_holding_only_ = media::MojoCdmService::LegacyGetCdm(cdm_id); | 1398 cdm_for_reference_holding_only_ = |
| 1399 media::MojoCdmService::LegacyGetCdm(config_.cdm_id); |
| 1308 DCHECK(cdm_for_reference_holding_only_); | 1400 DCHECK(cdm_for_reference_holding_only_); |
| 1309 | 1401 |
| 1310 // On Android platform the CdmContext must be a MediaDrmBridgeCdmContext. | 1402 // On Android platform the CdmContext must be a MediaDrmBridgeCdmContext. |
| 1311 media_drm_bridge_cdm_context_ = static_cast<media::MediaDrmBridgeCdmContext*>( | 1403 media_drm_bridge_cdm_context_ = static_cast<media::MediaDrmBridgeCdmContext*>( |
| 1312 cdm_for_reference_holding_only_->GetCdmContext()); | 1404 cdm_for_reference_holding_only_->GetCdmContext()); |
| 1313 DCHECK(media_drm_bridge_cdm_context_); | 1405 DCHECK(media_drm_bridge_cdm_context_); |
| 1314 | 1406 |
| 1315 // Register CDM callbacks. The callbacks registered will be posted back to | 1407 // Register CDM callbacks. The callbacks registered will be posted back to |
| 1316 // this thread via BindToCurrentLoop. | 1408 // this thread via BindToCurrentLoop. |
| 1317 | 1409 |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1502 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { | 1594 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { |
| 1503 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: | 1595 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: |
| 1504 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1596 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
| 1505 } | 1597 } |
| 1506 } | 1598 } |
| 1507 | 1599 |
| 1508 return capabilities; | 1600 return capabilities; |
| 1509 } | 1601 } |
| 1510 | 1602 |
| 1511 } // namespace media | 1603 } // namespace media |
| OLD | NEW |