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

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

Powered by Google App Engine
This is Rietveld 408576698