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 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla code.
17 : *
18 : * The Initial Developer of the Original Code is the Mozilla Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 2007
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Chris Double <chris.double@double.co.nz>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 : #if !defined(nsHTMLMediaElement_h__)
39 : #define nsHTMLMediaElement_h__
40 :
41 : #include "nsIDOMHTMLMediaElement.h"
42 : #include "nsGenericHTMLElement.h"
43 : #include "nsMediaDecoder.h"
44 : #include "nsIChannel.h"
45 : #include "nsIHttpChannel.h"
46 : #include "nsThreadUtils.h"
47 : #include "nsIDOMRange.h"
48 : #include "nsCycleCollectionParticipant.h"
49 : #include "nsILoadGroup.h"
50 : #include "nsIObserver.h"
51 : #include "nsAudioStream.h"
52 : #include "VideoFrameContainer.h"
53 : #include "mozilla/CORSMode.h"
54 :
55 : // Define to output information on decoding and painting framerate
56 : /* #define DEBUG_FRAME_RATE 1 */
57 :
58 : typedef PRUint16 nsMediaNetworkState;
59 : typedef PRUint16 nsMediaReadyState;
60 :
61 : class nsHTMLMediaElement : public nsGenericHTMLElement,
62 : public nsIObserver
63 : {
64 : public:
65 : typedef mozilla::TimeStamp TimeStamp;
66 : typedef mozilla::layers::ImageContainer ImageContainer;
67 : typedef mozilla::VideoFrameContainer VideoFrameContainer;
68 :
69 : enum CanPlayStatus {
70 : CANPLAY_NO,
71 : CANPLAY_MAYBE,
72 : CANPLAY_YES
73 : };
74 :
75 0 : mozilla::CORSMode GetCORSMode() {
76 0 : return mCORSMode;
77 : }
78 :
79 : nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo);
80 : virtual ~nsHTMLMediaElement();
81 :
82 : /**
83 : * This is used when the browser is constructing a video element to play
84 : * a channel that we've already started loading. The src attribute and
85 : * <source> children are ignored.
86 : * @param aChannel the channel to use
87 : * @param aListener returns a stream listener that should receive
88 : * notifications for the stream
89 : */
90 : nsresult LoadWithChannel(nsIChannel *aChannel, nsIStreamListener **aListener);
91 :
92 : // nsIDOMHTMLMediaElement
93 : NS_DECL_NSIDOMHTMLMEDIAELEMENT
94 :
95 : NS_DECL_NSIOBSERVER
96 :
97 : // nsISupports
98 : NS_DECL_ISUPPORTS_INHERITED
99 1464 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLMediaElement,
100 : nsGenericHTMLElement)
101 :
102 : virtual bool ParseAttribute(PRInt32 aNamespaceID,
103 : nsIAtom* aAttribute,
104 : const nsAString& aValue,
105 : nsAttrValue& aResult);
106 : // SetAttr override. C++ is stupid, so have to override both
107 : // overloaded methods.
108 0 : nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
109 : const nsAString& aValue, bool aNotify)
110 : {
111 0 : return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
112 : }
113 : virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
114 : nsIAtom* aPrefix, const nsAString& aValue,
115 : bool aNotify);
116 : virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttr,
117 : bool aNotify);
118 :
119 : virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
120 : nsIContent* aBindingParent,
121 : bool aCompileEventHandlers);
122 : virtual void UnbindFromTree(bool aDeep = true,
123 : bool aNullParent = true);
124 : virtual void DoneCreatingElement();
125 :
126 : /**
127 : * Call this to reevaluate whether we should start/stop due to our owner
128 : * document being active or inactive.
129 : */
130 : void NotifyOwnerDocumentActivityChanged();
131 :
132 : // Called by the video decoder object, on the main thread,
133 : // when it has read the metadata containing video dimensions,
134 : // etc.
135 : void MetadataLoaded(PRUint32 aChannels, PRUint32 aRate);
136 :
137 : // Called by the video decoder object, on the main thread,
138 : // when it has read the first frame of the video
139 : // aResourceFullyLoaded should be true if the resource has been
140 : // fully loaded and the caller will call ResourceLoaded next.
141 : void FirstFrameLoaded(bool aResourceFullyLoaded);
142 :
143 : // Called by the video decoder object, on the main thread,
144 : // when the resource has completed downloading.
145 : void ResourceLoaded();
146 :
147 : // Called by the video decoder object, on the main thread,
148 : // when the resource has a network error during loading.
149 : void NetworkError();
150 :
151 : // Called by the video decoder object, on the main thread, when the
152 : // resource has a decode error during metadata loading or decoding.
153 : void DecodeError();
154 :
155 : // Called by the video decoder object, on the main thread, when the
156 : // resource load has been cancelled.
157 : void LoadAborted();
158 :
159 : // Called by the video decoder object, on the main thread,
160 : // when the video playback has ended.
161 : void PlaybackEnded();
162 :
163 : // Called by the video decoder object, on the main thread,
164 : // when the resource has started seeking.
165 : void SeekStarted();
166 :
167 : // Called by the video decoder object, on the main thread,
168 : // when the resource has completed seeking.
169 : void SeekCompleted();
170 :
171 : // Called by the media stream, on the main thread, when the download
172 : // has been suspended by the cache or because the element itself
173 : // asked the decoder to suspend the download.
174 : void DownloadSuspended();
175 :
176 : // Called by the media stream, on the main thread, when the download
177 : // has been resumed by the cache or because the element itself
178 : // asked the decoder to resumed the download.
179 : void DownloadResumed();
180 :
181 : // Called by the media decoder to indicate that the download has stalled
182 : // (no data has arrived for a while).
183 : void DownloadStalled();
184 :
185 : // Called when a "MozAudioAvailable" event listener is added. The media
186 : // element will then notify its decoder that it needs to make a copy of
187 : // the audio data sent to hardware and dispatch it in "mozaudioavailable"
188 : // events. This allows us to not perform the copy and thus reduce overhead
189 : // in the common case where we don't have a "MozAudioAvailable" listener.
190 : void NotifyAudioAvailableListener();
191 :
192 : // Called by the media decoder and the video frame to get the
193 : // ImageContainer containing the video data.
194 : VideoFrameContainer* GetVideoFrameContainer();
195 0 : ImageContainer* GetImageContainer()
196 : {
197 0 : VideoFrameContainer* container = GetVideoFrameContainer();
198 0 : return container ? container->GetImageContainer() : nsnull;
199 : }
200 :
201 : // Called by the video frame to get the print surface, if this is
202 : // a static document and we're not actually playing video
203 : gfxASurface* GetPrintSurface() { return mPrintSurface; }
204 :
205 : // Dispatch events
206 : using nsGenericHTMLElement::DispatchEvent;
207 : nsresult DispatchEvent(const nsAString& aName);
208 : nsresult DispatchAsyncEvent(const nsAString& aName);
209 : nsresult DispatchAudioAvailableEvent(float* aFrameBuffer,
210 : PRUint32 aFrameBufferLength,
211 : float aTime);
212 :
213 : // Dispatch events that were raised while in the bfcache
214 : nsresult DispatchPendingMediaEvents();
215 :
216 : // Called by the decoder when some data has been downloaded or
217 : // buffering/seeking has ended. aNextFrameAvailable is true when
218 : // the data for the next frame is available. This method will
219 : // decide whether to set the ready state to HAVE_CURRENT_DATA,
220 : // HAVE_FUTURE_DATA or HAVE_ENOUGH_DATA.
221 : enum NextFrameStatus {
222 : // The next frame of audio/video is available
223 : NEXT_FRAME_AVAILABLE,
224 : // The next frame of audio/video is unavailable because the decoder
225 : // is paused while it buffers up data
226 : NEXT_FRAME_UNAVAILABLE_BUFFERING,
227 : // The next frame of audio/video is unavailable for some other reasons
228 : NEXT_FRAME_UNAVAILABLE
229 : };
230 : void UpdateReadyStateForData(NextFrameStatus aNextFrame);
231 :
232 : // Use this method to change the mReadyState member, so required
233 : // events can be fired.
234 : void ChangeReadyState(nsMediaReadyState aState);
235 :
236 : // Return true if we can activate autoplay assuming enough data has arrived.
237 : bool CanActivateAutoplay();
238 :
239 : // Notify that enough data has arrived to start autoplaying.
240 : // If the element is 'autoplay' and is ready to play back (not paused,
241 : // autoplay pref enabled, etc), it should start playing back.
242 : void NotifyAutoplayDataReady();
243 :
244 : // Check if the media element had crossorigin set when loading started
245 : bool ShouldCheckAllowOrigin();
246 :
247 : // Is the media element potentially playing as defined by the HTML 5 specification.
248 : // http://www.whatwg.org/specs/web-apps/current-work/#potentially-playing
249 : bool IsPotentiallyPlaying() const;
250 :
251 : // Has playback ended as defined by the HTML 5 specification.
252 : // http://www.whatwg.org/specs/web-apps/current-work/#ended
253 : bool IsPlaybackEnded() const;
254 :
255 : // principal of the currently playing stream
256 : already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
257 :
258 : // Update the visual size of the media. Called from the decoder on the
259 : // main thread when/if the size changes.
260 : void UpdateMediaSize(nsIntSize size);
261 :
262 : // Returns the CanPlayStatus indicating if we can handle this
263 : // MIME type. The MIME type should not include the codecs parameter.
264 : // If it returns anything other than CANPLAY_NO then it also
265 : // returns a null-terminated list of supported codecs
266 : // in *aSupportedCodecs. This list should not be freed, it is static data.
267 : static CanPlayStatus CanHandleMediaType(const char* aMIMEType,
268 : char const *const ** aSupportedCodecs);
269 :
270 : // Returns the CanPlayStatus indicating if we can handle the
271 : // full MIME type including the optional codecs parameter.
272 : static CanPlayStatus GetCanPlay(const nsAString& aType);
273 :
274 : // Returns true if we should handle this MIME type when it appears
275 : // as an <object> or as a toplevel page. If, in practice, our support
276 : // for the type is more limited than appears in the wild, we should return
277 : // false here even if CanHandleMediaType would return true.
278 : static bool ShouldHandleMediaType(const char* aMIMEType);
279 :
280 : #ifdef MOZ_OGG
281 : static bool IsOggEnabled();
282 : static bool IsOggType(const nsACString& aType);
283 : static const char gOggTypes[3][16];
284 : static char const *const gOggCodecs[3];
285 : #endif
286 :
287 : #ifdef MOZ_WAVE
288 : static bool IsWaveEnabled();
289 : static bool IsWaveType(const nsACString& aType);
290 : static const char gWaveTypes[4][16];
291 : static char const *const gWaveCodecs[2];
292 : #endif
293 :
294 : #ifdef MOZ_WEBM
295 : static bool IsWebMEnabled();
296 : static bool IsWebMType(const nsACString& aType);
297 : static const char gWebMTypes[2][17];
298 : static char const *const gWebMCodecs[4];
299 : #endif
300 :
301 : /**
302 : * Called when a child source element is added to this media element. This
303 : * may queue a task to run the select resource algorithm if appropriate.
304 : */
305 : void NotifyAddedSource();
306 :
307 : /**
308 : * Called when there's been an error fetching the resource. This decides
309 : * whether it's appropriate to fire an error event.
310 : */
311 : void NotifyLoadError();
312 :
313 : /**
314 : * Called when data has been written to the underlying audio stream.
315 : */
316 : void NotifyAudioAvailable(float* aFrameBuffer, PRUint32 aFrameBufferLength,
317 : float aTime);
318 :
319 : virtual bool IsNodeOfType(PRUint32 aFlags) const;
320 :
321 : /**
322 : * Returns the current load ID. Asynchronous events store the ID that was
323 : * current when they were enqueued, and if it has changed when they come to
324 : * fire, they consider themselves cancelled, and don't fire.
325 : */
326 0 : PRUint32 GetCurrentLoadID() { return mCurrentLoadID; }
327 :
328 : /**
329 : * Returns the load group for this media element's owner document.
330 : * XXX XBL2 issue.
331 : */
332 : already_AddRefed<nsILoadGroup> GetDocumentLoadGroup();
333 :
334 : /**
335 : * Returns true if the media has played or completed a seek.
336 : * Used by video frame to determine whether to paint the poster.
337 : */
338 0 : bool GetPlayedOrSeeked() const { return mHasPlayedOrSeeked; }
339 :
340 : nsresult CopyInnerTo(nsGenericElement* aDest) const;
341 :
342 : /**
343 : * Sets the Accept header on the HTTP channel to the required
344 : * video or audio MIME types.
345 : */
346 : virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) = 0;
347 :
348 : /**
349 : * Sets the required request headers on the HTTP channel for
350 : * video or audio requests.
351 : */
352 : void SetRequestHeaders(nsIHttpChannel* aChannel);
353 :
354 : /**
355 : * Fires a timeupdate event. If aPeriodic is true, the event will only
356 : * be fired if we've not fired a timeupdate event (for any reason) in the
357 : * last 250ms, as required by the spec when the current time is periodically
358 : * increasing during playback.
359 : */
360 : void FireTimeUpdate(bool aPeriodic);
361 :
362 : protected:
363 : class MediaLoadListener;
364 :
365 : /**
366 : * Logs a warning message to the web console to report various failures.
367 : * aMsg is the localized message identifier, aParams is the parameters to
368 : * be substituted into the localized message, and aParamCount is the number
369 : * of parameters in aParams.
370 : */
371 : void ReportLoadError(const char* aMsg,
372 : const PRUnichar** aParams = nsnull,
373 : PRUint32 aParamCount = 0);
374 :
375 : /**
376 : * Changes mHasPlayedOrSeeked to aValue. If mHasPlayedOrSeeked changes
377 : * we'll force a reflow so that the video frame gets reflowed to reflect
378 : * the poster hiding or showing immediately.
379 : */
380 : void SetPlayedOrSeeked(bool aValue);
381 :
382 : /**
383 : * Create a decoder for the given aMIMEType. Returns null if we
384 : * were unable to create the decoder.
385 : */
386 : already_AddRefed<nsMediaDecoder> CreateDecoder(const nsACString& aMIMEType);
387 :
388 : /**
389 : * Initialize a decoder as a clone of an existing decoder in another
390 : * element.
391 : * mLoadingSrc must already be set.
392 : */
393 : nsresult InitializeDecoderAsClone(nsMediaDecoder* aOriginal);
394 :
395 : /**
396 : * Initialize a decoder to load the given channel. The decoder's stream
397 : * listener is returned via aListener.
398 : * mLoadingSrc must already be set.
399 : */
400 : nsresult InitializeDecoderForChannel(nsIChannel *aChannel,
401 : nsIStreamListener **aListener);
402 :
403 : /**
404 : * Finish setting up the decoder after Load() has been called on it.
405 : * Called by InitializeDecoderForChannel/InitializeDecoderAsClone.
406 : */
407 : nsresult FinishDecoderSetup(nsMediaDecoder* aDecoder);
408 :
409 : /**
410 : * Call this after setting up mLoadingSrc and mDecoder.
411 : */
412 : void AddMediaElementToURITable();
413 : /**
414 : * Call this before clearing mLoadingSrc.
415 : */
416 : void RemoveMediaElementFromURITable();
417 : /**
418 : * Call this to find a media element with the same NodePrincipal and mLoadingSrc
419 : * set to aURI, and with a decoder on which Load() has been called.
420 : */
421 : nsHTMLMediaElement* LookupMediaElementURITable(nsIURI* aURI);
422 :
423 : /**
424 : * Execute the initial steps of the load algorithm that ensure existing
425 : * loads are aborted, the element is emptied, and a new load ID is
426 : * created.
427 : */
428 : void AbortExistingLoads();
429 :
430 : /**
431 : * Create a URI for the given aURISpec string.
432 : */
433 : nsresult NewURIFromString(const nsAutoString& aURISpec, nsIURI** aURI);
434 :
435 : /**
436 : * Called when all potential resources are exhausted. Changes network
437 : * state to NETWORK_NO_SOURCE, and sends error event with code
438 : * MEDIA_ERR_SRC_NOT_SUPPORTED.
439 : */
440 : void NoSupportedMediaSourceError();
441 :
442 : /**
443 : * Attempts to load resources from the <source> children. This is a
444 : * substep of the resource selection algorithm. Do not call this directly,
445 : * call QueueLoadFromSourceTask() instead.
446 : */
447 : void LoadFromSourceChildren();
448 :
449 : /**
450 : * Asynchronously awaits a stable state, and then causes
451 : * LoadFromSourceChildren() to be called on the main threads' event loop.
452 : */
453 : void QueueLoadFromSourceTask();
454 :
455 : /**
456 : * Runs the media resource selection algorithm.
457 : */
458 : void SelectResource();
459 :
460 : /**
461 : * A wrapper function that allows us to cleanly reset flags after a call
462 : * to SelectResource()
463 : */
464 : void SelectResourceWrapper();
465 :
466 : /**
467 : * Asynchronously awaits a stable state, and then causes SelectResource()
468 : * to be run on the main thread's event loop.
469 : */
470 : void QueueSelectResourceTask();
471 :
472 : /**
473 : * The resource-fetch algorithm step of the load algorithm.
474 : */
475 : nsresult LoadResource();
476 :
477 : /**
478 : * Selects the next <source> child from which to load a resource. Called
479 : * during the resource selection algorithm. Stores the return value in
480 : * mSourceLoadCandidate before returning.
481 : */
482 : nsIContent* GetNextSource();
483 :
484 : /**
485 : * Changes mDelayingLoadEvent, and will call BlockOnLoad()/UnblockOnLoad()
486 : * on the owning document, so it can delay the load event firing.
487 : */
488 : void ChangeDelayLoadStatus(bool aDelay);
489 :
490 : /**
491 : * If we suspended downloading after the first frame, unsuspend now.
492 : */
493 : void StopSuspendingAfterFirstFrame();
494 :
495 : /**
496 : * Called when our channel is redirected to another channel.
497 : * Updates our mChannel reference to aNewChannel.
498 : */
499 : nsresult OnChannelRedirect(nsIChannel *aChannel,
500 : nsIChannel *aNewChannel,
501 : PRUint32 aFlags);
502 :
503 : /**
504 : * Call this to reevaluate whether we should be holding a self-reference.
505 : */
506 : void AddRemoveSelfReference();
507 :
508 : /**
509 : * Called asynchronously to release a self-reference to this element.
510 : */
511 : void DoRemoveSelfReference();
512 :
513 : /**
514 : * Possible values of the 'preload' attribute.
515 : */
516 : enum PreloadAttrValue {
517 : PRELOAD_ATTR_EMPTY, // set to ""
518 : PRELOAD_ATTR_NONE, // set to "none"
519 : PRELOAD_ATTR_METADATA, // set to "metadata"
520 : PRELOAD_ATTR_AUTO // set to "auto"
521 : };
522 :
523 : /**
524 : * The preloading action to perform. These dictate how we react to the
525 : * preload attribute. See mPreloadAction.
526 : */
527 : enum PreloadAction {
528 : PRELOAD_UNDEFINED = 0, // not determined - used only for initialization
529 : PRELOAD_NONE = 1, // do not preload
530 : PRELOAD_METADATA = 2, // preload only the metadata (and first frame)
531 : PRELOAD_ENOUGH = 3 // preload enough data to allow uninterrupted
532 : // playback
533 : };
534 :
535 : /**
536 : * Suspends the load of mLoadingSrc, so that it can be resumed later
537 : * by ResumeLoad(). This is called when we have a media with a 'preload'
538 : * attribute value of 'none', during the resource selection algorithm.
539 : */
540 : void SuspendLoad();
541 :
542 : /**
543 : * Resumes a previously suspended load (suspended by SuspendLoad(uri)).
544 : * Will continue running the resource selection algorithm.
545 : * Sets mPreloadAction to aAction.
546 : */
547 : void ResumeLoad(PreloadAction aAction);
548 :
549 : /**
550 : * Handle a change to the preload attribute. Should be called whenever the
551 : * value (or presence) of the preload attribute changes. The change in
552 : * attribute value may cause a change in the mPreloadAction of this
553 : * element. If there is a change then this method will initiate any
554 : * behaviour that is necessary to implement the action.
555 : */
556 : void UpdatePreloadAction();
557 :
558 : /**
559 : * Dispatches an error event to a child source element.
560 : */
561 : void DispatchAsyncSourceError(nsIContent* aSourceElement);
562 :
563 : /**
564 : * Resets the media element for an error condition as per aErrorCode.
565 : * aErrorCode must be one of nsIDOMHTMLMediaError codes.
566 : */
567 : void Error(PRUint16 aErrorCode);
568 :
569 : /**
570 : * Returns the URL spec of the currentSrc.
571 : **/
572 : void GetCurrentSpec(nsCString& aString);
573 :
574 : /**
575 : * Process any media fragment entries in the URI
576 : */
577 : void ProcessMediaFragmentURI();
578 :
579 : // The current decoder. Load() has been called on this decoder.
580 : nsRefPtr<nsMediaDecoder> mDecoder;
581 :
582 : // A reference to the VideoFrameContainer which contains the current frame
583 : // of video to display.
584 : nsRefPtr<VideoFrameContainer> mVideoFrameContainer;
585 :
586 : // Holds a reference to the first channel we open to the media resource.
587 : // Once the decoder is created, control over the channel passes to the
588 : // decoder, and we null out this reference. We must store this in case
589 : // we need to cancel the channel before control of it passes to the decoder.
590 : nsCOMPtr<nsIChannel> mChannel;
591 :
592 : // Error attribute
593 : nsCOMPtr<nsIDOMMediaError> mError;
594 :
595 : // The current media load ID. This is incremented every time we start a
596 : // new load. Async events note the ID when they're first sent, and only fire
597 : // if the ID is unchanged when they come to fire.
598 : PRUint32 mCurrentLoadID;
599 :
600 : // Points to the child source elements, used to iterate through the children
601 : // when selecting a resource to load.
602 : nsCOMPtr<nsIDOMRange> mSourcePointer;
603 :
604 : // Points to the document whose load we're blocking. This is the document
605 : // we're bound to when loading starts.
606 : nsCOMPtr<nsIDocument> mLoadBlockedDoc;
607 :
608 : // Contains names of events that have been raised while in the bfcache.
609 : // These events get re-dispatched when the bfcache is exited.
610 : nsTArray<nsString> mPendingEvents;
611 :
612 : // Media loading flags. See:
613 : // http://www.whatwg.org/specs/web-apps/current-work/#video)
614 : nsMediaNetworkState mNetworkState;
615 : nsMediaReadyState mReadyState;
616 :
617 : enum LoadAlgorithmState {
618 : // No load algorithm instance is waiting for a source to be added to the
619 : // media in order to continue loading.
620 : NOT_WAITING,
621 : // We've run the load algorithm, and we tried all source children of the
622 : // media element, and failed to load any successfully. We're waiting for
623 : // another source element to be added to the media element, and will try
624 : // to load any such element when its added.
625 : WAITING_FOR_SOURCE
626 : };
627 :
628 : // Denotes the waiting state of a load algorithm instance. When the load
629 : // algorithm is waiting for a source element child to be added, this is set
630 : // to WAITING_FOR_SOURCE, otherwise it's NOT_WAITING.
631 : LoadAlgorithmState mLoadWaitStatus;
632 :
633 : // Current audio volume
634 : double mVolume;
635 :
636 : // Current number of audio channels.
637 : PRUint32 mChannels;
638 :
639 : // Current audio sample rate.
640 : PRUint32 mRate;
641 :
642 : // URI of the resource we're attempting to load. This stores the value we
643 : // return in the currentSrc attribute. Use GetCurrentSrc() to access the
644 : // currentSrc attribute.
645 : // This is always the original URL we're trying to load --- before
646 : // redirects etc.
647 : nsCOMPtr<nsIURI> mLoadingSrc;
648 :
649 : // Stores the current preload action for this element. Initially set to
650 : // PRELOAD_UNDEFINED, its value is changed by calling
651 : // UpdatePreloadAction().
652 : PreloadAction mPreloadAction;
653 :
654 : // Size of the media. Updated by the decoder on the main thread if
655 : // it changes. Defaults to a width and height of -1 if not set.
656 : // We keep this separate from the intrinsic size stored in the
657 : // VideoFrameContainer so that it doesn't change unexpectedly under us
658 : // due to decoder activity.
659 : nsIntSize mMediaSize;
660 :
661 : // Time that the last timeupdate event was fired. Read/Write from the
662 : // main thread only.
663 : TimeStamp mTimeUpdateTime;
664 :
665 : // Media 'currentTime' value when the last timeupdate event occurred.
666 : // Read/Write from the main thread only.
667 : double mLastCurrentTime;
668 :
669 : // Logical start time of the media resource in seconds as obtained
670 : // from any media fragments. A negative value indicates that no
671 : // fragment time has been set. Read/Write from the main thread only.
672 : double mFragmentStart;
673 :
674 : // Logical end time of the media resource in seconds as obtained
675 : // from any media fragments. A negative value indicates that no
676 : // fragment time has been set. Read/Write from the main thread only.
677 : double mFragmentEnd;
678 :
679 : nsRefPtr<gfxASurface> mPrintSurface;
680 :
681 : // Reference to the source element last returned by GetNextSource().
682 : // This is the child source element which we're trying to load from.
683 : nsCOMPtr<nsIContent> mSourceLoadCandidate;
684 :
685 : // An audio stream for writing audio directly from JS.
686 : nsRefPtr<nsAudioStream> mAudioStream;
687 :
688 : // True if MozAudioAvailable events can be safely dispatched, based on
689 : // a media and element same-origin check.
690 : bool mAllowAudioData;
691 :
692 : // If true then we have begun downloading the media content.
693 : // Set to false when completed, or not yet started.
694 : bool mBegun;
695 :
696 : // True when the decoder has loaded enough data to display the
697 : // first frame of the content.
698 : bool mLoadedFirstFrame;
699 :
700 : // Indicates whether current playback is a result of user action
701 : // (ie. calling of the Play method), or automatic playback due to
702 : // the 'autoplay' attribute being set. A true value indicates the
703 : // latter case.
704 : // The 'autoplay' HTML attribute indicates that the video should
705 : // start playing when loaded. The 'autoplay' attribute of the object
706 : // is a mirror of the HTML attribute. These are different from this
707 : // 'mAutoplaying' flag, which indicates whether the current playback
708 : // is a result of the autoplay attribute.
709 : bool mAutoplaying;
710 :
711 : // Indicates whether |autoplay| will actually autoplay based on the pref
712 : // media.autoplay.enabled
713 : bool mAutoplayEnabled;
714 :
715 : // Playback of the video is paused either due to calling the
716 : // 'Pause' method, or playback not yet having started.
717 : bool mPaused;
718 :
719 : // True if the sound is muted
720 : bool mMuted;
721 :
722 : // If TRUE then the media element was actively playing before the currently
723 : // in progress seeking. If FALSE then the media element is either not seeking
724 : // or was not actively playing before the current seek. Used to decide whether
725 : // to raise the 'waiting' event as per 4.7.1.8 in HTML 5 specification.
726 : bool mPlayingBeforeSeek;
727 :
728 : // True iff this element is paused because the document is inactive
729 : bool mPausedForInactiveDocument;
730 :
731 : // True if we've reported a "waiting" event since the last
732 : // readyState change to HAVE_CURRENT_DATA.
733 : bool mWaitingFired;
734 :
735 : // True if we're running the "load()" method.
736 : bool mIsRunningLoadMethod;
737 :
738 : // True if we're loading the resource from the child source elements.
739 : bool mIsLoadingFromSourceChildren;
740 :
741 : // True if we're delaying the "load" event. They are delayed until either
742 : // an error occurs, or the first frame is loaded.
743 : bool mDelayingLoadEvent;
744 :
745 : // True when we've got a task queued to call SelectResource(),
746 : // or while we're running SelectResource().
747 : bool mIsRunningSelectResource;
748 :
749 : // True when we already have select resource call queued
750 : bool mHaveQueuedSelectResource;
751 :
752 : // True if we suspended the decoder because we were paused,
753 : // preloading metadata is enabled, autoplay was not enabled, and we loaded
754 : // the first frame.
755 : bool mSuspendedAfterFirstFrame;
756 :
757 : // True if we are allowed to suspend the decoder because we were paused,
758 : // preloading metdata was enabled, autoplay was not enabled, and we loaded
759 : // the first frame.
760 : bool mAllowSuspendAfterFirstFrame;
761 :
762 : // True if we've played or completed a seek. We use this to determine
763 : // when the poster frame should be shown.
764 : bool mHasPlayedOrSeeked;
765 :
766 : // True if we've added a reference to ourselves to keep the element
767 : // alive while no-one is referencing it but the element may still fire
768 : // events of its own accord.
769 : bool mHasSelfReference;
770 :
771 : // True if we've received a notification that the engine is shutting
772 : // down.
773 : bool mShuttingDown;
774 :
775 : // True if we've suspended a load in the resource selection algorithm
776 : // due to loading a preload:none media. When true, the resource we'll
777 : // load when the user initiates either playback or an explicit load is
778 : // stored in mPreloadURI.
779 : bool mLoadIsSuspended;
780 :
781 : // True if a same-origin check has been done for the media element and resource.
782 : bool mMediaSecurityVerified;
783 :
784 : // The CORS mode when loading the media element
785 : mozilla::CORSMode mCORSMode;
786 : };
787 :
788 : #endif
|