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

Side by Side Diff: media/base/android/media_source_player.cc

Issue 254473010: Refactor MSE implementation on Android to simplify the logic and improve the performance (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: passing an EOS access unit during config change Created 6 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 (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/base/android/media_source_player.h" 5 #include "media/base/android/media_source_player.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/android/jni_android.h" 9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h" 10 #include "base/android/jni_string.h"
(...skipping 17 matching lines...) Expand all
28 MediaPlayerManager* manager, 28 MediaPlayerManager* manager,
29 const RequestMediaResourcesCB& request_media_resources_cb, 29 const RequestMediaResourcesCB& request_media_resources_cb,
30 const ReleaseMediaResourcesCB& release_media_resources_cb, 30 const ReleaseMediaResourcesCB& release_media_resources_cb,
31 scoped_ptr<DemuxerAndroid> demuxer) 31 scoped_ptr<DemuxerAndroid> demuxer)
32 : MediaPlayerAndroid(player_id, 32 : MediaPlayerAndroid(player_id,
33 manager, 33 manager,
34 request_media_resources_cb, 34 request_media_resources_cb,
35 release_media_resources_cb), 35 release_media_resources_cb),
36 demuxer_(demuxer.Pass()), 36 demuxer_(demuxer.Pass()),
37 pending_event_(NO_EVENT_PENDING), 37 pending_event_(NO_EVENT_PENDING),
38 width_(0),
39 height_(0),
40 audio_codec_(kUnknownAudioCodec),
41 video_codec_(kUnknownVideoCodec),
42 num_channels_(0),
43 sampling_rate_(0),
44 reached_audio_eos_(false),
45 reached_video_eos_(false),
46 playing_(false), 38 playing_(false),
47 is_audio_encrypted_(false),
48 is_video_encrypted_(false),
49 volume_(-1.0),
50 clock_(&default_tick_clock_), 39 clock_(&default_tick_clock_),
51 next_video_data_is_iframe_(true),
52 doing_browser_seek_(false), 40 doing_browser_seek_(false),
53 pending_seek_(false), 41 pending_seek_(false),
54 reconfig_audio_decoder_(false),
55 reconfig_video_decoder_(false),
56 drm_bridge_(NULL), 42 drm_bridge_(NULL),
57 is_waiting_for_key_(false), 43 is_waiting_for_key_(false),
58 has_pending_audio_data_request_(false), 44 is_waiting_for_audio_decoder_(false),
59 has_pending_video_data_request_(false), 45 is_waiting_for_video_decoder_(false),
60 weak_factory_(this) { 46 weak_factory_(this) {
47 audio_decoder_job_.reset(new AudioDecoderJob(
48 base::Bind(&DemuxerAndroid::RequestDemuxerData,
49 base::Unretained(demuxer_.get()),
50 DemuxerStream::AUDIO),
51 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged,
52 weak_factory_.GetWeakPtr())));
53 video_decoder_job_.reset(new VideoDecoderJob(
54 base::Bind(&DemuxerAndroid::RequestDemuxerData,
55 base::Unretained(demuxer_.get()),
56 DemuxerStream::VIDEO),
57 base::Bind(request_media_resources_cb_, player_id),
58 base::Bind(release_media_resources_cb_, player_id),
59 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged,
60 weak_factory_.GetWeakPtr())));
61 demuxer_->Initialize(this); 61 demuxer_->Initialize(this);
62 clock_.SetMaxTime(base::TimeDelta()); 62 clock_.SetMaxTime(base::TimeDelta());
63 } 63 }
64 64
65 MediaSourcePlayer::~MediaSourcePlayer() { 65 MediaSourcePlayer::~MediaSourcePlayer() {
66 Release(); 66 Release();
67 } 67 }
68 68
69 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { 69 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) {
70 // For an empty surface, always pass it to the decoder job so that it 70 DVLOG(1) << __FUNCTION__;
71 // can detach from the current one. Otherwise, don't pass an unprotected 71 if (!video_decoder_job_->SetVideoSurface(surface.Pass()))
72 // surface if the video content requires a protected one.
73 if (!surface.IsEmpty() &&
74 IsProtectedSurfaceRequired() && !surface.is_protected()) {
75 return; 72 return;
76 } 73 // Retry video decoder creation.
77 74 RetryDecoderCreation(false, true);
78 surface_ = surface.Pass();
79 is_surface_in_use_ = true;
80
81 // If there is a pending surface change event, just wait for it to be
82 // processed.
83 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
84 return;
85
86 // Eventual processing of surface change will take care of feeding the new
87 // video decoder initially with I-frame. See b/8950387.
88 SetPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
89
90 // If seek is already pending, processing of the pending surface change
91 // event will occur in OnDemuxerSeekDone().
92 if (IsEventPending(SEEK_EVENT_PENDING))
93 return;
94
95 // If video config change is already pending, processing of the pending
96 // surface change event will occur in OnDemuxerConfigsAvailable().
97 if (reconfig_video_decoder_ && IsEventPending(CONFIG_CHANGE_EVENT_PENDING))
98 return;
99
100 // Otherwise we need to trigger pending event processing now.
101 ProcessPendingEvents();
102 } 75 }
103 76
104 void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding( 77 void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding(
105 base::TimeDelta seek_time) { 78 base::TimeDelta seek_time) {
106 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")"; 79 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")";
107 DCHECK(!IsEventPending(SEEK_EVENT_PENDING)); 80 DCHECK(!IsEventPending(SEEK_EVENT_PENDING));
108 81
109 pending_seek_ = false; 82 pending_seek_ = false;
110 83
111 clock_.SetTime(seek_time, seek_time); 84 clock_.SetTime(seek_time, seek_time);
112 85
113 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) 86 if (audio_decoder_job_->is_decoding())
114 audio_decoder_job_->StopDecode(); 87 audio_decoder_job_->StopDecode();
115 if (video_decoder_job_ && video_decoder_job_->is_decoding()) 88 if (video_decoder_job_->is_decoding())
116 video_decoder_job_->StopDecode(); 89 video_decoder_job_->StopDecode();
117 90
118 SetPendingEvent(SEEK_EVENT_PENDING); 91 SetPendingEvent(SEEK_EVENT_PENDING);
119 ProcessPendingEvents(); 92 ProcessPendingEvents();
120 } 93 }
121 94
122 void MediaSourcePlayer::BrowserSeekToCurrentTime() { 95 void MediaSourcePlayer::BrowserSeekToCurrentTime() {
123 DVLOG(1) << __FUNCTION__; 96 DVLOG(1) << __FUNCTION__;
124 97
125 DCHECK(!IsEventPending(SEEK_EVENT_PENDING)); 98 DCHECK(!IsEventPending(SEEK_EVENT_PENDING));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 // MediaDecoderCallback() is called. 130 // MediaDecoderCallback() is called.
158 playing_ = false; 131 playing_ = false;
159 start_time_ticks_ = base::TimeTicks(); 132 start_time_ticks_ = base::TimeTicks();
160 } 133 }
161 134
162 bool MediaSourcePlayer::IsPlaying() { 135 bool MediaSourcePlayer::IsPlaying() {
163 return playing_; 136 return playing_;
164 } 137 }
165 138
166 int MediaSourcePlayer::GetVideoWidth() { 139 int MediaSourcePlayer::GetVideoWidth() {
167 return width_; 140 return video_decoder_job_->width();
168 } 141 }
169 142
170 int MediaSourcePlayer::GetVideoHeight() { 143 int MediaSourcePlayer::GetVideoHeight() {
171 return height_; 144 return video_decoder_job_->height();
172 } 145 }
173 146
174 void MediaSourcePlayer::SeekTo(base::TimeDelta timestamp) { 147 void MediaSourcePlayer::SeekTo(base::TimeDelta timestamp) {
175 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")"; 148 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")";
176 149
177 if (IsEventPending(SEEK_EVENT_PENDING)) { 150 if (IsEventPending(SEEK_EVENT_PENDING)) {
178 DCHECK(doing_browser_seek_) << "SeekTo while SeekTo in progress"; 151 DCHECK(doing_browser_seek_) << "SeekTo while SeekTo in progress";
179 DCHECK(!pending_seek_) << "SeekTo while SeekTo pending browser seek"; 152 DCHECK(!pending_seek_) << "SeekTo while SeekTo pending browser seek";
180 153
181 // There is a browser seek currently in progress to obtain I-frame to feed 154 // There is a browser seek currently in progress to obtain I-frame to feed
(...skipping 12 matching lines...) Expand all
194 return clock_.Elapsed(); 167 return clock_.Elapsed();
195 } 168 }
196 169
197 base::TimeDelta MediaSourcePlayer::GetDuration() { 170 base::TimeDelta MediaSourcePlayer::GetDuration() {
198 return duration_; 171 return duration_;
199 } 172 }
200 173
201 void MediaSourcePlayer::Release() { 174 void MediaSourcePlayer::Release() {
202 DVLOG(1) << __FUNCTION__; 175 DVLOG(1) << __FUNCTION__;
203 176
204 // Allow pending seeks and config changes to survive this Release().
205 // If previously pending a prefetch done event, or a job was still decoding,
206 // then at end of Release() we need to ProcessPendingEvents() to process any
207 // seek or config change that was blocked by the prefetch or decode.
208 // TODO(qinmin/wolenetz): Maintain channel state to not double-request data
209 // or drop data received across Release()+Start(). See http://crbug.com/306314
210 // and http://crbug.com/304234.
211 bool process_pending_events = false;
212 process_pending_events = IsEventPending(PREFETCH_DONE_EVENT_PENDING) ||
213 (audio_decoder_job_ && audio_decoder_job_->is_decoding()) ||
214 (video_decoder_job_ && video_decoder_job_->is_decoding());
215
216 // Clear all the pending events except seeks and config changes.
217 pending_event_ &= (SEEK_EVENT_PENDING | CONFIG_CHANGE_EVENT_PENDING);
218 is_surface_in_use_ = false; 177 is_surface_in_use_ = false;
219 ResetAudioDecoderJob(); 178 audio_decoder_job_->ReleaseDecoderResources();
220 ResetVideoDecoderJob(); 179 video_decoder_job_->ReleaseDecoderResources();
221
222 // Prevent job re-creation attempts in OnDemuxerConfigsAvailable()
223 reconfig_audio_decoder_ = false;
224 reconfig_video_decoder_ = false;
225 180
226 // Prevent player restart, including job re-creation attempts. 181 // Prevent player restart, including job re-creation attempts.
227 playing_ = false; 182 playing_ = false;
228 183
229 decoder_starvation_callback_.Cancel(); 184 decoder_starvation_callback_.Cancel();
230 surface_ = gfx::ScopedJavaSurface();
231 if (process_pending_events) {
232 DVLOG(1) << __FUNCTION__ << " : Resuming seek or config change processing";
233 ProcessPendingEvents();
234 }
235 } 185 }
236 186
237 void MediaSourcePlayer::SetVolume(double volume) { 187 void MediaSourcePlayer::SetVolume(double volume) {
238 volume_ = volume; 188 audio_decoder_job_->SetVolume(volume);
239 SetVolumeInternal();
240 } 189 }
241 190
242 void MediaSourcePlayer::OnKeyAdded() { 191 void MediaSourcePlayer::OnKeyAdded() {
243 DVLOG(1) << __FUNCTION__; 192 DVLOG(1) << __FUNCTION__;
244 if (!is_waiting_for_key_) 193 if (!is_waiting_for_key_)
245 return; 194 return;
246 195
247 is_waiting_for_key_ = false; 196 is_waiting_for_key_ = false;
248 if (playing_) 197 if (playing_)
249 StartInternal(); 198 StartInternal();
(...skipping 23 matching lines...) Expand all
273 DVLOG(1) << __FUNCTION__; 222 DVLOG(1) << __FUNCTION__;
274 // If there are pending events, wait for them finish. 223 // If there are pending events, wait for them finish.
275 if (pending_event_ != NO_EVENT_PENDING) 224 if (pending_event_ != NO_EVENT_PENDING)
276 return; 225 return;
277 226
278 // When we start, we'll have new demuxed data coming in. This new data could 227 // When we start, we'll have new demuxed data coming in. This new data could
279 // be clear (not encrypted) or encrypted with different keys. So 228 // be clear (not encrypted) or encrypted with different keys. So
280 // |is_waiting_for_key_| condition may not be true anymore. 229 // |is_waiting_for_key_| condition may not be true anymore.
281 is_waiting_for_key_ = false; 230 is_waiting_for_key_ = false;
282 231
283 // Create decoder jobs if they are not created
284 ConfigureAudioDecoderJob();
285 ConfigureVideoDecoderJob();
286
287 // If one of the decoder job is not ready, do nothing.
288 if ((HasAudio() && !audio_decoder_job_) ||
289 (HasVideo() && !video_decoder_job_)) {
290 return;
291 }
292
293 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 232 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
294 ProcessPendingEvents(); 233 ProcessPendingEvents();
295 } 234 }
296 235
297 void MediaSourcePlayer::OnDemuxerConfigsAvailable( 236 void MediaSourcePlayer::OnDemuxerConfigsAvailable(
298 const DemuxerConfigs& configs) { 237 const DemuxerConfigs& configs) {
299 DVLOG(1) << __FUNCTION__; 238 DVLOG(1) << __FUNCTION__;
300 DCHECK(!HasAudio() && !HasVideo()); 239 DCHECK(!HasAudio() && !HasVideo());
301 duration_ = configs.duration; 240 duration_ = configs.duration;
302 clock_.SetDuration(duration_); 241 clock_.SetDuration(duration_);
303 242
304 SetDemuxerConfigs(configs, true); 243 audio_decoder_job_->SetDemuxerConfigs(configs);
305 SetDemuxerConfigs(configs, false); 244 video_decoder_job_->SetDemuxerConfigs(configs);
306 245 OnDemuxerConfigsChanged();
307 manager()->OnMediaMetadataChanged(
308 player_id(), duration_, width_, height_, true);
309 } 246 }
310 247
311 void MediaSourcePlayer::OnDemuxerDataAvailable(const DemuxerData& data) { 248 void MediaSourcePlayer::OnDemuxerDataAvailable(const DemuxerData& data) {
312 DVLOG(1) << __FUNCTION__ << "(" << data.type << ")"; 249 DVLOG(1) << __FUNCTION__ << "(" << data.type << ")";
313 DCHECK_LT(0u, data.access_units.size()); 250 DCHECK_LT(0u, data.access_units.size());
314 CHECK_GE(1u, data.demuxer_configs.size()); 251 CHECK_GE(1u, data.demuxer_configs.size());
315 252
316 if (has_pending_audio_data_request_ && data.type == DemuxerStream::AUDIO) { 253 if (data.type == DemuxerStream::AUDIO)
317 has_pending_audio_data_request_ = false;
318 ProcessPendingEvents();
319 return;
320 }
321
322 if (has_pending_video_data_request_ && data.type == DemuxerStream::VIDEO) {
323 next_video_data_is_iframe_ = false;
324 has_pending_video_data_request_ = false;
325 ProcessPendingEvents();
326 return;
327 }
328
329 if (data.type == DemuxerStream::AUDIO && audio_decoder_job_) {
330 audio_decoder_job_->OnDataReceived(data); 254 audio_decoder_job_->OnDataReceived(data);
331 } else if (data.type == DemuxerStream::VIDEO) { 255 else if (data.type == DemuxerStream::VIDEO)
332 next_video_data_is_iframe_ = false; 256 video_decoder_job_->OnDataReceived(data);
333 if (video_decoder_job_)
334 video_decoder_job_->OnDataReceived(data);
335 }
336 } 257 }
337 258
338 void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) { 259 void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) {
339 duration_ = duration; 260 duration_ = duration;
340 clock_.SetDuration(duration_); 261 clock_.SetDuration(duration_);
341 } 262 }
342 263
343 base::android::ScopedJavaLocalRef<jobject> MediaSourcePlayer::GetMediaCrypto() {
344 base::android::ScopedJavaLocalRef<jobject> media_crypto;
345 if (drm_bridge_)
346 media_crypto = drm_bridge_->GetMediaCrypto();
347 return media_crypto;
348 }
349
350 void MediaSourcePlayer::OnMediaCryptoReady() { 264 void MediaSourcePlayer::OnMediaCryptoReady() {
351 DCHECK(!drm_bridge_->GetMediaCrypto().is_null()); 265 DCHECK(!drm_bridge_->GetMediaCrypto().is_null());
352 drm_bridge_->SetMediaCryptoReadyCB(base::Closure()); 266 drm_bridge_->SetMediaCryptoReadyCB(base::Closure());
353 267
354 if (playing_) 268 // Retry decoder creation if the decoders are waiting for MediaCrypto.
355 StartInternal(); 269 RetryDecoderCreation(true, true);
356 } 270 }
357 271
358 void MediaSourcePlayer::SetCdm(MediaKeys* cdm) { 272 void MediaSourcePlayer::SetCdm(MediaKeys* cdm) {
359 // Currently we don't support DRM change during the middle of playback, even 273 // Currently we don't support DRM change during the middle of playback, even
360 // if the player is paused. 274 // if the player is paused.
361 // TODO(qinmin): support DRM change after playback has started. 275 // TODO(qinmin): support DRM change after playback has started.
362 // http://crbug.com/253792. 276 // http://crbug.com/253792.
363 if (GetCurrentTime() > base::TimeDelta()) { 277 if (GetCurrentTime() > base::TimeDelta()) {
364 VLOG(0) << "Setting DRM bridge after playback has started. " 278 VLOG(0) << "Setting DRM bridge after playback has started. "
365 << "This is not well supported!"; 279 << "This is not well supported!";
366 } 280 }
367 281
368 // Only MediaDrmBridge will be set on MediaSourcePlayer. 282 // Only MediaDrmBridge will be set on MediaSourcePlayer.
369 drm_bridge_ = static_cast<MediaDrmBridge*>(cdm); 283 drm_bridge_ = static_cast<MediaDrmBridge*>(cdm);
370 284
285 audio_decoder_job_->SetDrmBridge(drm_bridge_);
286 video_decoder_job_->SetDrmBridge(drm_bridge_);
287
371 if (drm_bridge_->GetMediaCrypto().is_null()) { 288 if (drm_bridge_->GetMediaCrypto().is_null()) {
372 drm_bridge_->SetMediaCryptoReadyCB(base::Bind( 289 drm_bridge_->SetMediaCryptoReadyCB(base::Bind(
373 &MediaSourcePlayer::OnMediaCryptoReady, weak_factory_.GetWeakPtr())); 290 &MediaSourcePlayer::OnMediaCryptoReady, weak_factory_.GetWeakPtr()));
374 return; 291 return;
375 } 292 }
376 293
377 if (playing_) 294 // If the player is previously waiting for CDM, retry decoder creation.
378 StartInternal(); 295 RetryDecoderCreation(true, true);
379 } 296 }
380 297
381 void MediaSourcePlayer::OnDemuxerSeekDone( 298 void MediaSourcePlayer::OnDemuxerSeekDone(
382 base::TimeDelta actual_browser_seek_time) { 299 base::TimeDelta actual_browser_seek_time) {
383 DVLOG(1) << __FUNCTION__; 300 DVLOG(1) << __FUNCTION__;
384 301
385 ClearPendingEvent(SEEK_EVENT_PENDING); 302 ClearPendingEvent(SEEK_EVENT_PENDING);
386 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) 303 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING))
387 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 304 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
388 305
389 next_video_data_is_iframe_ = true;
390
391 if (pending_seek_) { 306 if (pending_seek_) {
392 DVLOG(1) << __FUNCTION__ << "processing pending seek"; 307 DVLOG(1) << __FUNCTION__ << "processing pending seek";
393 DCHECK(doing_browser_seek_); 308 DCHECK(doing_browser_seek_);
394 pending_seek_ = false; 309 pending_seek_ = false;
395 SeekTo(pending_seek_time_); 310 SeekTo(pending_seek_time_);
396 return; 311 return;
397 } 312 }
398 313
399 // It is possible that a browser seek to I-frame had to seek to a buffered 314 // It is possible that a browser seek to I-frame had to seek to a buffered
400 // I-frame later than the requested one due to data removal or GC. Update 315 // I-frame later than the requested one due to data removal or GC. Update
401 // player clock to the actual seek target. 316 // player clock to the actual seek target.
402 if (doing_browser_seek_) { 317 if (doing_browser_seek_) {
403 DCHECK(actual_browser_seek_time != kNoTimestamp()); 318 DCHECK(actual_browser_seek_time != kNoTimestamp());
404 base::TimeDelta seek_time = actual_browser_seek_time; 319 base::TimeDelta seek_time = actual_browser_seek_time;
405 // A browser seek must not jump into the past. Ideally, it seeks to the 320 // A browser seek must not jump into the past. Ideally, it seeks to the
406 // requested time, but it might jump into the future. 321 // requested time, but it might jump into the future.
407 DCHECK(seek_time >= GetCurrentTime()); 322 DCHECK(seek_time >= GetCurrentTime());
408 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: " 323 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: "
409 << seek_time.InSecondsF(); 324 << seek_time.InSecondsF();
410 clock_.SetTime(seek_time, seek_time); 325 clock_.SetTime(seek_time, seek_time);
411 if (audio_decoder_job_) 326 audio_decoder_job_->SetBaseTimestamp(seek_time);
412 audio_decoder_job_->SetBaseTimestamp(seek_time);
413 } else { 327 } else {
414 DCHECK(actual_browser_seek_time == kNoTimestamp()); 328 DCHECK(actual_browser_seek_time == kNoTimestamp());
415 } 329 }
416 330
417 reached_audio_eos_ = false;
418 reached_video_eos_ = false;
419
420 base::TimeDelta current_time = GetCurrentTime(); 331 base::TimeDelta current_time = GetCurrentTime();
421 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_| 332 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_|
422 // to preroll media decoder jobs. Currently |start_presentation_timestamp_| 333 // to preroll media decoder jobs. Currently |start_presentation_timestamp_|
423 // is calculated from decoder output, while preroll relies on the access 334 // is calculated from decoder output, while preroll relies on the access
424 // unit's timestamp. There are some differences between the two. 335 // unit's timestamp. There are some differences between the two.
425 preroll_timestamp_ = current_time; 336 preroll_timestamp_ = current_time;
426 if (audio_decoder_job_) 337 if (HasAudio())
427 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); 338 audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
428 if (video_decoder_job_) 339 if (HasVideo())
429 video_decoder_job_->BeginPrerolling(preroll_timestamp_); 340 video_decoder_job_->BeginPrerolling(preroll_timestamp_);
430 341
431 if (!doing_browser_seek_) 342 if (!doing_browser_seek_)
432 manager()->OnSeekComplete(player_id(), current_time); 343 manager()->OnSeekComplete(player_id(), current_time);
433 344
434 ProcessPendingEvents(); 345 ProcessPendingEvents();
435 } 346 }
436 347
437 void MediaSourcePlayer::UpdateTimestamps( 348 void MediaSourcePlayer::UpdateTimestamps(
438 base::TimeDelta current_presentation_timestamp, 349 base::TimeDelta current_presentation_timestamp,
439 base::TimeDelta max_presentation_timestamp) { 350 base::TimeDelta max_presentation_timestamp) {
440 clock_.SetTime(current_presentation_timestamp, max_presentation_timestamp); 351 clock_.SetTime(current_presentation_timestamp, max_presentation_timestamp);
441
442 manager()->OnTimeUpdate(player_id(), GetCurrentTime()); 352 manager()->OnTimeUpdate(player_id(), GetCurrentTime());
443 } 353 }
444 354
445 void MediaSourcePlayer::ProcessPendingEvents() { 355 void MediaSourcePlayer::ProcessPendingEvents() {
446 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_; 356 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_;
447 // Wait for all the decoding jobs to finish before processing pending tasks. 357 // Wait for all the decoding jobs to finish before processing pending tasks.
448 if (video_decoder_job_ && video_decoder_job_->is_decoding()) { 358 if (video_decoder_job_->is_decoding()) {
449 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding."; 359 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding.";
450 return; 360 return;
451 } 361 }
452 362
453 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) { 363 if (audio_decoder_job_->is_decoding()) {
454 DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding."; 364 DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding.";
455 return; 365 return;
456 } 366 }
457 367
458 if (has_pending_audio_data_request_ || has_pending_video_data_request_) {
459 DVLOG(1) << __FUNCTION__ << " : has pending data request.";
460 return;
461 }
462
463 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) { 368 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
464 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending."; 369 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending.";
465 return; 370 return;
466 } 371 }
467 372
468 if (IsEventPending(SEEK_EVENT_PENDING)) { 373 if (IsEventPending(SEEK_EVENT_PENDING)) {
469 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT"; 374 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT";
470 ClearDecodingData(); 375 ClearDecodingData();
471 if (audio_decoder_job_) 376 audio_decoder_job_->SetBaseTimestamp(GetCurrentTime());
472 audio_decoder_job_->SetBaseTimestamp(GetCurrentTime());
473 demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_); 377 demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_);
474 return; 378 return;
475 } 379 }
476 380
477 start_time_ticks_ = base::TimeTicks(); 381 if (IsEventPending(DECODER_CREATION_EVENT_PENDING)) {
478 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { 382 // Don't continue if one of the decoder is not created.
479 DVLOG(1) << __FUNCTION__ << " : Handling CONFIG_CHANGE_EVENT."; 383 if (is_waiting_for_audio_decoder_ || is_waiting_for_video_decoder_)
480 DCHECK(reconfig_audio_decoder_ || reconfig_video_decoder_);
481 manager()->OnMediaMetadataChanged(
482 player_id(), duration_, width_, height_, true);
483
484 if (reconfig_audio_decoder_)
485 ConfigureAudioDecoderJob();
486
487 if (reconfig_video_decoder_)
488 ConfigureVideoDecoderJob();
489
490 ClearPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
491 }
492
493 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) {
494 DVLOG(1) << __FUNCTION__ << " : Handling SURFACE_CHANGE_EVENT.";
495 // Setting a new surface will require a new MediaCodec to be created.
496 ResetVideoDecoderJob();
497 ConfigureVideoDecoderJob();
498
499 // Return early if we can't successfully configure a new video decoder job
500 // yet.
501 if (HasVideo() && !video_decoder_job_)
502 return; 384 return;
385 ClearPendingEvent(DECODER_CREATION_EVENT_PENDING);
503 } 386 }
504 387
505 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) { 388 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) {
506 DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT."; 389 DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT.";
507 // If one of the decoder is not initialized, cancel this event as it will be
508 // called later when Start() is called again.
509 if ((HasVideo() && !video_decoder_job_) ||
510 (HasAudio() && !audio_decoder_job_)) {
511 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
512 return;
513 }
514
515 DCHECK(audio_decoder_job_ || AudioFinished());
516 DCHECK(video_decoder_job_ || VideoFinished());
517 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1); 390 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1);
518 391
519 // It is possible that all streams have finished decode, yet starvation 392 // It is possible that all streams have finished decode, yet starvation
520 // occurred during the last stream's EOS decode. In this case, prefetch is a 393 // occurred during the last stream's EOS decode. In this case, prefetch is a
521 // no-op. 394 // no-op.
522 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 395 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
523 if (count == 0) 396 if (count == 0)
524 return; 397 return;
525 398
526 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING); 399 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING)); 459 DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING));
587 460
588 // Let |SEEK_EVENT_PENDING| (the highest priority event outside of 461 // Let |SEEK_EVENT_PENDING| (the highest priority event outside of
589 // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process 462 // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process
590 // any other pending events only after handling EOS detection. 463 // any other pending events only after handling EOS detection.
591 if (IsEventPending(SEEK_EVENT_PENDING)) { 464 if (IsEventPending(SEEK_EVENT_PENDING)) {
592 ProcessPendingEvents(); 465 ProcessPendingEvents();
593 return; 466 return;
594 } 467 }
595 468
596 if (status == MEDIA_CODEC_OK && is_clock_manager && 469 if ((status == MEDIA_CODEC_OK || status == MEDIA_CODEC_INPUT_END_OF_STREAM) &&
597 current_presentation_timestamp != kNoTimestamp()) { 470 is_clock_manager && current_presentation_timestamp != kNoTimestamp()) {
598 UpdateTimestamps( 471 UpdateTimestamps(current_presentation_timestamp,
599 current_presentation_timestamp, max_presentation_timestamp); 472 max_presentation_timestamp);
600 } 473 }
601 474
602 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) 475 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
603 PlaybackCompleted(is_audio); 476 PlaybackCompleted(is_audio);
604 477
605 if (pending_event_ != NO_EVENT_PENDING) { 478 if (pending_event_ != NO_EVENT_PENDING) {
606 ProcessPendingEvents(); 479 ProcessPendingEvents();
607 return; 480 return;
608 } 481 }
609 482
(...skipping 25 matching lines...) Expand all
635 StartStarvationCallback(current_presentation_timestamp, 508 StartStarvationCallback(current_presentation_timestamp,
636 max_presentation_timestamp); 509 max_presentation_timestamp);
637 else 510 else
638 start_time_ticks_ = base::TimeTicks::Now(); 511 start_time_ticks_ = base::TimeTicks::Now();
639 } 512 }
640 513
641 if (is_audio) 514 if (is_audio)
642 DecodeMoreAudio(); 515 DecodeMoreAudio();
643 else 516 else
644 DecodeMoreVideo(); 517 DecodeMoreVideo();
645
646 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING))
647 ProcessPendingEvents();
648 } 518 }
649 519
650 void MediaSourcePlayer::DecodeMoreAudio() { 520 void MediaSourcePlayer::DecodeMoreAudio() {
651 DVLOG(1) << __FUNCTION__; 521 DVLOG(1) << __FUNCTION__;
652 DCHECK(!audio_decoder_job_->is_decoding()); 522 DCHECK(!audio_decoder_job_->is_decoding());
653 DCHECK(!AudioFinished()); 523 DCHECK(!AudioFinished());
654 524
655 scoped_ptr<DemuxerConfigs> configs(audio_decoder_job_->Decode( 525 if (audio_decoder_job_->Decode(
656 start_time_ticks_, 526 start_time_ticks_,
657 start_presentation_timestamp_, 527 start_presentation_timestamp_,
658 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, 528 base::Bind(&MediaSourcePlayer::MediaDecoderCallback,
659 weak_factory_.GetWeakPtr(), 529 weak_factory_.GetWeakPtr(),
660 true))); 530 true))) {
661 if (!configs) {
662 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", 531 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio",
663 audio_decoder_job_.get()); 532 audio_decoder_job_.get());
664 return; 533 return;
665 } 534 }
666 535
667 // Failed to start the next decode. 536 is_waiting_for_audio_decoder_ = true;
668 DCHECK(!reconfig_audio_decoder_); 537 if (!IsEventPending(DECODER_CREATION_EVENT_PENDING))
669 reconfig_audio_decoder_ = true; 538 SetPendingEvent(DECODER_CREATION_EVENT_PENDING);
670 SetDemuxerConfigs(*configs, true);
671
672 // Config change may have just been detected on the other stream. If so,
673 // don't send a duplicate demuxer config request.
674 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
675 DCHECK(reconfig_video_decoder_);
676 return;
677 }
678
679 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
680 } 539 }
681 540
682 void MediaSourcePlayer::DecodeMoreVideo() { 541 void MediaSourcePlayer::DecodeMoreVideo() {
683 DVLOG(1) << __FUNCTION__; 542 DVLOG(1) << __FUNCTION__;
684 DCHECK(!video_decoder_job_->is_decoding()); 543 DCHECK(!video_decoder_job_->is_decoding());
685 DCHECK(!VideoFinished()); 544 DCHECK(!VideoFinished());
686 545
687 scoped_ptr<DemuxerConfigs> configs(video_decoder_job_->Decode( 546 if (video_decoder_job_->Decode(
688 start_time_ticks_, 547 start_time_ticks_,
689 start_presentation_timestamp_, 548 start_presentation_timestamp_,
690 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, 549 base::Bind(&MediaSourcePlayer::MediaDecoderCallback,
691 weak_factory_.GetWeakPtr(), 550 weak_factory_.GetWeakPtr(),
692 false))); 551 false))) {
693 if (!configs) {
694 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo", 552 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo",
695 video_decoder_job_.get()); 553 video_decoder_job_.get());
696 return; 554 return;
697 } 555 }
698 556
699 // Failed to start the next decode. 557 // If the decoder is waiting for iframe, trigger a browser seek.
700 // After this detection of video config change, next video data received 558 if (!video_decoder_job_->next_video_data_is_iframe()) {
701 // will begin with I-frame. 559 BrowserSeekToCurrentTime();
702 next_video_data_is_iframe_ = true;
703
704 DCHECK(!reconfig_video_decoder_);
705 reconfig_video_decoder_ = true;
706 SetDemuxerConfigs(*configs, false);
707
708 // Config change may have just been detected on the other stream. If so,
709 // don't send a duplicate demuxer config request.
710 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
711 DCHECK(reconfig_audio_decoder_);
712 return; 560 return;
713 } 561 }
714 562
715 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING); 563 is_waiting_for_video_decoder_ = true;
564 if (!IsEventPending(DECODER_CREATION_EVENT_PENDING))
565 SetPendingEvent(DECODER_CREATION_EVENT_PENDING);
716 } 566 }
717 567
718 void MediaSourcePlayer::PlaybackCompleted(bool is_audio) { 568 void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
719 DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")"; 569 DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")";
720 if (is_audio)
721 reached_audio_eos_ = true;
722 else
723 reached_video_eos_ = true;
724 570
725 if (AudioFinished() && VideoFinished()) { 571 if (AudioFinished() && VideoFinished()) {
726 playing_ = false; 572 playing_ = false;
727 clock_.Pause(); 573 clock_.Pause();
728 start_time_ticks_ = base::TimeTicks(); 574 start_time_ticks_ = base::TimeTicks();
729 manager()->OnPlaybackComplete(player_id()); 575 manager()->OnPlaybackComplete(player_id());
730 } 576 }
731 } 577 }
732 578
733 void MediaSourcePlayer::ClearDecodingData() { 579 void MediaSourcePlayer::ClearDecodingData() {
734 DVLOG(1) << __FUNCTION__; 580 DVLOG(1) << __FUNCTION__;
735 if (audio_decoder_job_) 581 audio_decoder_job_->Flush();
736 audio_decoder_job_->Flush(); 582 video_decoder_job_->Flush();
737 if (video_decoder_job_)
738 video_decoder_job_->Flush();
739 start_time_ticks_ = base::TimeTicks(); 583 start_time_ticks_ = base::TimeTicks();
740 } 584 }
741 585
742 bool MediaSourcePlayer::HasVideo() { 586 bool MediaSourcePlayer::HasVideo() {
743 return kUnknownVideoCodec != video_codec_; 587 return video_decoder_job_->HasStream();
744 } 588 }
745 589
746 bool MediaSourcePlayer::HasAudio() { 590 bool MediaSourcePlayer::HasAudio() {
747 return kUnknownAudioCodec != audio_codec_; 591 return audio_decoder_job_->HasStream();
748 } 592 }
749 593
750 bool MediaSourcePlayer::AudioFinished() { 594 bool MediaSourcePlayer::AudioFinished() {
751 return reached_audio_eos_ || !HasAudio(); 595 return audio_decoder_job_->OutputEOSReached() || !HasAudio();
752 } 596 }
753 597
754 bool MediaSourcePlayer::VideoFinished() { 598 bool MediaSourcePlayer::VideoFinished() {
755 return reached_video_eos_ || !HasVideo(); 599 return video_decoder_job_->OutputEOSReached() || !HasVideo();
756 }
757
758 void MediaSourcePlayer::ConfigureAudioDecoderJob() {
759 if (!HasAudio()) {
760 ResetAudioDecoderJob();
761 return;
762 }
763
764 // Create audio decoder job only if config changes.
765 if (audio_decoder_job_ && !reconfig_audio_decoder_)
766 return;
767
768 base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto();
769 if (is_audio_encrypted_ && media_crypto.is_null())
770 return;
771
772 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding());
773
774 ResetAudioDecoderJob();
775 DVLOG(1) << __FUNCTION__ << " : creating new audio decoder job";
776 audio_decoder_job_.reset(AudioDecoderJob::Create(
777 audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0],
778 audio_extra_data_.size(), media_crypto.obj(),
779 base::Bind(&DemuxerAndroid::RequestDemuxerData,
780 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO)));
781
782 if (audio_decoder_job_) {
783 SetVolumeInternal();
784 // Need to reset the base timestamp in |audio_decoder_job_|.
785 // TODO(qinmin): When reconfiguring the |audio_decoder_job_|, there might
786 // still be some audio frames in the decoder or in AudioTrack. Therefore,
787 // we are losing some time here. http://crbug.com/357726.
788 base::TimeDelta current_time = GetCurrentTime();
789 audio_decoder_job_->SetBaseTimestamp(current_time);
790 clock_.SetTime(current_time, current_time);
791 audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
792 reconfig_audio_decoder_ = false;
793 }
794 }
795
796 void MediaSourcePlayer::ResetVideoDecoderJob() {
797 if (video_decoder_job_) {
798 has_pending_video_data_request_ =
799 video_decoder_job_->is_requesting_demuxer_data();
800 }
801 video_decoder_job_.reset();
802
803 // Any eventual video decoder job re-creation will use the current |surface_|.
804 if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
805 ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
806 }
807
808 void MediaSourcePlayer::ResetAudioDecoderJob() {
809 if (audio_decoder_job_) {
810 has_pending_audio_data_request_ =
811 audio_decoder_job_->is_requesting_demuxer_data();
812 }
813 audio_decoder_job_.reset();
814 }
815
816 void MediaSourcePlayer::ConfigureVideoDecoderJob() {
817 if (!HasVideo() || surface_.IsEmpty()) {
818 ResetVideoDecoderJob();
819 return;
820 }
821
822 // Create video decoder job only if config changes or we don't have a job.
823 if (video_decoder_job_ && !reconfig_video_decoder_) {
824 DCHECK(!IsEventPending(SURFACE_CHANGE_EVENT_PENDING));
825 return;
826 }
827
828 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
829
830 if (reconfig_video_decoder_) {
831 // No hack browser seek should be required. I-Frame must be next.
832 DCHECK(next_video_data_is_iframe_) << "Received video data between "
833 << "detecting video config change and reconfiguring video decoder";
834 }
835
836 // If uncertain that video I-frame data is next and there is no seek already
837 // in process, request browser demuxer seek so the new decoder will decode
838 // an I-frame first. Otherwise, the new MediaCodec might crash. See b/8950387.
839 // Eventual OnDemuxerSeekDone() will trigger ProcessPendingEvents() and
840 // continue from here.
841 // TODO(wolenetz): Instead of doing hack browser seek, replay cached data
842 // since last keyframe. See http://crbug.com/304234.
843 if (!next_video_data_is_iframe_ && !IsEventPending(SEEK_EVENT_PENDING)) {
844 BrowserSeekToCurrentTime();
845 return;
846 }
847
848 // Release the old VideoDecoderJob first so the surface can get released.
849 // Android does not allow 2 MediaCodec instances use the same surface.
850 ResetVideoDecoderJob();
851
852 base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto();
853 if (is_video_encrypted_ && media_crypto.is_null())
854 return;
855
856 DVLOG(1) << __FUNCTION__ << " : creating new video decoder job";
857
858 // Create the new VideoDecoderJob.
859 bool is_secure = IsProtectedSurfaceRequired();
860 video_decoder_job_.reset(
861 VideoDecoderJob::Create(
862 video_codec_,
863 is_secure,
864 gfx::Size(width_, height_),
865 surface_.j_surface().obj(),
866 media_crypto.obj(),
867 base::Bind(&DemuxerAndroid::RequestDemuxerData,
868 base::Unretained(demuxer_.get()),
869 DemuxerStream::VIDEO),
870 base::Bind(request_media_resources_cb_, player_id()),
871 base::Bind(release_media_resources_cb_, player_id())));
872 if (!video_decoder_job_)
873 return;
874
875 video_decoder_job_->BeginPrerolling(preroll_timestamp_);
876 reconfig_video_decoder_ = false;
877
878 // Inform the fullscreen view the player is ready.
879 // TODO(qinmin): refactor MediaPlayerBridge so that we have a better way
880 // to inform ContentVideoView.
881 manager()->OnMediaMetadataChanged(
882 player_id(), duration_, width_, height_, true);
883 } 600 }
884 601
885 void MediaSourcePlayer::OnDecoderStarved() { 602 void MediaSourcePlayer::OnDecoderStarved() {
886 DVLOG(1) << __FUNCTION__; 603 DVLOG(1) << __FUNCTION__;
887 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 604 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
888 ProcessPendingEvents(); 605 ProcessPendingEvents();
889 } 606 }
890 607
891 void MediaSourcePlayer::StartStarvationCallback( 608 void MediaSourcePlayer::StartStarvationCallback(
892 base::TimeDelta current_presentation_timestamp, 609 base::TimeDelta current_presentation_timestamp,
(...skipping 20 matching lines...) Expand all
913 } 630 }
914 631
915 timeout = std::max(timeout, kMinStarvationTimeout); 632 timeout = std::max(timeout, kMinStarvationTimeout);
916 633
917 decoder_starvation_callback_.Reset(base::Bind( 634 decoder_starvation_callback_.Reset(base::Bind(
918 &MediaSourcePlayer::OnDecoderStarved, weak_factory_.GetWeakPtr())); 635 &MediaSourcePlayer::OnDecoderStarved, weak_factory_.GetWeakPtr()));
919 base::MessageLoop::current()->PostDelayedTask( 636 base::MessageLoop::current()->PostDelayedTask(
920 FROM_HERE, decoder_starvation_callback_.callback(), timeout); 637 FROM_HERE, decoder_starvation_callback_.callback(), timeout);
921 } 638 }
922 639
923 void MediaSourcePlayer::SetVolumeInternal() {
924 if (audio_decoder_job_ && volume_ >= 0)
925 audio_decoder_job_->SetVolume(volume_);
926 }
927
928 bool MediaSourcePlayer::IsProtectedSurfaceRequired() { 640 bool MediaSourcePlayer::IsProtectedSurfaceRequired() {
929 return is_video_encrypted_ && 641 return video_decoder_job_->is_content_encrypted() &&
930 drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired(); 642 drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired();
931 } 643 }
932 644
933 void MediaSourcePlayer::OnPrefetchDone() { 645 void MediaSourcePlayer::OnPrefetchDone() {
934 DVLOG(1) << __FUNCTION__; 646 DVLOG(1) << __FUNCTION__;
935 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding()); 647 DCHECK(!audio_decoder_job_->is_decoding());
936 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding()); 648 DCHECK(!video_decoder_job_->is_decoding());
937 649
938 // A previously posted OnPrefetchDone() could race against a Release(). If 650 // A previously posted OnPrefetchDone() could race against a Release(). If
939 // Release() won the race, we should no longer have decoder jobs. 651 // Release() won the race, we should no longer have decoder jobs.
940 // TODO(qinmin/wolenetz): Maintain channel state to not double-request data 652 // TODO(qinmin/wolenetz): Maintain channel state to not double-request data
941 // or drop data received across Release()+Start(). See http://crbug.com/306314 653 // or drop data received across Release()+Start(). See http://crbug.com/306314
942 // and http://crbug.com/304234. 654 // and http://crbug.com/304234.
943 if (!IsEventPending(PREFETCH_DONE_EVENT_PENDING)) { 655 if (!IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
944 DVLOG(1) << __FUNCTION__ << " : aborting"; 656 DVLOG(1) << __FUNCTION__ << " : aborting";
945 DCHECK(!audio_decoder_job_ && !video_decoder_job_);
946 return; 657 return;
947 } 658 }
948 659
949 ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING); 660 ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING);
950 661
951 if (pending_event_ != NO_EVENT_PENDING) { 662 if (pending_event_ != NO_EVENT_PENDING) {
952 ProcessPendingEvents(); 663 ProcessPendingEvents();
953 return; 664 return;
954 } 665 }
955 666
667 if (!playing_)
668 return;
669
956 start_time_ticks_ = base::TimeTicks::Now(); 670 start_time_ticks_ = base::TimeTicks::Now();
957 start_presentation_timestamp_ = GetCurrentTime(); 671 start_presentation_timestamp_ = GetCurrentTime();
958 if (!clock_.IsPlaying()) 672 if (!clock_.IsPlaying())
959 clock_.Play(); 673 clock_.Play();
960 674
961 if (!AudioFinished()) 675 if (!AudioFinished())
962 DecodeMoreAudio(); 676 DecodeMoreAudio();
963 677
964 if (!VideoFinished()) 678 if (!VideoFinished())
965 DecodeMoreVideo(); 679 DecodeMoreVideo();
680 }
966 681
967 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) 682 void MediaSourcePlayer::OnDemuxerConfigsChanged() {
968 ProcessPendingEvents(); 683 manager()->OnMediaMetadataChanged(
684 player_id(), duration_, GetVideoWidth(), GetVideoHeight(), true);
969 } 685 }
970 686
971 const char* MediaSourcePlayer::GetEventName(PendingEventFlags event) { 687 const char* MediaSourcePlayer::GetEventName(PendingEventFlags event) {
688 // Please keep this in sync with PendingEventFlags.
972 static const char* kPendingEventNames[] = { 689 static const char* kPendingEventNames[] = {
690 "PREFETCH_DONE",
973 "SEEK", 691 "SEEK",
974 "SURFACE_CHANGE", 692 "DECODER_CREATION",
975 "CONFIG_CHANGE",
976 "PREFETCH_REQUEST", 693 "PREFETCH_REQUEST",
977 "PREFETCH_DONE",
978 }; 694 };
979 695
980 int mask = 1; 696 int mask = 1;
981 for (size_t i = 0; i < arraysize(kPendingEventNames); ++i, mask <<= 1) { 697 for (size_t i = 0; i < arraysize(kPendingEventNames); ++i, mask <<= 1) {
982 if (event & mask) 698 if (event & mask)
983 return kPendingEventNames[i]; 699 return kPendingEventNames[i];
984 } 700 }
985 701
986 return "UNKNOWN"; 702 return "UNKNOWN";
987 } 703 }
(...skipping 11 matching lines...) Expand all
999 } 715 }
1000 716
1001 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { 717 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
1002 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; 718 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
1003 DCHECK_NE(event, NO_EVENT_PENDING); 719 DCHECK_NE(event, NO_EVENT_PENDING);
1004 DCHECK(IsEventPending(event)) << GetEventName(event); 720 DCHECK(IsEventPending(event)) << GetEventName(event);
1005 721
1006 pending_event_ &= ~event; 722 pending_event_ &= ~event;
1007 } 723 }
1008 724
1009 void MediaSourcePlayer::SetDemuxerConfigs(const DemuxerConfigs& configs, 725 void MediaSourcePlayer::RetryDecoderCreation(bool audio, bool video) {
1010 bool is_audio) { 726 if (audio)
1011 if (is_audio) { 727 is_waiting_for_audio_decoder_ = false;
1012 audio_codec_ = configs.audio_codec; 728 if (video)
1013 num_channels_ = configs.audio_channels; 729 is_waiting_for_video_decoder_ = false;
1014 sampling_rate_ = configs.audio_sampling_rate; 730 if (IsEventPending(DECODER_CREATION_EVENT_PENDING))
1015 is_audio_encrypted_ = configs.is_audio_encrypted; 731 ProcessPendingEvents();
1016 audio_extra_data_ = configs.audio_extra_data;
1017 } else {
1018 video_codec_ = configs.video_codec;
1019 width_ = configs.video_size.width();
1020 height_ = configs.video_size.height();
1021 is_video_encrypted_ = configs.is_video_encrypted;
1022 }
1023 } 732 }
1024 733
1025 } // namespace media 734 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698