|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 /* |
|
7 Each video element for a media file has two threads: |
|
8 |
|
9 1) The Audio thread writes the decoded audio data to the audio |
|
10 hardware. This is done in a separate thread to ensure that the |
|
11 audio hardware gets a constant stream of data without |
|
12 interruption due to decoding or display. At some point |
|
13 AudioStream will be refactored to have a callback interface |
|
14 where it asks for data and an extra thread will no longer be |
|
15 needed. |
|
16 |
|
17 2) The decode thread. This thread reads from the media stream and |
|
18 decodes the Theora and Vorbis data. It places the decoded data into |
|
19 queues for the other threads to pull from. |
|
20 |
|
21 All file reads, seeks, and all decoding must occur on the decode thread. |
|
22 Synchronisation of state between the thread is done via a monitor owned |
|
23 by MediaDecoder. |
|
24 |
|
25 The lifetime of the decode and audio threads is controlled by the state |
|
26 machine when it runs on the shared state machine thread. When playback |
|
27 needs to occur they are created and events dispatched to them to run |
|
28 them. These events exit when decoding/audio playback is completed or |
|
29 no longer required. |
|
30 |
|
31 A/V synchronisation is handled by the state machine. It examines the audio |
|
32 playback time and compares this to the next frame in the queue of video |
|
33 frames. If it is time to play the video frame it is then displayed, otherwise |
|
34 it schedules the state machine to run again at the time of the next frame. |
|
35 |
|
36 Frame skipping is done in the following ways: |
|
37 |
|
38 1) The state machine will skip all frames in the video queue whose |
|
39 display time is less than the current audio time. This ensures |
|
40 the correct frame for the current time is always displayed. |
|
41 |
|
42 2) The decode thread will stop decoding interframes and read to the |
|
43 next keyframe if it determines that decoding the remaining |
|
44 interframes will cause playback issues. It detects this by: |
|
45 a) If the amount of audio data in the audio queue drops |
|
46 below a threshold whereby audio may start to skip. |
|
47 b) If the video queue drops below a threshold where it |
|
48 will be decoding video data that won't be displayed due |
|
49 to the decode thread dropping the frame immediately. |
|
50 |
|
51 When hardware accelerated graphics is not available, YCbCr conversion |
|
52 is done on the decode thread when video frames are decoded. |
|
53 |
|
54 The decode thread pushes decoded audio and videos frames into two |
|
55 separate queues - one for audio and one for video. These are kept |
|
56 separate to make it easy to constantly feed audio data to the audio |
|
57 hardware while allowing frame skipping of video data. These queues are |
|
58 threadsafe, and neither the decode, audio, or state machine should |
|
59 be able to monopolize them, and cause starvation of the other threads. |
|
60 |
|
61 Both queues are bounded by a maximum size. When this size is reached |
|
62 the decode thread will no longer decode video or audio depending on the |
|
63 queue that has reached the threshold. If both queues are full, the decode |
|
64 thread will wait on the decoder monitor. |
|
65 |
|
66 When the decode queues are full (they've reaced their maximum size) and |
|
67 the decoder is not in PLAYING play state, the state machine may opt |
|
68 to shut down the decode thread in order to conserve resources. |
|
69 |
|
70 During playback the audio thread will be idle (via a Wait() on the |
|
71 monitor) if the audio queue is empty. Otherwise it constantly pops |
|
72 audio data off the queue and plays it with a blocking write to the audio |
|
73 hardware (via AudioStream). |
|
74 |
|
75 */ |
|
76 #if !defined(MediaDecoderStateMachine_h__) |
|
77 #define MediaDecoderStateMachine_h__ |
|
78 |
|
79 #include "mozilla/Attributes.h" |
|
80 #include "nsThreadUtils.h" |
|
81 #include "MediaDecoder.h" |
|
82 #include "mozilla/ReentrantMonitor.h" |
|
83 #include "MediaDecoderReader.h" |
|
84 #include "MediaDecoderOwner.h" |
|
85 #include "MediaMetadataManager.h" |
|
86 |
|
87 class nsITimer; |
|
88 |
|
89 namespace mozilla { |
|
90 |
|
91 class AudioSegment; |
|
92 class VideoSegment; |
|
93 class MediaTaskQueue; |
|
94 class SharedThreadPool; |
|
95 |
|
96 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to |
|
97 // GetTickCount() and conflicts with MediaDecoderStateMachine::GetCurrentTime |
|
98 // implementation. |
|
99 #ifdef GetCurrentTime |
|
100 #undef GetCurrentTime |
|
101 #endif |
|
102 |
|
103 /* |
|
104 The state machine class. This manages the decoding and seeking in the |
|
105 MediaDecoderReader on the decode thread, and A/V sync on the shared |
|
106 state machine thread, and controls the audio "push" thread. |
|
107 |
|
108 All internal state is synchronised via the decoder monitor. State changes |
|
109 are either propagated by NotifyAll on the monitor (typically when state |
|
110 changes need to be propagated to non-state machine threads) or by scheduling |
|
111 the state machine to run another cycle on the shared state machine thread. |
|
112 |
|
113 See MediaDecoder.h for more details. |
|
114 */ |
|
115 class MediaDecoderStateMachine |
|
116 { |
|
117 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderStateMachine) |
|
118 public: |
|
119 typedef MediaDecoder::DecodedStreamData DecodedStreamData; |
|
120 MediaDecoderStateMachine(MediaDecoder* aDecoder, |
|
121 MediaDecoderReader* aReader, |
|
122 bool aRealTime = false); |
|
123 |
|
124 nsresult Init(MediaDecoderStateMachine* aCloneDonor); |
|
125 |
|
126 // Enumeration for the valid decoding states |
|
127 enum State { |
|
128 DECODER_STATE_DECODING_METADATA, |
|
129 DECODER_STATE_WAIT_FOR_RESOURCES, |
|
130 DECODER_STATE_DORMANT, |
|
131 DECODER_STATE_DECODING, |
|
132 DECODER_STATE_SEEKING, |
|
133 DECODER_STATE_BUFFERING, |
|
134 DECODER_STATE_COMPLETED, |
|
135 DECODER_STATE_SHUTDOWN |
|
136 }; |
|
137 |
|
138 State GetState() { |
|
139 AssertCurrentThreadInMonitor(); |
|
140 return mState; |
|
141 } |
|
142 |
|
143 // Set the audio volume. The decoder monitor must be obtained before |
|
144 // calling this. |
|
145 void SetVolume(double aVolume); |
|
146 void SetAudioCaptured(bool aCapture); |
|
147 |
|
148 // Check if the decoder needs to become dormant state. |
|
149 bool IsDormantNeeded(); |
|
150 // Set/Unset dormant state. |
|
151 void SetDormant(bool aDormant); |
|
152 void Shutdown(); |
|
153 |
|
154 // Called from the main thread to get the duration. The decoder monitor |
|
155 // must be obtained before calling this. It is in units of microseconds. |
|
156 int64_t GetDuration(); |
|
157 |
|
158 // Called from the main thread to set the duration of the media resource |
|
159 // if it is able to be obtained via HTTP headers. Called from the |
|
160 // state machine thread to set the duration if it is obtained from the |
|
161 // media metadata. The decoder monitor must be obtained before calling this. |
|
162 // aDuration is in microseconds. |
|
163 void SetDuration(int64_t aDuration); |
|
164 |
|
165 // Called while decoding metadata to set the end time of the media |
|
166 // resource. The decoder monitor must be obtained before calling this. |
|
167 // aEndTime is in microseconds. |
|
168 void SetMediaEndTime(int64_t aEndTime); |
|
169 |
|
170 // Called from main thread to update the duration with an estimated value. |
|
171 // The duration is only changed if its significantly different than the |
|
172 // the current duration, as the incoming duration is an estimate and so |
|
173 // often is unstable as more data is read and the estimate is updated. |
|
174 // Can result in a durationchangeevent. aDuration is in microseconds. |
|
175 void UpdateEstimatedDuration(int64_t aDuration); |
|
176 |
|
177 // Functions used by assertions to ensure we're calling things |
|
178 // on the appropriate threads. |
|
179 bool OnDecodeThread() const; |
|
180 bool OnStateMachineThread() const; |
|
181 bool OnAudioThread() const { |
|
182 return IsCurrentThread(mAudioThread); |
|
183 } |
|
184 |
|
185 MediaDecoderOwner::NextFrameStatus GetNextFrameStatus(); |
|
186 |
|
187 // Cause state transitions. These methods obtain the decoder monitor |
|
188 // to synchronise the change of state, and to notify other threads |
|
189 // that the state has changed. |
|
190 void Play(); |
|
191 |
|
192 // Seeks to the decoder to aTarget asynchronously. |
|
193 void Seek(const SeekTarget& aTarget); |
|
194 |
|
195 // Returns the current playback position in seconds. |
|
196 // Called from the main thread to get the current frame time. The decoder |
|
197 // monitor must be obtained before calling this. |
|
198 double GetCurrentTime() const; |
|
199 |
|
200 // Clear the flag indicating that a playback position change event |
|
201 // is currently queued. This is called from the main thread and must |
|
202 // be called with the decode monitor held. |
|
203 void ClearPositionChangeFlag(); |
|
204 |
|
205 // Called from the main thread or the decoder thread to set whether the media |
|
206 // resource can seek into unbuffered ranges. The decoder monitor must be |
|
207 // obtained before calling this. |
|
208 void SetTransportSeekable(bool aSeekable); |
|
209 |
|
210 // Called from the main thread or the decoder thread to set whether the media |
|
211 // can seek to random location. This is not true for chained ogg and WebM |
|
212 // media without index. The decoder monitor must be obtained before calling |
|
213 // this. |
|
214 void SetMediaSeekable(bool aSeekable); |
|
215 |
|
216 // Update the playback position. This can result in a timeupdate event |
|
217 // and an invalidate of the frame being dispatched asynchronously if |
|
218 // there is no such event currently queued. |
|
219 // Only called on the decoder thread. Must be called with |
|
220 // the decode monitor held. |
|
221 void UpdatePlaybackPosition(int64_t aTime); |
|
222 |
|
223 // Causes the state machine to switch to buffering state, and to |
|
224 // immediately stop playback and buffer downloaded data. Must be called |
|
225 // with the decode monitor held. Called on the state machine thread and |
|
226 // the main thread. |
|
227 void StartBuffering(); |
|
228 |
|
229 // This is called on the state machine thread and audio thread. |
|
230 // The decoder monitor must be obtained before calling this. |
|
231 bool HasAudio() const { |
|
232 AssertCurrentThreadInMonitor(); |
|
233 return mInfo.HasAudio(); |
|
234 } |
|
235 |
|
236 // This is called on the state machine thread and audio thread. |
|
237 // The decoder monitor must be obtained before calling this. |
|
238 bool HasVideo() const { |
|
239 AssertCurrentThreadInMonitor(); |
|
240 return mInfo.HasVideo(); |
|
241 } |
|
242 |
|
243 // Should be called by main thread. |
|
244 bool HaveNextFrameData(); |
|
245 |
|
246 // Must be called with the decode monitor held. |
|
247 bool IsBuffering() const { |
|
248 AssertCurrentThreadInMonitor(); |
|
249 |
|
250 return mState == DECODER_STATE_BUFFERING; |
|
251 } |
|
252 |
|
253 // Must be called with the decode monitor held. |
|
254 bool IsSeeking() const { |
|
255 AssertCurrentThreadInMonitor(); |
|
256 |
|
257 return mState == DECODER_STATE_SEEKING; |
|
258 } |
|
259 |
|
260 nsresult GetBuffered(dom::TimeRanges* aBuffered); |
|
261 |
|
262 void SetPlaybackRate(double aPlaybackRate); |
|
263 void SetPreservesPitch(bool aPreservesPitch); |
|
264 |
|
265 size_t SizeOfVideoQueue() { |
|
266 if (mReader) { |
|
267 return mReader->SizeOfVideoQueueInBytes(); |
|
268 } |
|
269 return 0; |
|
270 } |
|
271 |
|
272 size_t SizeOfAudioQueue() { |
|
273 if (mReader) { |
|
274 return mReader->SizeOfAudioQueueInBytes(); |
|
275 } |
|
276 return 0; |
|
277 } |
|
278 |
|
279 void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset); |
|
280 |
|
281 int64_t GetEndMediaTime() const { |
|
282 AssertCurrentThreadInMonitor(); |
|
283 return mEndTime; |
|
284 } |
|
285 |
|
286 bool IsTransportSeekable() { |
|
287 AssertCurrentThreadInMonitor(); |
|
288 return mTransportSeekable; |
|
289 } |
|
290 |
|
291 bool IsMediaSeekable() { |
|
292 AssertCurrentThreadInMonitor(); |
|
293 return mMediaSeekable; |
|
294 } |
|
295 |
|
296 // Returns the shared state machine thread. |
|
297 nsIEventTarget* GetStateMachineThread(); |
|
298 |
|
299 // Calls ScheduleStateMachine() after taking the decoder lock. Also |
|
300 // notifies the decoder thread in case it's waiting on the decoder lock. |
|
301 void ScheduleStateMachineWithLockAndWakeDecoder(); |
|
302 |
|
303 // Schedules the shared state machine thread to run the state machine |
|
304 // in aUsecs microseconds from now, if it's not already scheduled to run |
|
305 // earlier, in which case the request is discarded. |
|
306 nsresult ScheduleStateMachine(int64_t aUsecs = 0); |
|
307 |
|
308 // Timer function to implement ScheduleStateMachine(aUsecs). |
|
309 nsresult TimeoutExpired(int aGeneration); |
|
310 |
|
311 // Set the media fragment end time. aEndTime is in microseconds. |
|
312 void SetFragmentEndTime(int64_t aEndTime); |
|
313 |
|
314 // Drop reference to decoder. Only called during shutdown dance. |
|
315 void ReleaseDecoder() { |
|
316 MOZ_ASSERT(mReader); |
|
317 if (mReader) { |
|
318 mReader->ReleaseDecoder(); |
|
319 } |
|
320 mDecoder = nullptr; |
|
321 } |
|
322 |
|
323 // If we're playing into a MediaStream, record the current point in the |
|
324 // MediaStream and the current point in our media resource so later we can |
|
325 // convert MediaStream playback positions to media resource positions. Best to |
|
326 // call this while we're not playing (while the MediaStream is blocked). Can |
|
327 // be called on any thread with the decoder monitor held. |
|
328 void SetSyncPointForMediaStream(); |
|
329 int64_t GetCurrentTimeViaMediaStreamSync(); |
|
330 |
|
331 // Copy queued audio/video data in the reader to any output MediaStreams that |
|
332 // need it. |
|
333 void SendStreamData(); |
|
334 void FinishStreamData(); |
|
335 bool HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs); |
|
336 bool HaveEnoughDecodedVideo(); |
|
337 |
|
338 // Returns true if the state machine has shutdown or is in the process of |
|
339 // shutting down. The decoder monitor must be held while calling this. |
|
340 bool IsShutdown(); |
|
341 |
|
342 void QueueMetadata(int64_t aPublishTime, int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags); |
|
343 |
|
344 // Returns true if we're currently playing. The decoder monitor must |
|
345 // be held. |
|
346 bool IsPlaying(); |
|
347 |
|
348 // Called when the reader may have acquired the hardware resources required |
|
349 // to begin decoding. The state machine may move into DECODING_METADATA if |
|
350 // appropriate. The decoder monitor must be held while calling this. |
|
351 void NotifyWaitingForResourcesStatusChanged(); |
|
352 |
|
353 // Notifies the state machine that should minimize the number of samples |
|
354 // decoded we preroll, until playback starts. The first time playback starts |
|
355 // the state machine is free to return to prerolling normally. Note |
|
356 // "prerolling" in this context refers to when we decode and buffer decoded |
|
357 // samples in advance of when they're needed for playback. |
|
358 void SetMinimizePrerollUntilPlaybackStarts(); |
|
359 |
|
360 protected: |
|
361 virtual ~MediaDecoderStateMachine(); |
|
362 |
|
363 void AssertCurrentThreadInMonitor() const { mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); } |
|
364 |
|
365 class WakeDecoderRunnable : public nsRunnable { |
|
366 public: |
|
367 WakeDecoderRunnable(MediaDecoderStateMachine* aSM) |
|
368 : mMutex("WakeDecoderRunnable"), mStateMachine(aSM) {} |
|
369 NS_IMETHOD Run() MOZ_OVERRIDE |
|
370 { |
|
371 nsRefPtr<MediaDecoderStateMachine> stateMachine; |
|
372 { |
|
373 // Don't let Run() (called by media stream graph thread) race with |
|
374 // Revoke() (called by decoder state machine thread) |
|
375 MutexAutoLock lock(mMutex); |
|
376 if (!mStateMachine) |
|
377 return NS_OK; |
|
378 stateMachine = mStateMachine; |
|
379 } |
|
380 stateMachine->ScheduleStateMachineWithLockAndWakeDecoder(); |
|
381 return NS_OK; |
|
382 } |
|
383 void Revoke() |
|
384 { |
|
385 MutexAutoLock lock(mMutex); |
|
386 mStateMachine = nullptr; |
|
387 } |
|
388 |
|
389 Mutex mMutex; |
|
390 // Protected by mMutex. |
|
391 // We don't use an owning pointer here, because keeping mStateMachine alive |
|
392 // would mean in some cases we'd have to destroy mStateMachine from this |
|
393 // object, which would be problematic since MediaDecoderStateMachine can |
|
394 // only be destroyed on the main thread whereas this object can be destroyed |
|
395 // on the media stream graph thread. |
|
396 MediaDecoderStateMachine* mStateMachine; |
|
397 }; |
|
398 WakeDecoderRunnable* GetWakeDecoderRunnable(); |
|
399 |
|
400 MediaQueue<AudioData>& AudioQueue() { return mReader->AudioQueue(); } |
|
401 MediaQueue<VideoData>& VideoQueue() { return mReader->VideoQueue(); } |
|
402 |
|
403 // True if our buffers of decoded audio are not full, and we should |
|
404 // decode more. |
|
405 bool NeedToDecodeAudio(); |
|
406 |
|
407 // Decodes some audio. This should be run on the decode task queue. |
|
408 void DecodeAudio(); |
|
409 |
|
410 // True if our buffers of decoded video are not full, and we should |
|
411 // decode more. |
|
412 bool NeedToDecodeVideo(); |
|
413 |
|
414 // Decodes some video. This should be run on the decode task queue. |
|
415 void DecodeVideo(); |
|
416 |
|
417 // Returns true if we've got less than aAudioUsecs microseconds of decoded |
|
418 // and playable data. The decoder monitor must be held. |
|
419 bool HasLowDecodedData(int64_t aAudioUsecs); |
|
420 |
|
421 // Returns true if we're running low on data which is not yet decoded. |
|
422 // The decoder monitor must be held. |
|
423 bool HasLowUndecodedData(); |
|
424 |
|
425 // Returns true if we have less than aUsecs of undecoded data available. |
|
426 bool HasLowUndecodedData(double aUsecs); |
|
427 |
|
428 // Returns the number of unplayed usecs of audio we've got decoded and/or |
|
429 // pushed to the hardware waiting to play. This is how much audio we can |
|
430 // play without having to run the audio decoder. The decoder monitor |
|
431 // must be held. |
|
432 int64_t AudioDecodedUsecs(); |
|
433 |
|
434 // Returns true when there's decoded audio waiting to play. |
|
435 // The decoder monitor must be held. |
|
436 bool HasFutureAudio(); |
|
437 |
|
438 // Returns true if we recently exited "quick buffering" mode. |
|
439 bool JustExitedQuickBuffering(); |
|
440 |
|
441 // Waits on the decoder ReentrantMonitor for aUsecs microseconds. If the decoder |
|
442 // monitor is awoken by a Notify() call, we'll continue waiting, unless |
|
443 // we've moved into shutdown state. This enables us to ensure that we |
|
444 // wait for a specified time, and that the myriad of Notify()s we do on |
|
445 // the decoder monitor don't cause the audio thread to be starved. aUsecs |
|
446 // values of less than 1 millisecond are rounded up to 1 millisecond |
|
447 // (see bug 651023). The decoder monitor must be held. Called only on the |
|
448 // audio thread. |
|
449 void Wait(int64_t aUsecs); |
|
450 |
|
451 // Dispatches an asynchronous event to update the media element's ready state. |
|
452 void UpdateReadyState(); |
|
453 |
|
454 // Resets playback timing data. Called when we seek, on the decode thread. |
|
455 void ResetPlayback(); |
|
456 |
|
457 // Returns the audio clock, if we have audio, or -1 if we don't. |
|
458 // Called on the state machine thread. |
|
459 int64_t GetAudioClock(); |
|
460 |
|
461 // Get the video stream position, taking the |playbackRate| change into |
|
462 // account. This is a position in the media, not the duration of the playback |
|
463 // so far. |
|
464 int64_t GetVideoStreamPosition(); |
|
465 |
|
466 // Return the current time, either the audio clock if available (if the media |
|
467 // has audio, and the playback is possible), or a clock for the video. |
|
468 // Called on the state machine thread. |
|
469 int64_t GetClock(); |
|
470 |
|
471 // Returns the presentation time of the first audio or video frame in the |
|
472 // media. If the media has video, it returns the first video frame. The |
|
473 // decoder monitor must be held with exactly one lock count. Called on the |
|
474 // state machine thread. |
|
475 VideoData* FindStartTime(); |
|
476 |
|
477 // Update only the state machine's current playback position (and duration, |
|
478 // if unknown). Does not update the playback position on the decoder or |
|
479 // media element -- use UpdatePlaybackPosition for that. Called on the state |
|
480 // machine thread, caller must hold the decoder lock. |
|
481 void UpdatePlaybackPositionInternal(int64_t aTime); |
|
482 |
|
483 // Pushes the image down the rendering pipeline. Called on the shared state |
|
484 // machine thread. The decoder monitor must *not* be held when calling this. |
|
485 void RenderVideoFrame(VideoData* aData, TimeStamp aTarget); |
|
486 |
|
487 // If we have video, display a video frame if it's time for display has |
|
488 // arrived, otherwise sleep until it's time for the next frame. Update the |
|
489 // current frame time as appropriate, and trigger ready state update. The |
|
490 // decoder monitor must be held with exactly one lock count. Called on the |
|
491 // state machine thread. |
|
492 void AdvanceFrame(); |
|
493 |
|
494 // Write aFrames of audio frames of silence to the audio hardware. Returns |
|
495 // the number of frames actually written. The write size is capped at |
|
496 // SILENCE_BYTES_CHUNK (32kB), so must be called in a loop to write the |
|
497 // desired number of frames. This ensures that the playback position |
|
498 // advances smoothly, and guarantees that we don't try to allocate an |
|
499 // impossibly large chunk of memory in order to play back silence. Called |
|
500 // on the audio thread. |
|
501 uint32_t PlaySilence(uint32_t aFrames, |
|
502 uint32_t aChannels, |
|
503 uint64_t aFrameOffset); |
|
504 |
|
505 // Pops an audio chunk from the front of the audio queue, and pushes its |
|
506 // audio data to the audio hardware. |
|
507 uint32_t PlayFromAudioQueue(uint64_t aFrameOffset, uint32_t aChannels); |
|
508 |
|
509 // Stops the audio thread. The decoder monitor must be held with exactly |
|
510 // one lock count. Called on the state machine thread. |
|
511 void StopAudioThread(); |
|
512 |
|
513 // Starts the audio thread. The decoder monitor must be held with exactly |
|
514 // one lock count. Called on the state machine thread. |
|
515 nsresult StartAudioThread(); |
|
516 |
|
517 // The main loop for the audio thread. Sent to the thread as |
|
518 // an nsRunnableMethod. This continually does blocking writes to |
|
519 // to audio stream to play audio data. |
|
520 void AudioLoop(); |
|
521 |
|
522 // Sets internal state which causes playback of media to pause. |
|
523 // The decoder monitor must be held. |
|
524 void StopPlayback(); |
|
525 |
|
526 // Sets internal state which causes playback of media to begin or resume. |
|
527 // Must be called with the decode monitor held. |
|
528 void StartPlayback(); |
|
529 |
|
530 // Moves the decoder into decoding state. Called on the state machine |
|
531 // thread. The decoder monitor must be held. |
|
532 void StartDecoding(); |
|
533 |
|
534 // Moves the decoder into the shutdown state, and dispatches an error |
|
535 // event to the media element. This begins shutting down the decoder. |
|
536 // The decoder monitor must be held. This is only called on the |
|
537 // decode thread. |
|
538 void DecodeError(); |
|
539 |
|
540 void StartWaitForResources(); |
|
541 |
|
542 // Dispatches a task to the decode task queue to begin decoding metadata. |
|
543 // This is threadsafe and can be called on any thread. |
|
544 // The decoder monitor must be held. |
|
545 nsresult EnqueueDecodeMetadataTask(); |
|
546 |
|
547 nsresult DispatchAudioDecodeTaskIfNeeded(); |
|
548 |
|
549 // Ensures a to decode audio has been dispatched to the decode task queue. |
|
550 // If a task to decode has already been dispatched, this does nothing, |
|
551 // otherwise this dispatches a task to do the decode. |
|
552 // This is called on the state machine or decode threads. |
|
553 // The decoder monitor must be held. |
|
554 nsresult EnsureAudioDecodeTaskQueued(); |
|
555 |
|
556 nsresult DispatchVideoDecodeTaskIfNeeded(); |
|
557 |
|
558 // Ensures a to decode video has been dispatched to the decode task queue. |
|
559 // If a task to decode has already been dispatched, this does nothing, |
|
560 // otherwise this dispatches a task to do the decode. |
|
561 // The decoder monitor must be held. |
|
562 nsresult EnsureVideoDecodeTaskQueued(); |
|
563 |
|
564 // Dispatches a task to the decode task queue to seek the decoder. |
|
565 // The decoder monitor must be held. |
|
566 nsresult EnqueueDecodeSeekTask(); |
|
567 |
|
568 // Calls the reader's SetIdle(), with aIsIdle as parameter. This is only |
|
569 // called in a task dispatched to the decode task queue, don't call it |
|
570 // directly. |
|
571 void SetReaderIdle(); |
|
572 void SetReaderActive(); |
|
573 |
|
574 // Re-evaluates the state and determines whether we need to dispatch |
|
575 // events to run the decode, or if not whether we should set the reader |
|
576 // to idle mode. This is threadsafe, and can be called from any thread. |
|
577 // The decoder monitor must be held. |
|
578 void DispatchDecodeTasksIfNeeded(); |
|
579 |
|
580 // Called before we do anything on the decode task queue to set the reader |
|
581 // as not idle if it was idle. This is called before we decode, seek, or |
|
582 // decode metadata (in case we were dormant or awaiting resources). |
|
583 void EnsureActive(); |
|
584 |
|
585 // Queries our state to see whether the decode has finished for all streams. |
|
586 // If so, we move into DECODER_STATE_COMPLETED and schedule the state machine |
|
587 // to run. |
|
588 // The decoder monitor must be held. |
|
589 void CheckIfDecodeComplete(); |
|
590 |
|
591 // Returns the "media time". This is the absolute time which the media |
|
592 // playback has reached. i.e. this returns values in the range |
|
593 // [mStartTime, mEndTime], and mStartTime will not be 0 if the media does |
|
594 // not start at 0. Note this is different to the value returned |
|
595 // by GetCurrentTime(), which is in the range [0,duration]. |
|
596 int64_t GetMediaTime() const { |
|
597 AssertCurrentThreadInMonitor(); |
|
598 return mStartTime + mCurrentFrameTime; |
|
599 } |
|
600 |
|
601 // Returns an upper bound on the number of microseconds of audio that is |
|
602 // decoded and playable. This is the sum of the number of usecs of audio which |
|
603 // is decoded and in the reader's audio queue, and the usecs of unplayed audio |
|
604 // which has been pushed to the audio hardware for playback. Note that after |
|
605 // calling this, the audio hardware may play some of the audio pushed to |
|
606 // hardware, so this can only be used as a upper bound. The decoder monitor |
|
607 // must be held when calling this. Called on the decode thread. |
|
608 int64_t GetDecodedAudioDuration(); |
|
609 |
|
610 // Load metadata. Called on the decode thread. The decoder monitor |
|
611 // must be held with exactly one lock count. |
|
612 nsresult DecodeMetadata(); |
|
613 |
|
614 // Seeks to mSeekTarget. Called on the decode thread. The decoder monitor |
|
615 // must be held with exactly one lock count. |
|
616 void DecodeSeek(); |
|
617 |
|
618 // Decode loop, decodes data until EOF or shutdown. |
|
619 // Called on the decode thread. |
|
620 void DecodeLoop(); |
|
621 |
|
622 void CallDecodeMetadata(); |
|
623 |
|
624 // Copy audio from an AudioData packet to aOutput. This may require |
|
625 // inserting silence depending on the timing of the audio packet. |
|
626 void SendStreamAudio(AudioData* aAudio, DecodedStreamData* aStream, |
|
627 AudioSegment* aOutput); |
|
628 |
|
629 // State machine thread run function. Defers to RunStateMachine(). |
|
630 nsresult CallRunStateMachine(); |
|
631 |
|
632 // Performs one "cycle" of the state machine. Polls the state, and may send |
|
633 // a video frame to be displayed, and generally manages the decode. Called |
|
634 // periodically via timer to ensure the video stays in sync. |
|
635 nsresult RunStateMachine(); |
|
636 |
|
637 bool IsStateMachineScheduled() const { |
|
638 AssertCurrentThreadInMonitor(); |
|
639 return !mTimeout.IsNull(); |
|
640 } |
|
641 |
|
642 // Returns true if we're not playing and the decode thread has filled its |
|
643 // decode buffers and is waiting. We can shut the decode thread down in this |
|
644 // case as it may not be needed again. |
|
645 bool IsPausedAndDecoderWaiting(); |
|
646 |
|
647 // The decoder object that created this state machine. The state machine |
|
648 // holds a strong reference to the decoder to ensure that the decoder stays |
|
649 // alive once media element has started the decoder shutdown process, and has |
|
650 // dropped its reference to the decoder. This enables the state machine to |
|
651 // keep using the decoder's monitor until the state machine has finished |
|
652 // shutting down, without fear of the monitor being destroyed. After |
|
653 // shutting down, the state machine will then release this reference, |
|
654 // causing the decoder to be destroyed. This is accessed on the decode, |
|
655 // state machine, audio and main threads. |
|
656 nsRefPtr<MediaDecoder> mDecoder; |
|
657 |
|
658 // The decoder monitor must be obtained before modifying this state. |
|
659 // NotifyAll on the monitor must be called when the state is changed so |
|
660 // that interested threads can wake up and alter behaviour if appropriate |
|
661 // Accessed on state machine, audio, main, and AV thread. |
|
662 State mState; |
|
663 |
|
664 // Thread for pushing audio onto the audio hardware. |
|
665 // The "audio push thread". |
|
666 nsCOMPtr<nsIThread> mAudioThread; |
|
667 |
|
668 // The task queue in which we run decode tasks. This is referred to as |
|
669 // the "decode thread", though in practise tasks can run on a different |
|
670 // thread every time they're called. |
|
671 RefPtr<MediaTaskQueue> mDecodeTaskQueue; |
|
672 |
|
673 RefPtr<SharedThreadPool> mStateMachineThreadPool; |
|
674 |
|
675 // Timer to run the state machine cycles. Used by |
|
676 // ScheduleStateMachine(). Access protected by decoder monitor. |
|
677 nsCOMPtr<nsITimer> mTimer; |
|
678 |
|
679 // Timestamp at which the next state machine cycle will run. |
|
680 // Access protected by decoder monitor. |
|
681 TimeStamp mTimeout; |
|
682 |
|
683 // Used to check if there are state machine cycles are running in sequence. |
|
684 DebugOnly<bool> mInRunningStateMachine; |
|
685 |
|
686 // The time that playback started from the system clock. This is used for |
|
687 // timing the presentation of video frames when there's no audio. |
|
688 // Accessed only via the state machine thread. |
|
689 TimeStamp mPlayStartTime; |
|
690 |
|
691 // When we start writing decoded data to a new DecodedDataStream, or we |
|
692 // restart writing due to PlaybackStarted(), we record where we are in the |
|
693 // MediaStream and what that corresponds to in the media. |
|
694 StreamTime mSyncPointInMediaStream; |
|
695 int64_t mSyncPointInDecodedStream; // microseconds |
|
696 |
|
697 // When the playbackRate changes, and there is no audio clock, it is necessary |
|
698 // to reset the mPlayStartTime. This is done next time the clock is queried, |
|
699 // when this member is true. Access protected by decoder monitor. |
|
700 bool mResetPlayStartTime; |
|
701 |
|
702 // The amount of time we've spent playing already the media. The current |
|
703 // playback position is therefore |Now() - mPlayStartTime + |
|
704 // mPlayDuration|, which must be adjusted by mStartTime if used with media |
|
705 // timestamps. Accessed only via the state machine thread. |
|
706 int64_t mPlayDuration; |
|
707 |
|
708 // Time that buffering started. Used for buffering timeout and only |
|
709 // accessed on the state machine thread. This is null while we're not |
|
710 // buffering. |
|
711 TimeStamp mBufferingStart; |
|
712 |
|
713 // Start time of the media, in microseconds. This is the presentation |
|
714 // time of the first frame decoded from the media, and is used to calculate |
|
715 // duration and as a bounds for seeking. Accessed on state machine, decode, |
|
716 // and main threads. Access controlled by decoder monitor. |
|
717 int64_t mStartTime; |
|
718 |
|
719 // Time of the last frame in the media, in microseconds. This is the |
|
720 // end time of the last frame in the media. Accessed on state |
|
721 // machine, decode, and main threads. Access controlled by decoder monitor. |
|
722 int64_t mEndTime; |
|
723 |
|
724 // Position to seek to in microseconds when the seek state transition occurs. |
|
725 // The decoder monitor lock must be obtained before reading or writing |
|
726 // this value. Accessed on main and decode thread. |
|
727 SeekTarget mSeekTarget; |
|
728 |
|
729 // Media Fragment end time in microseconds. Access controlled by decoder monitor. |
|
730 int64_t mFragmentEndTime; |
|
731 |
|
732 // The audio stream resource. Used on the state machine, and audio threads. |
|
733 // This is created and destroyed on the audio thread, while holding the |
|
734 // decoder monitor, so if this is used off the audio thread, you must |
|
735 // first acquire the decoder monitor and check that it is non-null. |
|
736 RefPtr<AudioStream> mAudioStream; |
|
737 |
|
738 // The reader, don't call its methods with the decoder monitor held. |
|
739 // This is created in the play state machine's constructor, and destroyed |
|
740 // in the play state machine's destructor. |
|
741 nsAutoPtr<MediaDecoderReader> mReader; |
|
742 |
|
743 // Accessed only on the state machine thread. |
|
744 // Not an nsRevocableEventPtr since we must Revoke() it well before |
|
745 // this object is destroyed, anyway. |
|
746 // Protected by decoder monitor except during the SHUTDOWN state after the |
|
747 // decoder thread has been stopped. |
|
748 nsRevocableEventPtr<WakeDecoderRunnable> mPendingWakeDecoder; |
|
749 |
|
750 // The time of the current frame in microseconds. This is referenced from |
|
751 // 0 which is the initial playback position. Set by the state machine |
|
752 // thread, and read-only from the main thread to get the current |
|
753 // time value. Synchronised via decoder monitor. |
|
754 int64_t mCurrentFrameTime; |
|
755 |
|
756 // The presentation time of the first audio frame that was played in |
|
757 // microseconds. We can add this to the audio stream position to determine |
|
758 // the current audio time. Accessed on audio and state machine thread. |
|
759 // Synchronized by decoder monitor. |
|
760 int64_t mAudioStartTime; |
|
761 |
|
762 // The end time of the last audio frame that's been pushed onto the audio |
|
763 // hardware in microseconds. This will approximately be the end time of the |
|
764 // audio stream, unless another frame is pushed to the hardware. |
|
765 int64_t mAudioEndTime; |
|
766 |
|
767 // The presentation end time of the last video frame which has been displayed |
|
768 // in microseconds. Accessed from the state machine thread. |
|
769 int64_t mVideoFrameEndTime; |
|
770 |
|
771 // Volume of playback. 0.0 = muted. 1.0 = full volume. Read/Written |
|
772 // from the state machine and main threads. Synchronised via decoder |
|
773 // monitor. |
|
774 double mVolume; |
|
775 |
|
776 // Playback rate. 1.0 : normal speed, 0.5 : two times slower. Synchronized via |
|
777 // decoder monitor. |
|
778 double mPlaybackRate; |
|
779 |
|
780 // Pitch preservation for the playback rate. Synchronized via decoder monitor. |
|
781 bool mPreservesPitch; |
|
782 |
|
783 // Position at which the last playback rate change occured, used to compute |
|
784 // the actual position in the stream when the playback rate changes and there |
|
785 // is no audio to be sync-ed to. Synchronized via decoder monitor. |
|
786 int64_t mBasePosition; |
|
787 |
|
788 // Time at which we started decoding. Synchronised via decoder monitor. |
|
789 TimeStamp mDecodeStartTime; |
|
790 |
|
791 // The maximum number of second we spend buffering when we are short on |
|
792 // unbuffered data. |
|
793 uint32_t mBufferingWait; |
|
794 int64_t mLowDataThresholdUsecs; |
|
795 |
|
796 // If we've got more than mAmpleVideoFrames decoded video frames waiting in |
|
797 // the video queue, we will not decode any more video frames until some have |
|
798 // been consumed by the play state machine thread. |
|
799 uint32_t mAmpleVideoFrames; |
|
800 |
|
801 // Low audio threshold. If we've decoded less than this much audio we |
|
802 // consider our audio decode "behind", and we may skip video decoding |
|
803 // in order to allow our audio decoding to catch up. We favour audio |
|
804 // decoding over video. We increase this threshold if we're slow to |
|
805 // decode video frames, in order to reduce the chance of audio underruns. |
|
806 // Note that we don't ever reset this threshold, it only ever grows as |
|
807 // we detect that the decode can't keep up with rendering. |
|
808 int64_t mLowAudioThresholdUsecs; |
|
809 |
|
810 // Our "ample" audio threshold. Once we've this much audio decoded, we |
|
811 // pause decoding. If we increase mLowAudioThresholdUsecs, we'll also |
|
812 // increase this too appropriately (we don't want mLowAudioThresholdUsecs |
|
813 // to be greater than ampleAudioThreshold, else we'd stop decoding!). |
|
814 // Note that we don't ever reset this threshold, it only ever grows as |
|
815 // we detect that the decode can't keep up with rendering. |
|
816 int64_t mAmpleAudioThresholdUsecs; |
|
817 |
|
818 // At the start of decoding we want to "preroll" the decode until we've |
|
819 // got a few frames decoded before we consider whether decode is falling |
|
820 // behind. Otherwise our "we're falling behind" logic will trigger |
|
821 // unneccessarily if we start playing as soon as the first sample is |
|
822 // decoded. These two fields store how many video frames and audio |
|
823 // samples we must consume before are considered to be finished prerolling. |
|
824 uint32_t mAudioPrerollUsecs; |
|
825 uint32_t mVideoPrerollFrames; |
|
826 |
|
827 // When we start decoding (either for the first time, or after a pause) |
|
828 // we may be low on decoded data. We don't want our "low data" logic to |
|
829 // kick in and decide that we're low on decoded data because the download |
|
830 // can't keep up with the decode, and cause us to pause playback. So we |
|
831 // have a "preroll" stage, where we ignore the results of our "low data" |
|
832 // logic during the first few frames of our decode. This occurs during |
|
833 // playback. The flags below are true when the corresponding stream is |
|
834 // being "prerolled". |
|
835 bool mIsAudioPrerolling; |
|
836 bool mIsVideoPrerolling; |
|
837 |
|
838 // True when we have an audio stream that we're decoding, and we have not |
|
839 // yet decoded to end of stream. |
|
840 bool mIsAudioDecoding; |
|
841 |
|
842 // True when we have a video stream that we're decoding, and we have not |
|
843 // yet decoded to end of stream. |
|
844 bool mIsVideoDecoding; |
|
845 |
|
846 // True when we have dispatched a task to the decode task queue to run |
|
847 // the audio decode. |
|
848 bool mDispatchedAudioDecodeTask; |
|
849 |
|
850 // True when we have dispatched a task to the decode task queue to run |
|
851 // the video decode. |
|
852 bool mDispatchedVideoDecodeTask; |
|
853 |
|
854 // True when the reader is initialized, but has been ordered "idle" by the |
|
855 // state machine. This happens when the MediaQueue's of decoded data are |
|
856 // "full" and playback is paused. The reader may choose to use the idle |
|
857 // notification to enter a low power state. |
|
858 bool mIsReaderIdle; |
|
859 |
|
860 // If the video decode is falling behind the audio, we'll start dropping the |
|
861 // inter-frames up until the next keyframe which is at or before the current |
|
862 // playback position. skipToNextKeyframe is true if we're currently |
|
863 // skipping up to the next keyframe. |
|
864 bool mSkipToNextKeyFrame; |
|
865 |
|
866 // True if we shouldn't play our audio (but still write it to any capturing |
|
867 // streams). When this is true, mStopAudioThread is always true and |
|
868 // the audio thread will never start again after it has stopped. |
|
869 bool mAudioCaptured; |
|
870 |
|
871 // True if the media resource can be seeked on a transport level. Accessed |
|
872 // from the state machine and main threads. Synchronised via decoder monitor. |
|
873 bool mTransportSeekable; |
|
874 |
|
875 // True if the media can be seeked. Accessed from the state machine and main |
|
876 // threads. Synchronised via decoder monitor. |
|
877 bool mMediaSeekable; |
|
878 |
|
879 // True if an event to notify about a change in the playback |
|
880 // position has been queued, but not yet run. It is set to false when |
|
881 // the event is run. This allows coalescing of these events as they can be |
|
882 // produced many times per second. Synchronised via decoder monitor. |
|
883 // Accessed on main and state machine threads. |
|
884 bool mPositionChangeQueued; |
|
885 |
|
886 // True if the audio playback thread has finished. It is finished |
|
887 // when either all the audio frames have completed playing, or we've moved |
|
888 // into shutdown state, and the threads are to be |
|
889 // destroyed. Written by the audio playback thread and read and written by |
|
890 // the state machine thread. Synchronised via decoder monitor. |
|
891 // When data is being sent to a MediaStream, this is true when all data has |
|
892 // been written to the MediaStream. |
|
893 bool mAudioCompleted; |
|
894 |
|
895 // True if mDuration has a value obtained from an HTTP header, or from |
|
896 // the media index/metadata. Accessed on the state machine thread. |
|
897 bool mGotDurationFromMetaData; |
|
898 |
|
899 // True if we've dispatched an event to the decode task queue to call |
|
900 // DecodeThreadRun(). We use this flag to prevent us from dispatching |
|
901 // unneccessary runnables, since the decode thread runs in a loop. |
|
902 bool mDispatchedEventToDecode; |
|
903 |
|
904 // False while audio thread should be running. Accessed state machine |
|
905 // and audio threads. Syncrhonised by decoder monitor. |
|
906 bool mStopAudioThread; |
|
907 |
|
908 // If this is true while we're in buffering mode, we can exit early, |
|
909 // as it's likely we may be able to playback. This happens when we enter |
|
910 // buffering mode soon after the decode starts, because the decode-ahead |
|
911 // ran fast enough to exhaust all data while the download is starting up. |
|
912 // Synchronised via decoder monitor. |
|
913 bool mQuickBuffering; |
|
914 |
|
915 // True if we should not decode/preroll unnecessary samples, unless we're |
|
916 // played. "Prerolling" in this context refers to when we decode and |
|
917 // buffer decoded samples in advance of when they're needed for playback. |
|
918 // This flag is set for preload=metadata media, and means we won't |
|
919 // decode more than the first video frame and first block of audio samples |
|
920 // for that media when we startup, or after a seek. When Play() is called, |
|
921 // we reset this flag, as we assume the user is playing the media, so |
|
922 // prerolling is appropriate then. This flag is used to reduce the overhead |
|
923 // of prerolling samples for media elements that may not play, both |
|
924 // memory and CPU overhead. |
|
925 bool mMinimizePreroll; |
|
926 |
|
927 // True if the decode thread has gone filled its buffers and is now |
|
928 // waiting to be awakened before it continues decoding. Synchronized |
|
929 // by the decoder monitor. |
|
930 bool mDecodeThreadWaiting; |
|
931 |
|
932 // True is we are decoding a realtime stream, like a camera stream |
|
933 bool mRealTime; |
|
934 |
|
935 // Stores presentation info required for playback. The decoder monitor |
|
936 // must be held when accessing this. |
|
937 MediaInfo mInfo; |
|
938 |
|
939 mozilla::MediaMetadataManager mMetadataManager; |
|
940 |
|
941 MediaDecoderOwner::NextFrameStatus mLastFrameStatus; |
|
942 |
|
943 // The id of timer tasks, used to ignore tasks that are scheduled previously. |
|
944 int mTimerId; |
|
945 }; |
|
946 |
|
947 } // namespace mozilla; |
|
948 #endif |