Bug 1672311 - Implement audio trimming for batch jobs. r=padenot

Differential Revision: https://phabricator.services.mozilla.com/D94280
This commit is contained in:
Jean-Yves Avenard 2020-10-22 12:40:29 +00:00
Родитель cc6e7ab133
Коммит cffbc80aca
2 изменённых файлов: 53 добавлений и 25 удалений

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

@ -24,27 +24,8 @@ RefPtr<MediaDataDecoder::DecodePromise> AudioTrimmer::Decode(
MediaRawData* aSample) {
MOZ_ASSERT(mThread->IsOnCurrentThread(),
"We're not on the thread we were first initialized on");
// A compress sample indicates that it needs to be trimmed after decoding by
// having its mOriginalPresentationWindow member set; in which case
// mOriginalPresentationWindow contains the original time and duration of the
// frame set by the demuxer and mTime and mDuration set to what it should be
// after trimming.
RefPtr<MediaRawData> sample = aSample;
if (sample->mOriginalPresentationWindow) {
LOG("sample[%" PRId64 ",%" PRId64 "] has trimming info ([%" PRId64
",%" PRId64 "]",
sample->mOriginalPresentationWindow->mStart.ToMicroseconds(),
sample->mOriginalPresentationWindow->mEnd.ToMicroseconds(),
sample->mTime.ToMicroseconds(), sample->GetEndTime().ToMicroseconds());
mTrimmers.AppendElement(
Some(TimeInterval(sample->mTime, sample->GetEndTime())));
sample->mTime = sample->mOriginalPresentationWindow->mStart;
sample->mDuration = sample->mOriginalPresentationWindow->Length();
} else {
LOG("sample[%" PRId64 ",%" PRId64 "] no trimming information",
sample->mTime.ToMicroseconds(), sample->GetEndTime().ToMicroseconds());
mTrimmers.AppendElement(Nothing());
}
PrepareTrimmers(sample);
RefPtr<AudioTrimmer> self = this;
RefPtr<DecodePromise> p = mDecoder->Decode(sample)->Then(
GetCurrentSerialEventTarget(), __func__,
@ -69,8 +50,7 @@ RefPtr<MediaDataDecoder::DecodePromise> AudioTrimmer::Drain() {
RefPtr<DecodePromise> p = mDecoder->Drain()->Then(
GetCurrentSerialEventTarget(), __func__,
[self = RefPtr{this}](DecodePromise::ResolveOrRejectValue&& aValue) {
auto p = self->HandleDecodedResult(std::move(aValue), nullptr);
return p;
return self->HandleDecodedResult(std::move(aValue), nullptr);
});
return p;
}
@ -178,6 +158,53 @@ RefPtr<MediaDataDecoder::DecodePromise> AudioTrimmer::HandleDecodedResult(
return DecodePromise::CreateAndResolve(std::move(results), __func__);
}
RefPtr<MediaDataDecoder::DecodePromise> AudioTrimmer::DecodeBatch(
nsTArray<RefPtr<MediaRawData>>&& aSamples) {
MOZ_ASSERT(mThread->IsOnCurrentThread(),
"We're not on the thread we were first initialized on");
LOG("DecodeBatch");
for (auto&& sample : aSamples) {
PrepareTrimmers(sample);
}
RefPtr<DecodePromise> p =
mDecoder->DecodeBatch(std::move(aSamples))
->Then(GetCurrentSerialEventTarget(), __func__,
[self = RefPtr{this}](
DecodePromise::ResolveOrRejectValue&& aValue) {
// If the decoder returned less samples than what we fed it.
// We can assume that this is due to the decoder encoding
// delay and that all decoded frames have been shifted by n =
// compressedSamples.Length() - decodedSamples.Length() and
// that the first n compressed samples returned nothing.
return self->HandleDecodedResult(std::move(aValue), nullptr);
});
return p;
}
void AudioTrimmer::PrepareTrimmers(MediaRawData* aRaw) {
// A compress sample indicates that it needs to be trimmed after decoding by
// having its mOriginalPresentationWindow member set; in which case
// mOriginalPresentationWindow contains the original time and duration of
// the frame set by the demuxer and mTime and mDuration set to what it
// should be after trimming.
if (aRaw->mOriginalPresentationWindow) {
LOG("sample[%" PRId64 ",%" PRId64 "] has trimming info ([%" PRId64
",%" PRId64 "]",
aRaw->mOriginalPresentationWindow->mStart.ToMicroseconds(),
aRaw->mOriginalPresentationWindow->mEnd.ToMicroseconds(),
aRaw->mTime.ToMicroseconds(), aRaw->GetEndTime().ToMicroseconds());
mTrimmers.AppendElement(
Some(TimeInterval(aRaw->mTime, aRaw->GetEndTime())));
aRaw->mTime = aRaw->mOriginalPresentationWindow->mStart;
aRaw->mDuration = aRaw->mOriginalPresentationWindow->Length();
} else {
LOG("sample[%" PRId64 ",%" PRId64 "] no trimming information",
aRaw->mTime.ToMicroseconds(), aRaw->GetEndTime().ToMicroseconds());
mTrimmers.AppendElement(Nothing());
}
}
} // namespace mozilla
#undef LOG

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

@ -24,9 +24,7 @@ class AudioTrimmer : public MediaDataDecoder {
RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
bool CanDecodeBatch() const override { return mDecoder->CanDecodeBatch(); }
RefPtr<DecodePromise> DecodeBatch(
nsTArray<RefPtr<MediaRawData>>&& aSamples) override {
return mDecoder->DecodeBatch(std::move(aSamples));
}
nsTArray<RefPtr<MediaRawData>>&& aSamples) override;
RefPtr<DecodePromise> Drain() override;
RefPtr<FlushPromise> Flush() override;
RefPtr<ShutdownPromise> Shutdown() override;
@ -37,8 +35,11 @@ class AudioTrimmer : public MediaDataDecoder {
ConversionRequired NeedsConversion() const override;
private:
// Apply trimming information on decoded data. aRaw can be null as it's only
// used for logging purposes.
RefPtr<DecodePromise> HandleDecodedResult(
DecodePromise::ResolveOrRejectValue&& aValue, MediaRawData* aRaw);
void PrepareTrimmers(MediaRawData* aRaw);
const RefPtr<MediaDataDecoder> mDecoder;
nsCOMPtr<nsISerialEventTarget> mThread;
AutoTArray<Maybe<media::TimeInterval>, 2> mTrimmers;