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

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

Issue 15993018: Reland: Use a shared thread for media operations (round 3). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix stop race Created 7 years, 6 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 "webkit/renderer/media/webmediaplayer_impl.h" 5 #include "webkit/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>
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 123
124 WebMediaPlayerImpl::WebMediaPlayerImpl( 124 WebMediaPlayerImpl::WebMediaPlayerImpl(
125 WebKit::WebFrame* frame, 125 WebKit::WebFrame* frame,
126 WebKit::WebMediaPlayerClient* client, 126 WebKit::WebMediaPlayerClient* client,
127 base::WeakPtr<WebMediaPlayerDelegate> delegate, 127 base::WeakPtr<WebMediaPlayerDelegate> delegate,
128 const WebMediaPlayerParams& params) 128 const WebMediaPlayerParams& params)
129 : frame_(frame), 129 : frame_(frame),
130 network_state_(WebMediaPlayer::NetworkStateEmpty), 130 network_state_(WebMediaPlayer::NetworkStateEmpty),
131 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), 131 ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
132 main_loop_(base::MessageLoopProxy::current()), 132 main_loop_(base::MessageLoopProxy::current()),
133 media_thread_("MediaPipeline"), 133 media_loop_(params.message_loop_proxy()),
134 paused_(true), 134 paused_(true),
135 seeking_(false), 135 seeking_(false),
136 playback_rate_(0.0f), 136 playback_rate_(0.0f),
137 pending_seek_(false), 137 pending_seek_(false),
138 pending_seek_seconds_(0.0f), 138 pending_seek_seconds_(0.0f),
139 client_(client), 139 client_(client),
140 delegate_(delegate), 140 delegate_(delegate),
141 media_log_(params.media_log()), 141 media_log_(params.media_log()),
142 accelerated_compositing_reported_(false), 142 accelerated_compositing_reported_(false),
143 incremented_externally_allocated_memory_(false), 143 incremented_externally_allocated_memory_(false),
144 gpu_factories_(params.gpu_factories()), 144 gpu_factories_(params.gpu_factories()),
145 is_local_source_(false), 145 is_local_source_(false),
146 supports_save_(true), 146 supports_save_(true),
147 starting_(false), 147 starting_(false),
148 chunk_demuxer_(NULL), 148 chunk_demuxer_(NULL),
149 pending_repaint_(false), 149 pending_repaint_(false),
150 pending_size_change_(false), 150 pending_size_change_(false),
151 video_frame_provider_client_(NULL), 151 video_frame_provider_client_(NULL),
152 text_track_index_(0) { 152 text_track_index_(0) {
153 media_log_->AddEvent( 153 media_log_->AddEvent(
154 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); 154 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
155 155
156 CHECK(media_thread_.Start()); 156 pipeline_.reset(new media::Pipeline(media_loop_, media_log_));
157 pipeline_.reset(new media::Pipeline(media_thread_.message_loop_proxy(),
158 media_log_.get()));
159 157
160 // Let V8 know we started new thread if we did not do it yet. 158 // Let V8 know we started new thread if we did not do it yet.
161 // Made separate task to avoid deletion of player currently being created. 159 // Made separate task to avoid deletion of player currently being created.
162 // Also, delaying GC until after player starts gets rid of starting lag -- 160 // Also, delaying GC until after player starts gets rid of starting lag --
163 // collection happens in parallel with playing. 161 // collection happens in parallel with playing.
164 // 162 //
165 // TODO(enal): remove when we get rid of per-audio-stream thread. 163 // TODO(enal): remove when we get rid of per-audio-stream thread.
166 main_loop_->PostTask( 164 main_loop_->PostTask(
167 FROM_HERE, 165 FROM_HERE,
168 base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory, 166 base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory,
169 AsWeakPtr())); 167 AsWeakPtr()));
170 168
171 // Also we want to be notified of |main_loop_| destruction. 169 // Also we want to be notified of |main_loop_| destruction.
172 base::MessageLoop::current()->AddDestructionObserver(this); 170 base::MessageLoop::current()->AddDestructionObserver(this);
173 171
174 if (WebKit::WebRuntimeFeatures::isLegacyEncryptedMediaEnabled()) { 172 if (WebKit::WebRuntimeFeatures::isLegacyEncryptedMediaEnabled()) {
175 decryptor_.reset(new ProxyDecryptor( 173 decryptor_.reset(new ProxyDecryptor(
176 client, 174 client,
177 frame, 175 frame,
178 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyAdded), 176 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyAdded),
179 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyError), 177 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyError),
180 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyMessage), 178 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyMessage),
181 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNeedKey))); 179 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNeedKey)));
182 } 180 }
183 181
184 // Use the null sink if no sink was provided. 182 // Use the null sink if no sink was provided.
185 audio_source_provider_ = new WebAudioSourceProviderImpl( 183 audio_source_provider_ = new WebAudioSourceProviderImpl(
186 params.audio_renderer_sink().get() 184 params.audio_renderer_sink().get()
187 ? params.audio_renderer_sink() 185 ? params.audio_renderer_sink()
188 : new media::NullAudioSink(media_thread_.message_loop_proxy())); 186 : new media::NullAudioSink(media_loop_));
189 } 187 }
190 188
191 WebMediaPlayerImpl::~WebMediaPlayerImpl() { 189 WebMediaPlayerImpl::~WebMediaPlayerImpl() {
192 SetVideoFrameProviderClient(NULL); 190 SetVideoFrameProviderClient(NULL);
193 GetClient()->setWebLayer(NULL); 191 GetClient()->setWebLayer(NULL);
194 192
195 DCHECK(main_loop_->BelongsToCurrentThread()); 193 DCHECK(main_loop_->BelongsToCurrentThread());
196 media_log_->AddEvent( 194 media_log_->AddEvent(
197 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); 195 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
198 196
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 void WebMediaPlayerImpl::StartPipeline(WebKit::WebMediaSource* media_source) { 1049 void WebMediaPlayerImpl::StartPipeline(WebKit::WebMediaSource* media_source) {
1052 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 1050 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
1053 1051
1054 1052
1055 // Figure out which demuxer to use. 1053 // Figure out which demuxer to use.
1056 if (!media_source) { 1054 if (!media_source) {
1057 DCHECK(!chunk_demuxer_); 1055 DCHECK(!chunk_demuxer_);
1058 DCHECK(data_source_); 1056 DCHECK(data_source_);
1059 1057
1060 demuxer_.reset(new media::FFmpegDemuxer( 1058 demuxer_.reset(new media::FFmpegDemuxer(
1061 media_thread_.message_loop_proxy(), data_source_.get(), 1059 media_loop_, data_source_.get(),
1062 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""))); 1060 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", "")));
1063 } else { 1061 } else {
1064 DCHECK(!chunk_demuxer_); 1062 DCHECK(!chunk_demuxer_);
1065 DCHECK(!data_source_); 1063 DCHECK(!data_source_);
1066 1064
1067 scoped_ptr<WebKit::WebMediaSource> ms(media_source); 1065 scoped_ptr<WebKit::WebMediaSource> ms(media_source);
1068 chunk_demuxer_ = new media::ChunkDemuxer( 1066 chunk_demuxer_ = new media::ChunkDemuxer(
1069 BIND_TO_RENDER_LOOP_1(&WebMediaPlayerImpl::OnDemuxerOpened, 1067 BIND_TO_RENDER_LOOP_1(&WebMediaPlayerImpl::OnDemuxerOpened,
1070 base::Passed(&ms)), 1068 base::Passed(&ms)),
1071 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""), 1069 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""),
(...skipping 12 matching lines...) Expand all
1084 1082
1085 // Figure out if EME is enabled. 1083 // Figure out if EME is enabled.
1086 media::SetDecryptorReadyCB set_decryptor_ready_cb; 1084 media::SetDecryptorReadyCB set_decryptor_ready_cb;
1087 if (decryptor_) { 1085 if (decryptor_) {
1088 set_decryptor_ready_cb = base::Bind(&ProxyDecryptor::SetDecryptorReadyCB, 1086 set_decryptor_ready_cb = base::Bind(&ProxyDecryptor::SetDecryptorReadyCB,
1089 base::Unretained(decryptor_.get())); 1087 base::Unretained(decryptor_.get()));
1090 } 1088 }
1091 1089
1092 // Create our audio decoders and renderer. 1090 // Create our audio decoders and renderer.
1093 ScopedVector<media::AudioDecoder> audio_decoders; 1091 ScopedVector<media::AudioDecoder> audio_decoders;
1094 audio_decoders.push_back(new media::FFmpegAudioDecoder( 1092 audio_decoders.push_back(new media::FFmpegAudioDecoder(media_loop_));
1095 media_thread_.message_loop_proxy()));
1096 if (cmd_line->HasSwitch(switches::kEnableOpusPlayback)) { 1093 if (cmd_line->HasSwitch(switches::kEnableOpusPlayback)) {
1097 audio_decoders.push_back(new media::OpusAudioDecoder( 1094 audio_decoders.push_back(new media::OpusAudioDecoder(media_loop_));
1098 media_thread_.message_loop_proxy()));
1099 } 1095 }
1100 1096
1101 scoped_ptr<media::AudioRenderer> audio_renderer( 1097 scoped_ptr<media::AudioRenderer> audio_renderer(
1102 new media::AudioRendererImpl(media_thread_.message_loop_proxy(), 1098 new media::AudioRendererImpl(media_loop_,
1103 audio_source_provider_.get(), 1099 audio_source_provider_.get(),
1104 audio_decoders.Pass(), 1100 audio_decoders.Pass(),
1105 set_decryptor_ready_cb)); 1101 set_decryptor_ready_cb));
1106 filter_collection->SetAudioRenderer(audio_renderer.Pass()); 1102 filter_collection->SetAudioRenderer(audio_renderer.Pass());
1107 1103
1108 // Create our video decoders and renderer. 1104 // Create our video decoders and renderer.
1109 ScopedVector<media::VideoDecoder> video_decoders; 1105 ScopedVector<media::VideoDecoder> video_decoders;
1110 1106
1111 if (gpu_factories_.get()) { 1107 if (gpu_factories_.get()) {
1112 video_decoders.push_back(new media::GpuVideoDecoder( 1108 video_decoders.push_back(new media::GpuVideoDecoder(
1113 media_thread_.message_loop_proxy(), gpu_factories_)); 1109 media_loop_, gpu_factories_));
1114 } 1110 }
1115 1111
1116 // TODO(phajdan.jr): Remove ifdefs when libvpx with vp9 support is released 1112 // TODO(phajdan.jr): Remove ifdefs when libvpx with vp9 support is released
1117 // (http://crbug.com/174287) . 1113 // (http://crbug.com/174287) .
1118 #if !defined(MEDIA_DISABLE_LIBVPX) 1114 #if !defined(MEDIA_DISABLE_LIBVPX)
1119 if (cmd_line->HasSwitch(switches::kEnableVp9Playback) || 1115 if (cmd_line->HasSwitch(switches::kEnableVp9Playback) ||
1120 cmd_line->HasSwitch(switches::kEnableVp8AlphaPlayback)) { 1116 cmd_line->HasSwitch(switches::kEnableVp8AlphaPlayback)) {
1121 video_decoders.push_back(new media::VpxVideoDecoder( 1117 video_decoders.push_back(new media::VpxVideoDecoder(media_loop_));
1122 media_thread_.message_loop_proxy()));
1123 } 1118 }
1124 #endif // !defined(MEDIA_DISABLE_LIBVPX) 1119 #endif // !defined(MEDIA_DISABLE_LIBVPX)
1125 1120
1126 video_decoders.push_back(new media::FFmpegVideoDecoder( 1121 video_decoders.push_back(new media::FFmpegVideoDecoder(media_loop_));
1127 media_thread_.message_loop_proxy()));
1128 1122
1129 scoped_ptr<media::VideoRenderer> video_renderer( 1123 scoped_ptr<media::VideoRenderer> video_renderer(
1130 new media::VideoRendererBase( 1124 new media::VideoRendererBase(
1131 media_thread_.message_loop_proxy(), 1125 media_loop_,
1132 video_decoders.Pass(), 1126 video_decoders.Pass(),
1133 set_decryptor_ready_cb, 1127 set_decryptor_ready_cb,
1134 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)), 1128 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)),
1135 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::SetOpaque), 1129 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::SetOpaque),
1136 true)); 1130 true));
1137 filter_collection->SetVideoRenderer(video_renderer.Pass()); 1131 filter_collection->SetVideoRenderer(video_renderer.Pass());
1138 1132
1139 // ... and we're ready to go! 1133 // ... and we're ready to go!
1140 starting_ = true; 1134 starting_ = true;
1141 pipeline_->Start( 1135 pipeline_->Start(
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 pipeline_->Stop(base::Bind( 1185 pipeline_->Stop(base::Bind(
1192 &base::WaitableEvent::Signal, base::Unretained(&waiter))); 1186 &base::WaitableEvent::Signal, base::Unretained(&waiter)));
1193 waiter.Wait(); 1187 waiter.Wait();
1194 1188
1195 // Let V8 know we are not using extra resources anymore. 1189 // Let V8 know we are not using extra resources anymore.
1196 if (incremented_externally_allocated_memory_) { 1190 if (incremented_externally_allocated_memory_) {
1197 v8::V8::AdjustAmountOfExternalAllocatedMemory(-kPlayerExtraMemory); 1191 v8::V8::AdjustAmountOfExternalAllocatedMemory(-kPlayerExtraMemory);
1198 incremented_externally_allocated_memory_ = false; 1192 incremented_externally_allocated_memory_ = false;
1199 } 1193 }
1200 1194
1201 media_thread_.Stop();
1202
1203 // Release any final references now that everything has stopped. 1195 // Release any final references now that everything has stopped.
1204 pipeline_.reset(); 1196 pipeline_.reset();
1205 demuxer_.reset(); 1197 demuxer_.reset();
1206 data_source_.reset(); 1198 data_source_.reset();
1207 } 1199 }
1208 1200
1209 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { 1201 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() {
1210 DCHECK(main_loop_->BelongsToCurrentThread()); 1202 DCHECK(main_loop_->BelongsToCurrentThread());
1211 DCHECK(client_); 1203 DCHECK(client_);
1212 return client_; 1204 return client_;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 1246
1255 if (pending_repaint_) 1247 if (pending_repaint_)
1256 return; 1248 return;
1257 1249
1258 pending_repaint_ = true; 1250 pending_repaint_ = true;
1259 main_loop_->PostTask(FROM_HERE, base::Bind( 1251 main_loop_->PostTask(FROM_HERE, base::Bind(
1260 &WebMediaPlayerImpl::Repaint, AsWeakPtr())); 1252 &WebMediaPlayerImpl::Repaint, AsWeakPtr()));
1261 } 1253 }
1262 1254
1263 } // namespace webkit_media 1255 } // namespace webkit_media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698