pdeljanov / Symphonia

Pure Rust multimedia format demuxing, tag reading, and audio decoding library
Mozilla Public License 2.0
2.45k stars 145 forks source link

[Feature request] make it easier to detect what a track / codec type is #258

Open hasezoey opened 10 months ago

hasezoey commented 10 months ago

From what i can tell, there currently is no way to "elegantly" determine what a track (/ codec)'s type is, as in "video", "audio" (others, like "subtitle"), the only workaround i found is comparing Track::codec_params.codec with CODEC_TYPE_NULL which does not seem to elegant.

This proposal is to add a helper function to determine the type of a codec (and maybe proxied to Track) with signature fn codec_type(&self) -> CodecType (where CodecType is a enum of types) or fn is_audio_codec(&self) -> bool. AND/OR a way to determine if a codec of a track is currently supported (not returning core (codec):unsupported codec)

also in addition maybe a function like default_track_audio (similar to default_track) but only for returning the first / default audio track. (because in something like webm it chooses the first stream, which is a video stream and fails)

pdeljanov commented 10 months ago

I agree with this general request.

CodecType isn't an enum because the whole system is designed to be extended out-of-tree. For example, you can implement your own Decoder for some codec and assign it a custom CodecType. Likewise, you could implement a Demuxer for a format that encapsulates a track encoded with some unknown codec. So it's not possible for Symphonia to map a codec type to media type by itself.

I was thinking of doing a bit of a clean-up of Track and CodecParameters since some things are in the wrong place (e.g., timing info. in CodeParameters). Part of that was adding a TrackType to each track. This should be possible since the demuxer knows what it's encapsulating.


#[non_exhaustive]
enum TrackType {
    Audio,
    Video,
    Subtitle,
    Data,  // Maybe
}
voidentente commented 7 months ago

Or, instead of a structural change, simply add a bulk of non-audio codec types?

pub(crate) fn codec_id_to_type(track: &TrackElement) -> Option<CodecType> {
    // ..

    match track.codec_id.as_str() {
        "V_AV1" => Some(codecs::CODEC_TYPE_AV1),
        // ..
    }
}

Edit: I'd be willing to simply go through (for example) https://www.matroska.org/technical/codec_specs.html and add the missing codecs.

Edit 2: Have a look at this? https://github.com/voidentente/Symphonia/commit/da50d26b15889e700dfe9ead8401215077db4f84