- add sources.
[platform/framework/web/crosswalk.git] / src / media / base / android / media_decoder_job.h
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   bool input_eos_encountered_;
148
149   // The timestamp the decoder needs to preroll to. If an access unit's
150   // timestamp is smaller than |preroll_timestamp_|, don't render it.
151   // TODO(qinmin): Comparing access unit's timestamp with |preroll_timestamp_|
152   // is not very accurate.
153   base::TimeDelta preroll_timestamp_;
154
155   // Indicates prerolling state. If true, this job has not yet decoded output
156   // that it will render, since the most recent of job construction or
157   // BeginPrerolling(). If false, |preroll_timestamp_| has been reached.
158   // TODO(qinmin): Comparing access unit's timestamp with |preroll_timestamp_|
159   // is not very accurate.
160   bool prerolling_;
161
162   // Weak pointer passed to media decoder jobs for callbacks. It is bounded to
163   // the decoder thread.
164   base::WeakPtrFactory<MediaDecoderJob> weak_this_;
165
166   // Callback used to request more data.
167   base::Closure request_data_cb_;
168
169   // Callback to run when new data has been received.
170   base::Closure on_data_received_cb_;
171
172   // Callback to run when the current Decode() operation completes.
173   DecoderCallback decode_cb_;
174
175   // The current access unit being processed.
176   size_t access_unit_index_;
177
178   // Data received over IPC from last RequestData() operation.
179   DemuxerData received_data_;
180
181   // The index of input buffer that can be used by QueueInputBuffer().
182   // If the index is uninitialized or invalid, it must be -1.
183   int input_buf_index_;
184
185   bool stop_decode_pending_;
186
187   // Indicates that this object should be destroyed once the current
188   // Decode() has completed. This gets set when Release() gets called
189   // while there is a decode in progress.
190   bool destroy_pending_;
191
192   DISALLOW_IMPLICIT_CONSTRUCTORS(MediaDecoderJob);
193 };
194
195 }  // namespace media
196
197 #endif  // MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_