Media3Engine's two MIME tables are untested, and one carries a "never reached" claim nothing checks #85

Closed
opened 2026-08-25 03:21:52 +00:00 by JMR-dev · 2 comments
JMR-dev commented 2026-08-25 03:21:52 +00:00 (Migrated from github.com)

Filed from a coverage read on ad28293. Media3Engine reports 0/38 on the JVM — and most of that is correct and should stay.

Most of this is device-only and already covered where it can be

transcode, buildTransformer, pollProgress, close and the constructor drive Media3's Transformer against real codecs. androidTest/Media3EngineTest and RemuxTest exercise them on a device; JaCoCo measures testDebugUnitTest only, so their 0% is a measurement boundary, not a gap. Do not chase it, and do not mock Transformer to make a number move.

Two pure lookups are the real gap

private fun videoMimeTypeFor(codec: VideoCodec): String? = when (codec) { ... }   // 6 lines, 0 covered
private fun audioMimeTypeFor(codec: AudioCodec): String? = when (codec) { ... }   // 8 lines, 0 covered

Enum-to-MIME tables with no device dependency at all. private, so widening to internal is the #57 precedent.

And one of them carries a claim nothing checks:

// Never reached: only an Encode plan consults this, and COPY/NONE are not Encode.
VideoCodec.COPY, VideoCodec.NONE -> null

That is an assertion about callers, sitting in a branch. If it is true, a test should say so; if it stops being true, nothing currently notices. audioMimeTypeFor carries a sibling claim — that MP3 and FLAC have no Android encoder so the router sends them to FFmpeg — which is checkable against ConversionRouter.

Done means

Both tables tested arm by arm, including every null arm, and the "never reached" claim either proved against the router's Encode plans or rewritten to say what is actually guaranteed.

Mutation: point VideoCodec.H265 at MimeTypes.VIDEO_H264 and the test goes red naming H.265.

Related

The same codec vocabulary is written out in at least four places across this codebase and they have already drifted — see the ticket on CodecNames vs AndroidDeviceCodecs. Fixing this one in isolation is fine; just do not add a fifth table.

_Filed from a coverage read on `ad28293`. `Media3Engine` reports **0/38** on the JVM — and most of that is correct and should stay._ ### Most of this is device-only and already covered where it can be `transcode`, `buildTransformer`, `pollProgress`, `close` and the constructor drive Media3's `Transformer` against real codecs. `androidTest/Media3EngineTest` and `RemuxTest` exercise them on a device; **JaCoCo measures `testDebugUnitTest` only**, so their 0% is a measurement boundary, not a gap. Do not chase it, and do not mock `Transformer` to make a number move. ### Two pure lookups are the real gap ```kotlin private fun videoMimeTypeFor(codec: VideoCodec): String? = when (codec) { ... } // 6 lines, 0 covered private fun audioMimeTypeFor(codec: AudioCodec): String? = when (codec) { ... } // 8 lines, 0 covered ``` Enum-to-MIME tables with no device dependency at all. `private`, so widening to `internal` is the #57 precedent. **And one of them carries a claim nothing checks:** ```kotlin // Never reached: only an Encode plan consults this, and COPY/NONE are not Encode. VideoCodec.COPY, VideoCodec.NONE -> null ``` That is an assertion about *callers*, sitting in a branch. If it is true, a test should say so; if it stops being true, nothing currently notices. `audioMimeTypeFor` carries a sibling claim — that MP3 and FLAC have no Android encoder so the router sends them to FFmpeg — which is checkable against `ConversionRouter`. ### Done means Both tables tested arm by arm, including every `null` arm, and the "never reached" claim either **proved** against the router's Encode plans or **rewritten** to say what is actually guaranteed. **Mutation:** point `VideoCodec.H265` at `MimeTypes.VIDEO_H264` and the test goes red naming H.265. ### Related The same codec vocabulary is written out in at least four places across this codebase and they have already drifted — see the ticket on `CodecNames` vs `AndroidDeviceCodecs`. Fixing this one in isolation is fine; just do not add a fifth table.
JMR-dev commented 2026-08-25 03:22:24 +00:00 (Migrated from github.com)

Read #87 before writing these tests. The tables this ticket covers have already drifted from CodecNames — five codec names resolve in one and not the other, in both directions.

Testing this table arm-by-arm in isolation would encode the disagreement rather than catch it. #87 carries the comparison and the mutation that actually bites (add an alias to one table only, and the cross-check goes red).

Read **#87** before writing these tests. The tables this ticket covers have already drifted from `CodecNames` — five codec names resolve in one and not the other, in both directions. Testing this table arm-by-arm in isolation would **encode the disagreement** rather than catch it. #87 carries the comparison and the mutation that actually bites (add an alias to one table only, and the cross-check goes red).
JMR-dev commented 2026-08-25 03:49:33 +00:00 (Migrated from github.com)

#87 and #74 landed together in PR #90. Media3Engine.kt is untouched — this ticket's file, left
alone deliberately — but the cross-check it should join now exists, and audio has no partner
table without it
.

What is there to join:

  • app/src/test/java/org/libremediaconverter/codec/CodecVocabularyTest.kt cross-checks
    CodecNames.VIDEO_ALIASES (now an internal map, not a when, precisely so a test can
    enumerate it) against AndroidDeviceCodecs.NAME_TO_MIME, in both directions and on meaning as
    well as membership.
  • AndroidDeviceCodecs.mimeFor(codec: VideoCodec): String? is now internal. That is the same
    shape as videoMimeTypeFor — enum to MIME — so the video half of this ticket is one assertion:
    for every VideoCodec, the two must return the same MIME wherever both are non-null. If
    they disagree, one of the engines is being asked for a codec the device check was asked about
    under a different name.

The audio half is the gap #90 could not close. CodecNames.AUDIO_ALIASES exists and is
enumerable, but AndroidDeviceCodecs is video-only, so there is no second audio table in the
module to compare it against. audioMimeTypeFor is that second table. Widening it to internal
(the JVM test source set is a friend of main; MainActivity.kt:36-38 carries the reasoning) is
what makes an audio cross-check possible at all.

Please do not add a fifth table. The pattern #90 settled on, if it helps: one legitimate asymmetry
is listed rather than implied (AndroidDeviceCodecs.DECODE_ONLY_NAMES = {"mpeg4"} — decodable
input with no VideoCodec to name it), and the list is itself checked in both directions, because
otherwise it is an escape hatch for the next divergence. Mutation-checked: adding "x265" to it
goes red.

#87 and #74 landed together in PR #90. `Media3Engine.kt` is untouched — this ticket's file, left alone deliberately — but the cross-check it should join now exists, and **audio has no partner table without it**. What is there to join: - `app/src/test/java/org/libremediaconverter/codec/CodecVocabularyTest.kt` cross-checks `CodecNames.VIDEO_ALIASES` (now an `internal` map, not a `when`, precisely so a test can enumerate it) against `AndroidDeviceCodecs.NAME_TO_MIME`, in both directions and on meaning as well as membership. - `AndroidDeviceCodecs.mimeFor(codec: VideoCodec): String?` is now `internal`. That is the same shape as `videoMimeTypeFor` — enum to MIME — so the video half of this ticket is one assertion: **for every `VideoCodec`, the two must return the same MIME wherever both are non-null.** If they disagree, one of the engines is being asked for a codec the device check was asked about under a different name. The audio half is the gap #90 could not close. `CodecNames.AUDIO_ALIASES` exists and is enumerable, but `AndroidDeviceCodecs` is video-only, so there is no second audio table in the module to compare it against. `audioMimeTypeFor` is that second table. Widening it to `internal` (the JVM test source set is a friend of `main`; `MainActivity.kt:36-38` carries the reasoning) is what makes an audio cross-check possible at all. Please do not add a fifth table. The pattern #90 settled on, if it helps: one legitimate asymmetry is *listed* rather than implied (`AndroidDeviceCodecs.DECODE_ONLY_NAMES = {"mpeg4"}` — decodable input with no `VideoCodec` to name it), and the list is itself checked in both directions, because otherwise it is an escape hatch for the next divergence. Mutation-checked: adding `"x265"` to it goes red.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JMR-dev/LibreMediaConverter#85