tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 729e32cb210d5aee6d8459bfbb715efbb706e65d
parent b00727bfd19041149e87ee14e351f2fb7268563e
Author: Andrew Osmond <aosmond@gmail.com>
Date:   Thu,  8 Jan 2026 15:56:04 +0000

Bug 2008354 - Part 2. Ensure we configure H264 MediaCodec encoders properly. r=media-playback-reviewers,jolin

This includes various H264 encoder options that we currently only set
for libx264.

Differential Revision: https://phabricator.services.mozilla.com/D277797

Diffstat:
Mdom/media/platforms/ffmpeg/FFmpegVideoEncoder.cpp | 78++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 46 insertions(+), 32 deletions(-)

diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoEncoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoEncoder.cpp @@ -522,21 +522,33 @@ MediaResult FFmpegVideoEncoder<LIBAV_VER>::InitEncoderInternal(bool aHardware) { } } +#ifdef MOZ_WIDGET_ANDROID + // If we are using MediaCodec, we can set more options. + if (aHardware) { + if (mConfig.mBitrateMode == BitrateMode::Constant) { + mLib->av_opt_set(mCodecContext->priv_data, "bitrate_mode", "cbr", 0); + } else { + mLib->av_opt_set(mCodecContext->priv_data, "bitrate_mode", "vbr", 0); + } + } +#endif + nsAutoCString h264Log; if (mConfig.mCodecSpecific.is<H264Specific>()) { - // TODO: Set profile, level, avcc/annexb for openh264 and others. - if (mCodecName == "libx264") { - const H264Specific& h264Specific = - mConfig.mCodecSpecific.as<H264Specific>(); - H264Settings s = GetH264Settings(h264Specific); - mCodecContext->profile = s.mProfile; - mCodecContext->level = s.mLevel; - for (const auto& pair : s.mSettingKeyValuePairs) { - mLib->av_opt_set(mCodecContext->priv_data, pair.first.get(), - pair.second.get(), 0); - } + const H264Specific& h264Specific = + mConfig.mCodecSpecific.as<H264Specific>(); + H264Settings s = GetH264Settings(h264Specific); + mCodecContext->profile = s.mProfile; + mCodecContext->level = s.mLevel; + for (const auto& pair : s.mSettingKeyValuePairs) { + mLib->av_opt_set(mCodecContext->priv_data, pair.first.get(), + pair.second.get(), 0); + } - // Log the settings. + // Log the settings. + const char* formatStr = + h264Specific.mFormat == H264BitStreamFormat::AVC ? "AVCC" : "AnnexB"; + if (mCodecName.Equals("libx264"_ns)) { // When using profile other than EXTENDED, the profile string is in the // first element of mSettingKeyValuePairs, while EXTENDED profile has no // profile string. @@ -550,11 +562,13 @@ MediaResult FFmpegVideoEncoder<LIBAV_VER>::InitEncoderInternal(bool aHardware) { const char* levelStr = s.mSettingKeyValuePairs.Length() == 3 ? s.mSettingKeyValuePairs[1].second.get() : s.mSettingKeyValuePairs[0].second.get(); - const char* formatStr = - h264Specific.mFormat == H264BitStreamFormat::AVC ? "AVCC" : "AnnexB"; h264Log.AppendPrintf(", H264: profile - %d (%s), level %d (%s), %s", mCodecContext->profile, profileStr, mCodecContext->level, levelStr, formatStr); + } else { + h264Log.AppendPrintf(", H264: profile - %d, level %d, %s", + mCodecContext->profile, mCodecContext->level, + formatStr); } } @@ -912,34 +926,34 @@ FFmpegVideoEncoder<LIBAV_VER>::GetSVCSettings() { FFmpegVideoEncoder<LIBAV_VER>::H264Settings FFmpegVideoEncoder< LIBAV_VER>::GetH264Settings(const H264Specific& aH264Specific) { - MOZ_ASSERT(mCodecName == "libx264", - "GetH264Settings is libx264-only for now"); - nsTArray<std::pair<nsCString, nsCString>> keyValuePairs; Maybe<H264Setting> profile = GetH264Profile(aH264Specific.mProfile); MOZ_RELEASE_ASSERT(profile.isSome()); - if (!profile->mString.IsEmpty()) { - keyValuePairs.AppendElement(std::make_pair("profile"_ns, profile->mString)); - } else { - MOZ_RELEASE_ASSERT(aH264Specific.mProfile == - H264_PROFILE::H264_PROFILE_EXTENDED); - } + MOZ_RELEASE_ASSERT(!profile->mString.IsEmpty() || + aH264Specific.mProfile == + H264_PROFILE::H264_PROFILE_EXTENDED); Maybe<H264Setting> level = GetH264Level(aH264Specific.mLevel); MOZ_RELEASE_ASSERT(level.isSome()); MOZ_RELEASE_ASSERT(!level->mString.IsEmpty()); + + if (!profile->mString.IsEmpty()) { + keyValuePairs.AppendElement(std::make_pair("profile"_ns, profile->mString)); + } keyValuePairs.AppendElement(std::make_pair("level"_ns, level->mString)); - // Set format: libx264's default format is annexb. - if (aH264Specific.mFormat == H264BitStreamFormat::AVC) { - keyValuePairs.AppendElement(std::make_pair("x264-params"_ns, "annexb=0")); - // mCodecContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER - // if we don't want to append SPS/PPS data in all keyframe - // (LIBAVCODEC_VERSION_MAJOR >= 57 only). - } else { - // Set annexb explicitly even if it's default format. - keyValuePairs.AppendElement(std::make_pair("x264-params"_ns, "annexb=1")); + if (mCodecName.Equals("libx264"_ns)) { + // Set format: libx264's default format is annexb. + if (aH264Specific.mFormat == H264BitStreamFormat::AVC) { + keyValuePairs.AppendElement(std::make_pair("x264-params"_ns, "annexb=0")); + // mCodecContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER + // if we don't want to append SPS/PPS data in all keyframe + // (LIBAVCODEC_VERSION_MAJOR >= 57 only). + } else { + // Set annexb explicitly even if it's default format. + keyValuePairs.AppendElement(std::make_pair("x264-params"_ns, "annexb=1")); + } } return H264Settings{.mProfile = profile->mValue,