void AudioContext::DecodeAudioData(const ArrayBuffer& aBuffer, DecodeSuccessCallback& aSuccessCallback, const Optional<OwningNonNull<DecodeErrorCallback> >& aFailureCallback) { AutoJSAPI jsapi; jsapi.Init(); JSContext* cx = jsapi.cx(); JSAutoCompartment ac(cx, aBuffer.Obj()); aBuffer.ComputeLengthAndData(); // Neuter the array buffer size_t length = aBuffer.Length(); JS::RootedObject obj(cx, aBuffer.Obj()); uint8_t* data = static_cast<uint8_t*>(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, data, length, contentType); nsRefPtr<DecodeErrorCallback> failureCallback; if (aFailureCallback.WasPassed()) { failureCallback = &aFailureCallback.Value(); } nsRefPtr<WebAudioDecodeJob> job( new WebAudioDecodeJob(contentType, this, &aSuccessCallback, failureCallback)); mDecoder.AsyncDecodeMedia(contentType.get(), data, length, *job); // Transfer the ownership to mDecodeJobs mDecodeJobs.AppendElement(job); }
already_AddRefed<Promise> AudioContext::DecodeAudioData(const ArrayBuffer& aBuffer, const Optional<OwningNonNull<DecodeSuccessCallback> >& aSuccessCallback, const Optional<OwningNonNull<DecodeErrorCallback> >& aFailureCallback, ErrorResult& aRv) { nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(GetParentObject()); RefPtr<Promise> promise; AutoJSAPI jsapi; jsapi.Init(); JSContext* cx = jsapi.cx(); JSAutoCompartment ac(cx, aBuffer.Obj()); promise = Promise::Create(parentObject, aRv); if (aRv.Failed()) { return nullptr; } aBuffer.ComputeLengthAndData(); if (aBuffer.IsShared()) { // Throw if the object is mapping shared memory (must opt in). aRv.ThrowTypeError<MSG_TYPEDARRAY_IS_SHARED>(NS_LITERAL_STRING("Argument of AudioContext.decodeAudioData")); return nullptr; } // Detach the array buffer size_t length = aBuffer.Length(); JS::RootedObject obj(cx, aBuffer.Obj()); uint8_t* data = static_cast<uint8_t*>(JS_StealArrayBufferContents(cx, obj)); // Sniff the content of the media. // Failed type sniffing will be handled by AsyncDecodeWebAudio. nsAutoCString contentType; NS_SniffContent(NS_DATA_SNIFFER_CATEGORY, nullptr, data, length, contentType); RefPtr<DecodeErrorCallback> failureCallback; RefPtr<DecodeSuccessCallback> successCallback; if (aFailureCallback.WasPassed()) { failureCallback = &aFailureCallback.Value(); } if (aSuccessCallback.WasPassed()) { successCallback = &aSuccessCallback.Value(); } RefPtr<WebAudioDecodeJob> job( new WebAudioDecodeJob(contentType, this, promise, successCallback, failureCallback)); AsyncDecodeWebAudio(contentType.get(), data, length, *job); // Transfer the ownership to mDecodeJobs mDecodeJobs.AppendElement(job.forget()); return promise.forget(); }
already_AddRefed<Promise> AudioContext::DecodeAudioData(const ArrayBuffer& aBuffer, const Optional<OwningNonNull<DecodeSuccessCallback> >& aSuccessCallback, const Optional<OwningNonNull<DecodeErrorCallback> >& aFailureCallback) { ErrorResult rv; nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(GetParentObject()); nsRefPtr<Promise> promise; AutoJSAPI jsapi; jsapi.Init(); JSContext* cx = jsapi.cx(); JSAutoCompartment ac(cx, aBuffer.Obj()); promise = Promise::Create(parentObject, rv); if (rv.Failed()) { return nullptr; } aBuffer.ComputeLengthAndData(); // Neuter the array buffer size_t length = aBuffer.Length(); JS::RootedObject obj(cx, aBuffer.Obj()); uint8_t* data = static_cast<uint8_t*>(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, data, length, contentType); nsRefPtr<DecodeErrorCallback> failureCallback; nsRefPtr<DecodeSuccessCallback> successCallback; if (aFailureCallback.WasPassed()) { failureCallback = &aFailureCallback.Value(); } if (aSuccessCallback.WasPassed()) { successCallback = &aSuccessCallback.Value(); } nsRefPtr<WebAudioDecodeJob> job( new WebAudioDecodeJob(contentType, this, promise, successCallback, failureCallback)); mDecoder.AsyncDecodeMedia(contentType.get(), data, length, *job); // Transfer the ownership to mDecodeJobs mDecodeJobs.AppendElement(job.forget()); return promise.forget(); }
WebAudioDecodeJob::WebAudioDecodeJob(const nsACString& aContentType, AudioContext* aContext, const ArrayBuffer& aBuffer, DecodeSuccessCallback* aSuccessCallback, DecodeErrorCallback* aFailureCallback) : mContentType(aContentType) , mWriteIndex(0) , mContext(aContext) , mSuccessCallback(aSuccessCallback) , mFailureCallback(aFailureCallback) { MOZ_ASSERT(aContext); MOZ_ASSERT(NS_IsMainThread()); MOZ_COUNT_CTOR(WebAudioDecodeJob); mArrayBuffer = aBuffer.Obj(); MOZ_ASSERT(aSuccessCallback || (!aSuccessCallback && !aFailureCallback), "If a success callback is not passed, no failure callback should be passed either"); mozilla::HoldJSObjects(this); }