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.
5 #ifndef MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_
6 #define MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_
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"
15 class MessageLoopProxy
;
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
{
25 inline void operator()(MediaDecoderJob
* ptr
) const { ptr
->Release(); }
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
;
39 virtual ~MediaDecoderJob();
41 // Called by MediaSourcePlayer when more data for this object has arrived.
42 void OnDataReceived(const DemuxerData
& data
);
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
);
48 // Called by MediaSourcePlayer to decode some data.
49 // |callback| - Run when decode operation has completed.
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
);
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.
72 // Enter prerolling state. The job must not currently be decoding.
73 void BeginPrerolling(const base::TimeDelta
& preroll_timestamp
);
75 bool prerolling() const { return prerolling_
; }
77 bool is_decoding() const { return !decode_cb_
.is_null(); }
80 MediaDecoderJob(const scoped_refptr
<base::MessageLoopProxy
>& decoder_loop
,
81 MediaCodecBridge
* media_codec_bridge
,
82 const base::Closure
& request_data_cb
);
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
,
90 const ReleaseOutputCompletionCallback
& callback
) = 0;
92 // Returns true if the "time to render" needs to be computed for frames in
94 virtual bool ComputeTimeToRender() const = 0;
97 // Causes this instance to be deleted on the thread it is bound to.
100 MediaCodecStatus
QueueInputBuffer(const AccessUnit
& unit
);
102 // Returns true if this object has data to decode.
103 bool HasData() const;
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
);
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
);
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
,
124 const DecoderCallback
& callback
);
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
);
133 // The UI message loop where callbacks should be dispatched.
134 scoped_refptr
<base::MessageLoopProxy
> ui_loop_
;
136 // The message loop that decoder job runs on.
137 scoped_refptr
<base::MessageLoopProxy
> decoder_loop_
;
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_
;
143 // Whether the decoder needs to be flushed.
146 // Whether input EOS is encountered.
147 bool input_eos_encountered_
;
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_
;
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.
162 // Weak pointer passed to media decoder jobs for callbacks. It is bounded to
163 // the decoder thread.
164 base::WeakPtrFactory
<MediaDecoderJob
> weak_this_
;
166 // Callback used to request more data.
167 base::Closure request_data_cb_
;
169 // Callback to run when new data has been received.
170 base::Closure on_data_received_cb_
;
172 // Callback to run when the current Decode() operation completes.
173 DecoderCallback decode_cb_
;
175 // The current access unit being processed.
176 size_t access_unit_index_
;
178 // Data received over IPC from last RequestData() operation.
179 DemuxerData received_data_
;
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_
;
185 bool stop_decode_pending_
;
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_
;
192 DISALLOW_IMPLICIT_CONSTRUCTORS(MediaDecoderJob
);
197 #endif // MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_