зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1299072: P12. Use MediaResult for MediaDataDemuxer promises. r=gerald
MozReview-Commit-ID: JeQrmoHbb8m --HG-- extra : rebase_source : 1f4581e5789f18b358a6f5bb5f8595cc7a75110b
This commit is contained in:
Родитель
162fa5f03b
Коммит
20dc9102e8
|
@ -318,7 +318,7 @@ ADTSDemuxer::Init()
|
|||
ADTSLOG("Init() failure: waiting for data");
|
||||
|
||||
return InitPromise::CreateAndReject(
|
||||
DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
|
||||
}
|
||||
|
||||
ADTSLOG("Init() successful");
|
||||
|
@ -515,10 +515,7 @@ ADTSTrackDemuxer::GetSamples(int32_t aNumSamples)
|
|||
aNumSamples, mOffset, mNumParsedFrames, mFrameIndex, mTotalFrameLen,
|
||||
mSamplesPerFrame, mSamplesPerSecond, mChannels);
|
||||
|
||||
if (!aNumSamples) {
|
||||
return SamplesPromise::CreateAndReject(
|
||||
DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
}
|
||||
MOZ_ASSERT(aNumSamples);
|
||||
|
||||
RefPtr<SamplesHolder> frames = new SamplesHolder();
|
||||
|
||||
|
@ -540,7 +537,7 @@ ADTSTrackDemuxer::GetSamples(int32_t aNumSamples)
|
|||
|
||||
if (frames->mSamples.IsEmpty()) {
|
||||
return SamplesPromise::CreateAndReject(
|
||||
DemuxerFailureReason::END_OF_STREAM, __func__);
|
||||
NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
|
||||
}
|
||||
|
||||
return SamplesPromise::CreateAndResolve(frames, __func__);
|
||||
|
@ -562,7 +559,7 @@ ADTSTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold)
|
|||
{
|
||||
// Will not be called for audio-only resources.
|
||||
return SkipAccessPointPromise::CreateAndReject(
|
||||
SkipFailureHolder(DemuxerFailureReason::DEMUXER_ERROR, 0), __func__);
|
||||
SkipFailureHolder(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, 0), __func__);
|
||||
}
|
||||
|
||||
int64_t
|
||||
|
|
|
@ -169,7 +169,7 @@ BenchmarkPlayback::DemuxSamples()
|
|||
}
|
||||
DemuxNextSample();
|
||||
},
|
||||
[this, ref](DemuxerFailureReason aReason) { MainThreadShutdown(); });
|
||||
[this, ref](const MediaResult& aError) { MainThreadShutdown(); });
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -190,9 +190,9 @@ BenchmarkPlayback::DemuxNextSample()
|
|||
Dispatch(NS_NewRunnableFunction([this, ref]() { DemuxNextSample(); }));
|
||||
}
|
||||
},
|
||||
[this, ref](DemuxerFailureReason aReason) {
|
||||
switch (aReason) {
|
||||
case DemuxerFailureReason::END_OF_STREAM:
|
||||
[this, ref](const MediaResult& aError) {
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
InitDecoder(Move(*mTrackDemuxer->GetInfo()));
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -55,7 +55,7 @@ MP3Demuxer::Init() {
|
|||
MP3LOG("MP3Demuxer::Init() failure: waiting for data");
|
||||
|
||||
return InitPromise::CreateAndReject(
|
||||
DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
|
||||
}
|
||||
|
||||
MP3LOG("MP3Demuxer::Init() successful");
|
||||
|
@ -276,7 +276,7 @@ MP3TrackDemuxer::GetSamples(int32_t aNumSamples) {
|
|||
|
||||
if (!aNumSamples) {
|
||||
return SamplesPromise::CreateAndReject(
|
||||
DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
|
||||
}
|
||||
|
||||
RefPtr<SamplesHolder> frames = new SamplesHolder();
|
||||
|
@ -300,7 +300,7 @@ MP3TrackDemuxer::GetSamples(int32_t aNumSamples) {
|
|||
|
||||
if (frames->mSamples.IsEmpty()) {
|
||||
return SamplesPromise::CreateAndReject(
|
||||
DemuxerFailureReason::END_OF_STREAM, __func__);
|
||||
NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
|
||||
}
|
||||
return SamplesPromise::CreateAndResolve(frames, __func__);
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ RefPtr<MP3TrackDemuxer::SkipAccessPointPromise>
|
|||
MP3TrackDemuxer::SkipToNextRandomAccessPoint(TimeUnit aTimeThreshold) {
|
||||
// Will not be called for audio-only resources.
|
||||
return SkipAccessPointPromise::CreateAndReject(
|
||||
SkipFailureHolder(DemuxerFailureReason::DEMUXER_ERROR, 0), __func__);
|
||||
SkipFailureHolder(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, 0), __func__);
|
||||
}
|
||||
|
||||
int64_t
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "MediaData.h"
|
||||
#include "MediaInfo.h"
|
||||
#include "MediaResult.h"
|
||||
#include "TimeUnits.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
@ -22,16 +23,6 @@ namespace mozilla {
|
|||
class MediaTrackDemuxer;
|
||||
class TrackMetadataHolder;
|
||||
|
||||
enum class DemuxerFailureReason : int8_t
|
||||
{
|
||||
WAITING_FOR_DATA,
|
||||
END_OF_STREAM,
|
||||
DEMUXER_ERROR,
|
||||
CANCELED,
|
||||
SHUTDOWN,
|
||||
};
|
||||
|
||||
|
||||
// Allows reading the media data: to retrieve the metadata and demux samples.
|
||||
// MediaDataDemuxer isn't designed to be thread safe.
|
||||
// When used by the MediaFormatDecoder, care is taken to ensure that the demuxer
|
||||
|
@ -41,7 +32,7 @@ class MediaDataDemuxer
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDataDemuxer)
|
||||
|
||||
typedef MozPromise<nsresult, DemuxerFailureReason, /* IsExclusive = */ true> InitPromise;
|
||||
typedef MozPromise<nsresult, MediaResult, /* IsExclusive = */ true> InitPromise;
|
||||
|
||||
// Initializes the demuxer. Other methods cannot be called unless
|
||||
// initialization has completed and succeeded.
|
||||
|
@ -120,16 +111,16 @@ public:
|
|||
|
||||
class SkipFailureHolder {
|
||||
public:
|
||||
SkipFailureHolder(DemuxerFailureReason aFailure, uint32_t aSkipped)
|
||||
SkipFailureHolder(const MediaResult& aFailure, uint32_t aSkipped)
|
||||
: mFailure(aFailure)
|
||||
, mSkipped(aSkipped)
|
||||
{}
|
||||
DemuxerFailureReason mFailure;
|
||||
MediaResult mFailure;
|
||||
uint32_t mSkipped;
|
||||
};
|
||||
|
||||
typedef MozPromise<media::TimeUnit, DemuxerFailureReason, /* IsExclusive = */ true> SeekPromise;
|
||||
typedef MozPromise<RefPtr<SamplesHolder>, DemuxerFailureReason, /* IsExclusive = */ true> SamplesPromise;
|
||||
typedef MozPromise<media::TimeUnit, MediaResult, /* IsExclusive = */ true> SeekPromise;
|
||||
typedef MozPromise<RefPtr<SamplesHolder>, MediaResult, /* IsExclusive = */ true> SamplesPromise;
|
||||
typedef MozPromise<uint32_t, SkipFailureHolder, /* IsExclusive = */ true> SkipAccessPointPromise;
|
||||
|
||||
// Returns the TrackInfo (a.k.a Track Description) for this track.
|
||||
|
|
|
@ -376,10 +376,10 @@ MediaFormatReader::OnDemuxerInitDone(nsresult)
|
|||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::OnDemuxerInitFailed(DemuxerFailureReason aFailure)
|
||||
MediaFormatReader::OnDemuxerInitFailed(const MediaResult& aError)
|
||||
{
|
||||
mDemuxerInitRequest.Complete();
|
||||
mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
|
||||
mMetadataPromise.Reject(aError, __func__);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -568,37 +568,33 @@ MediaFormatReader::RequestVideoData(bool aSkipToNextKeyframe,
|
|||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::OnDemuxFailed(TrackType aTrack, DemuxerFailureReason aFailure)
|
||||
MediaFormatReader::OnDemuxFailed(TrackType aTrack, const MediaResult& aError)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
LOG("Failed to demux %s, failure:%d",
|
||||
aTrack == TrackType::kVideoTrack ? "video" : "audio", aFailure);
|
||||
LOG("Failed to demux %s, failure:%u",
|
||||
aTrack == TrackType::kVideoTrack ? "video" : "audio", aError.Code());
|
||||
auto& decoder = GetDecoderData(aTrack);
|
||||
decoder.mDemuxRequest.Complete();
|
||||
switch (aFailure) {
|
||||
case DemuxerFailureReason::END_OF_STREAM:
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
if (!decoder.mWaitingForData) {
|
||||
decoder.mNeedDraining = true;
|
||||
}
|
||||
NotifyEndOfStream(aTrack);
|
||||
break;
|
||||
case DemuxerFailureReason::DEMUXER_ERROR:
|
||||
NotifyError(aTrack);
|
||||
break;
|
||||
case DemuxerFailureReason::WAITING_FOR_DATA:
|
||||
case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
|
||||
if (!decoder.mWaitingForData) {
|
||||
decoder.mNeedDraining = true;
|
||||
}
|
||||
NotifyWaitingForData(aTrack);
|
||||
break;
|
||||
case DemuxerFailureReason::CANCELED: MOZ_FALLTHROUGH;
|
||||
case DemuxerFailureReason::SHUTDOWN:
|
||||
case NS_ERROR_DOM_MEDIA_CANCELED:
|
||||
if (decoder.HasPromise()) {
|
||||
decoder.RejectPromise(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false);
|
||||
NotifyError(aTrack, aError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1052,24 +1048,23 @@ MediaFormatReader::InternalSeek(TrackType aTrack, const InternalSeekTarget& aTar
|
|||
self->SetVideoDecodeThreshold();
|
||||
self->ScheduleUpdate(aTrack);
|
||||
},
|
||||
[self, aTrack] (DemuxerFailureReason aResult) {
|
||||
[self, aTrack] (const MediaResult& aError) {
|
||||
auto& decoder = self->GetDecoderData(aTrack);
|
||||
decoder.mSeekRequest.Complete();
|
||||
switch (aResult) {
|
||||
case DemuxerFailureReason::WAITING_FOR_DATA:
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
|
||||
self->NotifyWaitingForData(aTrack);
|
||||
break;
|
||||
case DemuxerFailureReason::END_OF_STREAM:
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
decoder.mTimeThreshold.reset();
|
||||
self->NotifyEndOfStream(aTrack);
|
||||
break;
|
||||
case DemuxerFailureReason::CANCELED: MOZ_FALLTHROUGH;
|
||||
case DemuxerFailureReason::SHUTDOWN:
|
||||
case NS_ERROR_DOM_MEDIA_CANCELED:
|
||||
decoder.mTimeThreshold.reset();
|
||||
break;
|
||||
default:
|
||||
decoder.mTimeThreshold.reset();
|
||||
self->NotifyError(aTrack);
|
||||
self->NotifyError(aTrack, aError);
|
||||
break;
|
||||
}
|
||||
}));
|
||||
|
@ -1566,9 +1561,9 @@ MediaFormatReader::OnVideoSkipFailed(MediaTrackDemuxer::SkipFailureHolder aFailu
|
|||
LOG("Skipping failed, skipped %u frames", aFailure.mSkipped);
|
||||
mSkipRequest.Complete();
|
||||
|
||||
switch (aFailure.mFailure) {
|
||||
case DemuxerFailureReason::END_OF_STREAM: MOZ_FALLTHROUGH;
|
||||
case DemuxerFailureReason::WAITING_FOR_DATA:
|
||||
switch (aFailure.mFailure.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
|
||||
// Some frames may have been output by the decoder since we initiated the
|
||||
// videoskip process and we know they would be late.
|
||||
DropDecodedSamples(TrackInfo::kVideoTrack);
|
||||
|
@ -1576,14 +1571,13 @@ MediaFormatReader::OnVideoSkipFailed(MediaTrackDemuxer::SkipFailureHolder aFailu
|
|||
// normally.
|
||||
ScheduleUpdate(TrackInfo::kVideoTrack);
|
||||
break;
|
||||
case DemuxerFailureReason::CANCELED: MOZ_FALLTHROUGH;
|
||||
case DemuxerFailureReason::SHUTDOWN:
|
||||
case NS_ERROR_DOM_MEDIA_CANCELED:
|
||||
if (mVideo.HasPromise()) {
|
||||
mVideo.RejectPromise(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
|
||||
mVideo.RejectPromise(aFailure.mFailure, __func__);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NotifyError(TrackType::kVideoTrack);
|
||||
NotifyError(TrackType::kVideoTrack, aFailure.mFailure);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1695,17 +1689,17 @@ MediaFormatReader::AttemptSeek()
|
|||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::OnSeekFailed(TrackType aTrack, DemuxerFailureReason aResult)
|
||||
MediaFormatReader::OnSeekFailed(TrackType aTrack, const MediaResult& aError)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
LOGV("%s failure:%d", TrackTypeToStr(aTrack), aResult);
|
||||
LOGV("%s failure:%u", TrackTypeToStr(aTrack), aError.Code());
|
||||
if (aTrack == TrackType::kVideoTrack) {
|
||||
mVideo.mSeekRequest.Complete();
|
||||
} else {
|
||||
mAudio.mSeekRequest.Complete();
|
||||
}
|
||||
|
||||
if (aResult == DemuxerFailureReason::WAITING_FOR_DATA) {
|
||||
if (aError == NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA) {
|
||||
if (HasVideo() && aTrack == TrackType::kAudioTrack &&
|
||||
mFallbackSeekTime.isSome() &&
|
||||
mPendingSeekTime.ref() != mFallbackSeekTime.ref()) {
|
||||
|
@ -1739,7 +1733,7 @@ MediaFormatReader::OnSeekFailed(TrackType aTrack, DemuxerFailureReason aResult)
|
|||
}
|
||||
MOZ_ASSERT(!mVideo.mSeekRequest.Exists() && !mAudio.mSeekRequest.Exists());
|
||||
mPendingSeekTime.reset();
|
||||
mSeekPromise.Reject(NS_ERROR_FAILURE, __func__);
|
||||
mSeekPromise.Reject(aError, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1780,10 +1774,10 @@ MediaFormatReader::OnVideoSeekCompleted(media::TimeUnit aTime)
|
|||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::OnVideoSeekFailed(DemuxerFailureReason aFailure)
|
||||
MediaFormatReader::OnVideoSeekFailed(const MediaResult& aError)
|
||||
{
|
||||
mPreviousDecodedKeyframeTime_us = sNoPreviousDecodedKeyframe;
|
||||
OnSeekFailed(TrackType::kVideoTrack, aFailure);
|
||||
OnSeekFailed(TrackType::kVideoTrack, aError);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1847,9 +1841,9 @@ MediaFormatReader::OnAudioSeekCompleted(media::TimeUnit aTime)
|
|||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::OnAudioSeekFailed(DemuxerFailureReason aFailure)
|
||||
MediaFormatReader::OnAudioSeekFailed(const MediaResult& aError)
|
||||
{
|
||||
OnSeekFailed(TrackType::kAudioTrack, aFailure);
|
||||
OnSeekFailed(TrackType::kAudioTrack, aError);
|
||||
}
|
||||
|
||||
media::TimeIntervals
|
||||
|
|
|
@ -488,22 +488,22 @@ private:
|
|||
RefPtr<MediaDataDemuxer> mDemuxer;
|
||||
bool mDemuxerInitDone;
|
||||
void OnDemuxerInitDone(nsresult);
|
||||
void OnDemuxerInitFailed(DemuxerFailureReason aFailure);
|
||||
void OnDemuxerInitFailed(const MediaResult& aError);
|
||||
MozPromiseRequestHolder<MediaDataDemuxer::InitPromise> mDemuxerInitRequest;
|
||||
void OnDemuxFailed(TrackType aTrack, DemuxerFailureReason aFailure);
|
||||
void OnDemuxFailed(TrackType aTrack, const MediaResult& aError);
|
||||
|
||||
void DoDemuxVideo();
|
||||
void OnVideoDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
|
||||
void OnVideoDemuxFailed(DemuxerFailureReason aFailure)
|
||||
void OnVideoDemuxFailed(const MediaResult& aError)
|
||||
{
|
||||
OnDemuxFailed(TrackType::kVideoTrack, aFailure);
|
||||
OnDemuxFailed(TrackType::kVideoTrack, aError);
|
||||
}
|
||||
|
||||
void DoDemuxAudio();
|
||||
void OnAudioDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
|
||||
void OnAudioDemuxFailed(DemuxerFailureReason aFailure)
|
||||
void OnAudioDemuxFailed(const MediaResult& aError)
|
||||
{
|
||||
OnDemuxFailed(TrackType::kAudioTrack, aFailure);
|
||||
OnDemuxFailed(TrackType::kAudioTrack, aError);
|
||||
}
|
||||
|
||||
void SkipVideoDemuxToNextKeyFrame(media::TimeUnit aTimeThreshold);
|
||||
|
@ -551,15 +551,15 @@ private:
|
|||
}
|
||||
void ScheduleSeek();
|
||||
void AttemptSeek();
|
||||
void OnSeekFailed(TrackType aTrack, DemuxerFailureReason aFailure);
|
||||
void OnSeekFailed(TrackType aTrack, const MediaResult& aError);
|
||||
void DoVideoSeek();
|
||||
void OnVideoSeekCompleted(media::TimeUnit aTime);
|
||||
void OnVideoSeekFailed(DemuxerFailureReason aFailure);
|
||||
void OnVideoSeekFailed(const MediaResult& aError);
|
||||
bool mSeekScheduled;
|
||||
|
||||
void DoAudioSeek();
|
||||
void OnAudioSeekCompleted(media::TimeUnit aTime);
|
||||
void OnAudioSeekFailed(DemuxerFailureReason aFailure);
|
||||
void OnAudioSeekFailed(const MediaResult& aError);
|
||||
// The SeekTarget that was last given to Seek()
|
||||
SeekTarget mOriginalSeekTarget;
|
||||
// Temporary seek information while we wait for the data
|
||||
|
|
|
@ -584,7 +584,7 @@ FlacDemuxer::Init()
|
|||
LOG("Init() failure: waiting for data");
|
||||
|
||||
return InitPromise::CreateAndReject(
|
||||
DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
|
||||
}
|
||||
|
||||
LOG("Init() successful");
|
||||
|
@ -855,7 +855,7 @@ FlacTrackDemuxer::GetSamples(int32_t aNumSamples)
|
|||
|
||||
if (!aNumSamples) {
|
||||
return SamplesPromise::CreateAndReject(
|
||||
DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
|
||||
}
|
||||
|
||||
RefPtr<SamplesHolder> frames = new SamplesHolder();
|
||||
|
@ -875,7 +875,7 @@ FlacTrackDemuxer::GetSamples(int32_t aNumSamples)
|
|||
|
||||
if (frames->mSamples.IsEmpty()) {
|
||||
return SamplesPromise::CreateAndReject(
|
||||
DemuxerFailureReason::END_OF_STREAM, __func__);
|
||||
NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
|
||||
}
|
||||
|
||||
return SamplesPromise::CreateAndResolve(frames, __func__);
|
||||
|
@ -899,7 +899,7 @@ FlacTrackDemuxer::SkipToNextRandomAccessPoint(TimeUnit aTimeThreshold)
|
|||
{
|
||||
// Will not be called for audio-only resources.
|
||||
return SkipAccessPointPromise::CreateAndReject(
|
||||
SkipFailureHolder(DemuxerFailureReason::DEMUXER_ERROR, 0), __func__);
|
||||
SkipFailureHolder(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, 0), __func__);
|
||||
}
|
||||
|
||||
int64_t
|
||||
|
|
|
@ -125,13 +125,13 @@ MP4Demuxer::Init()
|
|||
|
||||
// Check that we have enough data to read the metadata.
|
||||
if (!mp4_demuxer::MP4Metadata::HasCompleteMetadata(stream)) {
|
||||
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
|
||||
}
|
||||
|
||||
mInitData = mp4_demuxer::MP4Metadata::Metadata(stream);
|
||||
if (!mInitData) {
|
||||
// OOM
|
||||
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
|
||||
}
|
||||
|
||||
RefPtr<mp4_demuxer::BufferStream> bufferstream =
|
||||
|
@ -141,7 +141,7 @@ MP4Demuxer::Init()
|
|||
|
||||
if (!mMetadata->GetNumberTracks(mozilla::TrackInfo::kAudioTrack) &&
|
||||
!mMetadata->GetNumberTracks(mozilla::TrackInfo::kVideoTrack)) {
|
||||
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
|
||||
}
|
||||
|
||||
return InitPromise::CreateAndResolve(NS_OK, __func__);
|
||||
|
@ -298,7 +298,7 @@ MP4TrackDemuxer::Seek(media::TimeUnit aTime)
|
|||
do {
|
||||
sample = GetNextSample();
|
||||
if (!sample) {
|
||||
return SeekPromise::CreateAndReject(DemuxerFailureReason::END_OF_STREAM, __func__);
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
|
||||
}
|
||||
if (!sample->Size()) {
|
||||
// This sample can't be decoded, continue searching.
|
||||
|
@ -370,7 +370,7 @@ MP4TrackDemuxer::GetSamples(int32_t aNumSamples)
|
|||
EnsureUpToDateIndex();
|
||||
RefPtr<SamplesHolder> samples = new SamplesHolder;
|
||||
if (!aNumSamples) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
|
||||
}
|
||||
|
||||
if (mQueuedSample) {
|
||||
|
@ -390,7 +390,7 @@ MP4TrackDemuxer::GetSamples(int32_t aNumSamples)
|
|||
}
|
||||
|
||||
if (samples->mSamples.IsEmpty()) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::END_OF_STREAM, __func__);
|
||||
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
|
||||
} else {
|
||||
for (const auto& sample : samples->mSamples) {
|
||||
// Collect telemetry from h264 Annex B SPS.
|
||||
|
@ -461,7 +461,7 @@ MP4TrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold)
|
|||
if (found) {
|
||||
return SkipAccessPointPromise::CreateAndResolve(parsed, __func__);
|
||||
} else {
|
||||
SkipFailureHolder failure(DemuxerFailureReason::END_OF_STREAM, parsed);
|
||||
SkipFailureHolder failure(NS_ERROR_DOM_MEDIA_END_OF_STREAM, parsed);
|
||||
return SkipAccessPointPromise::CreateAndReject(Move(failure), __func__);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,11 +119,8 @@ public:
|
|||
binding->CheckTrackSamples(track);
|
||||
}
|
||||
},
|
||||
[binding] (DemuxerFailureReason aReason) {
|
||||
if (aReason == DemuxerFailureReason::DEMUXER_ERROR) {
|
||||
EXPECT_TRUE(false);
|
||||
binding->mCheckTrackSamples.Reject(NS_ERROR_FAILURE, __func__);
|
||||
} else if (aReason == DemuxerFailureReason::END_OF_STREAM) {
|
||||
[binding] (const MediaResult& aError) {
|
||||
if (aError == NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
|
||||
EXPECT_TRUE(binding->mSamples.Length() > 1);
|
||||
for (uint32_t i = 0; i < (binding->mSamples.Length() - 1); i++) {
|
||||
EXPECT_LT(binding->mSamples[i]->mTimecode, binding->mSamples[i + 1]->mTimecode);
|
||||
|
@ -132,6 +129,9 @@ public:
|
|||
}
|
||||
}
|
||||
binding->mCheckTrackSamples.Resolve(true, __func__);
|
||||
} else {
|
||||
EXPECT_TRUE(false);
|
||||
binding->mCheckTrackSamples.Reject(aError, __func__);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -247,7 +247,7 @@ MediaSourceDemuxer::GetManager(TrackType aTrack)
|
|||
|
||||
MediaSourceDemuxer::~MediaSourceDemuxer()
|
||||
{
|
||||
mInitPromise.RejectIfExists(DemuxerFailureReason::SHUTDOWN, __func__);
|
||||
mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -397,7 +397,7 @@ MediaSourceTrackDemuxer::DoSeek(media::TimeUnit aTime)
|
|||
if (!buffered.ContainsWithStrictEnd(seekTime)) {
|
||||
if (!buffered.ContainsWithStrictEnd(aTime)) {
|
||||
// We don't have the data to seek to.
|
||||
return SeekPromise::CreateAndReject(DemuxerFailureReason::WAITING_FOR_DATA,
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA,
|
||||
__func__);
|
||||
}
|
||||
// Theoretically we should reject the promise with WAITING_FOR_DATA,
|
||||
|
@ -438,11 +438,11 @@ MediaSourceTrackDemuxer::DoGetSamples(int32_t aNumSamples)
|
|||
buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ / 2);
|
||||
|
||||
if (!buffered.Length() && mManager->IsEnded()) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::END_OF_STREAM,
|
||||
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM,
|
||||
__func__);
|
||||
}
|
||||
if (!buffered.ContainsWithStrictEnd(TimeUnit::FromMicroseconds(0))) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::WAITING_FOR_DATA,
|
||||
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA,
|
||||
__func__);
|
||||
}
|
||||
mReset = false;
|
||||
|
@ -456,12 +456,12 @@ MediaSourceTrackDemuxer::DoGetSamples(int32_t aNumSamples)
|
|||
sample = mManager->GetSample(mType, MediaSourceDemuxer::EOS_FUZZ, result);
|
||||
if (!sample) {
|
||||
if (result == Result::ERROR) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
|
||||
}
|
||||
return SamplesPromise::CreateAndReject(
|
||||
(result == Result::EOS && mManager->IsEnded())
|
||||
? DemuxerFailureReason::END_OF_STREAM
|
||||
: DemuxerFailureReason::WAITING_FOR_DATA, __func__);
|
||||
? NS_ERROR_DOM_MEDIA_END_OF_STREAM
|
||||
: NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA, __func__);
|
||||
}
|
||||
}
|
||||
RefPtr<SamplesHolder> samples = new SamplesHolder;
|
||||
|
@ -492,8 +492,8 @@ MediaSourceTrackDemuxer::DoSkipToNextRandomAccessPoint(media::TimeUnit aTimeThre
|
|||
}
|
||||
}
|
||||
SkipFailureHolder holder(
|
||||
mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
|
||||
DemuxerFailureReason::WAITING_FOR_DATA, parsed);
|
||||
mManager->IsEnded() ? NS_ERROR_DOM_MEDIA_END_OF_STREAM :
|
||||
NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA, parsed);
|
||||
return SkipAccessPointPromise::CreateAndReject(holder, __func__);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
class MediaResult;
|
||||
class MediaSourceTrackDemuxer;
|
||||
|
||||
class MediaSourceDemuxer : public MediaDataDemuxer
|
||||
|
@ -119,7 +120,7 @@ private:
|
|||
RefPtr<SeekPromise> DoSeek(media::TimeUnit aTime);
|
||||
RefPtr<SamplesPromise> DoGetSamples(int32_t aNumSamples);
|
||||
RefPtr<SkipAccessPointPromise> DoSkipToNextRandomAccessPoint(media::TimeUnit aTimeThreadshold);
|
||||
already_AddRefed<MediaRawData> GetSample(DemuxerFailureReason& aFailure);
|
||||
already_AddRefed<MediaRawData> GetSample(MediaResult& aError);
|
||||
// Return the timestamp of the next keyframe after mLastSampleIndex.
|
||||
media::TimeUnit GetNextRandomAccessPoint();
|
||||
|
||||
|
|
|
@ -451,7 +451,7 @@ SourceBuffer::AppendDataErrored(const MediaResult& aError)
|
|||
mPendingAppend.Complete();
|
||||
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_ABORT:
|
||||
case NS_ERROR_DOM_MEDIA_CANCELED:
|
||||
// Nothing further to do as the trackbuffer has been shutdown.
|
||||
// or append was aborted and abort() has handled all the events.
|
||||
break;
|
||||
|
|
|
@ -1095,12 +1095,12 @@ TrackBuffersManager::OnDemuxerInitDone(nsresult)
|
|||
}
|
||||
|
||||
void
|
||||
TrackBuffersManager::OnDemuxerInitFailed(DemuxerFailureReason aFailure)
|
||||
TrackBuffersManager::OnDemuxerInitFailed(const MediaResult& aError)
|
||||
{
|
||||
MOZ_ASSERT(aFailure != DemuxerFailureReason::WAITING_FOR_DATA);
|
||||
MOZ_ASSERT(aError != NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
|
||||
mDemuxerInitRequest.Complete();
|
||||
|
||||
RejectAppend(NS_ERROR_FAILURE, __func__);
|
||||
RejectAppend(aError, __func__);
|
||||
}
|
||||
|
||||
RefPtr<TrackBuffersManager::CodedFrameProcessingPromise>
|
||||
|
@ -1149,29 +1149,22 @@ TrackBuffersManager::CodedFrameProcessing()
|
|||
|
||||
void
|
||||
TrackBuffersManager::OnDemuxFailed(TrackType aTrack,
|
||||
DemuxerFailureReason aFailure)
|
||||
const MediaResult& aError)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
MSE_DEBUG("Failed to demux %s, failure:%d",
|
||||
aTrack == TrackType::kVideoTrack ? "video" : "audio", aFailure);
|
||||
switch (aFailure) {
|
||||
case DemuxerFailureReason::END_OF_STREAM:
|
||||
case DemuxerFailureReason::WAITING_FOR_DATA:
|
||||
MSE_DEBUG("Failed to demux %s, failure:%u",
|
||||
aTrack == TrackType::kVideoTrack ? "video" : "audio", aError.Code());
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
|
||||
if (aTrack == TrackType::kVideoTrack) {
|
||||
DoDemuxAudio();
|
||||
} else {
|
||||
CompleteCodedFrameProcessing();
|
||||
}
|
||||
break;
|
||||
case DemuxerFailureReason::DEMUXER_ERROR:
|
||||
RejectProcessing(NS_ERROR_FAILURE, __func__);
|
||||
break;
|
||||
case DemuxerFailureReason::CANCELED:
|
||||
case DemuxerFailureReason::SHUTDOWN:
|
||||
RejectProcessing(NS_ERROR_ABORT, __func__);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false);
|
||||
RejectProcessing(aError, __func__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace mozilla {
|
|||
class ContainerParser;
|
||||
class MediaByteBuffer;
|
||||
class MediaRawData;
|
||||
class MediaResult;
|
||||
class MediaSourceDemuxer;
|
||||
class SourceBufferResource;
|
||||
|
||||
|
@ -243,25 +244,25 @@ private:
|
|||
Maybe<media::TimeUnit> mLastParsedEndTime;
|
||||
|
||||
void OnDemuxerInitDone(nsresult);
|
||||
void OnDemuxerInitFailed(DemuxerFailureReason aFailure);
|
||||
void OnDemuxerInitFailed(const MediaResult& aFailure);
|
||||
void OnDemuxerResetDone(nsresult);
|
||||
MozPromiseRequestHolder<MediaDataDemuxer::InitPromise> mDemuxerInitRequest;
|
||||
bool mEncrypted;
|
||||
|
||||
void OnDemuxFailed(TrackType aTrack, DemuxerFailureReason aFailure);
|
||||
void OnDemuxFailed(TrackType aTrack, const MediaResult& aError);
|
||||
void DoDemuxVideo();
|
||||
void OnVideoDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
|
||||
void OnVideoDemuxFailed(DemuxerFailureReason aFailure)
|
||||
void OnVideoDemuxFailed(const MediaResult& aError)
|
||||
{
|
||||
mVideoTracks.mDemuxRequest.Complete();
|
||||
OnDemuxFailed(TrackType::kVideoTrack, aFailure);
|
||||
OnDemuxFailed(TrackType::kVideoTrack, aError);
|
||||
}
|
||||
void DoDemuxAudio();
|
||||
void OnAudioDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
|
||||
void OnAudioDemuxFailed(DemuxerFailureReason aFailure)
|
||||
void OnAudioDemuxFailed(const MediaResult& aError)
|
||||
{
|
||||
mAudioTracks.mDemuxRequest.Complete();
|
||||
OnDemuxFailed(TrackType::kAudioTrack, aFailure);
|
||||
OnDemuxFailed(TrackType::kAudioTrack, aError);
|
||||
}
|
||||
|
||||
void DoEvictData(const media::TimeUnit& aPlaybackTime, int64_t aSizeToEvict);
|
||||
|
|
|
@ -215,24 +215,19 @@ OggDemuxer::Init()
|
|||
{
|
||||
int ret = ogg_sync_init(OggSyncState(TrackInfo::kAudioTrack));
|
||||
if (ret != 0) {
|
||||
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return InitPromise::CreateAndReject(NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
}
|
||||
ret = ogg_sync_init(OggSyncState(TrackInfo::kVideoTrack));
|
||||
if (ret != 0) {
|
||||
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return InitPromise::CreateAndReject(NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
}
|
||||
/*
|
||||
if (InitBufferedState() != NS_OK) {
|
||||
return InitPromise::CreateAndReject(DemuxerFailureReason::WAITING_FOR_DATA, __func__);
|
||||
}
|
||||
*/
|
||||
if (ReadMetadata() != NS_OK) {
|
||||
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
|
||||
}
|
||||
|
||||
if (!GetNumberTracks(TrackInfo::kAudioTrack) &&
|
||||
!GetNumberTracks(TrackInfo::kVideoTrack)) {
|
||||
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
|
||||
}
|
||||
|
||||
return InitPromise::CreateAndResolve(NS_OK, __func__);
|
||||
|
@ -1483,7 +1478,7 @@ OggTrackDemuxer::Seek(TimeUnit aTime)
|
|||
|
||||
return SeekPromise::CreateAndResolve(seekTime, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1516,7 +1511,7 @@ OggTrackDemuxer::GetSamples(int32_t aNumSamples)
|
|||
{
|
||||
RefPtr<SamplesHolder> samples = new SamplesHolder;
|
||||
if (!aNumSamples) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
|
||||
}
|
||||
|
||||
while (aNumSamples) {
|
||||
|
@ -1529,7 +1524,7 @@ OggTrackDemuxer::GetSamples(int32_t aNumSamples)
|
|||
}
|
||||
|
||||
if (samples->mSamples.IsEmpty()) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::END_OF_STREAM, __func__);
|
||||
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
|
||||
} else {
|
||||
return SamplesPromise::CreateAndResolve(samples, __func__);
|
||||
}
|
||||
|
@ -1563,7 +1558,7 @@ OggTrackDemuxer::SkipToNextRandomAccessPoint(TimeUnit aTimeThreshold)
|
|||
parsed);
|
||||
return SkipAccessPointPromise::CreateAndResolve(parsed, __func__);
|
||||
} else {
|
||||
SkipFailureHolder failure(DemuxerFailureReason::END_OF_STREAM, parsed);
|
||||
SkipFailureHolder failure(NS_ERROR_DOM_MEDIA_END_OF_STREAM, parsed);
|
||||
return SkipAccessPointPromise::CreateAndReject(Move(failure), __func__);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ WAVDemuxer::Init()
|
|||
{
|
||||
if (!InitInternal()) {
|
||||
return InitPromise::CreateAndReject(
|
||||
DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
|
||||
}
|
||||
return InitPromise::CreateAndResolve(NS_OK, __func__);
|
||||
}
|
||||
|
@ -340,10 +340,7 @@ WAVTrackDemuxer::ScanUntil(const TimeUnit& aTime)
|
|||
RefPtr<WAVTrackDemuxer::SamplesPromise>
|
||||
WAVTrackDemuxer::GetSamples(int32_t aNumSamples)
|
||||
{
|
||||
if (!aNumSamples) {
|
||||
return SamplesPromise::CreateAndReject(
|
||||
DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
}
|
||||
MOZ_ASSERT(aNumSamples);
|
||||
|
||||
RefPtr<SamplesHolder> datachunks = new SamplesHolder();
|
||||
|
||||
|
@ -357,7 +354,7 @@ WAVTrackDemuxer::GetSamples(int32_t aNumSamples)
|
|||
|
||||
if (datachunks->mSamples.IsEmpty()) {
|
||||
return SamplesPromise::CreateAndReject(
|
||||
DemuxerFailureReason::END_OF_STREAM, __func__);
|
||||
NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
|
||||
}
|
||||
|
||||
return SamplesPromise::CreateAndResolve(datachunks, __func__);
|
||||
|
@ -377,7 +374,7 @@ RefPtr<WAVTrackDemuxer::SkipAccessPointPromise>
|
|||
WAVTrackDemuxer::SkipToNextRandomAccessPoint(TimeUnit aTimeThreshold)
|
||||
{
|
||||
return SkipAccessPointPromise::CreateAndReject(
|
||||
SkipFailureHolder(DemuxerFailureReason::DEMUXER_ERROR, 0), __func__);
|
||||
SkipFailureHolder(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, 0), __func__);
|
||||
}
|
||||
|
||||
int64_t
|
||||
|
|
|
@ -188,12 +188,12 @@ WebMDemuxer::Init()
|
|||
InitBufferedState();
|
||||
|
||||
if (NS_FAILED(ReadMetadata())) {
|
||||
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
|
||||
}
|
||||
|
||||
if (!GetNumberTracks(TrackInfo::kAudioTrack) &&
|
||||
!GetNumberTracks(TrackInfo::kVideoTrack)) {
|
||||
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
|
||||
}
|
||||
|
||||
return InitPromise::CreateAndResolve(NS_OK, __func__);
|
||||
|
@ -955,9 +955,7 @@ RefPtr<WebMTrackDemuxer::SamplesPromise>
|
|||
WebMTrackDemuxer::GetSamples(int32_t aNumSamples)
|
||||
{
|
||||
RefPtr<SamplesHolder> samples = new SamplesHolder;
|
||||
if (!aNumSamples) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
}
|
||||
MOZ_ASSERT(aNumSamples);
|
||||
|
||||
while (aNumSamples) {
|
||||
RefPtr<MediaRawData> sample(NextSample());
|
||||
|
@ -973,7 +971,7 @@ WebMTrackDemuxer::GetSamples(int32_t aNumSamples)
|
|||
}
|
||||
|
||||
if (samples->mSamples.IsEmpty()) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::END_OF_STREAM, __func__);
|
||||
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
|
||||
} else {
|
||||
UpdateSamples(samples->mSamples);
|
||||
return SamplesPromise::CreateAndResolve(samples, __func__);
|
||||
|
@ -1109,7 +1107,7 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold)
|
|||
parsed);
|
||||
return SkipAccessPointPromise::CreateAndResolve(parsed, __func__);
|
||||
} else {
|
||||
SkipFailureHolder failure(DemuxerFailureReason::END_OF_STREAM, parsed);
|
||||
SkipFailureHolder failure(NS_ERROR_DOM_MEDIA_END_OF_STREAM, parsed);
|
||||
return SkipAccessPointPromise::CreateAndReject(Move(failure), __func__);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче