Note: this is an upstream Telegram-Android defect that Forkgram inherits, not something introduced here. Filing it because Forkgram is actively maintained and could carry a fix ahead of upstream — DrKLO/Telegram has issues disabled, so there is nowhere else to report it in the open.
Summary
AV1 video input bypasses the video conversion pipeline entirely. The original file is uploaded unmodified — no downscale, no transcode to a widely-supported codec — and the failure is completely silent: no error, no compression option, no indication to the user that the file was sent unprocessed.
Consequences:
- A 4K AV1 clip uploads at full size (~126 MB here) instead of being downscaled to 1080p
- Recipients without AV1 support get audio with no video
- Previews/thumbnails are unreliable
- Uploads are slow, because the full-resolution original is transferred
This is increasingly common in the wild: Pixel "Video Boost" returns AV1, and Pixel 10 exposes AV1 recording in the camera app directly.
Evidence — controlled device capture
Four sends on a Pixel 9 Pro (Tensor G4), same build, Telegram logging enabled throughout. The build emits begin convert … on entry to conversion and compression completed … on success; those are the discriminators.
| # |
Source |
Res |
Route |
Converted? |
Codec components created |
Uploaded from |
| 1 |
AV1 |
4K |
share sheet |
❌ |
— |
cache/sharing/<original name> |
| 2 |
HEVC |
1080p |
in-app picker |
✅ |
c2.exynos.hevc.decoder + c2.exynos.h264.encoder |
cache/…mp4 (generated) |
| 3 |
AV1 |
4K |
in-app picker |
❌ |
c2.google.av1.decoder only — no encoder |
/storage/emulated/0/Download/…mp4 (verbatim) |
| 4 |
HEVC |
4K |
in-app picker |
✅ |
c2.exynos.hevc.decoder + c2.exynos.h264.encoder |
cache/…mp4 (generated) |
Runs 3 and 4 are the controlled pair — identical resolution (2160×3840), duration (28.6 s), HDR characteristics (10-bit BT.2020/HLG), source content and entry route. Only the codec differs.
Run 4 (HEVC, 4K) converts correctly:
D tmessages: begin convert /storage/emulated/0/Download/TEST_4K_HEVC_control.mp4
startTime = -1 avatarStartTime = -1 endTime -1
rWidth = 1080 rHeight = 1920 rotation = 0
oWidth = 2160 oHeight = 3840 framerate = 30 bitrate = 6800000 originalBitrate = 0
D tmessages: compression completed time=27387 needCompress=true w=1080 h=1920
bitrate=6800000 file size=23,8 MB encoder_name=c2.exynos.h264.encoder
4K → 1080p, 128.5 MB → 23.8 MB.
Run 3 (AV1, 4K) does not convert. Upload begins at file_part=0 straight from the file's on-disk location, ~7 s into the capture, with no preceding conversion phase:
D tmessages: debug_uploading: send reqId 9449
/storage/emulated/0/Download/TEST_4K_AV1_reencoded.mp4 file_part=0 isBig=true
Neither begin convert nor compression completed appears, and no video encoder is instantiated. The single c2.google.av1.decoder runs in PID 1209 (mediaserver) — system thumbnail extraction — not in Telegram's process.
Both entry routes and both resolutions were tested. Route and resolution are excluded; the defect tracks the codec.
Run 3 used a freshly re-encoded AV1 file with a different SHA256 and different decoded-frame MD5 from run 1, ruling out server-side dedup by file_id or content fingerprint.
Why this looks like a gap rather than a policy choice
In MediaCodecVideoConvertor.convertVideoInternal(), conversion is gated on:
boolean needConvertVideo = false;
if (videoIndex >= 0 && !extractor.getTrackFormat(videoIndex)
.getString(MediaFormat.KEY_MIME).equals(MediaController.VIDEO_MIME_TYPE)) {
needConvertVideo = true; // VIDEO_MIME_TYPE = "video/avc"
}
if (needCompress || needConvertVideo) { /* transcode */ } else { /* remux */ }
Any mime other than video/avc should therefore be transcoded — and run 2 confirms this empirically, logging needCompress=false yet converting HEVC → H.264 anyway. So AV1 falling through is inconsistent with the code's evident intent; something upstream of this decides AV1 is not convertible.
Reproduction
- Enable logging: Settings → tap the version number ~10× → Debug Menu → Enable Logs. Verify with
adb logcat -d | grep tmessages before proceeding — without this every marker is absent and the result is meaningless.
adb logcat -c
- Send a 4K AV1
.mp4 (any route), wait for the upload to complete.
adb logcat -d > out.log
- Grep for
begin convert and compression completed — both absent for AV1, present for an equivalent HEVC/H.264 file.
Secondary: two AV1 playback defects
Independent of the above, from reading TMessagesProj/src/main/java/org/telegram/ui/Components/VideoPlayer.java on master:
1. A single transient decoder exception permanently blacklists AV1. In onPlayerError():
if (cause.toString().contains("av1") || cause.toString().contains("av01")) {
MessagesController.getGlobalMainSettings().edit()
.putBoolean("unsupport_video/av01", true).commit();
supportsHardwareDecoder() reads that flag and returns false for the life of the install — no expiry, no retry, no reset on app upgrade. It then 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 perfectly good hardware AV1 behaves as though it has none. Only recovery is clearing app data. Suggested fix: a failure counter with a threshold plus expiry, invalidated on app version change, and scoped to (mime, resolution, bit depth) rather than the whole codec.
2. Software decoders are never considered. supportsHardwareDecoder() does if (!MediaCodecUtil.isHardwareAccelerated(info, mime)) continue;. Android 10+ mandates a software AV1 decoder (c2.android.av1-dec) and Telegram bundles its own FFmpeg, but neither is used as a fallback — so on devices without hardware AV1 the video track is dropped entirely while audio keeps playing. Suggested fix: keep the hardware check for quality-selection heuristics, but allow software decode below a resolution threshold for the hard gates that currently discard the track.
Also filed upstream
Reported on Telegram's own tracker (the only open channel — DrKLO/Telegram has issues disabled): https://bugs.telegram.org/c/64017
Environment
- App: Telegram Android 12.9.1 (69792)
- Device: Google Pixel 9 Pro (Tensor G4, hardware AV1 decode present), Android 17 (API 37)
- Source files: 4K AV1,
yuv420p10le, BT.2020 / HLG (arib-std-b67), from Pixel "Video Boost"
- Source analysis against
DrKLO/Telegram master; note released builds have drifted — the convertVideoInternal original=… log string in current source does not appear in shipping builds, and a logcat line reading Compiler allocated NNMB to compile … convertVideoInternal(…) is an ART JIT message, not a FileLog entry (false positive when grepping).
Summary
AV1 video input bypasses the video conversion pipeline entirely. The original file is uploaded unmodified — no downscale, no transcode to a widely-supported codec — and the failure is completely silent: no error, no compression option, no indication to the user that the file was sent unprocessed.
Consequences:
This is increasingly common in the wild: Pixel "Video Boost" returns AV1, and Pixel 10 exposes AV1 recording in the camera app directly.
Evidence — controlled device capture
Four sends on a Pixel 9 Pro (Tensor G4), same build, Telegram logging enabled throughout. The build emits
begin convert …on entry to conversion andcompression completed …on success; those are the discriminators.cache/sharing/<original name>c2.exynos.hevc.decoder+c2.exynos.h264.encodercache/…mp4(generated)c2.google.av1.decoderonly — no encoder/storage/emulated/0/Download/…mp4(verbatim)c2.exynos.hevc.decoder+c2.exynos.h264.encodercache/…mp4(generated)Runs 3 and 4 are the controlled pair — identical resolution (2160×3840), duration (28.6 s), HDR characteristics (10-bit BT.2020/HLG), source content and entry route. Only the codec differs.
Run 4 (HEVC, 4K) converts correctly:
4K → 1080p, 128.5 MB → 23.8 MB.
Run 3 (AV1, 4K) does not convert. Upload begins at
file_part=0straight from the file's on-disk location, ~7 s into the capture, with no preceding conversion phase:Neither
begin convertnorcompression completedappears, and no video encoder is instantiated. The singlec2.google.av1.decoderruns in PID 1209 (mediaserver) — system thumbnail extraction — not in Telegram's process.Both entry routes and both resolutions were tested. Route and resolution are excluded; the defect tracks the codec.
Run 3 used a freshly re-encoded AV1 file with a different SHA256 and different decoded-frame MD5 from run 1, ruling out server-side dedup by
file_idor content fingerprint.Why this looks like a gap rather than a policy choice
In
MediaCodecVideoConvertor.convertVideoInternal(), conversion is gated on:Any mime other than
video/avcshould therefore be transcoded — and run 2 confirms this empirically, loggingneedCompress=falseyet converting HEVC → H.264 anyway. So AV1 falling through is inconsistent with the code's evident intent; something upstream of this decides AV1 is not convertible.Reproduction
adb logcat -d | grep tmessagesbefore proceeding — without this every marker is absent and the result is meaningless.adb logcat -c.mp4(any route), wait for the upload to complete.adb logcat -d > out.logbegin convertandcompression completed— both absent for AV1, present for an equivalent HEVC/H.264 file.Secondary: two AV1 playback defects
Independent of the above, from reading
TMessagesProj/src/main/java/org/telegram/ui/Components/VideoPlayer.javaonmaster:1. A single transient decoder exception permanently blacklists AV1. In
onPlayerError():supportsHardwareDecoder()reads that flag and returnsfalsefor the life of the install — no expiry, no retry, no reset on app upgrade. It then 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 perfectly good hardware AV1 behaves as though it has none. Only recovery is clearing app data. Suggested fix: a failure counter with a threshold plus expiry, invalidated on app version change, and scoped to(mime, resolution, bit depth)rather than the whole codec.2. Software decoders are never considered.
supportsHardwareDecoder()doesif (!MediaCodecUtil.isHardwareAccelerated(info, mime)) continue;. Android 10+ mandates a software AV1 decoder (c2.android.av1-dec) and Telegram bundles its own FFmpeg, but neither is used as a fallback — so on devices without hardware AV1 the video track is dropped entirely while audio keeps playing. Suggested fix: keep the hardware check for quality-selection heuristics, but allow software decode below a resolution threshold for the hard gates that currently discard the track.Also filed upstream
Reported on Telegram's own tracker (the only open channel —
DrKLO/Telegramhas issues disabled): https://bugs.telegram.org/c/64017Environment
yuv420p10le, BT.2020 / HLG (arib-std-b67), from Pixel "Video Boost"DrKLO/Telegrammaster; note released builds have drifted — theconvertVideoInternal original=…log string in current source does not appear in shipping builds, and a logcat line readingCompiler allocated NNMB to compile … convertVideoInternal(…)is an ART JIT message, not aFileLogentry (false positive when grepping).