Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: media/base/android/media_decoder_job.h

Issue 196133020: Reducing the IPC latency for MSE video decoding (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix clang warning Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/base/android/demuxer_android.h ('k') | media/base/android/media_decoder_job.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_ 5 #ifndef MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_
6 #define MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_ 6 #define MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_
7 7
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/memory/weak_ptr.h" 9 #include "base/memory/weak_ptr.h"
10 #include "base/time/time.h" 10 #include "base/time/time.h"
11 #include "media/base/android/demuxer_stream_player_params.h" 11 #include "media/base/android/demuxer_stream_player_params.h"
12 #include "media/base/android/media_codec_bridge.h" 12 #include "media/base/android/media_codec_bridge.h"
13 13
14 namespace base { 14 namespace base {
15 class SingleThreadTaskRunner; 15 class SingleThreadTaskRunner;
16 } 16 }
17 17
18 namespace media { 18 namespace media {
19 19
20 // Class for managing all the decoding tasks. Each decoding task will be posted 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. 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.
22 class MediaDecoderJob { 25 class MediaDecoderJob {
23 public: 26 public:
24 struct Deleter { 27 struct Deleter {
25 inline void operator()(MediaDecoderJob* ptr) const { ptr->Release(); } 28 inline void operator()(MediaDecoderJob* ptr) const { ptr->Release(); }
26 }; 29 };
27 30
28 // Callback when a decoder job finishes its work. Args: whether decode 31 // Callback when a decoder job finishes its work. Args: whether decode
29 // finished successfully, presentation time, audio output bytes. 32 // finished successfully, presentation time, audio output bytes.
30 // If the presentation time is equal to kNoTimestamp(), the decoder job 33 // If the presentation time is equal to kNoTimestamp(), the decoder job
31 // skipped rendering of the decoded output and the callback target should 34 // skipped rendering of the decoded output and the callback target should
32 // update its clock to avoid introducing extra delays to the next frame. 35 // update its clock to avoid introducing extra delays to the next frame.
33 typedef base::Callback<void(MediaCodecStatus, const base::TimeDelta&, 36 typedef base::Callback<void(MediaCodecStatus, base::TimeDelta,
34 size_t)> DecoderCallback; 37 size_t)> DecoderCallback;
35 // Callback when a decoder job finishes releasing the output buffer. 38 // Callback when a decoder job finishes releasing the output buffer.
36 // Args: audio output bytes, must be 0 for video. 39 // Args: audio output bytes, must be 0 for video.
37 typedef base::Callback<void(size_t)> ReleaseOutputCompletionCallback; 40 typedef base::Callback<void(size_t)> ReleaseOutputCompletionCallback;
38 41
39 virtual ~MediaDecoderJob(); 42 virtual ~MediaDecoderJob();
40 43
41 // Called by MediaSourcePlayer when more data for this object has arrived. 44 // Called by MediaSourcePlayer when more data for this object has arrived.
42 void OnDataReceived(const DemuxerData& data); 45 void OnDataReceived(const DemuxerData& data);
43 46
44 // Prefetch so we know the decoder job has data when we call Decode(). 47 // Prefetch so we know the decoder job has data when we call Decode().
45 // |prefetch_cb| - Run when prefetching has completed. 48 // |prefetch_cb| - Run when prefetching has completed.
46 void Prefetch(const base::Closure& prefetch_cb); 49 void Prefetch(const base::Closure& prefetch_cb);
47 50
48 // Called by MediaSourcePlayer to decode some data. 51 // Called by MediaSourcePlayer to decode some data.
49 // |callback| - Run when decode operation has completed. 52 // |callback| - Run when decode operation has completed.
50 // 53 //
51 // Returns true if the next decode was started and |callback| will be 54 // Returns true if the next decode was started and |callback| will be
52 // called when the decode operation is complete. 55 // called when the decode operation is complete.
53 // Returns false if a config change is needed. |callback| is ignored 56 // Returns false if a config change is needed. |callback| is ignored
54 // and will not be called. 57 // and will not be called.
55 bool Decode(const base::TimeTicks& start_time_ticks, 58 bool Decode(base::TimeTicks start_time_ticks,
56 const base::TimeDelta& start_presentation_timestamp, 59 base::TimeDelta start_presentation_timestamp,
57 const DecoderCallback& callback); 60 const DecoderCallback& callback);
58 61
59 // Called to stop the last Decode() early. 62 // Called to stop the last Decode() early.
60 // If the decoder is in the process of decoding the next frame, then 63 // 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 64 // 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 65 // 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| 66 // 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 67 // 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 68 // the |callback| passed to Decode() is always called and the status
66 // reflects whether data was actually decoded or the decode terminated early. 69 // reflects whether data was actually decoded or the decode terminated early.
67 void StopDecode(); 70 void StopDecode();
68 71
69 // Flush the decoder. 72 // Flush the decoder.
70 void Flush(); 73 void Flush();
71 74
72 // Enter prerolling state. The job must not currently be decoding. 75 // Enter prerolling state. The job must not currently be decoding.
73 void BeginPrerolling(const base::TimeDelta& preroll_timestamp); 76 void BeginPrerolling(base::TimeDelta preroll_timestamp);
74 77
75 bool prerolling() const { return prerolling_; } 78 bool prerolling() const { return prerolling_; }
76 79
77 bool is_decoding() const { return !decode_cb_.is_null(); } 80 bool is_decoding() const { return !decode_cb_.is_null(); }
78 81
82 bool is_requesting_demuxer_data() const {
83 return is_requesting_demuxer_data_;
84 }
85
79 protected: 86 protected:
80 MediaDecoderJob( 87 MediaDecoderJob(
81 const scoped_refptr<base::SingleThreadTaskRunner>& decoder_task_runner, 88 const scoped_refptr<base::SingleThreadTaskRunner>& decoder_task_runner,
82 MediaCodecBridge* media_codec_bridge, 89 MediaCodecBridge* media_codec_bridge,
83 const base::Closure& request_data_cb); 90 const base::Closure& request_data_cb);
84 91
85 // Release the output buffer at index |output_buffer_index| and render it if 92 // Release the output buffer at index |output_buffer_index| and render it if
86 // |render_output| is true. Upon completion, |callback| will be called. 93 // |render_output| is true. Upon completion, |callback| will be called.
87 virtual void ReleaseOutputBuffer( 94 virtual void ReleaseOutputBuffer(
88 int output_buffer_index, 95 int output_buffer_index,
89 size_t size, 96 size_t size,
90 bool render_output, 97 bool render_output,
91 const ReleaseOutputCompletionCallback& callback) = 0; 98 const ReleaseOutputCompletionCallback& callback) = 0;
92 99
93 // Returns true if the "time to render" needs to be computed for frames in 100 // Returns true if the "time to render" needs to be computed for frames in
94 // this decoder job. 101 // this decoder job.
95 virtual bool ComputeTimeToRender() const = 0; 102 virtual bool ComputeTimeToRender() const = 0;
96 103
97 private: 104 private:
105 friend class MediaSourcePlayerTest;
106
98 // Causes this instance to be deleted on the thread it is bound to. 107 // Causes this instance to be deleted on the thread it is bound to.
99 void Release(); 108 void Release();
100 109
101 MediaCodecStatus QueueInputBuffer(const AccessUnit& unit); 110 MediaCodecStatus QueueInputBuffer(const AccessUnit& unit);
102 111
103 // Returns true if this object has data to decode. 112 // Returns true if this object has data to decode.
104 bool HasData() const; 113 bool HasData() const;
105 114
106 // Initiates a request for more data. 115 // Initiates a request for more data.
107 // |done_cb| is called when more data is available in |received_data_|. 116 // |done_cb| is called when more data is available in |received_data_|.
108 void RequestData(const base::Closure& done_cb); 117 void RequestData(const base::Closure& done_cb);
109 118
110 // Posts a task to start decoding the next access unit in |received_data_|. 119 // Posts a task to start decoding the current access unit in |received_data_|.
111 void DecodeNextAccessUnit( 120 void DecodeCurrentAccessUnit(
112 const base::TimeTicks& start_time_ticks, 121 base::TimeTicks start_time_ticks,
113 const base::TimeDelta& start_presentation_timestamp); 122 base::TimeDelta start_presentation_timestamp);
114 123
115 // Helper function to decoder data on |thread_|. |unit| contains all the data 124 // Helper function to decoder data on |thread_|. |unit| contains all the data
116 // to be decoded. |start_time_ticks| and |start_presentation_timestamp| 125 // to be decoded. |start_time_ticks| and |start_presentation_timestamp|
117 // represent the system time and the presentation timestamp when the first 126 // represent the system time and the presentation timestamp when the first
118 // frame is rendered. We use these information to estimate when the current 127 // frame is rendered. We use these information to estimate when the current
119 // frame should be rendered. If |needs_flush| is true, codec needs to be 128 // frame should be rendered. If |needs_flush| is true, codec needs to be
120 // flushed at the beginning of this call. 129 // flushed at the beginning of this call.
121 void DecodeInternal(const AccessUnit& unit, 130 void DecodeInternal(const AccessUnit& unit,
122 const base::TimeTicks& start_time_ticks, 131 base::TimeTicks start_time_ticks,
123 const base::TimeDelta& start_presentation_timestamp, 132 base::TimeDelta start_presentation_timestamp,
124 bool needs_flush, 133 bool needs_flush,
125 const DecoderCallback& callback); 134 const DecoderCallback& callback);
126 135
127 // Called on the UI thread to indicate that one decode cycle has completed. 136 // Called on the UI thread to indicate that one decode cycle has completed.
128 // Completes any pending job destruction or any pending decode stop. If 137 // Completes any pending job destruction or any pending decode stop. If
129 // destruction was not pending, passes its arguments to |decode_cb_|. 138 // destruction was not pending, passes its arguments to |decode_cb_|.
130 void OnDecodeCompleted(MediaCodecStatus status, 139 void OnDecodeCompleted(MediaCodecStatus status,
131 const base::TimeDelta& presentation_timestamp, 140 base::TimeDelta presentation_timestamp,
132 size_t audio_output_bytes); 141 size_t audio_output_bytes);
133 142
143 // Helper function to get the current access unit that is being decoded.
144 const AccessUnit& CurrentAccessUnit() const;
145
146 // Check whether a chunk has no remaining access units to decode. If
147 // |is_active_chunk| is true, this function returns whether decoder has
148 // consumed all data in |received_data_[current_demuxer_data_index_]|.
149 // Otherwise, it returns whether decoder has consumed all data in the inactive
150 // chunk.
151 bool NoAccessUnitsRemainingInChunk(bool is_active_chunk) const;
152
153 // Clearn all the received data.
154 void ClearData();
155
156 // Request new data for the current chunk if it runs out of data.
157 void RequestCurrentChunkIfEmpty();
158
159 // Initialize |received_data_| and |access_unit_index_|.
160 void InitializeReceivedData();
161
162 // Return the index to |received_data_| that is not currently being decoded.
163 size_t inactive_demuxer_data_index() const {
164 return 1 - current_demuxer_data_index_;
165 }
166
134 // The UI message loop where callbacks should be dispatched. 167 // The UI message loop where callbacks should be dispatched.
135 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; 168 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
136 169
137 // The task runner that decoder job runs on. 170 // The task runner that decoder job runs on.
138 scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner_; 171 scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner_;
139 172
140 // The media codec bridge used for decoding. Owned by derived class. 173 // The media codec bridge used for decoding. Owned by derived class.
141 // NOTE: This MUST NOT be accessed in the destructor. 174 // NOTE: This MUST NOT be accessed in the destructor.
142 MediaCodecBridge* media_codec_bridge_; 175 MediaCodecBridge* media_codec_bridge_;
143 176
(...skipping 28 matching lines...) Expand all
172 205
173 // Callback used to request more data. 206 // Callback used to request more data.
174 base::Closure request_data_cb_; 207 base::Closure request_data_cb_;
175 208
176 // Callback to run when new data has been received. 209 // Callback to run when new data has been received.
177 base::Closure on_data_received_cb_; 210 base::Closure on_data_received_cb_;
178 211
179 // Callback to run when the current Decode() operation completes. 212 // Callback to run when the current Decode() operation completes.
180 DecoderCallback decode_cb_; 213 DecoderCallback decode_cb_;
181 214
182 // The current access unit being processed. 215 // Data received over IPC from last RequestData() operation.
183 size_t access_unit_index_; 216 // We keep 2 chunks at the same time to reduce the IPC latency between chunks.
217 // If data inside the current chunk are all decoded, we will request a new
218 // chunk from the demuxer and swap the current chunk with the other one.
219 // New data will always be stored in the other chunk since the current
220 // one may be still in use.
221 DemuxerData received_data_[2];
184 222
185 // Data received over IPC from last RequestData() operation. 223 // Index to the current data chunk that is being decoded.
186 DemuxerData received_data_; 224 size_t current_demuxer_data_index_;
225
226 // Index to the access unit inside each data chunk that is being decoded.
227 size_t access_unit_index_[2];
187 228
188 // The index of input buffer that can be used by QueueInputBuffer(). 229 // The index of input buffer that can be used by QueueInputBuffer().
189 // If the index is uninitialized or invalid, it must be -1. 230 // If the index is uninitialized or invalid, it must be -1.
190 int input_buf_index_; 231 int input_buf_index_;
191 232
192 bool stop_decode_pending_; 233 bool stop_decode_pending_;
193 234
194 // Indicates that this object should be destroyed once the current 235 // Indicates that this object should be destroyed once the current
195 // Decode() has completed. This gets set when Release() gets called 236 // Decode() has completed. This gets set when Release() gets called
196 // while there is a decode in progress. 237 // while there is a decode in progress.
197 bool destroy_pending_; 238 bool destroy_pending_;
198 239
240 // Indicates whether the decoder is in the middle of requesting new data.
241 bool is_requesting_demuxer_data_;
242
243 // Indicates whether the incoming data should be ignored.
244 bool is_incoming_data_invalid_;
245
199 // Weak pointer passed to media decoder jobs for callbacks. It is bounded to 246 // Weak pointer passed to media decoder jobs for callbacks. It is bounded to
200 // the decoder thread. 247 // the decoder thread.
201 // NOTE: Weak pointers must be invalidated before all other member variables. 248 // NOTE: Weak pointers must be invalidated before all other member variables.
202 base::WeakPtrFactory<MediaDecoderJob> weak_factory_; 249 base::WeakPtrFactory<MediaDecoderJob> weak_factory_;
203 250
204 DISALLOW_IMPLICIT_CONSTRUCTORS(MediaDecoderJob); 251 DISALLOW_IMPLICIT_CONSTRUCTORS(MediaDecoderJob);
205 }; 252 };
206 253
207 } // namespace media 254 } // namespace media
208 255
209 #endif // MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_ 256 #endif // MEDIA_BASE_ANDROID_MEDIA_DECODER_JOB_H_
OLDNEW
« no previous file with comments | « media/base/android/demuxer_android.h ('k') | media/base/android/media_decoder_job.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698