diff --git a/content/media/webaudio/AudioContext.cpp b/content/media/webaudio/AudioContext.cpp index 825685f668a..5cb293f8ef7 100644 --- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -430,22 +430,29 @@ AudioContext::DecodeAudioData(const ArrayBuffer& aBuffer, DecodeSuccessCallback& aSuccessCallback, const Optional >& aFailureCallback) { + AutoJSAPI jsapi; + JSContext* cx = jsapi.cx(); + JSAutoCompartment ac(cx, aBuffer.Obj()); + + // Neuter the array buffer + size_t length = aBuffer.Length(); + JS::RootedObject obj(cx, aBuffer.Obj()); + + uint8_t* data = static_cast(JS_StealArrayBufferContents(cx, obj)); + // Sniff the content of the media. // Failed type sniffing will be handled by AsyncDecodeMedia. nsAutoCString contentType; - NS_SniffContent(NS_DATA_SNIFFER_CATEGORY, nullptr, - aBuffer.Data(), aBuffer.Length(), - contentType); + NS_SniffContent(NS_DATA_SNIFFER_CATEGORY, nullptr, data, length, contentType); nsRefPtr failureCallback; if (aFailureCallback.WasPassed()) { failureCallback = &aFailureCallback.Value(); } nsRefPtr job( - new WebAudioDecodeJob(contentType, this, aBuffer, + new WebAudioDecodeJob(contentType, this, &aSuccessCallback, failureCallback)); - mDecoder.AsyncDecodeMedia(contentType.get(), - aBuffer.Data(), aBuffer.Length(), *job); + mDecoder.AsyncDecodeMedia(contentType.get(), data, length, *job); // Transfer the ownership to mDecodeJobs mDecodeJobs.AppendElement(job); } diff --git a/content/media/webaudio/MediaBufferDecoder.cpp b/content/media/webaudio/MediaBufferDecoder.cpp index a113b110c24..5172b18a474 100644 --- a/content/media/webaudio/MediaBufferDecoder.cpp +++ b/content/media/webaudio/MediaBufferDecoder.cpp @@ -30,7 +30,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WebAudioDecodeJob) NS_IMPL_CYCLE_COLLECTION_UNLINK(mOutput) NS_IMPL_CYCLE_COLLECTION_UNLINK(mSuccessCallback) NS_IMPL_CYCLE_COLLECTION_UNLINK(mFailureCallback) - tmp->mArrayBuffer = nullptr; NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WebAudioDecodeJob) @@ -42,9 +41,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WebAudioDecodeJob) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(WebAudioDecodeJob) - NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mArrayBuffer) NS_IMPL_CYCLE_COLLECTION_TRACE_END - NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebAudioDecodeJob, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebAudioDecodeJob, Release) @@ -143,6 +140,7 @@ private: // Destruct MediaDecoderReader first. mDecoderReader = nullptr; mBufferDecoder = nullptr; + JS_free(nullptr, mBuffer); } private: @@ -482,7 +480,6 @@ MediaBufferDecoder::EnsureThreadPoolInitialized() WebAudioDecodeJob::WebAudioDecodeJob(const nsACString& aContentType, AudioContext* aContext, - const ArrayBuffer& aBuffer, DecodeSuccessCallback* aSuccessCallback, DecodeErrorCallback* aFailureCallback) : mContentType(aContentType) @@ -495,18 +492,12 @@ WebAudioDecodeJob::WebAudioDecodeJob(const nsACString& aContentType, MOZ_ASSERT(aSuccessCallback); MOZ_ASSERT(NS_IsMainThread()); MOZ_COUNT_CTOR(WebAudioDecodeJob); - - mArrayBuffer = aBuffer.Obj(); - - mozilla::HoldJSObjects(this); } WebAudioDecodeJob::~WebAudioDecodeJob() { MOZ_ASSERT(NS_IsMainThread()); MOZ_COUNT_DTOR(WebAudioDecodeJob); - mArrayBuffer = nullptr; - mozilla::DropJSObjects(this); } void diff --git a/content/media/webaudio/MediaBufferDecoder.h b/content/media/webaudio/MediaBufferDecoder.h index 38f867cc82b..f04ab3fc7cc 100644 --- a/content/media/webaudio/MediaBufferDecoder.h +++ b/content/media/webaudio/MediaBufferDecoder.h @@ -32,7 +32,6 @@ struct WebAudioDecodeJob MOZ_FINAL // The callbacks are only necessary for asynchronous operation. WebAudioDecodeJob(const nsACString& aContentType, dom::AudioContext* aContext, - const dom::ArrayBuffer& aBuffer, dom::DecodeSuccessCallback* aSuccessCallback = nullptr, dom::DecodeErrorCallback* aFailureCallback = nullptr); ~WebAudioDecodeJob(); @@ -59,7 +58,6 @@ struct WebAudioDecodeJob MOZ_FINAL size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; - JS::Heap mArrayBuffer; nsCString mContentType; uint32_t mWriteIndex; nsRefPtr mContext; diff --git a/content/media/webaudio/test/test_mediaDecoding.html b/content/media/webaudio/test/test_mediaDecoding.html index 8d7f49d97ae..9a32d105031 100644 --- a/content/media/webaudio/test/test_mediaDecoding.html +++ b/content/media/webaudio/test/test_mediaDecoding.html @@ -311,6 +311,9 @@ function runResampling(test, response, callback) { } function runTest(test, response, callback) { + // We need to copy the array here, because decodeAudioData is going to neuter + // the array. + var compressedAudio = response.slice(0); var expectCallback = false; var cx = new OfflineAudioContext(test.numberOfChannels || 1, test.frames || 1, test.sampleRate); @@ -322,7 +325,7 @@ function runTest(test, response, callback) { test.expectedBuffer = asyncResult; test.nativeContext = cx; - runResampling(test, response, callback); + runResampling(test, compressedAudio, callback); }, function onFailure() { ok(expectCallback, "Failure callback should fire asynchronously"); ok(!test.valid, "Did expect failure for test " + test.url);