Home | History | Annotate | Download | only in android
      1 // Copyright 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 #ifndef MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_
      6 #define MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_
      7 
      8 #include "base/callback.h"
      9 #include "base/memory/weak_ptr.h"
     10 #include "base/time/time.h"
     11 #include "media/base/android/demuxer_stream_player_params.h"
     12 #include "media/base/android/media_codec_bridge.h"
     13 
     14 namespace base {
     15 class MessageLoopProxy;
     16 }
     17 
     18 namespace media {
     19 
     20 // Class for managing all the decoding tasks. Each decoding task will be posted
     21 // onto the same thread. The thread will be stopped once Stop() is called.
     22 class MediaDecoderJob {
     23  public:
     24   struct Deleter {
     25     inline void operator()(MediaDecoderJob* ptr) const { ptr->Release(); }
     26   };
     27 
     28   // Callback when a decoder job finishes its work. Args: whether decode
     29   // finished successfully, presentation time, audio output bytes.
     30   // If the presentation time is equal to kNoTimestamp(), the decoder job
     31   // skipped rendering of the decoded output and the callback target should
     32   // update its clock to avoid introducing extra delays to the next frame.
     33   typedef base::Callback<void(MediaCodecStatus, const base::TimeDelta&,
     34                               size_t)> DecoderCallback;
     35   // Callback when a decoder job finishes releasing the output buffer.
     36   // Args: audio output bytes, must be 0 for video.
     37   typedef base::Callback<void(size_t)> ReleaseOutputCompletionCallback;
     38 
     39   virtual ~MediaDecoderJob();
     40 
     41   // Called by MediaSourcePlayer when more data for this object has arrived.
     42   void OnDataReceived(const DemuxerData& data);
     43 
     44   // Prefetch so we know the decoder job has data when we call Decode().
     45   // |prefetch_cb| - Run when prefetching has completed.
     46   void Prefetch(const base::Closure& prefetch_cb);
     47 
     48   // Called by MediaSourcePlayer to decode some data.
     49   // |callback| - Run when decode operation has completed.
     50   //
     51   // Returns true if the next decode was started and |callback| will be
     52   // called when the decode operation is complete.
     53   // Returns false if a config change is needed. |callback| is ignored
     54   // and will not be called.
     55   bool Decode(const base::TimeTicks& start_time_ticks,
     56               const base::TimeDelta& start_presentation_timestamp,
     57               const DecoderCallback& callback);
     58 
     59   // Called to stop the last Decode() early.
     60   // If the decoder is in the process of decoding the next frame, then
     61   // this method will just allow the decode to complete as normal. If
     62   // this object is waiting for a data request to complete, then this method
     63   // will wait for the data to arrive and then call the |callback|
     64   // passed to Decode() with a status of MEDIA_CODEC_STOPPED. This ensures that
     65   // the |callback| passed to Decode() is always called and the status
     66   // reflects whether data was actually decoded or the decode terminated early.
     67   void StopDecode();
     68 
     69   // Flush the decoder.
     70   void Flush();
     71 
     72   // Enter prerolling state. The job must not currently be decoding.
     73   void BeginPrerolling(const base::TimeDelta& preroll_timestamp);
     74 
     75   bool prerolling() const { return prerolling_; }
     76 
     77   bool is_decoding() const { return !decode_cb_.is_null(); }
     78 
     79  protected:
     80   MediaDecoderJob(const scoped_refptr<base::MessageLoopProxy>& decoder_loop,
     81                   MediaCodecBridge* media_codec_bridge,
     82                   const base::Closure& request_data_cb);
     83 
     84   // Release the output buffer at index |output_buffer_index| and render it if
     85   // |render_output| is true. Upon completion, |callback| will be called.
     86   virtual void ReleaseOutputBuffer(
     87       int output_buffer_index,
     88       size_t size,
     89       bool render_output,
     90       const ReleaseOutputCompletionCallback& callback) = 0;
     91 
     92   // Returns true if the "time to render" needs to be computed for frames in
     93   // this decoder job.
     94   virtual bool ComputeTimeToRender() const = 0;
     95 
     96  private:
     97   // Causes this instance to be deleted on the thread it is bound to.
     98   void Release();
     99 
    100   MediaCodecStatus QueueInputBuffer(const AccessUnit& unit);
    101 
    102   // Returns true if this object has data to decode.
    103   bool HasData() const;
    104 
    105   // Initiates a request for more data.
    106   // |done_cb| is called when more data is available in |received_data_|.
    107   void RequestData(const base::Closure& done_cb);
    108 
    109   // Posts a task to start decoding the next access unit in |received_data_|.
    110   void DecodeNextAccessUnit(
    111       const base::TimeTicks& start_time_ticks,
    112       const base::TimeDelta& start_presentation_timestamp);
    113 
    114   // Helper function to decoder data on |thread_|. |unit| contains all the data
    115   // to be decoded. |start_time_ticks| and |start_presentation_timestamp|
    116   // represent the system time and the presentation timestamp when the first
    117   // frame is rendered. We use these information to estimate when the current
    118   // frame should be rendered. If |needs_flush| is true, codec needs to be
    119   // flushed at the beginning of this call.
    120   void DecodeInternal(const AccessUnit& unit,
    121                       const base::TimeTicks& start_time_ticks,
    122                       const base::TimeDelta& start_presentation_timestamp,
    123                       bool needs_flush,
    124                       const DecoderCallback& callback);
    125 
    126   // Called on the UI thread to indicate that one decode cycle has completed.
    127   // Completes any pending job destruction or any pending decode stop. If
    128   // destruction was not pending, passes its arguments to |decode_cb_|.
    129   void OnDecodeCompleted(MediaCodecStatus status,
    130                          const base::TimeDelta& presentation_timestamp,
    131                          size_t audio_output_bytes);
    132 
    133   // The UI message loop where callbacks should be dispatched.
    134   scoped_refptr<base::MessageLoopProxy> ui_loop_;
    135 
    136   // The message loop that decoder job runs on.
    137   scoped_refptr<base::MessageLoopProxy> decoder_loop_;
    138 
    139   // The media codec bridge used for decoding. Owned by derived class.
    140   // NOTE: This MUST NOT be accessed in the destructor.
    141   MediaCodecBridge* media_codec_bridge_;
    142 
    143   // Whether the decoder needs to be flushed.
    144   bool needs_flush_;
    145 
    146   // Whether input EOS is encountered.
    147   // TODO(wolenetz/qinmin): Protect with a lock. See http://crbug.com/320043.
    148   bool input_eos_encountered_;
    149 
    150   // Whether output EOS is encountered.
    151   bool output_eos_encountered_;
    152 
    153   // Tracks whether DecodeInternal() should skip decoding if the first access
    154   // unit is EOS or empty, and report |MEDIA_CODEC_OUTPUT_END_OF_STREAM|. This
    155   // is to work around some decoders that could crash otherwise. See
    156   // http://b/11696552.
    157   bool skip_eos_enqueue_;
    158 
    159   // The timestamp the decoder needs to preroll to. If an access unit's
    160   // timestamp is smaller than |preroll_timestamp_|, don't render it.
    161   // TODO(qinmin): Comparing access unit's timestamp with |preroll_timestamp_|
    162   // is not very accurate.
    163   base::TimeDelta preroll_timestamp_;
    164 
    165   // Indicates prerolling state. If true, this job has not yet decoded output
    166   // that it will render, since the most recent of job construction or
    167   // BeginPrerolling(). If false, |preroll_timestamp_| has been reached.
    168   // TODO(qinmin): Comparing access unit's timestamp with |preroll_timestamp_|
    169   // is not very accurate.
    170   bool prerolling_;
    171 
    172   // Weak pointer passed to media decoder jobs for callbacks. It is bounded to
    173   // the decoder thread.
    174   base::WeakPtrFactory<MediaDecoderJob> weak_this_;
    175 
    176   // Callback used to request more data.
    177   base::Closure request_data_cb_;
    178 
    179   // Callback to run when new data has been received.
    180   base::Closure on_data_received_cb_;
    181 
    182   // Callback to run when the current Decode() operation completes.
    183   DecoderCallback decode_cb_;
    184 
    185   // The current access unit being processed.
    186   size_t access_unit_index_;
    187 
    188   // Data received over IPC from last RequestData() operation.
    189   DemuxerData received_data_;
    190 
    191   // The index of input buffer that can be used by QueueInputBuffer().
    192   // If the index is uninitialized or invalid, it must be -1.
    193   int input_buf_index_;
    194 
    195   bool stop_decode_pending_;
    196 
    197   // Indicates that this object should be destroyed once the current
    198   // Decode() has completed. This gets set when Release() gets called
    199   // while there is a decode in progress.
    200   bool destroy_pending_;
    201 
    202   DISALLOW_IMPLICIT_CONSTRUCTORS(MediaDecoderJob);
    203 };
    204 
    205 }  // namespace media
    206 
    207 #endif  // MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_
    208