Skip to content

Commit

Permalink
Bug 810177 - Part 4: Make nsMediaDecoder not depend on nsHTMLMediaEle…
Browse files Browse the repository at this point in the history
…ment; r=cpearce

The basic idea in this patch is to create an MediaDecoderOwner
interface which nsHTMLMediaElement would implement, and put everything
needed by nsMediaDeocder on that interface.  In addition to that,
there are a number of other cleanup patches which enables us to
eliminate many of the nsHTMLMediaElement.h #includes in the media code.
  • Loading branch information
ehsan committed Nov 9, 2012
1 parent 9ee252e commit f659ffc
Show file tree
Hide file tree
Showing 10 changed files with 287 additions and 101 deletions.
1 change: 1 addition & 0 deletions content/html/content/public/nsHTMLAudioElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class nsHTMLAudioElement : public nsHTMLMediaElement,
NS_FORWARD_NSIDOMHTMLELEMENT(nsHTMLMediaElement::)

// nsIDOMHTMLMediaElement
using nsHTMLMediaElement::GetPaused;
NS_FORWARD_NSIDOMHTMLMEDIAELEMENT(nsHTMLMediaElement::)

// nsIDOMHTMLAudioElement
Expand Down
70 changes: 43 additions & 27 deletions content/html/content/public/nsHTMLMediaElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#include "nsIDOMHTMLMediaElement.h"
#include "nsGenericHTMLElement.h"
#include "nsMediaDecoder.h"
#include "MediaDecoderOwner.h"
#include "nsIChannel.h"
#include "nsIHttpChannel.h"
#include "nsThreadUtils.h"
Expand Down Expand Up @@ -37,7 +37,8 @@ class nsDASHDecoder;
#endif

class nsHTMLMediaElement : public nsGenericHTMLElement,
public nsIObserver
public nsIObserver,
public mozilla::MediaDecoderOwner
{
public:
typedef mozilla::TimeStamp TimeStamp;
Expand Down Expand Up @@ -116,49 +117,49 @@ class nsHTMLMediaElement : public nsGenericHTMLElement,
// Called by the video decoder object, on the main thread,
// when it has read the metadata containing video dimensions,
// etc.
void MetadataLoaded(uint32_t aChannels,
uint32_t aRate,
bool aHasAudio,
const MetadataTags* aTags);
virtual void MetadataLoaded(uint32_t aChannels,
uint32_t aRate,
bool aHasAudio,
const MetadataTags* aTags) MOZ_FINAL MOZ_OVERRIDE;

// Called by the video decoder object, on the main thread,
// when it has read the first frame of the video
// aResourceFullyLoaded should be true if the resource has been
// fully loaded and the caller will call ResourceLoaded next.
void FirstFrameLoaded(bool aResourceFullyLoaded);
virtual void FirstFrameLoaded(bool aResourceFullyLoaded) MOZ_FINAL MOZ_OVERRIDE;

// Called by the video decoder object, on the main thread,
// when the resource has completed downloading.
void ResourceLoaded();
virtual void ResourceLoaded() MOZ_FINAL MOZ_OVERRIDE;

// Called by the video decoder object, on the main thread,
// when the resource has a network error during loading.
void NetworkError();
virtual void NetworkError() MOZ_FINAL MOZ_OVERRIDE;

// Called by the video decoder object, on the main thread, when the
// resource has a decode error during metadata loading or decoding.
void DecodeError();
virtual void DecodeError() MOZ_FINAL MOZ_OVERRIDE;

// Called by the video decoder object, on the main thread, when the
// resource load has been cancelled.
void LoadAborted();
virtual void LoadAborted() MOZ_FINAL MOZ_OVERRIDE;

// Called by the video decoder object, on the main thread,
// when the video playback has ended.
void PlaybackEnded();
virtual void PlaybackEnded() MOZ_FINAL MOZ_OVERRIDE;

// Called by the video decoder object, on the main thread,
// when the resource has started seeking.
void SeekStarted();
virtual void SeekStarted() MOZ_FINAL MOZ_OVERRIDE;

// Called by the video decoder object, on the main thread,
// when the resource has completed seeking.
void SeekCompleted();
virtual void SeekCompleted() MOZ_FINAL MOZ_OVERRIDE;

// Called by the media stream, on the main thread, when the download
// has been suspended by the cache or because the element itself
// asked the decoder to suspend the download.
void DownloadSuspended();
virtual void DownloadSuspended() MOZ_FINAL MOZ_OVERRIDE;

// Called by the media stream, on the main thread, when the download
// has been resumed by the cache or because the element itself
Expand All @@ -167,15 +168,15 @@ class nsHTMLMediaElement : public nsGenericHTMLElement,
// previously finished. We are downloading the middle of the media after
// having downloaded the end, we need to notify the element a download in
// ongoing.
void DownloadResumed(bool aForceNetworkLoading = false);
virtual void DownloadResumed(bool aForceNetworkLoading = false) MOZ_FINAL MOZ_OVERRIDE;

// Called by the media decoder to indicate that the download has stalled
// (no data has arrived for a while).
void DownloadStalled();
virtual void DownloadStalled() MOZ_FINAL MOZ_OVERRIDE;

// Called by the media decoder to indicate whether the media cache has
// suspended the channel.
void NotifySuspendedByCache(bool aIsSuspended);
virtual void NotifySuspendedByCache(bool aIsSuspended) MOZ_FINAL MOZ_OVERRIDE;

// Called when a "MozAudioAvailable" event listener is added. The media
// element will then notify its decoder that it needs to make a copy of
Expand All @@ -186,7 +187,7 @@ class nsHTMLMediaElement : public nsGenericHTMLElement,

// Called by the media decoder and the video frame to get the
// ImageContainer containing the video data.
VideoFrameContainer* GetVideoFrameContainer();
virtual VideoFrameContainer* GetVideoFrameContainer() MOZ_FINAL MOZ_OVERRIDE;
ImageContainer* GetImageContainer()
{
VideoFrameContainer* container = GetVideoFrameContainer();
Expand All @@ -199,8 +200,8 @@ class nsHTMLMediaElement : public nsGenericHTMLElement,

// Dispatch events
using nsGenericHTMLElement::DispatchEvent;
nsresult DispatchEvent(const nsAString& aName);
nsresult DispatchAsyncEvent(const nsAString& aName);
virtual nsresult DispatchEvent(const nsAString& aName) MOZ_FINAL MOZ_OVERRIDE;
virtual nsresult DispatchAsyncEvent(const nsAString& aName) MOZ_FINAL MOZ_OVERRIDE;
nsresult DispatchAudioAvailableEvent(float* aFrameBuffer,
uint32_t aFrameBufferLength,
float aTime);
Expand All @@ -213,7 +214,7 @@ class nsHTMLMediaElement : public nsGenericHTMLElement,
// the data for the next frame is available. This method will
// decide whether to set the ready state to HAVE_CURRENT_DATA,
// HAVE_FUTURE_DATA or HAVE_ENOUGH_DATA.
void UpdateReadyStateForData(nsMediaDecoder::NextFrameStatus aNextFrame);
virtual void UpdateReadyStateForData(nsMediaDecoder::NextFrameStatus aNextFrame) MOZ_FINAL MOZ_OVERRIDE;

// Use this method to change the mReadyState member, so required
// events can be fired.
Expand All @@ -225,7 +226,7 @@ class nsHTMLMediaElement : public nsGenericHTMLElement,
// Notify that enough data has arrived to start autoplaying.
// If the element is 'autoplay' and is ready to play back (not paused,
// autoplay pref enabled, etc), it should start playing back.
void NotifyAutoplayDataReady();
virtual void NotifyAutoplayDataReady() MOZ_FINAL MOZ_OVERRIDE;

// Check if the media element had crossorigin set when loading started
bool ShouldCheckAllowOrigin();
Expand All @@ -244,7 +245,7 @@ class nsHTMLMediaElement : public nsGenericHTMLElement,
already_AddRefed<nsIPrincipal> GetCurrentPrincipal();

// called to notify that the principal of the decoder's media resource has changed.
void NotifyDecoderPrincipalChanged();
virtual void NotifyDecoderPrincipalChanged() MOZ_FINAL MOZ_OVERRIDE;

// Update the visual size of the media. Called from the decoder on the
// main thread when/if the size changes.
Expand Down Expand Up @@ -331,8 +332,8 @@ class nsHTMLMediaElement : public nsGenericHTMLElement,
/**
* Called when data has been written to the underlying audio stream.
*/
void NotifyAudioAvailable(float* aFrameBuffer, uint32_t aFrameBufferLength,
float aTime);
virtual void NotifyAudioAvailable(float* aFrameBuffer, uint32_t aFrameBufferLength,
float aTime) MOZ_FINAL MOZ_OVERRIDE;

virtual bool IsNodeOfType(uint32_t aFlags) const;

Expand Down Expand Up @@ -375,7 +376,7 @@ class nsHTMLMediaElement : public nsGenericHTMLElement,
* last 250ms, as required by the spec when the current time is periodically
* increasing during playback.
*/
void FireTimeUpdate(bool aPeriodic);
virtual void FireTimeUpdate(bool aPeriodic) MOZ_FINAL MOZ_OVERRIDE;

MediaStream* GetSrcMediaStream()
{
Expand Down Expand Up @@ -626,6 +627,21 @@ class nsHTMLMediaElement : public nsGenericHTMLElement,
*/
void ProcessMediaFragmentURI();

// Get the nsHTMLMediaElement object if the decoder is being used from an
// HTML media element, and null otherwise.
virtual nsHTMLMediaElement* GetMediaElement() MOZ_FINAL MOZ_OVERRIDE
{
return this;
}

// Return true if decoding should be paused
virtual bool GetPaused() MOZ_FINAL MOZ_OVERRIDE
{
bool isPaused = false;
GetPaused(&isPaused);
return isPaused;
}

// The current decoder. Load() has been called on this decoder.
// At most one of mDecoder and mSrcStream can be non-null.
nsRefPtr<nsMediaDecoder> mDecoder;
Expand Down
1 change: 1 addition & 0 deletions content/html/content/public/nsHTMLVideoElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class nsHTMLVideoElement : public nsHTMLMediaElement,
NS_FORWARD_NSIDOMHTMLELEMENT(nsHTMLMediaElement::)

// nsIDOMHTMLMediaElement
using nsHTMLMediaElement::GetPaused;
NS_FORWARD_NSIDOMHTMLMEDIAELEMENT(nsHTMLMediaElement::)

// nsIDOMHTMLVideoElement
Expand Down
1 change: 1 addition & 0 deletions content/media/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ EXPORTS = \
AudioSampleFormat.h \
AudioSegment.h \
FileBlockCache.h \
MediaDecoderOwner.h \
MediaResource.h \
MediaSegment.h \
MediaStreamGraph.h \
Expand Down
133 changes: 133 additions & 0 deletions content/media/MediaDecoderOwner.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MediaDecoderOwner_h_
#define MediaDecoderOwner_h_

#include "nsMediaDecoder.h"

namespace mozilla {

class MediaDecoderOwner
{
public:
// Called by the media decoder to indicate that the download has stalled
// (no data has arrived for a while).
virtual void DownloadStalled() = 0;

// Dispatch a synchronous event to the decoder owner
virtual nsresult DispatchEvent(const nsAString& aName) = 0;

// Dispatch an asynchronous event to the decoder owner
virtual nsresult DispatchAsyncEvent(const nsAString& aName) = 0;

/**
* Fires a timeupdate event. If aPeriodic is true, the event will only
* be fired if we've not fired a timeupdate event (for any reason) in the
* last 250ms, as required by the spec when the current time is periodically
* increasing during playback.
*/
virtual void FireTimeUpdate(bool aPeriodic) = 0;

// Get the nsHTMLMediaElement object if the decoder is being used from an
// HTML media element, and null otherwise.
virtual nsHTMLMediaElement* GetMediaElement()
{
return nullptr;
}

// Return true if decoding should be paused
virtual bool GetPaused() = 0;

/**
* Called when data has been written to the underlying audio stream.
*/
virtual void NotifyAudioAvailable(float* aFrameBuffer, uint32_t aFrameBufferLength,
float aTime) = 0;

// Called by the video decoder object, on the main thread,
// when it has read the metadata containing video dimensions,
// etc.
virtual void MetadataLoaded(uint32_t aChannels,
uint32_t aRate,
bool aHasAudio,
const MetadataTags* aTags) = 0;

// Called by the video decoder object, on the main thread,
// when it has read the first frame of the video
// aResourceFullyLoaded should be true if the resource has been
// fully loaded and the caller will call ResourceLoaded next.
virtual void FirstFrameLoaded(bool aResourceFullyLoaded) = 0;

// Called by the video decoder object, on the main thread,
// when the resource has completed downloading.
virtual void ResourceLoaded() = 0;

// Called by the video decoder object, on the main thread,
// when the resource has a network error during loading.
virtual void NetworkError() = 0;

// Called by the video decoder object, on the main thread, when the
// resource has a decode error during metadata loading or decoding.
virtual void DecodeError() = 0;

// Called by the video decoder object, on the main thread, when the
// resource load has been cancelled.
virtual void LoadAborted() = 0;

// Called by the video decoder object, on the main thread,
// when the video playback has ended.
virtual void PlaybackEnded() = 0;

// Called by the video decoder object, on the main thread,
// when the resource has started seeking.
virtual void SeekStarted() = 0;

// Called by the video decoder object, on the main thread,
// when the resource has completed seeking.
virtual void SeekCompleted() = 0;

// Called by the media stream, on the main thread, when the download
// has been suspended by the cache or because the element itself
// asked the decoder to suspend the download.
virtual void DownloadSuspended() = 0;

// Called by the media stream, on the main thread, when the download
// has been resumed by the cache or because the element itself
// asked the decoder to resumed the download.
// If aForceNetworkLoading is True, ignore the fact that the download has
// previously finished. We are downloading the middle of the media after
// having downloaded the end, we need to notify the element a download in
// ongoing.
virtual void DownloadResumed(bool aForceNetworkLoading = false) = 0;

// Notify that enough data has arrived to start autoplaying.
// If the element is 'autoplay' and is ready to play back (not paused,
// autoplay pref enabled, etc), it should start playing back.
virtual void NotifyAutoplayDataReady() = 0;

// Called by the media decoder to indicate whether the media cache has
// suspended the channel.
virtual void NotifySuspendedByCache(bool aIsSuspended) = 0;

// called to notify that the principal of the decoder's media resource has changed.
virtual void NotifyDecoderPrincipalChanged() = 0;

// Called by the decoder when some data has been downloaded or
// buffering/seeking has ended. aNextFrameAvailable is true when
// the data for the next frame is available. This method will
// decide whether to set the ready state to HAVE_CURRENT_DATA,
// HAVE_FUTURE_DATA or HAVE_ENOUGH_DATA.
virtual void UpdateReadyStateForData(nsMediaDecoder::NextFrameStatus aNextFrame) = 0;

// Called by the media decoder and the video frame to get the
// ImageContainer containing the video data.
virtual mozilla::VideoFrameContainer* GetVideoFrameContainer() = 0;
};

}

#endif

Loading

0 comments on commit f659ffc

Please sign in to comment.