Skip to content

Reuse a AVPacket read buffer when demuxing#2234

Merged
WyattBlue merged 2 commits intoPyAV-Org:mainfrom
lgeiger:reuse-read-packet
Apr 17, 2026
Merged

Reuse a AVPacket read buffer when demuxing#2234
WyattBlue merged 2 commits intoPyAV-Org:mainfrom
lgeiger:reuse-read-packet

Conversation

@lgeiger
Copy link
Copy Markdown
Contributor

@lgeiger lgeiger commented Apr 17, 2026

This allocates one Packet as a read buffer and reuses it in each iteration. This prevents the need to allocate and free a packet even if the stream is filtered out.

@WyattBlue
Copy link
Copy Markdown
Member

Why not use AVPacket directly

diff --git a/av/container/input.py b/av/container/input.py
index 699497d..6ccc44e 100644
--- a/av/container/input.py
+++ b/av/container/input.py
@@ -153,9 +153,8 @@ class InputContainer(Container):
 
         i: cython.uint
         packet: Packet
-        read_packet: Packet
+        read_packet: cython.pointer[lib.AVPacket]
         ret: cython.int
-
         self.set_timeout(self.read_timeout)
         try:
             for i in range(self.ptr.nb_streams):
@@ -167,30 +166,34 @@ class InputContainer(Container):
                 include_stream[i] = True
 
             # Pre-allocate a AVPacket that is reused as the read buffer.
-            read_packet = Packet()
+            with cython.nogil:
+                read_packet = lib.av_packet_alloc()
+            if read_packet == cython.NULL:
+                raise MemoryError()
+
             while True:
                 # Reset the read buffer
                 with cython.nogil:
-                    lib.av_packet_unref(read_packet.ptr)
+                    lib.av_packet_unref(read_packet)
                 try:
                     self.start_timeout()
                     with cython.nogil:
-                        ret = lib.av_read_frame(self.ptr, read_packet.ptr)
+                        ret = lib.av_read_frame(self.ptr, read_packet)
                     self.err_check(ret)
                 except EOFError:
                     break
 
-                if include_stream[read_packet.ptr.stream_index]:
+                if include_stream[read_packet.stream_index]:
                     # If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams
                     # may also appear in av_read_frame().
                     # http://ffmpeg.org/doxygen/trunk/structAVFormatContext.html
                     # TODO: find better way to handle this
-                    if read_packet.ptr.stream_index < len(self.streams):
+                    if read_packet.stream_index < len(self.streams):
                         # Move the encoded data out of the read buffer into a
                         # fresh Packet for the caller.
                         packet = Packet()
                         with cython.nogil:
-                            lib.av_packet_move_ref(packet.ptr, read_packet.ptr)
+                            lib.av_packet_move_ref(packet.ptr, read_packet)
                         packet._stream = self.streams[packet.ptr.stream_index]
                         # Keep track of this so that remuxing is easier.
                         packet.ptr.time_base = packet._stream.ptr.time_base
@@ -207,6 +210,8 @@ class InputContainer(Container):
         finally:
             self.set_timeout(None)
             free(include_stream)
+            if read_packet != cython.NULL:
+                lib.av_packet_free(cython.address(read_packet))
 
     def decode(self, *args, **kwargs):
         """decode(streams=None, video=None, audio=None, subtitles=None, data=None)

@lgeiger
Copy link
Copy Markdown
Contributor Author

lgeiger commented Apr 17, 2026

Good idea. Done in b20db65

Co-authored-by: WyattBlue <wyattblue@auto-editor.com>
@lgeiger lgeiger force-pushed the reuse-read-packet branch from b17f940 to b20db65 Compare April 17, 2026 01:58
@WyattBlue WyattBlue merged commit b82546f into PyAV-Org:main Apr 17, 2026
7 checks passed
@lgeiger lgeiger deleted the reuse-read-packet branch April 17, 2026 02:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants