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