Skip to content

Transformer: export permanently stalls, then watchdog aborts with "Muxer error", on VFR input with long gaps between video samples #3357

Description

@PierfrancescoSoffritti

Version

Media3 1.10.1

More version details

No response

Devices that reproduce the issue

  • Pixel 9 (Android 16)
  • API 35 arm64 emulator
  • In production crash reporting: ~1,850 occurrences / ~870 affected users across many OEMs and Android 12–16 since June 2026

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Not tested

Reproduction steps

Repro assets (synthetic clip + trace + logcat): https://github.com/PierfrancescoSoffritti/media3-transformer-vfr-gap-repro

synthetic_vfr_hole.mp4 (18.6 MB, 5 min, AVC 1612×720 24 fps + continuous AAC 44.1 kHz) has no video samples at all between 60 s and 180 s (a 120 s gap), while audio is continuous — mimicking screen recorders that emit no frames while the screen is static. It is fully synthetic (testsrc2 + sine; the ffmpeg command to regenerate it is in the repo README).

val mediaItem = MediaItem.Builder()
  .setUri(inputUri) // synthetic_vfr_hole.mp4
  .setClippingConfiguration(
    MediaItem.ClippingConfiguration.Builder()
      .setStartPositionMs(5_000)
      .setEndPositionMs(295_000)
      .build()
  )
  .build()
Transformer.Builder(context).addListener(listener).build()
  .start(EditedMediaItem.Builder(mediaItem).build(), outputPath)

On an API 35 arm64 emulator this fails ~45 s in, every time.

Expected result

The export completes; gaps between video samples are tolerated (the next video sample after a gap is delivered, and MuxerWrapper already has an "unstuck" branch for consecutive same-track timestamps more than MAX_TRACK_WRITE_AHEAD_US apart).

Actual result

The export proceeds normally until the timeline reaches the video-sample gap, then all muxer output stops permanently and the watchdog aborts with ERROR_CODE_MUXING_TIMEOUT:

androidx.media3.transformer.ExportException: Muxer error
  at androidx.media3.transformer.Transformer.lambda$maybeInitializeExportWatchdogTimer$0(Transformer.java:1276)
Caused by: java.lang.IllegalStateException: Abort: no output sample written in the last 25000 milliseconds.

This is a deadlock, not slowness. We first hit it in production with real screen recordings (one 2h07m file has video-sample gaps up to 992 s; a multi-item clipped Composition over it stalls identically), and with the timeout raised to 600 000 ms the export still never recovers. DebugTraceUtil at abort time shows:

  • VideoDecoder.AcceptedInput — the last accepted input samples are the final frames before the gap; no further video input is ever delivered to the decoder (the first video sample after the gap never arrives from the asset loader).
  • VideoDecoder.ProducedOutput and VideoFrameProcessor.QueueFrame counts track perfectly and then starve together — downstream stages are healthy and idle.
  • All audio-graph components (AudioDecoder/AudioGraph/AudioMixer/AudioEncoder) report "No events" (audio on the encoded/transmux path).

DebugTrace JSON and logcat excerpt are in the linked repo.

Media

https://github.com/PierfrancescoSoffritti/media3-transformer-vfr-gap-repro (synthetic_vfr_hole.mp4)

Bug Report

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions