diff options
author | qinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 19:55:24 +0000 |
---|---|---|
committer | qinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 19:55:24 +0000 |
commit | d19c472f0586c0619e5b3240e8b27a25e630fba6 (patch) | |
tree | e6cce568beef22f0bf6f3c324d5f250edafd8f3a /media/base/android/media_source_player.h | |
parent | 62269731005768be1dedf14968d69fb74faa524d (diff) | |
download | chromium_src-d19c472f0586c0619e5b3240e8b27a25e630fba6.zip chromium_src-d19c472f0586c0619e5b3240e8b27a25e630fba6.tar.gz chromium_src-d19c472f0586c0619e5b3240e8b27a25e630fba6.tar.bz2 |
Set start timestamps when StartIntnernal() is called.
The following changes are made in this CL:
1. Change wallclock_time_ to time_ticks_ due to recent change from base::Time to base::TimeTicks
2. When sending an IPC for data, if the data does not come back within the given timeout, we request both audio and video decoder to wait for data and start together when data arrives.
2. When startInternal is called, we request audio and video decoder job to start together. Previously there is a bug that video can start first without audio, and a/v lose sync afterwards.
BUG=233420
Review URL: https://chromiumcodereview.appspot.com/18080003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209758 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base/android/media_source_player.h')
-rw-r--r-- | media/base/android/media_source_player.h | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/media/base/android/media_source_player.h b/media/base/android/media_source_player.h index 5448e109..b3be398 100644 --- a/media/base/android/media_source_player.h +++ b/media/base/android/media_source_player.h @@ -12,13 +12,16 @@ #include "base/android/scoped_java_ref.h" #include "base/callback.h" +#include "base/cancelable_callback.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread.h" +#include "base/time/default_tick_clock.h" #include "base/time/time.h" #include "media/base/android/demuxer_stream_player_params.h" #include "media/base/android/media_codec_bridge.h" #include "media/base/android/media_player_android.h" +#include "media/base/clock.h" #include "media/base/media_export.h" namespace base { @@ -27,8 +30,9 @@ class MessageLoopProxy; namespace media { -class VideoDecoderJob; class AudioDecoderJob; +class AudioTimestampHelper; +class VideoDecoderJob; // Class for managing all the decoding tasks. Each decoding task will be posted // onto the same thread. The thread will be stopped once Stop() is called. @@ -43,15 +47,15 @@ class MediaDecoderJob { virtual ~MediaDecoderJob(); // Callback when a decoder job finishes its work. Args: whether decode - // finished successfully, presentation time, timestamp when the data is - // rendered, whether decoder is reaching EOS. + // finished successfully, presentation time, audio output bytes, whether + // decoder is reaching EOS. typedef base::Callback<void(DecodeStatus, const base::TimeDelta&, - const base::TimeTicks&, bool)> DecoderCallback; + size_t, bool)> DecoderCallback; // Called by MediaSourcePlayer to decode some data. void Decode( const MediaPlayerHostMsg_ReadFromDemuxerAck_Params::AccessUnit& unit, - const base::TimeTicks& start_wallclock_time, + const base::TimeTicks& start_time_ticks, const base::TimeDelta& start_presentation_timestamp, const MediaDecoderJob::DecoderCallback& callback); @@ -82,14 +86,14 @@ class MediaDecoderJob { bool end_of_stream, const MediaDecoderJob::DecoderCallback& callback); // Helper function to decoder data on |thread_|. |unit| contains all the data - // to be decoded. |start_wallclock_time| and |start_presentation_timestamp| + // to be decoded. |start_time_ticks| and |start_presentation_timestamp| // represent the system time and the presentation timestamp when the first // frame is rendered. We use these information to estimate when the current // frame should be rendered. If |needs_flush| is true, codec needs to be // flushed at the beginning of this call. void DecodeInternal( const MediaPlayerHostMsg_ReadFromDemuxerAck_Params::AccessUnit& unit, - const base::TimeTicks& start_wallclock_time, + const base::TimeTicks& start_time_ticks, const base::TimeDelta& start_presentation_timestamp, bool needs_flush, const MediaDecoderJob::DecoderCallback& callback); @@ -128,8 +132,7 @@ class MEDIA_EXPORT MediaSourcePlayer : public MediaPlayerAndroid { public: // Construct a MediaSourcePlayer object with all the needed media player // callbacks. - MediaSourcePlayer(int player_id, - MediaPlayerManager* manager); + MediaSourcePlayer(int player_id, MediaPlayerManager* manager); virtual ~MediaSourcePlayer(); // MediaPlayerAndroid implementation. @@ -157,10 +160,9 @@ class MEDIA_EXPORT MediaSourcePlayer : public MediaPlayerAndroid { virtual void SetDrmBridge(MediaDrmBridge* drm_bridge) OVERRIDE; private: - // Update the timestamps for A/V sync scheduling. - void UpdateTimestamps( - const base::TimeDelta& presentation_timestamp, - const base::TimeTicks& wallclock_time); + // Update the current timestamp. + void UpdateTimestamps(const base::TimeDelta& presentation_timestamp, + size_t audio_output_bytes); // Helper function for starting media playback. void StartInternal(); @@ -172,7 +174,7 @@ class MEDIA_EXPORT MediaSourcePlayer : public MediaPlayerAndroid { void MediaDecoderCallback( bool is_audio, MediaDecoderJob::DecodeStatus decode_status, const base::TimeDelta& presentation_timestamp, - const base::TimeTicks& wallclock_time, bool end_of_stream); + size_t audio_output_bytes, bool end_of_stream); // Handle pending events when all the decoder jobs finished. void ProcessPendingEvents(); @@ -195,6 +197,27 @@ class MEDIA_EXPORT MediaSourcePlayer : public MediaPlayerAndroid { // Determine seekability based on duration. bool Seekable(); + // Called when the |decoder_starvation_callback_| times out. + void OnDecoderStarved(); + + // Starts the |decoder_starvation_callback_| task with the timeout value. + void StartStarvationCallback(const base::TimeDelta& timeout); + + // Called to sync decoder jobs. This call requests data from chunk demuxer + // first. Then it updates |start_time_ticks_| and + // |start_presentation_timestamp_| so that video can resync with audio. + void SyncAndStartDecoderJobs(); + + // Functions that send IPC requests to the renderer process for more + // audio/video data. Returns true if a request has been sent and the decoder + // needs to wait, or false otherwise. + void RequestAudioData(); + void RequestVideoData(); + + // Check whether audio or video data is available for decoders to consume. + bool HasAudioData() const; + bool HasVideoData() const; + enum PendingEventFlags { NO_EVENT_PENDING = 0, SEEK_EVENT_PENDING = 1 << 0, @@ -215,7 +238,6 @@ class MEDIA_EXPORT MediaSourcePlayer : public MediaPlayerAndroid { VideoCodec video_codec_; int num_channels_; int sampling_rate_; - base::TimeDelta last_presentation_timestamp_; std::vector<uint8> audio_extra_data_; bool audio_finished_; bool video_finished_; @@ -223,13 +245,19 @@ class MEDIA_EXPORT MediaSourcePlayer : public MediaPlayerAndroid { bool is_audio_encrypted_; bool is_video_encrypted_; + // base::TickClock used by |clock_|. + base::DefaultTickClock default_tick_clock_; + + // Reference clock. Keeps track of current playback time. + Clock clock_; + // Timestamps for providing simple A/V sync. When start decoding an audio // chunk, we record its presentation timestamp and the current system time. // Then we use this information to estimate when the next audio/video frame // should be rendered. // TODO(qinmin): Need to fix the problem if audio/video lagged too far behind // due to network or decoding problem. - base::TimeTicks start_wallclock_time_; + base::TimeTicks start_time_ticks_; base::TimeDelta start_presentation_timestamp_; // The surface object currently owned by the player. @@ -252,6 +280,17 @@ class MEDIA_EXPORT MediaSourcePlayer : public MediaPlayerAndroid { MediaPlayerHostMsg_ReadFromDemuxerAck_Params received_audio_; MediaPlayerHostMsg_ReadFromDemuxerAck_Params received_video_; + // A cancelable task that is posted when the audio decoder starts requesting + // new data. This callback runs if no data arrives before the timeout period + // elapses. + base::CancelableClosure decoder_starvation_callback_; + + // Whether the audio and video decoder jobs should resync with each other. + bool sync_decoder_jobs_; + + // Object to calculate the current audio timestamp for A/V sync. + scoped_ptr<AudioTimestampHelper> audio_timestamp_helper_; + // Weak pointer passed to media decoder jobs for callbacks. base::WeakPtrFactory<MediaSourcePlayer> weak_this_; |