Upstream version 10.39.225.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 #include "ui/gl/android/scoped_java_surface.h"
14
15 namespace base {
16 class SingleThreadTaskRunner;
17 }
18
19 namespace media {
20
21 class MediaDrmBridge;
22
23 // Class for managing all the decoding tasks. Each decoding task will be posted
24 // onto the same thread. The thread will be stopped once Stop() is called.
25 // Data is stored in 2 chunks. When new data arrives, it is always stored in
26 // an inactive chunk. And when the current active chunk becomes empty, a new
27 // data request will be sent to the renderer.
28 class MediaDecoderJob {
29  public:
30   struct Deleter {
31     inline void operator()(MediaDecoderJob* ptr) const { ptr->Release(); }
32   };
33
34   // Callback when a decoder job finishes its work. Args: whether decode
35   // finished successfully, current presentation time, max presentation time.
36   // If the current presentation time is equal to kNoTimestamp(), the decoder
37   // job skipped rendering of the decoded output and the callback target should
38   // ignore the timestamps provided.
39   typedef base::Callback<void(MediaCodecStatus, base::TimeDelta,
40                               base::TimeDelta)> DecoderCallback;
41   // Callback when a decoder job finishes releasing the output buffer.
42   // Args: current presentation time, max presentation time.
43   // If the current presentation time is equal to kNoTimestamp(), the callback
44   // target should ignore the timestamps provided.
45   typedef base::Callback<void(base::TimeDelta, base::TimeDelta)>
46       ReleaseOutputCompletionCallback;
47
48   virtual ~MediaDecoderJob();
49
50   // Called by MediaSourcePlayer when more data for this object has arrived.
51   void OnDataReceived(const DemuxerData& data);
52
53   // Prefetch so we know the decoder job has data when we call Decode().
54   // |prefetch_cb| - Run when prefetching has completed.
55   void Prefetch(const base::Closure& prefetch_cb);
56
57   // Called by MediaSourcePlayer to decode some data.
58   // |callback| - Run when decode operation has completed.
59   //
60   // Returns true if the next decode was started and |callback| will be
61   // called when the decode operation is complete.
62   // Returns false if |media_codec_bridge_| cannot be created; |callback| is
63   // ignored and will not be called.
64   bool Decode(base::TimeTicks start_time_ticks,
65               base::TimeDelta start_presentation_timestamp,
66               const DecoderCallback& callback);
67
68   // Called to stop the last Decode() early.
69   // If the decoder is in the process of decoding the next frame, then
70   // this method will just allow the decode to complete as normal. If
71   // this object is waiting for a data request to complete, then this method
72   // will wait for the data to arrive and then call the |callback|
73   // passed to Decode() with a status of MEDIA_CODEC_STOPPED. This ensures that
74   // the |callback| passed to Decode() is always called and the status
75   // reflects whether data was actually decoded or the decode terminated early.
76   void StopDecode();
77
78   // Flushes the decoder and abandons all the data that is being decoded.
79   virtual void Flush();
80
81   // Enters prerolling state. The job must not currently be decoding.
82   void BeginPrerolling(base::TimeDelta preroll_timestamp);
83
84   // Releases all the decoder resources as the current tab is going background.
85   virtual void ReleaseDecoderResources();
86
87   // Sets the demuxer configs. Returns true if configs has changed, or false
88   // otherwise.
89   bool SetDemuxerConfigs(const DemuxerConfigs& configs);
90
91   // Returns whether the decoder has finished decoding all the data.
92   bool OutputEOSReached() const;
93
94   // Returns true if the audio/video stream is available, implemented by child
95   // classes.
96   virtual bool HasStream() const = 0;
97
98   void SetDrmBridge(MediaDrmBridge* drm_bridge);
99
100   bool is_decoding() const { return !decode_cb_.is_null(); }
101
102   bool is_content_encrypted() const { return is_content_encrypted_; }
103
104   bool prerolling() const { return prerolling_; }
105
106  protected:
107   // Creates a new MediaDecoderJob instance.
108   // |decoder_task_runner| - Thread on which the decoder task will run.
109   // |request_data_cb| - Callback to request more data for the decoder.
110   // |config_changed_cb| - Callback to inform the caller that
111   // demuxer config has changed.
112   MediaDecoderJob(
113       const scoped_refptr<base::SingleThreadTaskRunner>& decoder_task_runner,
114       const base::Closure& request_data_cb,
115       const base::Closure& config_changed_cb);
116
117   // Release the output buffer at index |output_buffer_index| and render it if
118   // |render_output| is true. Upon completion, |callback| will be called.
119   virtual void ReleaseOutputBuffer(
120       int output_buffer_index,
121       size_t size,
122       bool render_output,
123       base::TimeDelta current_presentation_timestamp,
124       const ReleaseOutputCompletionCallback& callback) = 0;
125
126   // Returns true if the "time to render" needs to be computed for frames in
127   // this decoder job.
128   virtual bool ComputeTimeToRender() const = 0;
129
130   // Gets MediaCrypto object from |drm_bridge_|.
131   base::android::ScopedJavaLocalRef<jobject> GetMediaCrypto();
132
133   // Releases the |media_codec_bridge_|.
134   void ReleaseMediaCodecBridge();
135
136   MediaDrmBridge* drm_bridge() { return drm_bridge_; }
137
138   void set_is_content_encrypted(bool is_content_encrypted) {
139     is_content_encrypted_ = is_content_encrypted;
140   }
141
142   bool need_to_reconfig_decoder_job_;
143
144   scoped_ptr<MediaCodecBridge> media_codec_bridge_;
145
146  private:
147   friend class MediaSourcePlayerTest;
148
149   // Causes this instance to be deleted on the thread it is bound to.
150   void Release();
151
152   // Queues an access unit into |media_codec_bridge_|'s input buffer.
153   MediaCodecStatus QueueInputBuffer(const AccessUnit& unit);
154
155   // Returns true if this object has data to decode.
156   bool HasData() const;
157
158   // Initiates a request for more data.
159   // |done_cb| is called when more data is available in |received_data_|.
160   void RequestData(const base::Closure& done_cb);
161
162   // Posts a task to start decoding the current access unit in |received_data_|.
163   void DecodeCurrentAccessUnit(
164       base::TimeTicks start_time_ticks,
165       base::TimeDelta start_presentation_timestamp);
166
167   // Helper function to decode data on |decoder_task_runner_|. |unit| contains
168   // the data to be decoded. |start_time_ticks| and
169   // |start_presentation_timestamp| represent the system time and the
170   // presentation timestamp when the first frame is rendered. We use these
171   // information to estimate when the current frame should be rendered.
172   // If |needs_flush| is true, codec needs to be flushed at the beginning of
173   // this call.
174   // It is possible that |stop_decode_pending_| or |release_resources_pending_|
175   // becomes true while DecodeInternal() is called. However, they should have
176   // no impact on DecodeInternal(). They will be handled after DecoderInternal()
177   // finishes and OnDecodeCompleted() is posted on the UI thread.
178   void DecodeInternal(const AccessUnit& unit,
179                       base::TimeTicks start_time_ticks,
180                       base::TimeDelta start_presentation_timestamp,
181                       bool needs_flush,
182                       const DecoderCallback& callback);
183
184   // Called on the UI thread to indicate that one decode cycle has completed.
185   // Completes any pending job destruction or any pending decode stop. If
186   // destruction was not pending, passes its arguments to |decode_cb_|.
187   void OnDecodeCompleted(MediaCodecStatus status,
188                          base::TimeDelta current_presentation_timestamp,
189                          base::TimeDelta max_presentation_timestamp);
190
191   // Helper function to get the current access unit that is being decoded.
192   const AccessUnit& CurrentAccessUnit() const;
193
194   // Helper function to get the current data chunk index that is being decoded.
195   size_t CurrentReceivedDataChunkIndex() const;
196
197   // Check whether a chunk has no remaining access units to decode. If
198   // |is_active_chunk| is true, this function returns whether decoder has
199   // consumed all data in |received_data_[current_demuxer_data_index_]|.
200   // Otherwise, it returns whether decoder has consumed all data in the inactive
201   // chunk.
202   bool NoAccessUnitsRemainingInChunk(bool is_active_chunk) const;
203
204   // Requests new data for the current chunk if it runs out of data.
205   void RequestCurrentChunkIfEmpty();
206
207   // Initializes |received_data_| and |access_unit_index_|.
208   void InitializeReceivedData();
209
210   // Called when the decoder is completely drained and is ready to be released.
211   void OnDecoderDrained();
212
213   // Creates |media_codec_bridge_| for decoding purpose. Returns true if it is
214   // created, or false otherwise.
215   bool CreateMediaCodecBridge();
216
217   // Called when an access unit is consumed by the decoder. |is_config_change|
218   // indicates whether the current access unit is a config change. If it is
219   // true, the next access unit is guarateed to be an I-frame.
220   virtual void CurrentDataConsumed(bool is_config_change) {}
221
222   // Implemented by the child class to create |media_codec_bridge_| for a
223   // particular stream. Returns true if it is created, or false otherwise.
224   virtual bool CreateMediaCodecBridgeInternal() = 0;
225
226   // Returns true if the |configs| doesn't match the current demuxer configs
227   // the decoder job has.
228   virtual bool AreDemuxerConfigsChanged(
229       const DemuxerConfigs& configs) const = 0;
230
231   // Updates the demuxer configs.
232   virtual void UpdateDemuxerConfigs(const DemuxerConfigs& configs) = 0;
233
234   // Returns true if |media_codec_bridge_| needs to be reconfigured for the
235   // new DemuxerConfigs, or false otherwise.
236   virtual bool IsCodecReconfigureNeeded(const DemuxerConfigs& configs) const;
237
238   // Return the index to |received_data_| that is not currently being decoded.
239   size_t inactive_demuxer_data_index() const {
240     return 1 - current_demuxer_data_index_;
241   }
242
243   // The UI message loop where callbacks should be dispatched.
244   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
245
246   // The task runner that decoder job runs on.
247   scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner_;
248
249   // Whether the decoder needs to be flushed.
250   bool needs_flush_;
251
252   // Whether input EOS is encountered.
253   // TODO(wolenetz/qinmin): Protect with a lock. See http://crbug.com/320043.
254   bool input_eos_encountered_;
255
256   // Whether output EOS is encountered.
257   bool output_eos_encountered_;
258
259   // Tracks whether DecodeInternal() should skip decoding if the first access
260   // unit is EOS or empty, and report |MEDIA_CODEC_OUTPUT_END_OF_STREAM|. This
261   // is to work around some decoders that could crash otherwise. See
262   // http://b/11696552.
263   bool skip_eos_enqueue_;
264
265   // The timestamp the decoder needs to preroll to. If an access unit's
266   // timestamp is smaller than |preroll_timestamp_|, don't render it.
267   // TODO(qinmin): Comparing access unit's timestamp with |preroll_timestamp_|
268   // is not very accurate.
269   base::TimeDelta preroll_timestamp_;
270
271   // Indicates prerolling state. If true, this job has not yet decoded output
272   // that it will render, since the most recent of job construction or
273   // BeginPrerolling(). If false, |preroll_timestamp_| has been reached.
274   // TODO(qinmin): Comparing access unit's timestamp with |preroll_timestamp_|
275   // is not very accurate.
276   bool prerolling_;
277
278   // Callback used to request more data.
279   base::Closure request_data_cb_;
280
281   // Callback to notify the caller config has changed.
282   base::Closure config_changed_cb_;
283
284   // Callback to run when new data has been received.
285   base::Closure data_received_cb_;
286
287   // Callback to run when the current Decode() operation completes.
288   DecoderCallback decode_cb_;
289
290   // Data received over IPC from last RequestData() operation.
291   // We keep 2 chunks at the same time to reduce the IPC latency between chunks.
292   // If data inside the current chunk are all decoded, we will request a new
293   // chunk from the demuxer and swap the current chunk with the other one.
294   // New data will always be stored in the other chunk since the current
295   // one may be still in use.
296   DemuxerData received_data_[2];
297
298   // Index to the current data chunk that is being decoded.
299   size_t current_demuxer_data_index_;
300
301   // Index to the access unit inside each data chunk that is being decoded.
302   size_t access_unit_index_[2];
303
304   // The index of input buffer that can be used by QueueInputBuffer().
305   // If the index is uninitialized or invalid, it must be -1.
306   int input_buf_index_;
307
308   // Indicates whether content is encrypted.
309   bool is_content_encrypted_;
310
311   // Indicates the decoder job should stop after decoding the current access
312   // unit.
313   bool stop_decode_pending_;
314
315   // Indicates that this object should be destroyed once the current
316   // Decode() has completed. This gets set when Release() gets called
317   // while there is a decode in progress.
318   bool destroy_pending_;
319
320   // Indicates whether the decoder is in the middle of requesting new data.
321   bool is_requesting_demuxer_data_;
322
323   // Indicates whether the incoming data should be ignored.
324   bool is_incoming_data_invalid_;
325
326   // Indicates that |media_codec_bridge_| should be released once the current
327   // Decode() has completed. This gets set when ReleaseDecoderResources() gets
328   // called while there is a decode in progress.
329   bool release_resources_pending_;
330
331   // Pointer to a DRM object that will be used for encrypted streams.
332   MediaDrmBridge* drm_bridge_;
333
334   // Indicates whether |media_codec_bridge_| is in the middle of being drained
335   // due to a config change.
336   bool drain_decoder_;
337
338   // This access unit is passed to the decoder during config changes to drain
339   // the decoder.
340   AccessUnit eos_unit_;
341
342   DISALLOW_IMPLICIT_CONSTRUCTORS(MediaDecoderJob);
343 };
344
345 }  // namespace media
346
347 #endif  // MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_