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

Side by Side Diff: content/renderer/media/webmediaplayer_impl.cc

Issue 501473003: Move EME code out of WebMediaPlayerImpl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 6 years, 4 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 | Annotate | Revision Log
OLDNEW
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/renderer/media/webmediaplayer_impl.h" 5 #include "content/renderer/media/webmediaplayer_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/callback.h" 13 #include "base/callback.h"
14 #include "base/callback_helpers.h" 14 #include "base/callback_helpers.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/debug/alias.h" 16 #include "base/debug/alias.h"
17 #include "base/debug/crash_logging.h" 17 #include "base/debug/crash_logging.h"
18 #include "base/debug/trace_event.h" 18 #include "base/debug/trace_event.h"
19 #include "base/message_loop/message_loop_proxy.h" 19 #include "base/message_loop/message_loop_proxy.h"
20 #include "base/metrics/histogram.h" 20 #include "base/metrics/histogram.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/synchronization/waitable_event.h" 21 #include "base/synchronization/waitable_event.h"
24 #include "cc/blink/web_layer_impl.h" 22 #include "cc/blink/web_layer_impl.h"
25 #include "cc/layers/video_layer.h" 23 #include "cc/layers/video_layer.h"
26 #include "content/public/common/content_switches.h" 24 #include "content/public/common/content_switches.h"
27 #include "content/public/renderer/render_frame.h" 25 #include "content/public/renderer/render_frame.h"
28 #include "content/renderer/media/buffered_data_source.h" 26 #include "content/renderer/media/buffered_data_source.h"
29 #include "content/renderer/media/crypto/key_systems.h" 27 #include "content/renderer/media/crypto/encrypted_media_player_support.h"
30 #include "content/renderer/media/render_media_log.h" 28 #include "content/renderer/media/render_media_log.h"
31 #include "content/renderer/media/texttrack_impl.h" 29 #include "content/renderer/media/texttrack_impl.h"
32 #include "content/renderer/media/webaudiosourceprovider_impl.h" 30 #include "content/renderer/media/webaudiosourceprovider_impl.h"
33 #include "content/renderer/media/webcontentdecryptionmodule_impl.h"
34 #include "content/renderer/media/webinbandtexttrack_impl.h" 31 #include "content/renderer/media/webinbandtexttrack_impl.h"
35 #include "content/renderer/media/webmediaplayer_delegate.h" 32 #include "content/renderer/media/webmediaplayer_delegate.h"
36 #include "content/renderer/media/webmediaplayer_params.h" 33 #include "content/renderer/media/webmediaplayer_params.h"
37 #include "content/renderer/media/webmediaplayer_util.h" 34 #include "content/renderer/media/webmediaplayer_util.h"
38 #include "content/renderer/media/webmediasource_impl.h" 35 #include "content/renderer/media/webmediasource_impl.h"
39 #include "content/renderer/pepper/pepper_webplugin_impl.h"
40 #include "content/renderer/render_thread_impl.h" 36 #include "content/renderer/render_thread_impl.h"
41 #include "gpu/GLES2/gl2extchromium.h" 37 #include "gpu/GLES2/gl2extchromium.h"
42 #include "gpu/command_buffer/common/mailbox_holder.h" 38 #include "gpu/command_buffer/common/mailbox_holder.h"
43 #include "media/audio/null_audio_sink.h" 39 #include "media/audio/null_audio_sink.h"
44 #include "media/base/audio_hardware_config.h" 40 #include "media/base/audio_hardware_config.h"
45 #include "media/base/bind_to_current_loop.h" 41 #include "media/base/bind_to_current_loop.h"
46 #include "media/base/filter_collection.h" 42 #include "media/base/filter_collection.h"
47 #include "media/base/limits.h" 43 #include "media/base/limits.h"
48 #include "media/base/media_log.h" 44 #include "media/base/media_log.h"
49 #include "media/base/media_switches.h" 45 #include "media/base/media_switches.h"
50 #include "media/base/pipeline.h" 46 #include "media/base/pipeline.h"
51 #include "media/base/text_renderer.h" 47 #include "media/base/text_renderer.h"
52 #include "media/base/video_frame.h" 48 #include "media/base/video_frame.h"
53 #include "media/filters/audio_renderer_impl.h" 49 #include "media/filters/audio_renderer_impl.h"
54 #include "media/filters/chunk_demuxer.h" 50 #include "media/filters/chunk_demuxer.h"
55 #include "media/filters/ffmpeg_audio_decoder.h" 51 #include "media/filters/ffmpeg_audio_decoder.h"
56 #include "media/filters/ffmpeg_demuxer.h" 52 #include "media/filters/ffmpeg_demuxer.h"
57 #include "media/filters/ffmpeg_video_decoder.h" 53 #include "media/filters/ffmpeg_video_decoder.h"
58 #include "media/filters/gpu_video_accelerator_factories.h" 54 #include "media/filters/gpu_video_accelerator_factories.h"
59 #include "media/filters/gpu_video_decoder.h" 55 #include "media/filters/gpu_video_decoder.h"
60 #include "media/filters/opus_audio_decoder.h" 56 #include "media/filters/opus_audio_decoder.h"
61 #include "media/filters/renderer_impl.h" 57 #include "media/filters/renderer_impl.h"
62 #include "media/filters/video_renderer_impl.h" 58 #include "media/filters/video_renderer_impl.h"
63 #include "media/filters/vpx_video_decoder.h" 59 #include "media/filters/vpx_video_decoder.h"
64 #include "third_party/WebKit/public/platform/WebContentDecryptionModule.h"
65 #include "third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h"
66 #include "third_party/WebKit/public/platform/WebMediaSource.h" 60 #include "third_party/WebKit/public/platform/WebMediaSource.h"
67 #include "third_party/WebKit/public/platform/WebRect.h" 61 #include "third_party/WebKit/public/platform/WebRect.h"
68 #include "third_party/WebKit/public/platform/WebSize.h" 62 #include "third_party/WebKit/public/platform/WebSize.h"
69 #include "third_party/WebKit/public/platform/WebString.h" 63 #include "third_party/WebKit/public/platform/WebString.h"
70 #include "third_party/WebKit/public/platform/WebURL.h" 64 #include "third_party/WebKit/public/platform/WebURL.h"
71 #include "third_party/WebKit/public/web/WebDocument.h"
72 #include "third_party/WebKit/public/web/WebLocalFrame.h" 65 #include "third_party/WebKit/public/web/WebLocalFrame.h"
73 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
74 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" 66 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
75 #include "third_party/WebKit/public/web/WebView.h" 67 #include "third_party/WebKit/public/web/WebView.h"
76 #include "v8/include/v8.h" 68 #include "v8/include/v8.h"
77 69
78 #if defined(ENABLE_PEPPER_CDMS)
79 #include "content/renderer/media/crypto/pepper_cdm_wrapper_impl.h"
80 #endif
81
82 using blink::WebCanvas; 70 using blink::WebCanvas;
83 using blink::WebMediaPlayer; 71 using blink::WebMediaPlayer;
84 using blink::WebRect; 72 using blink::WebRect;
85 using blink::WebSize; 73 using blink::WebSize;
86 using blink::WebString; 74 using blink::WebString;
87 using media::PipelineStatus; 75 using media::PipelineStatus;
88 76
89 namespace { 77 namespace {
90 78
91 // Amount of extra memory used by each player instance reported to V8. 79 // Amount of extra memory used by each player instance reported to V8.
(...skipping 18 matching lines...) Expand all
110 // 98 //
111 // A very slow speed, ie 0.00000001x, causes the machine to lock up. (It seems 99 // A very slow speed, ie 0.00000001x, causes the machine to lock up. (It seems
112 // like a busy loop). It gets unresponsive, although its not completely dead. 100 // like a busy loop). It gets unresponsive, although its not completely dead.
113 // 101 //
114 // Also our timers are not very accurate (especially for ogg), which becomes 102 // Also our timers are not very accurate (especially for ogg), which becomes
115 // evident at low speeds and on Vista. Since other speeds are risky and outside 103 // evident at low speeds and on Vista. Since other speeds are risky and outside
116 // the norms, we think 1/16x to 16x is a safe and useful range for now. 104 // the norms, we think 1/16x to 16x is a safe and useful range for now.
117 const double kMinRate = 0.0625; 105 const double kMinRate = 0.0625;
118 const double kMaxRate = 16.0; 106 const double kMaxRate = 16.0;
119 107
120 // Prefix for histograms related to Encrypted Media Extensions.
121 const char* kMediaEme = "Media.EME.";
122
123 class SyncPointClientImpl : public media::VideoFrame::SyncPointClient { 108 class SyncPointClientImpl : public media::VideoFrame::SyncPointClient {
124 public: 109 public:
125 explicit SyncPointClientImpl( 110 explicit SyncPointClientImpl(
126 blink::WebGraphicsContext3D* web_graphics_context) 111 blink::WebGraphicsContext3D* web_graphics_context)
127 : web_graphics_context_(web_graphics_context) {} 112 : web_graphics_context_(web_graphics_context) {}
128 virtual ~SyncPointClientImpl() {} 113 virtual ~SyncPointClientImpl() {}
129 virtual uint32 InsertSyncPoint() OVERRIDE { 114 virtual uint32 InsertSyncPoint() OVERRIDE {
130 return web_graphics_context_->insertSyncPoint(); 115 return web_graphics_context_->insertSyncPoint();
131 } 116 }
132 virtual void WaitSyncPoint(uint32 sync_point) OVERRIDE { 117 virtual void WaitSyncPoint(uint32 sync_point) OVERRIDE {
133 web_graphics_context_->waitSyncPoint(sync_point); 118 web_graphics_context_->waitSyncPoint(sync_point);
134 } 119 }
135 120
136 private: 121 private:
137 blink::WebGraphicsContext3D* web_graphics_context_; 122 blink::WebGraphicsContext3D* web_graphics_context_;
138 }; 123 };
139 124
140 // Used for calls to decryptor_ready_cb where the result can be ignored.
141 void DoNothing(bool) {
142 }
143
144 } // namespace 125 } // namespace
145 126
146 namespace content { 127 namespace content {
147 128
148 class BufferedDataSourceHostImpl; 129 class BufferedDataSourceHostImpl;
149 130
150 #define COMPILE_ASSERT_MATCHING_ENUM(name) \ 131 #define COMPILE_ASSERT_MATCHING_ENUM(name) \
151 COMPILE_ASSERT(static_cast<int>(WebMediaPlayer::CORSMode ## name) == \ 132 COMPILE_ASSERT(static_cast<int>(WebMediaPlayer::CORSMode ## name) == \
152 static_cast<int>(BufferedResourceLoader::k ## name), \ 133 static_cast<int>(BufferedResourceLoader::k ## name), \
153 mismatching_enums) 134 mismatching_enums)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 chunk_demuxer_(NULL), 181 chunk_demuxer_(NULL),
201 // Threaded compositing isn't enabled universally yet. 182 // Threaded compositing isn't enabled universally yet.
202 compositor_task_runner_( 183 compositor_task_runner_(
203 RenderThreadImpl::current()->compositor_message_loop_proxy() 184 RenderThreadImpl::current()->compositor_message_loop_proxy()
204 ? RenderThreadImpl::current()->compositor_message_loop_proxy() 185 ? RenderThreadImpl::current()->compositor_message_loop_proxy()
205 : base::MessageLoopProxy::current()), 186 : base::MessageLoopProxy::current()),
206 compositor_(new VideoFrameCompositor( 187 compositor_(new VideoFrameCompositor(
207 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNaturalSizeChanged), 188 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNaturalSizeChanged),
208 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged))), 189 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged))),
209 text_track_index_(0), 190 text_track_index_(0),
210 web_cdm_(NULL) { 191 encrypted_media_support_(EncryptedMediaPlayerSupport::Create(client)) {
192 DCHECK(encrypted_media_support_);
193
211 media_log_->AddEvent( 194 media_log_->AddEvent(
212 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); 195 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
213 196
214 // |gpu_factories_| requires that its entry points be called on its 197 // |gpu_factories_| requires that its entry points be called on its
215 // |GetTaskRunner()|. Since |pipeline_| will own decoders created from the 198 // |GetTaskRunner()|. Since |pipeline_| will own decoders created from the
216 // factories, require that their message loops are identical. 199 // factories, require that their message loops are identical.
217 DCHECK(!gpu_factories_ || (gpu_factories_->GetTaskRunner() == media_loop_)); 200 DCHECK(!gpu_factories_ || (gpu_factories_->GetTaskRunner() == media_loop_));
218 201
219 // Let V8 know we started new thread if we did not do it yet. 202 // Let V8 know we started new thread if we did not do it yet.
220 // Made separate task to avoid deletion of player currently being created. 203 // Made separate task to avoid deletion of player currently being created.
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 false); 646 false);
664 647
665 web_graphics_context->deleteTexture(source_texture); 648 web_graphics_context->deleteTexture(source_texture);
666 web_graphics_context->flush(); 649 web_graphics_context->flush();
667 650
668 SyncPointClientImpl client(web_graphics_context); 651 SyncPointClientImpl client(web_graphics_context);
669 video_frame->UpdateReleaseSyncPoint(&client); 652 video_frame->UpdateReleaseSyncPoint(&client);
670 return true; 653 return true;
671 } 654 }
672 655
673 // Helper functions to report media EME related stats to UMA. They follow the
674 // convention of more commonly used macros UMA_HISTOGRAM_ENUMERATION and
675 // UMA_HISTOGRAM_COUNTS. The reason that we cannot use those macros directly is
676 // that UMA_* macros require the names to be constant throughout the process'
677 // lifetime.
678 static void EmeUMAHistogramEnumeration(const std::string& key_system,
679 const std::string& method,
680 int sample,
681 int boundary_value) {
682 base::LinearHistogram::FactoryGet(
683 kMediaEme + KeySystemNameForUMA(key_system) + "." + method,
684 1, boundary_value, boundary_value + 1,
685 base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
686 }
687
688 static void EmeUMAHistogramCounts(const std::string& key_system,
689 const std::string& method,
690 int sample) {
691 // Use the same parameters as UMA_HISTOGRAM_COUNTS.
692 base::Histogram::FactoryGet(
693 kMediaEme + KeySystemNameForUMA(key_system) + "." + method,
694 1, 1000000, 50, base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
695 }
696
697 // Helper enum for reporting generateKeyRequest/addKey histograms.
698 enum MediaKeyException {
699 kUnknownResultId,
700 kSuccess,
701 kKeySystemNotSupported,
702 kInvalidPlayerState,
703 kMaxMediaKeyException
704 };
705
706 static MediaKeyException MediaKeyExceptionForUMA(
707 WebMediaPlayer::MediaKeyException e) {
708 switch (e) {
709 case WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported:
710 return kKeySystemNotSupported;
711 case WebMediaPlayer::MediaKeyExceptionInvalidPlayerState:
712 return kInvalidPlayerState;
713 case WebMediaPlayer::MediaKeyExceptionNoError:
714 return kSuccess;
715 default:
716 return kUnknownResultId;
717 }
718 }
719
720 // Helper for converting |key_system| name and exception |e| to a pair of enum
721 // values from above, for reporting to UMA.
722 static void ReportMediaKeyExceptionToUMA(const std::string& method,
723 const std::string& key_system,
724 WebMediaPlayer::MediaKeyException e) {
725 MediaKeyException result_id = MediaKeyExceptionForUMA(e);
726 DCHECK_NE(result_id, kUnknownResultId) << e;
727 EmeUMAHistogramEnumeration(
728 key_system, method, result_id, kMaxMediaKeyException);
729 }
730
731 // Convert a WebString to ASCII, falling back on an empty string in the case
732 // of a non-ASCII string.
733 static std::string ToASCIIOrEmpty(const blink::WebString& string) {
734 return base::IsStringASCII(string) ? base::UTF16ToASCII(string)
735 : std::string();
736 }
737
738 WebMediaPlayer::MediaKeyException 656 WebMediaPlayer::MediaKeyException
739 WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system, 657 WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system,
740 const unsigned char* init_data, 658 const unsigned char* init_data,
741 unsigned init_data_length) { 659 unsigned init_data_length) {
742 DVLOG(1) << "generateKeyRequest: " << base::string16(key_system) << ": "
743 << std::string(reinterpret_cast<const char*>(init_data),
744 static_cast<size_t>(init_data_length));
745
746 std::string ascii_key_system =
747 GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
748
749 WebMediaPlayer::MediaKeyException e =
750 GenerateKeyRequestInternal(ascii_key_system, init_data, init_data_length);
751 ReportMediaKeyExceptionToUMA("generateKeyRequest", ascii_key_system, e);
752 return e;
753 }
754
755 // Guess the type of |init_data|. This is only used to handle some corner cases
756 // so we keep it as simple as possible without breaking major use cases.
757 static std::string GuessInitDataType(const unsigned char* init_data,
758 unsigned init_data_length) {
759 // Most WebM files use KeyId of 16 bytes. MP4 init data are always >16 bytes.
760 if (init_data_length == 16)
761 return "video/webm";
762
763 return "video/mp4";
764 }
765
766 WebMediaPlayer::MediaKeyException
767 WebMediaPlayerImpl::GenerateKeyRequestInternal(const std::string& key_system,
768 const unsigned char* init_data,
769 unsigned init_data_length) {
770 DCHECK(main_loop_->BelongsToCurrentThread()); 660 DCHECK(main_loop_->BelongsToCurrentThread());
771 661
772 if (!IsConcreteSupportedKeySystem(key_system)) 662 return encrypted_media_support_->GenerateKeyRequest(
773 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; 663 frame_, key_system, init_data, init_data_length);
774
775 // We do not support run-time switching between key systems for now.
776 if (current_key_system_.empty()) {
777 if (!proxy_decryptor_) {
778 proxy_decryptor_.reset(new ProxyDecryptor(
779 #if defined(ENABLE_PEPPER_CDMS)
780 // Create() must be called synchronously as |frame_| may not be
781 // valid afterwards.
782 base::Bind(&PepperCdmWrapperImpl::Create, frame_),
783 #elif defined(ENABLE_BROWSER_CDMS)
784 #error Browser side CDM in WMPI for prefixed EME API not supported yet.
785 #endif
786 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyAdded),
787 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyError),
788 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyMessage)));
789 }
790
791 GURL security_origin(frame_->document().securityOrigin().toString());
792 if (!proxy_decryptor_->InitializeCDM(key_system, security_origin))
793 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
794
795 if (proxy_decryptor_ && !decryptor_ready_cb_.is_null()) {
796 base::ResetAndReturn(&decryptor_ready_cb_)
797 .Run(proxy_decryptor_->GetDecryptor(), base::Bind(DoNothing));
798 }
799
800 current_key_system_ = key_system;
801 } else if (key_system != current_key_system_) {
802 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
803 }
804
805 std::string init_data_type = init_data_type_;
806 if (init_data_type.empty())
807 init_data_type = GuessInitDataType(init_data, init_data_length);
808
809 // TODO(xhwang): We assume all streams are from the same container (thus have
810 // the same "type") for now. In the future, the "type" should be passed down
811 // from the application.
812 if (!proxy_decryptor_->GenerateKeyRequest(
813 init_data_type, init_data, init_data_length)) {
814 current_key_system_.clear();
815 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
816 }
817
818 return WebMediaPlayer::MediaKeyExceptionNoError;
819 } 664 }
820 665
821 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( 666 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey(
822 const WebString& key_system, 667 const WebString& key_system,
823 const unsigned char* key, 668 const unsigned char* key,
824 unsigned key_length, 669 unsigned key_length,
825 const unsigned char* init_data, 670 const unsigned char* init_data,
826 unsigned init_data_length, 671 unsigned init_data_length,
827 const WebString& session_id) { 672 const WebString& session_id) {
828 DVLOG(1) << "addKey: " << base::string16(key_system) << ": " 673 DCHECK(main_loop_->BelongsToCurrentThread());
829 << std::string(reinterpret_cast<const char*>(key),
830 static_cast<size_t>(key_length)) << ", "
831 << std::string(reinterpret_cast<const char*>(init_data),
832 static_cast<size_t>(init_data_length)) << " ["
833 << base::string16(session_id) << "]";
834 674
835 std::string ascii_key_system = 675 return encrypted_media_support_->AddKey(
836 GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system)); 676 key_system, key, key_length, init_data, init_data_length, session_id);
837 std::string ascii_session_id = ToASCIIOrEmpty(session_id);
838
839 WebMediaPlayer::MediaKeyException e = AddKeyInternal(ascii_key_system,
840 key,
841 key_length,
842 init_data,
843 init_data_length,
844 ascii_session_id);
845 ReportMediaKeyExceptionToUMA("addKey", ascii_key_system, e);
846 return e;
847 }
848
849 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::AddKeyInternal(
850 const std::string& key_system,
851 const unsigned char* key,
852 unsigned key_length,
853 const unsigned char* init_data,
854 unsigned init_data_length,
855 const std::string& session_id) {
856 DCHECK(key);
857 DCHECK_GT(key_length, 0u);
858
859 if (!IsConcreteSupportedKeySystem(key_system))
860 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
861
862 if (current_key_system_.empty() || key_system != current_key_system_)
863 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
864
865 proxy_decryptor_->AddKey(
866 key, key_length, init_data, init_data_length, session_id);
867 return WebMediaPlayer::MediaKeyExceptionNoError;
868 } 677 }
869 678
870 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest( 679 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest(
871 const WebString& key_system, 680 const WebString& key_system,
872 const WebString& session_id) { 681 const WebString& session_id) {
873 DVLOG(1) << "cancelKeyRequest: " << base::string16(key_system) << ": " 682 DCHECK(main_loop_->BelongsToCurrentThread());
874 << " [" << base::string16(session_id) << "]";
875 683
876 std::string ascii_key_system = 684 return encrypted_media_support_->CancelKeyRequest(key_system, session_id);
877 GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
878 std::string ascii_session_id = ToASCIIOrEmpty(session_id);
879
880 WebMediaPlayer::MediaKeyException e =
881 CancelKeyRequestInternal(ascii_key_system, ascii_session_id);
882 ReportMediaKeyExceptionToUMA("cancelKeyRequest", ascii_key_system, e);
883 return e;
884 }
885
886 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::CancelKeyRequestInternal(
887 const std::string& key_system,
888 const std::string& session_id) {
889 if (!IsConcreteSupportedKeySystem(key_system))
890 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
891
892 if (current_key_system_.empty() || key_system != current_key_system_)
893 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
894
895 proxy_decryptor_->CancelKeyRequest(session_id);
896 return WebMediaPlayer::MediaKeyExceptionNoError;
897 } 685 }
898 686
899 void WebMediaPlayerImpl::setContentDecryptionModule( 687 void WebMediaPlayerImpl::setContentDecryptionModule(
900 blink::WebContentDecryptionModule* cdm) { 688 blink::WebContentDecryptionModule* cdm) {
901 DCHECK(main_loop_->BelongsToCurrentThread()); 689 DCHECK(main_loop_->BelongsToCurrentThread());
902 690
903 // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324 691 encrypted_media_support_->SetContentDecryptionModule(cdm);
904 if (!cdm)
905 return;
906
907 web_cdm_ = ToWebContentDecryptionModuleImpl(cdm);
908
909 if (web_cdm_ && !decryptor_ready_cb_.is_null())
910 base::ResetAndReturn(&decryptor_ready_cb_)
911 .Run(web_cdm_->GetDecryptor(), base::Bind(DoNothing));
912 } 692 }
913 693
914 void WebMediaPlayerImpl::setContentDecryptionModule( 694 void WebMediaPlayerImpl::setContentDecryptionModule(
915 blink::WebContentDecryptionModule* cdm, 695 blink::WebContentDecryptionModule* cdm,
916 blink::WebContentDecryptionModuleResult result) { 696 blink::WebContentDecryptionModuleResult result) {
917 DCHECK(main_loop_->BelongsToCurrentThread()); 697 DCHECK(main_loop_->BelongsToCurrentThread());
918 698
919 // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324 699 encrypted_media_support_->SetContentDecryptionModule(cdm, result);
920 if (!cdm) {
921 result.completeWithError(
922 blink::WebContentDecryptionModuleExceptionNotSupportedError,
923 0,
924 "Null MediaKeys object is not supported.");
925 return;
926 }
927
928 web_cdm_ = ToWebContentDecryptionModuleImpl(cdm);
929
930 if (web_cdm_ && !decryptor_ready_cb_.is_null()) {
931 base::ResetAndReturn(&decryptor_ready_cb_)
932 .Run(web_cdm_->GetDecryptor(),
933 BIND_TO_RENDER_LOOP1(
934 &WebMediaPlayerImpl::ContentDecryptionModuleAttached, result));
935 } else {
936 // No pipeline/decoder connected, so resolve the promise. When something
937 // is connected, setting the CDM will happen in SetDecryptorReadyCB().
938 ContentDecryptionModuleAttached(result, true);
939 }
940 } 700 }
941 701
942 void WebMediaPlayerImpl::setContentDecryptionModuleSync( 702 void WebMediaPlayerImpl::setContentDecryptionModuleSync(
943 blink::WebContentDecryptionModule* cdm) { 703 blink::WebContentDecryptionModule* cdm) {
944 DCHECK(main_loop_->BelongsToCurrentThread()); 704 DCHECK(main_loop_->BelongsToCurrentThread());
945 705
946 // Used when loading media and no pipeline/decoder attached yet. 706 encrypted_media_support_->SetContentDecryptionModuleSync(cdm);
947 DCHECK(decryptor_ready_cb_.is_null());
948
949 web_cdm_ = ToWebContentDecryptionModuleImpl(cdm);
950 }
951
952 void WebMediaPlayerImpl::ContentDecryptionModuleAttached(
953 blink::WebContentDecryptionModuleResult result,
954 bool success) {
955 if (success) {
956 result.complete();
957 return;
958 }
959
960 result.completeWithError(
961 blink::WebContentDecryptionModuleExceptionNotSupportedError,
962 0,
963 "Unable to set MediaKeys object");
964 } 707 }
965 708
966 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_changed, 709 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_changed,
967 PipelineStatus status) { 710 PipelineStatus status) {
968 DVLOG(1) << __FUNCTION__ << "(" << time_changed << ", " << status << ")"; 711 DVLOG(1) << __FUNCTION__ << "(" << time_changed << ", " << status << ")";
969 DCHECK(main_loop_->BelongsToCurrentThread()); 712 DCHECK(main_loop_->BelongsToCurrentThread());
970 seeking_ = false; 713 seeking_ = false;
971 if (pending_seek_) { 714 if (pending_seek_) {
972 pending_seek_ = false; 715 pending_seek_ = false;
973 seek(pending_seek_seconds_); 716 seek(pending_seek_seconds_);
(...skipping 25 matching lines...) Expand all
999 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) { 742 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) {
1000 // Any error that occurs before reaching ReadyStateHaveMetadata should 743 // Any error that occurs before reaching ReadyStateHaveMetadata should
1001 // be considered a format error. 744 // be considered a format error.
1002 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); 745 SetNetworkState(WebMediaPlayer::NetworkStateFormatError);
1003 return; 746 return;
1004 } 747 }
1005 748
1006 SetNetworkState(PipelineErrorToNetworkState(error)); 749 SetNetworkState(PipelineErrorToNetworkState(error));
1007 750
1008 if (error == media::PIPELINE_ERROR_DECRYPT) 751 if (error == media::PIPELINE_ERROR_DECRYPT)
1009 EmeUMAHistogramCounts(current_key_system_, "DecryptError", 1); 752 encrypted_media_support_->OnPipelineDecryptError();
1010 } 753 }
1011 754
1012 void WebMediaPlayerImpl::OnPipelineMetadata( 755 void WebMediaPlayerImpl::OnPipelineMetadata(
1013 media::PipelineMetadata metadata) { 756 media::PipelineMetadata metadata) {
1014 DVLOG(1) << __FUNCTION__; 757 DVLOG(1) << __FUNCTION__;
1015 758
1016 pipeline_metadata_ = metadata; 759 pipeline_metadata_ = metadata;
1017 760
1018 UMA_HISTOGRAM_ENUMERATION("Media.VideoRotation", 761 UMA_HISTOGRAM_ENUMERATION("Media.VideoRotation",
1019 metadata.video_rotation, 762 metadata.video_rotation,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 if (should_notify_time_changed_) 797 if (should_notify_time_changed_)
1055 client_->timeChanged(); 798 client_->timeChanged();
1056 } 799 }
1057 800
1058 void WebMediaPlayerImpl::OnDemuxerOpened() { 801 void WebMediaPlayerImpl::OnDemuxerOpened() {
1059 DCHECK(main_loop_->BelongsToCurrentThread()); 802 DCHECK(main_loop_->BelongsToCurrentThread());
1060 client_->mediaSourceOpened(new WebMediaSourceImpl( 803 client_->mediaSourceOpened(new WebMediaSourceImpl(
1061 chunk_demuxer_, base::Bind(&LogMediaSourceError, media_log_))); 804 chunk_demuxer_, base::Bind(&LogMediaSourceError, media_log_)));
1062 } 805 }
1063 806
1064 void WebMediaPlayerImpl::OnKeyAdded(const std::string& session_id) {
1065 DCHECK(main_loop_->BelongsToCurrentThread());
1066 EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1);
1067 client_->keyAdded(
1068 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)),
1069 WebString::fromUTF8(session_id));
1070 }
1071
1072 void WebMediaPlayerImpl::OnNeedKey(const std::string& type,
1073 const std::vector<uint8>& init_data) {
1074 DCHECK(main_loop_->BelongsToCurrentThread());
1075
1076 // Do not fire NeedKey event if encrypted media is not enabled.
1077 if (!blink::WebRuntimeFeatures::isPrefixedEncryptedMediaEnabled() &&
1078 !blink::WebRuntimeFeatures::isEncryptedMediaEnabled()) {
1079 return;
1080 }
1081
1082 UMA_HISTOGRAM_COUNTS(kMediaEme + std::string("NeedKey"), 1);
1083
1084 DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_);
1085 if (init_data_type_.empty())
1086 init_data_type_ = type;
1087
1088 const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0];
1089 client_->keyNeeded(
1090 WebString::fromUTF8(type), init_data_ptr, init_data.size());
1091 }
1092
1093 void WebMediaPlayerImpl::OnAddTextTrack( 807 void WebMediaPlayerImpl::OnAddTextTrack(
1094 const media::TextTrackConfig& config, 808 const media::TextTrackConfig& config,
1095 const media::AddTextTrackDoneCB& done_cb) { 809 const media::AddTextTrackDoneCB& done_cb) {
1096 DCHECK(main_loop_->BelongsToCurrentThread()); 810 DCHECK(main_loop_->BelongsToCurrentThread());
1097 811
1098 const WebInbandTextTrackImpl::Kind web_kind = 812 const WebInbandTextTrackImpl::Kind web_kind =
1099 static_cast<WebInbandTextTrackImpl::Kind>(config.kind()); 813 static_cast<WebInbandTextTrackImpl::Kind>(config.kind());
1100 const blink::WebString web_label = 814 const blink::WebString web_label =
1101 blink::WebString::fromUTF8(config.label()); 815 blink::WebString::fromUTF8(config.label());
1102 const blink::WebString web_language = 816 const blink::WebString web_language =
1103 blink::WebString::fromUTF8(config.language()); 817 blink::WebString::fromUTF8(config.language());
1104 const blink::WebString web_id = 818 const blink::WebString web_id =
1105 blink::WebString::fromUTF8(config.id()); 819 blink::WebString::fromUTF8(config.id());
1106 820
1107 scoped_ptr<WebInbandTextTrackImpl> web_inband_text_track( 821 scoped_ptr<WebInbandTextTrackImpl> web_inband_text_track(
1108 new WebInbandTextTrackImpl(web_kind, web_label, web_language, web_id, 822 new WebInbandTextTrackImpl(web_kind, web_label, web_language, web_id,
1109 text_track_index_++)); 823 text_track_index_++));
1110 824
1111 scoped_ptr<media::TextTrack> text_track( 825 scoped_ptr<media::TextTrack> text_track(
1112 new TextTrackImpl(main_loop_, client_, web_inband_text_track.Pass())); 826 new TextTrackImpl(main_loop_, client_, web_inband_text_track.Pass()));
1113 827
1114 done_cb.Run(text_track.Pass()); 828 done_cb.Run(text_track.Pass());
1115 } 829 }
1116 830
1117 void WebMediaPlayerImpl::OnKeyError(const std::string& session_id,
1118 media::MediaKeys::KeyError error_code,
1119 uint32 system_code) {
1120 DCHECK(main_loop_->BelongsToCurrentThread());
1121
1122 EmeUMAHistogramEnumeration(current_key_system_, "KeyError",
1123 error_code, media::MediaKeys::kMaxKeyError);
1124
1125 unsigned short short_system_code = 0;
1126 if (system_code > std::numeric_limits<unsigned short>::max()) {
1127 LOG(WARNING) << "system_code exceeds unsigned short limit.";
1128 short_system_code = std::numeric_limits<unsigned short>::max();
1129 } else {
1130 short_system_code = static_cast<unsigned short>(system_code);
1131 }
1132
1133 client_->keyError(
1134 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)),
1135 WebString::fromUTF8(session_id),
1136 static_cast<blink::WebMediaPlayerClient::MediaKeyErrorCode>(error_code),
1137 short_system_code);
1138 }
1139
1140 void WebMediaPlayerImpl::OnKeyMessage(const std::string& session_id,
1141 const std::vector<uint8>& message,
1142 const GURL& destination_url) {
1143 DCHECK(main_loop_->BelongsToCurrentThread());
1144
1145 DCHECK(destination_url.is_empty() || destination_url.is_valid());
1146
1147 client_->keyMessage(
1148 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)),
1149 WebString::fromUTF8(session_id),
1150 message.empty() ? NULL : &message[0],
1151 message.size(),
1152 destination_url);
1153 }
1154
1155 void WebMediaPlayerImpl::DataSourceInitialized(bool success) { 831 void WebMediaPlayerImpl::DataSourceInitialized(bool success) {
1156 DCHECK(main_loop_->BelongsToCurrentThread()); 832 DCHECK(main_loop_->BelongsToCurrentThread());
1157 833
1158 if (!success) { 834 if (!success) {
1159 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); 835 SetNetworkState(WebMediaPlayer::NetworkStateFormatError);
1160 return; 836 return;
1161 } 837 }
1162 838
1163 StartPipeline(); 839 StartPipeline();
1164 } 840 }
1165 841
1166 void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { 842 void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) {
1167 if (!is_downloading && network_state_ == WebMediaPlayer::NetworkStateLoading) 843 if (!is_downloading && network_state_ == WebMediaPlayer::NetworkStateLoading)
1168 SetNetworkState(WebMediaPlayer::NetworkStateIdle); 844 SetNetworkState(WebMediaPlayer::NetworkStateIdle);
1169 else if (is_downloading && network_state_ == WebMediaPlayer::NetworkStateIdle) 845 else if (is_downloading && network_state_ == WebMediaPlayer::NetworkStateIdle)
1170 SetNetworkState(WebMediaPlayer::NetworkStateLoading); 846 SetNetworkState(WebMediaPlayer::NetworkStateLoading);
1171 media_log_->AddEvent( 847 media_log_->AddEvent(
1172 media_log_->CreateBooleanEvent( 848 media_log_->CreateBooleanEvent(
1173 media::MediaLogEvent::NETWORK_ACTIVITY_SET, 849 media::MediaLogEvent::NETWORK_ACTIVITY_SET,
1174 "is_downloading_data", is_downloading)); 850 "is_downloading_data", is_downloading));
1175 } 851 }
1176 852
1177 // TODO(xhwang): Move this to a factory class so that we can create different 853 // TODO(xhwang): Move this to a factory class so that we can create different
1178 // renderers. 854 // renderers.
1179 scoped_ptr<media::Renderer> WebMediaPlayerImpl::CreateRenderer() { 855 scoped_ptr<media::Renderer> WebMediaPlayerImpl::CreateRenderer() {
1180 media::SetDecryptorReadyCB set_decryptor_ready_cb = 856 media::SetDecryptorReadyCB set_decryptor_ready_cb =
1181 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::SetDecryptorReadyCB); 857 encrypted_media_support_->CreateSetDecryptorReadyCB();
1182 858
1183 // Create our audio decoders and renderer. 859 // Create our audio decoders and renderer.
1184 ScopedVector<media::AudioDecoder> audio_decoders; 860 ScopedVector<media::AudioDecoder> audio_decoders;
1185 861
1186 media::LogCB log_cb = base::Bind(&LogMediaSourceError, media_log_); 862 media::LogCB log_cb = base::Bind(&LogMediaSourceError, media_log_);
1187 audio_decoders.push_back(new media::FFmpegAudioDecoder(media_loop_, log_cb)); 863 audio_decoders.push_back(new media::FFmpegAudioDecoder(media_loop_, log_cb));
1188 audio_decoders.push_back(new media::OpusAudioDecoder(media_loop_)); 864 audio_decoders.push_back(new media::OpusAudioDecoder(media_loop_));
1189 865
1190 scoped_ptr<media::AudioRenderer> audio_renderer(new media::AudioRendererImpl( 866 scoped_ptr<media::AudioRenderer> audio_renderer(new media::AudioRendererImpl(
1191 media_loop_, 867 media_loop_,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 902
1227 void WebMediaPlayerImpl::StartPipeline() { 903 void WebMediaPlayerImpl::StartPipeline() {
1228 DCHECK(main_loop_->BelongsToCurrentThread()); 904 DCHECK(main_loop_->BelongsToCurrentThread());
1229 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 905 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
1230 906
1231 // Keep track if this is a MSE or non-MSE playback. 907 // Keep track if this is a MSE or non-MSE playback.
1232 UMA_HISTOGRAM_BOOLEAN("Media.MSE.Playback", 908 UMA_HISTOGRAM_BOOLEAN("Media.MSE.Playback",
1233 (load_type_ == LoadTypeMediaSource)); 909 (load_type_ == LoadTypeMediaSource));
1234 910
1235 media::LogCB mse_log_cb; 911 media::LogCB mse_log_cb;
912 media::Demuxer::NeedKeyCB need_key_cb =
913 encrypted_media_support_->CreateNeedKeyCB();
1236 914
1237 // Figure out which demuxer to use. 915 // Figure out which demuxer to use.
1238 if (load_type_ != LoadTypeMediaSource) { 916 if (load_type_ != LoadTypeMediaSource) {
1239 DCHECK(!chunk_demuxer_); 917 DCHECK(!chunk_demuxer_);
1240 DCHECK(data_source_); 918 DCHECK(data_source_);
1241 919
1242 demuxer_.reset(new media::FFmpegDemuxer( 920 demuxer_.reset(new media::FFmpegDemuxer(
1243 media_loop_, data_source_.get(), 921 media_loop_, data_source_.get(),
1244 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNeedKey), 922 need_key_cb,
1245 media_log_)); 923 media_log_));
1246 } else { 924 } else {
1247 DCHECK(!chunk_demuxer_); 925 DCHECK(!chunk_demuxer_);
1248 DCHECK(!data_source_); 926 DCHECK(!data_source_);
1249 927
1250 mse_log_cb = base::Bind(&LogMediaSourceError, media_log_); 928 mse_log_cb = base::Bind(&LogMediaSourceError, media_log_);
1251 929
1252 chunk_demuxer_ = new media::ChunkDemuxer( 930 chunk_demuxer_ = new media::ChunkDemuxer(
1253 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened), 931 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened),
1254 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNeedKey), 932 need_key_cb,
1255 mse_log_cb, 933 mse_log_cb,
1256 true); 934 true);
1257 demuxer_.reset(chunk_demuxer_); 935 demuxer_.reset(chunk_demuxer_);
1258 } 936 }
1259 937
1260 scoped_ptr<media::FilterCollection> filter_collection( 938 scoped_ptr<media::FilterCollection> filter_collection(
1261 new media::FilterCollection()); 939 new media::FilterCollection());
1262 filter_collection->SetDemuxer(demuxer_.get()); 940 filter_collection->SetDemuxer(demuxer_.get());
1263 filter_collection->SetRenderer(CreateRenderer()); 941 filter_collection->SetRenderer(CreateRenderer());
1264 942
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 1035
1358 void WebMediaPlayerImpl::FrameReady( 1036 void WebMediaPlayerImpl::FrameReady(
1359 const scoped_refptr<media::VideoFrame>& frame) { 1037 const scoped_refptr<media::VideoFrame>& frame) {
1360 compositor_task_runner_->PostTask( 1038 compositor_task_runner_->PostTask(
1361 FROM_HERE, 1039 FROM_HERE,
1362 base::Bind(&VideoFrameCompositor::UpdateCurrentFrame, 1040 base::Bind(&VideoFrameCompositor::UpdateCurrentFrame,
1363 base::Unretained(compositor_), 1041 base::Unretained(compositor_),
1364 frame)); 1042 frame));
1365 } 1043 }
1366 1044
1367 void WebMediaPlayerImpl::SetDecryptorReadyCB(
1368 const media::DecryptorReadyCB& decryptor_ready_cb) {
1369 DCHECK(main_loop_->BelongsToCurrentThread());
1370
1371 // Cancels the previous decryptor request.
1372 if (decryptor_ready_cb.is_null()) {
1373 if (!decryptor_ready_cb_.is_null()) {
1374 base::ResetAndReturn(&decryptor_ready_cb_)
1375 .Run(NULL, base::Bind(DoNothing));
1376 }
1377 return;
1378 }
1379
1380 // TODO(xhwang): Support multiple decryptor notification request (e.g. from
1381 // video and audio). The current implementation is okay for the current
1382 // media pipeline since we initialize audio and video decoders in sequence.
1383 // But WebMediaPlayerImpl should not depend on media pipeline's implementation
1384 // detail.
1385 DCHECK(decryptor_ready_cb_.is_null());
1386
1387 // Mixed use of prefixed and unprefixed EME APIs is disallowed by Blink.
1388 DCHECK(!proxy_decryptor_ || !web_cdm_);
1389
1390 if (proxy_decryptor_) {
1391 decryptor_ready_cb.Run(proxy_decryptor_->GetDecryptor(),
1392 base::Bind(DoNothing));
1393 return;
1394 }
1395
1396 if (web_cdm_) {
1397 decryptor_ready_cb.Run(web_cdm_->GetDecryptor(), base::Bind(DoNothing));
1398 return;
1399 }
1400
1401 decryptor_ready_cb_ = decryptor_ready_cb;
1402 }
1403
1404 static void GetCurrentFrameAndSignal( 1045 static void GetCurrentFrameAndSignal(
1405 VideoFrameCompositor* compositor, 1046 VideoFrameCompositor* compositor,
1406 scoped_refptr<media::VideoFrame>* video_frame_out, 1047 scoped_refptr<media::VideoFrame>* video_frame_out,
1407 base::WaitableEvent* event) { 1048 base::WaitableEvent* event) {
1408 TRACE_EVENT0("media", "GetCurrentFrameAndSignal"); 1049 TRACE_EVENT0("media", "GetCurrentFrameAndSignal");
1409 *video_frame_out = compositor->GetCurrentFrame(); 1050 *video_frame_out = compositor->GetCurrentFrame();
1410 event->Signal(); 1051 event->Signal();
1411 } 1052 }
1412 1053
1413 scoped_refptr<media::VideoFrame> 1054 scoped_refptr<media::VideoFrame>
1414 WebMediaPlayerImpl::GetCurrentFrameFromCompositor() { 1055 WebMediaPlayerImpl::GetCurrentFrameFromCompositor() {
1415 TRACE_EVENT0("media", "WebMediaPlayerImpl::GetCurrentFrameFromCompositor"); 1056 TRACE_EVENT0("media", "WebMediaPlayerImpl::GetCurrentFrameFromCompositor");
1416 if (compositor_task_runner_->BelongsToCurrentThread()) 1057 if (compositor_task_runner_->BelongsToCurrentThread())
1417 return compositor_->GetCurrentFrame(); 1058 return compositor_->GetCurrentFrame();
1418 1059
1419 // Use a posted task and waitable event instead of a lock otherwise 1060 // Use a posted task and waitable event instead of a lock otherwise
1420 // WebGL/Canvas can see different content than what the compositor is seeing. 1061 // WebGL/Canvas can see different content than what the compositor is seeing.
1421 scoped_refptr<media::VideoFrame> video_frame; 1062 scoped_refptr<media::VideoFrame> video_frame;
1422 base::WaitableEvent event(false, false); 1063 base::WaitableEvent event(false, false);
1423 compositor_task_runner_->PostTask(FROM_HERE, 1064 compositor_task_runner_->PostTask(FROM_HERE,
1424 base::Bind(&GetCurrentFrameAndSignal, 1065 base::Bind(&GetCurrentFrameAndSignal,
1425 base::Unretained(compositor_), 1066 base::Unretained(compositor_),
1426 &video_frame, 1067 &video_frame,
1427 &event)); 1068 &event));
1428 event.Wait(); 1069 event.Wait();
1429 return video_frame; 1070 return video_frame;
1430 } 1071 }
1431 1072
1432 } // namespace content 1073 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webmediaplayer_impl.h ('k') | content/renderer/media/webmediaplayer_params.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698