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
1212from 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
2324
24- cdef class InputContainer(Container):
25+ @cython .cclass
26+ class InputContainer (Container ):
2527 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
28+ py_codec_context : CodecContext
29+ i : cython . uint
30+ stream : cython . pointer [ lib .AVStream ]
31+ codec : cython . pointer [ lib .AVCodec ]
32+ codec_context : cython . pointer [ lib .AVCodecContext ]
3133
3234 # If we have either the global `options`, or a `stream_options`, prepare
3335 # a mashup of those options for each stream.
34- cdef lib.AVDictionary ** c_options = NULL
35- cdef _Dictionary base_dict, stream_dict
36+ c_options : cython .pointer [cython .pointer [lib .AVDictionary ]] = cython .NULL
37+ base_dict : _Dictionary
38+ stream_dict : _Dictionary
3639 if self .options or self .stream_options :
3740 base_dict = Dictionary (self .options )
38- c_options = < lib.AVDictionary** > malloc(self .ptr.nb_streams * sizeof(void * ))
41+ c_options = cython .cast (
42+ cython .pointer [cython .pointer [lib .AVDictionary ]],
43+ malloc (self .ptr .nb_streams * cython .sizeof (cython .p_void )),
44+ )
3945 for i in range (self .ptr .nb_streams ):
40- c_options[i] = NULL
46+ c_options [i ] = cython . NULL
4147 if i < len (self .stream_options ) and self .stream_options :
4248 stream_dict = base_dict .copy ()
4349 stream_dict .update (self .stream_options [i ])
44- lib.av_dict_copy(& c_options[i], stream_dict.ptr, 0 )
50+ lib .av_dict_copy (cython . address ( c_options [i ]) , stream_dict .ptr , 0 )
4551 else :
46- lib.av_dict_copy(& c_options[i], base_dict.ptr, 0 )
52+ lib .av_dict_copy (cython . address ( c_options [i ]) , base_dict .ptr , 0 )
4753
4854 self .set_timeout (self .open_timeout )
4955 self .start_timeout ()
50- with nogil:
56+ with cython . nogil :
5157 # This peeks are the first few frames to:
5258 # - set stream.disposition from codec.audio_service_type (not exposed);
5359 # - set stream.codec.bits_per_coded_sample;
5460 # - set stream.duration;
5561 # - set stream.start_time;
5662 # - set stream.r_frame_rate to average value;
5763 # - open and closes codecs with the options provided.
58- ret = lib.avformat_find_stream_info(
59- self .ptr,
60- c_options
61- )
64+ ret = lib .avformat_find_stream_info (self .ptr , c_options )
6265 self .set_timeout (None )
6366 self .err_check (ret )
6467
65- # Cleanup all of our options.
68+ # Clean up all of our options.
6669 if c_options :
6770 for i in range (self .ptr .nb_streams ):
68- lib.av_dict_free(& c_options[i])
71+ lib .av_dict_free (cython . address ( c_options [i ]) )
6972 free (c_options )
7073
7174 at_least_one_accelerated_context = False
@@ -75,22 +78,34 @@ def __cinit__(self, *args, **kwargs):
7578 stream = self .ptr .streams [i ]
7679 codec = lib .avcodec_find_decoder (stream .codecpar .codec_id )
7780 if codec :
78- # allocate and initialise decoder
81+ # allocate and initialize decoder
7982 codec_context = lib .avcodec_alloc_context3 (codec )
80- err_check(lib.avcodec_parameters_to_context(codec_context, stream.codecpar))
83+ err_check (
84+ lib .avcodec_parameters_to_context (codec_context , stream .codecpar )
85+ )
8186 codec_context .pkt_timebase = stream .time_base
82- py_codec_context = wrap_codec_context(codec_context, codec, self .hwaccel)
87+ py_codec_context = wrap_codec_context (
88+ codec_context , codec , self .hwaccel
89+ )
8390 if py_codec_context .is_hwaccel :
8491 at_least_one_accelerated_context = True
8592 else :
8693 # no decoder is available
8794 py_codec_context = None
8895 self .streams .add_stream (wrap_stream (self , stream , py_codec_context ))
8996
90- if self .hwaccel and not self .hwaccel.allow_software_fallback and not at_least_one_accelerated_context:
91- raise RuntimeError (" Hardware accelerated decode requested but no stream is compatible" )
97+ if (
98+ self .hwaccel
99+ and not self .hwaccel .allow_software_fallback
100+ and not at_least_one_accelerated_context
101+ ):
102+ raise RuntimeError (
103+ "Hardware accelerated decode requested but no stream is compatible"
104+ )
92105
93- self .metadata = avdict_to_dict(self .ptr.metadata, self .metadata_encoding, self .metadata_errors)
106+ self .metadata = avdict_to_dict (
107+ self .ptr .metadata , self .metadata_encoding , self .metadata_errors
108+ )
94109
95110 def __dealloc__ (self ):
96111 close_input (self )
@@ -141,19 +156,20 @@ def demux(self, *args, **kwargs):
141156 # For whatever reason, Cython does not like us directly passing kwargs
142157 # from one method to another. Without kwargs, it ends up passing a
143158 # 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).
159+ # This is a bug in Cython; see https://github.com/cython/cython/issues/2166
146160 id (kwargs )
147161
148162 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 :
163+ include_stream : cython .pointer [cython .bint ] = cython .cast (
164+ cython .pointer [cython .bint ],
165+ malloc (self .ptr .nb_streams * cython .sizeof (bint )),
166+ )
167+ if include_stream == cython .NULL :
152168 raise MemoryError ()
153169
154- cdef unsigned int i
155- cdef Packet packet
156- cdef int ret
170+ i : cython . uint
171+ packet : Packet
172+ ret : cython . int
157173
158174 self .set_timeout (self .read_timeout )
159175 try :
@@ -169,7 +185,7 @@ def demux(self, *args, **kwargs):
169185 packet = Packet ()
170186 try :
171187 self .start_timeout ()
172- with nogil:
188+ with cython . nogil :
173189 ret = lib .av_read_frame (self .ptr , packet .ptr )
174190 self .err_check (ret )
175191 except EOFError :
@@ -217,8 +233,14 @@ def decode(self, *args, **kwargs):
217233 yield frame
218234
219235 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
236+ self ,
237+ offset ,
238+ * ,
239+ backward : bint = True ,
240+ any_frame : bint = False ,
241+ stream : Stream | None = None ,
242+ unsupported_frame_offset : bint = False ,
243+ unsupported_byte_offset : bint = False ,
222244 ):
223245 """seek(offset, *, backward=True, any_frame=False, stream=None)
224246
@@ -249,16 +271,12 @@ def seek(
249271 """
250272 self ._assert_open ()
251273
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.
255274 if not isinstance (offset , int ):
256275 raise TypeError ("Container.seek only accepts integer offset." , type (offset ))
257276
258- cdef int64_t c_offset = offset
259-
260- cdef int flags = 0
261- cdef int ret
277+ c_offset : int64_t = offset
278+ flags : cython .int = 0
279+ ret : cython .int
262280
263281 if backward :
264282 flags |= lib .AVSEEK_FLAG_BACKWARD
@@ -271,18 +289,19 @@ def seek(
271289 if unsupported_byte_offset :
272290 flags |= lib .AVSEEK_FLAG_BYTE
273291
274- cdef int stream_index = stream.index if stream else - 1
275- with nogil:
292+ stream_index : cython . int = stream .index if stream else - 1
293+ with cython . nogil :
276294 ret = lib .av_seek_frame (self .ptr , stream_index , c_offset , flags )
277295 err_check (ret )
278296
279297 self .flush_buffers ()
280298
281- cdef flush_buffers(self ):
299+ @cython .cfunc
300+ def flush_buffers (self ):
282301 self ._assert_open ()
283302
284- cdef Stream stream
285- cdef CodecContext codec_context
303+ stream : Stream
304+ codec_context : CodecContext
286305
287306 for stream in self .streams :
288307 codec_context = stream .codec_context
0 commit comments