| Index: media/base/android/media_decoder_job.h
|
| diff --git a/media/base/android/media_decoder_job.h b/media/base/android/media_decoder_job.h
|
| index 9dbbd00fceaba8c1a222fabfd6e95c0fce8749b1..6542ba41f0b193fe1943ee09d68d34842aaaa19b 100644
|
| --- a/media/base/android/media_decoder_job.h
|
| +++ b/media/base/android/media_decoder_job.h
|
| @@ -10,6 +10,7 @@
|
| #include "base/time/time.h"
|
| #include "media/base/android/demuxer_stream_player_params.h"
|
| #include "media/base/android/media_codec_bridge.h"
|
| +#include "ui/gl/android/scoped_java_surface.h"
|
|
|
| namespace base {
|
| class SingleThreadTaskRunner;
|
| @@ -17,6 +18,8 @@ class SingleThreadTaskRunner;
|
|
|
| namespace media {
|
|
|
| +class MediaDrmBridge;
|
| +
|
| // 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.
|
| // Data is stored in 2 chunks. When new data arrives, it is always stored in
|
| @@ -56,8 +59,8 @@ class MediaDecoderJob {
|
| //
|
| // Returns true if the next decode was started and |callback| will be
|
| // called when the decode operation is complete.
|
| - // Returns false if a config change is needed. |callback| is ignored
|
| - // and will not be called.
|
| + // Returns false if |media_codec_bridge_| cannot be created. |callback| is
|
| + // ignored and will not be called.
|
| bool Decode(base::TimeTicks start_time_ticks,
|
| base::TimeDelta start_presentation_timestamp,
|
| const DecoderCallback& callback);
|
| @@ -72,25 +75,42 @@ class MediaDecoderJob {
|
| // reflects whether data was actually decoded or the decode terminated early.
|
| void StopDecode();
|
|
|
| - // Flush the decoder.
|
| + // Flushes the decoder and abandons all the data that is being decoded.
|
| void Flush();
|
|
|
| // Enter prerolling state. The job must not currently be decoding.
|
| void BeginPrerolling(base::TimeDelta preroll_timestamp);
|
|
|
| - bool prerolling() const { return prerolling_; }
|
| + // Releases all the decoder resources as the current tab is going background.
|
| + virtual void ReleaseDecoderResources();
|
| +
|
| + // Sets the demuxer configs. Returns true if configs has changed, or false
|
| + // otherwise.
|
| + virtual bool SetDemuxerConfigs(const DemuxerConfigs& configs);
|
| +
|
| + // Returns whether the decoder has finished decoding all the data.
|
| + bool OutputEOSReached() const;
|
| +
|
| + // Returns true if the audio/video stream is available, implemented by child
|
| + // classes.
|
| + virtual bool HasStream() const = 0;
|
|
|
| bool is_decoding() const { return !decode_cb_.is_null(); }
|
|
|
| - bool is_requesting_demuxer_data() const {
|
| - return is_requesting_demuxer_data_;
|
| - }
|
| + void set_drm_bridge(MediaDrmBridge* drm_bridge) { drm_bridge_ = drm_bridge; }
|
| +
|
| + bool is_content_encrypted() const { return is_content_encrypted_; }
|
|
|
| protected:
|
| + // Creates a new MediaDecoderJob instance.
|
| + // |decoder_task_runner| - Thread on which the decoder task will run.
|
| + // |request_data_cb| - Callback to request more data for the decoder.
|
| + // |on_demuxer_config_changed_cb| - Callback to inform the caller that
|
| + // demuxer config has changed.
|
| MediaDecoderJob(
|
| const scoped_refptr<base::SingleThreadTaskRunner>& decoder_task_runner,
|
| - MediaCodecBridge* media_codec_bridge,
|
| - const base::Closure& request_data_cb);
|
| + const base::Closure& request_data_cb,
|
| + const base::Closure& on_demuxer_config_changed_cb);
|
|
|
| // Release the output buffer at index |output_buffer_index| and render it if
|
| // |render_output| is true. Upon completion, |callback| will be called.
|
| @@ -105,13 +125,32 @@ class MediaDecoderJob {
|
| // this decoder job.
|
| virtual bool ComputeTimeToRender() const = 0;
|
|
|
| + // Gets MediaCrypto object from |drm_bridge_|.
|
| + base::android::ScopedJavaLocalRef<jobject> GetMediaCrypto();
|
| +
|
| + // Releases the |media_codec_bridge_|.
|
| + void ReleaseMediaCodecBridge();
|
| +
|
| + MediaDrmBridge* drm_bridge() { return drm_bridge_; }
|
| +
|
| + void set_is_content_encrypted(bool is_content_encrypted) {
|
| + is_content_encrypted_ = is_content_encrypted;
|
| + }
|
| +
|
| + bool need_to_reconfig_decoder_job_;
|
| +
|
| + scoped_ptr<MediaCodecBridge> media_codec_bridge_;
|
| +
|
| private:
|
| friend class MediaSourcePlayerTest;
|
|
|
| // Causes this instance to be deleted on the thread it is bound to.
|
| void Release();
|
|
|
| - MediaCodecStatus QueueInputBuffer(const AccessUnit& unit);
|
| + // Queues an access unit into |media_codec_bridge_|'s input buffer. If
|
| + // |drain_decoder| is true, the access unit is replaced with an EOS unit so
|
| + // that we can drain the current buffer in |media_codec_bridge_|.
|
| + MediaCodecStatus QueueInputBuffer(const AccessUnit& unit, bool drain_decoder);
|
|
|
| // Returns true if this object has data to decode.
|
| bool HasData() const;
|
| @@ -135,6 +174,7 @@ class MediaDecoderJob {
|
| base::TimeTicks start_time_ticks,
|
| base::TimeDelta start_presentation_timestamp,
|
| bool needs_flush,
|
| + bool drain_decoder,
|
| const DecoderCallback& callback);
|
|
|
| // Called on the UI thread to indicate that one decode cycle has completed.
|
| @@ -147,22 +187,43 @@ class MediaDecoderJob {
|
| // Helper function to get the current access unit that is being decoded.
|
| const AccessUnit& CurrentAccessUnit() const;
|
|
|
| - // Check whether a chunk has no remaining access units to decode. If
|
| + // Checks whether a chunk has no remaining access units to decode. If
|
| // |is_active_chunk| is true, this function returns whether decoder has
|
| // consumed all data in |received_data_[current_demuxer_data_index_]|.
|
| // Otherwise, it returns whether decoder has consumed all data in the inactive
|
| // chunk.
|
| bool NoAccessUnitsRemainingInChunk(bool is_active_chunk) const;
|
|
|
| - // Clearn all the received data.
|
| - void ClearData();
|
| -
|
| - // Request new data for the current chunk if it runs out of data.
|
| + // Requests new data for the current chunk if it runs out of data.
|
| void RequestCurrentChunkIfEmpty();
|
|
|
| - // Initialize |received_data_| and |access_unit_index_|.
|
| + // Initializes |received_data_| and |access_unit_index_|.
|
| void InitializeReceivedData();
|
|
|
| + void OnDecoderDrained();
|
| +
|
| + // Creates |media_codec_bridge_| for decoding purpose.
|
| + bool CreateMediaCodecBridge();
|
| +
|
| + // Called when an access unit is consumed by the decoder. |is_config_change|
|
| + // indicates whether the current access unit is a config change. If it is
|
| + // true, the next access unit is guarateed to be an I-frame.
|
| + virtual void CurrentDataConsumed(bool is_config_change) {}
|
| +
|
| + // Called when |media_codec_bridge_| is released
|
| + virtual void OnMediaCodecBridgeReleased() {}
|
| +
|
| + // Implemented by the child class to create |media_codec_bridge_| for a
|
| + // particular stream.
|
| + virtual bool CreateMediaCodecBridgeInternal() = 0;
|
| +
|
| + // Returns true if the |configs| doesn't match the current demuxer configs
|
| + // the decoder job has.
|
| + virtual bool IsDemuxerConfigChanged(const DemuxerConfigs& configs) const = 0;
|
| +
|
| + // Update the demuxer configs.
|
| + virtual void UpdateDemuxerConfigs(const DemuxerConfigs& configs) = 0;
|
| +
|
| // Return the index to |received_data_| that is not currently being decoded.
|
| size_t inactive_demuxer_data_index() const {
|
| return 1 - current_demuxer_data_index_;
|
| @@ -174,10 +235,6 @@ class MediaDecoderJob {
|
| // The task runner that decoder job runs on.
|
| scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner_;
|
|
|
| - // The media codec bridge used for decoding. Owned by derived class.
|
| - // NOTE: This MUST NOT be accessed in the destructor.
|
| - MediaCodecBridge* media_codec_bridge_;
|
| -
|
| // Whether the decoder needs to be flushed.
|
| bool needs_flush_;
|
|
|
| @@ -210,6 +267,9 @@ class MediaDecoderJob {
|
| // Callback used to request more data.
|
| base::Closure request_data_cb_;
|
|
|
| + // Callback to notify the caller config has changed.
|
| + base::Closure on_demuxer_config_changed_cb_;
|
| +
|
| // Callback to run when new data has been received.
|
| base::Closure on_data_received_cb_;
|
|
|
| @@ -234,6 +294,11 @@ class MediaDecoderJob {
|
| // If the index is uninitialized or invalid, it must be -1.
|
| int input_buf_index_;
|
|
|
| + // Indicates whether content is encrypted.
|
| + bool is_content_encrypted_;
|
| +
|
| + // Indicates the decoder job should stop after decoding the current access
|
| + // unit.
|
| bool stop_decode_pending_;
|
|
|
| // Indicates that this object should be destroyed once the current
|
| @@ -247,10 +312,17 @@ class MediaDecoderJob {
|
| // Indicates whether the incoming data should be ignored.
|
| bool is_incoming_data_invalid_;
|
|
|
| - // Weak pointer passed to media decoder jobs for callbacks. It is bounded to
|
| - // the decoder thread.
|
| - // NOTE: Weak pointers must be invalidated before all other member variables.
|
| - base::WeakPtrFactory<MediaDecoderJob> weak_factory_;
|
| + // Indicates that |media_codec_bridge_| should be released once the current
|
| + // Decode() has completed. This gets set when ReleaseDecoderResources() gets
|
| + // called while there is a decode in progress.
|
| + bool release_resources_pending_;
|
| +
|
| + // Pointer to a DRM object that will be used for encrypted streams.
|
| + MediaDrmBridge* drm_bridge_;
|
| +
|
| + // Indicates whether |media_codec_bridge_| is in the middle of being drained
|
| + // due to a config change.
|
| + bool drain_decoder_;
|
|
|
| DISALLOW_IMPLICIT_CONSTRUCTORS(MediaDecoderJob);
|
| };
|
|
|