--- a/dom/media/Benchmark.cpp
+++ b/dom/media/Benchmark.cpp
@@ -276,17 +276,17 @@ BenchmarkPlayback::Output(MediaData* aDa
ref->Dispatch(NS_NewRunnableFunction([ref, decodeFps]() {
ref->ReturnResult(decodeFps);
}));
}
}));
}
void
-BenchmarkPlayback::Error(MediaDataDecoderError aError)
+BenchmarkPlayback::Error(const MediaResult& aError)
{
RefPtr<Benchmark> ref(mMainThreadState);
Dispatch(NS_NewRunnableFunction([this, ref]() { MainThreadShutdown(); }));
}
void
BenchmarkPlayback::InputExhausted()
{
--- a/dom/media/Benchmark.h
+++ b/dom/media/Benchmark.h
@@ -27,17 +27,17 @@ class BenchmarkPlayback : public QueueOb
void DemuxSamples();
void DemuxNextSample();
void MainThreadShutdown();
void InitDecoder(TrackInfo&& aInfo);
// MediaDataDecoderCallback
// Those methods are called on the MediaDataDecoder's task queue.
void Output(MediaData* aData) override;
- void Error(MediaDataDecoderError aError) override;
+ void Error(const MediaResult& aError) override;
void InputExhausted() override;
void DrainComplete() override;
bool OnReaderTaskQueue() override;
Atomic<Benchmark*> mMainThreadState;
RefPtr<TaskQueue> mDecoderTaskQueue;
RefPtr<MediaDataDecoder> mDecoder;
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -718,17 +718,17 @@ MediaFormatReader::NotifyDrainComplete(T
LOG("MediaFormatReader called DrainComplete() before flushing, ignoring.");
return;
}
decoder.mDrainComplete = true;
ScheduleUpdate(aTrack);
}
void
-MediaFormatReader::NotifyError(TrackType aTrack, MediaDataDecoderError aError)
+MediaFormatReader::NotifyError(TrackType aTrack, const MediaResult& aError)
{
MOZ_ASSERT(OnTaskQueue());
LOGV("%s Decoding error", TrackTypeToStr(aTrack));
auto& decoder = GetDecoderData(aTrack);
decoder.mError = decoder.HasFatalError() ? decoder.mError : Some(aError);
ScheduleUpdate(aTrack);
}
@@ -1248,17 +1248,17 @@ MediaFormatReader::Update(TrackType aTra
}
if (decoder.mNeedDraining) {
DrainDecoder(aTrack);
return;
}
if (decoder.mError &&
- decoder.mError.ref() == MediaDataDecoderError::DECODE_ERROR) {
+ decoder.mError.ref().Code() == NS_ERROR_DOM_MEDIA_DECODE_ERR) {
decoder.mDecodePending = false;
decoder.mError.reset();
if (++decoder.mNumOfConsecutiveError > decoder.mMaxConsecutiveError) {
NotifyError(aTrack);
return;
}
LOG("%s decoded error count %d", TrackTypeToStr(aTrack),
decoder.mNumOfConsecutiveError);
@@ -1413,17 +1413,17 @@ MediaFormatReader::ResetDecode(TrackSet
return MediaDecoderReader::ResetDecode(aTracks);
}
void
MediaFormatReader::Output(TrackType aTrack, MediaData* aSample)
{
if (!aSample) {
NS_WARNING("MediaFormatReader::Output() passed a null sample");
- Error(aTrack);
+ Error(aTrack, MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__));
return;
}
LOGV("Decoded %s sample time=%lld timecode=%lld kf=%d dur=%lld",
TrackTypeToStr(aTrack), aSample->mTime, aSample->mTimecode,
aSample->mKeyframe, aSample->mDuration);
RefPtr<nsIRunnable> task =
@@ -1446,20 +1446,20 @@ MediaFormatReader::InputExhausted(TrackT
{
RefPtr<nsIRunnable> task =
NewRunnableMethod<TrackType>(
this, &MediaFormatReader::NotifyInputExhausted, aTrack);
OwnerThread()->Dispatch(task.forget());
}
void
-MediaFormatReader::Error(TrackType aTrack, MediaDataDecoderError aError)
+MediaFormatReader::Error(TrackType aTrack, const MediaResult& aError)
{
RefPtr<nsIRunnable> task =
- NewRunnableMethod<TrackType, MediaDataDecoderError>(
+ NewRunnableMethod<TrackType, MediaResult>(
this, &MediaFormatReader::NotifyError, aTrack, aError);
OwnerThread()->Dispatch(task.forget());
}
void
MediaFormatReader::Reset(TrackType aTrack)
{
MOZ_ASSERT(OnTaskQueue());
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -161,30 +161,31 @@ private:
// the first sample past the target will be dropped.
void InternalSeek(TrackType aTrack, const InternalSeekTarget& aTarget);
// Drain the current decoder.
void DrainDecoder(TrackType aTrack);
void NotifyNewOutput(TrackType aTrack, MediaData* aSample);
void NotifyInputExhausted(TrackType aTrack);
void NotifyDrainComplete(TrackType aTrack);
- void NotifyError(TrackType aTrack, MediaDataDecoderError aError = MediaDataDecoderError::FATAL_ERROR);
+ void NotifyError(TrackType aTrack,
+ const MediaResult& aError = MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR));
void NotifyWaitingForData(TrackType aTrack);
void NotifyEndOfStream(TrackType aTrack);
void ExtractCryptoInitData(nsTArray<uint8_t>& aInitData);
// Initializes mLayersBackendType if possible.
void InitLayersBackendType();
// DecoderCallback proxies the MediaDataDecoderCallback calls to these
// functions.
void Output(TrackType aType, MediaData* aSample);
void InputExhausted(TrackType aTrack);
- void Error(TrackType aTrack, MediaDataDecoderError aError = MediaDataDecoderError::FATAL_ERROR);
+ void Error(TrackType aTrack, const MediaResult& aError);
void Reset(TrackType aTrack);
void DrainComplete(TrackType aTrack);
void DropDecodedSamples(TrackType aTrack);
void WaitingForKey(TrackType aTrack);
bool ShouldSkip(bool aSkipToNextKeyframe, media::TimeUnit aTimeThreshold);
void SetVideoDecodeThreshold();
@@ -201,17 +202,17 @@ private:
{
}
void Output(MediaData* aSample) override {
mReader->Output(mType, aSample);
}
void InputExhausted() override {
mReader->InputExhausted(mType);
}
- void Error(MediaDataDecoderError aError) override {
+ void Error(const MediaResult& aError) override {
mReader->Error(mType, aError);
}
void DrainComplete() override {
mReader->DrainComplete(mType);
}
void ReleaseMediaResources() override {
mReader->ReleaseResources();
}
@@ -322,20 +323,20 @@ private:
bool HasPendingDrain() const
{
return mDraining || mDrainComplete;
}
uint32_t mNumOfConsecutiveError;
uint32_t mMaxConsecutiveError;
- Maybe<MediaDataDecoderError> mError;
+ Maybe<MediaResult> mError;
bool HasFatalError() const
{
- return mError.isSome() && mError.ref() == MediaDataDecoderError::FATAL_ERROR;
+ return mError.isSome() && mError.ref() != NS_ERROR_DOM_MEDIA_DECODE_ERR;
}
// If set, all decoded samples prior mTimeThreshold will be dropped.
// Used for internal seeking when a change of stream is detected or when
// encountering data discontinuity.
Maybe<InternalSeekTarget> mTimeThreshold;
// Time of last sample returned.
Maybe<media::TimeInterval> mLastSampleTime;
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -9,16 +9,17 @@
#include "MediaDecoderReader.h"
#include "mozilla/MozPromise.h"
#include "mozilla/layers/LayersTypes.h"
#include "nsTArray.h"
#include "mozilla/RefPtr.h"
#include "GMPService.h"
#include <queue>
+#include "MediaResult.h"
namespace mozilla {
class TrackInfo;
class AudioInfo;
class VideoInfo;
class MediaRawData;
class DecoderDoctorDiagnostics;
@@ -149,34 +150,29 @@ protected:
// On Windows the task queue's threads in have MSCOM initialized with
// COINIT_MULTITHREADED.
// It is safe to store a reference to aConfig.
// This is called on the decode task queue.
virtual already_AddRefed<MediaDataDecoder>
CreateAudioDecoder(const CreateDecoderParams& aParams) = 0;
};
-enum class MediaDataDecoderError : uint8_t{
- FATAL_ERROR,
- DECODE_ERROR
-};
-
// A callback used by MediaDataDecoder to return output/errors to the
// MediaFormatReader.
// Implementation is threadsafe, and can be called on any thread.
class MediaDataDecoderCallback {
public:
virtual ~MediaDataDecoderCallback() {}
// Called by MediaDataDecoder when a sample has been decoded.
virtual void Output(MediaData* aData) = 0;
// Denotes an error in the decoding process. The reader will stop calling
// the decoder.
- virtual void Error(MediaDataDecoderError aError) = 0;
+ virtual void Error(const MediaResult& aError) = 0;
// Denotes that the last input sample has been inserted into the decoder,
// and no more output can be produced unless more input is sent.
// A frame decoding session is completed once InputExhausted has been called.
// MediaDataDecoder::Input will not be called again until InputExhausted has
// been called.
virtual void InputExhausted() = 0;
--- a/dom/media/platforms/agnostic/BlankDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/BlankDecoderModule.cpp
@@ -74,17 +74,17 @@ public:
{
return "blank media data decoder";
}
private:
void OutputFrame(MediaData* aData)
{
if (!aData) {
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
return;
}
// Frames come out in DTS order but we need to output them in PTS order.
mReorderQueue.Push(aData);
while (mReorderQueue.Length() > mMaxRefFrames) {
mCallback->Output(mReorderQueue.Pop().get());
--- a/dom/media/platforms/agnostic/OpusDecoder.cpp
+++ b/dom/media/platforms/agnostic/OpusDecoder.cpp
@@ -149,20 +149,22 @@ OpusDataDecoder::ProcessDecode(MediaRawD
{
if (mIsFlushing) {
return;
}
DecodeError err = DoDecode(aSample);
switch (err) {
case DecodeError::FATAL_ERROR:
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
return;
case DecodeError::DECODE_ERROR:
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ __func__));
break;
case DecodeError::DECODE_SUCCESS:
mCallback->InputExhausted();
break;
}
}
OpusDataDecoder::DecodeError
--- a/dom/media/platforms/agnostic/TheoraDecoder.cpp
+++ b/dom/media/platforms/agnostic/TheoraDecoder.cpp
@@ -194,17 +194,18 @@ TheoraDecoder::DoDecode(MediaRawData* aS
void
TheoraDecoder::ProcessDecode(MediaRawData* aSample)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
if (mIsFlushing) {
return;
}
if (DoDecode(aSample) == -1) {
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
} else {
mCallback->InputExhausted();
}
}
void
TheoraDecoder::Input(MediaRawData* aSample)
{
--- a/dom/media/platforms/agnostic/VPXDecoder.cpp
+++ b/dom/media/platforms/agnostic/VPXDecoder.cpp
@@ -186,17 +186,18 @@ VPXDecoder::DoDecode(MediaRawData* aSamp
void
VPXDecoder::ProcessDecode(MediaRawData* aSample)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
if (mIsFlushing) {
return;
}
if (DoDecode(aSample) == -1) {
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ __func__));
} else {
mCallback->InputExhausted();
}
}
void
VPXDecoder::Input(MediaRawData* aSample)
{
--- a/dom/media/platforms/agnostic/VorbisDecoder.cpp
+++ b/dom/media/platforms/agnostic/VorbisDecoder.cpp
@@ -133,17 +133,18 @@ VorbisDataDecoder::Input(MediaRawData* a
void
VorbisDataDecoder::ProcessDecode(MediaRawData* aSample)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
if (mIsFlushing) {
return;
}
if (DoDecode(aSample) == -1) {
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ __func__));
} else {
mCallback->InputExhausted();
}
}
int
VorbisDataDecoder::DoDecode(MediaRawData* aSample)
{
--- a/dom/media/platforms/agnostic/WAVDecoder.cpp
+++ b/dom/media/platforms/agnostic/WAVDecoder.cpp
@@ -61,17 +61,18 @@ WaveDataDecoder::Init()
{
return InitPromise::CreateAndResolve(TrackInfo::kAudioTrack, __func__);
}
void
WaveDataDecoder::Input(MediaRawData* aSample)
{
if (!DoDecode(aSample)) {
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ __func__));
} else {
mCallback->InputExhausted();
}
}
bool
WaveDataDecoder::DoDecode(MediaRawData* aSample)
{
--- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
@@ -88,17 +88,18 @@ public:
if (aDecrypted.mStatus == NoKeyErr) {
// Key became unusable after we sent the sample to CDM to decrypt.
// Call Input() again, so that the sample is enqueued for decryption
// if the key becomes usable again.
Input(aDecrypted.mSample);
} else if (aDecrypted.mStatus != Ok) {
if (mCallback) {
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
}
} else {
MOZ_ASSERT(!mIsShutdown);
// The Adobe GMP AAC decoder gets confused if we pass it non-encrypted
// samples with valid crypto data. So clear the crypto data, since the
// sample should be decrypted now anyway. If we don't do this and we're
// using the Adobe GMP for unencrypted decoding of data that is decrypted
// by gmp-clearkey, decoding will fail.
--- a/dom/media/platforms/agnostic/gmp/GMPAudioDecoder.cpp
+++ b/dom/media/platforms/agnostic/gmp/GMPAudioDecoder.cpp
@@ -3,16 +3,17 @@
/* 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 "GMPAudioDecoder.h"
#include "nsServiceManagerUtils.h"
#include "MediaInfo.h"
#include "GMPDecoderModule.h"
+#include "nsPrintfCString.h"
namespace mozilla {
#if defined(DEBUG)
bool IsOnGMPThread()
{
nsCOMPtr<mozIGeckoMediaPluginService> mps = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
MOZ_ASSERT(mps);
@@ -26,56 +27,59 @@ bool IsOnGMPThread()
void
AudioCallbackAdapter::Decoded(const nsTArray<int16_t>& aPCM, uint64_t aTimeStamp, uint32_t aChannels, uint32_t aRate)
{
MOZ_ASSERT(IsOnGMPThread());
if (aRate == 0 || aChannels == 0) {
NS_WARNING("Invalid rate or num channels returned on GMP audio samples");
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
return;
}
size_t numFrames = aPCM.Length() / aChannels;
MOZ_ASSERT((aPCM.Length() % aChannels) == 0);
AlignedAudioBuffer audioData(aPCM.Length());
if (!audioData) {
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
return;
}
for (size_t i = 0; i < aPCM.Length(); ++i) {
audioData[i] = AudioSampleToFloat(aPCM[i]);
}
if (mMustRecaptureAudioPosition) {
mAudioFrameSum = 0;
auto timestamp = UsecsToFrames(aTimeStamp, aRate);
if (!timestamp.isValid()) {
NS_WARNING("Invalid timestamp");
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_OVERFLOW_ERR,
+ __func__));
return;
}
mAudioFrameOffset = timestamp.value();
mMustRecaptureAudioPosition = false;
}
auto timestamp = FramesToUsecs(mAudioFrameOffset + mAudioFrameSum, aRate);
if (!timestamp.isValid()) {
NS_WARNING("Invalid timestamp on audio samples");
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_OVERFLOW_ERR,
+ __func__));
return;
}
mAudioFrameSum += numFrames;
auto duration = FramesToUsecs(numFrames, aRate);
if (!duration.isValid()) {
NS_WARNING("Invalid duration on audio samples");
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_OVERFLOW_ERR,
+ __func__));
return;
}
RefPtr<AudioData> audio(new AudioData(mLastStreamOffset,
timestamp.value(),
duration.value(),
numFrames,
Move(audioData),
@@ -111,24 +115,26 @@ AudioCallbackAdapter::ResetComplete()
mMustRecaptureAudioPosition = true;
mCallback->FlushComplete();
}
void
AudioCallbackAdapter::Error(GMPErr aErr)
{
MOZ_ASSERT(IsOnGMPThread());
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ nsPrintfCString("%s: %d", __func__, aErr)));
}
void
AudioCallbackAdapter::Terminated()
{
NS_WARNING("AAC GMP decoder terminated.");
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
}
GMPAudioDecoderParams::GMPAudioDecoderParams(const CreateDecoderParams& aParams)
: mConfig(aParams.AudioConfig())
, mTaskQueue(aParams.mTaskQueue)
, mCallback(nullptr)
, mAdapter(nullptr)
, mCrashHelper(aParams.mCrashHelper)
@@ -241,26 +247,28 @@ GMPAudioDecoder::Init()
void
GMPAudioDecoder::Input(MediaRawData* aSample)
{
MOZ_ASSERT(IsOnGMPThread());
RefPtr<MediaRawData> sample(aSample);
if (!mGMP) {
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
return;
}
mAdapter->SetLastStreamOffset(sample->mOffset);
gmp::GMPAudioSamplesImpl samples(sample, mConfig.mChannels, mConfig.mRate);
nsresult rv = mGMP->Decode(samples);
if (NS_FAILED(rv)) {
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(
+ MediaResult(rv, nsPrintfCString("%s: decode error (%d)",
+ __func__, rv)));
}
}
void
GMPAudioDecoder::Flush()
{
MOZ_ASSERT(IsOnGMPThread());
--- a/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
+++ b/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
@@ -49,17 +49,17 @@ VideoCallbackAdapter::Decoded(GMPVideoi4
decodedFrame->Duration(),
b,
false,
-1,
pictureRegion);
if (v) {
mCallback->Output(v);
} else {
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
}
}
void
VideoCallbackAdapter::ReceivedDecodedReferenceFrame(const uint64_t aPictureId)
{
MOZ_ASSERT(IsOnGMPThread());
}
@@ -90,25 +90,26 @@ VideoCallbackAdapter::ResetComplete()
MOZ_ASSERT(IsOnGMPThread());
mCallback->FlushComplete();
}
void
VideoCallbackAdapter::Error(GMPErr aErr)
{
MOZ_ASSERT(IsOnGMPThread());
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ nsPrintfCString("%s: %d", __func__, aErr)));
}
void
VideoCallbackAdapter::Terminated()
{
// Note that this *may* be called from the proxy thread also.
NS_WARNING("GMP decoder terminated.");
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
}
GMPVideoDecoderParams::GMPVideoDecoderParams(const CreateDecoderParams& aParams)
: mConfig(aParams.VideoConfig())
, mTaskQueue(aParams.mTaskQueue)
, mCallback(nullptr)
, mAdapter(nullptr)
, mImageContainer(aParams.mImageContainer)
@@ -178,24 +179,24 @@ GMPVideoDecoder::GetNodeId()
}
GMPUniquePtr<GMPVideoEncodedFrame>
GMPVideoDecoder::CreateFrame(MediaRawData* aSample)
{
GMPVideoFrame* ftmp = nullptr;
GMPErr err = mHost->CreateFrame(kGMPEncodedVideoFrame, &ftmp);
if (GMP_FAILED(err)) {
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
return nullptr;
}
GMPUniquePtr<GMPVideoEncodedFrame> frame(static_cast<GMPVideoEncodedFrame*>(ftmp));
err = frame->CreateEmptyFrame(aSample->Size());
if (GMP_FAILED(err)) {
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
return nullptr;
}
memcpy(frame->Buffer(), aSample->Data(), frame->Size());
// Convert 4-byte NAL unit lengths to host-endian 4-byte buffer lengths to
// suit the GMP API.
if (mConvertNALUnitLengths) {
@@ -315,31 +316,32 @@ GMPVideoDecoder::Init()
void
GMPVideoDecoder::Input(MediaRawData* aSample)
{
MOZ_ASSERT(IsOnGMPThread());
RefPtr<MediaRawData> sample(aSample);
if (!mGMP) {
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
return;
}
mAdapter->SetLastStreamOffset(sample->mOffset);
GMPUniquePtr<GMPVideoEncodedFrame> frame = CreateFrame(sample);
if (!frame) {
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
return;
}
nsTArray<uint8_t> info; // No codec specific per-frame info to pass.
nsresult rv = mGMP->Decode(Move(frame), false, info, 0);
if (NS_FAILED(rv)) {
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__));
}
}
void
GMPVideoDecoder::Flush()
{
MOZ_ASSERT(IsOnGMPThread());
--- a/dom/media/platforms/agnostic/gmp/MediaDataDecoderProxy.cpp
+++ b/dom/media/platforms/agnostic/gmp/MediaDataDecoderProxy.cpp
@@ -5,17 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MediaDataDecoderProxy.h"
#include "MediaData.h"
namespace mozilla {
void
-MediaDataDecoderCallbackProxy::Error(MediaDataDecoderError aError)
+MediaDataDecoderCallbackProxy::Error(const MediaResult& aError)
{
mProxyCallback->Error(aError);
}
void
MediaDataDecoderCallbackProxy::FlushComplete()
{
mProxyDecoder->FlushComplete();
--- a/dom/media/platforms/agnostic/gmp/MediaDataDecoderProxy.h
+++ b/dom/media/platforms/agnostic/gmp/MediaDataDecoderProxy.h
@@ -69,17 +69,17 @@ public:
, mProxyCallback(aCallback)
{
}
void Output(MediaData* aData) override {
mProxyCallback->Output(aData);
}
- void Error(MediaDataDecoderError aError) override;
+ void Error(const MediaResult& aError) override;
void InputExhausted() override {
mProxyCallback->InputExhausted();
}
void DrainComplete() override {
mProxyCallback->DrainComplete();
}
--- a/dom/media/platforms/android/MediaCodecDataDecoder.cpp
+++ b/dom/media/platforms/android/MediaCodecDataDecoder.cpp
@@ -263,17 +263,18 @@ MediaCodecDataDecoder::Init()
MediaDataDecoder::DecoderFailureReason::INIT_ERROR, __func__);
}
nsresult
MediaCodecDataDecoder::InitDecoder(Surface::Param aSurface)
{
mDecoder = CreateDecoder(mMimeType);
if (!mDecoder) {
- INVOKE_CALLBACK(Error, MediaDataDecoderError::FATAL_ERROR);
+ INVOKE_CALLBACK(Error,
+ MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
return NS_ERROR_FAILURE;
}
nsresult rv;
NS_ENSURE_SUCCESS(rv = mDecoder->Configure(mFormat, aSurface, nullptr, 0), rv);
NS_ENSURE_SUCCESS(rv = mDecoder->Start(), rv);
NS_ENSURE_SUCCESS(rv = ResetInputBuffers(), rv);
@@ -290,17 +291,17 @@ static const int64_t kDecoderTimeout = 1
#define BREAK_ON_DECODER_ERROR() \
if (NS_FAILED(res)) { \
NS_WARNING("Exiting decoder loop due to exception"); \
if (mState == ModuleState::kDrainDecoder) { \
INVOKE_CALLBACK(DrainComplete); \
SetState(ModuleState::kDecoding); \
} \
- INVOKE_CALLBACK(Error, MediaDataDecoderError::FATAL_ERROR); \
+ INVOKE_CALLBACK(Error, MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__)); \
break; \
}
nsresult
MediaCodecDataDecoder::GetInputBuffer(
JNIEnv* aEnv, int aIndex, jni::Object::LocalRef* aBuffer)
{
MOZ_ASSERT(aEnv);
@@ -530,17 +531,19 @@ MediaCodecDataDecoder::DecoderLoop()
} else if (outputStatus == MediaCodec::INFO_OUTPUT_BUFFERS_CHANGED) {
res = ResetOutputBuffers();
BREAK_ON_DECODER_ERROR();
} else if (outputStatus == MediaCodec::INFO_OUTPUT_FORMAT_CHANGED) {
res = mDecoder->GetOutputFormat(ReturnTo(&outputFormat));
BREAK_ON_DECODER_ERROR();
} else if (outputStatus < 0) {
NS_WARNING("Unknown error from decoder!");
- INVOKE_CALLBACK(Error, MediaDataDecoderError::DECODE_ERROR);
+ INVOKE_CALLBACK(Error,
+ MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ __func__));
// Don't break here just in case it's recoverable. If it's not, other
// stuff will fail later and we'll bail out.
} else {
// We have a valid buffer index >= 0 here.
int32_t flags;
nsresult res = bufferInfo->Flags(&flags);
BREAK_ON_DECODER_ERROR();
--- a/dom/media/platforms/android/RemoteDataDecoder.cpp
+++ b/dom/media/platforms/android/RemoteDataDecoder.cpp
@@ -75,18 +75,18 @@ public:
HandleOutputFormatChanged(MediaFormat::Ref::From(aFormat));
}
}
void OnError(bool aIsFatal)
{
if (mDecoderCallback) {
mDecoderCallback->Error(aIsFatal ?
- MediaDataDecoderError::FATAL_ERROR :
- MediaDataDecoderError::DECODE_ERROR);
+ MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__) :
+ MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__));
}
}
void DisposeNative()
{
// TODO
}
@@ -377,17 +377,18 @@ private:
}
}
void HandleOutputFormatChanged(MediaFormat::Param aFormat) override
{
aFormat->GetInteger(NS_LITERAL_STRING("channel-count"), &mOutputChannels);
AudioConfig::ChannelLayout layout(mOutputChannels);
if (!layout.IsValid()) {
- mDecoderCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mDecoderCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
return;
}
aFormat->GetInteger(NS_LITERAL_STRING("sample-rate"), &mOutputSampleRate);
LOG("Audio output format changed: channels:%d sample rate:%d", mOutputChannels, mOutputSampleRate);
}
private:
RemoteAudioDecoder* mDecoder;
@@ -471,17 +472,17 @@ RemoteDataDecoder::Input(MediaRawData* a
env->SetByteArrayRegion(data, 0, length, reinterpret_cast<const jbyte*>(aSample->Data()));
jni::ByteArray::LocalRef bytes(env);
bytes = jni::Object::LocalRef::Adopt(env, data);
BufferInfo::LocalRef bufferInfo;
nsresult rv = BufferInfo::New(&bufferInfo);
if (NS_FAILED(rv)) {
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
return;
}
bufferInfo->Set(0, aSample->Size(), aSample->mTime, 0);
mJavaDecoder->Input(bytes, bufferInfo);
}
} // mozilla
--- a/dom/media/platforms/apple/AppleATDecoder.cpp
+++ b/dom/media/platforms/apple/AppleATDecoder.cpp
@@ -189,28 +189,30 @@ AppleATDecoder::SubmitSample(MediaRawDat
if (mIsFlushing) {
return;
}
nsresult rv = NS_OK;
if (!mConverter) {
rv = SetupDecoder(aSample);
if (rv != NS_OK && rv != NS_ERROR_NOT_INITIALIZED) {
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
return;
}
}
mQueuedSamples.AppendElement(aSample);
if (rv == NS_OK) {
for (size_t i = 0; i < mQueuedSamples.Length(); i++) {
- if (NS_FAILED(DecodeSample(mQueuedSamples[i]))) {
+ rv = DecodeSample(mQueuedSamples[i]);
+ if (NS_FAILED(rv)) {
mQueuedSamples.Clear();
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(MediaResult(rv, __func__));
return;
}
}
mQueuedSamples.Clear();
}
mCallback->InputExhausted();
}
@@ -257,17 +259,17 @@ AppleATDecoder::DecodeSample(MediaRawDat
_PassthroughInputDataCallback,
&userData,
&numFrames /* in/out */,
&decBuffer,
packets.get());
if (rv && rv != kNoMoreDataErr) {
LOG("Error decoding audio stream: %d\n", rv);
- return NS_ERROR_FAILURE;
+ return NS_ERROR_DOM_MEDIA_DECODE_ERR;
}
if (numFrames) {
outputData.AppendElements(decoded.get(), numFrames * channels);
}
if (rv == kNoMoreDataErr) {
break;
@@ -278,34 +280,34 @@ AppleATDecoder::DecodeSample(MediaRawDat
return NS_OK;
}
size_t numFrames = outputData.Length() / channels;
int rate = mOutputFormat.mSampleRate;
media::TimeUnit duration = FramesToTimeUnit(numFrames, rate);
if (!duration.IsValid()) {
NS_WARNING("Invalid count of accumulated audio samples");
- return NS_ERROR_FAILURE;
+ return NS_ERROR_DOM_MEDIA_OVERFLOW_ERR;
}
#ifdef LOG_SAMPLE_DECODE
LOG("pushed audio at time %lfs; duration %lfs\n",
(double)aSample->mTime / USECS_PER_S,
duration.ToSeconds());
#endif
AudioSampleBuffer data(outputData.Elements(), outputData.Length());
if (!data.Data()) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (mChannelLayout && !mAudioConverter) {
AudioConfig in(*mChannelLayout.get(), rate);
AudioConfig out(channels, rate);
if (!in.IsValid() || !out.IsValid()) {
- return NS_ERROR_FAILURE;
+ return NS_ERROR_DOM_MEDIA_DECODE_ERR;
}
mAudioConverter = MakeUnique<AudioConverter>(in, out);
}
if (mAudioConverter) {
MOZ_ASSERT(mAudioConverter->CanWorkInPlace());
data = mAudioConverter->Process(Move(data));
}
--- a/dom/media/platforms/apple/AppleVTDecoder.cpp
+++ b/dom/media/platforms/apple/AppleVTDecoder.cpp
@@ -305,18 +305,18 @@ AppleVTDecoder::OutputFrame(CVPixelBuffe
MOZ_ASSERT(planes == 2, "Likely not NV12 format and it must be.");
VideoData::YCbCrBuffer buffer;
// Lock the returned image data.
CVReturn rv = CVPixelBufferLockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
if (rv != kCVReturnSuccess) {
NS_ERROR("error locking pixel data");
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
- return NS_ERROR_FAILURE;
+ mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
+ return NS_ERROR_OUT_OF_MEMORY;
}
// Y plane.
buffer.mPlanes[0].mData =
static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 0));
buffer.mPlanes[0].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 0);
buffer.mPlanes[0].mWidth = width;
buffer.mPlanes[0].mHeight = height;
buffer.mPlanes[0].mOffset = 0;
@@ -371,18 +371,18 @@ AppleVTDecoder::OutputFrame(CVPixelBuffe
visible);
#else
MOZ_ASSERT_UNREACHABLE("No MacIOSurface on iOS");
#endif
}
if (!data) {
NS_ERROR("Couldn't create VideoData for frame");
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
- return NS_ERROR_FAILURE;
+ mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
+ return NS_ERROR_OUT_OF_MEMORY;
}
// Frames come out in DTS order but we need to output them
// in composition order.
MonitorAutoLock mon(mMonitor);
mReorderQueue.Push(data);
if (mReorderQueue.Length() > mMaxRefFrames) {
mCallback->Output(mReorderQueue.Pop().get());
@@ -441,37 +441,39 @@ AppleVTDecoder::DoDecode(MediaRawData* a
kCFAllocatorNull, // Block allocator.
NULL, // Block source.
0, // Data offset.
aSample->Size(),
false,
block.receive());
if (rv != noErr) {
NS_ERROR("Couldn't create CMBlockBuffer");
- return NS_ERROR_FAILURE;
+ mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
+ return NS_ERROR_OUT_OF_MEMORY;
}
CMSampleTimingInfo timestamp = TimingInfoFromSample(aSample);
rv = CMSampleBufferCreate(kCFAllocatorDefault, block, true, 0, 0, mFormat, 1, 1, ×tamp, 0, NULL, sample.receive());
if (rv != noErr) {
NS_ERROR("Couldn't create CMSampleBuffer");
- return NS_ERROR_FAILURE;
+ mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
+ return NS_ERROR_OUT_OF_MEMORY;
}
VTDecodeFrameFlags decodeFlags =
kVTDecodeFrame_EnableAsynchronousDecompression;
rv = VTDecompressionSessionDecodeFrame(mSession,
sample,
decodeFlags,
CreateAppleFrameRef(aSample),
&infoFlags);
if (rv != noErr && !(infoFlags & kVTDecodeInfo_FrameDropped)) {
LOG("AppleVTDecoder: Error %d VTDecompressionSessionDecodeFrame", rv);
NS_WARNING("Couldn't pass frame to decoder");
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
- return NS_ERROR_FAILURE;
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__));
+ return NS_ERROR_DOM_MEDIA_DECODE_ERR;
}
return NS_OK;
}
nsresult
AppleVTDecoder::InitializeSession()
{
--- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
@@ -106,20 +106,20 @@ void
FFmpegDataDecoder<LIBAV_VER>::ProcessDecode(MediaRawData* aSample)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
if (mIsFlushing) {
return;
}
switch (DoDecode(aSample)) {
case DecodeResult::DECODE_ERROR:
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__));
break;
case DecodeResult::FATAL_ERROR:
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
break;
case DecodeResult::DECODE_NO_FRAME:
case DecodeResult::DECODE_FRAME:
mCallback->InputExhausted();
break;
default:
break;
}
--- a/dom/media/platforms/gonk/GonkMediaDataDecoder.cpp
+++ b/dom/media/platforms/gonk/GonkMediaDataDecoder.cpp
@@ -170,31 +170,33 @@ GonkDecoderManager::ProcessInput(bool aE
mToDo->setInt32("input-eos", 1);
}
mDecoder->requestActivityNotification(mToDo);
} else if (aEndOfStream) {
mToDo->setInt32("input-eos", 1);
}
} else {
GMDD_LOG("input processed: error#%d", rv);
- mDecodeCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mDecodeCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
}
}
void
GonkDecoderManager::ProcessFlush()
{
MOZ_ASSERT(OnTaskLooper());
mLastTime = INT64_MIN;
MonitorAutoLock lock(mFlushMonitor);
mWaitOutput.Clear();
if (mDecoder->flush() != OK) {
GMDD_LOG("flush error");
- mDecodeCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mDecodeCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
}
mIsFlushing = false;
lock.NotifyAll();
}
// Use output timestamp to determine which output buffer is already returned
// and remove corresponding info, except for EOS, from the waiting list.
// This method handles the cases that audio decoder sends multiple output
@@ -220,17 +222,18 @@ void
GonkDecoderManager::ProcessToDo(bool aEndOfStream)
{
MOZ_ASSERT(OnTaskLooper());
MOZ_ASSERT(mToDo.get() != nullptr);
mToDo.clear();
if (NumQueuedSamples() > 0 && ProcessQueuedSamples() < 0) {
- mDecodeCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mDecodeCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
return;
}
while (mWaitOutput.Length() > 0) {
RefPtr<MediaData> output;
WaitOutputInfo wait = mWaitOutput.ElementAt(0);
nsresult rv = Output(wait.mOffset, output);
if (rv == NS_OK) {
@@ -247,17 +250,18 @@ GonkDecoderManager::ProcessToDo(bool aEn
MOZ_ASSERT(mWaitOutput.Length() == 1);
mWaitOutput.RemoveElementAt(0);
mDecodeCallback->DrainComplete();
ResetEOS();
return;
} else if (rv == NS_ERROR_NOT_AVAILABLE) {
break;
} else {
- mDecodeCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mDecodeCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
return;
}
}
if (!aEndOfStream && NumQueuedSamples() <= MIN_QUEUED_SAMPLES) {
mDecodeCallback->InputExhausted();
// No need to shedule todo task this time because InputExhausted() will
// cause Input() to be invoked and do it for us.
@@ -275,17 +279,18 @@ GonkDecoderManager::ProcessToDo(bool aEn
void
GonkDecoderManager::ResetEOS()
{
// After eos, android::MediaCodec needs to be flushed to receive next input
mWaitOutput.Clear();
if (mDecoder->flush() != OK) {
GMDD_LOG("flush error");
- mDecodeCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mDecodeCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
}
}
void
GonkDecoderManager::onMessageReceived(const sp<AMessage> &aMessage)
{
switch (aMessage->what()) {
case kNotifyProcessInput:
--- a/dom/media/platforms/omx/OmxDataDecoder.cpp
+++ b/dom/media/platforms/omx/OmxDataDecoder.cpp
@@ -425,19 +425,19 @@ OmxDataDecoder::EmptyBufferDone(BufferDa
void
OmxDataDecoder::EmptyBufferFailure(OmxBufferFailureHolder aFailureHolder)
{
NotifyError(aFailureHolder.mError, __func__);
}
void
-OmxDataDecoder::NotifyError(OMX_ERRORTYPE aOmxError, const char* aLine, MediaDataDecoderError aError)
+OmxDataDecoder::NotifyError(OMX_ERRORTYPE aOmxError, const char* aLine, const MediaResult& aError)
{
- LOG("NotifyError %d (%d) at %s", aOmxError, aError, aLine);
+ LOG("NotifyError %d (%d) at %s", aOmxError, aError.Code(), aLine);
mCallback->Error(aError);
}
void
OmxDataDecoder::FillAndEmptyBuffers()
{
MOZ_ASSERT(mOmxTaskQueue->IsCurrentThreadIn());
MOZ_ASSERT(mOmxState == OMX_StateExecuting);
@@ -685,17 +685,18 @@ OmxDataDecoder::Event(OMX_EVENTTYPE aEve
}
LOG("Got OMX_EventPortSettingsChanged event");
break;
}
default:
{
// Got error during decoding, send msg to MFR skipping to next key frame.
if (aEvent == OMX_EventError && mOmxState == OMX_StateExecuting) {
- NotifyError((OMX_ERRORTYPE)aData1, __func__, MediaDataDecoderError::DECODE_ERROR);
+ NotifyError((OMX_ERRORTYPE)aData1, __func__,
+ MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__));
return true;
}
LOG("WARNING: got none handle event: %d, aData1: %d, aData2: %d",
aEvent, aData1, aData2);
return false;
}
}
--- a/dom/media/platforms/omx/OmxDataDecoder.h
+++ b/dom/media/platforms/omx/OmxDataDecoder.h
@@ -98,17 +98,17 @@ protected:
void FillBufferFailure(OmxBufferFailureHolder aFailureHolder);
void EmptyBufferDone(BufferData* aData);
void EmptyBufferFailure(OmxBufferFailureHolder aFailureHolder);
void NotifyError(OMX_ERRORTYPE aOmxError,
const char* aLine,
- MediaDataDecoderError aError = MediaDataDecoderError::FATAL_ERROR);
+ const MediaResult& aError = MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR));
// Configure audio/video codec.
// Some codec may just ignore this and rely on codec specific data in
// FillCodecConfigDataToOmx().
void ConfigCodec();
// Sending codec specific data to OMX component. OMX component could send a
// OMX_EventPortSettingsChanged back to client. And then client needs to
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
@@ -118,17 +118,17 @@ WMFMediaDataDecoder::ProcessDecode(Media
if (mIsFlushing) {
// Skip sample, to be released by runnable.
return;
}
HRESULT hr = mMFTManager->Input(aSample);
if (FAILED(hr)) {
NS_WARNING("MFTManager rejected sample");
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__));
if (!mRecordedError) {
SendTelemetry(hr);
mRecordedError = true;
}
return;
}
mLastStreamOffset = aSample->mOffset;
@@ -145,17 +145,17 @@ WMFMediaDataDecoder::ProcessOutput()
output) {
mHasSuccessfulOutput = true;
mCallback->Output(output);
}
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
mCallback->InputExhausted();
} else if (FAILED(hr)) {
NS_WARNING("WMFMediaDataDecoder failed to output data");
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__));
if (!mRecordedError) {
SendTelemetry(hr);
mRecordedError = true;
}
}
}
void
--- a/dom/media/platforms/wrappers/FuzzingWrapper.cpp
+++ b/dom/media/platforms/wrappers/FuzzingWrapper.cpp
@@ -166,29 +166,27 @@ DecoderCallbackFuzzingWrapper::Output(Me
}
// Passing the data straight through, no need to dispatch to another queue,
// callback should deal with that.
mCallback->Output(aData);
}
void
-DecoderCallbackFuzzingWrapper::Error(MediaDataDecoderError aError)
+DecoderCallbackFuzzingWrapper::Error(const MediaResult& aError)
{
if (!mTaskQueue->IsCurrentThreadIn()) {
- mTaskQueue->Dispatch(
- NewRunnableMethod<MediaDataDecoderError>(this,
- &DecoderCallbackFuzzingWrapper::Error,
- aError));
+ mTaskQueue->Dispatch(NewRunnableMethod<MediaResult>(
+ this, &DecoderCallbackFuzzingWrapper::Error, aError));
return;
}
CFW_LOGV("");
MOZ_ASSERT(mCallback);
ClearDelayedOutput();
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(aError);
}
void
DecoderCallbackFuzzingWrapper::InputExhausted()
{
if (!mTaskQueue->IsCurrentThreadIn()) {
mTaskQueue->Dispatch(NewRunnableMethod(this, &DecoderCallbackFuzzingWrapper::InputExhausted));
return;
--- a/dom/media/platforms/wrappers/FuzzingWrapper.h
+++ b/dom/media/platforms/wrappers/FuzzingWrapper.h
@@ -55,17 +55,17 @@ public:
// in lots of frames being decoded and queued for delayed output!
void SetDontDelayInputExhausted(bool aDontDelayInputExhausted);
private:
virtual ~DecoderCallbackFuzzingWrapper();
// MediaDataDecoderCallback implementation.
void Output(MediaData* aData) override;
- void Error(MediaDataDecoderError aError) override;
+ void Error(const MediaResult& aError) override;
void InputExhausted() override;
void DrainComplete() override;
void ReleaseMediaResources() override;
bool OnReaderTaskQueue() override;
MediaDataDecoderCallback* mCallback;
// Settings for minimum frame output interval & InputExhausted,
--- a/dom/media/platforms/wrappers/H264Converter.cpp
+++ b/dom/media/platforms/wrappers/H264Converter.cpp
@@ -50,17 +50,17 @@ H264Converter::Init()
}
void
H264Converter::Input(MediaRawData* aSample)
{
if (!mp4_demuxer::AnnexB::ConvertSampleToAVCC(aSample)) {
// We need AVCC content to be able to later parse the SPS.
// This is a no-op if the data is already AVCC.
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
return;
}
if (mInitPromiseRequest.Exists()) {
if (mNeedKeyframe) {
if (!aSample->mKeyframe) {
// Frames dropped, we need a new one.
mCallback->InputExhausted();
@@ -83,28 +83,28 @@ H264Converter::Input(MediaRawData* aSamp
// Ignore for the time being, the MediaRawData will be dropped.
mCallback->InputExhausted();
return;
}
} else {
rv = CheckForSPSChange(aSample);
}
if (NS_FAILED(rv)) {
- mCallback->Error(MediaDataDecoderError::DECODE_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
return;
}
if (mNeedKeyframe && !aSample->mKeyframe) {
mCallback->InputExhausted();
return;
}
if (!mNeedAVCC &&
!mp4_demuxer::AnnexB::ConvertSampleToAnnexB(aSample)) {
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
return;
}
mNeedKeyframe = false;
aSample->mExtraData = mCurrentConfig.mExtraData;
mDecoder->Input(aSample);
@@ -247,17 +247,18 @@ H264Converter::OnDecoderInitDone(const T
}
mMediaRawSamples.Clear();
}
void
H264Converter::OnDecoderInitFailed(MediaDataDecoder::DecoderFailureReason aReason)
{
mInitPromiseRequest.Complete();
- mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ __func__));
}
nsresult
H264Converter::CheckForSPSChange(MediaRawData* aSample)
{
RefPtr<MediaByteBuffer> extra_data =
mp4_demuxer::AnnexB::ExtractExtraData(aSample);
if (!mp4_demuxer::AnnexB::HasSPS(extra_data) ||