Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / media / base / android / media_source_player.cc
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
35 bool MediaSourcePlayer::IsTypeSupported(
36     const std::vector<uint8>& scheme_uuid,
37     MediaDrmBridge::SecurityLevel 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
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
95 MediaSourcePlayer::~MediaSourcePlayer() {
96   Release();
97 }
98
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
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
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
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
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
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
193 bool MediaSourcePlayer::IsPlaying() {
194   return playing_;
195 }
196
197 int MediaSourcePlayer::GetVideoWidth() {
198   return width_;
199 }
200
201 int MediaSourcePlayer::GetVideoHeight() {
202   return height_;
203 }
204
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
224 base::TimeDelta MediaSourcePlayer::GetCurrentTime() {
225   return clock_.Elapsed();
226 }
227
228 base::TimeDelta MediaSourcePlayer::GetDuration() {
229   return duration_;
230 }
231
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
269 void MediaSourcePlayer::SetVolume(double volume) {
270   volume_ = volume;
271   SetVolumeInternal();
272 }
273
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
284 bool MediaSourcePlayer::CanPause() {
285   return Seekable();
286 }
287
288 bool MediaSourcePlayer::CanSeekForward() {
289   return Seekable();
290 }
291
292 bool MediaSourcePlayer::CanSeekBackward() {
293   return Seekable();
294 }
295
296 bool MediaSourcePlayer::IsPlayerReady() {
297   return audio_decoder_job_ || video_decoder_job_;
298 }
299
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
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
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
379 void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) {
380   duration_ = duration;
381   clock_.SetDuration(duration_);
382 }
383
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
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
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
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
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
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
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
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
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
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
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
754 bool MediaSourcePlayer::HasVideo() {
755   return kUnknownVideoCodec != video_codec_;
756 }
757
758 bool MediaSourcePlayer::HasAudio() {
759   return kUnknownAudioCodec != audio_codec_;
760 }
761
762 bool MediaSourcePlayer::AudioFinished() {
763   return reached_audio_eos_ || !HasAudio();
764 }
765
766 bool MediaSourcePlayer::VideoFinished() {
767   return reached_video_eos_ || !HasVideo();
768 }
769
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
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
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
875 void MediaSourcePlayer::OnDecoderStarved() {
876   DVLOG(1) << __FUNCTION__;
877   SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
878   ProcessPendingEvents();
879 }
880
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
913 void MediaSourcePlayer::SetVolumeInternal() {
914   if (audio_decoder_job_ && volume_ >= 0)
915     audio_decoder_job_->SetVolume(volume_);
916 }
917
918 bool MediaSourcePlayer::IsProtectedSurfaceRequired() {
919   return is_video_encrypted_ &&
920       drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired();
921 }
922
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
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
976 bool MediaSourcePlayer::IsEventPending(PendingEventFlags event) const {
977   return pending_event_ & event;
978 }
979
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
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