Skip to content

Commit eb8428d

Browse files
committed
Use Flag enum for format flags
1 parent 49c0605 commit eb8428d

2 files changed

Lines changed: 69 additions & 102 deletions

File tree

av/format.pyi

Lines changed: 35 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,42 @@
1-
__all__ = ("ContainerFormat", "formats_available")
1+
__all__ = ("Flags", "ContainerFormat", "formats_available")
22

3-
from typing import Literal
3+
from enum import Flag
4+
from typing import ClassVar, Literal
45

5-
from .enum import EnumFlag
6-
7-
class Flags(EnumFlag):
8-
NOFILE: int
9-
NEEDNUMBER: int
10-
SHOW_IDS: int
11-
GLOBALHEADER: int
12-
NOTIMESTAMPS: int
13-
GENERIC_INDEX: int
14-
TS_DISCONT: int
15-
VARIABLE_FPS: int
16-
NODIMENSIONS: int
17-
NOSTREAMS: int
18-
NOBINSEARCH: int
19-
NOGENSEARCH: int
20-
NO_BYTE_SEEK: int
21-
ALLOW_FLUSH: int
22-
TS_NONSTRICT: int
23-
TS_NEGATIVE: int
24-
SEEK_TO_PTS: int
6+
class Flags(Flag):
7+
no_file: ClassVar[Flags]
8+
need_number: ClassVar[Flags]
9+
show_ids: ClassVar[Flags]
10+
global_header: ClassVar[Flags]
11+
no_timestamps: ClassVar[Flags]
12+
generic_index: ClassVar[Flags]
13+
ts_discont: ClassVar[Flags]
14+
variable_fps: ClassVar[Flags]
15+
no_dimensions: ClassVar[Flags]
16+
no_streams: ClassVar[Flags]
17+
no_bin_search: ClassVar[Flags]
18+
no_gen_search: ClassVar[Flags]
19+
no_byte_seek: ClassVar[Flags]
20+
allow_flush: ClassVar[Flags]
21+
ts_nonstrict: ClassVar[Flags]
22+
ts_negative: ClassVar[Flags]
23+
seek_to_pts: ClassVar[Flags]
2524

2625
class ContainerFormat:
2726
def __init__(self, name: str, mode: Literal["r", "w"] | None = None) -> None: ...
28-
name: str
29-
long_name: str
30-
is_input: bool
31-
is_output: bool
32-
extensions: set[str]
33-
34-
# flags
35-
no_file: int
36-
need_number: int
37-
show_ids: int
38-
global_header: int
39-
no_timestamps: int
40-
generic_index: int
41-
ts_discont: int
42-
variable_fps: int
43-
no_dimensions: int
44-
no_streams: int
45-
no_bin_search: int
46-
no_gen_search: int
47-
no_byte_seek: int
48-
allow_flush: int
49-
ts_nonstrict: int
50-
ts_negative: int
51-
seek_to_pts: int
27+
@property
28+
def name(self) -> str: ...
29+
@property
30+
def long_name(self) -> str: ...
31+
@property
32+
def is_input(self) -> bool: ...
33+
@property
34+
def is_output(self) -> bool: ...
35+
@property
36+
def extensions(self) -> set[str]: ...
37+
@property
38+
def flags(self) -> int: ...
39+
@property
40+
def no_file(self) -> bool: ...
5241

5342
formats_available: set[str]

av/format.pyx

Lines changed: 34 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
cimport libav as lib
22

33
from av.descriptor cimport wrap_avclass
4-
from av.enum cimport define_enum
4+
5+
from enum import Flag
56

67

78
cdef object _cinit_bypass_sentinel = object()
@@ -16,41 +17,28 @@ cdef ContainerFormat build_container_format(lib.AVInputFormat* iptr, lib.AVOutpu
1617
return format
1718

1819

19-
Flags = define_enum("Flags", __name__, (
20-
("NOFILE", lib.AVFMT_NOFILE),
21-
("NEEDNUMBER", lib.AVFMT_NEEDNUMBER, "Needs '%d' in filename."),
22-
("SHOW_IDS", lib.AVFMT_SHOW_IDS, "Show format stream IDs numbers."),
23-
("GLOBALHEADER", lib.AVFMT_GLOBALHEADER, "Format wants global header."),
24-
("NOTIMESTAMPS", lib.AVFMT_NOTIMESTAMPS, "Format does not need / have any timestamps."),
25-
("GENERIC_INDEX", lib.AVFMT_GENERIC_INDEX, "Use generic index building code."),
26-
("TS_DISCONT", lib.AVFMT_TS_DISCONT,
27-
"""Format allows timestamp discontinuities.
28-
Note, muxers always require valid (monotone) timestamps"""),
29-
("VARIABLE_FPS", lib.AVFMT_VARIABLE_FPS, "Format allows variable fps."),
30-
("NODIMENSIONS", lib.AVFMT_NODIMENSIONS, "Format does not need width/height"),
31-
("NOSTREAMS", lib.AVFMT_NOSTREAMS, "Format does not require any streams"),
32-
("NOBINSEARCH", lib.AVFMT_NOBINSEARCH,
33-
"Format does not allow to fall back on binary search via read_timestamp"),
34-
("NOGENSEARCH", lib.AVFMT_NOGENSEARCH,
35-
"Format does not allow to fall back on generic search"),
36-
("NO_BYTE_SEEK", lib.AVFMT_NO_BYTE_SEEK, "Format does not allow seeking by bytes"),
37-
("ALLOW_FLUSH", lib.AVFMT_ALLOW_FLUSH,
38-
"""Format allows flushing. If not set, the muxer will not receive a NULL
39-
packet in the write_packet function."""),
40-
("TS_NONSTRICT", lib.AVFMT_TS_NONSTRICT,
41-
"""Format does not require strictly increasing timestamps, but they must
42-
still be monotonic."""),
43-
("TS_NEGATIVE", lib.AVFMT_TS_NEGATIVE,
44-
"""Format allows muxing negative timestamps. If not set the timestamp
45-
will be shifted in av_write_frame and av_interleaved_write_frame so they
46-
start from 0. The user or muxer can override this through
47-
AVFormatContext.avoid_negative_ts"""),
48-
("SEEK_TO_PTS", lib.AVFMT_SEEK_TO_PTS, "Seeking is based on PTS"),
49-
), is_flags=True)
50-
20+
class Flags(Flag):
21+
no_file = lib.AVFMT_NOFILE
22+
need_number: "Needs '%d' in filename." = lib.AVFMT_NEEDNUMBER
23+
show_ids: "Show format stream IDs numbers." = lib.AVFMT_SHOW_IDS
24+
global_header: "Format wants global header." = lib.AVFMT_GLOBALHEADER
25+
no_timestamps: "Format does not need / have any timestamps." = lib.AVFMT_NOTIMESTAMPS
26+
generic_index: "Use generic index building code." = lib.AVFMT_GENERIC_INDEX
27+
ts_discont: "Format allows timestamp discontinuities" = lib.AVFMT_TS_DISCONT
28+
variable_fps: "Format allows variable fps." = lib.AVFMT_VARIABLE_FPS
29+
no_dimensions: "Format does not need width/height" = lib.AVFMT_NODIMENSIONS
30+
no_streams: "Format does not require any streams" = lib.AVFMT_NOSTREAMS
31+
no_bin_search: "Format does not allow to fall back on binary search via read_timestamp" = lib.AVFMT_NOBINSEARCH
32+
no_gen_search: "Format does not allow to fall back on generic search" = lib.AVFMT_NOGENSEARCH
33+
no_byte_seek: "Format does not allow seeking by bytes" = lib.AVFMT_NO_BYTE_SEEK
34+
allow_flush: "Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function." = lib.AVFMT_ALLOW_FLUSH
35+
ts_nonstrict: "Format does not require strictly increasing timestamps, but they must still be monotonic." = lib.AVFMT_TS_NONSTRICT
36+
ts_negative: "Format allows muxing negative timestamps." = lib.AVFMT_TS_NEGATIVE
37+
# If not set the timestamp will be shifted in `av_write_frame()` and `av_interleaved_write_frame()`
38+
# so they start from 0. The user or muxer can override this through AVFormatContext.avoid_negative_ts
39+
seek_to_pts: "Seeking is based on PTS" = lib.AVFMT_SEEK_TO_PTS
5140

5241
cdef class ContainerFormat:
53-
5442
"""Descriptor of a container format.
5543
5644
:param str name: The name of the format.
@@ -63,12 +51,11 @@ cdef class ContainerFormat:
6351
if name is _cinit_bypass_sentinel:
6452
return
6553

66-
# We need to hold onto the original name because AVInputFormat.name
67-
# is actually comma-seperated, and so we need to remember which one
68-
# this was.
54+
# We need to hold onto the original name because AVInputFormat.name is
55+
# actually comma-separated, and so we need to remember which one this was.
6956
self.name = name
7057

71-
# Searches comma-seperated names.
58+
# Searches comma-separated names.
7259
if mode is None or mode == "r":
7360
self.iptr = lib.av_find_input_format(name)
7461

@@ -135,30 +122,21 @@ cdef class ContainerFormat:
135122
exts.update(self.optr.extensions.split(","))
136123
return exts
137124

138-
@Flags.property
125+
@property
139126
def flags(self):
127+
"""
128+
Get the flags bitmask for the format.
129+
130+
:rtype: int
131+
"""
140132
return (
141133
(self.iptr.flags if self.iptr else 0) |
142134
(self.optr.flags if self.optr else 0)
143135
)
144136

145-
no_file = flags.flag_property("NOFILE")
146-
need_number = flags.flag_property("NEEDNUMBER")
147-
show_ids = flags.flag_property("SHOW_IDS")
148-
global_header = flags.flag_property("GLOBALHEADER")
149-
no_timestamps = flags.flag_property("NOTIMESTAMPS")
150-
generic_index = flags.flag_property("GENERIC_INDEX")
151-
ts_discont = flags.flag_property("TS_DISCONT")
152-
variable_fps = flags.flag_property("VARIABLE_FPS")
153-
no_dimensions = flags.flag_property("NODIMENSIONS")
154-
no_streams = flags.flag_property("NOSTREAMS")
155-
no_bin_search = flags.flag_property("NOBINSEARCH")
156-
no_gen_search = flags.flag_property("NOGENSEARCH")
157-
no_byte_seek = flags.flag_property("NO_BYTE_SEEK")
158-
allow_flush = flags.flag_property("ALLOW_FLUSH")
159-
ts_nonstrict = flags.flag_property("TS_NONSTRICT")
160-
ts_negative = flags.flag_property("TS_NEGATIVE")
161-
seek_to_pts = flags.flag_property("SEEK_TO_PTS")
137+
@property
138+
def no_file(self):
139+
return bool(self.flags & lib.AVFMT_NOFILE)
162140

163141

164142
cdef get_output_format_names():

0 commit comments

Comments
 (0)