Bug 1299072: P7. Use MediaResult with MetadataPromise. r?cpearce
MozReview-Commit-ID: KrRr8wDuPNT
--- a/dom/media/MediaDecoderReader.cpp
+++ b/dom/media/MediaDecoderReader.cpp
@@ -355,31 +355,29 @@ MediaDecoderReader::GetBuffered()
}
return GetEstimatedBufferedTimeRanges(stream, mDuration.Ref().ref().ToMicroseconds());
}
RefPtr<MediaDecoderReader::MetadataPromise>
MediaDecoderReader::AsyncReadMetadata()
{
- typedef ReadMetadataFailureReason Reason;
-
MOZ_ASSERT(OnTaskQueue());
DECODER_LOG("MediaDecoderReader::AsyncReadMetadata");
// Attempt to read the metadata.
RefPtr<MetadataHolder> metadata = new MetadataHolder();
nsresult rv = ReadMetadata(&metadata->mInfo, getter_Transfers(metadata->mTags));
metadata->mInfo.AssertValid();
// We're not waiting for anything. If we didn't get the metadata, that's an
// error.
if (NS_FAILED(rv) || !metadata->mInfo.HasValidMedia()) {
DECODER_WARN("ReadMetadata failed, rv=%x HasValidMedia=%d", rv, metadata->mInfo.HasValidMedia());
- return MetadataPromise::CreateAndReject(Reason::METADATA_ERROR, __func__);
+ return MetadataPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
}
// Success!
return MetadataPromise::CreateAndResolve(metadata, __func__);
}
class ReRequestVideoWithSkipTask : public Runnable
{
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -46,38 +46,33 @@ public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MetadataHolder)
MediaInfo mInfo;
nsAutoPtr<MetadataTags> mTags;
private:
virtual ~MetadataHolder() {}
};
-enum class ReadMetadataFailureReason : int8_t
-{
- METADATA_ERROR
-};
-
// Encapsulates the decoding and reading of media data. Reading can either
// synchronous and done on the calling "decode" thread, or asynchronous and
// performed on a background thread, with the result being returned by
// callback. Never hold the decoder monitor when calling into this class.
// Unless otherwise specified, methods and fields of this class can only
// be accessed on the decode task queue.
class MediaDecoderReader {
friend class ReRequestVideoWithSkipTask;
friend class ReRequestAudioTask;
static const bool IsExclusive = true;
public:
using TrackSet = EnumSet<TrackInfo::TrackType>;
using MetadataPromise =
- MozPromise<RefPtr<MetadataHolder>, ReadMetadataFailureReason, IsExclusive>;
+ MozPromise<RefPtr<MetadataHolder>, MediaResult, IsExclusive>;
using MediaDataPromise =
MozPromise<RefPtr<MediaData>, MediaResult, IsExclusive>;
using SeekPromise = MozPromise<media::TimeUnit, nsresult, IsExclusive>;
// Note that, conceptually, WaitForData makes sense in a non-exclusive sense.
// But in the current architecture it's only ever used exclusively (by MDSM),
// so we mark it that way to verify our assumptions. If you have a use-case
// for multiple WaitForData consumers, feel free to flip the exclusivity here.
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -258,18 +258,18 @@ public:
// We disconnect mMetadataRequest in Exit() so it is fine to capture
// a raw pointer here.
mMetadataRequest.Begin(Reader()->ReadMetadata()
->Then(OwnerThread(), __func__,
[this] (MetadataHolder* aMetadata) {
OnMetadataRead(aMetadata);
},
- [this] (ReadMetadataFailureReason aReason) {
- OnMetadataNotRead(aReason);
+ [this] (const MediaResult& aError) {
+ OnMetadataNotRead(aError);
}));
}
void Exit() override
{
mMetadataRequest.DisconnectIfExists();
}
@@ -350,21 +350,21 @@ private:
// to become available so that we can build the correct decryptor/decoder.
SetState(DECODER_STATE_WAIT_FOR_CDM);
return;
}
SetState(DECODER_STATE_DECODING_FIRSTFRAME);
}
- void OnMetadataNotRead(ReadMetadataFailureReason aReason)
+ void OnMetadataNotRead(const MediaResult& aError)
{
mMetadataRequest.Complete();
SWARN("Decode metadata failed, shutting down decoder");
- mMaster->DecodeError();
+ mMaster->DecodeError(aError);
}
MozPromiseRequestHolder<MediaDecoderReader::MetadataPromise> mMetadataRequest;
// True if we need to enter dormant state after reading metadata. Note that
// we can't enter dormant state until reading metadata is done for some
// limitations of the reader.
bool mPendingDormant = false;
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -88,17 +88,17 @@ MediaFormatReader::~MediaFormatReader()
}
RefPtr<ShutdownPromise>
MediaFormatReader::Shutdown()
{
MOZ_ASSERT(OnTaskQueue());
mDemuxerInitRequest.DisconnectIfExists();
- mMetadataPromise.RejectIfExists(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+ mMetadataPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
mSeekPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
mSkipRequest.DisconnectIfExists();
if (mAudio.mDecoder) {
Reset(TrackInfo::kAudioTrack);
if (mAudio.HasPromise()) {
mAudio.RejectPromise(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
}
@@ -278,26 +278,26 @@ MediaFormatReader::OnDemuxerInitDone(nsr
// To decode, we need valid video and a place to put it.
bool videoActive = !!mDemuxer->GetNumberTracks(TrackInfo::kVideoTrack) &&
GetImageContainer();
if (videoActive) {
// We currently only handle the first video track.
mVideo.mTrackDemuxer = mDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0);
if (!mVideo.mTrackDemuxer) {
- mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+ mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
return;
}
UniquePtr<TrackInfo> videoInfo = mVideo.mTrackDemuxer->GetInfo();
videoActive = videoInfo && videoInfo->IsValid();
if (videoActive) {
if (platform && !platform->SupportsMimeType(videoInfo->mMimeType, nullptr)) {
// We have no decoder for this track. Error.
- mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+ mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
return;
}
mInfo.mVideo = *videoInfo->GetAsVideoInfo();
for (const MetadataTag& tag : videoInfo->mTags) {
tags->Put(tag.mKey, tag.mValue);
}
mVideo.mCallback = new DecoderCallback(this, TrackInfo::kVideoTrack);
mVideo.mTimeRanges = mVideo.mTrackDemuxer->GetBuffered();
@@ -307,17 +307,17 @@ MediaFormatReader::OnDemuxerInitDone(nsr
mVideo.mTrackDemuxer = nullptr;
}
}
bool audioActive = !!mDemuxer->GetNumberTracks(TrackInfo::kAudioTrack);
if (audioActive) {
mAudio.mTrackDemuxer = mDemuxer->GetTrackDemuxer(TrackInfo::kAudioTrack, 0);
if (!mAudio.mTrackDemuxer) {
- mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+ mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
return;
}
UniquePtr<TrackInfo> audioInfo = mAudio.mTrackDemuxer->GetInfo();
// We actively ignore audio tracks that we know we can't play.
audioActive = audioInfo && audioInfo->IsValid() &&
(!platform ||
platform->SupportsMimeType(audioInfo->mMimeType, nullptr));
@@ -359,32 +359,32 @@ MediaFormatReader::OnDemuxerInitDone(nsr
mInfo.mMetadataDuration = Some(TimeUnit::FromMicroseconds(duration));
}
mInfo.mMediaSeekable = mDemuxer->IsSeekable();
mInfo.mMediaSeekableOnlyInBufferedRanges =
mDemuxer->IsSeekableOnlyInBufferedRanges();
if (!videoActive && !audioActive) {
- mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+ mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
return;
}
mInitDone = true;
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = tags->Count() ? tags.release() : nullptr;
mMetadataPromise.Resolve(metadata, __func__);
}
void
MediaFormatReader::OnDemuxerInitFailed(DemuxerFailureReason aFailure)
{
mDemuxerInitRequest.Complete();
- mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+ mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
}
bool
MediaFormatReader::EnsureDecoderCreated(TrackType aTrack)
{
MOZ_ASSERT(OnTaskQueue());
MOZ_DIAGNOSTIC_ASSERT(!IsSuspended());
--- a/dom/media/gtest/TestMediaFormatReader.cpp
+++ b/dom/media/gtest/TestMediaFormatReader.cpp
@@ -83,17 +83,17 @@ public:
{
EXPECT_TRUE(aMetadata);
mReader->RequestVideoData(true, 0)
->Then(mReader->OwnerThread(), __func__, this,
&MediaFormatReaderBinding::OnVideoRawDataDemuxed,
&MediaFormatReaderBinding::OnNotDemuxed);
}
- void OnMetadataNotRead(ReadMetadataFailureReason aReason) {
+ void OnMetadataNotRead(const MediaResult& aError) {
EXPECT_TRUE(false);
ReaderShutdown();
}
void OnAudioRawDataDemuxed(MediaData* aAudioSample)
{
EXPECT_TRUE(aAudioSample);
EXPECT_EQ(MediaData::RAW_DATA, aAudioSample->mType);
--- a/dom/media/omx/MediaOmxReader.cpp
+++ b/dom/media/omx/MediaOmxReader.cpp
@@ -170,17 +170,17 @@ MediaOmxReader::Shutdown()
p->Then(AbstractThread::MainThread(), __func__, this, &MediaOmxReader::ReleaseDecoder, &MediaOmxReader::ReleaseDecoder);
return p;
}
void MediaOmxReader::ReleaseResources()
{
mMediaResourceRequest.DisconnectIfExists();
- mMetadataPromise.RejectIfExists(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+ mMetadataPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
ResetDecode();
// Before freeing a video codec, all video buffers needed to be released
// even from graphics pipeline.
VideoFrameContainer* container = mDecoder->GetVideoFrameContainer();
if (container) {
container->ClearCurrentFrame();
}
@@ -216,17 +216,17 @@ MediaOmxReader::AsyncReadMetadata()
{
MOZ_ASSERT(OnTaskQueue());
EnsureActive();
// Initialize the internal OMX Decoder.
nsresult rv = InitOmxDecoder();
if (NS_FAILED(rv)) {
return MediaDecoderReader::MetadataPromise::CreateAndReject(
- ReadMetadataFailureReason::METADATA_ERROR, __func__);
+ NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
}
bool isMP3 = mDecoder->GetResource()->GetContentType().EqualsASCII(AUDIO_MP3);
if (isMP3) {
// When read sdcard's file on b2g platform at constructor,
// the mDecoder->GetResource()->GetLength() would return -1.
// Delay set the total duration on this function.
mMP3FrameParser.SetLength(mDecoder->GetResource()->GetLength());
@@ -238,29 +238,29 @@ MediaOmxReader::AsyncReadMetadata()
RefPtr<MediaOmxReader> self = this;
mMediaResourceRequest.Begin(mOmxDecoder->AllocateMediaResources()
->Then(OwnerThread(), __func__,
[self] (bool) -> void {
self->mMediaResourceRequest.Complete();
self->HandleResourceAllocated();
}, [self] (bool) -> void {
self->mMediaResourceRequest.Complete();
- self->mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+ self->mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
}));
return p;
}
void MediaOmxReader::HandleResourceAllocated()
{
EnsureActive();
// After resources are available, set the metadata.
if (!mOmxDecoder->EnsureMetadata()) {
- mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+ mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
return;
}
bool isMP3 = mDecoder->GetResource()->GetContentType().EqualsASCII(AUDIO_MP3);
if (isMP3 && mMP3FrameParser.IsMP3()) {
// Check if the MP3 frame parser found a duration.
mLastParserDuration = mMP3FrameParser.GetDuration();
}
@@ -284,17 +284,17 @@ void MediaOmxReader::HandleResourceAlloc
&width, &height);
nsIntRect pictureRect(0, 0, width, height);
// Validate the container-reported frame and pictureRect sizes. This ensures
// that our video frame creation code doesn't overflow.
nsIntSize displaySize(displayWidth, displayHeight);
nsIntSize frameSize(width, height);
if (!IsValidVideoRegion(frameSize, pictureRect, displaySize)) {
- mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+ mMetadataPromise.RejectNS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
return;
}
// Video track's frame sizes will not overflow. Activate the video track.
mHasVideo = true;
mInfo.mVideo.mDisplay = displaySize;
mPicture = pictureRect;
mInitialFrame = frameSize;
--- a/dom/media/webaudio/MediaBufferDecoder.cpp
+++ b/dom/media/webaudio/MediaBufferDecoder.cpp
@@ -127,17 +127,17 @@ private:
nsCOMPtr<nsIRunnable> event =
new ReportResultTask(mDecodeJob, &WebAudioDecodeJob::OnFailure, aErrorCode);
NS_DispatchToMainThread(event);
}
}
void Decode();
void OnMetadataRead(MetadataHolder* aMetadata);
- void OnMetadataNotRead(ReadMetadataFailureReason aReason);
+ void OnMetadataNotRead(const MediaResult& aError);
void RequestSample();
void SampleDecoded(MediaData* aData);
void SampleNotDecoded(const MediaResult& aError);
void FinishDecode();
void AllocateBuffer();
void CallbackTheResult();
void Cleanup()
@@ -305,17 +305,17 @@ MediaDecodeTask::OnMetadataRead(Metadata
Telemetry::Accumulate(Telemetry::ID::MEDIA_CODEC_USED, codec);
});
AbstractThread::MainThread()->Dispatch(task.forget());
RequestSample();
}
void
-MediaDecodeTask::OnMetadataNotRead(ReadMetadataFailureReason aReason)
+MediaDecodeTask::OnMetadataNotRead(const MediaResult& aReason)
{
mDecoderReader->Shutdown();
ReportFailureOnMainThread(WebAudioDecodeJob::InvalidContent);
}
void
MediaDecodeTask::RequestSample()
{