already_AddRefed<AudioBuffer> AudioContext::CreateBuffer(JSContext* aJSContext, const ArrayBuffer& aBuffer, bool aMixToMono, ErrorResult& aRv) { // Do not accept this method unless the legacy pref has been set. if (!Preferences::GetBool("media.webaudio.legacy.AudioContext")) { aRv.ThrowNotEnoughArgsError(); return nullptr; } // Sniff the content of the media. // Failed type sniffing will be handled by SyncDecodeMedia. nsAutoCString contentType; NS_SniffContent(NS_DATA_SNIFFER_CATEGORY, nullptr, aBuffer.Data(), aBuffer.Length(), contentType); nsRefPtr<WebAudioDecodeJob> job = new WebAudioDecodeJob(contentType, this, aBuffer); if (mDecoder.SyncDecodeMedia(contentType.get(), aBuffer.Data(), aBuffer.Length(), *job) && job->mOutput) { nsRefPtr<AudioBuffer> buffer = job->mOutput.forget(); if (aMixToMono) { buffer->MixToMono(aJSContext); } return buffer.forget(); } return nullptr; }
already_AddRefed<AudioBuffer> AudioContext::CreateBuffer(JSContext* aJSContext, ArrayBuffer& aBuffer, bool aMixToMono, ErrorResult& aRv) { // Sniff the content of the media. // Failed type sniffing will be handled by SyncDecodeMedia. nsAutoCString contentType; NS_SniffContent(NS_DATA_SNIFFER_CATEGORY, nullptr, aBuffer.Data(), aBuffer.Length(), contentType); WebAudioDecodeJob job(contentType, this); if (mDecoder.SyncDecodeMedia(contentType.get(), aBuffer.Data(), aBuffer.Length(), job) && job.mOutput) { nsRefPtr<AudioBuffer> buffer = job.mOutput.forget(); if (aMixToMono) { buffer->MixToMono(aJSContext); } return buffer.forget(); } return nullptr; }
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); }
static void CallTypeSniffers(void *aClosure, const uint8_t *aData, uint32_t aCount) { nsIChannel *chan = static_cast<nsIChannel*>(aClosure); nsAutoCString newType; NS_SniffContent(NS_CONTENT_SNIFFER_CATEGORY, chan, aData, aCount, newType); if (!newType.IsEmpty()) { chan->SetContentType(newType); } }
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(); }
void AudioContext::DecodeAudioData(const ArrayBuffer& aBuffer, DecodeSuccessCallback& aSuccessCallback, const Optional<OwningNonNull<DecodeErrorCallback> >& aFailureCallback) { // 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); nsCOMPtr<DecodeErrorCallback> failureCallback; if (aFailureCallback.WasPassed()) { failureCallback = &aFailureCallback.Value(); } nsRefPtr<WebAudioDecodeJob> job( new WebAudioDecodeJob(contentType, this, aBuffer, &aSuccessCallback, failureCallback)); mDecoder.AsyncDecodeMedia(contentType.get(), aBuffer.Data(), aBuffer.Length(), *job); // Transfer the ownership to mDecodeJobs mDecodeJobs.AppendElement(job.forget()); }
void nsUnknownDecoder::DetermineContentType(nsIRequest* aRequest) { NS_ASSERTION(mContentType.IsEmpty(), "Content type is already known."); if (!mContentType.IsEmpty()) return; const char* testData = mBuffer; uint32_t testDataLen = mBufferLen; // Check if data are compressed. nsCOMPtr<nsIHttpChannel> channel(do_QueryInterface(aRequest)); if (channel) { nsresult rv = ConvertEncodedData(aRequest, mBuffer, mBufferLen); if (NS_SUCCEEDED(rv)) { if (!mDecodedData.IsEmpty()) { testData = mDecodedData.get(); testDataLen = std::min(mDecodedData.Length(), MAX_BUFFER_SIZE); } } } // First, run through all the types we can detect reliably based on // magic numbers uint32_t i; for (i = 0; i < sSnifferEntryNum; ++i) { if (testDataLen >= sSnifferEntries[i].mByteLen && // enough data memcmp(testData, sSnifferEntries[i].mBytes, sSnifferEntries[i].mByteLen) == 0) { // and type matches NS_ASSERTION(sSnifferEntries[i].mMimeType || sSnifferEntries[i].mContentTypeSniffer, "Must have either a type string or a function to set the type"); NS_ASSERTION(!sSnifferEntries[i].mMimeType || !sSnifferEntries[i].mContentTypeSniffer, "Both a type string and a type sniffing function set;" " using type string"); if (sSnifferEntries[i].mMimeType) { mContentType = sSnifferEntries[i].mMimeType; NS_ASSERTION(!mContentType.IsEmpty(), "Content type should be known by now."); return; } if ((this->*(sSnifferEntries[i].mContentTypeSniffer))(aRequest)) { NS_ASSERTION(!mContentType.IsEmpty(), "Content type should be known by now."); return; } } } NS_SniffContent(NS_DATA_SNIFFER_CATEGORY, aRequest, (const uint8_t*)testData, testDataLen, mContentType); if (!mContentType.IsEmpty()) { return; } if (SniffForHTML(aRequest)) { NS_ASSERTION(!mContentType.IsEmpty(), "Content type should be known by now."); return; } // We don't know what this is yet. Before we just give up, try // the URI from the request. if (SniffURI(aRequest)) { NS_ASSERTION(!mContentType.IsEmpty(), "Content type should be known by now."); return; } LastDitchSniff(aRequest); NS_ASSERTION(!mContentType.IsEmpty(), "Content type should be known by now."); }