зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1839391 - Switch WebM demuxer to use mOriginalPresentationWindow to trim packets. r=alwu
The AudioTrimmer change is to properly implement a behaviour Gecko has about the DiscardPadding WebM element. If it's invalid (negative, present more than once, spanning multiple packets), the decoder is supposed to reject the file. This is tested by the files: invalid-discard_on_multi_blocks.webm invalid-excess_discard.webm invalid-excess_neg_discard.webm invalid-neg_discard.webm in test_invalid_reject.html. Since the demuxer now handles those trimming concerns, we simply flag the packet has needing to be rejected, by making it have an duration that's a TimeUnit::Invalid(), and letting the AudioTrimmer reject it. The rest is straightforward. Differential Revision: https://phabricator.services.mozilla.com/D181523
This commit is contained in:
Родитель
d2caeb9b64
Коммит
5f6c5765b7
|
@ -116,6 +116,11 @@ RefPtr<MediaDataDecoder::DecodePromise> AudioTrimmer::HandleDecodedResult(
|
|||
for (uint32_t i = 0; i < results.Length();) {
|
||||
const RefPtr<MediaData>& data = results[i];
|
||||
MOZ_ASSERT(data->mType == MediaData::Type::AUDIO_DATA);
|
||||
|
||||
if (!data->mDuration.IsValid()) {
|
||||
return DecodePromise::CreateAndReject(std::move(aValue.RejectValue()),
|
||||
__func__);
|
||||
}
|
||||
TimeInterval sampleInterval(data->mTime, data->GetEndTime());
|
||||
if (mTrimmers.IsEmpty()) {
|
||||
// mTrimmers being empty can only occurs if the decoder returned more
|
||||
|
|
|
@ -235,6 +235,7 @@ already_AddRefed<MediaTrackDemuxer> WebMDemuxer::GetTrackDemuxer(
|
|||
}
|
||||
|
||||
void WebMDemuxer::Reset(TrackInfo::TrackType aType) {
|
||||
mProcessedDiscardPadding = false;
|
||||
if (aType == TrackInfo::kVideoTrack) {
|
||||
mVideoPackets.Reset();
|
||||
} else {
|
||||
|
@ -416,11 +417,12 @@ nsresult WebMDemuxer::ReadMetadata() {
|
|||
uint64_t codecDelayUs = params.codec_delay / 1000;
|
||||
mInfo.mAudio.mMimeType = "audio/opus";
|
||||
OpusCodecSpecificData opusCodecSpecificData;
|
||||
opusCodecSpecificData.mContainerCodecDelayMicroSeconds =
|
||||
AssertedCast<int64_t>(codecDelayUs);
|
||||
opusCodecSpecificData.mContainerCodecDelayFrames =
|
||||
AssertedCast<int64_t>(USECS_PER_S * codecDelayUs / 48000);
|
||||
mInfo.mAudio.mCodecSpecificConfig =
|
||||
AudioCodecSpecificVariant{std::move(opusCodecSpecificData)};
|
||||
WEBM_DEBUG("Preroll for Opus: %" PRIu64, codecDelayUs);
|
||||
WEBM_DEBUG("Preroll for Opus: %" PRIu64 " frames",
|
||||
opusCodecSpecificData.mContainerCodecDelayFrames);
|
||||
}
|
||||
mSeekPreroll = params.seek_preroll;
|
||||
mInfo.mAudio.mRate = AssertedCast<uint32_t>(params.rate);
|
||||
|
@ -739,20 +741,25 @@ nsresult WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType,
|
|||
sample->mOffset = holder->Offset();
|
||||
sample->mKeyframe = isKeyframe;
|
||||
if (discardPadding && i == count - 1) {
|
||||
CheckedInt64 discardFrames;
|
||||
sample->mOriginalPresentationWindow =
|
||||
Some(media::TimeInterval{sample->mTime, sample->GetEndTime()});
|
||||
if (discardPadding < 0) {
|
||||
// This is an invalid value as discard padding should never be negative.
|
||||
// Set to maximum value so that the decoder will reject it as it's
|
||||
// greater than the number of frames available.
|
||||
discardFrames = INT32_MAX;
|
||||
WEBM_DEBUG("Invalid negative discard padding");
|
||||
// This will ensure decoding will error out, and the file is rejected.
|
||||
sample->mDuration = TimeUnit::Invalid();
|
||||
} else {
|
||||
discardFrames = TimeUnitToFrames(
|
||||
TimeUnit::FromNanoseconds(discardPadding), mInfo.mAudio.mRate);
|
||||
}
|
||||
if (discardFrames.isValid()) {
|
||||
sample->mDiscardPadding = discardFrames.value();
|
||||
TimeUnit padding = TimeUnit::FromNanoseconds(discardPadding);
|
||||
if (padding > sample->mDuration || mProcessedDiscardPadding) {
|
||||
WEBM_DEBUG(
|
||||
"Padding frames larger than packet size, flagging the packet for "
|
||||
"error (padding: %s, duration: %s, already processed: %s)",
|
||||
padding.ToString().get(), sample->mDuration.ToString().get(),
|
||||
mProcessedDiscardPadding ? "true" : "false");
|
||||
sample->mDuration = TimeUnit::Invalid();
|
||||
} else {
|
||||
sample->mDuration -= padding;
|
||||
}
|
||||
}
|
||||
mProcessedDiscardPadding = true;
|
||||
}
|
||||
|
||||
if (packetEncryption == NESTEGG_PACKET_HAS_SIGNAL_BYTE_ENCRYPTED ||
|
||||
|
|
|
@ -238,6 +238,11 @@ class WebMDemuxer : public MediaDataDemuxer,
|
|||
// as nestegg only performs 1-byte read at a time.
|
||||
int64_t mLastWebMBlockOffset;
|
||||
const bool mIsMediaSource;
|
||||
// Discard padding in WebM cannot occur more than once. This is set to true if
|
||||
// a discard padding element has been found and processed, and the decoding is
|
||||
// expected to error out if another discard padding element is found
|
||||
// subsequently in the byte stream.
|
||||
bool mProcessedDiscardPadding = false;
|
||||
|
||||
EncryptionInfo mCrypto;
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче