Upstream version 7.36.149.0
[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 SingleThreadTaskRunner;
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 // Data is stored in 2 chunks. When new data arrives, it is always stored in
23 // an inactive chunk. And when the current active chunk becomes empty, a new
24 // data request will be sent to the renderer.
25 class MediaDecoderJob {
26  public:
27   struct Deleter {
28     inline void operator()(MediaDecoderJob* ptr) const { ptr->Release(); }
29   };
30
31   // Callback when a decoder job finishes its work. Args: whether decode
32   // finished successfully, current presentation time, max presentation time.
33   // If the current presentation time is equal to kNoTimestamp(), the decoder
34   // job skipped rendering of the decoded output and the callback target should
35   // ignore the timestamps provided.
36   typedef base::Callback<void(MediaCodecStatus, base::TimeDelta,
37                               base::TimeDelta)> DecoderCallback;
38   // Callback when a decoder job finishes releasing the output buffer.
39   // Args: current presentation time, max presentation time.
40   // If the current presentation time is equal to kNoTimestamp(), the callback
41   // target should ignore the timestamps provided.
42   typedef base::Callback<void(base::TimeDelta, base::TimeDelta)>
43       ReleaseOutputCompletionCallback;
44
45   virtual ~MediaDecoderJob();
46
47   // Called by MediaSourcePlayer when more data for this object has arrived.
48   void OnDataReceived(const DemuxerData& data);
49
50   // Prefetch so we know the decoder job has data when we call Decode().
51   // |prefetch_cb| - Run when prefetching has completed.
52   void Prefetch(const base::Closure& prefetch_cb);
53
54   // Called by MediaSourcePlayer to decode some data.
55   // |callback| - Run when decode operation has completed.
56   //
57   // Returns true if the next decode was started and |callback| will be
58   // called when the decode operation is complete.
59   // Returns false if a config change is needed. |callback| is ignored
60   // and will not be called.
61   bool Decode(base::TimeTicks start_time_ticks,
62               base::TimeDelta start_presentation_timestamp,
63               const DecoderCallback& callback);
64
65   // Called to stop the last Decode() early.
66   // If the decoder is in the process of decoding the next frame, then
67   // this method will just allow the decode to complete as normal. If
68   // this object is waiting for a data request to complete, then this method
69   // will wait for the data to arrive and then call the |callback|
70   // passed to Decode() with a status of MEDIA_CODEC_STOPPED. This ensures that
71   // the |callback| passed to Decode() is always called and the status
72   // reflects whether data was actually decoded or the decode terminated early.
73   void StopDecode();
74
75   // Flush the decoder.
76   void Flush();
77
78   // Enter prerolling state. The job must not currently be decoding.
79   void BeginPrerolling(base::TimeDelta preroll_timestamp);
80
81   bool prerolling() const { return prerolling_; }
82
83   bool is_decoding() const { return !decode_cb_.is_null(); }
84
85   bool is_requesting_demuxer_data() const {
86     return is_requesting_demuxer_data_;
87   }
88
89  protected:
90   MediaDecoderJob(
91       const scoped_refptr<base::SingleThreadTaskRunner>& decoder_task_runner,
92       MediaCodecBridge* media_codec_bridge,
93       const base::Closure& request_data_cb);
94
95   // Release the output buffer at index |output_buffer_index| and render it if
96   // |render_output| is true. Upon completion, |callback| will be called.
97   virtual void ReleaseOutputBuffer(
98       int output_buffer_index,
99       size_t size,
100       bool render_output,
101       base::TimeDelta current_presentation_timestamp,
102       const ReleaseOutputCompletionCallback& callback) = 0;
103
104   // Returns true if the "time to render" needs to be computed for frames in
105   // this decoder job.
106   virtual bool ComputeTimeToRender() const = 0;
107
108  private:
109   friend class MediaSourcePlayerTest;
110
111   // Causes this instance to be deleted on the thread it is bound to.
112   void Release();
113
114   MediaCodecStatus QueueInputBuffer(const AccessUnit& unit);
115
116   // Returns true if this object has data to decode.
117   bool HasData() const;
118
119   // Initiates a request for more data.
120   // |done_cb| is called when more data is available in |received_data_|.
121   void RequestData(const base::Closure& done_cb);
122
123   // Posts a task to start decoding the current access unit in |received_data_|.
124   void DecodeCurrentAccessUnit(
125       base::TimeTicks start_time_ticks,
126       base::TimeDelta start_presentation_timestamp);
127
128   // Helper function to decoder data on |thread_|. |unit| contains all the data
129   // to be decoded. |start_time_ticks| and |start_presentation_timestamp|
130   // represent the system time and the presentation timestamp when the first
131   // frame is rendered. We use these information to estimate when the current
132   // frame should be rendered. If |needs_flush| is true, codec needs to be
133   // flushed at the beginning of this call.
134   void DecodeInternal(const AccessUnit& unit,
135                       base::TimeTicks start_time_ticks,
136                       base::TimeDelta start_presentation_timestamp,
137                       bool needs_flush,
138                       const DecoderCallback& callback);
139
140   // Called on the UI thread to indicate that one decode cycle has completed.
141   // Completes any pending job destruction or any pending decode stop. If
142   // destruction was not pending, passes its arguments to |decode_cb_|.
143   void OnDecodeCompleted(MediaCodecStatus status,
144                          base::TimeDelta current_presentation_timestamp,
145                          base::TimeDelta max_presentation_timestamp);
146
147   // Helper function to get the current access unit that is being decoded.
148   const AccessUnit& CurrentAccessUnit() const;
149
150   // Check whether a chunk has no remaining access units to decode. If
151   // |is_active_chunk| is true, this function returns whether decoder has
152   // consumed all data in |received_data_[current_demuxer_data_index_]|.
153   // Otherwise, it returns whether decoder has consumed all data in the inactive
154   // chunk.
155   bool NoAccessUnitsRemainingInChunk(bool is_active_chunk) const;
156
157   // Clearn all the received data.
158   void ClearData();
159
160   // Request new data for the current chunk if it runs out of data.
161   void RequestCurrentChunkIfEmpty();
162
163   // Initialize |received_data_| and |access_unit_index_|.
164   void InitializeReceivedData();
165
166   // Return the index to |received_data_| that is not currently being decoded.
167   size_t inactive_demuxer_data_index() const {
168     return 1 - current_demuxer_data_index_;
169   }
170
171   // The UI message loop where callbacks should be dispatched.
172   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
173
174   // The task runner that decoder job runs on.
175   scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner_;
176
177   // The media codec bridge used for decoding. Owned by derived class.
178   // NOTE: This MUST NOT be accessed in the destructor.
179   MediaCodecBridge* media_codec_bridge_;
180
181   // Whether the decoder needs to be flushed.
182   bool needs_flush_;
183
184   // Whether input EOS is encountered.
185   // TODO(wolenetz/qinmin): Protect with a lock. See http://crbug.com/320043.
186   bool input_eos_encountered_;
187
188   // Whether output EOS is encountered.
189   bool output_eos_encountered_;
190
191   // Tracks whether DecodeInternal() should skip decoding if the first access
192   // unit is EOS or empty, and report |MEDIA_CODEC_OUTPUT_END_OF_STREAM|. This
193   // is to work around some decoders that could crash otherwise. See
194   // http://b/11696552.
195   bool skip_eos_enqueue_;
196
197   // The timestamp the decoder needs to preroll to. If an access unit's
198   // timestamp is smaller than |preroll_timestamp_|, don't render it.
199   // TODO(qinmin): Comparing access unit's timestamp with |preroll_timestamp_|
200   // is not very accurate.
201   base::TimeDelta preroll_timestamp_;
202
203   // Indicates prerolling state. If true, this job has not yet decoded output
204   // that it will render, since the most recent of job construction or
205   // BeginPrerolling(). If false, |preroll_timestamp_| has been reached.
206   // TODO(qinmin): Comparing access unit's timestamp with |preroll_timestamp_|
207   // is not very accurate.
208   bool prerolling_;
209
210   // Callback used to request more data.
211   base::Closure request_data_cb_;
212
213   // Callback to run when new data has been received.
214   base::Closure on_data_received_cb_;
215
216   // Callback to run when the current Decode() operation completes.
217   DecoderCallback decode_cb_;
218
219   // Data received over IPC from last RequestData() operation.
220   // We keep 2 chunks at the same time to reduce the IPC latency between chunks.
221   // If data inside the current chunk are all decoded, we will request a new
222   // chunk from the demuxer and swap the current chunk with the other one.
223   // New data will always be stored in the other chunk since the current
224   // one may be still in use.
225   DemuxerData received_data_[2];
226
227   // Index to the current data chunk that is being decoded.
228   size_t current_demuxer_data_index_;
229
230   // Index to the access unit inside each data chunk that is being decoded.
231   size_t access_unit_index_[2];
232
233   // The index of input buffer that can be used by QueueInputBuffer().
234   // If the index is uninitialized or invalid, it must be -1.
235   int input_buf_index_;
236
237   bool stop_decode_pending_;
238
239   // Indicates that this object should be destroyed once the current
240   // Decode() has completed. This gets set when Release() gets called
241   // while there is a decode in progress.
242   bool destroy_pending_;
243
244   // Indicates whether the decoder is in the middle of requesting new data.
245   bool is_requesting_demuxer_data_;
246
247   // Indicates whether the incoming data should be ignored.
248   bool is_incoming_data_invalid_;
249
250   // Weak pointer passed to media decoder jobs for callbacks. It is bounded to
251   // the decoder thread.
252   // NOTE: Weak pointers must be invalidated before all other member variables.
253   base::WeakPtrFactory<MediaDecoderJob> weak_factory_;
254
255   DISALLOW_IMPLICIT_CONSTRUCTORS(MediaDecoderJob);
256 };
257
258 }  // namespace media
259
260 #endif  // MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_