summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortrav90 <travawine@palemoon.org>2018-10-08 21:43:06 -0500
committertrav90 <travawine@palemoon.org>2018-10-08 21:43:06 -0500
commit632b67483c9d964cd84ee90d162e88b510a70707 (patch)
treee58d67dd63f1f45b5019843840639a7bd43e15b2
parent3ec54eeacb8fcb5b844aa07c803cf52d1aedb0d4 (diff)
downloadUXP-632b67483c9d964cd84ee90d162e88b510a70707.tar
UXP-632b67483c9d964cd84ee90d162e88b510a70707.tar.gz
UXP-632b67483c9d964cd84ee90d162e88b510a70707.tar.lz
UXP-632b67483c9d964cd84ee90d162e88b510a70707.tar.xz
UXP-632b67483c9d964cd84ee90d162e88b510a70707.zip
[webm] Treat demuxing errors differently than EOS
Otherwise the WebM demuxer makes no difference between a genuine EOS and encountering an error.
-rw-r--r--dom/media/webm/WebMDemuxer.cpp105
-rw-r--r--dom/media/webm/WebMDemuxer.h11
2 files changed, 75 insertions, 41 deletions
diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp
index b39bec661..395262a2e 100644
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -547,7 +547,7 @@ WebMDemuxer::GetTrackCrypto(TrackInfo::TrackType aType, size_t aTrackNumber) {
return crypto;
}
-bool
+nsresult
WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSamples)
{
if (mIsMediaSource) {
@@ -555,17 +555,18 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
EnsureUpToDateIndex();
}
- RefPtr<NesteggPacketHolder> holder(NextPacket(aType));
+ RefPtr<NesteggPacketHolder> holder;
+ nsresult rv = NextPacket(aType, holder);
- if (!holder) {
- return false;
+ if (NS_FAILED(rv)) {
+ return rv;
}
int r = 0;
unsigned int count = 0;
r = nestegg_packet_count(holder->Packet(), &count);
if (r == -1) {
- return false;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
int64_t tstamp = holder->Timestamp();
int64_t duration = holder->Duration();
@@ -576,7 +577,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
// video frame.
int64_t next_tstamp = INT64_MIN;
if (aType == TrackInfo::kAudioTrack) {
- RefPtr<NesteggPacketHolder> next_holder(NextPacket(aType));
+ RefPtr<NesteggPacketHolder> next_holder;
+ rv = NextPacket(aType, next_holder);
+ if (NS_FAILED(rv) && rv != NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
+ return rv;
+ }
if (next_holder) {
next_tstamp = next_holder->Timestamp();
PushAudioPacket(next_holder);
@@ -591,7 +596,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
}
mLastAudioFrameTime = Some(tstamp);
} else if (aType == TrackInfo::kVideoTrack) {
- RefPtr<NesteggPacketHolder> next_holder(NextPacket(aType));
+ RefPtr<NesteggPacketHolder> next_holder;
+ rv = NextPacket(aType, next_holder);
+ if (NS_FAILED(rv) && rv != NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
+ return rv;
+ }
if (next_holder) {
next_tstamp = next_holder->Timestamp();
PushVideoPacket(next_holder);
@@ -608,7 +617,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
}
if (mIsMediaSource && next_tstamp == INT64_MIN) {
- return false;
+ return NS_ERROR_DOM_MEDIA_END_OF_STREAM;
}
int64_t discardPadding = 0;
@@ -624,7 +633,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
r = nestegg_packet_data(holder->Packet(), i, &data, &length);
if (r == -1) {
WEBM_DEBUG("nestegg_packet_data failed r=%d", r);
- return false;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
bool isKeyframe = false;
if (aType == TrackInfo::kAudioTrack) {
@@ -668,7 +677,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
RefPtr<MediaRawData> sample = new MediaRawData(data, length);
if (length && !sample->Data()) {
// OOM.
- return false;
+ return NS_ERROR_OUT_OF_MEMORY;
}
sample->mTimecode = tstamp;
sample->mTime = tstamp;
@@ -721,11 +730,12 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
}
aSamples->Push(sample);
}
- return true;
+ return NS_OK;
}
-RefPtr<NesteggPacketHolder>
-WebMDemuxer::NextPacket(TrackInfo::TrackType aType)
+nsresult
+WebMDemuxer::NextPacket(TrackInfo::TrackType aType,
+ RefPtr<NesteggPacketHolder>& aPacket)
{
bool isVideo = aType == TrackInfo::kVideoTrack;
@@ -734,56 +744,64 @@ WebMDemuxer::NextPacket(TrackInfo::TrackType aType)
bool hasType = isVideo ? mHasVideo : mHasAudio;
if (!hasType) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
// The packet queue for the type that we are interested in.
WebMPacketQueue &packets = isVideo ? mVideoPackets : mAudioPackets;
if (packets.GetSize() > 0) {
- return packets.PopFront();
+ aPacket = packets.PopFront();
+ return NS_OK;
}
// Track we are interested in
uint32_t ourTrack = isVideo ? mVideoTrack : mAudioTrack;
do {
- RefPtr<NesteggPacketHolder> holder = DemuxPacket(aType);
+ RefPtr<NesteggPacketHolder> holder;
+ nsresult rv = DemuxPacket(aType, holder);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
if (!holder) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
if (ourTrack == holder->Track()) {
- return holder;
+ aPacket = holder;
+ return NS_OK;
}
} while (true);
}
-RefPtr<NesteggPacketHolder>
-WebMDemuxer::DemuxPacket(TrackInfo::TrackType aType)
+nsresult
+WebMDemuxer::DemuxPacket(TrackInfo::TrackType aType,
+ RefPtr<NesteggPacketHolder>& aPacket)
{
nestegg_packet* packet;
int r = nestegg_read_packet(Context(aType), &packet);
if (r == 0) {
nestegg_read_reset(Context(aType));
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_END_OF_STREAM;
} else if (r < 0) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
unsigned int track = 0;
r = nestegg_packet_track(packet, &track);
if (r == -1) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
int64_t offset = Resource(aType).Tell();
RefPtr<NesteggPacketHolder> holder = new NesteggPacketHolder();
if (!holder->Init(packet, offset, track, false)) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
- return holder;
+ aPacket = holder;
+ return NS_OK;
}
void
@@ -943,7 +961,10 @@ WebMTrackDemuxer::Seek(media::TimeUnit aTime)
media::TimeUnit seekTime = aTime;
mSamples.Reset();
mParent->SeekInternal(mType, aTime);
- mParent->GetNextPacket(mType, &mSamples);
+ nsresult rv = mParent->GetNextPacket(mType, &mSamples);
+ if (NS_FAILED(rv)) {
+ return SeekPromise::CreateAndReject(rv, __func__);
+ }
mNeedKeyframe = true;
// Check what time we actually seeked to.
@@ -956,15 +977,18 @@ WebMTrackDemuxer::Seek(media::TimeUnit aTime)
return SeekPromise::CreateAndResolve(seekTime, __func__);
}
-RefPtr<MediaRawData>
-WebMTrackDemuxer::NextSample()
+nsresult
+WebMTrackDemuxer::NextSample(RefPtr<MediaRawData>& aData)
{
- while (mSamples.GetSize() < 1 && mParent->GetNextPacket(mType, &mSamples)) {
+ nsresult rv;
+ while (mSamples.GetSize() < 1 &&
+ NS_SUCCEEDED((rv = mParent->GetNextPacket(mType, &mSamples)))) {
}
if (mSamples.GetSize()) {
- return mSamples.PopFront();
+ aData = mSamples.PopFront();
+ return NS_OK;
}
- return nullptr;
+ return rv;
}
RefPtr<WebMTrackDemuxer::SamplesPromise>
@@ -973,9 +997,12 @@ WebMTrackDemuxer::GetSamples(int32_t aNumSamples)
RefPtr<SamplesHolder> samples = new SamplesHolder;
MOZ_ASSERT(aNumSamples);
+ nsresult rv = NS_ERROR_DOM_MEDIA_END_OF_STREAM;
+
while (aNumSamples) {
- RefPtr<MediaRawData> sample(NextSample());
- if (!sample) {
+ RefPtr<MediaRawData> sample;
+ rv = NextSample(sample);
+ if (NS_FAILED(rv)) {
break;
}
if (mNeedKeyframe && !sample->mKeyframe) {
@@ -987,7 +1014,7 @@ WebMTrackDemuxer::GetSamples(int32_t aNumSamples)
}
if (samples->mSamples.IsEmpty()) {
- return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
+ return SamplesPromise::CreateAndReject(rv, __func__);
} else {
UpdateSamples(samples->mSamples);
return SamplesPromise::CreateAndResolve(samples, __func__);
@@ -1022,7 +1049,8 @@ WebMTrackDemuxer::SetNextKeyFrameTime()
}
// Demux and buffer frames until we find a keyframe.
RefPtr<MediaRawData> sample;
- while (!foundKeyframe && (sample = NextSample())) {
+ nsresult rv = NS_OK;
+ while (!foundKeyframe && NS_SUCCEEDED((rv = NextSample(sample)))) {
if (sample->mKeyframe) {
frameTime = sample->mTime;
foundKeyframe = true;
@@ -1104,10 +1132,11 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold)
uint32_t parsed = 0;
bool found = false;
RefPtr<MediaRawData> sample;
+ nsresult rv = NS_OK;
int64_t sampleTime;
WEBM_DEBUG("TimeThreshold: %f", aTimeThreshold.ToSeconds());
- while (!found && (sample = NextSample())) {
+ while (!found && NS_SUCCEEDED((rv = NextSample(sample)))) {
parsed++;
sampleTime = sample->mTime;
if (sample->mKeyframe && sampleTime >= aTimeThreshold.ToMicroseconds()) {
@@ -1116,7 +1145,9 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold)
mSamples.PushFront(sample.forget());
}
}
- SetNextKeyFrameTime();
+ if (NS_SUCCEEDED(rv)) {
+ SetNextKeyFrameTime();
+ }
if (found) {
WEBM_DEBUG("next sample: %f (parsed: %d)",
media::TimeUnit::FromMicroseconds(sampleTime).ToSeconds(),
diff --git a/dom/media/webm/WebMDemuxer.h b/dom/media/webm/WebMDemuxer.h
index a5008022f..09780e8d3 100644
--- a/dom/media/webm/WebMDemuxer.h
+++ b/dom/media/webm/WebMDemuxer.h
@@ -111,7 +111,8 @@ public:
bool GetOffsetForTime(uint64_t aTime, int64_t* aOffset);
// Demux next WebM packet and append samples to MediaRawDataQueue
- bool GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSamples);
+ nsresult GetNextPacket(TrackInfo::TrackType aType,
+ MediaRawDataQueue *aSamples);
nsresult Reset(TrackInfo::TrackType aType);
@@ -175,11 +176,13 @@ private:
// Read a packet from the nestegg file. Returns nullptr if all packets for
// the particular track have been read. Pass TrackInfo::kVideoTrack or
// TrackInfo::kVideoTrack to indicate the type of the packet we want to read.
- RefPtr<NesteggPacketHolder> NextPacket(TrackInfo::TrackType aType);
+ nsresult NextPacket(TrackInfo::TrackType aType,
+ RefPtr<NesteggPacketHolder>& aPacket);
// Internal method that demuxes the next packet from the stream. The caller
// is responsible for making sure it doesn't get lost.
- RefPtr<NesteggPacketHolder> DemuxPacket(TrackInfo::TrackType aType);
+ nsresult DemuxPacket(TrackInfo::TrackType aType,
+ RefPtr<NesteggPacketHolder>& aPacket);
// libnestegg audio and video context for webm container.
// Access on reader's thread only.
@@ -275,7 +278,7 @@ private:
~WebMTrackDemuxer();
void UpdateSamples(nsTArray<RefPtr<MediaRawData>>& aSamples);
void SetNextKeyFrameTime();
- RefPtr<MediaRawData> NextSample ();
+ nsresult NextSample(RefPtr<MediaRawData>& aData);
RefPtr<WebMDemuxer> mParent;
TrackInfo::TrackType mType;
UniquePtr<TrackInfo> mInfo;