Index: media/base/android/media_codec_decoder.cc |
diff --git a/media/base/android/media_codec_decoder.cc b/media/base/android/media_codec_decoder.cc |
index 6d7119f408590b5372261766708adb741119b779..026df89dd3642a394c9ff9b8b84b9aa5755153e6 100644 |
--- a/media/base/android/media_codec_decoder.cc |
+++ b/media/base/android/media_codec_decoder.cc |
@@ -50,7 +50,7 @@ MediaCodecDecoder::MediaCodecDecoder( |
stop_done_cb_(stop_done_cb), |
error_cb_(error_cb), |
state_(kStopped), |
- preroll_mode_(kPrerollTillPTS), |
+ is_prepared_(false), |
eos_enqueued_(false), |
completed_(false), |
last_frame_posted_(false), |
@@ -104,7 +104,7 @@ void MediaCodecDecoder::Flush() { |
verify_next_frame_is_key_ = true; |
#endif |
- preroll_mode_ = kPrerollTillPTS; |
+ is_prepared_ = false; |
if (media_codec_bridge_) { |
// MediaCodecBridge::Reset() performs MediaCodecBridge.flush() |
@@ -123,7 +123,7 @@ void MediaCodecDecoder::ReleaseMediaCodec() { |
DVLOG(1) << class_name() << "::" << __FUNCTION__; |
media_codec_bridge_.reset(); |
- preroll_mode_ = kPrerollTillPTS; |
+ is_prepared_ = false; |
qinmin
2015/09/03 05:30:04
this variable is updated on both decoder thread an
Tima Vaisburd
2015/09/03 19:55:27
During Flush() and ReleaseMediaCodec() the decoder
|
} |
bool MediaCodecDecoder::IsPrefetchingOrPlaying() const { |
@@ -163,14 +163,15 @@ bool MediaCodecDecoder::IsCompleted() const { |
bool MediaCodecDecoder::NotCompletedAndNeedsPreroll() const { |
DCHECK(media_task_runner_->BelongsToCurrentThread()); |
- return HasStream() && preroll_mode_ != kNoPreroll && !completed_; |
+ return HasStream() && !completed_ && |
+ (!is_prepared_ || preroll_timestamp_ != base::TimeDelta()); |
} |
-void MediaCodecDecoder::SetDecodingUntilOutputIsPresent() { |
+void MediaCodecDecoder::SetPrerollTimestamp(base::TimeDelta preroll_timestamp) { |
DCHECK(media_task_runner_->BelongsToCurrentThread()); |
- DVLOG(1) << class_name() << "::" << __FUNCTION__; |
+ DVLOG(1) << class_name() << "::" << __FUNCTION__ << ": " << preroll_timestamp; |
- preroll_mode_ = kPrerollTillOutputIsPresent; |
+ preroll_timestamp_ = preroll_timestamp; |
} |
base::android::ScopedJavaLocalRef<jobject> MediaCodecDecoder::GetMediaCrypto() { |
@@ -242,12 +243,11 @@ MediaCodecDecoder::ConfigStatus MediaCodecDecoder::Configure() { |
return result; |
} |
-bool MediaCodecDecoder::Preroll(base::TimeDelta preroll_timestamp, |
- const base::Closure& preroll_done_cb) { |
+bool MediaCodecDecoder::Preroll(const base::Closure& preroll_done_cb) { |
DCHECK(media_task_runner_->BelongsToCurrentThread()); |
DVLOG(1) << class_name() << "::" << __FUNCTION__ |
- << " preroll_timestamp:" << preroll_timestamp; |
+ << " preroll_timestamp:" << preroll_timestamp_; |
DecoderState state = GetState(); |
if (state != kPrefetched) { |
@@ -263,16 +263,12 @@ bool MediaCodecDecoder::Preroll(base::TimeDelta preroll_timestamp, |
} |
DCHECK(!decoder_thread_.IsRunning()); |
- DCHECK(preroll_mode_ != kNoPreroll); |
preroll_done_cb_ = preroll_done_cb; |
// We only synchronize video stream. |
DissociatePTSFromTime(); // associaton will happen after preroll is done. |
- preroll_timestamp_ = (preroll_mode_ == kPrerollTillPTS) ? preroll_timestamp |
- : base::TimeDelta(); |
- |
last_frame_posted_ = false; |
// Start the decoder thread |
@@ -313,7 +309,7 @@ bool MediaCodecDecoder::Start(base::TimeDelta start_timestamp) { |
// We only synchronize video stream. |
AssociateCurrentTimeWithPTS(start_timestamp); |
- preroll_timestamp_ = base::TimeDelta(); |
+ // preroll_timestamp_ = base::TimeDelta(); |
qinmin
2015/09/03 05:30:04
remove this if unused
Tima Vaisburd
2015/09/03 19:55:26
Replaced with
DCHECK(preroll_timestamp_ == base:
|
// Start the decoder thread |
if (!decoder_thread_.IsRunning()) { |
@@ -399,16 +395,18 @@ void MediaCodecDecoder::OnLastFrameRendered(bool eos_encountered) { |
SetState(kStopped); |
completed_ = (eos_encountered && !drain_decoder_); |
+ // If the stream is completed during preroll we need to report it since |
+ // another stream might be running and the player waits for two callbacks. |
if (completed_ && !preroll_done_cb_.is_null()) { |
+ preroll_timestamp_ = base::TimeDelta(); |
media_task_runner_->PostTask(FROM_HERE, |
base::ResetAndReturn(&preroll_done_cb_)); |
} |
if (eos_encountered && drain_decoder_) { |
- ReleaseMediaCodec(); |
drain_decoder_ = false; |
eos_enqueued_ = false; |
- preroll_mode_ = kPrerollTillOutputIsPresent; |
+ ReleaseMediaCodec(); |
media_task_runner_->PostTask(FROM_HERE, decoder_drained_cb_); |
} |
@@ -420,14 +418,14 @@ void MediaCodecDecoder::OnPrerollDone() { |
DVLOG(1) << class_name() << "::" << __FUNCTION__; |
- preroll_mode_ = kNoPreroll; |
+ preroll_timestamp_ = base::TimeDelta(); |
- // The state might be kStopping. |
- if (GetState() == kPrerolling) { |
+ // The state might be kStopping (?) |
+ if (GetState() == kPrerolling) |
SetState(kPrerolled); |
- media_task_runner_->PostTask(FROM_HERE, |
- base::ResetAndReturn(&preroll_done_cb_)); |
- } |
+ |
+ if (!preroll_done_cb_.is_null()) |
+ base::ResetAndReturn(&preroll_done_cb_).Run(); |
} |
void MediaCodecDecoder::OnDemuxerDataAvailable(const DemuxerData& data) { |
@@ -578,6 +576,7 @@ void MediaCodecDecoder::ProcessNextFrame() { |
// We can stop processing, the |au_queue_| and MediaCodec queues can freeze. |
// We only need to let finish the delayed rendering tasks. |
+ DVLOG(1) << class_name() << "::" << __FUNCTION__ << " kStopping, returning"; |
return; |
} |
@@ -797,6 +796,8 @@ bool MediaCodecDecoder::DepleteOutputBufferQueue() { |
case MEDIA_CODEC_OK: |
// We got the decoded frame. |
+ is_prepared_ = true; |
+ |
if (pts < preroll_timestamp_) |
render_mode = kRenderSkip; |
else if (GetState() == kPrerolling) |