Skip to content

Commit 4937cfb

Browse files
committed
Make container/input pure
1 parent 9e09e3c commit 4937cfb

1 file changed

Lines changed: 50 additions & 53 deletions

File tree

Lines changed: 50 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,55 @@
1-
from libc.stdint cimport int64_t
2-
from libc.stdlib cimport free, malloc
3-
4-
from av.codec.context cimport CodecContext, wrap_codec_context
5-
from av.container.streams cimport StreamContainer
6-
from av.dictionary cimport _Dictionary
7-
from av.error cimport err_check
8-
from av.packet cimport Packet
9-
from av.stream cimport Stream, wrap_stream
10-
from av.utils cimport avdict_to_dict
1+
import cython
2+
from cython.cimports.av.codec.context import CodecContext, wrap_codec_context
3+
from cython.cimports.av.container.streams import StreamContainer
4+
from cython.cimports.av.dictionary import _Dictionary
5+
from cython.cimports.av.error import err_check
6+
from cython.cimports.av.packet import Packet
7+
from cython.cimports.av.stream import Stream, wrap_stream
8+
from cython.cimports.av.utils import avdict_to_dict
9+
from cython.cimports.libc.stdint import int64_t
10+
from cython.cimports.libc.stdlib import free, malloc
1111

1212
from av.dictionary import Dictionary
1313

1414

15-
cdef close_input(InputContainer self):
15+
@cython.cfunc
16+
def close_input(self: InputContainer):
1617
self.streams = StreamContainer()
1718
if self.input_was_opened:
18-
with nogil:
19+
with cython.nogil:
1920
# This causes `self.ptr` to be set to NULL.
20-
lib.avformat_close_input(&self.ptr)
21+
lib.avformat_close_input(cython.address(self.ptr))
2122
self.input_was_opened = False
2223

23-
24-
cdef class InputContainer(Container):
24+
@cython.cclass
25+
class InputContainer(Container):
2526
def __cinit__(self, *args, **kwargs):
26-
cdef CodecContext py_codec_context
27-
cdef unsigned int i
28-
cdef lib.AVStream *stream
29-
cdef lib.AVCodec *codec
30-
cdef lib.AVCodecContext *codec_context
27+
py_codec_context: CodecContext
28+
i: cython.uint
29+
stream: cython.pointer[lib.AVStream]
30+
codec: cython.pointer[lib.AVCodec]
31+
codec_context: cython.pointer[lib.AVCodecContext]
3132

3233
# If we have either the global `options`, or a `stream_options`, prepare
3334
# a mashup of those options for each stream.
34-
cdef lib.AVDictionary **c_options = NULL
35-
cdef _Dictionary base_dict, stream_dict
35+
c_options: cython.pointer[cython.pointer[lib.AVDictionary]] = cython.NULL
36+
base_dict: _Dictionary
37+
stream_dict: _Dictionary
3638
if self.options or self.stream_options:
3739
base_dict = Dictionary(self.options)
38-
c_options = <lib.AVDictionary**>malloc(self.ptr.nb_streams * sizeof(void*))
40+
c_options = cython.cast(cython.pointer[cython.pointer[lib.AVDictionary]], malloc(self.ptr.nb_streams * cython.sizeof(cython.p_void)))
3941
for i in range(self.ptr.nb_streams):
40-
c_options[i] = NULL
42+
c_options[i] = cython.NULL
4143
if i < len(self.stream_options) and self.stream_options:
4244
stream_dict = base_dict.copy()
4345
stream_dict.update(self.stream_options[i])
44-
lib.av_dict_copy(&c_options[i], stream_dict.ptr, 0)
46+
lib.av_dict_copy(cython.address(c_options[i]), stream_dict.ptr, 0)
4547
else:
46-
lib.av_dict_copy(&c_options[i], base_dict.ptr, 0)
48+
lib.av_dict_copy(cython.address(c_options[i]), base_dict.ptr, 0)
4749

4850
self.set_timeout(self.open_timeout)
4951
self.start_timeout()
50-
with nogil:
52+
with cython.nogil:
5153
# This peeks are the first few frames to:
5254
# - set stream.disposition from codec.audio_service_type (not exposed);
5355
# - set stream.codec.bits_per_coded_sample;
@@ -62,10 +64,10 @@ def __cinit__(self, *args, **kwargs):
6264
self.set_timeout(None)
6365
self.err_check(ret)
6466

65-
# Cleanup all of our options.
67+
# Clean up all of our options.
6668
if c_options:
6769
for i in range(self.ptr.nb_streams):
68-
lib.av_dict_free(&c_options[i])
70+
lib.av_dict_free(cython.address(c_options[i]))
6971
free(c_options)
7072

7173
at_least_one_accelerated_context = False
@@ -75,7 +77,7 @@ def __cinit__(self, *args, **kwargs):
7577
stream = self.ptr.streams[i]
7678
codec = lib.avcodec_find_decoder(stream.codecpar.codec_id)
7779
if codec:
78-
# allocate and initialise decoder
80+
# allocate and initialize decoder
7981
codec_context = lib.avcodec_alloc_context3(codec)
8082
err_check(lib.avcodec_parameters_to_context(codec_context, stream.codecpar))
8183
codec_context.pkt_timebase = stream.time_base
@@ -141,19 +143,17 @@ def demux(self, *args, **kwargs):
141143
# For whatever reason, Cython does not like us directly passing kwargs
142144
# from one method to another. Without kwargs, it ends up passing a
143145
# NULL reference, which segfaults. So we force it to do something with it.
144-
# This is likely a bug in Cython; see https://github.com/cython/cython/issues/2166
145-
# (and others).
146+
# This is a bug in Cython; see https://github.com/cython/cython/issues/2166
146147
id(kwargs)
147148

148149
streams = self.streams.get(*args, **kwargs)
149-
150-
cdef bint *include_stream = <bint*>malloc(self.ptr.nb_streams * sizeof(bint))
151-
if include_stream == NULL:
150+
include_stream: cython.pointer[cython.bint] = cython.cast(cython.pointer[cython.bint], malloc(self.ptr.nb_streams * cython.sizeof(bint)))
151+
if include_stream == cython.NULL:
152152
raise MemoryError()
153153

154-
cdef unsigned int i
155-
cdef Packet packet
156-
cdef int ret
154+
i: cython.uint
155+
packet: Packet
156+
ret: cython.int
157157

158158
self.set_timeout(self.read_timeout)
159159
try:
@@ -169,7 +169,7 @@ def demux(self, *args, **kwargs):
169169
packet = Packet()
170170
try:
171171
self.start_timeout()
172-
with nogil:
172+
with cython.nogil:
173173
ret = lib.av_read_frame(self.ptr, packet.ptr)
174174
self.err_check(ret)
175175
except EOFError:
@@ -217,8 +217,8 @@ def decode(self, *args, **kwargs):
217217
yield frame
218218

219219
def seek(
220-
self, offset, *, bint backward=True, bint any_frame=False, Stream stream=None,
221-
bint unsupported_frame_offset=False, bint unsupported_byte_offset=False
220+
self, offset, *, backward: bint=True, any_frame: bint=False, stream: Stream | None=None,
221+
unsupported_frame_offset: bint =False, unsupported_byte_offset: bint =False
222222
):
223223
"""seek(offset, *, backward=True, any_frame=False, stream=None)
224224
@@ -249,16 +249,12 @@ def seek(
249249
"""
250250
self._assert_open()
251251

252-
# We used to take floats here and assume they were in seconds. This
253-
# was super confusing, so lets go in the complete opposite direction
254-
# and reject non-ints.
255252
if not isinstance(offset, int):
256253
raise TypeError("Container.seek only accepts integer offset.", type(offset))
257254

258-
cdef int64_t c_offset = offset
259-
260-
cdef int flags = 0
261-
cdef int ret
255+
c_offset: int64_t = offset
256+
flags: cython.int = 0
257+
ret: cython.int
262258

263259
if backward:
264260
flags |= lib.AVSEEK_FLAG_BACKWARD
@@ -271,18 +267,19 @@ def seek(
271267
if unsupported_byte_offset:
272268
flags |= lib.AVSEEK_FLAG_BYTE
273269

274-
cdef int stream_index = stream.index if stream else -1
275-
with nogil:
270+
stream_index: cython.int = stream.index if stream else -1
271+
with cython.nogil:
276272
ret = lib.av_seek_frame(self.ptr, stream_index, c_offset, flags)
277273
err_check(ret)
278274

279275
self.flush_buffers()
280276

281-
cdef flush_buffers(self):
277+
@cython.cfunc
278+
def flush_buffers(self):
282279
self._assert_open()
283280

284-
cdef Stream stream
285-
cdef CodecContext codec_context
281+
stream: Stream
282+
codec_context: CodecContext
286283

287284
for stream in self.streams:
288285
codec_context = stream.codec_context

0 commit comments

Comments
 (0)