diff mbox series

[FFmpeg-devel,03/10] avformat/utils: use av_packet_alloc() to allocate packets

Message ID 20210201224421.1395-4-jamrial@gmail.com
State New
Headers show
Series deprecate av_init_packet() and sizeof(AVPacket) as part of the ABI | expand

Checks

Context Check Description
andriy/x86_make_warn warning New warnings during build
andriy/x86_make success Make finished
andriy/x86_make_fate fail Make fate failed
andriy/PPC64_make success Make finished

Commit Message

James Almer Feb. 1, 2021, 10:44 p.m. UTC
Signed-off-by: James Almer <jamrial@gmail.com>
---
av_get_packet() and av_read_frame() were allowed to be called with
uninitialized packets in stack, so to keep supporting that we need to leave the
calls to av_init_packet() in place during the deprecation period.

 libavformat/internal.h |   1 +
 libavformat/options.c  |  13 +++--
 libavformat/utils.c    | 105 +++++++++++++++++++++++------------------
 3 files changed, 68 insertions(+), 51 deletions(-)

Comments

Michael Niedermayer Feb. 3, 2021, 10:23 p.m. UTC | #1
On Mon, Feb 01, 2021 at 07:44:14PM -0300, James Almer wrote:
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> av_get_packet() and av_read_frame() were allowed to be called with
> uninitialized packets in stack, so to keep supporting that we need to leave the
> calls to av_init_packet() in place during the deprecation period.
> 
>  libavformat/internal.h |   1 +
>  libavformat/options.c  |  13 +++--
>  libavformat/utils.c    | 105 +++++++++++++++++++++++------------------
>  3 files changed, 68 insertions(+), 51 deletions(-)

valgrind dislikes this

will send you the file by private mail

[avi @ 0x169f9280] Something went wrong during header parsing, tag [0][0][0][0] has size 2147483648, I will ignore it and try to continue anyway.
[avi @ 0x169f9280] non-interleaved AVI
[avi @ 0x169f9280] nothing to probe for stream 2
[avi @ 0x169f9280] probed stream 2 failed
[avi @ 0x169f9280] probed stream 6 failed
[avi @ 0x169f9280] nothing to probe for stream 7
[avi @ 0x169f9280] probed stream 7 failed
[avi @ 0x169f9280] nothing to probe for stream 8
[avi @ 0x169f9280] probed stream 8 failed
[avi @ 0x169f9280] nothing to probe for stream 9
[avi @ 0x169f9280] probed stream 9 failed
[avi @ 0x169f9280] Could not find codec parameters for stream 0 (Video: mpeg4 (XVID / 0x44495658), none, 640x480): unspecified pixel format
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
[avi @ 0x169f9280] Could not find codec parameters for stream 2 (Subtitle: none): unknown codec
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
[avi @ 0x169f9280] Could not find codec parameters for stream 4 (Unknown: none): unknown codec
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
[avi @ 0x169f9280] Could not find codec parameters for stream 6 (Subtitle: none): unknown codec
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
[avi @ 0x169f9280] Could not find codec parameters for stream 7 (Subtitle: none): unknown codec
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
[avi @ 0x169f9280] Could not find codec parameters for stream 8 (Subtitle: none): unknown codec
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
[avi @ 0x169f9280] Could not find codec parameters for stream 9 (Subtitle: none): unknown codec
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
Input #0, avi, from 'mewmew_ssa.avi.asan.1c.3781':
  Duration: 00:00:58.22, start: 0.000000, bitrate: 1087 kb/s
  Stream #0:0: Video: mpeg4 (XVID / 0x44495658), none, 640x480, 23.98 fps, 23.98 tbr, 23.98 tbn, 23.98 tbc
  Stream #0:1: Audio: mp2 (P[0][0][0] / 0x0050), 48000 Hz, stereo, s16p, 64 kb/s
    Metadata:
      title           : test
  Stream #0:2: Subtitle: none
    Metadata:
      title           : Credits
  Stream #0:3: Subtitle: ass
  Stream #0:4: Unknown: none
    Metadata:
      title           : English
  Stream #0:5: Subtitle: ass
    Metadata:
      title           : Finnish
  Stream #0:6: Subtitle: none
    Metadata:
      title           : French
  Stream #0:7: Subtitle: none
    Metadata:
      title           : Hebrew
  Stream #0:8: Subtitle: none
    Metadata:
      title           : Hungarian
  Stream #0:9: Subtitle: none
    Metadata:
      title           : Italian
At least one output file must be specified
==12602==    at 0x121EC6E: VALGRIND_PRINTF_BACKTRACE (valgrind.h:6303)
==12602==    by 0x121F82C: av_log_default_callback (log.c:397)
==12602==    by 0x121FAD3: av_vlog (log.c:432)
==12602==    by 0x121F932: av_log (log.c:411)
==12602==    by 0x25B892: main (ffmpeg.c:4971)
==12602== Invalid read of size 8
==12602==    at 0x1208302: buffer_replace (buffer.c:111)
==12602==    by 0x12083D7: av_buffer_unref (buffer.c:130)
==12602==    by 0x794E97: av_packet_unref (avpacket.c:609)
==12602==    by 0x795651: avpriv_packet_list_free (avpacket.c:789)
==12602==    by 0x7026A2: flush_packet_queue (utils.c:1833)
==12602==    by 0x70C29B: avformat_close_input (utils.c:4484)
==12602==    by 0x24A207: ffmpeg_cleanup (ffmpeg.c:626)
==12602==    by 0x241A25: exit_program (cmdutils.c:136)
==12602==    by 0x25B89C: main (ffmpeg.c:4972)
==12602==  Address 0x16a46dc0 is 0 bytes inside a block of size 24 free'd
==12602==    at 0x4C32D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12602==    by 0x122297A: av_free (mem.c:224)
==12602==    by 0x12229C2: av_freep (mem.c:234)
==12602==    by 0x120834D: buffer_replace (buffer.c:117)
==12602==    by 0x12083D7: av_buffer_unref (buffer.c:130)
==12602==    by 0x794E97: av_packet_unref (avpacket.c:609)
==12602==    by 0x6FDF58: ff_read_packet (utils.c:808)
==12602==    by 0x569798: get_subtitle_pkt (avidec.c:1183)
==12602==    by 0x56A3E4: avi_read_packet (avidec.c:1452)
==12602==    by 0x6FE05A: ff_read_packet (utils.c:827)
==12602==    by 0x7011F0: read_frame_internal (utils.c:1529)
==12602==    by 0x709592: avformat_find_stream_info (utils.c:3794)
==12602==    by 0x22D4C9: open_input_file (ffmpeg_opt.c:1195)
==12602==    by 0x23BC31: open_files (ffmpeg_opt.c:3318)
==12602==    by 0x23BDE5: ffmpeg_parse_options (ffmpeg_opt.c:3358)
==12602==    by 0x25B809: main (ffmpeg.c:4959)
==12602==  Block was alloc'd at
==12602==    at 0x4C33E76: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12602==    by 0x4C33F91: posix_memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12602==    by 0x12225DC: av_malloc (mem.c:86)
==12602==    by 0x12229F1: av_mallocz (mem.c:239)
==12602==    by 0x1208296: av_buffer_ref (buffer.c:95)
==12602==    by 0x794FCD: av_packet_ref (avpacket.c:635)
==12602==    by 0x6E643B: ff_subtitles_queue_read_packet (subtitles.c:219)
==12602==    by 0x561D48: ass_read_packet (assdec.c:174)
==12602==    by 0x6FE05A: ff_read_packet (utils.c:827)
==12602==    by 0x569474: read_gab2_sub (avidec.c:1138)
==12602==    by 0x56A619: avi_read_packet (avidec.c:1495)
==12602==    by 0x6FE05A: ff_read_packet (utils.c:827)
==12602==    by 0x7011F0: read_frame_internal (utils.c:1529)
==12602==    by 0x709592: avformat_find_stream_info (utils.c:3794)
==12602==    by 0x22D4C9: open_input_file (ffmpeg_opt.c:1195)
==12602==    by 0x23BC31: open_files (ffmpeg_opt.c:3318)
==12602==    by 0x23BDE5: ffmpeg_parse_options (ffmpeg_opt.c:3358)
==12602==    by 0x25B809: main (ffmpeg.c:4959)
==12602== 
==12602== Invalid free() / delete / delete[] / realloc()
==12602==    at 0x4C32D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12602==    by 0x122297A: av_free (mem.c:224)
==12602==    by 0x12229C2: av_freep (mem.c:234)
==12602==    by 0x120834D: buffer_replace (buffer.c:117)
==12602==    by 0x12083D7: av_buffer_unref (buffer.c:130)
==12602==    by 0x794E97: av_packet_unref (avpacket.c:609)
==12602==    by 0x795651: avpriv_packet_list_free (avpacket.c:789)
==12602==    by 0x7026A2: flush_packet_queue (utils.c:1833)
==12602==    by 0x70C29B: avformat_close_input (utils.c:4484)
==12602==    by 0x24A207: ffmpeg_cleanup (ffmpeg.c:626)
==12602==    by 0x241A25: exit_program (cmdutils.c:136)
==12602==    by 0x25B89C: main (ffmpeg.c:4972)
==12602==  Address 0x16a46dc0 is 0 bytes inside a block of size 24 free'd
==12602==    at 0x4C32D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12602==    by 0x122297A: av_free (mem.c:224)
==12602==    by 0x12229C2: av_freep (mem.c:234)
==12602==    by 0x120834D: buffer_replace (buffer.c:117)
==12602==    by 0x12083D7: av_buffer_unref (buffer.c:130)
==12602==    by 0x794E97: av_packet_unref (avpacket.c:609)
==12602==    by 0x6FDF58: ff_read_packet (utils.c:808)
==12602==    by 0x569798: get_subtitle_pkt (avidec.c:1183)
==12602==    by 0x56A3E4: avi_read_packet (avidec.c:1452)
==12602==    by 0x6FE05A: ff_read_packet (utils.c:827)
==12602==    by 0x7011F0: read_frame_internal (utils.c:1529)
==12602==    by 0x709592: avformat_find_stream_info (utils.c:3794)
==12602==    by 0x22D4C9: open_input_file (ffmpeg_opt.c:1195)
==12602==    by 0x23BC31: open_files (ffmpeg_opt.c:3318)
==12602==    by 0x23BDE5: ffmpeg_parse_options (ffmpeg_opt.c:3358)
==12602==    by 0x25B809: main (ffmpeg.c:4959)
==12602==  Block was alloc'd at
==12602==    at 0x4C33E76: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12602==    by 0x4C33F91: posix_memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12602==    by 0x12225DC: av_malloc (mem.c:86)
==12602==    by 0x12229F1: av_mallocz (mem.c:239)
==12602==    by 0x1208296: av_buffer_ref (buffer.c:95)
==12602==    by 0x794FCD: av_packet_ref (avpacket.c:635)
==12602==    by 0x6E643B: ff_subtitles_queue_read_packet (subtitles.c:219)
==12602==    by 0x561D48: ass_read_packet (assdec.c:174)
==12602==    by 0x6FE05A: ff_read_packet (utils.c:827)
==12602==    by 0x569474: read_gab2_sub (avidec.c:1138)
==12602==    by 0x56A619: avi_read_packet (avidec.c:1495)
==12602==    by 0x6FE05A: ff_read_packet (utils.c:827)
==12602==    by 0x7011F0: read_frame_internal (utils.c:1529)
==12602==    by 0x709592: avformat_find_stream_info (utils.c:3794)
==12602==    by 0x22D4C9: open_input_file (ffmpeg_opt.c:1195)
==12602==    by 0x23BC31: open_files (ffmpeg_opt.c:3318)
==12602==    by 0x23BDE5: ffmpeg_parse_options (ffmpeg_opt.c:3358)
==12602==    by 0x25B809: main (ffmpeg.c:4959)



[...]
James Almer Feb. 3, 2021, 10:25 p.m. UTC | #2
On 2/3/2021 7:23 PM, Michael Niedermayer wrote:
> On Mon, Feb 01, 2021 at 07:44:14PM -0300, James Almer wrote:
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>> av_get_packet() and av_read_frame() were allowed to be called with
>> uninitialized packets in stack, so to keep supporting that we need to leave the
>> calls to av_init_packet() in place during the deprecation period.
>>
>>   libavformat/internal.h |   1 +
>>   libavformat/options.c  |  13 +++--
>>   libavformat/utils.c    | 105 +++++++++++++++++++++++------------------
>>   3 files changed, 68 insertions(+), 51 deletions(-)
> 
> valgrind dislikes this

Did you apply patch 10/10 first, like i mentioned in another reply?
I mistakenly sent that patch, which introduces an FF_API define, before 
the patches that make use of it (This one being the first doing so).
Michael Niedermayer Feb. 3, 2021, 10:36 p.m. UTC | #3
On Wed, Feb 03, 2021 at 07:25:29PM -0300, James Almer wrote:
> On 2/3/2021 7:23 PM, Michael Niedermayer wrote:
> > On Mon, Feb 01, 2021 at 07:44:14PM -0300, James Almer wrote:
> > > Signed-off-by: James Almer <jamrial@gmail.com>
> > > ---
> > > av_get_packet() and av_read_frame() were allowed to be called with
> > > uninitialized packets in stack, so to keep supporting that we need to leave the
> > > calls to av_init_packet() in place during the deprecation period.
> > > 
> > >   libavformat/internal.h |   1 +
> > >   libavformat/options.c  |  13 +++--
> > >   libavformat/utils.c    | 105 +++++++++++++++++++++++------------------
> > >   3 files changed, 68 insertions(+), 51 deletions(-)
> > 
> > valgrind dislikes this
> 
> Did you apply patch 10/10 first, like i mentioned in another reply?
> I mistakenly sent that patch, which introduces an FF_API define, before the
> patches that make use of it (This one being the first doing so).

I probably applied them in order yesterday on their numbers and testing today
if that was wrong ill test again next time this is posted i guess
iam a little behind today with things i wanted to do

thx

[...]
James Almer Feb. 3, 2021, 10:55 p.m. UTC | #4
On 2/3/2021 7:36 PM, Michael Niedermayer wrote:
> On Wed, Feb 03, 2021 at 07:25:29PM -0300, James Almer wrote:
>> On 2/3/2021 7:23 PM, Michael Niedermayer wrote:
>>> On Mon, Feb 01, 2021 at 07:44:14PM -0300, James Almer wrote:
>>>> Signed-off-by: James Almer <jamrial@gmail.com>
>>>> ---
>>>> av_get_packet() and av_read_frame() were allowed to be called with
>>>> uninitialized packets in stack, so to keep supporting that we need to leave the
>>>> calls to av_init_packet() in place during the deprecation period.
>>>>
>>>>    libavformat/internal.h |   1 +
>>>>    libavformat/options.c  |  13 +++--
>>>>    libavformat/utils.c    | 105 +++++++++++++++++++++++------------------
>>>>    3 files changed, 68 insertions(+), 51 deletions(-)
>>>
>>> valgrind dislikes this
>>
>> Did you apply patch 10/10 first, like i mentioned in another reply?
>> I mistakenly sent that patch, which introduces an FF_API define, before the
>> patches that make use of it (This one being the first doing so).
> 
> I probably applied them in order yesterday on their numbers and testing today
> if that was wrong ill test again next time this is posted i guess
> iam a little behind today with things i wanted to do

Just checked and i can reproduce it even with patch 10/10 present.
Turns out applying the avidec patch i already have written to make it 
use allocated AVPackets fixes it, which goes as follows:

> diff --git a/libavformat/avidec.c b/libavformat/avidec.c
> index 79000f3e81..0dd447aa7f 100644
> --- a/libavformat/avidec.c
> +++ b/libavformat/avidec.c
> @@ -59,7 +59,7 @@ typedef struct AVIStream {
>                               * the MS dshow demuxer */
> 
>      AVFormatContext *sub_ctx;
> -    AVPacket sub_pkt;
> +    AVPacket *sub_pkt;
>      AVBufferRef *sub_buffer;
> 
>      int64_t seek_pos;
> @@ -1124,6 +1124,9 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)
>          if (strcmp(sub_demuxer->name, "srt") && strcmp(sub_demuxer->name, "ass"))
>              goto error;
> 
> +        if (!(ast->sub_pkt = av_packet_alloc()))
> +            goto error;
> +
>          if (!(ast->sub_ctx = avformat_alloc_context()))
>              goto error;
> 
> @@ -1135,7 +1138,7 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)
>          if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
>              if (ast->sub_ctx->nb_streams != 1)
>                  goto error;
> -            ff_read_packet(ast->sub_ctx, &ast->sub_pkt);
> +            ff_read_packet(ast->sub_ctx, ast->sub_pkt);
>              avcodec_parameters_copy(st->codecpar, ast->sub_ctx->streams[0]->codecpar);
>              time_base = ast->sub_ctx->streams[0]->time_base;
>              avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
> @@ -1146,6 +1149,7 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)
>          return 1;
> 
>  error:
> +        av_packet_free(&ast->sub_pkt);
>          av_freep(&ast->sub_ctx);
>          avio_context_free(&pb);
>      }
> @@ -1166,8 +1170,8 @@ static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st,
>      for (i = 0; i < s->nb_streams; i++) {
>          st  = s->streams[i];
>          ast = st->priv_data;
> -        if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) {
> -            ts = av_rescale_q(ast->sub_pkt.dts, st->time_base, AV_TIME_BASE_Q);
> +        if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt && ast->sub_pkt->data) {
> +            ts = av_rescale_q(ast->sub_pkt->dts, st->time_base, AV_TIME_BASE_Q);
>              if (ts <= next_ts && ts < ts_min) {
>                  ts_min = ts;
>                  sub_st = st;
> @@ -1177,11 +1181,11 @@ static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st,
> 
>      if (sub_st) {
>          ast               = sub_st->priv_data;
> -        *pkt              = ast->sub_pkt;
> +        av_packet_move_ref(pkt, ast->sub_pkt);
>          pkt->stream_index = sub_st->index;
> 
> -        if (ff_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0)
> -            ast->sub_pkt.data = NULL;
> +        if (ff_read_packet(ast->sub_ctx, ast->sub_pkt) < 0)
> +            ast->sub_pkt->data = NULL;
>      }
>      return sub_st;
>  }
> @@ -1800,10 +1804,10 @@ static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp)
>  {
>      AVIStream *ast2 = st2->priv_data;
>      int64_t ts2     = av_rescale_q(timestamp, st->time_base, st2->time_base);
> -    av_packet_unref(&ast2->sub_pkt);
> +    av_packet_unref(ast2->sub_pkt);
>      if (avformat_seek_file(ast2->sub_ctx, 0, INT64_MIN, ts2, ts2, 0) >= 0 ||
>          avformat_seek_file(ast2->sub_ctx, 0, ts2, ts2, INT64_MAX, 0) >= 0)
> -        ff_read_packet(ast2->sub_ctx, &ast2->sub_pkt);
> +        ff_read_packet(ast2->sub_ctx, ast2->sub_pkt);
>  }
> 
>  static int avi_read_seek(AVFormatContext *s, int stream_index,
> @@ -1937,7 +1941,7 @@ static int avi_read_close(AVFormatContext *s)
>                  avformat_close_input(&ast->sub_ctx);
>              }
>              av_buffer_unref(&ast->sub_buffer);
> -            av_packet_unref(&ast->sub_pkt);
> +            av_packet_free(&ast->sub_pkt);
>          }
>      }

Not really happy to see there's such a dependency between generic code 
and a single module (I suspect one cause is the removal of 
av_init_packet() from ff_read_packet(), which requires callers to pass 
an already initialized packet), so I guess i should send all ~50 patches 
that completely get rid of av_init_packet() and all the stack usage i 
could find, instead of just this subset.

If the core deprecation change in patch 10/10 is ok'd, then I'll go 
ahead do it.
diff mbox series

Patch

diff --git a/libavformat/internal.h b/libavformat/internal.h
index 2fe1afa8e3..ff8b657343 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -90,6 +90,7 @@  struct AVFormatInternal {
     /**
      * Packets split by the parser get queued here.
      */
+    AVPacket *parse_pkt;
     struct AVPacketList *parse_queue;
     struct AVPacketList *parse_queue_end;
 
diff --git a/libavformat/options.c b/libavformat/options.c
index 2de2db8f09..07403b533e 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -220,14 +220,17 @@  AVFormatContext *avformat_alloc_context(void)
         av_free(ic);
         return NULL;
     }
-    avformat_get_context_defaults(ic);
-    ic->internal = internal;
-    ic->internal->pkt = av_packet_alloc();
-    if (!ic->internal->pkt) {
-        av_free(ic->internal);
+    internal->pkt = av_packet_alloc();
+    internal->parse_pkt = av_packet_alloc();
+    if (!internal->pkt || !internal->parse_pkt) {
+        av_packet_free(&internal->pkt);
+        av_packet_free(&internal->parse_pkt);
+        av_free(internal);
         av_free(ic);
         return NULL;
     }
+    avformat_get_context_defaults(ic);
+    ic->internal = internal;
     ic->internal->offset = AV_NOPTS_VALUE;
     ic->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
     ic->internal->shortest_end = AV_NOPTS_VALUE;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 2587bedc05..8cd5d0760f 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -309,9 +309,15 @@  static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size)
 
 int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
 {
+#if FF_API_INIT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
     av_init_packet(pkt);
     pkt->data = NULL;
     pkt->size = 0;
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+    av_packet_unref(pkt);
+#endif
     pkt->pos  = avio_tell(s);
 
     return append_packet_chunked(s, pkt, size);
@@ -799,9 +805,7 @@  int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
     int ret, i, err;
     AVStream *st;
 
-    pkt->data = NULL;
-    pkt->size = 0;
-    av_init_packet(pkt);
+    av_packet_unref(pkt);
 
     for (;;) {
         AVPacketList *pktl = s->internal->raw_packet_buffer;
@@ -1401,14 +1405,14 @@  FF_ENABLE_DEPRECATION_WARNINGS
 static int parse_packet(AVFormatContext *s, AVPacket *pkt,
                         int stream_index, int flush)
 {
-    AVPacket out_pkt;
+    AVPacket *out_pkt = s->internal->parse_pkt;
     AVStream *st = s->streams[stream_index];
     uint8_t *data = pkt->data;
     int size      = pkt->size;
     int ret = 0, got_output = flush;
 
     if (size || flush) {
-        av_init_packet(&out_pkt);
+        av_packet_unref(out_pkt);
     } else if (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) {
         // preserve 0-size sync packets
         compute_pkt_fields(s, st, st->parser, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
@@ -1420,7 +1424,7 @@  static int parse_packet(AVFormatContext *s, AVPacket *pkt,
         int64_t next_dts = pkt->dts;
 
         len = av_parser_parse2(st->parser, st->internal->avctx,
-                               &out_pkt.data, &out_pkt.size, data, size,
+                               &out_pkt->data, &out_pkt->size, data, size,
                                pkt->pts, pkt->dts, pkt->pos);
 
         pkt->pts = pkt->dts = AV_NOPTS_VALUE;
@@ -1429,39 +1433,39 @@  static int parse_packet(AVFormatContext *s, AVPacket *pkt,
         data += len;
         size -= len;
 
-        got_output = !!out_pkt.size;
+        got_output = !!out_pkt->size;
 
-        if (!out_pkt.size)
+        if (!out_pkt->size)
             continue;
 
-        if (pkt->buf && out_pkt.data == pkt->data) {
-            /* reference pkt->buf only when out_pkt.data is guaranteed to point
+        if (pkt->buf && out_pkt->data == pkt->data) {
+            /* reference pkt->buf only when out_pkt->data is guaranteed to point
              * to data in it and not in the parser's internal buffer. */
             /* XXX: Ensure this is the case with all parsers when st->parser->flags
              * is PARSER_FLAG_COMPLETE_FRAMES and check for that instead? */
-            out_pkt.buf = av_buffer_ref(pkt->buf);
-            if (!out_pkt.buf) {
+            out_pkt->buf = av_buffer_ref(pkt->buf);
+            if (!out_pkt->buf) {
                 ret = AVERROR(ENOMEM);
                 goto fail;
             }
         } else {
-            ret = av_packet_make_refcounted(&out_pkt);
+            ret = av_packet_make_refcounted(out_pkt);
             if (ret < 0)
                 goto fail;
         }
 
         if (pkt->side_data) {
-            out_pkt.side_data       = pkt->side_data;
-            out_pkt.side_data_elems = pkt->side_data_elems;
+            out_pkt->side_data       = pkt->side_data;
+            out_pkt->side_data_elems = pkt->side_data_elems;
             pkt->side_data          = NULL;
             pkt->side_data_elems    = 0;
         }
 
         /* set the duration */
-        out_pkt.duration = (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->duration : 0;
+        out_pkt->duration = (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->duration : 0;
         if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
             if (st->internal->avctx->sample_rate > 0) {
-                out_pkt.duration =
+                out_pkt->duration =
                     av_rescale_q_rnd(st->parser->duration,
                                      (AVRational) { 1, st->internal->avctx->sample_rate },
                                      st->time_base,
@@ -1469,30 +1473,30 @@  static int parse_packet(AVFormatContext *s, AVPacket *pkt,
             }
         }
 
-        out_pkt.stream_index = st->index;
-        out_pkt.pts          = st->parser->pts;
-        out_pkt.dts          = st->parser->dts;
-        out_pkt.pos          = st->parser->pos;
-        out_pkt.flags       |= pkt->flags & AV_PKT_FLAG_DISCARD;
+        out_pkt->stream_index = st->index;
+        out_pkt->pts          = st->parser->pts;
+        out_pkt->dts          = st->parser->dts;
+        out_pkt->pos          = st->parser->pos;
+        out_pkt->flags       |= pkt->flags & AV_PKT_FLAG_DISCARD;
 
         if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW)
-            out_pkt.pos = st->parser->frame_offset;
+            out_pkt->pos = st->parser->frame_offset;
 
         if (st->parser->key_frame == 1 ||
             (st->parser->key_frame == -1 &&
              st->parser->pict_type == AV_PICTURE_TYPE_I))
-            out_pkt.flags |= AV_PKT_FLAG_KEY;
+            out_pkt->flags |= AV_PKT_FLAG_KEY;
 
         if (st->parser->key_frame == -1 && st->parser->pict_type ==AV_PICTURE_TYPE_NONE && (pkt->flags&AV_PKT_FLAG_KEY))
-            out_pkt.flags |= AV_PKT_FLAG_KEY;
+            out_pkt->flags |= AV_PKT_FLAG_KEY;
 
-        compute_pkt_fields(s, st, st->parser, &out_pkt, next_dts, next_pts);
+        compute_pkt_fields(s, st, st->parser, out_pkt, next_dts, next_pts);
 
         ret = avpriv_packet_list_put(&s->internal->parse_queue,
                                  &s->internal->parse_queue_end,
-                                 &out_pkt, NULL, 0);
+                                 out_pkt, NULL, 0);
         if (ret < 0) {
-            av_packet_unref(&out_pkt);
+            av_packet_unref(out_pkt);
             goto fail;
         }
     }
@@ -1722,6 +1726,13 @@  int av_read_frame(AVFormatContext *s, AVPacket *pkt)
     int ret;
     AVStream *st;
 
+#if FF_API_INIT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+    pkt->data = NULL;
+    pkt->size = 0;
+    av_init_packet(pkt);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
     if (!genpts) {
         ret = s->internal->packet_buffer
               ? avpriv_packet_list_get(&s->internal->packet_buffer,
@@ -2368,7 +2379,7 @@  static int seek_frame_generic(AVFormatContext *s, int stream_index,
         return -1;
 
     if (index < 0 || index == st->internal->nb_index_entries - 1) {
-        AVPacket pkt;
+        AVPacket *pkt = s->internal->pkt;
         int nonkey = 0;
 
         if (st->internal->nb_index_entries) {
@@ -2381,25 +2392,26 @@  static int seek_frame_generic(AVFormatContext *s, int stream_index,
             if ((ret = avio_seek(s->pb, s->internal->data_offset, SEEK_SET)) < 0)
                 return ret;
         }
+        av_packet_unref(pkt);
         for (;;) {
             int read_status;
             do {
-                read_status = av_read_frame(s, &pkt);
+                read_status = av_read_frame(s, pkt);
             } while (read_status == AVERROR(EAGAIN));
             if (read_status < 0)
                 break;
-            if (stream_index == pkt.stream_index && pkt.dts > timestamp) {
-                if (pkt.flags & AV_PKT_FLAG_KEY) {
-                    av_packet_unref(&pkt);
+            if (stream_index == pkt->stream_index && pkt->dts > timestamp) {
+                if (pkt->flags & AV_PKT_FLAG_KEY) {
+                    av_packet_unref(pkt);
                     break;
                 }
                 if (nonkey++ > 1000 && st->codecpar->codec_id != AV_CODEC_ID_CDGRAPHICS) {
                     av_log(s, AV_LOG_ERROR,"seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, %d non keyframes found\n", nonkey);
-                    av_packet_unref(&pkt);
+                    av_packet_unref(pkt);
                     break;
                 }
             }
-            av_packet_unref(&pkt);
+            av_packet_unref(pkt);
         }
         index = av_index_search_timestamp(st, timestamp, flags);
     }
@@ -2747,7 +2759,7 @@  static void estimate_timings_from_bit_rate(AVFormatContext *ic)
 /* only usable for MPEG-PS streams */
 static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
 {
-    AVPacket pkt1, *pkt = &pkt1;
+    AVPacket *pkt = ic->internal->pkt;
     AVStream *st;
     int num, den, read_size, i, ret;
     int found_duration = 0;
@@ -3576,7 +3588,7 @@  int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
     int64_t read_size;
     AVStream *st;
     AVCodecContext *avctx;
-    AVPacket pkt1;
+    AVPacket *pkt1 = ic->internal->pkt;
     int64_t old_offset  = avio_tell(ic->pb);
     // new streams might appear, no options for those
     int orig_nb_streams = ic->nb_streams;
@@ -3779,7 +3791,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
 
         /* NOTE: A new stream can be added there if no header in file
          * (AVFMTCTX_NOHEADER). */
-        ret = read_frame_internal(ic, &pkt1);
+        ret = read_frame_internal(ic, pkt1);
         if (ret == AVERROR(EAGAIN))
             continue;
 
@@ -3792,13 +3804,13 @@  FF_ENABLE_DEPRECATION_WARNINGS
         if (!(ic->flags & AVFMT_FLAG_NOBUFFER)) {
             ret = avpriv_packet_list_put(&ic->internal->packet_buffer,
                                      &ic->internal->packet_buffer_end,
-                                     &pkt1, NULL, 0);
+                                     pkt1, NULL, 0);
             if (ret < 0)
                 goto unref_then_goto_end;
 
             pkt = &ic->internal->packet_buffer_end->pkt;
         } else {
-            pkt = &pkt1;
+            pkt = pkt1;
         }
 
         st = ic->streams[pkt->stream_index];
@@ -3878,7 +3890,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
                        limit,
                        t, pkt->stream_index);
                 if (ic->flags & AVFMT_FLAG_NOBUFFER)
-                    av_packet_unref(&pkt1);
+                    av_packet_unref(pkt1);
                 break;
             }
             if (pkt->duration) {
@@ -3915,7 +3927,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
                          (options && i < orig_nb_streams) ? &options[i] : NULL);
 
         if (ic->flags & AVFMT_FLAG_NOBUFFER)
-            av_packet_unref(&pkt1);
+            av_packet_unref(pkt1);
 
         st->codec_info_nb_frames++;
         count++;
@@ -3948,9 +3960,9 @@  FF_ENABLE_DEPRECATION_WARNINGS
     }
 
     if (flush_codecs) {
-        AVPacket empty_pkt = { 0 };
+        AVPacket *empty_pkt = ic->internal->pkt;
         int err = 0;
-        av_init_packet(&empty_pkt);
+        av_packet_unref(empty_pkt);
 
         for (i = 0; i < ic->nb_streams; i++) {
 
@@ -3959,7 +3971,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
             /* flush the decoders */
             if (st->internal->info->found_decoder == 1) {
                 do {
-                    err = try_decode_frame(ic, st, &empty_pkt,
+                    err = try_decode_frame(ic, st, empty_pkt,
                                             (options && i < orig_nb_streams)
                                             ? &options[i] : NULL);
                 } while (err > 0 && !has_codec_parameters(st, NULL));
@@ -4182,7 +4194,7 @@  find_stream_info_err:
     return ret;
 
 unref_then_goto_end:
-    av_packet_unref(&pkt1);
+    av_packet_unref(pkt1);
     goto find_stream_info_err;
 }
 
@@ -4446,6 +4458,7 @@  void avformat_free_context(AVFormatContext *s)
     av_dict_free(&s->metadata);
     av_dict_free(&s->internal->id3v2_meta);
     av_packet_free(&s->internal->pkt);
+    av_packet_free(&s->internal->parse_pkt);
     av_freep(&s->streams);
     flush_packet_queue(s);
     av_freep(&s->internal);