author | Ehsan Akhgari <ehsan@mozilla.com> |
Thu, 25 Jul 2013 15:01:49 +1200 | |
changeset 141610 | 27f3845226754750f69e1c5b63ed985ea0276b18 |
parent 141609 | 11b2cd90a51ae9e1c1d2f8e610a681b07b9bcc6e |
child 141611 | e14729d47ea8ff0b0d24cac7d6f418106cdf35d0 |
push id | 32157 |
push user | rocallahan@mozilla.com |
push date | Wed, 07 Aug 2013 02:31:51 +0000 |
treeherder | mozilla-inbound@91f4bd08f12b [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 855568 |
milestone | 26.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -3,24 +3,26 @@ /* 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 "AudioContext.h" #include "nsContentUtils.h" #include "nsPIDOMWindow.h" #include "mozilla/ErrorResult.h" +#include "mozilla/dom/AnalyserNode.h" #include "mozilla/dom/AudioContextBinding.h" +#include "mozilla/dom/HTMLMediaElement.h" #include "mozilla/dom/OfflineAudioContextBinding.h" #include "MediaStreamGraph.h" -#include "mozilla/dom/AnalyserNode.h" #include "AudioDestinationNode.h" #include "AudioBufferSourceNode.h" #include "AudioBuffer.h" #include "GainNode.h" +#include "MediaElementAudioSourceNode.h" #include "MediaStreamAudioSourceNode.h" #include "DelayNode.h" #include "PannerNode.h" #include "AudioListener.h" #include "DynamicsCompressorNode.h" #include "BiquadFilterNode.h" #include "ScriptProcessorNode.h" #include "ChannelMergerNode.h" @@ -249,25 +251,43 @@ AudioContext::CreateScriptProcessor(uint already_AddRefed<AnalyserNode> AudioContext::CreateAnalyser() { nsRefPtr<AnalyserNode> analyserNode = new AnalyserNode(this); return analyserNode.forget(); } +already_AddRefed<MediaElementAudioSourceNode> +AudioContext::CreateMediaElementSource(HTMLMediaElement& aMediaElement, + ErrorResult& aRv) +{ + if (mIsOffline) { + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return nullptr; + } + nsRefPtr<DOMMediaStream> stream = aMediaElement.MozCaptureStream(aRv); + if (aRv.Failed()) { + return nullptr; + } + nsRefPtr<MediaElementAudioSourceNode> mediaElementAudioSourceNode = + new MediaElementAudioSourceNode(this, stream); + return mediaElementAudioSourceNode.forget(); +} + already_AddRefed<MediaStreamAudioSourceNode> AudioContext::CreateMediaStreamSource(DOMMediaStream& aMediaStream, ErrorResult& aRv) { if (mIsOffline) { aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return nullptr; } - nsRefPtr<MediaStreamAudioSourceNode> mediaStreamAudioSourceNode = new MediaStreamAudioSourceNode(this, &aMediaStream); + nsRefPtr<MediaStreamAudioSourceNode> mediaStreamAudioSourceNode = + new MediaStreamAudioSourceNode(this, &aMediaStream); return mediaStreamAudioSourceNode.forget(); } already_AddRefed<GainNode> AudioContext::CreateGain() { nsRefPtr<GainNode> gainNode = new GainNode(this); return gainNode.forget();
--- a/content/media/webaudio/AudioContext.h +++ b/content/media/webaudio/AudioContext.h @@ -47,16 +47,18 @@ class AudioListener; class BiquadFilterNode; class ChannelMergerNode; class ChannelSplitterNode; class ConvolverNode; class DelayNode; class DynamicsCompressorNode; class GainNode; class GlobalObject; +class HTMLMediaElement; +class MediaElementAudioSourceNode; class MediaStreamAudioDestinationNode; class MediaStreamAudioSourceNode; class OfflineRenderSuccessCallback; class PannerNode; class ScriptProcessorNode; class WaveShaperNode; class PeriodicWave; @@ -157,16 +159,18 @@ public: CreateWaveShaper(); already_AddRefed<GainNode> CreateGainNode() { return CreateGain(); } + already_AddRefed<MediaElementAudioSourceNode> + CreateMediaElementSource(HTMLMediaElement& aMediaElement, ErrorResult& aRv); already_AddRefed<MediaStreamAudioSourceNode> CreateMediaStreamSource(DOMMediaStream& aMediaStream, ErrorResult& aRv); already_AddRefed<DelayNode> CreateDelay(double aMaxDelayTime, ErrorResult& aRv); already_AddRefed<DelayNode> CreateDelayNode(double aMaxDelayTime, ErrorResult& aRv)
new file mode 100644 --- /dev/null +++ b/content/media/webaudio/MediaElementAudioSourceNode.cpp @@ -0,0 +1,27 @@ +/* -*- 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 "MediaElementAudioSourceNode.h" +#include "mozilla/dom/MediaElementAudioSourceNodeBinding.h" +#include "mozilla/dom/HTMLMediaElement.h" + +namespace mozilla { +namespace dom { + +MediaElementAudioSourceNode::MediaElementAudioSourceNode(AudioContext* aContext, + DOMMediaStream* aStream) + : MediaStreamAudioSourceNode(aContext, aStream) +{ +} + +JSObject* +MediaElementAudioSourceNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) +{ + return MediaElementAudioSourceNodeBinding::Wrap(aCx, aScope, this); +} + +} +}
new file mode 100644 --- /dev/null +++ b/content/media/webaudio/MediaElementAudioSourceNode.h @@ -0,0 +1,29 @@ +/* -*- 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 MediaElementAudioSourceNode_h_ +#define MediaElementAudioSourceNode_h_ + +#include "MediaStreamAudioSourceNode.h" + +namespace mozilla { +namespace dom { + +class HTMLMediaElement; + +class MediaElementAudioSourceNode : public MediaStreamAudioSourceNode +{ +public: + MediaElementAudioSourceNode(AudioContext* aContext, + DOMMediaStream* aStream); + + virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE; +}; + +} +} + +#endif
--- a/content/media/webaudio/moz.build +++ b/content/media/webaudio/moz.build @@ -34,16 +34,17 @@ EXPORTS.mozilla.dom += [ 'BiquadFilterNode.h', 'ChannelMergerNode.h', 'ChannelSplitterNode.h', 'ConvolverNode.h', 'DelayNode.h', 'DynamicsCompressorNode.h', 'EnableWebAudioCheck.h', 'GainNode.h', + 'MediaElementAudioSourceNode.h', 'MediaStreamAudioDestinationNode.h', 'MediaStreamAudioSourceNode.h', 'OfflineAudioCompletionEvent.h', 'PannerNode.h', 'PeriodicWave.h', 'ScriptProcessorNode.h', 'WaveShaperNode.h', ] @@ -62,16 +63,17 @@ CPP_SOURCES += [ 'ChannelMergerNode.cpp', 'ChannelSplitterNode.cpp', 'ConvolverNode.cpp', 'DelayNode.cpp', 'DynamicsCompressorNode.cpp', 'EnableWebAudioCheck.cpp', 'GainNode.cpp', 'MediaBufferDecoder.cpp', + 'MediaElementAudioSourceNode.cpp', 'MediaStreamAudioDestinationNode.cpp', 'MediaStreamAudioSourceNode.cpp', 'OfflineAudioCompletionEvent.cpp', 'PannerNode.cpp', 'PeriodicWave.cpp', 'ScriptProcessorNode.cpp', 'ThreeDPoint.cpp', 'WaveShaperNode.cpp',
--- a/content/media/webaudio/test/Makefile.in +++ b/content/media/webaudio/test/Makefile.in @@ -62,16 +62,17 @@ MOCHITEST_FILES := \ test_delayNode.html \ test_delayNodeSmallMaxDelay.html \ test_delayNodeWithGain.html \ test_dynamicsCompressorNode.html \ test_gainNode.html \ test_gainNodeInLoop.html \ test_maxChannelCount.html \ test_mediaDecoding.html \ + test_mediaElementAudioSourceNode.html \ test_mediaStreamAudioDestinationNode.html \ test_mediaStreamAudioSourceNode.html \ test_mediaStreamAudioSourceNodeCrossOrigin.html \ test_mediaStreamAudioSourceNodeResampling.html \ test_mixingRules.html \ test_nodeToParamConnection.html \ test_OfflineAudioContext.html \ test_offlineDestinationChannelCountLess.html \
new file mode 100644 --- /dev/null +++ b/content/media/webaudio/test/test_mediaElementAudioSourceNode.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML> +<html> +<meta charset="utf-8"> +<head> + <title>Test MediaElementAudioSourceNode</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"> +SimpleTest.waitForExplicitFinish(); + +var audio = new Audio("small-shot.ogg"); +var context = new AudioContext(); +var node = context.createMediaElementSource(audio); +var sp = context.createScriptProcessor(2048, 1); +node.connect(sp); +var expectedMinNonzeroSampleCount; +var expectedMaxNonzeroSampleCount; +var nonzeroSampleCount = 0; +var complete = false; +var iterationCount = 0; + +// This test ensures we receive at least expectedSampleCount nonzero samples +function processSamples(e) { + if (complete) { + return; + } + + if (iterationCount == 0) { + // Don't start playing the audio until the AudioContext stuff is connected + // and running. + audio.play(); + } + ++iterationCount; + + var buf = e.inputBuffer.getChannelData(0); + var nonzeroSamplesThisBuffer = 0; + for (var i = 0; i < buf.length; ++i) { + if (buf[i] != 0) { + ++nonzeroSamplesThisBuffer; + } + } + nonzeroSampleCount += nonzeroSamplesThisBuffer; + is(e.inputBuffer.numberOfChannels, 1, + "Checking data channel count (nonzeroSamplesThisBuffer=" + + nonzeroSamplesThisBuffer + ")"); + ok(nonzeroSampleCount <= expectedMaxNonzeroSampleCount, + "Too many nonzero samples (got " + nonzeroSampleCount + ", expected max " + expectedMaxNonzeroSampleCount + ")"); + if (nonzeroSampleCount >= expectedMinNonzeroSampleCount && + nonzeroSamplesThisBuffer == 0) { + ok(true, + "Check received enough nonzero samples (got " + nonzeroSampleCount + ", expected min " + expectedMinNonzeroSampleCount + ")"); + SimpleTest.finish(); + complete = true; + } +} + +audio.oncanplaythrough = function() { + // Use a fuzz factor of 100 to account for samples that just happen to be zero + expectedMinNonzeroSampleCount = Math.floor(audio.duration*context.sampleRate) - 100; + expectedMaxNonzeroSampleCount = Math.floor(audio.duration*context.sampleRate) + 500; + sp.onaudioprocess = processSamples; +}; +</script> +</pre> +</body> +</html>
--- a/dom/webidl/AudioContext.webidl +++ b/dom/webidl/AudioContext.webidl @@ -38,16 +38,18 @@ interface AudioContext : EventTarget { [Creator, Throws] ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize = 0, optional unsigned long numberOfInputChannels = 2, optional unsigned long numberOfOutputChannels = 2); [Creator] AnalyserNode createAnalyser(); [Creator, Throws] + MediaElementAudioSourceNode createMediaElementSource(HTMLMediaElement mediaElement); + [Creator, Throws] MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream); [Creator] GainNode createGain(); [Creator, Throws] DelayNode createDelay(optional double maxDelayTime = 1); [Creator] BiquadFilterNode createBiquadFilter(); [Creator]
new file mode 100644 --- /dev/null +++ b/dom/webidl/MediaElementAudioSourceNode.webidl @@ -0,0 +1,17 @@ +/* -*- 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/. + * + * The origin of this IDL file is + * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +[PrefControlled] +interface MediaElementAudioSourceNode : AudioNode { + +}; +
--- a/dom/webidl/WebIDL.mk +++ b/dom/webidl/WebIDL.mk @@ -178,16 +178,17 @@ webidl_files = \ ImageData.webidl \ ImageDocument.webidl \ InspectorUtils.webidl \ KeyboardEvent.webidl \ KeyEvent.webidl \ LinkStyle.webidl \ LocalMediaStream.webidl \ Location.webidl \ + MediaElementAudioSourceNode.webidl \ MediaError.webidl \ MediaRecorder.webidl \ MediaSource.webidl \ MediaStream.webidl \ MediaStreamAudioDestinationNode.webidl \ MediaStreamAudioSourceNode.webidl \ MediaStreamEvent.webidl \ MediaStreamTrack.webidl \