diff --git a/av/codec/context.pyx b/av/codec/context.pyx
index d93fb64f578c8af1625da8d353193a154828a1d8..ec27d02ed05812b528ead2d079747e544885d2e1 100644
--- a/av/codec/context.pyx
+++ b/av/codec/context.pyx
@@ -376,7 +376,7 @@ cdef class CodecContext(object):
                 # ... but this results in corruption.
 
                 packet = Packet(out_size)
-                memcpy(packet.struct.data, out_data, out_size)
+                memcpy(packet.ptr.data, out_data, out_size)
 
                 packets.append(packet)
 
@@ -417,7 +417,7 @@ cdef class CodecContext(object):
 
         cdef int res
         with nogil:
-            res = lib.avcodec_send_packet(self.ptr, &packet.struct if packet is not None else NULL)
+            res = lib.avcodec_send_packet(self.ptr, packet.ptr if packet is not None else NULL)
         err_check(res)
 
         out = []
@@ -459,7 +459,7 @@ cdef class CodecContext(object):
 
         cdef int res
         with nogil:
-            res = lib.avcodec_receive_packet(self.ptr, &packet.struct)
+            res = lib.avcodec_receive_packet(self.ptr, packet.ptr)
         if res == -EAGAIN or res == lib.AVERROR_EOF:
             return
         err_check(res)
diff --git a/av/container/input.pyx b/av/container/input.pyx
index 64612d84e9e40902f5909ff52ce17c015bc4ca0d..4b3a5ea5ec0af2f67f1bcefa550e62729edd72d3 100644
--- a/av/container/input.pyx
+++ b/av/container/input.pyx
@@ -138,18 +138,18 @@ cdef class InputContainer(Container):
                 try:
                     self.start_timeout()
                     with nogil:
-                        ret = lib.av_read_frame(self.ptr, &packet.struct)
+                        ret = lib.av_read_frame(self.ptr, packet.ptr)
                     self.err_check(ret)
                 except EOFError:
                     break
 
-                if include_stream[packet.struct.stream_index]:
+                if include_stream[packet.ptr.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 packet.struct.stream_index < len(self.streams):
-                        packet._stream = self.streams[packet.struct.stream_index]
+                    if packet.ptr.stream_index < len(self.streams):
+                        packet._stream = self.streams[packet.ptr.stream_index]
                         # Keep track of this so that remuxing is easier.
                         packet._time_base = packet._stream._stream.time_base
                         yield packet
diff --git a/av/container/output.pyx b/av/container/output.pyx
index 9569c3e9d4c2589b1611931d0b9b27d226375d60..c1a47b5bfbaab3413209ec1b7d51596a4c407d84 100644
--- a/av/container/output.pyx
+++ b/av/container/output.pyx
@@ -210,18 +210,17 @@ cdef class OutputContainer(Container):
         self.start_encoding()
 
         # Assert the packet is in stream time.
-        if packet.struct.stream_index < 0 or <unsigned int>packet.struct.stream_index >= self.ptr.nb_streams:
+        if packet.ptr.stream_index < 0 or <unsigned int>packet.ptr.stream_index >= self.ptr.nb_streams:
             raise ValueError('Bad Packet stream_index.')
-        cdef lib.AVStream *stream = self.ptr.streams[packet.struct.stream_index]
+        cdef lib.AVStream *stream = self.ptr.streams[packet.ptr.stream_index]
         packet._rebase_time(stream.time_base)
 
         # Make another reference to the packet, as av_interleaved_write_frame
         # takes ownership of it.
-        cdef lib.AVPacket packet_ref
-        lib.av_init_packet(&packet_ref)
-        self.err_check(lib.av_packet_ref(&packet_ref, &packet.struct))
+        cdef lib.AVPacket *packet_ptr = lib.av_packet_alloc()
+        self.err_check(lib.av_packet_ref(packet_ptr, packet.ptr))
 
         cdef int ret
         with nogil:
-            ret = lib.av_interleaved_write_frame(self.ptr, &packet_ref)
+            ret = lib.av_interleaved_write_frame(self.ptr, packet_ptr)
         self.err_check(ret)
diff --git a/av/packet.pxd b/av/packet.pxd
index 317443fde8b53794ad4072207a214700a9bef815..ca21e6b76dcf50c86e9c4a79a4ddf4e64410e04d 100644
--- a/av/packet.pxd
+++ b/av/packet.pxd
@@ -7,7 +7,7 @@ from av.stream cimport Stream
 
 cdef class Packet(Buffer):
 
-    cdef lib.AVPacket struct
+    cdef lib.AVPacket* ptr
 
     cdef Stream _stream
 
diff --git a/av/packet.pyx b/av/packet.pyx
index 2ffbcca62e5e4fb79ae77833737aaf04a70847e0..fae970ee3f6385c88f7bb2004b674393b887a7e3 100644
--- a/av/packet.pyx
+++ b/av/packet.pyx
@@ -18,7 +18,7 @@ cdef class Packet(Buffer):
 
     def __cinit__(self, input=None):
         with nogil:
-            lib.av_init_packet(&self.struct)
+            self.ptr = lib.av_packet_alloc()
 
     def __init__(self, input=None):
 
@@ -35,7 +35,7 @@ cdef class Packet(Buffer):
             size = source.length
 
         if size:
-            err_check(lib.av_new_packet(&self.struct, size))
+            err_check(lib.av_new_packet(self.ptr, size))
 
         if source is not None:
             self.update(source)
@@ -45,7 +45,7 @@ cdef class Packet(Buffer):
 
     def __dealloc__(self):
         with nogil:
-            lib.av_packet_unref(&self.struct)
+            lib.av_packet_free(&self.ptr)
 
     def __repr__(self):
         return '<av.%s of #%d, dts=%s, pts=%s; %s bytes at 0x%x>' % (
@@ -53,15 +53,15 @@ cdef class Packet(Buffer):
             self._stream.index if self._stream else 0,
             self.dts,
             self.pts,
-            self.struct.size,
+            self.ptr.size,
             id(self),
         )
 
     # Buffer protocol.
     cdef size_t _buffer_size(self):
-        return self.struct.size
+        return self.ptr.size
     cdef void* _buffer_ptr(self):
-        return self.struct.data
+        return self.ptr.data
 
     cdef _rebase_time(self, lib.AVRational dst):
 
@@ -75,7 +75,7 @@ cdef class Packet(Buffer):
         if self._time_base.num == dst.num and self._time_base.den == dst.den:
             return
 
-        lib.av_packet_rescale_ts(&self.struct, self._time_base, dst)
+        lib.av_packet_rescale_ts(self.ptr, self._time_base, dst)
 
         self._time_base = dst
 
@@ -101,7 +101,7 @@ cdef class Packet(Buffer):
 
     property stream_index:
         def __get__(self):
-            return self.struct.stream_index
+            return self.ptr.stream_index
 
     property stream:
         """
@@ -112,7 +112,7 @@ cdef class Packet(Buffer):
 
         def __set__(self, Stream stream):
             self._stream = stream
-            self.struct.stream_index = stream._stream.index
+            self.ptr.stream_index = stream._stream.index
 
     property time_base:
         """
@@ -135,14 +135,14 @@ cdef class Packet(Buffer):
         :type: int
         """
         def __get__(self):
-            if self.struct.pts != lib.AV_NOPTS_VALUE:
-                return self.struct.pts
+            if self.ptr.pts != lib.AV_NOPTS_VALUE:
+                return self.ptr.pts
 
         def __set__(self, v):
             if v is None:
-                self.struct.pts = lib.AV_NOPTS_VALUE
+                self.ptr.pts = lib.AV_NOPTS_VALUE
             else:
-                self.struct.pts = v
+                self.ptr.pts = v
 
     property dts:
         """
@@ -151,14 +151,14 @@ cdef class Packet(Buffer):
         :type: int
         """
         def __get__(self):
-            if self.struct.dts != lib.AV_NOPTS_VALUE:
-                return self.struct.dts
+            if self.ptr.dts != lib.AV_NOPTS_VALUE:
+                return self.ptr.dts
 
         def __set__(self, v):
             if v is None:
-                self.struct.dts = lib.AV_NOPTS_VALUE
+                self.ptr.dts = lib.AV_NOPTS_VALUE
             else:
-                self.struct.dts = v
+                self.ptr.dts = v
 
     property pos:
         """
@@ -169,8 +169,8 @@ cdef class Packet(Buffer):
         :type: int
         """
         def __get__(self):
-            if self.struct.pos != -1:
-                return self.struct.pos
+            if self.ptr.pos != -1:
+                return self.ptr.pos
 
     property size:
         """
@@ -179,7 +179,7 @@ cdef class Packet(Buffer):
         :type: int
         """
         def __get__(self):
-            return self.struct.size
+            return self.ptr.size
 
     property duration:
         """
@@ -190,11 +190,11 @@ cdef class Packet(Buffer):
         :type: int
         """
         def __get__(self):
-            if self.struct.duration != lib.AV_NOPTS_VALUE:
-                return self.struct.duration
+            if self.ptr.duration != lib.AV_NOPTS_VALUE:
+                return self.ptr.duration
 
     property is_keyframe:
-        def __get__(self): return bool(self.struct.flags & lib.AV_PKT_FLAG_KEY)
+        def __get__(self): return bool(self.ptr.flags & lib.AV_PKT_FLAG_KEY)
 
     property is_corrupt:
-        def __get__(self): return bool(self.struct.flags & lib.AV_PKT_FLAG_CORRUPT)
+        def __get__(self): return bool(self.ptr.flags & lib.AV_PKT_FLAG_CORRUPT)
diff --git a/av/stream.pyx b/av/stream.pyx
index f24912d5f496134c9c3ac6a85244195f85bde003..c20c92a3491bce584c12bfad00d6f0111e693381 100644
--- a/av/stream.pyx
+++ b/av/stream.pyx
@@ -156,7 +156,7 @@ cdef class Stream(object):
         cdef Packet packet
         for packet in packets:
             packet._stream = self
-            packet.struct.stream_index = self._stream.index
+            packet.ptr.stream_index = self._stream.index
         return packets
 
     def decode(self, packet=None):
diff --git a/av/subtitles/codeccontext.pyx b/av/subtitles/codeccontext.pyx
index c4d83a2568a0bbd21a31c14c8c1ef14149f7b1ff..a120fc3a5882ed83cab6474c0fbd9bc6f6051cbb 100644
--- a/av/subtitles/codeccontext.pyx
+++ b/av/subtitles/codeccontext.pyx
@@ -16,7 +16,7 @@ cdef class SubtitleCodecContext(CodecContext):
             self.ptr,
             &proxy.struct,
             &got_frame,
-            &packet.struct if packet else NULL))
+            packet.ptr if packet else NULL))
         if got_frame:
             return [SubtitleSet(proxy)]
         else:
diff --git a/include/libavcodec/avcodec.pxd b/include/libavcodec/avcodec.pxd
index 7e921e8475cac7c816c03ed5e580aacb4d261713..8e5752ae565fc6a0d11a126ff8ddeaa9cbe4c597 100644
--- a/include/libavcodec/avcodec.pxd
+++ b/include/libavcodec/avcodec.pxd
@@ -338,8 +338,6 @@ cdef extern from "libavcodec/avcodec.h" nogil:
 
         int64_t pos
 
-        void (*destruct)(AVPacket*)
-
 
     cdef int avcodec_fill_audio_frame(
         AVFrame *frame,
@@ -352,10 +350,10 @@ cdef extern from "libavcodec/avcodec.h" nogil:
 
     cdef void avcodec_free_frame(AVFrame **frame)
 
-    cdef void av_init_packet(AVPacket*)
+    cdef AVPacket* av_packet_alloc()
+    cdef void av_packet_free(AVPacket **)
     cdef int av_new_packet(AVPacket*, int)
     cdef int av_packet_ref(AVPacket *dst, const AVPacket *src)
-    cdef void av_packet_unref(AVPacket *pkt)
     cdef void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb)
 
     cdef enum AVSubtitleType: