diff --git a/av/codec/__init__.py b/av/codec/__init__.py index 178ed5106..f8d4d75ae 100644 --- a/av/codec/__init__.py +++ b/av/codec/__init__.py @@ -2,7 +2,6 @@ Capabilities, Codec, Properties, - codec_descriptor, codecs_available, find_best_pix_fmt_of_list, ) @@ -12,7 +11,6 @@ "Capabilities", "Codec", "Properties", - "codec_descriptor", "codecs_available", "find_best_pix_fmt_of_list", "CodecContext", diff --git a/av/codec/codec.py b/av/codec/codec.py index 681e8cd1d..aff456ecb 100644 --- a/av/codec/codec.py +++ b/av/codec/codec.py @@ -4,7 +4,6 @@ from cython.cimports import libav as lib from cython.cimports.av.audio.format import get_audio_format from cython.cimports.av.codec.hwaccel import wrap_hwconfig -from cython.cimports.av.descriptor import wrap_avclass from cython.cimports.av.utils import avrational_to_fraction from cython.cimports.av.video.format import VideoFormat, get_pix_fmt, get_video_format from cython.cimports.libc.stdlib import free, malloc @@ -146,10 +145,6 @@ def mode(self): def is_decoder(self): return not self.is_encoder - @property - def descriptor(self): - return wrap_avclass(self.ptr.priv_class) - @property def name(self): return self.ptr.name or "" @@ -355,7 +350,6 @@ def get_codec_names(): codecs_available = get_codec_names() -codec_descriptor = wrap_avclass(lib.avcodec_get_class()) def dump_codecs(): diff --git a/av/codec/codec.pyi b/av/codec/codec.pyi index 221872c33..1459bc777 100644 --- a/av/codec/codec.pyi +++ b/av/codec/codec.pyi @@ -4,7 +4,6 @@ from typing import ClassVar, Literal, Sequence, cast, overload from av.audio.codeccontext import AudioCodecContext from av.audio.format import AudioFormat -from av.descriptor import Descriptor from av.subtitles.codeccontext import SubtitleCodecContext from av.video.codeccontext import VideoCodecContext from av.video.format import VideoFormat @@ -53,7 +52,6 @@ class Codec: def is_decoder(self) -> bool: ... @property def mode(self) -> Literal["r", "w"]: ... - descriptor: Descriptor @property def name(self) -> str: ... @property @@ -107,10 +105,6 @@ class Codec: VideoCodecContext | AudioCodecContext | SubtitleCodecContext | CodecContext ): ... -class codec_descriptor: - name: str - options: tuple[int, ...] - codecs_available: set[str] def dump_codecs() -> None: ... diff --git a/av/descriptor.pxd b/av/descriptor.pxd deleted file mode 100644 index 404f646af..000000000 --- a/av/descriptor.pxd +++ /dev/null @@ -1,20 +0,0 @@ -cimport libav as lib - - -cdef class Descriptor: - - # These are present as: - # - AVCodecContext.av_class (same as avcodec_get_class()) - # - AVFormatContext.av_class (same as avformat_get_class()) - # - AVFilterContext.av_class (same as avfilter_get_class()) - # - AVCodec.priv_class - # - AVOutputFormat.priv_class - # - AVInputFormat.priv_class - # - AVFilter.priv_class - - cdef const lib.AVClass *ptr - - cdef object _options # Option list cache. - - -cdef Descriptor wrap_avclass(const lib.AVClass*) diff --git a/av/descriptor.py b/av/descriptor.py deleted file mode 100644 index faaa0f57c..000000000 --- a/av/descriptor.py +++ /dev/null @@ -1,76 +0,0 @@ -import cython -import cython.cimports.libav as lib -from cython.cimports.av.option import ( - Option, - OptionChoice, - wrap_option, - wrap_option_choice, -) - -_cinit_sentinel = cython.declare(object, object()) - - -@cython.cfunc -def wrap_avclass(ptr: cython.pointer[cython.const[lib.AVClass]]) -> Descriptor | None: - if ptr == cython.NULL: - return None - obj: Descriptor = Descriptor(_cinit_sentinel) - obj.ptr = ptr - return obj - - -@cython.final -@cython.cclass -class Descriptor: - def __cinit__(self, sentinel): - if sentinel is not _cinit_sentinel: - raise RuntimeError("Cannot construct av.Descriptor") - - @property - def name(self): - return self.ptr.class_name if self.ptr.class_name else None - - @property - def options(self): - ptr: cython.pointer[cython.const[lib.AVOption]] = self.ptr.option - choice_ptr: cython.pointer[cython.const[lib.AVOption]] - option: Option - option_choice: OptionChoice - choice_is_default: cython.bint - if self._options is None: - options: list = [] - ptr = self.ptr.option - while ptr != cython.NULL and ptr.name != cython.NULL: - if ptr.type == lib.AV_OPT_TYPE_CONST: - ptr += 1 - continue - choices: list = [] - if ( - ptr.unit != cython.NULL - ): # option has choices (matching const options) - choice_ptr = self.ptr.option - while choice_ptr != cython.NULL and choice_ptr.name != cython.NULL: - if ( - choice_ptr.type != lib.AV_OPT_TYPE_CONST - or choice_ptr.unit != ptr.unit - ): - choice_ptr += 1 - continue - choice_is_default = ( - choice_ptr.default_val.i64 == ptr.default_val.i64 - or ptr.type == lib.AV_OPT_TYPE_FLAGS - and choice_ptr.default_val.i64 & ptr.default_val.i64 - ) - option_choice = wrap_option_choice( - choice_ptr, choice_is_default - ) - choices.append(option_choice) - choice_ptr += 1 - option = wrap_option(tuple(choices), ptr) - options.append(option) - ptr += 1 - self._options = tuple(options) - return self._options - - def __repr__(self): - return f"<{self.__class__.__name__} {self.name} at 0x{id(self):x}>" diff --git a/av/descriptor.pyi b/av/descriptor.pyi deleted file mode 100644 index 4aa2144a3..000000000 --- a/av/descriptor.pyi +++ /dev/null @@ -1,5 +0,0 @@ -from .option import Option - -class Descriptor: - name: str - options: tuple[Option, ...] diff --git a/av/filter/__init__.py b/av/filter/__init__.py index 14c8563ce..cffc49e7d 100644 --- a/av/filter/__init__.py +++ b/av/filter/__init__.py @@ -1,3 +1,3 @@ -from .filter import Filter, filter_descriptor, filters_available +from .filter import Filter, filters_available from .graph import Graph as Graph from .loudnorm import stats as stats diff --git a/av/filter/filter.pxd b/av/filter/filter.pxd index 0a7cd41a0..d74065a19 100644 --- a/av/filter/filter.pxd +++ b/av/filter/filter.pxd @@ -1,13 +1,10 @@ cimport libav as lib -from av.descriptor cimport Descriptor - cdef class Filter: cdef const lib.AVFilter *ptr cdef object _inputs cdef object _outputs - cdef Descriptor _descriptor cdef Filter wrap_filter(const lib.AVFilter *ptr) diff --git a/av/filter/filter.py b/av/filter/filter.py index bd4d21896..acbbc111a 100644 --- a/av/filter/filter.py +++ b/av/filter/filter.py @@ -1,6 +1,5 @@ import cython from cython.cimports import libav as lib -from cython.cimports.av.descriptor import wrap_avclass from cython.cimports.av.filter.link import alloc_filter_pads _cinit_sentinel = cython.declare(object, object()) @@ -26,18 +25,6 @@ def __cinit__(self, name): if not self.ptr: raise ValueError(f"no filter {name}") - @property - def descriptor(self): - if self._descriptor is None: - self._descriptor = wrap_avclass(self.ptr.priv_class) - return self._descriptor - - @property - def options(self): - if self.descriptor is None: - return - return self.descriptor.options - @property def name(self): return self.ptr.name @@ -78,4 +65,3 @@ def get_filter_names() -> set: filters_available = get_filter_names() -filter_descriptor = wrap_avclass(lib.avfilter_get_class()) diff --git a/av/filter/filter.pyi b/av/filter/filter.pyi index f07f317fc..090d4f1d0 100644 --- a/av/filter/filter.pyi +++ b/av/filter/filter.pyi @@ -1,11 +1,6 @@ -from av.descriptor import Descriptor -from av.option import Option - class Filter: name: str description: str - descriptor: Descriptor - options: tuple[Option, ...] | None flags: int def __init__(self, name: str) -> None: ... diff --git a/av/format.py b/av/format.py index a8222577b..fec69f7a0 100644 --- a/av/format.py +++ b/av/format.py @@ -2,7 +2,6 @@ import cython import cython.cimports.libav as lib -from cython.cimports.av.descriptor import wrap_avclass _cinit_bypass_sentinel = cython.declare(object, object()) @@ -78,17 +77,6 @@ def __cinit__(self, name, mode=None): def __repr__(self): return f"" - @property - def descriptor(self): - if self.iptr: - return wrap_avclass(self.iptr.priv_class) - else: - return wrap_avclass(self.optr.priv_class) - - @property - def options(self): - return self.descriptor.options - @property def input(self): """An input-only view of this format.""" @@ -178,4 +166,3 @@ def get_input_format_names() -> set: formats_available = get_output_format_names() formats_available.update(get_input_format_names()) -format_descriptor = wrap_avclass(lib.avformat_get_class()) diff --git a/av/option.pxd b/av/option.pxd deleted file mode 100644 index 4c8eaffbf..000000000 --- a/av/option.pxd +++ /dev/null @@ -1,14 +0,0 @@ -cimport libav as lib - - -cdef class BaseOption: - cdef const lib.AVOption *ptr - -cdef class Option(BaseOption): - cdef readonly tuple choices - -cdef class OptionChoice(BaseOption): - cdef readonly bint is_default - -cdef Option wrap_option(tuple choices, const lib.AVOption *ptr) -cdef OptionChoice wrap_option_choice(const lib.AVOption *ptr, bint is_default) diff --git a/av/option.py b/av/option.py deleted file mode 100644 index 8ed3c8fb1..000000000 --- a/av/option.py +++ /dev/null @@ -1,203 +0,0 @@ -from enum import Enum, Flag - -import cython -import cython.cimports.libav as lib -from cython import NULL, bint -from cython.cimports.libc.stdint import uint64_t - -_cinit_sentinel = cython.declare(object, object()) - - -@cython.cfunc -def wrap_option( - choices: tuple, ptr: cython.pointer[cython.const[lib.AVOption]] -) -> Option: - if ptr == NULL: - return None - obj: Option = Option(_cinit_sentinel) - obj.ptr = ptr - obj.choices = choices - return obj - - -@cython.cfunc -def flag_in_bitfield(bitfield: uint64_t, flag: uint64_t) -> bool: - return bool(bitfield & flag) - - -class OptionType(Enum): - FLAGS = lib.AV_OPT_TYPE_FLAGS - INT = lib.AV_OPT_TYPE_INT - INT64 = lib.AV_OPT_TYPE_INT64 - DOUBLE = lib.AV_OPT_TYPE_DOUBLE - FLOAT = lib.AV_OPT_TYPE_FLOAT - STRING = lib.AV_OPT_TYPE_STRING - RATIONAL = lib.AV_OPT_TYPE_RATIONAL - BINARY = lib.AV_OPT_TYPE_BINARY - DICT = lib.AV_OPT_TYPE_DICT - UINT64 = lib.AV_OPT_TYPE_UINT64 - CONST = lib.AV_OPT_TYPE_CONST - IMAGE_SIZE = lib.AV_OPT_TYPE_IMAGE_SIZE - PIXEL_FMT = lib.AV_OPT_TYPE_PIXEL_FMT - SAMPLE_FMT = lib.AV_OPT_TYPE_SAMPLE_FMT - VIDEO_RATE = lib.AV_OPT_TYPE_VIDEO_RATE - DURATION = lib.AV_OPT_TYPE_DURATION - COLOR = lib.AV_OPT_TYPE_COLOR - CHANNEL_LAYOUT = lib.AV_OPT_TYPE_CHLAYOUT - BOOL = lib.AV_OPT_TYPE_BOOL - - -class OptionFlags(Flag): - ENCODING_PARAM = lib.AV_OPT_FLAG_ENCODING_PARAM - DECODING_PARAM = lib.AV_OPT_FLAG_DECODING_PARAM - AUDIO_PARAM = lib.AV_OPT_FLAG_AUDIO_PARAM - VIDEO_PARAM = lib.AV_OPT_FLAG_VIDEO_PARAM - SUBTITLE_PARAM = lib.AV_OPT_FLAG_SUBTITLE_PARAM - EXPORT = lib.AV_OPT_FLAG_EXPORT - READONLY = lib.AV_OPT_FLAG_READONLY - FILTERING_PARAM = lib.AV_OPT_FLAG_FILTERING_PARAM - - -_INT_TYPES = cython.declare( - tuple, - ( - lib.AV_OPT_TYPE_FLAGS, - lib.AV_OPT_TYPE_INT, - lib.AV_OPT_TYPE_INT64, - lib.AV_OPT_TYPE_PIXEL_FMT, - lib.AV_OPT_TYPE_SAMPLE_FMT, - lib.AV_OPT_TYPE_DURATION, - lib.AV_OPT_TYPE_CHLAYOUT, - lib.AV_OPT_TYPE_BOOL, - ), -) - - -@cython.cclass -class BaseOption: - def __cinit__(self, sentinel): - if sentinel is not _cinit_sentinel: - raise RuntimeError(f"Cannot construct av.{self.__class__.__name__}") - - @property - def name(self): - return self.ptr.name - - @property - def help(self): - return self.ptr.help if self.ptr.help != NULL else "" - - @property - def flags(self): - return self.ptr.flags - - @property - def is_encoding_param(self): - return flag_in_bitfield(self.ptr.flags, lib.AV_OPT_FLAG_ENCODING_PARAM) - - @property - def is_decoding_param(self): - return flag_in_bitfield(self.ptr.flags, lib.AV_OPT_FLAG_DECODING_PARAM) - - @property - def is_audio_param(self): - return flag_in_bitfield(self.ptr.flags, lib.AV_OPT_FLAG_AUDIO_PARAM) - - @property - def is_video_param(self): - return flag_in_bitfield(self.ptr.flags, lib.AV_OPT_FLAG_VIDEO_PARAM) - - @property - def is_subtitle_param(self): - return flag_in_bitfield(self.ptr.flags, lib.AV_OPT_FLAG_SUBTITLE_PARAM) - - @property - def is_export(self): - return flag_in_bitfield(self.ptr.flags, lib.AV_OPT_FLAG_EXPORT) - - @property - def is_readonly(self): - return flag_in_bitfield(self.ptr.flags, lib.AV_OPT_FLAG_READONLY) - - @property - def is_filtering_param(self): - return flag_in_bitfield(self.ptr.flags, lib.AV_OPT_FLAG_FILTERING_PARAM) - - -@cython.final -@cython.cclass -class Option(BaseOption): - @property - def type(self): - return OptionType(self.ptr.type) - - @property - def offset(self): - """ - This can be used to find aliases of an option. - Options in a particular descriptor with the same offset are aliases. - """ - return self.ptr.offset - - @property - def default(self): - if self.ptr.type in _INT_TYPES: - return self.ptr.default_val.i64 - if self.ptr.type in ( - lib.AV_OPT_TYPE_DOUBLE, - lib.AV_OPT_TYPE_FLOAT, - lib.AV_OPT_TYPE_RATIONAL, - ): - return self.ptr.default_val.dbl - if self.ptr.type in ( - lib.AV_OPT_TYPE_STRING, - lib.AV_OPT_TYPE_BINARY, - lib.AV_OPT_TYPE_IMAGE_SIZE, - lib.AV_OPT_TYPE_VIDEO_RATE, - lib.AV_OPT_TYPE_COLOR, - ): - return self.ptr.default_val.str if self.ptr.default_val.str != NULL else "" - - @property - def min(self): - if self.ptr.type in _INT_TYPES: - return int(self.ptr.min) - return self.ptr.min - - @property - def max(self): - if self.ptr.type in _INT_TYPES: - return int(self.ptr.max) - return self.ptr.max - - def __repr__(self): - return f"" - - -@cython.cfunc -def wrap_option_choice( - ptr: cython.pointer[cython.const[lib.AVOption]], is_default: bint -) -> OptionChoice | None: - if ptr == NULL: - return None - - obj: OptionChoice = OptionChoice(_cinit_sentinel) - obj.ptr = ptr - obj.is_default = is_default - return obj - - -@cython.final -@cython.cclass -class OptionChoice(BaseOption): - """ - Represents AV_OPT_TYPE_CONST options which are essentially - choices of non-const option with same unit. - """ - - @property - def value(self): - return self.ptr.default_val.i64 - - def __repr__(self): - return f"" diff --git a/av/option.pyi b/av/option.pyi deleted file mode 100644 index f989a1138..000000000 --- a/av/option.pyi +++ /dev/null @@ -1,55 +0,0 @@ -from enum import Enum, Flag -from typing import cast - -class OptionType(Enum): - FLAGS = cast(int, ...) - INT = cast(int, ...) - INT64 = cast(int, ...) - DOUBLE = cast(int, ...) - FLOAT = cast(int, ...) - STRING = cast(int, ...) - RATIONAL = cast(int, ...) - BINARY = cast(int, ...) - DICT = cast(int, ...) - CONST = cast(int, ...) - IMAGE_SIZE = cast(int, ...) - PIXEL_FMT = cast(int, ...) - SAMPLE_FMT = cast(int, ...) - VIDEO_RATE = cast(int, ...) - DURATION = cast(int, ...) - COLOR = cast(int, ...) - CHANNEL_LAYOUT = cast(int, ...) - BOOL = cast(int, ...) - -class OptionFlags(Flag): - ENCODING_PARAM = cast(int, ...) - DECODING_PARAM = cast(int, ...) - AUDIO_PARAM = cast(int, ...) - VIDEO_PARAM = cast(int, ...) - SUBTITLE_PARAM = cast(int, ...) - EXPORT = cast(int, ...) - READONLY = cast(int, ...) - FILTERING_PARAM = cast(int, ...) - -class BaseOption: - name: str - help: str - flags: int - is_encoding_param: bool - is_decoding_param: bool - is_audio_param: bool - is_video_param: bool - is_subtitle_param: bool - is_export: bool - is_readonly: bool - is_filtering_param: bool - -class Option(BaseOption): - type: OptionType - offset: int - default: int - min: int - max: int - -class OptionChoice(BaseOption): - value: int diff --git a/tests/test_options.py b/tests/test_options.py deleted file mode 100644 index f5593a77d..000000000 --- a/tests/test_options.py +++ /dev/null @@ -1,17 +0,0 @@ -from av import ContainerFormat -from av.option import Option, OptionType - - -class TestOptions: - def test_mov_options(self) -> None: - mov = ContainerFormat("mov") - options = mov.descriptor.options # type: ignore - by_name = {opt.name: opt for opt in options} - - opt = by_name.get("use_absolute_path") - - assert isinstance(opt, Option) - assert opt.name == "use_absolute_path" - - # This was not a good option to actually test. - assert opt.type in (OptionType.BOOL, OptionType.INT)