Bug 1874723 - Accept imprecision when trimming audio content media in certain cases. r=alwu

In the test case, the time base is 69 (generated by a fuzzer), and so there's a
very large loss in precision in the computation, and eventually the assumption
doesn't hold. It should however hold for the common case.

Differential Revision: https://phabricator.services.mozilla.com/D200176
This commit is contained in:
Paul Adenot 2024-02-01 17:13:15 +00:00
parent 011d915474
commit 359d6e23af
6 changed files with 41 additions and 18 deletions

View file

@ -107,9 +107,16 @@ bool AudioData::SetTrimWindow(const media::TimeInterval& aTrim) {
mDataOffset = frameOffset * mChannels;
MOZ_DIAGNOSTIC_ASSERT(mDataOffset <= mAudioData.Length(),
"Data offset outside original buffer");
mFrames = (trimAfter - trimBefore).ToTicksAtRate(mRate);
MOZ_DIAGNOSTIC_ASSERT(mFrames <= mAudioData.Length() / mChannels,
"More frames than found in container");
int64_t frameCountAfterTrim = (trimAfter - trimBefore).ToTicksAtRate(mRate);
if (frameCountAfterTrim >
AssertedCast<int64_t>(mAudioData.Length() / mChannels)) {
// Accept rounding error caused by an imprecise time_base in the container,
// that can cause a mismatch but not other kind of unexpected frame count.
MOZ_RELEASE_ASSERT(!trimBefore.IsBase(mRate));
mFrames = 0;
} else {
mFrames = frameCountAfterTrim;
}
mTime = mOriginalTime + trimBefore;
mDuration = TimeUnit(mFrames, mRate);
@ -449,21 +456,21 @@ already_AddRefed<VideoData> VideoData::CreateFromImage(
nsCString VideoData::ToString() const {
std::array ImageFormatStrings = {
"PLANAR_YCBCR",
"NV_IMAGE",
"SHARED_RGB",
"MOZ2D_SURFACE",
"MAC_IOSURFACE",
"SURFACE_TEXTURE",
"D3D9_RGB32_TEXTURE",
"OVERLAY_IMAGE",
"D3D11_SHARE_HANDLE_TEXTURE",
"D3D11_TEXTURE_IMF_SAMPLE",
"TEXTURE_WRAPPER",
"D3D11_YCBCR_IMAGE",
"GPU_VIDEO",
"DMABUF",
"DCOMP_SURFACE",
"PLANAR_YCBCR",
"NV_IMAGE",
"SHARED_RGB",
"MOZ2D_SURFACE",
"MAC_IOSURFACE",
"SURFACE_TEXTURE",
"D3D9_RGB32_TEXTURE",
"OVERLAY_IMAGE",
"D3D11_SHARE_HANDLE_TEXTURE",
"D3D11_TEXTURE_IMF_SAMPLE",
"TEXTURE_WRAPPER",
"D3D11_YCBCR_IMAGE",
"GPU_VIDEO",
"DMABUF",
"DCOMP_SURFACE",
};
nsCString rv;

View file

@ -98,6 +98,8 @@ int64_t TimeUnit::ToTicksAtRate(int64_t aRate) const {
return mTicks.value() * aRate / mBase;
}
bool TimeUnit::IsBase(int64_t aBase) const { return aBase == mBase; }
double TimeUnit::ToSeconds() const {
if (IsPosInf()) {
return PositiveInfinity<double>();

View file

@ -118,6 +118,9 @@ class TimeUnit final {
int64_t ToMicroseconds() const;
int64_t ToNanoseconds() const;
int64_t ToTicksAtRate(int64_t aRate) const;
// Only to be used in release assertions or unit testing, returns true if this
// TimeUnit has base aBase
bool IsBase(int64_t aBase) const;
double ToSeconds() const;
nsCString ToString() const;
TimeDuration ToTimeDuration() const;

View file

@ -179,3 +179,4 @@ test-pref(media.wmf.hevc.enabled,1) load 1859600.mp4
test-pref(media.wmf.hevc.enabled,1) load 1860840.mp4
load 1864450.html
load 1872787.html
load small-timebase.html

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html class="reftest-wait">
<video id=a src=small-timebase.mp4 controls autoplay></video>
<script>
a.onplaying = function() {
dump("OK");
document.documentElement.removeAttribute("class");
}
</script>
</html>

Binary file not shown.