OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "content/browser/media/android/browser_media_player_manager.h" | 5 #include "content/browser/media/android/browser_media_player_manager.h" |
6 | 6 |
7 #include "base/android/scoped_java_ref.h" | 7 #include "base/android/scoped_java_ref.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
ddorwin
2014/06/04 01:02:30
Do you still need this?
xhwang
2014/06/04 18:54:07
Done.
| |
10 #include "content/browser/android/content_view_core_impl.h" | 10 #include "content/browser/android/content_view_core_impl.h" |
11 #include "content/browser/media/android/browser_demuxer_android.h" | 11 #include "content/browser/media/android/browser_demuxer_android.h" |
12 #include "content/browser/media/android/media_resource_getter_impl.h" | 12 #include "content/browser/media/android/media_resource_getter_impl.h" |
13 #include "content/browser/renderer_host/render_view_host_impl.h" | 13 #include "content/browser/renderer_host/render_view_host_impl.h" |
14 #include "content/browser/web_contents/web_contents_view_android.h" | 14 #include "content/browser/web_contents/web_contents_view_android.h" |
15 #include "content/common/media/cdm_messages.h" | |
16 #include "content/common/media/media_player_messages_android.h" | 15 #include "content/common/media/media_player_messages_android.h" |
17 #include "content/public/browser/android/content_view_core.h" | 16 #include "content/public/browser/android/content_view_core.h" |
18 #include "content/public/browser/android/external_video_surface_container.h" | 17 #include "content/public/browser/android/external_video_surface_container.h" |
19 #include "content/public/browser/browser_context.h" | 18 #include "content/public/browser/browser_context.h" |
20 #include "content/public/browser/content_browser_client.h" | 19 #include "content/public/browser/content_browser_client.h" |
21 #include "content/public/browser/render_frame_host.h" | 20 #include "content/public/browser/render_frame_host.h" |
22 #include "content/public/browser/render_process_host.h" | 21 #include "content/public/browser/render_process_host.h" |
23 #include "content/public/browser/render_view_host.h" | 22 #include "content/public/browser/render_view_host.h" |
24 #include "content/public/browser/storage_partition.h" | 23 #include "content/public/browser/storage_partition.h" |
25 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
26 #include "content/public/browser/web_contents_delegate.h" | 25 #include "content/public/browser/web_contents_delegate.h" |
27 #include "content/public/common/content_client.h" | 26 #include "content/public/common/content_client.h" |
28 #include "content/public/common/content_switches.h" | 27 #include "content/public/common/content_switches.h" |
29 #include "media/base/android/media_player_bridge.h" | 28 #include "media/base/android/media_player_bridge.h" |
30 #include "media/base/android/media_source_player.h" | 29 #include "media/base/android/media_source_player.h" |
31 #include "media/base/browser_cdm.h" | |
32 #include "media/base/browser_cdm_factory.h" | |
33 #include "media/base/media_switches.h" | 30 #include "media/base/media_switches.h" |
34 | 31 |
35 using media::BrowserCdm; | |
36 using media::MediaKeys; | |
37 using media::MediaPlayerAndroid; | 32 using media::MediaPlayerAndroid; |
38 using media::MediaPlayerBridge; | 33 using media::MediaPlayerBridge; |
39 using media::MediaPlayerManager; | 34 using media::MediaPlayerManager; |
40 using media::MediaSourcePlayer; | 35 using media::MediaSourcePlayer; |
41 | 36 |
42 namespace content { | 37 namespace content { |
43 | 38 |
44 // Threshold on the number of media players per renderer before we start | 39 // Threshold on the number of media players per renderer before we start |
45 // attempting to release inactive media players. | 40 // attempting to release inactive media players. |
46 const int kMediaPlayerThreshold = 1; | 41 const int kMediaPlayerThreshold = 1; |
47 | 42 |
48 // Maximum lengths for various EME API parameters. These are checks to | |
49 // prevent unnecessarily large parameters from being passed around, and the | |
50 // lengths are somewhat arbitrary as the EME spec doesn't specify any limits. | |
51 const size_t kMaxInitDataLength = 64 * 1024; // 64 KB | |
52 const size_t kMaxSessionResponseLength = 64 * 1024; // 64 KB | |
53 const size_t kMaxKeySystemLength = 256; | |
54 | |
55 static BrowserMediaPlayerManager::Factory g_factory = NULL; | 43 static BrowserMediaPlayerManager::Factory g_factory = NULL; |
56 | 44 |
57 // static | 45 // static |
58 void BrowserMediaPlayerManager::RegisterFactory(Factory factory) { | 46 void BrowserMediaPlayerManager::RegisterFactory(Factory factory) { |
59 g_factory = factory; | 47 g_factory = factory; |
60 } | 48 } |
61 | 49 |
62 // static | 50 // static |
63 BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create( | 51 BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create( |
64 RenderFrameHost* rfh) { | 52 RenderFrameHost* rfh) { |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
312 | 300 |
313 MediaPlayerAndroid* BrowserMediaPlayerManager::GetPlayer(int player_id) { | 301 MediaPlayerAndroid* BrowserMediaPlayerManager::GetPlayer(int player_id) { |
314 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); | 302 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); |
315 it != players_.end(); ++it) { | 303 it != players_.end(); ++it) { |
316 if ((*it)->player_id() == player_id) | 304 if ((*it)->player_id() == player_id) |
317 return *it; | 305 return *it; |
318 } | 306 } |
319 return NULL; | 307 return NULL; |
320 } | 308 } |
321 | 309 |
322 BrowserCdm* BrowserMediaPlayerManager::GetCdm(int cdm_id) { | |
323 CdmMap::const_iterator iter = cdm_map_.find(cdm_id); | |
324 return (iter == cdm_map_.end()) ? NULL : iter->second; | |
325 } | |
326 | |
327 void BrowserMediaPlayerManager::DestroyAllMediaPlayers() { | 310 void BrowserMediaPlayerManager::DestroyAllMediaPlayers() { |
328 players_.clear(); | 311 players_.clear(); |
329 STLDeleteValues(&cdm_map_); | |
330 if (fullscreen_player_id_ != -1) { | 312 if (fullscreen_player_id_ != -1) { |
331 video_view_.reset(); | 313 video_view_.reset(); |
332 fullscreen_player_id_ = -1; | 314 fullscreen_player_id_ = -1; |
333 } | 315 } |
334 } | 316 } |
335 | 317 |
336 void BrowserMediaPlayerManager::RequestFullScreen(int player_id) { | 318 void BrowserMediaPlayerManager::RequestFullScreen(int player_id) { |
337 if (fullscreen_player_id_ == player_id) | 319 if (fullscreen_player_id_ == player_id) |
338 return; | 320 return; |
339 | 321 |
340 if (fullscreen_player_id_ != -1) { | 322 if (fullscreen_player_id_ != -1) { |
341 // TODO(qinmin): Determine the correct error code we should report to WMPA. | 323 // TODO(qinmin): Determine the correct error code we should report to WMPA. |
342 OnError(player_id, MediaPlayerAndroid::MEDIA_ERROR_DECODE); | 324 OnError(player_id, MediaPlayerAndroid::MEDIA_ERROR_DECODE); |
343 return; | 325 return; |
344 } | 326 } |
345 } | 327 } |
346 | 328 |
347 // The following 5 functions are EME MediaKeySession events. | |
348 | |
349 void BrowserMediaPlayerManager::OnSessionCreated( | |
350 int cdm_id, | |
351 uint32 session_id, | |
352 const std::string& web_session_id) { | |
353 Send(new CdmMsg_SessionCreated( | |
354 RoutingID(), cdm_id, session_id, web_session_id)); | |
355 } | |
356 | |
357 void BrowserMediaPlayerManager::OnSessionMessage( | |
358 int cdm_id, | |
359 uint32 session_id, | |
360 const std::vector<uint8>& message, | |
361 const GURL& destination_url) { | |
362 GURL verified_gurl = destination_url; | |
363 if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) { | |
364 DLOG(WARNING) << "SessionMessage destination_url is invalid : " | |
365 << destination_url.possibly_invalid_spec(); | |
366 verified_gurl = GURL::EmptyGURL(); // Replace invalid destination_url. | |
367 } | |
368 | |
369 Send(new CdmMsg_SessionMessage( | |
370 RoutingID(), cdm_id, session_id, message, verified_gurl)); | |
371 } | |
372 | |
373 void BrowserMediaPlayerManager::OnSessionReady(int cdm_id, uint32 session_id) { | |
374 Send(new CdmMsg_SessionReady(RoutingID(), cdm_id, session_id)); | |
375 } | |
376 | |
377 void BrowserMediaPlayerManager::OnSessionClosed(int cdm_id, uint32 session_id) { | |
378 Send(new CdmMsg_SessionClosed(RoutingID(), cdm_id, session_id)); | |
379 } | |
380 | |
381 void BrowserMediaPlayerManager::OnSessionError(int cdm_id, | |
382 uint32 session_id, | |
383 MediaKeys::KeyError error_code, | |
384 uint32 system_code) { | |
385 Send(new CdmMsg_SessionError( | |
386 RoutingID(), cdm_id, session_id, error_code, system_code)); | |
387 } | |
388 | |
389 #if defined(VIDEO_HOLE) | 329 #if defined(VIDEO_HOLE) |
390 void BrowserMediaPlayerManager::AttachExternalVideoSurface(int player_id, | 330 void BrowserMediaPlayerManager::AttachExternalVideoSurface(int player_id, |
391 jobject surface) { | 331 jobject surface) { |
392 MediaPlayerAndroid* player = GetPlayer(player_id); | 332 MediaPlayerAndroid* player = GetPlayer(player_id); |
393 if (player) { | 333 if (player) { |
394 player->SetVideoSurface( | 334 player->SetVideoSurface( |
395 gfx::ScopedJavaSurface::AcquireExternalSurface(surface)); | 335 gfx::ScopedJavaSurface::AcquireExternalSurface(surface)); |
396 } | 336 } |
397 } | 337 } |
398 | 338 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
549 if (player_id == fullscreen_player_id_) | 489 if (player_id == fullscreen_player_id_) |
550 fullscreen_player_is_released_ = true; | 490 fullscreen_player_is_released_ = true; |
551 } | 491 } |
552 | 492 |
553 void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) { | 493 void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) { |
554 RemovePlayer(player_id); | 494 RemovePlayer(player_id); |
555 if (fullscreen_player_id_ == player_id) | 495 if (fullscreen_player_id_ == player_id) |
556 fullscreen_player_id_ = -1; | 496 fullscreen_player_id_ = -1; |
557 } | 497 } |
558 | 498 |
559 void BrowserMediaPlayerManager::OnInitializeCdm(int cdm_id, | |
560 const std::string& key_system, | |
561 const GURL& security_origin) { | |
562 if (key_system.size() > kMaxKeySystemLength) { | |
563 // This failure will be discovered and reported by OnCreateSession() | |
564 // as GetCdm() will return null. | |
565 NOTREACHED() << "Invalid key system: " << key_system; | |
566 return; | |
567 } | |
568 | |
569 AddCdm(cdm_id, key_system, security_origin); | |
570 } | |
571 | |
572 void BrowserMediaPlayerManager::OnCreateSession( | |
573 int cdm_id, | |
574 uint32 session_id, | |
575 CdmHostMsg_CreateSession_ContentType content_type, | |
576 const std::vector<uint8>& init_data) { | |
577 if (init_data.size() > kMaxInitDataLength) { | |
578 LOG(WARNING) << "InitData for ID: " << cdm_id | |
579 << " too long: " << init_data.size(); | |
580 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0); | |
581 return; | |
582 } | |
583 | |
584 // Convert the session content type into a MIME type. "audio" and "video" | |
585 // don't matter, so using "video" for the MIME type. | |
586 // Ref: | |
587 // https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypte d-media.html#dom-createsession | |
588 std::string mime_type; | |
589 switch (content_type) { | |
590 case CREATE_SESSION_TYPE_WEBM: | |
591 mime_type = "video/webm"; | |
592 break; | |
593 case CREATE_SESSION_TYPE_MP4: | |
594 mime_type = "video/mp4"; | |
595 break; | |
596 default: | |
597 NOTREACHED(); | |
598 return; | |
599 } | |
600 | |
601 if (CommandLine::ForCurrentProcess() | |
602 ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) { | |
603 CreateSessionIfPermitted(cdm_id, session_id, mime_type, init_data, true); | |
604 return; | |
605 } | |
606 | |
607 BrowserCdm* cdm = GetCdm(cdm_id); | |
608 if (!cdm) { | |
609 DLOG(WARNING) << "No CDM for ID " << cdm_id << " found"; | |
610 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0); | |
611 return; | |
612 } | |
613 | |
614 BrowserContext* context = | |
615 web_contents()->GetRenderProcessHost()->GetBrowserContext(); | |
616 | |
617 std::map<int, GURL>::const_iterator iter = | |
618 cdm_security_origin_map_.find(cdm_id); | |
619 if (iter == cdm_security_origin_map_.end()) { | |
620 NOTREACHED(); | |
621 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0); | |
622 return; | |
623 } | |
624 | |
625 context->RequestProtectedMediaIdentifierPermission( | |
626 web_contents()->GetRenderProcessHost()->GetID(), | |
627 web_contents()->GetRenderViewHost()->GetRoutingID(), | |
628 iter->second, | |
629 base::Bind(&BrowserMediaPlayerManager::CreateSessionIfPermitted, | |
630 weak_ptr_factory_.GetWeakPtr(), | |
631 cdm_id, | |
632 session_id, | |
633 mime_type, | |
634 init_data)); | |
635 } | |
636 | |
637 void BrowserMediaPlayerManager::OnUpdateSession( | |
638 int cdm_id, | |
639 uint32 session_id, | |
640 const std::vector<uint8>& response) { | |
641 BrowserCdm* cdm = GetCdm(cdm_id); | |
642 if (!cdm) { | |
643 DLOG(WARNING) << "No CDM for ID " << cdm_id << " found"; | |
644 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0); | |
645 return; | |
646 } | |
647 | |
648 if (response.size() > kMaxSessionResponseLength) { | |
649 LOG(WARNING) << "Response for ID " << cdm_id | |
650 << " is too long: " << response.size(); | |
651 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0); | |
652 return; | |
653 } | |
654 | |
655 cdm->UpdateSession(session_id, &response[0], response.size()); | |
656 } | |
657 | |
658 void BrowserMediaPlayerManager::OnReleaseSession(int cdm_id, | |
659 uint32 session_id) { | |
660 BrowserCdm* cdm = GetCdm(cdm_id); | |
661 if (!cdm) { | |
662 DLOG(WARNING) << "No CDM for ID " << cdm_id << " found"; | |
663 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0); | |
664 return; | |
665 } | |
666 | |
667 cdm->ReleaseSession(session_id); | |
668 } | |
669 | |
670 void BrowserMediaPlayerManager::OnDestroyCdm(int cdm_id) { | |
671 BrowserCdm* cdm = GetCdm(cdm_id); | |
672 if (!cdm) | |
673 return; | |
674 | |
675 CancelAllPendingSessionCreations(cdm_id); | |
676 RemoveCdm(cdm_id); | |
677 } | |
678 | |
679 void BrowserMediaPlayerManager::CancelAllPendingSessionCreations(int cdm_id) { | |
680 BrowserContext* context = | |
681 web_contents()->GetRenderProcessHost()->GetBrowserContext(); | |
682 std::map<int, GURL>::const_iterator iter = | |
683 cdm_security_origin_map_.find(cdm_id); | |
684 if (iter == cdm_security_origin_map_.end()) | |
685 return; | |
686 context->CancelProtectedMediaIdentifierPermissionRequests( | |
687 web_contents()->GetRenderProcessHost()->GetID(), | |
688 web_contents()->GetRenderViewHost()->GetRoutingID(), | |
689 iter->second); | |
690 } | |
691 | |
692 void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) { | 499 void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) { |
693 DCHECK(!GetPlayer(player->player_id())); | 500 DCHECK(!GetPlayer(player->player_id())); |
694 players_.push_back(player); | 501 players_.push_back(player); |
695 } | 502 } |
696 | 503 |
697 void BrowserMediaPlayerManager::RemovePlayer(int player_id) { | 504 void BrowserMediaPlayerManager::RemovePlayer(int player_id) { |
698 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); | 505 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); |
699 it != players_.end(); ++it) { | 506 it != players_.end(); ++it) { |
700 MediaPlayerAndroid* player = *it; | 507 MediaPlayerAndroid* player = *it; |
701 if (player->player_id() == player_id) { | 508 if (player->player_id() == player_id) { |
(...skipping 11 matching lines...) Expand all Loading... | |
713 if ((*it)->player_id() == player_id) { | 520 if ((*it)->player_id() == player_id) { |
714 previous_player = *it; | 521 previous_player = *it; |
715 players_.weak_erase(it); | 522 players_.weak_erase(it); |
716 players_.push_back(player); | 523 players_.push_back(player); |
717 break; | 524 break; |
718 } | 525 } |
719 } | 526 } |
720 return scoped_ptr<media::MediaPlayerAndroid>(previous_player); | 527 return scoped_ptr<media::MediaPlayerAndroid>(previous_player); |
721 } | 528 } |
722 | 529 |
723 void BrowserMediaPlayerManager::AddCdm(int cdm_id, | |
724 const std::string& key_system, | |
725 const GURL& security_origin) { | |
726 DCHECK(!GetCdm(cdm_id)); | |
727 base::WeakPtr<BrowserMediaPlayerManager> weak_this = | |
728 weak_ptr_factory_.GetWeakPtr(); | |
729 | |
730 int id = cdm_id; | |
731 scoped_ptr<BrowserCdm> cdm(media::CreateBrowserCdm( | |
732 key_system, | |
733 base::Bind(&BrowserMediaPlayerManager::OnSessionCreated, weak_this, id), | |
734 base::Bind(&BrowserMediaPlayerManager::OnSessionMessage, weak_this, id), | |
735 base::Bind(&BrowserMediaPlayerManager::OnSessionReady, weak_this, id), | |
736 base::Bind(&BrowserMediaPlayerManager::OnSessionClosed, weak_this, id), | |
737 base::Bind(&BrowserMediaPlayerManager::OnSessionError, weak_this, id))); | |
738 | |
739 if (!cdm) { | |
740 // This failure will be discovered and reported by OnCreateSession() | |
741 // as GetCdm() will return null. | |
742 DVLOG(1) << "failed to create CDM."; | |
743 return; | |
744 } | |
745 | |
746 cdm_map_[cdm_id] = cdm.release(); | |
747 cdm_security_origin_map_[cdm_id] = security_origin; | |
748 } | |
749 | |
750 void BrowserMediaPlayerManager::RemoveCdm(int cdm_id) { | |
751 // TODO(xhwang): Detach CDM from the player it's set to. In prefixed | |
752 // EME implementation the current code is fine because we always destroy the | |
753 // player before we destroy the DrmBridge. This will not always be the case | |
754 // in unprefixed EME implementation. | |
755 CdmMap::iterator iter = cdm_map_.find(cdm_id); | |
756 if (iter != cdm_map_.end()) { | |
757 delete iter->second; | |
758 cdm_map_.erase(iter); | |
759 } | |
760 cdm_security_origin_map_.erase(cdm_id); | |
761 } | |
762 | |
763 void BrowserMediaPlayerManager::OnSetCdm(int player_id, int cdm_id) { | |
764 MediaPlayerAndroid* player = GetPlayer(player_id); | |
765 BrowserCdm* cdm = GetCdm(cdm_id); | |
766 // Currently we do not support detaching CDM from a player. | |
767 if (!cdm || !player) { | |
768 NOTREACHED() << "Cannot set CDM on the specified player."; | |
769 return; | |
770 } | |
771 | |
772 // TODO(qinmin): add the logic to decide whether we should create the | |
773 // fullscreen surface for EME lv1. | |
774 player->SetCdm(cdm); | |
775 } | |
776 | |
777 int BrowserMediaPlayerManager::RoutingID() { | 530 int BrowserMediaPlayerManager::RoutingID() { |
778 return render_frame_host_->GetRoutingID(); | 531 return render_frame_host_->GetRoutingID(); |
779 } | 532 } |
780 | 533 |
781 bool BrowserMediaPlayerManager::Send(IPC::Message* msg) { | 534 bool BrowserMediaPlayerManager::Send(IPC::Message* msg) { |
782 return render_frame_host_->Send(msg); | 535 return render_frame_host_->Send(msg); |
783 } | 536 } |
784 | 537 |
785 void BrowserMediaPlayerManager::CreateSessionIfPermitted( | |
786 int cdm_id, | |
787 uint32 session_id, | |
788 const std::string& content_type, | |
789 const std::vector<uint8>& init_data, | |
790 bool permitted) { | |
791 if (!permitted) { | |
792 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0); | |
793 return; | |
794 } | |
795 | |
796 BrowserCdm* cdm = GetCdm(cdm_id); | |
797 if (!cdm) { | |
798 DLOG(WARNING) << "No CDM for ID: " << cdm_id << " found"; | |
799 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0); | |
800 return; | |
801 } | |
802 | |
803 // This could fail, in which case a SessionError will be fired. | |
804 cdm->CreateSession(session_id, content_type, &init_data[0], init_data.size()); | |
805 } | |
806 | |
807 void BrowserMediaPlayerManager::ReleaseFullscreenPlayer( | 538 void BrowserMediaPlayerManager::ReleaseFullscreenPlayer( |
808 MediaPlayerAndroid* player) { | 539 MediaPlayerAndroid* player) { |
809 player->Release(); | 540 player->Release(); |
810 } | 541 } |
811 | 542 |
812 void BrowserMediaPlayerManager::OnMediaResourcesRequested(int player_id) { | 543 void BrowserMediaPlayerManager::OnMediaResourcesRequested(int player_id) { |
813 int num_active_player = 0; | 544 int num_active_player = 0; |
814 ScopedVector<MediaPlayerAndroid>::iterator it; | 545 ScopedVector<MediaPlayerAndroid>::iterator it; |
815 for (it = players_.begin(); it != players_.end(); ++it) { | 546 for (it = players_.begin(); it != players_.end(); ++it) { |
816 if (!(*it)->IsPlayerReady()) | 547 if (!(*it)->IsPlayerReady()) |
(...skipping 24 matching lines...) Expand all Loading... | |
841 #if defined(VIDEO_HOLE) | 572 #if defined(VIDEO_HOLE) |
842 MediaPlayerAndroid* player = GetPlayer(player_id); | 573 MediaPlayerAndroid* player = GetPlayer(player_id); |
843 if (player && player->IsSurfaceInUse()) | 574 if (player && player->IsSurfaceInUse()) |
844 return; | 575 return; |
845 if (external_video_surface_container_) | 576 if (external_video_surface_container_) |
846 external_video_surface_container_->ReleaseExternalVideoSurface(player_id); | 577 external_video_surface_container_->ReleaseExternalVideoSurface(player_id); |
847 #endif // defined(VIDEO_HOLE) | 578 #endif // defined(VIDEO_HOLE) |
848 } | 579 } |
849 | 580 |
850 } // namespace content | 581 } // namespace content |
OLD | NEW |