зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1525507 - P1. Don't trust mp4 container to determine if a VP9 frame is a keyframe. r=bryce
Similar to what we do for H264 and for vp9 in webm, we parse the VP9 bytestream and check if a frame is a keyframe there instead. Differential Revision: https://phabricator.services.mozilla.com/D18790 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
8e0e225e22
Коммит
8be6b34abb
|
@ -14,9 +14,12 @@
|
|||
#include "BufferStream.h"
|
||||
#include "H264.h"
|
||||
#include "Index.h"
|
||||
#include "MP4Decoder.h"
|
||||
#include "MP4Metadata.h"
|
||||
#include "MoofParser.h"
|
||||
#include "ResourceStream.h"
|
||||
#include "VPXDecoder.h"
|
||||
#include "mozilla/Span.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
@ -71,7 +74,11 @@ class MP4TrackDemuxer : public MediaTrackDemuxer,
|
|||
RefPtr<MediaRawData> mQueuedSample;
|
||||
bool mNeedReIndex;
|
||||
bool mNeedSPSForTelemetry;
|
||||
bool mIsH264 = false;
|
||||
enum CodecType {
|
||||
kH264,
|
||||
kVP9,
|
||||
kOther
|
||||
} mType = kOther;
|
||||
};
|
||||
|
||||
// Returns true if no SPS was found and search for it should continue.
|
||||
|
@ -350,9 +357,8 @@ MP4TrackDemuxer::MP4TrackDemuxer(MediaResource* aResource,
|
|||
|
||||
VideoInfo* videoInfo = mInfo->GetAsVideoInfo();
|
||||
// Collect telemetry from h264 AVCC SPS.
|
||||
if (videoInfo && (mInfo->mMimeType.EqualsLiteral("video/mp4") ||
|
||||
mInfo->mMimeType.EqualsLiteral("video/avc"))) {
|
||||
mIsH264 = true;
|
||||
if (videoInfo && MP4Decoder::IsH264(mInfo->mMimeType)) {
|
||||
mType = kH264;
|
||||
RefPtr<MediaByteBuffer> extraData = videoInfo->mExtraData;
|
||||
mNeedSPSForTelemetry = AccumulateSPSTelemetry(extraData);
|
||||
SPSData spsdata;
|
||||
|
@ -365,6 +371,9 @@ MP4TrackDemuxer::MP4TrackDemuxer(MediaResource* aResource,
|
|||
videoInfo->mDisplay.height = spsdata.display_height;
|
||||
}
|
||||
} else {
|
||||
if (videoInfo && VPXDecoder::IsVP9(mInfo->mMimeType)) {
|
||||
mType = kVP9;
|
||||
}
|
||||
// No SPS to be found.
|
||||
mNeedSPSForTelemetry = false;
|
||||
}
|
||||
|
@ -422,7 +431,7 @@ already_AddRefed<MediaRawData> MP4TrackDemuxer::GetNextSample() {
|
|||
}
|
||||
if (mInfo->GetAsVideoInfo()) {
|
||||
sample->mExtraData = mInfo->GetAsVideoInfo()->mExtraData;
|
||||
if (mIsH264 && !sample->mCrypto.IsEncrypted()) {
|
||||
if (mType == kH264 && !sample->mCrypto.IsEncrypted()) {
|
||||
H264::FrameType type = H264::GetFrameType(sample);
|
||||
switch (type) {
|
||||
case H264::FrameType::I_FRAME:
|
||||
|
@ -455,6 +464,20 @@ already_AddRefed<MediaRawData> MP4TrackDemuxer::GetNextSample() {
|
|||
// TODO: make demuxer errors non-fatal.
|
||||
break;
|
||||
}
|
||||
} else if (mType == kVP9 && !sample->mCrypto.IsEncrypted()) {
|
||||
bool keyframe = VPXDecoder::IsKeyframe(
|
||||
MakeSpan<const uint8_t>(sample->Data(), sample->Size()),
|
||||
VPXDecoder::Codec::VP9);
|
||||
if (sample->mKeyframe != keyframe) {
|
||||
NS_WARNING(nsPrintfCString(
|
||||
"Frame incorrectly marked as %skeyframe "
|
||||
"@ pts:%" PRId64 " dur:%" PRId64 " dts:%" PRId64,
|
||||
keyframe ? "" : "non-", sample->mTime.ToMicroseconds(),
|
||||
sample->mDuration.ToMicroseconds(),
|
||||
sample->mTimecode.ToMicroseconds())
|
||||
.get());
|
||||
sample->mKeyframe = keyframe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,7 +514,7 @@ RefPtr<MP4TrackDemuxer::SamplesPromise> MP4TrackDemuxer::GetSamples(
|
|||
}
|
||||
for (const auto& sample : samples->mSamples) {
|
||||
// Collect telemetry from h264 Annex B SPS.
|
||||
if (mNeedSPSForTelemetry && mIsH264 && AnnexB::IsAVCC(sample)) {
|
||||
if (mNeedSPSForTelemetry && mType == kH264 && AnnexB::IsAVCC(sample)) {
|
||||
RefPtr<MediaByteBuffer> extradata = H264::ExtractExtraData(sample);
|
||||
if (H264::HasSPS(extradata)) {
|
||||
RefPtr<MediaByteBuffer> extradata = H264::ExtractExtraData(sample);
|
||||
|
|
Загрузка…
Ссылка в новой задаче