Bug 927245 - Remove deprecated Audio Data API implementation. r=cajbir,smaug

This commit is contained in:
Matthew Gregan 2014-04-03 10:53:39 +13:00
parent 9016ae3f0e
commit 5979b051e5
54 changed files with 9 additions and 2171 deletions

View File

@ -28,7 +28,6 @@ DEPRECATED_OPERATION(MutationEvent)
DEPRECATED_OPERATION(Components)
DEPRECATED_OPERATION(PrefixedVisibilityAPI)
DEPRECATED_OPERATION(NodeIteratorDetach)
DEPRECATED_OPERATION(MozAudioData)
DEPRECATED_OPERATION(LenientThis)
DEPRECATED_OPERATION(GetPreventDefault)
DEPRECATED_OPERATION(GetSetUserData)

View File

@ -1891,14 +1891,6 @@ public:
virtual Element* FindImageMap(const nsAString& aNormalizedMapName) = 0;
// Called to notify the document that a listener on the "mozaudioavailable"
// event has been added. Media elements in the document need to ensure they
// fire the event.
virtual void NotifyAudioAvailableListener() = 0;
// Returns true if the document has "mozaudioavailable" event listeners.
virtual bool HasAudioAvailableListeners() = 0;
// Add aLink to the set of links that need their status resolved.
void RegisterPendingLinkUpdate(mozilla::dom::Link* aLink);

View File

@ -9866,23 +9866,6 @@ nsDocument::AddImage(imgIRequest* aImage)
return rv;
}
static void
NotifyAudioAvailableListener(nsIContent *aContent, void *aUnused)
{
nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aContent));
if (domMediaElem) {
HTMLMediaElement* mediaElem = static_cast<HTMLMediaElement*>(aContent);
mediaElem->NotifyAudioAvailableListener();
}
}
void
nsDocument::NotifyAudioAvailableListener()
{
mHasAudioAvailableListener = true;
EnumerateFreezableElements(::NotifyAudioAvailableListener, nullptr);
}
nsresult
nsDocument::RemoveImage(imgIRequest* aImage, uint32_t aFlags)
{

View File

@ -1107,13 +1107,6 @@ public:
virtual Element* FindImageMap(const nsAString& aNormalizedMapName) MOZ_OVERRIDE;
virtual void NotifyAudioAvailableListener() MOZ_OVERRIDE;
bool HasAudioAvailableListeners() MOZ_OVERRIDE
{
return mHasAudioAvailableListener;
}
virtual Element* GetFullScreenElement() MOZ_OVERRIDE;
virtual void AsyncRequestFullScreen(Element* aElement) MOZ_OVERRIDE;
virtual void RestorePreviousFullScreenState() MOZ_OVERRIDE;
@ -1471,10 +1464,6 @@ public:
// Whether we currently require our images to animate
bool mAnimatingImages:1;
// Whether some node in this document has a listener for the
// "mozaudioavailable" event.
bool mHasAudioAvailableListener:1;
// Whether we're currently under a FlushPendingNotifications call to
// our presshell. This is used to handle flush reentry correctly.
bool mInFlush:1;

View File

@ -1919,7 +1919,6 @@ GK_ATOM(onended, "onended")
GK_ATOM(onratechange, "onratechange")
GK_ATOM(ondurationchange, "ondurationchange")
GK_ATOM(onvolumechange, "onvolumechange")
GK_ATOM(onMozAudioAvailable, "onMozAudioAvailable")
GK_ATOM(onaddtrack, "onaddtrack")
GK_ATOM(oncuechange, "oncuechange")
GK_ATOM(onenter, "onenter")

View File

@ -495,9 +495,6 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
if (elm->MayHavePaintEventListener()) {
window->SetHasPaintEventListeners();
}
if (elm->MayHaveAudioAvailableEventListener()) {
window->SetHasAudioAvailableEventListeners();
}
if (elm->MayHaveTouchEventListener()) {
window->SetHasTouchEventListeners();
}

View File

@ -11,8 +11,6 @@
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/TypedArray.h"
class nsITimer;
typedef uint16_t nsMediaNetworkState;
typedef uint16_t nsMediaReadyState;
@ -20,7 +18,6 @@ namespace mozilla {
namespace dom {
class HTMLAudioElement MOZ_FINAL : public HTMLMediaElement,
public nsITimerCallback,
public nsIDOMHTMLAudioElement
{
public:
@ -34,12 +31,6 @@ public:
using HTMLMediaElement::GetPaused;
NS_FORWARD_NSIDOMHTMLMEDIAELEMENT(HTMLMediaElement::)
// nsIAudioChannelAgentCallback
NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
// NS_DECL_NSITIMERCALLBACK
NS_DECL_NSITIMERCALLBACK
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel);
@ -51,33 +42,9 @@ public:
Audio(const GlobalObject& aGlobal,
const Optional<nsAString>& aSrc, ErrorResult& aRv);
void MozSetup(uint32_t aChannels, uint32_t aRate, ErrorResult& aRv);
uint32_t MozWriteAudio(const Float32Array& aData, ErrorResult& aRv)
{
return MozWriteAudio(aData.Data(), aData.Length(), aRv);
}
uint32_t MozWriteAudio(const Sequence<float>& aData, ErrorResult& aRv)
{
return MozWriteAudio(aData.Elements(), aData.Length(), aRv);
}
uint32_t MozWriteAudio(const float* aData, uint32_t aLength,
ErrorResult& aRv);
uint64_t MozCurrentSampleOffset(ErrorResult& aRv);
protected:
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
// Update the audio channel playing state
virtual void UpdateAudioChannelPlayingState() MOZ_OVERRIDE;
// Due to that audio data API doesn't indicate the timing of pause or end,
// the timer is used to defer the timing of pause/stop after writing data.
nsCOMPtr<nsITimer> mDeferStopPlayTimer;
// To indicate mDeferStopPlayTimer is on fire or not.
bool mTimerActivated;
};
} // namespace dom

View File

@ -32,7 +32,6 @@ typedef uint16_t nsMediaNetworkState;
typedef uint16_t nsMediaReadyState;
namespace mozilla {
class AudioStream;
class ErrorResult;
class MediaResource;
class MediaDecoder;
@ -197,13 +196,6 @@ public:
// suspended the channel.
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
// the audio data sent to hardware and dispatch it in "mozaudioavailable"
// events. This allows us to not perform the copy and thus reduce overhead
// in the common case where we don't have a "MozAudioAvailable" listener.
void NotifyAudioAvailableListener();
// Called by the media decoder and the video frame to get the
// ImageContainer containing the video data.
virtual VideoFrameContainer* GetVideoFrameContainer() MOZ_FINAL MOZ_OVERRIDE;
@ -213,9 +205,6 @@ public:
using nsGenericHTMLElement::DispatchEvent;
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);
// Dispatch events that were raised while in the bfcache
nsresult DispatchPendingMediaEvents();
@ -279,12 +268,6 @@ public:
*/
void NotifyLoadError();
/**
* Called when data has been written to the underlying audio stream.
*/
virtual void NotifyAudioAvailable(float* aFrameBuffer, uint32_t aFrameBufferLength,
float aTime) MOZ_FINAL MOZ_OVERRIDE;
virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
/**
@ -506,14 +489,6 @@ public:
return mAudioCaptured;
}
uint32_t GetMozChannels(ErrorResult& aRv) const;
uint32_t GetMozSampleRate(ErrorResult& aRv) const;
uint32_t GetMozFrameBufferLength(ErrorResult& aRv) const;
void SetMozFrameBufferLength(uint32_t aValue, ErrorResult& aRv);
JSObject* MozGetMetadata(JSContext* aCx, ErrorResult& aRv);
double MozFragmentEnd();
@ -871,7 +846,7 @@ protected:
void Seek(double aTime, SeekTarget::Type aSeekType, ErrorResult& aRv);
// Update the audio channel playing state
virtual void UpdateAudioChannelPlayingState();
void UpdateAudioChannelPlayingState();
// Adds to the element's list of pending text tracks each text track
// in the element's list of text tracks whose text track mode is not disabled
@ -963,12 +938,6 @@ protected:
// Current audio volume
double mVolume;
// Current number of audio channels.
uint32_t mChannels;
// Current audio sample rate.
uint32_t mRate;
// Helper function to iterate over a hash table
// and convert it to a JSObject.
static PLDHashOperator BuildObjectFromTags(nsCStringHashKey::KeyType aKey,
@ -1031,19 +1000,12 @@ protected:
// This is the child source element which we're trying to load from.
nsCOMPtr<nsIContent> mSourceLoadCandidate;
// An audio stream for writing audio directly from JS.
nsAutoPtr<AudioStream> mAudioStream;
// Range of time played.
nsRefPtr<TimeRanges> mPlayed;
// Stores the time at the start of the current 'played' range.
double mCurrentPlayRangeStart;
// True if MozAudioAvailable events can be safely dispatched, based on
// a media and element same-origin check.
bool mAllowAudioData;
// If true then we have begun downloading the media content.
// Set to false when completed, or not yet started.
bool mBegun;

View File

@ -29,16 +29,14 @@ namespace dom {
extern bool IsAudioAPIEnabled();
NS_IMPL_ISUPPORTS_INHERITED4(HTMLAudioElement, HTMLMediaElement,
nsIDOMHTMLMediaElement, nsIDOMHTMLAudioElement,
nsITimerCallback, nsIAudioChannelAgentCallback)
NS_IMPL_ISUPPORTS_INHERITED2(HTMLAudioElement, HTMLMediaElement,
nsIDOMHTMLMediaElement, nsIDOMHTMLAudioElement)
NS_IMPL_ELEMENT_CLONE(HTMLAudioElement)
HTMLAudioElement::HTMLAudioElement(already_AddRefed<nsINodeInfo>& aNodeInfo)
: HTMLMediaElement(aNodeInfo),
mTimerActivated(false)
: HTMLMediaElement(aNodeInfo)
{
}
@ -77,128 +75,6 @@ HTMLAudioElement::Audio(const GlobalObject& aGlobal,
return audio.forget();
}
void
HTMLAudioElement::MozSetup(uint32_t aChannels, uint32_t aRate, ErrorResult& aRv)
{
if (!IsAudioAPIEnabled()) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return;
}
OwnerDoc()->WarnOnceAbout(nsIDocument::eMozAudioData);
// If there is already a src provided, don't setup another stream
if (mDecoder) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
// MozWriteAudio divides by mChannels, so validate now.
if (0 == aChannels) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
if (mAudioStream) {
mAudioStream->Shutdown();
}
#ifdef MOZ_B2G
if (mTimerActivated) {
mDeferStopPlayTimer->Cancel();
mTimerActivated = false;
UpdateAudioChannelPlayingState();
}
#endif
mAudioStream = new AudioStream();
aRv = mAudioStream->Init(aChannels, aRate, mAudioChannelType, AudioStream::HighLatency);
if (aRv.Failed()) {
mAudioStream->Shutdown();
mAudioStream = nullptr;
return;
}
MetadataLoaded(aChannels, aRate, true, false, nullptr);
mAudioStream->SetVolume(mMuted ? 0.0 : mVolume);
}
uint32_t
HTMLAudioElement::MozWriteAudio(const float* aData, uint32_t aLength,
ErrorResult& aRv)
{
if (!IsAudioAPIEnabled()) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return 0;
}
if (!mAudioStream) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return 0;
}
// Make sure that we are going to write the correct amount of data based
// on number of channels.
if (aLength % mChannels != 0) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return 0;
}
#ifdef MOZ_B2G
if (!mDeferStopPlayTimer) {
mDeferStopPlayTimer = do_CreateInstance("@mozilla.org/timer;1");
}
if (mTimerActivated) {
mDeferStopPlayTimer->Cancel();
}
// The maximum buffer size of audio backend is 1 second, so waiting for 1
// second is sufficient enough.
mDeferStopPlayTimer->InitWithCallback(this, 1000, nsITimer::TYPE_ONE_SHOT);
mTimerActivated = true;
UpdateAudioChannelPlayingState();
#endif
// Don't write more than can be written without blocking.
uint32_t writeLen = std::min(mAudioStream->Available(), aLength / mChannels);
// Convert the samples back to integers as we are using fixed point audio in
// the AudioStream.
// This could be optimized to avoid allocation and memcpy when
// AudioDataValue is 'float', but it's not worth it for this deprecated API.
nsAutoArrayPtr<AudioDataValue> audioData(new AudioDataValue[writeLen * mChannels]);
ConvertAudioSamples(aData, audioData.get(), writeLen * mChannels);
aRv = mAudioStream->Write(audioData.get(), writeLen);
if (aRv.Failed()) {
return 0;
}
mAudioStream->Start();
// Return the actual amount written.
return writeLen * mChannels;
}
uint64_t
HTMLAudioElement::MozCurrentSampleOffset(ErrorResult& aRv)
{
if (!IsAudioAPIEnabled()) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return 0;
}
if (!mAudioStream) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return 0;
}
int64_t position = mAudioStream->GetPositionInFrames();
if (position < 0) {
return 0;
}
return position * mChannels;
}
nsresult HTMLAudioElement::SetAcceptHeader(nsIHttpChannel* aChannel)
{
nsAutoCString value(
@ -224,78 +100,5 @@ HTMLAudioElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
return HTMLAudioElementBinding::Wrap(aCx, aScope, this);
}
/* void canPlayChanged (in boolean canPlay); */
NS_IMETHODIMP
HTMLAudioElement::CanPlayChanged(int32_t canPlay)
{
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
// Only Audio_Data API will initialize the mAudioStream, so we call the parent
// one when this audio tag is not used by Audio_Data API.
if (!mAudioStream) {
return HTMLMediaElement::CanPlayChanged(canPlay);
}
#ifdef MOZ_B2G
if (canPlay != AUDIO_CHANNEL_STATE_MUTED) {
SetMutedInternal(mMuted & ~MUTED_BY_AUDIO_CHANNEL);
} else {
SetMutedInternal(mMuted | MUTED_BY_AUDIO_CHANNEL);
}
#endif
return NS_OK;
}
NS_IMETHODIMP
HTMLAudioElement::WindowVolumeChanged()
{
return HTMLMediaElement::WindowVolumeChanged();
}
NS_IMETHODIMP
HTMLAudioElement::Notify(nsITimer* aTimer)
{
#ifdef MOZ_B2G
mTimerActivated = false;
UpdateAudioChannelPlayingState();
#endif
return NS_OK;
}
void
HTMLAudioElement::UpdateAudioChannelPlayingState()
{
if (!mAudioStream) {
HTMLMediaElement::UpdateAudioChannelPlayingState();
return;
}
// The HTMLAudioElement is registered to the AudioChannelService only on B2G.
#ifdef MOZ_B2G
if (mTimerActivated != mPlayingThroughTheAudioChannel) {
mPlayingThroughTheAudioChannel = mTimerActivated;
if (!mAudioChannelAgent) {
nsresult rv;
mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1", &rv);
if (!mAudioChannelAgent) {
return;
}
// Use a weak ref so the audio channel agent can't leak |this|.
mAudioChannelAgent->InitWithWeakCallback(OwnerDoc()->GetWindow(),
mAudioChannelType, this);
mAudioChannelAgent->SetVisibilityState(!OwnerDoc()->Hidden());
}
if (mPlayingThroughTheAudioChannel) {
int32_t canPlay;
mAudioChannelAgent->StartPlaying(&canPlay);
CanPlayChanged(canPlay);
} else {
mAudioChannelAgent->StopPlaying();
mAudioChannelAgent = nullptr;
}
}
#endif
}
} // namespace dom
} // namespace mozilla

View File

@ -59,7 +59,6 @@
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsIAppShell.h"
#include "nsWidgetsCID.h"
#include "nsIDOMNotifyAudioAvailableEvent.h"
#include "nsMediaFragmentURIParser.h"
#include "nsURIHashKey.h"
#include "nsJSUtils.h"
@ -624,10 +623,6 @@ void HTMLMediaElement::AbortExistingLoads()
mMediaSource->Detach();
mMediaSource = nullptr;
}
if (mAudioStream) {
mAudioStream->Shutdown();
mAudioStream = nullptr;
}
mLoadingSrc = nullptr;
@ -648,8 +643,6 @@ void HTMLMediaElement::AbortExistingLoads()
mDownloadSuspendedByCache = false;
mSourcePointer = nullptr;
mChannels = 0;
mRate = 0;
mTags = nullptr;
if (mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
@ -864,27 +857,6 @@ void HTMLMediaElement::NotifyLoadError()
}
}
void HTMLMediaElement::NotifyAudioAvailable(float* aFrameBuffer,
uint32_t aFrameBufferLength,
float aTime)
{
// Auto manage the memory for the frame buffer, so that if we add an early
// return-on-error here in future, we won't forget to release the memory.
// Otherwise we hand ownership of the memory over to the event created by
// DispatchAudioAvailableEvent().
nsAutoArrayPtr<float> frameBuffer(aFrameBuffer);
// Do same-origin check on element and media before allowing MozAudioAvailable events.
if (!mMediaSecurityVerified) {
nsCOMPtr<nsIPrincipal> principal = GetCurrentPrincipal();
nsresult rv = NodePrincipal()->Subsumes(principal, &mAllowAudioData);
if (NS_FAILED(rv)) {
mAllowAudioData = false;
}
}
DispatchAudioAvailableEvent(frameBuffer.forget(), aFrameBufferLength, aTime);
}
void HTMLMediaElement::LoadFromSourceChildren()
{
NS_ASSERTION(mDelayingLoadEvent,
@ -1013,12 +985,6 @@ static bool UseAudioChannelService()
return Preferences::GetBool("media.useAudioChannelService");
}
// Not static because it's used in HTMLAudioElement.
bool IsAudioAPIEnabled()
{
return mozilla::Preferences::GetBool("media.audio_data.enabled", false);
}
void HTMLMediaElement::UpdatePreloadAction()
{
PreloadAction nextAction = PRELOAD_UNDEFINED;
@ -1673,54 +1639,6 @@ NS_IMETHODIMP HTMLMediaElement::SetVolume(double aVolume)
return rv.ErrorCode();
}
uint32_t
HTMLMediaElement::GetMozChannels(ErrorResult& aRv) const
{
if (!IsAudioAPIEnabled()) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return 0;
}
if (!mDecoder && !mAudioStream) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return 0;
}
return mChannels;
}
NS_IMETHODIMP
HTMLMediaElement::GetMozChannels(uint32_t* aMozChannels)
{
ErrorResult rv;
*aMozChannels = GetMozChannels(rv);
return rv.ErrorCode();
}
uint32_t
HTMLMediaElement::GetMozSampleRate(ErrorResult& aRv) const
{
if (!IsAudioAPIEnabled()) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return 0;
}
if (!mDecoder && !mAudioStream) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return 0;
}
return mRate;
}
NS_IMETHODIMP
HTMLMediaElement::GetMozSampleRate(uint32_t* aMozSampleRate)
{
ErrorResult rv;
*aMozSampleRate = GetMozSampleRate(rv);
return rv.ErrorCode();
}
// Helper struct with arguments for our hash iterator.
typedef struct MOZ_STACK_CLASS {
JSContext* cx;
@ -1793,56 +1711,6 @@ HTMLMediaElement::MozGetMetadata(JSContext* cx, JS::MutableHandle<JS::Value> aVa
return rv.ErrorCode();
}
uint32_t
HTMLMediaElement::GetMozFrameBufferLength(ErrorResult& aRv) const
{
if (!IsAudioAPIEnabled()) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return 0;
}
// The framebuffer (via MozAudioAvailable events) is only available
// when reading vs. writing audio directly.
if (!mDecoder) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return 0;
}
return mDecoder->GetFrameBufferLength();
}
NS_IMETHODIMP
HTMLMediaElement::GetMozFrameBufferLength(uint32_t* aMozFrameBufferLength)
{
ErrorResult rv;
*aMozFrameBufferLength = GetMozFrameBufferLength(rv);
return rv.ErrorCode();
}
void
HTMLMediaElement::SetMozFrameBufferLength(uint32_t aMozFrameBufferLength, ErrorResult& aRv)
{
if (!IsAudioAPIEnabled()) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return;
}
if (!mDecoder) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
aRv = mDecoder->RequestFrameBufferLength(aMozFrameBufferLength);
}
NS_IMETHODIMP
HTMLMediaElement::SetMozFrameBufferLength(uint32_t aMozFrameBufferLength)
{
ErrorResult rv;
SetMozFrameBufferLength(aMozFrameBufferLength, rv);
return rv.ErrorCode();
}
/* attribute boolean muted; */
NS_IMETHODIMP HTMLMediaElement::GetMuted(bool* aMuted)
{
@ -1877,8 +1745,6 @@ void HTMLMediaElement::SetVolumeInternal()
if (mDecoder) {
mDecoder->SetVolume(effectiveVolume);
} else if (mAudioStream) {
mAudioStream->SetVolume(effectiveVolume);
} else if (mSrcStream) {
GetSrcMediaStream()->SetAudioOutputVolume(this, effectiveVolume);
}
@ -2105,8 +1971,6 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<nsINodeInfo>& aNodeInfo)
mReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING),
mLoadWaitStatus(NOT_WAITING),
mVolume(1.0),
mChannels(0),
mRate(0),
mPreloadAction(PRELOAD_UNDEFINED),
mMediaSize(-1,-1),
mLastCurrentTime(0.0),
@ -2117,7 +1981,6 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<nsINodeInfo>& aNodeInfo)
mPreservesPitch(true),
mPlayed(new TimeRanges),
mCurrentPlayRangeStart(-1.0),
mAllowAudioData(false),
mBegun(false),
mLoadedFirstFrame(false),
mAutoplaying(true),
@ -2189,9 +2052,6 @@ HTMLMediaElement::~HTMLMediaElement()
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
}
if (mAudioStream) {
mAudioStream->Shutdown();
}
WakeLockRelease();
}
@ -2591,13 +2451,6 @@ nsresult HTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParen
// The preload action depends on the value of the autoplay attribute.
// It's value may have changed, so update it.
UpdatePreloadAction();
if (aDocument->HasAudioAvailableListeners()) {
// The document already has listeners for the "MozAudioAvailable"
// event, so the decoder must be notified so it initiates
// "MozAudioAvailable" event dispatch.
NotifyAudioAvailableListener();
}
}
return rv;
@ -2798,10 +2651,6 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
}
}
if (OwnerDoc()->HasAudioAvailableListeners()) {
NotifyAudioAvailableListener();
}
if (NS_FAILED(rv)) {
ShutdownDecoder();
}
@ -3001,8 +2850,6 @@ void HTMLMediaElement::MetadataLoaded(int aChannels,
bool aHasVideo,
const MetadataTags* aTags)
{
mChannels = aChannels;
mRate = aRate;
mHasAudio = aHasAudio;
mTags = aTags;
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
@ -3401,39 +3248,6 @@ VideoFrameContainer* HTMLMediaElement::GetVideoFrameContainer()
return mVideoFrameContainer;
}
nsresult HTMLMediaElement::DispatchAudioAvailableEvent(float* aFrameBuffer,
uint32_t aFrameBufferLength,
float aTime)
{
// Auto manage the memory for the frame buffer. If we fail and return
// an error, this ensures we free the memory in the frame buffer. Otherwise
// we hand off ownership of the frame buffer to the audioavailable event,
// which frees the memory when it's destroyed.
nsAutoArrayPtr<float> frameBuffer(aFrameBuffer);
if (!IsAudioAPIEnabled()) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(OwnerDoc());
nsRefPtr<HTMLMediaElement> kungFuDeathGrip = this;
NS_ENSURE_TRUE(domDoc, NS_ERROR_INVALID_ARG);
nsCOMPtr<nsIDOMEvent> event;
nsresult rv = domDoc->CreateEvent(NS_LITERAL_STRING("MozAudioAvailableEvent"),
getter_AddRefs(event));
nsCOMPtr<nsIDOMNotifyAudioAvailableEvent> audioavailableEvent(do_QueryInterface(event));
NS_ENSURE_SUCCESS(rv, rv);
rv = audioavailableEvent->InitAudioAvailableEvent(NS_LITERAL_STRING("MozAudioAvailable"),
false, false, frameBuffer.forget(), aFrameBufferLength,
aTime, mAllowAudioData);
NS_ENSURE_SUCCESS(rv, rv);
bool dummy;
return DispatchEvent(event, &dummy);
}
nsresult HTMLMediaElement::DispatchEvent(const nsAString& aName)
{
LOG_EVENT(PR_LOG_DEBUG, ("%p Dispatching event %s", this,
@ -3884,14 +3698,6 @@ NS_IMETHODIMP HTMLMediaElement::GetMozFragmentEnd(double* aTime)
return NS_OK;
}
void HTMLMediaElement::NotifyAudioAvailableListener()
{
OwnerDoc()->WarnOnceAbout(nsIDocument::eMozAudioData);
if (mDecoder) {
mDecoder->NotifyAudioAvailableListener();
}
}
static double ClampPlaybackRate(double aPlaybackRate)
{
if (aPlaybackRate == 0.0) {
@ -3944,7 +3750,7 @@ HTMLMediaElement::SetPlaybackRate(double aPlaybackRate, ErrorResult& aRv)
{
// Changing the playback rate of a media that has more than two channels is
// not supported.
if (aPlaybackRate < 0 || (mChannels > 2 && aPlaybackRate != 1.0)) {
if (aPlaybackRate < 0) {
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return;
}

View File

@ -1,249 +0,0 @@
/* -*- 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/. */
#include "AudioAvailableEventManager.h"
#include "VideoUtils.h"
#include "MediaDecoder.h"
#include "nsIRunnable.h"
namespace mozilla {
static const nsTArray< nsCOMPtr<nsIRunnable> >::size_type MAX_PENDING_EVENTS = 100;
class nsAudioAvailableEventRunner : public nsRunnable
{
private:
nsRefPtr<MediaDecoder> mDecoder;
nsAutoArrayPtr<float> mFrameBuffer;
public:
nsAudioAvailableEventRunner(MediaDecoder* aDecoder, float* aFrameBuffer,
uint32_t aFrameBufferLength, float aTime) :
mDecoder(aDecoder),
mFrameBuffer(aFrameBuffer),
mFrameBufferLength(aFrameBufferLength),
mTime(aTime)
{
MOZ_COUNT_CTOR(nsAudioAvailableEventRunner);
}
~nsAudioAvailableEventRunner() {
MOZ_COUNT_DTOR(nsAudioAvailableEventRunner);
}
NS_IMETHOD Run()
{
mDecoder->AudioAvailable(mFrameBuffer.forget(), mFrameBufferLength, mTime);
return NS_OK;
}
const uint32_t mFrameBufferLength;
// Start time of the buffer data (in seconds).
const float mTime;
};
AudioAvailableEventManager::AudioAvailableEventManager(MediaDecoder* aDecoder) :
mDecoder(aDecoder),
mSignalBuffer(new float[mDecoder->GetFrameBufferLength()]),
mSignalBufferLength(mDecoder->GetFrameBufferLength()),
mNewSignalBufferLength(mSignalBufferLength),
mSignalBufferPosition(0),
mReentrantMonitor("media.audioavailableeventmanager"),
mHasListener(false)
{
MOZ_COUNT_CTOR(AudioAvailableEventManager);
}
AudioAvailableEventManager::~AudioAvailableEventManager()
{
MOZ_COUNT_DTOR(AudioAvailableEventManager);
}
void AudioAvailableEventManager::Init(uint32_t aChannels, uint32_t aRate)
{
NS_ASSERTION(aChannels != 0 && aRate != 0, "Audio metadata not known.");
mSamplesPerSecond = static_cast<float>(aChannels * aRate);
}
void AudioAvailableEventManager::DispatchPendingEvents(uint64_t aCurrentTime)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (!mHasListener) {
return;
}
while (mPendingEvents.Length() > 0) {
nsAudioAvailableEventRunner* e =
(nsAudioAvailableEventRunner*)mPendingEvents[0].get();
if (e->mTime * USECS_PER_S > aCurrentTime) {
break;
}
nsCOMPtr<nsIRunnable> event = mPendingEvents[0];
mPendingEvents.RemoveElementAt(0);
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
}
}
void AudioAvailableEventManager::QueueWrittenAudioData(AudioDataValue* aAudioData,
uint32_t aAudioDataLength,
uint64_t aEndTimeSampleOffset)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (!mHasListener) {
return;
}
uint32_t currentBufferSize = mNewSignalBufferLength;
if (currentBufferSize == 0) {
NS_WARNING("Decoder framebuffer length not set.");
return;
}
if (!mSignalBuffer ||
(mSignalBufferPosition == 0 && mSignalBufferLength != currentBufferSize)) {
if (!mSignalBuffer || (mSignalBufferLength < currentBufferSize)) {
// Only resize if buffer is empty or smaller.
mSignalBuffer = new float[currentBufferSize];
}
mSignalBufferLength = currentBufferSize;
}
AudioDataValue* audioData = aAudioData;
uint32_t audioDataLength = aAudioDataLength;
uint32_t signalBufferTail = mSignalBufferLength - mSignalBufferPosition;
// Group audio samples into optimal size for event dispatch, and queue.
while (signalBufferTail <= audioDataLength) {
float time = 0.0;
// Guard against unsigned number overflow during first frame time calculation.
if (aEndTimeSampleOffset > mSignalBufferPosition + audioDataLength) {
time = (aEndTimeSampleOffset - mSignalBufferPosition - audioDataLength) /
mSamplesPerSecond;
}
// Fill the signalBuffer.
uint32_t i;
float *signalBuffer = mSignalBuffer.get() + mSignalBufferPosition;
if (audioData) {
for (i = 0; i < signalBufferTail; ++i) {
signalBuffer[i] = AudioSampleToFloat(audioData[i]);
}
} else {
memset(signalBuffer, 0, signalBufferTail*sizeof(signalBuffer[0]));
}
if (audioData) {
audioData += signalBufferTail;
}
NS_ASSERTION(audioDataLength >= signalBufferTail,
"audioDataLength about to wrap past zero to +infinity!");
audioDataLength -= signalBufferTail;
if (mPendingEvents.Length() > 0) {
// Check last event timecode to make sure that all queued events
// are in non-descending sequence.
nsAudioAvailableEventRunner* lastPendingEvent =
(nsAudioAvailableEventRunner*)mPendingEvents[mPendingEvents.Length() - 1].get();
if (lastPendingEvent->mTime > time) {
// Clear the queue to start a fresh sequence.
mPendingEvents.Clear();
} else if (mPendingEvents.Length() >= MAX_PENDING_EVENTS) {
NS_WARNING("Hit audio event queue max.");
mPendingEvents.RemoveElementsAt(0, mPendingEvents.Length() - MAX_PENDING_EVENTS + 1);
}
}
// Inform the element that we've written audio data.
nsCOMPtr<nsIRunnable> event =
new nsAudioAvailableEventRunner(mDecoder, mSignalBuffer.forget(),
mSignalBufferLength, time);
mPendingEvents.AppendElement(event);
// Reset the buffer
mSignalBufferLength = currentBufferSize;
mSignalBuffer = new float[currentBufferSize];
mSignalBufferPosition = 0;
signalBufferTail = currentBufferSize;
}
NS_ASSERTION(mSignalBufferPosition + audioDataLength < mSignalBufferLength,
"Intermediate signal buffer must fit at least one more item.");
if (audioDataLength > 0) {
// Add data to the signalBuffer.
uint32_t i;
float *signalBuffer = mSignalBuffer.get() + mSignalBufferPosition;
if (audioData) {
for (i = 0; i < audioDataLength; ++i) {
signalBuffer[i] = AudioSampleToFloat(audioData[i]);
}
} else {
memset(signalBuffer, 0, audioDataLength*sizeof(signalBuffer[0]));
}
mSignalBufferPosition += audioDataLength;
}
}
void AudioAvailableEventManager::Clear()
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
mPendingEvents.Clear();
mSignalBufferPosition = 0;
}
void AudioAvailableEventManager::Drain(uint64_t aEndTime)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (!mHasListener) {
return;
}
// Force all pending events to go now.
for (uint32_t i = 0; i < mPendingEvents.Length(); ++i) {
nsCOMPtr<nsIRunnable> event = mPendingEvents[i];
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
}
mPendingEvents.Clear();
// If there is anything left in the signal buffer, put it in an event and fire.
if (0 == mSignalBufferPosition)
return;
// Zero-pad the end of the signal buffer so it's complete.
memset(mSignalBuffer.get() + mSignalBufferPosition, 0,
(mSignalBufferLength - mSignalBufferPosition) * sizeof(float));
// Force this last event to go now.
float time = (aEndTime / static_cast<float>(USECS_PER_S)) -
(mSignalBufferPosition / mSamplesPerSecond);
nsCOMPtr<nsIRunnable> lastEvent =
new nsAudioAvailableEventRunner(mDecoder, mSignalBuffer.forget(),
mSignalBufferLength, time);
NS_DispatchToMainThread(lastEvent, NS_DISPATCH_NORMAL);
mSignalBufferPosition = 0;
}
void AudioAvailableEventManager::SetSignalBufferLength(uint32_t aLength)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
mNewSignalBufferLength = aLength;
}
void AudioAvailableEventManager::NotifyAudioAvailableListener()
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
mHasListener = true;
}
} // namespace mozilla

View File

@ -1,97 +0,0 @@
/* -*- 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 AudioAvailableEventManager_h__
#define AudioAvailableEventManager_h__
#include "nsAutoPtr.h"
#include "nsTArray.h"
#include "AudioSampleFormat.h"
#include "mozilla/ReentrantMonitor.h"
class nsIRunnable;
template <class T> class nsCOMPtr;
namespace mozilla {
class MediaDecoder;
class AudioAvailableEventManager
{
public:
AudioAvailableEventManager(MediaDecoder* aDecoder);
~AudioAvailableEventManager();
// Initialize the event manager with audio metadata. Called before
// audio begins to get queued or events are dispatched.
void Init(uint32_t aChannels, uint32_t aRate);
// Dispatch pending MozAudioAvailable events in the queue. Called
// from the state machine thread.
void DispatchPendingEvents(uint64_t aCurrentTime);
// Queues audio sample data and re-packages it into equal sized
// framebuffers. Called from the audio thread.
void QueueWrittenAudioData(AudioDataValue* aAudioData,
uint32_t aAudioDataLength,
uint64_t aEndTimeSampleOffset);
// Clears the queue of any existing events. Called from both the state
// machine and audio threads.
void Clear();
// Fires one last event for any extra samples that didn't fit in a whole
// framebuffer. This is meant to be called only once when the audio finishes.
// Called from the state machine thread.
void Drain(uint64_t aTime);
// Sets the size of the signal buffer.
// Called from the main and the state machine thread.
void SetSignalBufferLength(uint32_t aLength);
// Called by the media element to notify the manager that there is a
// listener on the "MozAudioAvailable" event, and that we need to dispatch
// such events. Called from the main thread.
void NotifyAudioAvailableListener();
private:
// The decoder associated with the event manager. The event manager shares
// the same lifetime as the decoder (the decoder holds a reference to the
// manager).
MediaDecoder* mDecoder;
// The number of samples per second.
float mSamplesPerSecond;
// A buffer for audio data to be dispatched in DOM events.
nsAutoArrayPtr<float> mSignalBuffer;
// The current size of the signal buffer, may change due to DOM calls.
uint32_t mSignalBufferLength;
// The size of the new signal buffer, may change due to DOM calls.
uint32_t mNewSignalBufferLength;
// The position of the first available item in mSignalBuffer
uint32_t mSignalBufferPosition;
// The MozAudioAvailable events to be dispatched. This queue is shared
// between the state machine and audio threads.
nsTArray< nsCOMPtr<nsIRunnable> > mPendingEvents;
// ReentrantMonitor for shared access to mPendingEvents queue or
// buffer length.
ReentrantMonitor mReentrantMonitor;
// True if something in the owning document has a listener on the
// "MozAudioAvailable" event. If not, we don't need to bother copying played
// audio data and dispatching the event. Synchronized by mReentrantMonitor.
bool mHasListener;
};
} // namespace mozilla
#endif

View File

@ -424,7 +424,6 @@ MediaDecoder::MediaDecoder() :
mIgnoreProgressData(false),
mInfiniteStream(false),
mOwner(nullptr),
mFrameBufferLength(0),
mPinnedForSeek(false),
mShuttingDown(false),
mPausedForPlaybackRateNull(false),
@ -555,10 +554,6 @@ nsresult MediaDecoder::InitializeStateMachine(MediaDecoder* aCloneDonor)
if (mMinimizePreroll) {
mDecoderStateMachine->SetMinimizePrerollUntilPlaybackStarts();
}
if (mFrameBufferLength > 0) {
// The valid mFrameBufferLength value was specified earlier
mDecoderStateMachine->SetFrameBufferLength(mFrameBufferLength);
}
}
ChangeState(PLAY_STATE_LOADING);
@ -572,20 +567,6 @@ void MediaDecoder::SetMinimizePrerollUntilPlaybackStarts()
mMinimizePreroll = true;
}
nsresult MediaDecoder::RequestFrameBufferLength(uint32_t aLength)
{
if (aLength < FRAMEBUFFER_LENGTH_MIN || aLength > FRAMEBUFFER_LENGTH_MAX) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
mFrameBufferLength = aLength;
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
if (mDecoderStateMachine) {
mDecoderStateMachine->SetFrameBufferLength(aLength);
}
return NS_OK;
}
nsresult MediaDecoder::ScheduleStateMachineThread()
{
MOZ_ASSERT(NS_IsMainThread());
@ -668,21 +649,6 @@ already_AddRefed<nsIPrincipal> MediaDecoder::GetCurrentPrincipal()
return mResource ? mResource->GetCurrentPrincipal() : nullptr;
}
void MediaDecoder::AudioAvailable(float* aFrameBuffer,
uint32_t aFrameBufferLength,
float aTime)
{
// Auto manage the frame buffer's memory. If we return due to an error
// here, this ensures we free the memory. Otherwise, we pass off ownership
// to HTMLMediaElement::NotifyAudioAvailable().
nsAutoArrayPtr<float> frameBuffer(aFrameBuffer);
MOZ_ASSERT(NS_IsMainThread());
if (mShuttingDown || !mOwner) {
return;
}
mOwner->NotifyAudioAvailable(frameBuffer.forget(), aFrameBufferLength, aTime);
}
void MediaDecoder::QueueMetadata(int64_t aPublishTime,
int aChannels,
int aRate,
@ -1435,15 +1401,6 @@ bool MediaDecoder::OnStateMachineThread() const
return mDecoderStateMachine->OnStateMachineThread();
}
void MediaDecoder::NotifyAudioAvailableListener()
{
MOZ_ASSERT(NS_IsMainThread());
if (mDecoderStateMachine) {
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
mDecoderStateMachine->NotifyAudioAvailableListener();
}
}
void MediaDecoder::SetPlaybackRate(double aPlaybackRate)
{
if (aPlaybackRate == 0) {

View File

@ -210,16 +210,6 @@ class VideoFrameContainer;
class MediaDecoderStateMachine;
class MediaDecoderOwner;
// The size to use for audio data frames in MozAudioAvailable events.
// This value is per channel, and is chosen to give ~43 fps of events,
// for example, 44100 with 2 channels, 2*1024 = 2048.
static const uint32_t FRAMEBUFFER_LENGTH_PER_CHANNEL = 1024;
// The total size of the framebuffer used for MozAudioAvailable events
// has to be within the following range.
static const uint32_t FRAMEBUFFER_LENGTH_MIN = 512;
static const uint32_t FRAMEBUFFER_LENGTH_MAX = 16384;
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
// GetTickCount() and conflicts with MediaDecoder::GetCurrentTime implementation.
#ifdef GetCurrentTime
@ -659,12 +649,6 @@ public:
// Returns a weak reference to the media decoder owner.
MediaDecoderOwner* GetMediaOwner() const;
// Returns the current size of the framebuffer used in
// MozAudioAvailable events.
uint32_t GetFrameBufferLength() { return mFrameBufferLength; }
void AudioAvailable(float* aFrameBuffer, uint32_t aFrameBufferLength, float aTime);
// Called by the state machine to notify the decoder that the duration
// has changed.
void DurationChanged();
@ -695,10 +679,6 @@ public:
}
layers::ImageContainer* GetImageContainer() MOZ_OVERRIDE;
// Sets the length of the framebuffer used in MozAudioAvailable events.
// The new size must be between 512 and 16384.
virtual nsresult RequestFrameBufferLength(uint32_t aLength);
// Return the current state. Can be called on any thread. If called from
// a non-main thread, the decoder monitor must be held.
PlayState GetState() {
@ -841,11 +821,6 @@ public:
// Drop reference to state machine. Only called during shutdown dance.
virtual void ReleaseStateMachine();
// Called when a "MozAudioAvailable" event listener is added. This enables
// the decoder to only dispatch "MozAudioAvailable" events when a
// handler exists, reducing overhead. Called on the main thread.
virtual void NotifyAudioAvailableListener();
// Notifies the element that decoding has failed.
virtual void DecodeError();
@ -1211,9 +1186,6 @@ protected:
// time of the last decoded video frame).
MediaChannelStatistics mPlaybackStatistics;
// The framebuffer size to use for audioavailable events.
uint32_t mFrameBufferLength;
// True when our media stream has been pinned. We pin the stream
// while seeking.
bool mPinnedForSeek;

View File

@ -46,12 +46,6 @@ public:
// 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.

View File

@ -197,7 +197,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
mDispatchedRunEvent(false),
mDecodeThreadWaiting(false),
mRealTime(aRealTime),
mEventManager(aDecoder),
mLastFrameStatus(MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED)
{
MOZ_COUNT_CTOR(MediaDecoderStateMachine);
@ -945,8 +944,6 @@ void MediaDecoderStateMachine::AudioLoop()
ReentrantMonitorAutoExit exit(mDecoder->GetReentrantMonitor());
mAudioStream->Drain();
}
// Fire one last event for any extra frames that didn't fill a framebuffer.
mEventManager.Drain(mAudioEndTime);
}
}
}
@ -957,7 +954,6 @@ void MediaDecoderStateMachine::AudioLoop()
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mAudioStream->Shutdown();
mAudioStream = nullptr;
mEventManager.Clear();
if (!mAudioCaptured) {
mAudioCompleted = true;
UpdateReadyState();
@ -979,9 +975,6 @@ uint32_t MediaDecoderStateMachine::PlaySilence(uint32_t aFrames,
uint32_t maxFrames = SILENCE_BYTES_CHUNK / aChannels / sizeof(AudioDataValue);
uint32_t frames = std::min(aFrames, maxFrames);
WriteSilence(mAudioStream, frames);
// Dispatch events to the DOM for the audio just written.
mEventManager.QueueWrittenAudioData(nullptr, frames * aChannels,
(aFrameOffset + frames) * aChannels);
return frames;
}
@ -1014,10 +1007,6 @@ uint32_t MediaDecoderStateMachine::PlayFromAudioQueue(uint64_t aFrameOffset,
offset = audio->mOffset;
frames = audio->mFrames;
// Dispatch events to the DOM for the audio just written.
mEventManager.QueueWrittenAudioData(audio->mAudioData.get(),
audio->mFrames * aChannels,
(aFrameOffset + frames) * aChannels);
if (offset != -1) {
mDecoder->UpdatePlaybackOffset(offset);
}
@ -1142,9 +1131,6 @@ void MediaDecoderStateMachine::UpdatePlaybackPosition(int64_t aTime)
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
}
// Notify DOM of any queued up audioavailable events
mEventManager.DispatchPendingEvents(GetMediaTime());
mMetadataManager.DispatchMetadataIfNeeded(mDecoder, aTime);
if (fragmentEnded) {
@ -1776,14 +1762,6 @@ bool MediaDecoderStateMachine::HasLowUndecodedData(double aUsecs) const
return stream->GetCachedDataEnd(currentPos) < requiredPos;
}
void MediaDecoderStateMachine::SetFrameBufferLength(uint32_t aLength)
{
NS_ASSERTION(aLength >= 512 && aLength <= 16384,
"The length must be between 512 and 16384");
AssertCurrentThreadInMonitor();
mEventManager.SetSignalBufferLength(aLength);
}
void
MediaDecoderStateMachine::DecodeError()
{
@ -1887,19 +1865,7 @@ nsresult MediaDecoderStateMachine::DecodeMetadata()
mLowAudioThresholdUsecs /= NO_VIDEO_AMPLE_AUDIO_DIVISOR;
}
// Inform the element that we've loaded the metadata and the first frame,
// setting the default framebuffer size for audioavailable events. Also,
// if there is audio, let the MozAudioAvailable event manager know about
// the metadata.
if (HasAudio()) {
mEventManager.Init(mInfo.mAudio.mChannels, mInfo.mAudio.mRate);
// Set the buffer length at the decoder level to be able, to be able
// to retrive the value via media element method. The RequestFrameBufferLength
// will call the MediaDecoderStateMachine::SetFrameBufferLength().
uint32_t frameBufferLength = mInfo.mAudio.mChannels * FRAMEBUFFER_LENGTH_PER_CHANNEL;
mDecoder->RequestFrameBufferLength(frameBufferLength);
}
// Inform the element that we've loaded the metadata and the first frame.
nsCOMPtr<nsIRunnable> metadataLoadedEvent =
new AudioMetadataEventRunner(mDecoder,
mInfo.mAudio.mChannels,
@ -2852,12 +2818,6 @@ nsIEventTarget* MediaDecoderStateMachine::GetStateMachineThread()
return mStateMachineThreadPool->GetEventTarget();
}
void MediaDecoderStateMachine::NotifyAudioAvailableListener()
{
AssertCurrentThreadInMonitor();
mEventManager.NotifyAudioAvailableListener();
}
void MediaDecoderStateMachine::SetPlaybackRate(double aPlaybackRate)
{
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");

View File

@ -79,7 +79,6 @@ hardware (via AudioStream).
#include "mozilla/Attributes.h"
#include "nsThreadUtils.h"
#include "MediaDecoder.h"
#include "AudioAvailableEventManager.h"
#include "mozilla/ReentrantMonitor.h"
#include "MediaDecoderReader.h"
#include "MediaDecoderOwner.h"
@ -297,10 +296,6 @@ public:
return mMediaSeekable;
}
// Sets the current frame buffer length for the MozAudioAvailable event.
// Accessed on the main and state machine threads.
void SetFrameBufferLength(uint32_t aLength);
// Returns the shared state machine thread.
nsIEventTarget* GetStateMachineThread();
@ -336,10 +331,6 @@ public:
void SetSyncPointForMediaStream();
int64_t GetCurrentTimeViaMediaStreamSync();
// Called when a "MozAudioAvailable" event listener is added to the media
// element. Called on the main thread.
void NotifyAudioAvailableListener();
// Copy queued audio/video data in the reader to any output MediaStreams that
// need it.
void SendStreamData();
@ -512,8 +503,7 @@ private:
uint64_t aFrameOffset);
// Pops an audio chunk from the front of the audio queue, and pushes its
// audio data to the audio hardware. MozAudioAvailable data is also queued
// here. Called on the audio thread.
// audio data to the audio hardware.
uint32_t PlayFromAudioQueue(uint64_t aFrameOffset, uint32_t aChannels);
// Stops the audio thread. The decoder monitor must be held with exactly
@ -955,11 +945,6 @@ private:
// True is we are decoding a realtime stream, like a camera stream
bool mRealTime;
// Manager for queuing and dispatching MozAudioAvailable events. The
// event manager is accessed from the state machine and audio threads,
// and takes care of synchronizing access to its internal queue.
AudioAvailableEventManager mEventManager;
// Stores presentation info required for playback. The decoder monitor
// must be held when accessing this.
MediaInfo mInfo;

View File

@ -54,7 +54,6 @@ TEST_DIRS += [
EXPORTS += [
'AbstractMediaDecoder.h',
'AudioAvailableEventManager.h',
'AudioChannelFormat.h',
'AudioCompactor.h',
'AudioEventTimeline.h',
@ -111,7 +110,6 @@ EXPORTS.mozilla.dom += [
]
UNIFIED_SOURCES += [
'AudioAvailableEventManager.cpp',
'AudioChannelFormat.cpp',
'AudioCompactor.cpp',
'AudioNodeEngine.cpp',

Binary file not shown.

View File

@ -1 +0,0 @@
Cache-Control: no-store

View File

@ -1,16 +0,0 @@
<html>
<head>
<script>
function audioAvailable(e) {
document.getElementById("wasAudioAvailableCalled").checked = true;
}
</script>
</head>
<body>
<audio id="a1" src="sound.ogg" controls></audio>
<script>
document.getElementById("a1").addEventListener("MozAudioAvailable", audioAvailable, false);
</script>
<input id="wasAudioAvailableCalled" type="checkbox" readonly />
</body>
</html>

View File

@ -142,10 +142,7 @@ support-files =
dirac.ogg^headers^
dynamic_redirect.sjs
dynamic_resource.sjs
file_a4_tone.ogg
file_a4_tone.ogg^headers^
file_access_controls.html
file_audio_event_adopt_iframe.html
fragment_noplay.js
fragment_play.js
gizmo.mp4
@ -295,12 +292,10 @@ support-files =
wavedata_u8.wav
wavedata_u8.wav^headers^
[test_a4_tone.html]
[test_access_control.html]
[test_aspectratio_mp4.html]
[test_audio1.html]
[test_audio2.html]
[test_audio_event_adopt.html]
[test_autoplay.html]
[test_bug448534.html]
skip-if = buildapp == 'b2g' # b2g(Timed out, bug 894922? Bug 902677 is for the timing out of a lot of media tests) b2g-debug(Timed out, bug 894922? Bug 902677 is for the timing out of a lot of media tests) b2g-desktop(Timed out, bug 894922? Bug 902677 is for the timing out of a lot of media tests)
@ -311,7 +306,6 @@ skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(timed
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug))
[test_bug654550.html]
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(timed out) b2g-desktop(timed out)
[test_bug686137.html]
[test_bug686942.html]
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(timed out) b2g-desktop(timed out)
# [test_bug726904.html] # disabled - See bug 754860
@ -348,8 +342,6 @@ skip-if = buildapp == 'b2g' # b2g(6 failures) b2g-debug(6 failures) b2g-desktop(
[test_error_on_404.html]
skip-if = buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(timed out) b2g-desktop(timed out)
[test_fastSeek.html]
[test_framebuffer.html]
skip-if = buildapp == 'b2g' # b2g(timed out) b2g-debug(timed out) b2g-desktop(timed out)
[test_info_leak.html]
skip-if = buildapp == 'b2g' # b2g(2 failures) b2g-debug(2 failures) b2g-desktop(2 failures)
[test_invalid_reject.html]
@ -399,7 +391,6 @@ skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug))
[test_standalone.html]
[test_volume.html]
[test_video_to_canvas.html]
[test_audiowrite.html]
[test_mediarecorder_creation.html]
[test_mediarecorder_creation_fail.html]
[test_mediarecorder_avoid_recursion.html]
@ -504,7 +495,3 @@ skip-if = wave
run-if = wave
[test_fragment_play.html]
run-if = wave
[test_wave_data_s16.html]
run-if = wave
[test_wave_data_u8.html]
run-if = wave

View File

@ -1,263 +0,0 @@
<!DOCTYPE HTML>
<html>
<!-- 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/. -->
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=490705
-->
<head>
<title>Media test: simple audioAvalailable event checks</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=490705">Mozilla Bug 490705</a>
<pre id="test">
<script class="testbody" type="text/javascript">
/**
* FFT is a class for calculating the Discrete Fourier Transform of a signal
* with the Fast Fourier Transform algorithm.
*
* Source: github.com/corbanbrook/dsp.js; License: MIT; Copyright: Corban Brook
*
* @param {Number} bufferSize The size of the sample buffer to be computed. Must be power of 2
* @param {Number} sampleRate The sampleRate of the buffer (eg. 44100)
*
* @constructor
*/
FFT = function(bufferSize, sampleRate) {
this.bufferSize = bufferSize;
this.sampleRate = sampleRate;
this.spectrum = new Float32Array(bufferSize/2);
this.real = new Float32Array(bufferSize);
this.imag = new Float32Array(bufferSize);
this.reverseTable = new Uint32Array(bufferSize);
var limit = 1;
var bit = bufferSize >> 1;
while ( limit < bufferSize ) {
for ( var i = 0; i < limit; i++ ) {
this.reverseTable[i + limit] = this.reverseTable[i] + bit;
}
limit = limit << 1;
bit = bit >> 1;
}
this.sinTable = new Float32Array(bufferSize);
this.cosTable = new Float32Array(bufferSize);
for ( var i = 0; i < bufferSize; i++ ) {
this.sinTable[i] = Math.sin(-Math.PI/i);
this.cosTable[i] = Math.cos(-Math.PI/i);
}
};
/**
* Performs a forward tranform on the sample buffer.
* Converts a time domain signal to frequency domain spectra.
*
* @param {Array} buffer The sample buffer. Buffer Length must be power of 2
*
* @returns The frequency spectrum array
*/
FFT.prototype.forward = function(buffer) {
// Locally scope variables for speed up
var bufferSize = this.bufferSize,
cosTable = this.cosTable,
sinTable = this.sinTable,
reverseTable = this.reverseTable,
real = this.real,
imag = this.imag,
spectrum = this.spectrum;
var k = Math.floor(Math.log(bufferSize) / Math.LN2);
if ( Math.pow(2, k) !== bufferSize ) {
throw "Invalid buffer size, must be a power of 2.";
}
if ( bufferSize !== buffer.length ) {
throw "Supplied buffer is not the same size as defined FFT. FFT Size: " + bufferSize + " Buffer Size: " + buffer.length;
}
for ( var i = 0; i < bufferSize; i++ ) {
real[i] = buffer[reverseTable[i]];
imag[i] = 0;
}
var halfSize = 1,
phaseShiftStepReal,
phaseShiftStepImag,
currentPhaseShiftReal,
currentPhaseShiftImag,
off,
tr,
ti,
tmpReal,
i;
while ( halfSize < bufferSize ) {
phaseShiftStepReal = cosTable[halfSize];
phaseShiftStepImag = sinTable[halfSize];
currentPhaseShiftReal = 1;
currentPhaseShiftImag = 0;
for ( var fftStep = 0; fftStep < halfSize; fftStep++ ) {
i = fftStep;
while ( i < bufferSize ) {
off = i + halfSize;
tr = (currentPhaseShiftReal * real[off]) - (currentPhaseShiftImag * imag[off]);
ti = (currentPhaseShiftReal * imag[off]) + (currentPhaseShiftImag * real[off]);
real[off] = real[i] - tr;
imag[off] = imag[i] - ti;
real[i] += tr;
imag[i] += ti;
i += halfSize << 1;
}
tmpReal = currentPhaseShiftReal;
currentPhaseShiftReal = (tmpReal * phaseShiftStepReal) - (currentPhaseShiftImag * phaseShiftStepImag);
currentPhaseShiftImag = (tmpReal * phaseShiftStepImag) + (currentPhaseShiftImag * phaseShiftStepReal);
}
halfSize = halfSize << 1;
}
i = bufferSize/2;
while(i--) {
spectrum[i] = 2 * Math.sqrt(real[i] * real[i] + imag[i] * imag[i]) / bufferSize;
}
return spectrum;
};
/* end of FFT */
var testFile = "file_a4_tone.ogg";
var testFileDuration = 3.0;
var testFileChannelCount = 1;
var testFileSampleRate = 44100;
var testFileFrameBufferLength = 1024;
var signal = [{start:1.1, end: 1.9, fftBin: 10 } ];
var noSignal = [{start:0.1, end: 0.9 }, {start:2.1, end: 2.9 } ];
var undef;
var fft, fftBufferSize;
var currentSampleOffset = 0;
var spectrumMaxs = [];
var isTimePropertyValid = true;
function audioAvailable(event) {
var buffer = event.frameBuffer;
if(fft === undef) {
fftBufferSize = buffer.length;
fft = new FFT(fftBufferSize, testFileSampleRate);
}
fft.forward(buffer);
var spectrum = fft.spectrum;
// Finding pick frequency
var maxIndex = 0, maxValue = spectrum[0];
for(var i=0;i<spectrum.length;i++) {
if(maxValue < spectrum[i]) {
maxValue = spectrum[maxIndex = i];
}
}
spectrumMaxs.push({ value: maxValue, index: maxIndex, time: (currentSampleOffset / testFileSampleRate) });
if( (typeof event.time !== "number") ||
(Math.abs(event.time - currentSampleOffset / testFileSampleRate) >= 0.001) ) {
isTimePropertyValid = false;
}
currentSampleOffset += buffer.length;
}
var loadedMetadataCalled = false;
function loadedMetadata() {
loadedMetadataCalled = true;
var a1 = document.getElementById('a1');
is(a1.mozChannels, testFileChannelCount, "mozChannels should be " + testFileChannelCount + ".");
is(a1.mozSampleRate, testFileSampleRate, "mozSampleRate should be " + testFileSampleRate + ".");
is(a1.mozFrameBufferLength, testFileFrameBufferLength, "mozFrameBufferLength should be " + testFileFrameBufferLength + ".");
}
function checkResults() {
ok(loadedMetadataCalled, "loadedmetadata event not dispatched.");
ok(isTimePropertyValid, "The audioAvailable event's time attribute was invalid.");
var expectedOffset = Math.ceil(testFileDuration * testFileSampleRate);
if(expectedOffset % fftBufferSize !== 0) { expectedOffset += (fftBufferSize - (expectedOffset % fftBufferSize)); }
is(currentSampleOffset, expectedOffset, "Check amount of signal data processed");
var i, j;
var signalPresent = true;
for(i=0;i<signal.length;++i) {
var signalAnalysed = false;
for(j=0;j<spectrumMaxs.length;++j) {
if(signal[i].start <= spectrumMaxs[j].time && spectrumMaxs[j].time < signal[i].end) {
signalAnalysed = true;
signalPresent = spectrumMaxs[j].index == signal[i].fftBin;
}
if(!signalPresent) break;
}
if(!signalAnalysed) signalPresent = false;;
if(!signalPresent) break;
}
is(signalPresent, true, "Check signal present");
var noSignalPresent = true;
for(i=0;i<noSignal.length;++i) {
var signalAnalysed = false;
for(j=0;j<spectrumMaxs.length;++j) {
if(noSignal[i].start <= spectrumMaxs[j].time && spectrumMaxs[j].time < noSignal[i].end) {
signalAnalysed = true;
noSignalPresent = spectrumMaxs[j].index == 0;
}
if(!noSignalPresent) break;
}
if(!signalAnalysed) noSignalPresent = false;;
if(!noSignalPresent) break;
}
is(signalPresent, true, "Check mute fragments present");
SimpleTest.finish();
}
function audioEnded() {
checkResults();
}
function initTest() {
var a1 = document.createElement("audio");
a1.id = "a1";
a1.addEventListener("ended", audioEnded, false);
a1.addEventListener("loadedmetadata", loadedMetadata, false);
a1.addEventListener("MozAudioAvailable", audioAvailable, false);
a1.src = testFile;
a1.muted = true;
a1.play();
document.body.appendChild(a1);
}
window.addEventListener("load", function(e) {
SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]}, initTest);
}, false);
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View File

@ -1,42 +0,0 @@
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=490705
-->
<head>
<title>Media test: addEventListener optimization and adoptNode</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script>
function adopt() {
var a1Node = document.getElementById("f1").contentDocument.getElementById("a1");
var adopted = document.adoptNode(a1Node);
document.body.appendChild(adopted);
return adopted;
}
function wasAudioAvailableCalled() {
var resultNode = document.getElementById("f1").contentDocument.getElementById("wasAudioAvailableCalled");
return document.adoptNode(resultNode).checked;
}
function endTest() {
is(wasAudioAvailableCalled(), true, "audioAvailable was not called");
SimpleTest.finish();
}
function startTest() {
SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]}, function () {
var audio = adopt();
audio.addEventListener("ended", endTest, false);
audio.play();
});
}
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=490705">Mozilla Bug 490705</a>
<iframe id="f1" src="file_audio_event_adopt_iframe.html" onload="startTest()"></iframe>
</body>
</html>

View File

@ -1,79 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=490705
-->
<head>
<title>Media test: simple audio write checks</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=490705">Mozilla Bug 490705</a>
<pre id="test">
<script class="testbody" type="text/javascript">
var channels = 2;
var rate = 44100;
function runTests() {
var a1 = new Audio();
ok("mozSetup" in a1, "mozSetup should be supported");
ok("mozWriteAudio" in a1, "mozWriteAudio should be supported");
ok("mozCurrentSampleOffset" in a1, "mozCurrentSampleOffset should be supported");
try {
a1.mozSetup(channels, rate);
} catch (ex) {
todo(false, "Audio hardware is disabled, can't test audio write API");
SimpleTest.finish();
return;
}
is(a1.mozChannels, channels, "mozChannels should be " + channels + ".");
is(a1.mozSampleRate, rate, "mozSampleRate should be " + rate + ".");
is(a1.volume, 1.0, "volume should be 1.0 by default.");
// Make sure changing volume on audio changes write audio stream.
a1.volume = 0.5;
is(a1.volume, 0.5, "volume should have been changed to 0.5.");
a1.muted = true;
ok(a1.muted, "volume should be muted.");
is(a1.mozCurrentSampleOffset(), 0, "mozCurrentSampleOffset() not working.");
// Test writing with js array
var samples1 = [.5, .5];
var written = sampleOffset = a1.mozWriteAudio(samples1);
is(written, samples1.length, "Not all samples in JS Array written.");
// Test writing with Float32Array
var samples2 = new Float32Array([.2, .3, .2, .3]);
written = a1.mozWriteAudio(samples2);
is(written, samples2.length, "Not all samples in Float32Array written.");
// Test passing the wrong arguments to mozWriteAudio.
var writeArgsOK = false;
try {
// incorrect, should throw
written = a1.mozWriteAudio(samples2.length, samples2);
} catch(e) {
writeArgsOK = true;
}
ok(writeArgsOK, "mozWriteAudio args test failed.");
SimpleTest.finish();
}
window.addEventListener("load", function(e) {
SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]}, runTests);
}, false);
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View File

@ -1,47 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=686137
-->
<head>
<title>Media test: changing mozFrameBufferLength</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=686137">Mozilla Bug 686137</a>
<pre id="test">
<script class="testbody" type="text/javascript">
SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]}, function () {
var a1 = document.createElement("audio");
a1.controls = true;
a1.muted = true;
a1.preload = "metadata";
a1.addEventListener("loadedmetadata", metaDataLoaded, false);
a1.src = "bug495794.ogg";
a1.load();
});
SimpleTest.waitForExplicitFinish();
function audioAvailable(event) {
var a1 = event.target;
a1.removeEventListener("MozAudioAvailable", audioAvailable);
is( event.frameBuffer.length, 9001, "event.frameBuffer.length should be 9001.");
is( event.frameBuffer.length, a1.mozFrameBufferLength, "event.frameBuffer.length should be " + a1.mozFrameBufferLength + ".");
SimpleTest.finish();
}
function metaDataLoaded(event){
var a1 = event.target;
a1.addEventListener("MozAudioAvailable", audioAvailable, false);
a1.mozFrameBufferLength = 9001;
a1.play();
}
</script>
</pre>
</body>
</html>

View File

@ -1,112 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=490705
-->
<head>
<title>Media test: framebuffer size checks</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=490705">Mozilla Bug 490705</a>
<pre id="test">
<script class="testbody" type="text/javascript">
var testFile = "bug495794.ogg";
var testFileDuration = 0.30;
var testFileChannelCount = 6;
var testFileSampleRate = 48000;
var testFileFrameBufferLength = testFileChannelCount * 1024;
var undef;
var currentSampleOffset = 0;
var isTimePropertyValid = true;
function audioAvailable(event) {
var buffer = event.frameBuffer;
if ( (typeof event.time !== "number") ||
(Math.abs(event.time - currentSampleOffset / testFileSampleRate / testFileChannelCount) > testFileDuration) ) {
isTimePropertyValid = false;
}
currentSampleOffset += buffer.length;
}
var loadedMetadataCalled = false;
function loadedMetadata() {
loadedMetadataCalled = true;
var a1 = document.getElementById('a1');
is(a1.mozChannels, testFileChannelCount, "mozChannels should be " + testFileChannelCount + ".");
is(a1.mozSampleRate, testFileSampleRate, "mozSampleRate should be " + testFileSampleRate + ".");
is(a1.mozFrameBufferLength, testFileFrameBufferLength, "default mozFrameBufferLength should be " + testFileFrameBufferLength + ".");
var minFailed = false;
try {
a1.mozFrameBufferLength = 4;
} catch(e) {
minFailed = true;
}
ok(minFailed, "mozFrameBufferLength min fail check");
var maxFailed = false;
try {
a1.mozFrameBufferLength = 44444;
} catch(e) {
maxFailed = true;
}
ok(maxFailed, "mozFrameBufferLength max fail check");
a1.mozFrameBufferLength = testFileFrameBufferLength;
}
function checkResults() {
ok(loadedMetadataCalled, "loadedmetadata event not dispatched.");
ok(isTimePropertyValid, "The audioAvailable event's time attribute was invalid.");
var expectedOffset = Math.ceil(testFileDuration * testFileSampleRate * testFileChannelCount);
if (expectedOffset % testFileFrameBufferLength !== 0) {
expectedOffset += (testFileFrameBufferLength - (expectedOffset % testFileFrameBufferLength));
}
is(currentSampleOffset, expectedOffset, "Check amount of signal data processed");
SimpleTest.finish();
}
function audioEnded() {
checkResults();
}
function initTest() {
var a1 = document.createElement("audio");
a1.id = "a1";
a1.preload = "metadata";
a1.controls = true;
document.body.appendChild(a1);
a1.addEventListener("ended", audioEnded, false);
a1.addEventListener("loadedmetadata", loadedMetadata, false);
a1.addEventListener("MozAudioAvailable", audioAvailable, false);
a1.src = testFile;
a1.muted = true;
a1.play();
}
window.addEventListener("load", function(e) {
if (SpecialPowers.getBoolPref("media.audio_data.enabled")) {
initTest();
} else {
ok(true, "old audio data api behind a pref");
SimpleTest.finish();
}
}, false);
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View File

@ -1,54 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Wave Media test: ended</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
// Test if the ended event works correctly.
var endPassed = false;
var completed = false;
function audioavailable(e) {
if (completed)
return;
completed = true;
var samples = e.frameBuffer;
var time = e.time;
ok(samples.length >= 3, "Must be 3 or more samples. There were " + samples.length);
if (samples.length >= 3) {
ok(samples[0] > 0.99 && samples[0] < 1.01, "First sound sample should be close to 1.0. It was " + samples[0]);
ok(samples[1] > -1.01 && samples [1] < -0.99, "Second sound sample should be close to -1.0. It was " + samples[1]);
ok(samples[2] > -0.01 && samples[2] < 0.01, "Third sound sample should be close to 0. It was " + samples[2]);
}
// Only care about the first few samples
SimpleTest.finish();
}
function startTest() {
if (completed)
return;
SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]},
function () {
var v = document.getElementById('v');
v.addEventListener('MozAudioAvailable', audioavailable, false);
v.play();
});
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
<audio id='v'
preload="metadata"
onloadedmetadata='return startTest();'>
<source type='audio/x-wav' src='wavedata_s16.wav'>
</audio>
</body>
</html>

View File

@ -1,54 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Wave Media test: ended</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
// Test if the ended event works correctly.
var endPassed = false;
var completed = false;
function audioavailable(e) {
if (completed)
return;
completed = true;
var samples = e.frameBuffer;
var time = e.time;
ok(samples.length >= 3, "Must be 3 or more samples. There were " + samples.length);
if (samples.length >= 3) {
ok(samples[0] > 0.99 && samples[0] < 1.01, "First sound sample should be close to 1.0. It was " + samples[0]);
ok(samples[1] > -1.01 && samples [1] < -0.99, "Second sound sample should be close to -1.0. It was " + samples[1]);
ok(samples[2] > -0.01 && samples[2] < 0.01, "Third sound sample should be close to 0. It was " + samples[2]);
}
// Only care about the first few samples
SimpleTest.finish();
}
function startTest() {
if (completed)
return;
SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]},
function () {
var v = document.getElementById('v');
v.addEventListener('MozAudioAvailable', audioavailable, false);
v.play();
});
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
<audio id='v'
preload="metadata"
onloadedmetadata='return startTest();'>
<source type='audio/x-wav' src='wavedata_u8.wav'>
</audio>
</body>
</html>

View File

@ -13441,16 +13441,6 @@ nsGlobalModalWindow::SetReturnValue(nsIVariant *aRetVal)
return NS_OK;
}
void
nsGlobalWindow::SetHasAudioAvailableEventListeners()
{
MOZ_ASSERT(IsInnerWindow());
if (mDoc) {
mDoc->NotifyAudioAvailableListener();
}
}
NS_IMETHODIMP
nsGlobalWindow::GetConsole(JSContext* aCx,
JS::MutableHandle<JS::Value> aConsole)

View File

@ -547,9 +547,6 @@ public:
void DisableDialogs();
bool AreDialogsEnabled();
// Inner windows only.
virtual void SetHasAudioAvailableEventListeners();
nsIScriptContext *GetContextInternal()
{
if (mOuterWindow) {

View File

@ -472,12 +472,6 @@ public:
*/
virtual nsresult SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust) = 0;
/**
* Call this to indicate that some node (this window, its document,
* or content in that document) has a "MozAudioAvailable" event listener.
*/
virtual void SetHasAudioAvailableEventListeners() = 0;
/**
* Call this to check whether some node (this window, its document,
* or content in that document) has a mouseenter/leave event listener.

View File

@ -816,8 +816,6 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
return NS_NewDOMScrollAreaEvent(aDOMEvent, aOwner, aPresContext, nullptr);
if (aEventType.LowerCaseEqualsLiteral("popstateevent"))
return NS_NewDOMPopStateEvent(aDOMEvent, aOwner, aPresContext, nullptr);
if (aEventType.LowerCaseEqualsLiteral("mozaudioavailableevent"))
return NS_NewDOMAudioAvailableEvent(aDOMEvent, aOwner, aPresContext, nullptr);
if (aEventType.LowerCaseEqualsLiteral("closeevent"))
return NS_NewDOMCloseEvent(aDOMEvent, aOwner, aPresContext, nullptr);
if (aEventType.LowerCaseEqualsLiteral("touchevent") &&

View File

@ -92,7 +92,6 @@ EventListenerManager::EventListenerManager(EventTarget* aTarget)
, mMayHaveMutationListeners(false)
, mMayHaveCapturingListeners(false)
, mMayHaveSystemGroupListeners(false)
, mMayHaveAudioAvailableEventListener(false)
, mMayHaveTouchEventListener(false)
, mMayHaveMouseEnterLeaveEventListener(false)
, mMayHavePointerEnterLeaveEventListener(false)
@ -282,12 +281,6 @@ EventListenerManager::AddEventListenerInternal(
if (window) {
window->SetHasPaintEventListeners();
}
} else if (aType == NS_MOZAUDIOAVAILABLE) {
mMayHaveAudioAvailableEventListener = true;
nsPIDOMWindow* window = GetInnerWindowForTarget();
if (window) {
window->SetHasAudioAvailableEventListeners();
}
} else if (aType >= NS_MUTATION_START && aType <= NS_MUTATION_END) {
// For mutation listeners, we need to update the global bit on the DOM window.
// Otherwise we won't actually fire the mutation event.

View File

@ -386,12 +386,6 @@ public:
*/
bool MayHavePaintEventListener() { return mMayHavePaintEventListener; }
/**
* Returns true if there may be a MozAudioAvailable event listener registered,
* false if there definitely isn't.
*/
bool MayHaveAudioAvailableEventListener() { return mMayHaveAudioAvailableEventListener; }
/**
* Returns true if there may be a touch event listener registered,
* false if there definitely isn't.
@ -543,13 +537,12 @@ protected:
uint32_t mMayHaveMutationListeners : 1;
uint32_t mMayHaveCapturingListeners : 1;
uint32_t mMayHaveSystemGroupListeners : 1;
uint32_t mMayHaveAudioAvailableEventListener : 1;
uint32_t mMayHaveTouchEventListener : 1;
uint32_t mMayHaveMouseEnterLeaveEventListener : 1;
uint32_t mMayHavePointerEnterLeaveEventListener : 1;
uint32_t mClearingListeners : 1;
uint32_t mIsMainThreadELM : 1;
uint32_t mNoListenerForEvent : 22;
uint32_t mNoListenerForEvent : 23;
nsAutoTObserverArray<Listener, 2> mListeners;
dom::EventTarget* mTarget; // WEAK

View File

@ -790,10 +790,6 @@ NON_IDL_EVENT(repeatEvent,
EventNameType_None,
NS_SMIL_TIME_EVENT)
NON_IDL_EVENT(MozAudioAvailable,
NS_MOZAUDIOAVAILABLE,
EventNameType_None,
NS_EVENT)
NON_IDL_EVENT(MozAfterPaint,
NS_AFTERPAINT,
EventNameType_None,

View File

@ -1,184 +0,0 @@
/* -*- 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/. */
#include "mozilla/dom/NotifyAudioAvailableEvent.h"
#include "mozilla/HoldDropJSObjects.h"
#include "nsError.h"
#include "jsfriendapi.h"
namespace mozilla {
namespace dom {
NotifyAudioAvailableEvent::NotifyAudioAvailableEvent(
EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetEvent* aEvent,
uint32_t aEventType,
float* aFrameBuffer,
uint32_t aFrameBufferLength,
float aTime)
: Event(aOwner, aPresContext, aEvent)
, mFrameBuffer(aFrameBuffer)
, mFrameBufferLength(aFrameBufferLength)
, mTime(aTime)
, mCachedArray(nullptr)
, mAllowAudioData(false)
{
MOZ_COUNT_CTOR(NotifyAudioAvailableEvent);
if (mEvent) {
mEvent->message = aEventType;
}
}
NS_IMPL_ADDREF_INHERITED(NotifyAudioAvailableEvent, Event)
NS_IMPL_RELEASE_INHERITED(NotifyAudioAvailableEvent, Event)
NS_IMPL_CYCLE_COLLECTION_CLASS(NotifyAudioAvailableEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(NotifyAudioAvailableEvent,
Event)
if (tmp->mCachedArray) {
tmp->mCachedArray = nullptr;
DropJSObjects(tmp);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(NotifyAudioAvailableEvent,
Event)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(NotifyAudioAvailableEvent,
Event)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCachedArray)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(NotifyAudioAvailableEvent)
NS_INTERFACE_MAP_ENTRY(nsIDOMNotifyAudioAvailableEvent)
NS_INTERFACE_MAP_END_INHERITING(Event)
NotifyAudioAvailableEvent::~NotifyAudioAvailableEvent()
{
MOZ_COUNT_DTOR(NotifyAudioAvailableEvent);
if (mCachedArray) {
mCachedArray = nullptr;
mozilla::DropJSObjects(this);
}
}
NS_IMETHODIMP
NotifyAudioAvailableEvent::GetFrameBuffer(JSContext* aCx,
JS::MutableHandle<JS::Value> aResult)
{
if (!mAllowAudioData) {
// Media is not same-origin, don't allow the data out.
return NS_ERROR_DOM_SECURITY_ERR;
}
if (mCachedArray) {
aResult.setObject(*mCachedArray);
return NS_OK;
}
// Cache this array so we don't recreate on next call.
mozilla::HoldJSObjects(this);
mCachedArray = JS_NewFloat32Array(aCx, mFrameBufferLength);
if (!mCachedArray) {
mozilla::DropJSObjects(this);
return NS_ERROR_FAILURE;
}
memcpy(JS_GetFloat32ArrayData(mCachedArray), mFrameBuffer.get(),
mFrameBufferLength * sizeof(float));
aResult.setObject(*mCachedArray);
return NS_OK;
}
NS_IMETHODIMP
NotifyAudioAvailableEvent::GetTime(float* aRetVal)
{
*aRetVal = Time();
return NS_OK;
}
NS_IMETHODIMP
NotifyAudioAvailableEvent::InitAudioAvailableEvent(const nsAString& aType,
bool aCanBubble,
bool aCancelable,
float* aFrameBuffer,
uint32_t aFrameBufferLength,
float aTime,
bool aAllowAudioData)
{
// Auto manage the memory which stores the frame buffer. This ensures
// that if we exit due to some error, the memory will be freed. Otherwise,
// the framebuffer's memory will be freed when this event is destroyed.
nsAutoArrayPtr<float> frameBuffer(aFrameBuffer);
nsresult rv = Event::InitEvent(aType, aCanBubble, aCancelable);
NS_ENSURE_SUCCESS(rv, rv);
mFrameBuffer = frameBuffer.forget();
mFrameBufferLength = aFrameBufferLength;
mTime = aTime;
mAllowAudioData = aAllowAudioData;
mCachedArray = nullptr;
return NS_OK;
}
void
NotifyAudioAvailableEvent::InitAudioAvailableEvent(
const nsAString& aType,
bool aCanBubble,
bool aCancelable,
const Nullable<Sequence<float> >& aFrameBuffer,
uint32_t aFrameBufferLength,
float aTime,
bool aAllowAudioData,
ErrorResult& aRv)
{
if ((aFrameBuffer.IsNull() && aFrameBufferLength > 0) ||
(!aFrameBuffer.IsNull() &&
aFrameBuffer.Value().Length() < aFrameBufferLength)) {
aRv = NS_ERROR_UNEXPECTED;
return;
}
nsAutoArrayPtr<float> buffer;
if (!aFrameBuffer.IsNull()) {
buffer = new float[aFrameBufferLength];
memcpy(buffer.get(), aFrameBuffer.Value().Elements(),
aFrameBufferLength * sizeof(float));
}
aRv = InitAudioAvailableEvent(aType, aCanBubble, aCancelable,
buffer.forget(),
aFrameBufferLength,
aTime, aAllowAudioData);
}
} // namespace dom
} // namespace mozilla
using namespace mozilla;
using namespace mozilla::dom;
nsresult
NS_NewDOMAudioAvailableEvent(nsIDOMEvent** aInstancePtrResult,
EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetEvent* aEvent,
uint32_t aEventType,
float* aFrameBuffer,
uint32_t aFrameBufferLength,
float aTime)
{
NotifyAudioAvailableEvent* it =
new NotifyAudioAvailableEvent(aOwner, aPresContext, aEvent, aEventType,
aFrameBuffer, aFrameBufferLength, aTime);
NS_ADDREF(it);
*aInstancePtrResult = static_cast<Event*>(it);
return NS_OK;
}

View File

@ -1,78 +0,0 @@
/* -*- 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 mozilla_dom_NotifyAudioAvailableEvent_h_
#define mozilla_dom_NotifyAudioAvailableEvent_h_
#include "mozilla/dom/Event.h"
#include "mozilla/dom/NotifyAudioAvailableEventBinding.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIDOMNotifyAudioAvailableEvent.h"
class nsPresContext;
namespace mozilla {
namespace dom {
class NotifyAudioAvailableEvent : public Event,
public nsIDOMNotifyAudioAvailableEvent
{
public:
NotifyAudioAvailableEvent(EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetEvent* aEvent,
uint32_t aEventType,
float* aFrameBuffer,
uint32_t aFrameBufferLength,
float aTime);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
NotifyAudioAvailableEvent, Event)
NS_DECL_NSIDOMNOTIFYAUDIOAVAILABLEEVENT
NS_FORWARD_NSIDOMEVENT(Event::)
~NotifyAudioAvailableEvent();
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE
{
return NotifyAudioAvailableEventBinding::Wrap(aCx, aScope, this);
}
JSObject* GetFrameBuffer(JSContext* aCx, ErrorResult& aRv)
{
JS::Rooted<JS::Value> dummy(aCx);
aRv = GetFrameBuffer(aCx, &dummy);
return mCachedArray;
}
float Time()
{
return mTime;
}
void InitAudioAvailableEvent(const nsAString& aType,
bool aCanBubble,
bool aCancelable,
const Nullable<Sequence<float> >& aFrameBuffer,
uint32_t aFrameBufferLength,
float aTime,
bool aAllowAudioData,
ErrorResult& aRv);
private:
nsAutoArrayPtr<float> mFrameBuffer;
uint32_t mFrameBufferLength;
float mTime;
JS::Heap<JSObject*> mCachedArray;
bool mAllowAudioData;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_NotifyAudioAvailableEvent_h_

View File

@ -49,7 +49,6 @@ EXPORTS.mozilla.dom += [
'MouseEvent.h',
'MouseScrollEvent.h',
'MutationEvent.h',
'NotifyAudioAvailableEvent.h',
'NotifyPaintEvent.h',
'PointerEvent.h',
'ScrollAreaEvent.h',
@ -92,7 +91,6 @@ UNIFIED_SOURCES += [
'MouseEvent.cpp',
'MouseScrollEvent.cpp',
'MutationEvent.cpp',
'NotifyAudioAvailableEvent.cpp',
'NotifyPaintEvent.cpp',
'nsPaintRequest.cpp',
'PointerEvent.cpp',

View File

@ -118,7 +118,6 @@ skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
skip-if = toolkit == 'android'
[test_bug742376.html]
[test_bug812744.html]
[test_bug847597.html]
[test_bug855741.html]
[test_bug864040.html]
skip-if = buildapp == 'b2g' # b2g(failing when the test gets moved around, and on debug) b2g-debug(failing when the test gets moved around, and on debug) b2g-desktop(failing when the test gets moved around, and on debug)

View File

@ -282,14 +282,6 @@ const kEventConstructors = {
return e;
},
},
NotifyAudioAvailableEvent: { create: function (aName, aProps) {
var e = document.createEvent("mozaudioavailableevent");
e.initAudioAvailableEvent(aName, aProps.bubbles, aProps.cancelable,
aProps.frameBuffer, aProps.frameBufferLength,
aProps.time || 0.0, aProps.allowAudioData);
return e;
},
},
NotifyPaintEvent: { create: function (aName, aProps) {
var e = document.createEvent("notifypaintevent");
e.initEvent(aName, aProps.bubbles, aProps.cancelable);

View File

@ -1,81 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=847597
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 847597</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 847597 **/
var e = document.createEvent("mozaudioavailableevent");
e.initAudioAvailableEvent("foo", true, true, [1], 1, 123456, false);
is(e.type, "foo");
is(e.bubbles, true);
is(e.cancelable, true);
is(e.time, 123456);
try {
e.frameBuffer;
ok(false, "Should not be possible to access frameBuffer in unsafe context when the last parameter to init is false.");
} catch(ex) {
ok(true);
}
try {
e.initAudioAvailableEvent("foo", true, true, [1, 2, 3], 4, 123456, false);
ok(false, "Should have thrown an exception because too short array");
} catch(ex) {
ok(true);
}
try {
e.initAudioAvailableEvent("foo", true, true, [], 1, 123456, false);
ok(false, "Should have thrown an exception because too short array");
} catch(ex) {
ok(true);
}
try {
e.initAudioAvailableEvent("foo", true, true, null, 1, 123456, false);
ok(false, "Should have thrown an exception because too short array");
} catch(ex) {
ok(true);
}
e.initAudioAvailableEvent("foo", true, true, null, 0, 123456, false);
e.initAudioAvailableEvent("foo", true, true, [], 0, 123456, false);
e.initAudioAvailableEvent("foo", true, true, [1], 0, 123456, false);
e.initAudioAvailableEvent("foo", true, true, [0, 1, 2], 0, 123456, true);
is(e.frameBuffer.length, 0);
e.initAudioAvailableEvent("foo", true, true, [0, 1, 2], 1, 123456, true);
is(e.frameBuffer.length, 1);
is(e.frameBuffer[0], 0);
e.initAudioAvailableEvent("foo", true, true, [0, 1, 2], 2, 123456, true);
is(e.frameBuffer.length, 2);
is(e.frameBuffer[0], 0);
is(e.frameBuffer[1], 1);
e.initAudioAvailableEvent("foo", true, true, [0, 1, 2], 3, 123456, true);
is(e.frameBuffer.length, 3);
is(e.frameBuffer[0], 0);
is(e.frameBuffer[1], 1);
is(e.frameBuffer[2], 2);
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=847597">Mozilla Bug 847597</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -28,7 +28,6 @@ XPIDL_SOURCES += [
'nsIDOMMouseEvent.idl',
'nsIDOMMouseScrollEvent.idl',
'nsIDOMMutationEvent.idl',
'nsIDOMNotifyAudioAvailableEvent.idl',
'nsIDOMNotifyPaintEvent.idl',
'nsIDOMNSEvent.idl',
'nsIDOMPageTransitionEvent.idl',

View File

@ -337,15 +337,6 @@ NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult,
uint32_t aEventType = 0,
nsInvalidateRequestList* aInvalidateRequests = nullptr);
nsresult
NS_NewDOMAudioAvailableEvent(nsIDOMEvent** aResult,
mozilla::dom::EventTarget* aOwner,
nsPresContext* aPresContext,
mozilla::WidgetEvent* aEvent,
uint32_t aEventType = 0,
float* aFrameBuffer = nullptr,
uint32_t aFrameBufferLength = 0,
float aTime = 0);
nsresult
NS_NewDOMSimpleGestureEvent(nsIDOMEvent** aInstancePtrResult,
mozilla::dom::EventTarget* aOwner,
nsPresContext* aPresContext,

View File

@ -1,25 +0,0 @@
/* -*- 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/. */
#include "nsIDOMEvent.idl"
#include "nsIVariant.idl"
[scriptable, builtinclass, uuid(2345d43d-197a-4589-a4b7-983b41b76c25)]
interface nsIDOMNotifyAudioAvailableEvent : nsIDOMEvent
{
[implicit_jscontext]
readonly attribute jsval frameBuffer;
readonly attribute float time;
void initAudioAvailableEvent(in DOMString typeArg,
in boolean canBubbleArg,
in boolean cancelableArg,
[array, size_is(frameBufferLength)] in float frameBufferPtr,
in unsigned long frameBufferLength,
in float time,
in boolean allowAudioData);
};

View File

@ -27,7 +27,7 @@ interface nsIDOMMediaStream;
#endif
%}
[scriptable, uuid(d83d38f3-68b9-4ea2-8748-1cc738d74333)]
[scriptable, uuid(1f9393e8-2df0-4072-87b9-c26999b09acc)]
interface nsIDOMHTMLMediaElement : nsISupports
{
// error state
@ -84,16 +84,6 @@ interface nsIDOMHTMLMediaElement : nsISupports
nsIDOMMediaStream mozCaptureStreamUntilEnded();
readonly attribute boolean mozAudioCaptured;
// Mozilla extension: extra stream metadata information, used as part
// of MozAudioAvailable events and the mozWriteAudio() method. The
// mozFrameBufferLength method allows for the size of the framebuffer
// used within MozAudioAvailable events to be changed. The new size must
// be between 512 and 16384. The default size, for a media element with
// audio is (mozChannels * 1024).
readonly attribute unsigned long mozChannels;
readonly attribute unsigned long mozSampleRate;
attribute unsigned long mozFrameBufferLength;
// Mozilla extension: return embedded metadata from the stream as a
// JSObject with key:value pairs for each tag. This can be used by
// player interfaces to display the song title, artist, etc.

View File

@ -121,8 +121,6 @@ PluginHangUIStopButton=Stop plugin
PrefixedVisibilityApiWarning='mozHidden' and 'mozVisibilityState' are deprecated. Please use the unprefixed 'hidden' and 'visibilityState' instead.
# LOCALIZATION NOTE: Do not translate "NodeIterator" or "detach()".
NodeIteratorDetachWarning=Calling detach() on a NodeIterator no longer has an effect.
# LOCALIZATION NOTE: Do not translate "Mozilla Audio Data API" and "Web Audio API".
MozAudioDataWarning=The Mozilla Audio Data API is deprecated. Please use the Web Audio API instead.
# LOCALIZATION NOTE: Do not translate "LenientThis" and "this"
LenientThisWarning=Ignoring get or set of property that has [LenientThis] because the "this" object is incorrect.
# LOCALIZATION NOTE: Do not translate "nsIDOMWindowUtils", "getWindowWithOuterId", or "nsIWindowMediator"

View File

@ -713,8 +713,6 @@ var interfaceNamesInGlobalScope =
"NodeIterator",
// IMPORTANT: Do not change this list without review from a DOM peer!
"NodeList",
// IMPORTANT: Do not change this list without review from a DOM peer!
"NotifyAudioAvailableEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"Notification",
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -14,20 +14,3 @@
[NamedConstructor=Audio(optional DOMString src)]
interface HTMLAudioElement : HTMLMediaElement {};
partial interface HTMLAudioElement
{
// Setup the audio stream for writing
[Pref="media.audio_data.enabled", Throws]
void mozSetup(unsigned long channels, unsigned long rate);
// Write audio to the audio stream
[Pref="media.audio_data.enabled", Throws]
unsigned long mozWriteAudio(Float32Array data);
[Pref="media.audio_data.enabled", Throws]
unsigned long mozWriteAudio(sequence<unrestricted float> data);
// Get the current offset (measured in samples since the start) of the audio
// stream created using mozWriteAudio().
[Pref="media.audio_data.enabled", Throws]
unsigned long long mozCurrentSampleOffset();
};

View File

@ -109,19 +109,6 @@ partial interface HTMLMediaElement {
MediaStream mozCaptureStreamUntilEnded();
readonly attribute boolean mozAudioCaptured;
// Mozilla extension: extra stream metadata information, used as part
// of MozAudioAvailable events and the mozWriteAudio() method. The
// mozFrameBufferLength method allows for the size of the framebuffer
// used within MozAudioAvailable events to be changed. The new size must
// be between 512 and 16384. The default size, for a media element with
// audio is (mozChannels * 1024).
[Pref="media.audio_data.enabled", GetterThrows]
readonly attribute unsigned long mozChannels;
[Pref="media.audio_data.enabled", GetterThrows]
readonly attribute unsigned long mozSampleRate;
[Pref="media.audio_data.enabled", Throws]
attribute unsigned long mozFrameBufferLength;
// Mozilla extension: return embedded metadata from the stream as a
// JSObject with key:value pairs for each tag. This can be used by
// player interfaces to display the song title, artist, etc.

View File

@ -1,22 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*/
interface NotifyAudioAvailableEvent : Event
{
[Throws]
readonly attribute Float32Array frameBuffer;
readonly attribute float time;
[Throws]
void initAudioAvailableEvent(DOMString type,
boolean canBubble,
boolean cancelable,
sequence<float>? frameBuffer,
unsigned long frameBufferLength,
float time,
boolean allowAudioData);
};

View File

@ -257,7 +257,6 @@ WEBIDL_FILES = [
'NodeIterator.webidl',
'NodeList.webidl',
'Notification.webidl',
'NotifyAudioAvailableEvent.webidl',
'NotifyPaintEvent.webidl',
'OfflineAudioCompletionEvent.webidl',
'OfflineAudioContext.webidl',

View File

@ -121,8 +121,6 @@ PluginHangUIStopButton=Stop plugin
PrefixedVisibilityApiWarning='mozHidden' and 'mozVisibilityState' are deprecated. Please use the unprefixed 'hidden' and 'visibilityState' instead.
# LOCALIZATION NOTE: Do not translate "NodeIterator" or "detach()".
NodeIteratorDetachWarning=Calling detach() on a NodeIterator no longer has an effect.
# LOCALIZATION NOTE: Do not translate "Mozilla Audio Data API" and "Web Audio API".
MozAudioDataWarning=The Mozilla Audio Data API is deprecated. Please use the Web Audio API instead.
# LOCALIZATION NOTE: Do not translate "LenientThis" and "this"
LenientThisWarning=Ignoring get or set of property that has [LenientThis] because the "this" object is incorrect.
# LOCALIZATION NOTE: Do not translate "nsIDOMWindowUtils", "getWindowWithOuterId", or "nsIWindowMediator"

View File

@ -318,7 +318,6 @@ enum nsEventStructType
#define NS_RATECHANGE (NS_MEDIA_EVENT_START+17)
#define NS_DURATIONCHANGE (NS_MEDIA_EVENT_START+18)
#define NS_VOLUMECHANGE (NS_MEDIA_EVENT_START+19)
#define NS_MOZAUDIOAVAILABLE (NS_MEDIA_EVENT_START+20)
// paint notification events
#define NS_NOTIFYPAINT_START 3400