commit c199318144ce0ab51cdbb3488318ea86f170c10c
parent f58ac665285a3ea9fb101c05949a0aefd335f9f7
Author: Andrew Osmond <aosmond@gmail.com>
Date: Thu, 8 Jan 2026 15:56:04 +0000
Bug 2008354 - Part 5. Use map to track durations for MediaCodec encoders. r=media-playback-reviewers,padenot
MediaCodec encoders do not remember the durations for samples when
producing output, so we need to reuse the mechanism implemented for old
ffmpeg software encoders.
Differential Revision: https://phabricator.services.mozilla.com/D277800
Diffstat:
2 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoEncoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoEncoder.cpp
@@ -381,7 +381,11 @@ MediaResult FFmpegVideoEncoder<LIBAV_VER>::InitEncoderInternal(bool aHardware) {
mIsHardwareAccelerated = aHardware;
break;
}
+ mUseDurationMap = aHardware;
#else
+# ifdef MOZ_FFMPEG_ENCODER_USE_DURATION_MAP
+ mUseDurationMap = true;
+# endif
mIsHardwareAccelerated = aHardware;
#endif
@@ -700,11 +704,13 @@ Result<MediaDataEncoder::EncodedData, MediaResult> FFmpegVideoEncoder<
} else {
mFrame->pts = aSample->mTime.ToMicroseconds();
}
-# if LIBAVCODEC_VERSION_MAJOR >= 60
- mFrame->duration = aSample->mDuration.ToMicroseconds();
+# ifdef MOZ_FFMPEG_ENCODER_USE_DURATION_MAP
+ if (mUseDurationMap) {
+ // Save duration in the time_base unit.
+ mDurationMap.Insert(mFrame->pts, aSample->mDuration.ToMicroseconds());
+ }
# else
- // Save duration in the time_base unit.
- mDurationMap.Insert(mFrame->pts, aSample->mDuration.ToMicroseconds());
+ mFrame->duration = aSample->mDuration.ToMicroseconds();
# endif
Duration(mFrame) = aSample->mDuration.ToMicroseconds();
@@ -773,16 +779,15 @@ FFmpegVideoEncoder<LIBAV_VER>::ToMediaRawData(AVPacket* aPacket) {
// is recommended to be the reciprocal of the frame rate, but we set it to
// microsecond for now.
data->mTime = media::TimeUnit::FromMicroseconds(aPacket->pts);
-#if LIBAVCODEC_VERSION_MAJOR >= 60
- data->mDuration = media::TimeUnit::FromMicroseconds(aPacket->duration);
-#else
+#ifdef MOZ_FFMPEG_ENCODER_USE_DURATION_MAP
int64_t duration;
- if (mDurationMap.Find(aPacket->pts, duration)) {
+ if (mUseDurationMap && mDurationMap.Find(aPacket->pts, duration)) {
data->mDuration = media::TimeUnit::FromMicroseconds(duration);
- } else {
+ } else
+#endif
+ {
data->mDuration = media::TimeUnit::FromMicroseconds(aPacket->duration);
}
-#endif
data->mTimecode = media::TimeUnit::FromMicroseconds(aPacket->dts);
if (mConfig.mCodec == CodecType::AV1) {
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoEncoder.h b/dom/media/platforms/ffmpeg/FFmpegVideoEncoder.h
@@ -15,6 +15,10 @@
// This must be the last header included
#include "FFmpegLibs.h"
+#if LIBAVCODEC_VERSION_MAJOR < 60 || defined(MOZ_WIDGET_ANDROID)
+# define MOZ_FFMPEG_ENCODER_USE_DURATION_MAP
+#endif
+
namespace mozilla {
template <int V>
@@ -80,6 +84,9 @@ class FFmpegVideoEncoder<LIBAV_VER> final
Maybe<SVCInfo> mSVCInfo{};
// Can be accessed on any thread, but only written on during init.
Atomic<bool> mIsHardwareAccelerated{false};
+#ifdef MOZ_FFMPEG_ENCODER_USE_DURATION_MAP
+ bool mUseDurationMap = false;
+#endif
// Some codecs use the input frames pts for rate control. We'd rather only use
// the duration. Synthetize fake pts based on integrating over the duration of
// input frames.