@@ -367,47 +367,89 @@ def get_codec_names():
367367 return names
368368
369369
370+ @cython .cfunc
371+ def get_media_type_name (media_type : lib .AVMediaType ) -> str :
372+ name = lib .av_get_media_type_string (media_type )
373+ return "unknown" if name == cython .NULL else name
374+
375+
376+ @cython .cfunc
377+ def get_codec_summaries ():
378+ summaries : dict = {}
379+ desc = cython .declare (
380+ cython .pointer [cython .const [lib .AVCodecDescriptor ]], cython .NULL
381+ )
382+ while True :
383+ desc = lib .avcodec_descriptor_next (desc )
384+ if not desc :
385+ break
386+ summaries [desc .name ] = [
387+ desc .long_name or "" ,
388+ get_media_type_name (desc .type ),
389+ desc .props ,
390+ lib .avcodec_find_decoder (desc .id ) != cython .NULL ,
391+ lib .avcodec_find_encoder (desc .id ) != cython .NULL ,
392+ ]
393+
394+ canonical_names : set = set (summaries )
395+
396+ ptr = cython .declare (cython .pointer [cython .const [lib .AVCodec ]])
397+ opaque : cython .p_void = cython .NULL
398+ while True :
399+ ptr = lib .av_codec_iterate (cython .address (opaque ))
400+ if not ptr :
401+ break
402+ if ptr .name in canonical_names :
403+ continue
404+
405+ desc = lib .avcodec_descriptor_get (ptr .id )
406+ summary = summaries .setdefault (
407+ ptr .name ,
408+ [
409+ ptr .long_name or "" ,
410+ get_media_type_name (ptr .type ),
411+ desc .props if desc else 0 ,
412+ False ,
413+ False ,
414+ ],
415+ )
416+ summary [3 if lib .av_codec_is_decoder (ptr ) else 4 ] = True
417+
418+ return summaries
419+
420+
370421codecs_available = get_codec_names ()
371422
372423
373424def dump_codecs ():
374425 """Print information about available codecs."""
375426
427+ def _type_char (media_type : str ) -> str :
428+ return "T" if media_type == "attachment" else media_type [0 ].upper ()
429+
376430 print (
377431 """Codecs:
378432 D..... = Decoding supported
379433 .E.... = Encoding supported
380434 ..V... = Video codec
381435 ..A... = Audio codec
382436 ..S... = Subtitle codec
437+ ..D... = Data codec
438+ ..T... = Attachment codec
383439 ...I.. = Intra frame-only codec
384440 ....L. = Lossy compression
385441 .....S = Lossless compression
386442 ------"""
387443 )
388444
389- for name in sorted (codecs_available ):
390- try :
391- e_codec = Codec (name , "w" )
392- except ValueError :
393- e_codec = None
394-
395- try :
396- d_codec = Codec (name , "r" )
397- except ValueError :
398- d_codec = None
399-
400- # TODO: Assert these always have the same properties.
401- codec = e_codec or d_codec
402-
403- try :
404- print (
405- f" { '.D' [bool (d_codec )]} { '.E' [bool (e_codec )]} { codec .type [0 ].upper ()} "
406- f"{ '.I' [codec .intra_only ]} { '.L' [codec .lossy ]} { '.S' [codec .lossless ]} "
407- f" { codec .name :<18} { codec .long_name } "
408- )
409- except Exception as e :
410- print (f"...... { codec .name :<18} ERROR: { e } " )
445+ for name , (long_name , media_type , props , can_decode , can_encode ) in sorted (get_codec_summaries ().items ()):
446+ print (
447+ f" { '.D' [can_decode ]} { '.E' [can_encode ]} { _type_char (media_type )} "
448+ f"{ '.I' [bool (props & lib .AV_CODEC_PROP_INTRA_ONLY )]} "
449+ f"{ '.L' [bool (props & lib .AV_CODEC_PROP_LOSSY )]} "
450+ f"{ '.S' [bool (props & lib .AV_CODEC_PROP_LOSSLESS )]} "
451+ f" { name :<18} { long_name } "
452+ )
411453
412454
413455def dump_hwconfigs ():
0 commit comments