File: option.pyx

package info (click to toggle)
python-av 14.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,664 kB
  • sloc: python: 4,712; sh: 175; ansic: 174; makefile: 123
file content (172 lines) | stat: -rw-r--r-- 5,138 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
cimport libav as lib

from av.utils cimport flag_in_bitfield

from enum import Enum, Flag


cdef object _cinit_sentinel = object()

cdef Option wrap_option(tuple choices, const lib.AVOption *ptr):
    if ptr == NULL:
        return None
    cdef Option obj = Option(_cinit_sentinel)
    obj.ptr = ptr
    obj.choices = choices
    return obj


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

cdef tuple _INT_TYPES = (
    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,
)

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


cdef 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

    # Option 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)


cdef 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 ""

    def _norm_range(self, value):
        if self.ptr.type in _INT_TYPES:
            return int(value)
        return value

    @property
    def min(self):
        return self._norm_range(self.ptr.min)

    @property
    def max(self):
        return self._norm_range(self.ptr.max)

    def __repr__(self):
        return (
            f"<av.{self.__class__.__name__} {self.name}"
            f" ({self.type} at *0x{self.offset:x}) at 0x{id(self):x}>"
        )


cdef OptionChoice wrap_option_choice(const lib.AVOption *ptr, bint is_default):
    if ptr == NULL:
        return None

    cdef OptionChoice obj = OptionChoice(_cinit_sentinel)
    obj.ptr = ptr
    obj.is_default = is_default
    return obj


cdef 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"<av.{self.__class__.__name__} {self.name} at 0x{id(self):x}>"