@@ -153,6 +153,7 @@ def demux(self, *args, **kwargs):
153153
154154 i : cython .uint
155155 packet : Packet
156+ read_packet : Packet
156157 ret : cython .int
157158
158159 self .set_timeout (self .read_timeout )
@@ -165,22 +166,31 @@ def demux(self, *args, **kwargs):
165166 raise ValueError (f"stream index { i } out of range" )
166167 include_stream [i ] = True
167168
169+ # Pre-allocate a AVPacket that is reused as the read buffer.
170+ read_packet = Packet ()
168171 while True :
169- packet = Packet ()
172+ # Reset the read buffer
173+ with cython .nogil :
174+ lib .av_packet_unref (read_packet .ptr )
170175 try :
171176 self .start_timeout ()
172177 with cython .nogil :
173- ret = lib .av_read_frame (self .ptr , packet .ptr )
178+ ret = lib .av_read_frame (self .ptr , read_packet .ptr )
174179 self .err_check (ret )
175180 except EOFError :
176181 break
177182
178- if include_stream [packet .ptr .stream_index ]:
183+ if include_stream [read_packet .ptr .stream_index ]:
179184 # If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams
180185 # may also appear in av_read_frame().
181186 # http://ffmpeg.org/doxygen/trunk/structAVFormatContext.html
182187 # TODO: find better way to handle this
183- if packet .ptr .stream_index < len (self .streams ):
188+ if read_packet .ptr .stream_index < len (self .streams ):
189+ # Move the encoded data out of the read buffer into a
190+ # fresh Packet for the caller.
191+ packet = Packet ()
192+ with cython .nogil :
193+ lib .av_packet_move_ref (packet .ptr , read_packet .ptr )
184194 packet ._stream = self .streams [packet .ptr .stream_index ]
185195 # Keep track of this so that remuxing is easier.
186196 packet .ptr .time_base = packet ._stream .ptr .time_base
0 commit comments