Skip to content

Commit 5e9cc00

Browse files
committed
Make filter/context pure
1 parent ea4fd39 commit 5e9cc00

1 file changed

Lines changed: 71 additions & 53 deletions

File tree

Lines changed: 71 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,69 @@
1-
cimport libav as lib
2-
31
import weakref
42

5-
from av.audio.frame cimport alloc_audio_frame
6-
from av.dictionary cimport _Dictionary
7-
from av.dictionary import Dictionary
8-
from av.error cimport err_check
9-
from av.filter.link cimport alloc_filter_pads
10-
from av.frame cimport Frame
11-
from av.utils cimport avrational_to_fraction
12-
from av.video.frame cimport alloc_video_frame
3+
import cython
4+
import cython.cimports.libav as lib
5+
from cython.cimports.av.audio.frame import alloc_audio_frame
6+
from cython.cimports.av.dictionary import _Dictionary
7+
from cython.cimports.av.error import err_check
8+
from cython.cimports.av.filter.link import alloc_filter_pads
9+
from cython.cimports.av.frame import Frame
10+
from cython.cimports.av.utils import avrational_to_fraction
11+
from cython.cimports.av.video.frame import alloc_video_frame
1312

13+
from av.dictionary import Dictionary
1414

15-
cdef object _cinit_sentinel = object()
15+
_cinit_sentinel = cython.declare(object, object())
1616

1717

18-
cdef FilterContext wrap_filter_context(Graph graph, Filter filter, lib.AVFilterContext *ptr):
19-
cdef FilterContext self = FilterContext(_cinit_sentinel)
18+
@cython.cfunc
19+
def wrap_filter_context(
20+
graph: Graph, filter: Filter, ptr: cython.pointer[lib.AVFilterContext]
21+
) -> FilterContext:
22+
self: FilterContext = FilterContext(_cinit_sentinel)
2023
self._graph = weakref.ref(graph)
2124
self.filter = filter
2225
self.ptr = ptr
2326
return self
2427

2528

26-
cdef class FilterContext:
29+
@cython.cclass
30+
class FilterContext:
2731
def __cinit__(self, sentinel):
2832
if sentinel is not _cinit_sentinel:
2933
raise RuntimeError("cannot construct FilterContext")
3034

3135
def __repr__(self):
32-
if self.ptr != NULL:
33-
name = repr(self.ptr.name) if self.ptr.name != NULL else "<NULL>"
36+
if self.ptr != cython.NULL:
37+
name = repr(self.ptr.name) if self.ptr.name != cython.NULL else "<NULL>"
3438
else:
3539
name = "None"
3640

37-
parent = self.filter.ptr.name if self.filter and self.filter.ptr != NULL else None
41+
parent = (
42+
self.filter.ptr.name
43+
if self.filter and self.filter.ptr != cython.NULL
44+
else None
45+
)
3846
return f"<av.FilterContext {name} of {parent!r} at 0x{id(self):x}>"
3947

4048
@property
4149
def name(self):
42-
if self.ptr.name != NULL:
50+
if self.ptr.name != cython.NULL:
4351
return self.ptr.name
4452

4553
@property
4654
def inputs(self):
4755
if self._inputs is None:
48-
self._inputs = alloc_filter_pads(self.filter, self.ptr.input_pads, True, self)
56+
self._inputs = alloc_filter_pads(
57+
self.filter, self.ptr.input_pads, True, self
58+
)
4959
return self._inputs
5060

5161
@property
5262
def outputs(self):
5363
if self._outputs is None:
54-
self._outputs = alloc_filter_pads(self.filter, self.ptr.output_pads, False, self)
64+
self._outputs = alloc_filter_pads(
65+
self.filter, self.ptr.output_pads, False, self
66+
)
5567
return self._outputs
5668

5769
def init(self, args=None, **kwargs):
@@ -60,40 +72,45 @@ def init(self, args=None, **kwargs):
6072
if args and kwargs:
6173
raise ValueError("cannot init from args and kwargs")
6274

63-
cdef _Dictionary dict_ = None
64-
cdef char *c_args = NULL
75+
dict_: _Dictionary = None
76+
c_args: cython.p_char = cython.NULL
6577
if args or not kwargs:
6678
if args:
6779
c_args = args
6880
err_check(lib.avfilter_init_str(self.ptr, c_args))
6981
else:
7082
dict_ = Dictionary(kwargs)
71-
err_check(lib.avfilter_init_dict(self.ptr, &dict_.ptr))
83+
err_check(lib.avfilter_init_dict(self.ptr, cython.address(dict_.ptr)))
7284

7385
self.inited = True
7486
if dict_:
7587
raise ValueError(f"unused config: {', '.join(sorted(dict_))}")
7688

77-
def link_to(self, FilterContext input_, int output_idx=0, int input_idx=0):
89+
def link_to(
90+
self,
91+
input_: FilterContext,
92+
output_idx: cython.int = 0,
93+
input_idx: cython.int = 0,
94+
):
7895
err_check(lib.avfilter_link(self.ptr, output_idx, input_.ptr, input_idx))
79-
96+
8097
@property
8198
def graph(self):
82-
if (graph := self._graph()):
99+
if graph := self._graph():
83100
return graph
84101
else:
85102
raise RuntimeError("graph is unallocated")
86103

87-
def push(self, Frame frame):
88-
cdef int res
104+
def push(self, frame: Frame | None):
105+
res: cython.int
89106

90107
if frame is None:
91-
with nogil:
92-
res = lib.av_buffersrc_write_frame(self.ptr, NULL)
108+
with cython.nogil:
109+
res = lib.av_buffersrc_write_frame(self.ptr, cython.NULL)
93110
err_check(res)
94111
return
95112
elif self.filter.name in ("abuffer", "buffer"):
96-
with nogil:
113+
with cython.nogil:
97114
res = lib.av_buffersrc_write_frame(self.ptr, frame.ptr)
98115
err_check(res)
99116
return
@@ -108,9 +125,8 @@ def push(self, Frame frame):
108125
self.inputs[0].linked.context.push(frame)
109126

110127
def pull(self):
111-
cdef Frame frame
112-
cdef int res
113-
128+
frame: Frame
129+
res: cython.int
114130
if self.filter.name == "buffersink":
115131
frame = alloc_video_frame()
116132
elif self.filter.name == "abuffersink":
@@ -127,46 +143,48 @@ def pull(self):
127143

128144
self.graph.configure()
129145

130-
with nogil:
146+
with cython.nogil:
131147
res = lib.av_buffersink_get_frame(self.ptr, frame.ptr)
132148
err_check(res)
133149

134150
frame._init_user_attributes()
135-
frame.time_base = avrational_to_fraction(&self.ptr.inputs[0].time_base)
151+
frame.time_base = avrational_to_fraction(
152+
cython.address(self.ptr.inputs[0].time_base)
153+
)
136154
return frame
137155

138-
def process_command(self, cmd, arg=None, int res_len=1024, int flags=0):
156+
def process_command(
157+
self, cmd, arg=None, res_len: cython.int = 1024, flags: cython.int = 0
158+
):
139159
if not cmd:
140160
raise ValueError("Invalid cmd")
141161

142-
cdef char *c_cmd = NULL
143-
cdef char *c_arg = NULL
144-
145-
c_cmd = cmd
162+
c_arg: cython.p_char = cython.NULL
163+
c_cmd: cython.p_char = cmd
146164
if arg is not None:
147165
c_arg = arg
148166

149-
cdef char *c_res = NULL
150-
cdef int ret
151-
cdef bytearray res_buf = None
152-
cdef unsigned char[:] view
153-
cdef bytes b
154-
cdef int nul
167+
c_res: cython.p_char = cython.NULL
168+
ret: cython.int
169+
res_buf: bytearray = None
170+
view: cython.uchar[:]
171+
b: bytes
172+
nul: cython.int
155173

156174
if res_len > 0:
157175
res_buf = bytearray(res_len)
158176
view = res_buf
159-
c_res = <char*>&view[0]
160-
else:
161-
c_res = NULL
177+
c_res = cython.cast(cython.p_char, cython.address(view[0]))
162178

163-
with nogil:
164-
ret = lib.avfilter_process_command(self.ptr, c_cmd, c_arg, c_res, res_len, flags)
179+
with cython.nogil:
180+
ret = lib.avfilter_process_command(
181+
self.ptr, c_cmd, c_arg, c_res, res_len, flags
182+
)
165183
err_check(ret)
166184

167185
if res_buf is not None:
168186
b = bytes(res_buf)
169-
nul = b.find(b'\x00')
187+
nul = b.find(b"\x00")
170188
if nul >= 0:
171189
b = b[:nul]
172190
if b:

0 commit comments

Comments
 (0)