ffmpeg

Determine which decoders/demuxers/parsers ffmpeg needs to successfully consume file


I'm trying to custom compile a build of ffmpeg.wasm as the prebuilt, "support everything" is a tad hefty at 35mb. This base build (as well as standard ffmpeg, running on my desktop) works perfectly fine for the provided file, however, so I do have something I can work against.

My issue is that I'm a bit stuck on figuring out what precisely I need to support the provided file, the correct combination of decoders, demuxers, parsers, etc., and the encoders, muxers I'll need to use to convert it to my desired output.

I'm sure I can brute force this with time, but is there a way of having ffmpeg report precisely which combination it's using when running against a file? I've tried -report but it doesn't seem to contain this information, really it contains no more useful codex information than the standard output log as far as I can tell.

For example, I can see the current file I'm testing with (foo.m4s) is h264 video and aac audio, so I tried the following flags based on what I've been able to find online and by looking through the list of muxers:

--enable-decoder=aac,h264
--enable-demuxer=aac,h264
--enable-parser=aac,h264

However, this results in the following error:

foo.m4s: Invalid data found when processing input

So it seems like it's not quite the correct list.

Is there any good way to debug this? Some way of having ffmpeg itself report exactly what I'll need set to handle this conversion using my own compilation? As the goal is a minimum build, adding the kitchen sink and slowly reducing over time will obviously be super time consuming, so I'd like to avoid it if at all possible.


Edit: Trial and error got me down to this, though I don't quite understand it (and the question still stands as I could reasonably need to handle other files in the future):

--enable-demuxer=aac,mov
--enable-parser=aac

mov for some reason ended up being the fix? The first line of ffmpeg's output was Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'foo.m4s', and so I simply grabbed those one-by-one and sure enough mov worked, despite the video having h264. Would love if someone could explain this too.


Solution

  • mov worked, despite the video having h264.

    This indicates some confusion about media files. So, a brief primer follows.

    A media file, at the top-level, consists of one or more streams or tracks. The syntax and layout of the metadata about these tracks constitutes a container format. Examples are AVI, MP4, WebM, MXF, WAV...etc

    The language in which each stream is written is its codec. A container may have streams of different codecs. A codec may be found in many distinct containers. So, a h264/aac set of streams may be present within MP4 or AVI or MKV.

    The module which works to parse the container is the demuxer. The module which parses a stream is the decoder. The demuxer extracts chunks of data, based on metadata, and emits a packet belonging to a stream. Depending on the stream's codec, this packet may first be passed on to a parser (specific to the codec), and the output packet(s) from the parser onto the decoder. The decoder outputs uncompressed media data.

    Primer over.


    A .m4s file is a fragment of a specially formatted MP4 file ('fragmented mp4') used in streaming scenarios. It is produced by a DASH or HLS muxer, which will generate a short codec initialization file (usually called init.mp4) followed by a chain of .m4s files. The init data is needed to process the media in the m4s.

    The name of the demuxer in this case is mov,mp4,m4a,3gp,3g2,mj2. The multiple strings don't identify different demuxers. That happens to be the unwieldy name of a single demuxer which handles all of these file types because they each are small variations on the same underlying file structure.


    With ffprobe, if you run

    ffprobe -v 0 -of compact=p=0 -show_entries format=format_name:stream=codec_name INPUT

    that will output

    codec_name=h264
    codec_name=aac
    format_name=mov,mp4,m4a,3gp,3g2,mj2