Fix AV1 videos being uploaded without transcoding, and two AV1 playback defects - #1990
Open
ThatHunky wants to merge 2 commits into
Open
Fix AV1 videos being uploaded without transcoding, and two AV1 playback defects#1990ThatHunky wants to merge 2 commits into
ThatHunky wants to merge 2 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1. AV1 videos are uploaded without transcoding —
gifvideo.cppnGetVideoInforeportsPARAM_NUM_SUPPORTED_VIDEO_CODECfrom a hardcoded allowlist:AV_CODEC_ID_AV1is absent. The consequence chain:gifvideo.cppreturns 0 →PhotoViewersetsvideoConvertSupported = false→ the entire compression-setup block is skipped, soresultWidth/compressionsCount/selectedCompressionare never populated →compressItem.setState(videoConvertSupported && compressionsCount > 1, …)disables the compression UI → novideoEditedInfocarrying convert params → theSendMessagesHelpergatevideoEditedInfo != null && needConvert()fails → the original file is uploaded verbatim.It fails silently because it isn't an error path — it's a disabled feature. No error, no compression option, no indication the file went out unprocessed.
The fix adds AV1 to the allowlist, gated on API 29 where AOSP ships
c2.android.av1-dec, mirroring the existing HEVC guard. Note the convert pipeline decodes via platformMediaCodec, not the bundled FFmpeg — so nobuild_ffmpeg.shchange is required.Evidence
Device captures on a Pixel 9 Pro (Telegram 12.9.1, Android 17), logging enabled:
cache/sharing/<original>exynos.hevc.decoder+exynos.h264.encoderc2.google.av1.decoderonly — no encoder/Download/…verbatimexynos.hevc.decoder+exynos.h264.encoderRows 3 and 4 are the controlled pair — identical resolution, duration, HDR characteristics and route; only the codec differs:
For AV1, neither line appears, no encoder is created, and upload starts at
file_part=0straight from the on-disk path. The AV1 file was freshly re-encoded (different SHA256 and different decoded-frame MD5), ruling out dedup.2. One transient decoder error permanently disabled AV1 —
VideoPlayer.javaonPlayerErrorwroteunsupport_video/av01on anyMediaCodecDecoderExceptionmentioning av1, and nothing ever cleared it — no expiry, no retry, no reset on upgrade.supportsHardwareDecoder()then returned false for the life of the install, which gates thumbnails, playback, and strips AV1 URIs from the quality list. Codec-instance exhaustion from opening several videos at once is enough to trigger it, after which a device with working hardware AV1 behaves as if it had none. Only recovery was clearing app data.Replaced with a failure counter (threshold 3) that expires after 30 days and self-resets on app upgrade or when the verdict goes stale, and
CodecException.isTransient()failures aren't counted at all.3. Software decoders were never considered —
VideoPlayer.javasupportsHardwareDecoder()skipped every non-hardware-accelerated codec. Android 10+ ships a software AV1 decoder, but the method was used as a blanket gate, so on devices without hardware AV1 the video track was dropped entirely while audio kept playing — the widely reported "AV1 plays sound with a black screen". The video wasn't failing to decode; it was never being decoded.Added
supportsSoftwareDecoder()andsupportsDecoder(codec, w, h)(software permitted up to 1080p), used for the three hard gates that discarded the track.supportsHardwareDecoder()is retained for quality-selection heuristics, where preferring hardware is correct.Review notes
Things a reviewer should push on, stated rather than hidden:
triedAv1CodecFallback), reset on first-frame render and inreleasePlayer— neither is on the retry path. Below the blacklist thresholdfilterByCodecmay strip nothing, so an unbounded retry would loop forever.isCodecBlacklisted()writes SharedPreferences from what reads as a predicate (the self-healing reset). Self-limiting: only reached on a cache miss.reportCodecFailure's read-modify-write isn't atomic — concurrent failures can lose an increment. That only makes blacklisting slower, never wrong.onRenderedFirstFrame, which felt too invasive here.Also reported upstream at https://bugs.telegram.org/c/64017 (
DrKLO/Telegramhas issues disabled).