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 |