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

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: addressing comments 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_video_decoder_(false),
59 has_pending_video_data_request_(false),
60 weak_factory_(this) { 45 weak_factory_(this) {
46 audio_decoder_job_.reset(new AudioDecoderJob(
47 base::Bind(&DemuxerAndroid::RequestDemuxerData,
48 base::Unretained(demuxer_.get()),
49 DemuxerStream::AUDIO),
50 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged,
51 weak_factory_.GetWeakPtr())));
52 video_decoder_job_.reset(new VideoDecoderJob(
53 base::Bind(&DemuxerAndroid::RequestDemuxerData,
54 base::Unretained(demuxer_.get()),
55 DemuxerStream::VIDEO),
56 base::Bind(request_media_resources_cb_, player_id),
57 base::Bind(release_media_resources_cb_, player_id),
58 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged,
59 weak_factory_.GetWeakPtr())));
61 demuxer_->Initialize(this); 60 demuxer_->Initialize(this);
62 clock_.SetMaxTime(base::TimeDelta()); 61 clock_.SetMaxTime(base::TimeDelta());
63 } 62 }
64 63
65 MediaSourcePlayer::~MediaSourcePlayer() { 64 MediaSourcePlayer::~MediaSourcePlayer() {
66 Release(); 65 Release();
67 } 66 }
68 67
69 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { 68 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) {
70 // For an empty surface, always pass it to the decoder job so that it 69 DVLOG(1) << __FUNCTION__;
71 // can detach from the current one. Otherwise, don't pass an unprotected 70 // If the player is waiting for the video decoder job, retry video decoder
72 // surface if the video content requires a protected one. 71 // creation.
73 if (!surface.IsEmpty() && 72 if (is_waiting_for_video_decoder_)
74 IsProtectedSurfaceRequired() && !surface.is_protected()) { 73 is_waiting_for_video_decoder_ = false;
74
75 if (!video_decoder_job_->SetVideoSurface(surface.Pass()))
75 return; 76 return;
76 } 77 if (IsEventPending(VIDEO_DECODER_CREATION_EVENT_PENDING))
77 78 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 } 79 }
103 80
104 void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding( 81 void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding(
105 base::TimeDelta seek_time) { 82 base::TimeDelta seek_time) {
106 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")"; 83 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")";
107 DCHECK(!IsEventPending(SEEK_EVENT_PENDING)); 84 DCHECK(!IsEventPending(SEEK_EVENT_PENDING));
108 85
109 pending_seek_ = false; 86 pending_seek_ = false;
110 87
111 clock_.SetTime(seek_time, seek_time); 88 clock_.SetTime(seek_time, seek_time);
112 89
113 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) 90 if (audio_decoder_job_->is_decoding())
114 audio_decoder_job_->StopDecode(); 91 audio_decoder_job_->StopDecode();
115 if (video_decoder_job_ && video_decoder_job_->is_decoding()) 92 if (video_decoder_job_->is_decoding())
116 video_decoder_job_->StopDecode(); 93 video_decoder_job_->StopDecode();
117 94
118 SetPendingEvent(SEEK_EVENT_PENDING); 95 SetPendingEvent(SEEK_EVENT_PENDING);
119 ProcessPendingEvents(); 96 ProcessPendingEvents();
120 } 97 }
121 98
122 void MediaSourcePlayer::BrowserSeekToCurrentTime() { 99 void MediaSourcePlayer::BrowserSeekToCurrentTime() {
123 DVLOG(1) << __FUNCTION__; 100 DVLOG(1) << __FUNCTION__;
124 101
125 DCHECK(!IsEventPending(SEEK_EVENT_PENDING)); 102 DCHECK(!IsEventPending(SEEK_EVENT_PENDING));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 // MediaDecoderCallback() is called. 134 // MediaDecoderCallback() is called.
158 playing_ = false; 135 playing_ = false;
159 start_time_ticks_ = base::TimeTicks(); 136 start_time_ticks_ = base::TimeTicks();
160 } 137 }
161 138
162 bool MediaSourcePlayer::IsPlaying() { 139 bool MediaSourcePlayer::IsPlaying() {
163 return playing_; 140 return playing_;
164 } 141 }
165 142
166 int MediaSourcePlayer::GetVideoWidth() { 143 int MediaSourcePlayer::GetVideoWidth() {
167 return width_; 144 return video_decoder_job_->width();
168 } 145 }
169 146
170 int MediaSourcePlayer::GetVideoHeight() { 147 int MediaSourcePlayer::GetVideoHeight() {
171 return height_; 148 return video_decoder_job_->height();
172 } 149 }
173 150
174 void MediaSourcePlayer::SeekTo(base::TimeDelta timestamp) { 151 void MediaSourcePlayer::SeekTo(base::TimeDelta timestamp) {
175 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")"; 152 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")";
176 153
177 if (IsEventPending(SEEK_EVENT_PENDING)) { 154 if (IsEventPending(SEEK_EVENT_PENDING)) {
178 DCHECK(doing_browser_seek_) << "SeekTo while SeekTo in progress"; 155 DCHECK(doing_browser_seek_) << "SeekTo while SeekTo in progress";
179 DCHECK(!pending_seek_) << "SeekTo while SeekTo pending browser seek"; 156 DCHECK(!pending_seek_) << "SeekTo while SeekTo pending browser seek";
180 157
181 // There is a browser seek currently in progress to obtain I-frame to feed 158 // There is a browser seek currently in progress to obtain I-frame to feed
(...skipping 12 matching lines...) Expand all
194 return clock_.Elapsed(); 171 return clock_.Elapsed();
195 } 172 }
196 173
197 base::TimeDelta MediaSourcePlayer::GetDuration() { 174 base::TimeDelta MediaSourcePlayer::GetDuration() {
198 return duration_; 175 return duration_;
199 } 176 }
200 177
201 void MediaSourcePlayer::Release() { 178 void MediaSourcePlayer::Release() {
202 DVLOG(1) << __FUNCTION__; 179 DVLOG(1) << __FUNCTION__;
203 180
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; 181 is_surface_in_use_ = false;
219 ResetAudioDecoderJob(); 182 audio_decoder_job_->ReleaseDecoderResources();
220 ResetVideoDecoderJob(); 183 video_decoder_job_->ReleaseDecoderResources();
221
222 // Prevent job re-creation attempts in OnDemuxerConfigsAvailable()
223 reconfig_audio_decoder_ = false;
224 reconfig_video_decoder_ = false;
225 184
226 // Prevent player restart, including job re-creation attempts. 185 // Prevent player restart, including job re-creation attempts.
227 playing_ = false; 186 playing_ = false;
228 187
229 decoder_starvation_callback_.Cancel(); 188 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 } 189 }
236 190
237 void MediaSourcePlayer::SetVolume(double volume) { 191 void MediaSourcePlayer::SetVolume(double volume) {
238 volume_ = volume; 192 audio_decoder_job_->SetVolume(volume);
239 SetVolumeInternal();
240 } 193 }
241 194
242 void MediaSourcePlayer::OnKeyAdded() { 195 void MediaSourcePlayer::OnKeyAdded() {
243 DVLOG(1) << __FUNCTION__; 196 DVLOG(1) << __FUNCTION__;
244 if (!is_waiting_for_key_) 197 if (!is_waiting_for_key_)
245 return; 198 return;
246 199
247 is_waiting_for_key_ = false; 200 is_waiting_for_key_ = false;
248 if (playing_) 201 if (playing_)
249 StartInternal(); 202 StartInternal();
(...skipping 23 matching lines...) Expand all
273 DVLOG(1) << __FUNCTION__; 226 DVLOG(1) << __FUNCTION__;
274 // If there are pending events, wait for them finish. 227 // If there are pending events, wait for them finish.
275 if (pending_event_ != NO_EVENT_PENDING) 228 if (pending_event_ != NO_EVENT_PENDING)
276 return; 229 return;
277 230
278 // When we start, we'll have new demuxed data coming in. This new data could 231 // 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 232 // be clear (not encrypted) or encrypted with different keys. So
280 // |is_waiting_for_key_| condition may not be true anymore. 233 // |is_waiting_for_key_| condition may not be true anymore.
281 is_waiting_for_key_ = false; 234 is_waiting_for_key_ = false;
282 235
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); 236 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
294 ProcessPendingEvents(); 237 ProcessPendingEvents();
295 } 238 }
296 239
297 void MediaSourcePlayer::OnDemuxerConfigsAvailable( 240 void MediaSourcePlayer::OnDemuxerConfigsAvailable(
298 const DemuxerConfigs& configs) { 241 const DemuxerConfigs& configs) {
299 DVLOG(1) << __FUNCTION__; 242 DVLOG(1) << __FUNCTION__;
300 DCHECK(!HasAudio() && !HasVideo()); 243 DCHECK(!HasAudio() && !HasVideo());
301 duration_ = configs.duration; 244 duration_ = configs.duration;
302 clock_.SetDuration(duration_); 245 clock_.SetDuration(duration_);
303 246
304 SetDemuxerConfigs(configs, true); 247 audio_decoder_job_->SetDemuxerConfigs(configs);
305 SetDemuxerConfigs(configs, false); 248 video_decoder_job_->SetDemuxerConfigs(configs);
306 249 OnDemuxerConfigsChanged();
307 manager()->OnMediaMetadataChanged(
308 player_id(), duration_, width_, height_, true);
309 } 250 }
310 251
311 void MediaSourcePlayer::OnDemuxerDataAvailable(const DemuxerData& data) { 252 void MediaSourcePlayer::OnDemuxerDataAvailable(const DemuxerData& data) {
312 DVLOG(1) << __FUNCTION__ << "(" << data.type << ")"; 253 DVLOG(1) << __FUNCTION__ << "(" << data.type << ")";
313 DCHECK_LT(0u, data.access_units.size()); 254 DCHECK_LT(0u, data.access_units.size());
314 CHECK_GE(1u, data.demuxer_configs.size()); 255 CHECK_GE(1u, data.demuxer_configs.size());
315 256
316 if (has_pending_audio_data_request_ && data.type == DemuxerStream::AUDIO) { 257 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); 258 audio_decoder_job_->OnDataReceived(data);
331 } else if (data.type == DemuxerStream::VIDEO) { 259 else if (data.type == DemuxerStream::VIDEO)
332 next_video_data_is_iframe_ = false; 260 video_decoder_job_->OnDataReceived(data);
333 if (video_decoder_job_)
334 video_decoder_job_->OnDataReceived(data);
335 }
336 } 261 }
337 262
338 void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) { 263 void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) {
339 duration_ = duration; 264 duration_ = duration;
340 clock_.SetDuration(duration_); 265 clock_.SetDuration(duration_);
341 } 266 }
342 267
343 base::android::ScopedJavaLocalRef<jobject> MediaSourcePlayer::GetMediaCrypto() { 268 base::android::ScopedJavaLocalRef<jobject> MediaSourcePlayer::GetMediaCrypto() {
344 base::android::ScopedJavaLocalRef<jobject> media_crypto; 269 base::android::ScopedJavaLocalRef<jobject> media_crypto;
345 if (drm_bridge_) 270 if (drm_bridge_)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 } 304 }
380 305
381 void MediaSourcePlayer::OnDemuxerSeekDone( 306 void MediaSourcePlayer::OnDemuxerSeekDone(
382 base::TimeDelta actual_browser_seek_time) { 307 base::TimeDelta actual_browser_seek_time) {
383 DVLOG(1) << __FUNCTION__; 308 DVLOG(1) << __FUNCTION__;
384 309
385 ClearPendingEvent(SEEK_EVENT_PENDING); 310 ClearPendingEvent(SEEK_EVENT_PENDING);
386 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) 311 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING))
387 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 312 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
388 313
389 next_video_data_is_iframe_ = true;
390
391 if (pending_seek_) { 314 if (pending_seek_) {
392 DVLOG(1) << __FUNCTION__ << "processing pending seek"; 315 DVLOG(1) << __FUNCTION__ << "processing pending seek";
393 DCHECK(doing_browser_seek_); 316 DCHECK(doing_browser_seek_);
394 pending_seek_ = false; 317 pending_seek_ = false;
395 SeekTo(pending_seek_time_); 318 SeekTo(pending_seek_time_);
396 return; 319 return;
397 } 320 }
398 321
399 // 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
400 // 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
401 // player clock to the actual seek target. 324 // player clock to the actual seek target.
402 if (doing_browser_seek_) { 325 if (doing_browser_seek_) {
403 DCHECK(actual_browser_seek_time != kNoTimestamp()); 326 DCHECK(actual_browser_seek_time != kNoTimestamp());
404 base::TimeDelta seek_time = actual_browser_seek_time; 327 base::TimeDelta seek_time = actual_browser_seek_time;
405 // 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
406 // requested time, but it might jump into the future. 329 // requested time, but it might jump into the future.
407 DCHECK(seek_time >= GetCurrentTime()); 330 DCHECK(seek_time >= GetCurrentTime());
408 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: " 331 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: "
409 << seek_time.InSecondsF(); 332 << seek_time.InSecondsF();
410 clock_.SetTime(seek_time, seek_time); 333 clock_.SetTime(seek_time, seek_time);
411 if (audio_decoder_job_) 334 audio_decoder_job_->SetBaseTimestamp(seek_time);
412 audio_decoder_job_->SetBaseTimestamp(seek_time);
413 } else { 335 } else {
414 DCHECK(actual_browser_seek_time == kNoTimestamp()); 336 DCHECK(actual_browser_seek_time == kNoTimestamp());
415 } 337 }
416 338
417 reached_audio_eos_ = false;
418 reached_video_eos_ = false;
419
420 base::TimeDelta current_time = GetCurrentTime(); 339 base::TimeDelta current_time = GetCurrentTime();
421 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_| 340 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_|
422 // to preroll media decoder jobs. Currently |start_presentation_timestamp_| 341 // to preroll media decoder jobs. Currently |start_presentation_timestamp_|
423 // is calculated from decoder output, while preroll relies on the access 342 // is calculated from decoder output, while preroll relies on the access
424 // unit's timestamp. There are some differences between the two. 343 // unit's timestamp. There are some differences between the two.
425 preroll_timestamp_ = current_time; 344 preroll_timestamp_ = current_time;
426 if (audio_decoder_job_) 345 if (HasAudio())
427 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); 346 audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
428 if (video_decoder_job_) 347 if (HasVideo())
429 video_decoder_job_->BeginPrerolling(preroll_timestamp_); 348 video_decoder_job_->BeginPrerolling(preroll_timestamp_);
430 349
431 if (!doing_browser_seek_) 350 if (!doing_browser_seek_)
432 manager()->OnSeekComplete(player_id(), current_time); 351 manager()->OnSeekComplete(player_id(), current_time);
433 352
434 ProcessPendingEvents(); 353 ProcessPendingEvents();
435 } 354 }
436 355
437 void MediaSourcePlayer::UpdateTimestamps( 356 void MediaSourcePlayer::UpdateTimestamps(
438 base::TimeDelta current_presentation_timestamp, 357 base::TimeDelta current_presentation_timestamp,
439 base::TimeDelta max_presentation_timestamp) { 358 base::TimeDelta max_presentation_timestamp) {
440 clock_.SetTime(current_presentation_timestamp, max_presentation_timestamp); 359 clock_.SetTime(current_presentation_timestamp, max_presentation_timestamp);
441
442 manager()->OnTimeUpdate(player_id(), GetCurrentTime()); 360 manager()->OnTimeUpdate(player_id(), GetCurrentTime());
443 } 361 }
444 362
445 void MediaSourcePlayer::ProcessPendingEvents() { 363 void MediaSourcePlayer::ProcessPendingEvents() {
446 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_; 364 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_;
447 // Wait for all the decoding jobs to finish before processing pending tasks. 365 // Wait for all the decoding jobs to finish before processing pending tasks.
448 if (video_decoder_job_ && video_decoder_job_->is_decoding()) { 366 if (video_decoder_job_->is_decoding()) {
449 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding."; 367 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding.";
450 return; 368 return;
451 } 369 }
452 370
453 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) { 371 if (audio_decoder_job_->is_decoding()) {
454 DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding."; 372 DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding.";
455 return; 373 return;
456 } 374 }
457 375
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)) { 376 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
464 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending."; 377 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending.";
465 return; 378 return;
466 } 379 }
467 380
468 if (IsEventPending(SEEK_EVENT_PENDING)) { 381 if (IsEventPending(SEEK_EVENT_PENDING)) {
469 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT"; 382 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT";
470 ClearDecodingData(); 383 ClearDecodingData();
471 if (audio_decoder_job_) 384 audio_decoder_job_->SetBaseTimestamp(GetCurrentTime());
472 audio_decoder_job_->SetBaseTimestamp(GetCurrentTime());
473 demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_); 385 demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_);
474 return; 386 return;
475 } 387 }
476 388
477 start_time_ticks_ = base::TimeTicks(); 389 if (IsEventPending(VIDEO_DECODER_CREATION_EVENT_PENDING)) {
478 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { 390 // Don't continue if one of the decoder is not created.
479 DVLOG(1) << __FUNCTION__ << " : Handling CONFIG_CHANGE_EVENT."; 391 if (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; 392 return;
393 ClearPendingEvent(VIDEO_DECODER_CREATION_EVENT_PENDING);
503 } 394 }
504 395
505 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) { 396 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) {
506 DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT."; 397 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); 398 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1);
518 399
519 // It is possible that all streams have finished decode, yet starvation 400 // 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 401 // occurred during the last stream's EOS decode. In this case, prefetch is a
521 // no-op. 402 // no-op.
522 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 403 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
523 if (count == 0) 404 if (count == 0)
524 return; 405 return;
525 406
526 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING); 407 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 base::ResetAndReturn(&decode_callback_for_testing_).Run(); 453 base::ResetAndReturn(&decode_callback_for_testing_).Run();
573 454
574 bool is_clock_manager = is_audio || !HasAudio(); 455 bool is_clock_manager = is_audio || !HasAudio();
575 456
576 if (is_clock_manager) 457 if (is_clock_manager)
577 decoder_starvation_callback_.Cancel(); 458 decoder_starvation_callback_.Cancel();
578 459
579 if (status == MEDIA_CODEC_ERROR) { 460 if (status == MEDIA_CODEC_ERROR) {
580 DVLOG(1) << __FUNCTION__ << " : decode error"; 461 DVLOG(1) << __FUNCTION__ << " : decode error";
581 Release(); 462 Release();
582 manager()->OnError(player_id(), MEDIA_ERROR_DECODE); 463 OnDecodeError();
583 return; 464 return;
584 } 465 }
585 466
586 DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING)); 467 DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING));
587 468
588 // Let |SEEK_EVENT_PENDING| (the highest priority event outside of 469 // Let |SEEK_EVENT_PENDING| (the highest priority event outside of
589 // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process 470 // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process
590 // any other pending events only after handling EOS detection. 471 // any other pending events only after handling EOS detection.
591 if (IsEventPending(SEEK_EVENT_PENDING)) { 472 if (IsEventPending(SEEK_EVENT_PENDING)) {
592 ProcessPendingEvents(); 473 ProcessPendingEvents();
593 return; 474 return;
594 } 475 }
595 476
596 if (status == MEDIA_CODEC_OK && is_clock_manager && 477 if (status == MEDIA_CODEC_OK && is_clock_manager &&
597 current_presentation_timestamp != kNoTimestamp()) { 478 current_presentation_timestamp != kNoTimestamp()) {
598 UpdateTimestamps( 479 UpdateTimestamps(current_presentation_timestamp,
599 current_presentation_timestamp, max_presentation_timestamp); 480 max_presentation_timestamp);
600 } 481 }
601 482
602 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) 483 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
603 PlaybackCompleted(is_audio); 484 PlaybackCompleted(is_audio);
604 485
605 if (pending_event_ != NO_EVENT_PENDING) { 486 if (pending_event_ != NO_EVENT_PENDING) {
606 ProcessPendingEvents(); 487 ProcessPendingEvents();
607 return; 488 return;
608 } 489 }
609 490
(...skipping 25 matching lines...) Expand all
635 StartStarvationCallback(current_presentation_timestamp, 516 StartStarvationCallback(current_presentation_timestamp,
636 max_presentation_timestamp); 517 max_presentation_timestamp);
637 else 518 else
638 start_time_ticks_ = base::TimeTicks::Now(); 519 start_time_ticks_ = base::TimeTicks::Now();
639 } 520 }
640 521
641 if (is_audio) 522 if (is_audio)
642 DecodeMoreAudio(); 523 DecodeMoreAudio();
643 else 524 else
644 DecodeMoreVideo(); 525 DecodeMoreVideo();
645
646 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING))
647 ProcessPendingEvents();
648 } 526 }
649 527
650 void MediaSourcePlayer::DecodeMoreAudio() { 528 void MediaSourcePlayer::DecodeMoreAudio() {
651 DVLOG(1) << __FUNCTION__; 529 DVLOG(1) << __FUNCTION__;
652 DCHECK(!audio_decoder_job_->is_decoding()); 530 DCHECK(!audio_decoder_job_->is_decoding());
653 DCHECK(!AudioFinished()); 531 DCHECK(!AudioFinished());
654 532
655 scoped_ptr<DemuxerConfigs> configs(audio_decoder_job_->Decode( 533 if (audio_decoder_job_->Decode(
656 start_time_ticks_, 534 start_time_ticks_,
657 start_presentation_timestamp_, 535 start_presentation_timestamp_,
658 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, 536 base::Bind(&MediaSourcePlayer::MediaDecoderCallback,
659 weak_factory_.GetWeakPtr(), 537 weak_factory_.GetWeakPtr(),
660 true))); 538 true))) {
661 if (!configs) {
662 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", 539 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio",
663 audio_decoder_job_.get()); 540 audio_decoder_job_.get());
664 return; 541 return;
665 } 542 }
666 543
667 // Failed to start the next decode. 544 // Cannot create audio decoder, reports an error.
668 DCHECK(!reconfig_audio_decoder_); 545 OnDecodeError();
669 reconfig_audio_decoder_ = true;
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 } 546 }
681 547
682 void MediaSourcePlayer::DecodeMoreVideo() { 548 void MediaSourcePlayer::DecodeMoreVideo() {
683 DVLOG(1) << __FUNCTION__; 549 DVLOG(1) << __FUNCTION__;
684 DCHECK(!video_decoder_job_->is_decoding()); 550 DCHECK(!video_decoder_job_->is_decoding());
685 DCHECK(!VideoFinished()); 551 DCHECK(!VideoFinished());
686 552
687 scoped_ptr<DemuxerConfigs> configs(video_decoder_job_->Decode( 553 if (video_decoder_job_->Decode(
688 start_time_ticks_, 554 start_time_ticks_,
689 start_presentation_timestamp_, 555 start_presentation_timestamp_,
690 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, 556 base::Bind(&MediaSourcePlayer::MediaDecoderCallback,
691 weak_factory_.GetWeakPtr(), 557 weak_factory_.GetWeakPtr(),
692 false))); 558 false))) {
693 if (!configs) {
694 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo", 559 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo",
695 video_decoder_job_.get()); 560 video_decoder_job_.get());
696 return; 561 return;
697 } 562 }
698 563
699 // Failed to start the next decode. 564 // If the decoder is waiting for iframe, trigger a browser seek.
700 // After this detection of video config change, next video data received 565 if (!video_decoder_job_->next_video_data_is_iframe()) {
701 // will begin with I-frame. 566 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; 567 return;
713 } 568 }
714 569
715 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING); 570 is_waiting_for_video_decoder_ = true;
571 if (!IsEventPending(VIDEO_DECODER_CREATION_EVENT_PENDING))
572 SetPendingEvent(VIDEO_DECODER_CREATION_EVENT_PENDING);
716 } 573 }
717 574
718 void MediaSourcePlayer::PlaybackCompleted(bool is_audio) { 575 void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
719 DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")"; 576 DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")";
720 if (is_audio)
721 reached_audio_eos_ = true;
722 else
723 reached_video_eos_ = true;
724 577
725 if (AudioFinished() && VideoFinished()) { 578 if (AudioFinished() && VideoFinished()) {
726 playing_ = false; 579 playing_ = false;
727 clock_.Pause(); 580 clock_.Pause();
728 start_time_ticks_ = base::TimeTicks(); 581 start_time_ticks_ = base::TimeTicks();
729 manager()->OnPlaybackComplete(player_id()); 582 manager()->OnPlaybackComplete(player_id());
730 } 583 }
731 } 584 }
732 585
733 void MediaSourcePlayer::ClearDecodingData() { 586 void MediaSourcePlayer::ClearDecodingData() {
734 DVLOG(1) << __FUNCTION__; 587 DVLOG(1) << __FUNCTION__;
735 if (audio_decoder_job_) 588 audio_decoder_job_->Flush();
736 audio_decoder_job_->Flush(); 589 video_decoder_job_->Flush();
737 if (video_decoder_job_)
738 video_decoder_job_->Flush();
739 start_time_ticks_ = base::TimeTicks(); 590 start_time_ticks_ = base::TimeTicks();
740 } 591 }
741 592
742 bool MediaSourcePlayer::HasVideo() { 593 bool MediaSourcePlayer::HasVideo() {
743 return kUnknownVideoCodec != video_codec_; 594 return video_decoder_job_->HasStream();
744 } 595 }
745 596
746 bool MediaSourcePlayer::HasAudio() { 597 bool MediaSourcePlayer::HasAudio() {
747 return kUnknownAudioCodec != audio_codec_; 598 return audio_decoder_job_->HasStream();
748 } 599 }
749 600
750 bool MediaSourcePlayer::AudioFinished() { 601 bool MediaSourcePlayer::AudioFinished() {
751 return reached_audio_eos_ || !HasAudio(); 602 return audio_decoder_job_->OutputEOSReached() || !HasAudio();
752 } 603 }
753 604
754 bool MediaSourcePlayer::VideoFinished() { 605 bool MediaSourcePlayer::VideoFinished() {
755 return reached_video_eos_ || !HasVideo(); 606 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 } 607 }
884 608
885 void MediaSourcePlayer::OnDecoderStarved() { 609 void MediaSourcePlayer::OnDecoderStarved() {
886 DVLOG(1) << __FUNCTION__; 610 DVLOG(1) << __FUNCTION__;
887 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 611 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
888 ProcessPendingEvents(); 612 ProcessPendingEvents();
889 } 613 }
890 614
891 void MediaSourcePlayer::StartStarvationCallback( 615 void MediaSourcePlayer::StartStarvationCallback(
892 base::TimeDelta current_presentation_timestamp, 616 base::TimeDelta current_presentation_timestamp,
(...skipping 20 matching lines...) Expand all
913 } 637 }
914 638
915 timeout = std::max(timeout, kMinStarvationTimeout); 639 timeout = std::max(timeout, kMinStarvationTimeout);
916 640
917 decoder_starvation_callback_.Reset(base::Bind( 641 decoder_starvation_callback_.Reset(base::Bind(
918 &MediaSourcePlayer::OnDecoderStarved, weak_factory_.GetWeakPtr())); 642 &MediaSourcePlayer::OnDecoderStarved, weak_factory_.GetWeakPtr()));
919 base::MessageLoop::current()->PostDelayedTask( 643 base::MessageLoop::current()->PostDelayedTask(
920 FROM_HERE, decoder_starvation_callback_.callback(), timeout); 644 FROM_HERE, decoder_starvation_callback_.callback(), timeout);
921 } 645 }
922 646
923 void MediaSourcePlayer::SetVolumeInternal() {
924 if (audio_decoder_job_ && volume_ >= 0)
925 audio_decoder_job_->SetVolume(volume_);
926 }
927
928 bool MediaSourcePlayer::IsProtectedSurfaceRequired() { 647 bool MediaSourcePlayer::IsProtectedSurfaceRequired() {
929 return is_video_encrypted_ && 648 return video_decoder_job_->is_content_encrypted() &&
930 drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired(); 649 drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired();
931 } 650 }
932 651
933 void MediaSourcePlayer::OnPrefetchDone() { 652 void MediaSourcePlayer::OnPrefetchDone() {
934 DVLOG(1) << __FUNCTION__; 653 DVLOG(1) << __FUNCTION__;
935 DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding()); 654 DCHECK(!audio_decoder_job_->is_decoding());
936 DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding()); 655 DCHECK(!video_decoder_job_->is_decoding());
937 656
938 // A previously posted OnPrefetchDone() could race against a Release(). If 657 // A previously posted OnPrefetchDone() could race against a Release(). If
939 // Release() won the race, we should no longer have decoder jobs. 658 // Release() won the race, we should no longer have decoder jobs.
940 // TODO(qinmin/wolenetz): Maintain channel state to not double-request data 659 // TODO(qinmin/wolenetz): Maintain channel state to not double-request data
941 // 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
942 // and http://crbug.com/304234. 661 // and http://crbug.com/304234.
943 if (!IsEventPending(PREFETCH_DONE_EVENT_PENDING)) { 662 if (!IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
944 DVLOG(1) << __FUNCTION__ << " : aborting"; 663 DVLOG(1) << __FUNCTION__ << " : aborting";
945 DCHECK(!audio_decoder_job_ && !video_decoder_job_);
946 return; 664 return;
947 } 665 }
948 666
949 ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING); 667 ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING);
950 668
951 if (pending_event_ != NO_EVENT_PENDING) { 669 if (pending_event_ != NO_EVENT_PENDING) {
952 ProcessPendingEvents(); 670 ProcessPendingEvents();
953 return; 671 return;
954 } 672 }
955 673
674 if (!playing_)
675 return;
676
956 start_time_ticks_ = base::TimeTicks::Now(); 677 start_time_ticks_ = base::TimeTicks::Now();
957 start_presentation_timestamp_ = GetCurrentTime(); 678 start_presentation_timestamp_ = GetCurrentTime();
958 if (!clock_.IsPlaying()) 679 if (!clock_.IsPlaying())
959 clock_.Play(); 680 clock_.Play();
960 681
961 if (!AudioFinished()) 682 if (!AudioFinished())
962 DecodeMoreAudio(); 683 DecodeMoreAudio();
963 684
964 if (!VideoFinished()) 685 if (!VideoFinished())
965 DecodeMoreVideo(); 686 DecodeMoreVideo();
687 }
966 688
967 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) 689 void MediaSourcePlayer::OnDemuxerConfigsChanged() {
968 ProcessPendingEvents(); 690 manager()->OnMediaMetadataChanged(
691 player_id(), duration_, GetVideoWidth(), GetVideoHeight(), true);
969 } 692 }
970 693
971 const char* MediaSourcePlayer::GetEventName(PendingEventFlags event) { 694 const char* MediaSourcePlayer::GetEventName(PendingEventFlags event) {
695 // Please keep this in sync with PendingEventFlags.
972 static const char* kPendingEventNames[] = { 696 static const char* kPendingEventNames[] = {
697 "PREFETCH_DONE",
973 "SEEK", 698 "SEEK",
974 "SURFACE_CHANGE", 699 "VIDEO_DECODER_CREATION",
975 "CONFIG_CHANGE",
976 "PREFETCH_REQUEST", 700 "PREFETCH_REQUEST",
977 "PREFETCH_DONE",
978 }; 701 };
979 702
980 int mask = 1; 703 int mask = 1;
981 for (size_t i = 0; i < arraysize(kPendingEventNames); ++i, mask <<= 1) { 704 for (size_t i = 0; i < arraysize(kPendingEventNames); ++i, mask <<= 1) {
982 if (event & mask) 705 if (event & mask)
983 return kPendingEventNames[i]; 706 return kPendingEventNames[i];
984 } 707 }
985 708
986 return "UNKNOWN"; 709 return "UNKNOWN";
987 } 710 }
(...skipping 11 matching lines...) Expand all
999 } 722 }
1000 723
1001 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { 724 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
1002 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; 725 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
1003 DCHECK_NE(event, NO_EVENT_PENDING); 726 DCHECK_NE(event, NO_EVENT_PENDING);
1004 DCHECK(IsEventPending(event)) << GetEventName(event); 727 DCHECK(IsEventPending(event)) << GetEventName(event);
1005 728
1006 pending_event_ &= ~event; 729 pending_event_ &= ~event;
1007 } 730 }
1008 731
1009 void MediaSourcePlayer::SetDemuxerConfigs(const DemuxerConfigs& configs, 732 void MediaSourcePlayer::OnDecodeError() {
1010 bool is_audio) { 733 manager()->OnError(player_id(), MEDIA_ERROR_DECODE);
1011 if (is_audio) {
1012 audio_codec_ = configs.audio_codec;
1013 num_channels_ = configs.audio_channels;
1014 sampling_rate_ = configs.audio_sampling_rate;
1015 is_audio_encrypted_ = configs.is_audio_encrypted;
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 } 734 }
1024 735
1025 } // namespace media 736 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698