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

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

Issue 2276343005: Delete MediaCodecPlayer, it's time! (Closed)
Patch Set: Created 4 years, 3 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
OLDNEW
(Empty)
1 // Copyright 2015 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_CODEC_DECODER_H_
6 #define MEDIA_BASE_ANDROID_MEDIA_CODEC_DECODER_H_
7
8 #include <stddef.h>
9
10 #include <memory>
11
12 #include "base/android/scoped_java_ref.h"
13 #include "base/callback.h"
14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/synchronization/lock.h"
18 #include "base/threading/thread.h"
19 #include "base/time/time.h"
20 #include "media/base/android/access_unit_queue.h"
21 #include "media/base/android/demuxer_stream_player_params.h"
22
23 namespace media {
24
25 struct FrameStatistics;
26 class MediaCodecBridge;
27
28 // The decoder for MediaCodecPlayer.
29 // This class accepts the incoming data into AccessUnitQueue and works with
30 // MediaCodecBridge for decoding and rendering the frames. The MediaCodecPlayer
31 // has two decoder objects: audio and video.
32 //
33 // The decoder works on two threads. The data from demuxer comes on Media
34 // thread. The commands from MediaCodecPlayer, such as Prefetch, Start,
35 // RequestToStop also come on the Media thread. The operations with MediaCodec
36 // buffers and rendering happen on a separate thread called Decoder thread.
37 // This class creates, starts and stops it as necessary.
38 //
39 // Decoder's internal state machine goes through the following states:
40 //
41 // [ Stopped ] <------------------- (any state except Error)
42 // | | |
43 // | Prefetch |--- internal ------|
44 // v | transition v
45 // [ Prefetching ] | [ Error ]
46 // | |
47 // | internal transition |
48 // v | Error recovery:
49 // [ Prefetched ] |
50 // | | (any state including Error)
51 // | Configure and Start | |
52 // v | | ReleaseDecoderResources
53 // [ Running ] | v
54 // | | [ InEmergencyStop ]
55 // | RequestToStop | |
56 // v | |(decoder thread stopped)
57 // [ Stopping ] ------------------- v
58 // [ Stopped ]
59 //
60 // [ Stopped ] --------------------
61 // ^ |
62 // | Flush |
63 // ---------------------------
64
65 // (any state except Error)
66 // |
67 // | SyncStop
68 // v
69 // [ InEmergencyStop ]
70 // |
71 // |(decoder thread stopped)
72 // v
73 // [ Stopped ]
74
75 // Here is the workflow that is expected to be maintained by a caller, which is
76 // MediaCodecPlayer currently.
77 //
78 // [ Stopped ]
79 // |
80 // | Prefetch
81 // v
82 // [ Prefetching ]
83 // |
84 // | (Enough data received)
85 // v
86 // [ Prefetched ]
87 // |
88 // | <---------- SetDemuxerConfigs (*)
89 // |
90 // | <---------- SetVideoSurface (**)
91 // |
92 // | Configure --------------------------------------------+
93 // | |
94 // v v
95 // ( Config Succeeded ) ( Key frame required )
96 // | |
97 // | Start |
98 // v |
99 // [ Running ] ------------------------------+ |
100 // | | |
101 // | | |
102 // | RequestToStop | SyncStop | SyncStop
103 // | | |
104 // [ Stopping ] | |
105 // | | |
106 // | ( Last frame rendered ) | |
107 // | | |
108 // | | |
109 // v | |
110 // [ Stopped ] <-----------------------------+-----------------+
111 //
112 //
113 // (*) Demuxer configs is a precondition to Configure(), but MediaCodecPlayer
114 // has stricter requirements and they are set before Prefetch().
115 //
116 // (**) VideoSurface is a precondition to video decoder Configure(), can be set
117 // any time before Configure().
118
119 class MediaCodecDecoder {
120 public:
121 // The result of MediaCodec configuration, used by MediaCodecPlayer.
122 enum ConfigStatus {
123 kConfigFailure = 0,
124 kConfigOk,
125 kConfigKeyFrameRequired,
126 };
127
128 // The decoder reports current playback time to the MediaCodecPlayer.
129 // For audio, the parameters designate the beginning and end of a time
130 // interval. The beginning is the estimated time that is playing right now.
131 // The end is the playback time of the last buffered data. During normal
132 // playback the subsequent intervals overlap.
133 // For video both values are PTS of the corresponding frame, i.e. the interval
134 // has zero width.
135 // The third parameter means "postpone", it is set to true if the actual
136 // rendering will start in a later point in time. This only happens with
137 // audio after preroll. The MediaCodecPlayer might decide to update the
138 // current time but not pass it to the upper layer.
139 typedef base::Callback<void(base::TimeDelta, base::TimeDelta, bool)>
140 SetTimeCallback;
141
142 // MediaCodecDecoder constructor.
143 // Parameters:
144 // decoder_thread_name:
145 // The thread name to be passed to decoder thread constructor.
146 // media_task_runner:
147 // A task runner for the controlling thread. All public methods should be
148 // called on this thread, and callbacks are delivered on this thread.
149 // The MediaCodecPlayer uses a dedicated (Media) thread for this.
150 // frame_statistics:
151 // A pointer to FrameStatistics object which gathers playback quality
152 // related data.
153 // external_request_data_cb:
154 // Called periodically as the amount of internally stored data decreases.
155 // The receiver should call OnDemuxerDataAvailable() with more data.
156 // starvation_cb:
157 // Called when starvation is detected. The decoder state does not change.
158 // The player is supposed to stop and then prefetch the decoder.
159 // decoder_drained_cb:
160 // Called when decoder is drained for reconfiguration.
161 // stop_done_cb:
162 // Called when async stop request is completed.
163 // waiting_for_decryption_key_cb:
164 // Will be executed whenever the key needed to decrypt the stream is not
165 // available.
166 // error_cb:
167 // Called when a MediaCodec error occurred. If this happens, a player has
168 // to either call ReleaseDecoderResources() or destroy the decoder object.
169 MediaCodecDecoder(
170 const char* decoder_thread_name,
171 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
172 FrameStatistics* frame_statistics,
173 const base::Closure& external_request_data_cb,
174 const base::Closure& starvation_cb,
175 const base::Closure& decoder_drained_cb,
176 const base::Closure& stop_done_cb,
177 const base::Closure& waiting_for_decryption_key_cb,
178 const base::Closure& error_cb);
179
180 virtual ~MediaCodecDecoder();
181
182 virtual const char* class_name() const;
183
184 // MediaCodecDecoder exists through the whole lifetime of the player
185 // to support dynamic addition and removal of the streams.
186 // This method returns true if the current stream (audio or video)
187 // is currently active.
188 virtual bool HasStream() const = 0;
189
190 // Stores configuration for the use of upcoming Configure()
191 virtual void SetDemuxerConfigs(const DemuxerConfigs& configs) = 0;
192
193 // Returns true if the DemuxerConfigs announce that content is encrypted and
194 // that MediaCrypto is required for configuration.
195 virtual bool IsContentEncrypted() const = 0;
196
197 // Stops decoder thread, releases the MediaCodecBridge and other resources.
198 virtual void ReleaseDecoderResources() = 0;
199
200 // Flushes the MediaCodec, after that resets the AccessUnitQueue and blocks
201 // the input. Decoder thread should not be running.
202 virtual void Flush();
203
204 // Releases MediaCodecBridge and any related buffers or references.
205 virtual void ReleaseMediaCodec();
206
207 // Returns corresponding conditions.
208 bool IsPrefetchingOrPlaying() const;
209 bool IsStopped() const;
210 bool IsCompleted() const;
211 bool NotCompletedAndNeedsPreroll() const;
212
213 // Forces reconfiguraton on the next Configure().
214 void SetNeedsReconfigure();
215
216 // Sets preroll timestamp and requests preroll.
217 void SetPrerollTimestamp(base::TimeDelta preroll_ts);
218
219 // Starts prefetching: accumulates enough data in AccessUnitQueue.
220 // Decoder thread is not running.
221 void Prefetch(const base::Closure& prefetch_done_cb);
222
223 // Configures MediaCodec.
224 ConfigStatus Configure(jobject media_crypto);
225
226 // Starts the decoder for prerolling. This method starts the decoder thread.
227 bool Preroll(const base::Closure& preroll_done_cb);
228
229 // Starts the decoder after preroll is not needed, starting decoder thread
230 // if it has not started yet.
231 bool Start(base::TimeDelta start_timestamp);
232
233 // Stops the playback process synchronously. This method stops the decoder
234 // thread synchronously, and then releases all MediaCodec buffers.
235 void SyncStop();
236
237 // Requests to stop the playback and returns.
238 // Decoder will stop asynchronously after all the dequeued output buffers
239 // are rendered.
240 void RequestToStop();
241
242 // Notification posted when asynchronous stop is done or playback completed.
243 void OnLastFrameRendered(bool eos_encountered);
244
245 // Notification posted when last prerolled frame has been returned to codec.
246 void OnPrerollDone();
247
248 // Puts the incoming data into AccessUnitQueue.
249 void OnDemuxerDataAvailable(const DemuxerData& data);
250
251 // For testing only.
252
253 // Returns true if the decoder is in kPrerolling state.
254 bool IsPrerollingForTests() const;
255
256 // Drains decoder and reconfigures for each |kConfigChanged|.
257 void SetAlwaysReconfigureForTests();
258
259 // Sets the notification to be called when MediaCodec is created.
260 void SetCodecCreatedCallbackForTests(base::Closure cb);
261
262 protected:
263 enum RenderMode {
264 kRenderSkip = 0,
265 kRenderAfterPreroll,
266 kRenderNow,
267 };
268
269 // Returns true if the new DemuxerConfigs requires MediaCodec
270 // reconfiguration.
271 virtual bool IsCodecReconfigureNeeded(const DemuxerConfigs& next) const = 0;
272
273 // Does the part of MediaCodecBridge configuration that is specific
274 // to audio or video.
275 virtual ConfigStatus ConfigureInternal(jobject media_crypto) = 0;
276
277 // Associates PTS with device time so we can calculate delays.
278 // We use delays for video decoder only.
279 virtual void AssociateCurrentTimeWithPTS(base::TimeDelta current_time) {}
280
281 // Invalidate delay calculation. We use delays for video decoder only.
282 virtual void DissociatePTSFromTime() {}
283
284 // Processes the change of the output format, varies by stream.
285 // Returns true if this processing succeeded.
286 virtual bool OnOutputFormatChanged() = 0;
287
288 // Renders the decoded frame and releases output buffer, or posts a delayed
289 // task to do it at a later time. Returnes false if an error occurred.
290 virtual bool Render(int buffer_index,
291 size_t offset,
292 size_t size,
293 RenderMode render_mode,
294 base::TimeDelta pts,
295 bool eos_encountered) = 0;
296
297 // Returns the number of delayed task (we might have them for video).
298 virtual int NumDelayedRenderTasks() const;
299
300 // Releases output buffers that are dequeued and not released yet (video).
301 virtual void ReleaseDelayedBuffers() {}
302
303 #ifndef NDEBUG
304 // For video, checks that access unit is the key frame or stand-alone EOS.
305 virtual void VerifyUnitIsKeyFrame(const AccessUnit* unit) const {}
306 #endif
307
308 // Helper methods.
309
310 // Synchroniously stop decoder thread.
311 void DoEmergencyStop();
312
313 // Returns true if we are in the process of sync stop.
314 bool InEmergencyStop() const { return GetState() == kInEmergencyStop; }
315
316 // Notifies the decoder if the frame is the last one.
317 void CheckLastFrame(bool eos_encountered, bool has_delayed_tasks);
318
319 const char* AsString(RenderMode render_mode);
320
321 // Protected data.
322
323 // We call MediaCodecBridge on this thread for both input and output buffers.
324 base::Thread decoder_thread_;
325
326 // Object for posting tasks on Media thread.
327 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
328
329 // Statistics for UMA.
330 FrameStatistics* frame_statistics_;
331
332 // Controls Android MediaCodec
333 std::unique_ptr<MediaCodecBridge> media_codec_bridge_;
334
335 // The queue of access units.
336 AccessUnitQueue au_queue_;
337
338 // Flag forces reconfiguration even if |media_codec_bridge_| exists. Currently
339 // is set by video decoder when the video surface changes.
340 bool needs_reconfigure_;
341
342 // Flag forces to drain decoder in the process of dynamic reconfiguration.
343 bool drain_decoder_;
344
345 // For tests only. Forces to always reconfigure for |kConfigChanged| unit.
346 bool always_reconfigure_for_tests_;
347
348 // For tests only. Callback to be callned when MediaCodec is created.
349 base::Closure codec_created_for_tests_cb_;
350
351 private:
352 enum DecoderState {
353 kStopped = 0,
354 kPrefetching,
355 kPrefetched,
356 kPrerolling,
357 kPrerolled,
358 kRunning,
359 kStopping,
360 kInEmergencyStop,
361 kError,
362 };
363
364 // Helper method that processes an error from MediaCodec.
365 void OnCodecError();
366
367 // Requests data. Ensures there is no more than one request at a time.
368 void RequestData();
369
370 // Prefetching callback that is posted to Media thread
371 // in the kPrefetching state.
372 void PrefetchNextChunk();
373
374 // The callback to do actual playback. Posted to Decoder thread
375 // in the kRunning state.
376 void ProcessNextFrame();
377
378 // Helper method for ProcessNextFrame.
379 // Pushes one input buffer to the MediaCodec if the codec can accept it.
380 // Returns false if there was MediaCodec error.
381 bool EnqueueInputBuffer();
382
383 // Helper method for EnqueueInputBuffer.
384 // Gets the next data frame from the queue, requesting more data and saving
385 // configuration changes on the way. Sets |drain_decoder| to true of any of
386 // the configuration changes requires draining the decoder. Returns the Info
387 // pointing to the current data unit ot empty Info if it got past the end of
388 // the queue.
389 AccessUnitQueue::Info AdvanceAccessUnitQueue(bool* drain_decoder);
390
391 // Helper method for ProcessNextFrame.
392 // Pulls all currently available output frames and renders them.
393 // Returns true if we need to continue decoding process, i.e post next
394 // ProcessNextFrame method, and false if we need to stop decoding.
395 bool DepleteOutputBufferQueue();
396
397 DecoderState GetState() const;
398 void SetState(DecoderState state);
399 const char* AsString(DecoderState state);
400
401 // Private Data.
402
403 // External data request callback that is passed to decoder.
404 base::Closure external_request_data_cb_;
405
406 // These notifications are called on corresponding conditions.
407 base::Closure prefetch_done_cb_;
408 base::Closure starvation_cb_;
409 base::Closure preroll_done_cb_;
410 base::Closure decoder_drained_cb_;
411 base::Closure stop_done_cb_;
412 base::Closure waiting_for_decryption_key_cb_;
413 base::Closure error_cb_;
414
415 // Data request callback that is posted by decoder internally.
416 base::Closure request_data_cb_;
417
418 // Callback used to post OnCodecError method.
419 base::Closure internal_error_cb_;
420
421 // Callback for posting OnPrerollDone method.
422 base::Closure internal_preroll_done_cb_;
423
424 // Internal state.
425 DecoderState state_;
426 mutable base::Lock state_lock_;
427
428 // Preroll timestamp is set if we need preroll and cleared after we done it.
429 base::TimeDelta preroll_timestamp_;
430
431 // Index of the dequeued and filled buffer that we keep trying to enqueue.
432 // Such buffer appears in MEDIA_CODEC_NO_KEY processing.
433 int pending_input_buf_index_;
434
435 // Set to true when MediaCodec internal buffers are filled up.
436 bool is_prepared_;
437
438 // Flag is set when the EOS is enqueued into MediaCodec. Reset by Flush.
439 bool eos_enqueued_;
440
441 // Flag is set when NO_KEY error is received from QueueSecureInputBuffer.
442 // Reset after we stop.
443 bool missing_key_reported_;
444
445 // Flag is set when the EOS is received in MediaCodec output. Reset by Flush.
446 bool completed_;
447
448 // Flag to ensure we post last frame notification once.
449 bool last_frame_posted_;
450
451 // Indicates whether the data request is in progress.
452 bool is_data_request_in_progress_;
453
454 // Indicates whether the incoming data should be ignored.
455 bool is_incoming_data_invalid_;
456
457 #ifndef NDEBUG
458 // When set, we check that the following video frame is the key frame.
459 bool verify_next_frame_is_key_;
460 #endif
461
462 // NOTE: Weak pointers must be invalidated before all other member variables.
463 base::WeakPtrFactory<MediaCodecDecoder> weak_factory_;
464
465 DISALLOW_COPY_AND_ASSIGN(MediaCodecDecoder);
466 };
467
468 } // namespace media
469
470 #endif // MEDIA_BASE_ANDROID_MEDIA_CODEC_DECODER_H_
OLDNEW
« no previous file with comments | « media/base/android/audio_media_codec_decoder.cc ('k') | media/base/android/media_codec_decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698