Bug 1232045 - WebMDemuxer handles resolution changes. r=jya

Update the WebMDemuxer to detect changes in resolution. When it does so it
changes the streamID so that we get a new decoder created to handle the
resolution change. The demuxer will also update media info in these cases, so
the new decoder has the correct information. The demuxer will only handle
resolution changes on key frames, files that attempt changes other times are not
considered valid at this stage. If a resolution change cannot be performed
because nest_egg cannot read track info, or because the new resolution is
invalid, a change will not take place.

MozReview-Commit-ID: 1JKz3mGbEvi

--HG--
extra : rebase_source : aebd609651dfbd48d2f6ea3e33986a7e12b1495e
This commit is contained in:
Bryce Van Dyk 2016-03-15 00:28:47 +13:00
Родитель f25aa29f5e
Коммит a0436efae3
2 изменённых файлов: 28 добавлений и 0 удалений

Просмотреть файл

@ -11,6 +11,7 @@
#include "WebMDemuxer.h"
#include "WebMBufferedParser.h"
#include "gfx2DGlue.h"
#include "mozilla/Atomics.h"
#include "mozilla/Endian.h"
#include "mozilla/Preferences.h"
#include "mozilla/SharedThreadPool.h"
@ -42,6 +43,8 @@ LazyLogModule gNesteggLog("Nestegg");
// files encountered appear to have keyframes located < 4s.
#define MAX_LOOK_AHEAD 10000000
static Atomic<uint32_t> sStreamSourceID(0u);
// Functions for reading and seeking using WebMDemuxer required for
// nestegg_io. The 'user data' passed to these functions is the
// demuxer.
@ -572,6 +575,22 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
break;
}
isKeyframe = si.is_kf;
if (isKeyframe) {
// We only look for resolution changes on keyframes for both VP8 and
// VP9. Other resolution changes are invalid.
if (mLastSeenFrameWidth.isSome() && mLastSeenFrameHeight.isSome() &&
(si.w != mLastSeenFrameWidth.value() ||
si.h != mLastSeenFrameHeight.value())) {
// We ignore cropping information on resizes during streams.
// Cropping alone is rare, and we do not consider cropping to
// still be valid after a resolution change
mInfo.mVideo.mDisplay = nsIntSize(si.w, si.h);
mInfo.mVideo.mImage = nsIntRect(0, 0, si.w, si.h);
mSharedVideoTrackInfo = new SharedTrackInfo(mInfo.mVideo, ++sStreamSourceID);
}
mLastSeenFrameWidth = Some(si.w);
mLastSeenFrameHeight = Some(si.h);
}
}
WEBM_DEBUG("push sample tstamp: %ld next_tstamp: %ld length: %ld kf: %d",
@ -588,6 +607,9 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
sample->mExtraData = new MediaByteBuffer;
sample->mExtraData->AppendElements(&c[0], 8);
}
if (aType == TrackInfo::kVideoTrack) {
sample->mTrackInfo = mSharedVideoTrackInfo;
}
aSamples->Push(sample);
}
return true;

Просмотреть файл

@ -201,6 +201,12 @@ private:
// as nestegg only performs 1-byte read at a time.
int64_t mLastWebMBlockOffset;
const bool mIsMediaSource;
Maybe<uint32_t> mLastSeenFrameWidth;
Maybe<uint32_t> mLastSeenFrameHeight;
// This will be populated only if a resolution change occurs, otherwise it
// will be left as null so the original metadata is used
RefPtr<SharedTrackInfo> mSharedVideoTrackInfo;
};
class WebMTrackDemuxer : public MediaTrackDemuxer