1- from av.error cimport err_check
2- from av.opaque cimport opaque_container
3- from av.utils cimport avrational_to_fraction, to_avrational
1+ import cython
2+ from cython .cimports .av .error import err_check
3+ from cython .cimports .av .opaque import opaque_container
4+ from cython .cimports .av .utils import avrational_to_fraction , to_avrational
45
56from av .sidedata .sidedata import SideDataContainer
67
78
8- cdef class Frame:
9+ @cython .cclass
10+ class Frame :
911 """
1012 Base class for audio and video frames.
1113
1214 See also :class:`~av.audio.frame.AudioFrame` and :class:`~av.video.frame.VideoFrame`.
1315 """
1416
1517 def __cinit__ (self , * args , ** kwargs ):
16- with nogil:
18+ with cython . nogil :
1719 self .ptr = lib .av_frame_alloc ()
1820
1921 def __dealloc__ (self ):
20- with nogil:
21- # This calls av_frame_unref, and then frees the pointer.
22- # Thats it.
23- lib.av_frame_free(& self .ptr)
22+ with cython .nogil :
23+ lib .av_frame_free (cython .address (self .ptr ))
2424
2525 def __repr__ (self ):
26- return f" av.{self.__class__.__name__} pts={self.pts} at 0x{id(self):x}>"
26+ return f"< av.{ self .__class__ .__name__ } pts={ self .pts } at 0x{ id (self ):x} >"
2727
28- cdef _copy_internal_attributes(self , Frame source, bint data_layout = True ):
29- """ Mimic another frame."""
28+ @cython .cfunc
29+ def _copy_internal_attributes (self , source : Frame , data_layout : cython .bint = True ):
30+ # Mimic another frame
3031 self ._time_base = source ._time_base
3132 lib .av_frame_copy_props (self .ptr , source .ptr )
3233 if data_layout :
@@ -36,10 +37,12 @@ def __repr__(self):
3637 self .ptr .height = source .ptr .height
3738 self .ptr .ch_layout = source .ptr .ch_layout
3839
39- cdef _init_user_attributes(self ):
40+ @cython .cfunc
41+ def _init_user_attributes (self ):
4042 pass # Dummy to match the API of the others.
4143
42- cdef _rebase_time(self , lib.AVRational dst):
44+ @cython .cfunc
45+ def _rebase_time (self , dst : lib .AVRational ):
4346 if not dst .num :
4447 raise ValueError ("Cannot rebase to zero time." )
4548
@@ -54,7 +57,9 @@ def __repr__(self):
5457 self .ptr .pts = lib .av_rescale_q (self .ptr .pts , self ._time_base , dst )
5558
5659 if self .ptr .duration != 0 :
57- self .ptr.duration = lib.av_rescale_q(self .ptr.duration, self ._time_base, dst)
60+ self .ptr .duration = lib .av_rescale_q (
61+ self .ptr .duration , self ._time_base , dst
62+ )
5863
5964 self ._time_base = dst
6065
@@ -65,7 +70,7 @@ def dts(self):
6570
6671 (if frame threading isn't used) This is also the Presentation time of this frame calculated from only :attr:`.Packet.dts` values without pts values.
6772
68- :type: int
73+ :type: int | None
6974 """
7075 if self .ptr .pkt_dts == lib .AV_NOPTS_VALUE :
7176 return None
@@ -85,7 +90,7 @@ def pts(self):
8590
8691 This is the time at which the frame should be shown to the user.
8792
88- :type: int
93+ :type: int | None
8994 """
9095 if self .ptr .pts == lib .AV_NOPTS_VALUE :
9196 return None
@@ -105,16 +110,11 @@ def duration(self):
105110
106111 :type: int
107112 """
108- if self .ptr.duration == 0 :
109- return None
110113 return self .ptr .duration
111114
112115 @duration .setter
113116 def duration (self , value ):
114- if value is None :
115- self .ptr.duration = 0
116- else :
117- self .ptr.duration = value
117+ self .ptr .duration = value
118118
119119 @property
120120 def time (self ):
@@ -123,26 +123,25 @@ def time(self):
123123
124124 This is the time at which the frame should be shown to the user.
125125
126- :type: float
126+ :type: float | None
127127 """
128128 if self .ptr .pts == lib .AV_NOPTS_VALUE :
129129 return None
130- else :
131- return float (self .ptr.pts) * self ._time_base.num / self ._time_base.den
130+ return float (self .ptr .pts ) * self ._time_base .num / self ._time_base .den
132131
133132 @property
134133 def time_base (self ):
135134 """
136135 The unit of time (in fractional seconds) in which timestamps are expressed.
137136
138- :type: fractions.Fraction
137+ :type: fractions.Fraction | None
139138 """
140139 if self ._time_base .num :
141- return avrational_to_fraction(& self ._time_base)
140+ return avrational_to_fraction (cython . address ( self ._time_base ) )
142141
143142 @time_base .setter
144143 def time_base (self , value ):
145- to_avrational(value, & self ._time_base)
144+ to_avrational (value , cython . address ( self ._time_base ) )
146145
147146 @property
148147 def is_corrupt (self ):
@@ -151,7 +150,9 @@ def is_corrupt(self):
151150
152151 :type: bool
153152 """
154- return self .ptr.decode_error_flags != 0 or bool (self .ptr.flags & lib.AV_FRAME_FLAG_CORRUPT)
153+ return self .ptr .decode_error_flags != 0 or bool (
154+ self .ptr .flags & lib .AV_FRAME_FLAG_CORRUPT
155+ )
155156
156157 @property
157158 def key_frame (self ):
@@ -162,6 +163,13 @@ def key_frame(self):
162163 """
163164 return bool (self .ptr .flags & lib .AV_FRAME_FLAG_KEY )
164165
166+ @key_frame .setter
167+ def key_frame (self , v ):
168+ # PyAV makes no guarantees this does anything.
169+ if v :
170+ self .ptr .flags |= lib .AV_FRAME_FLAG_KEY
171+ else :
172+ self .ptr .flags &= ~ lib .AV_FRAME_FLAG_KEY
165173
166174 @property
167175 def side_data (self ):
@@ -174,20 +182,19 @@ def make_writable(self):
174182 Ensures that the frame data is writable. Copy the data to new buffer if it is not.
175183 This is a wrapper around :ffmpeg:`av_frame_make_writable`.
176184 """
177- cdef int ret
178-
179- ret = lib.av_frame_make_writable(self .ptr)
185+ ret : cython .int = lib .av_frame_make_writable (self .ptr )
180186 err_check (ret )
181187
182188 @property
183189 def opaque (self ):
184- if self .ptr.opaque_ref is not NULL :
185- return opaque_container.get(< char * > self .ptr.opaque_ref.data)
190+ if self .ptr .opaque_ref is not cython .NULL :
191+ return opaque_container .get (
192+ cython .cast (cython .p_char , self .ptr .opaque_ref .data )
193+ )
186194
187195 @opaque .setter
188196 def opaque (self , v ):
189- lib.av_buffer_unref(& self .ptr.opaque_ref)
197+ lib .av_buffer_unref (cython . address ( self .ptr .opaque_ref ) )
190198
191- if v is None :
192- return
193- self .ptr.opaque_ref = opaque_container.add(v)
199+ if v is not None :
200+ self .ptr .opaque_ref = opaque_container .add (v )
0 commit comments