diff mbox series

[FFmpeg-devel,1/2,RFC] avcodec/packet: move AVPacketList definition and function helpers over from libavformat

Message ID 20200818195332.9442-2-jamrial@gmail.com
State Accepted
Headers show
Series avcodec/decode: use a packet list for last_pkt_props | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

James Almer Aug. 18, 2020, 7:53 p.m. UTC
Signed-off-by: James Almer <jamrial@gmail.com>
---
Not making these public because someone mentioned that the current signature
for these helpers was ugly (two AVPacketList pointers the caller needs to keep
around to track the list), and changing it would either require modifying a
public struct, introducing a new one, or making incredibly inefficient function
helpers that navigate the entire list to reach the end every time a new entry is
added.

A possible approach could be something like:

[libavcodec/packet.h]
typedef struct AVPacketList AVPacketList; // Opaque struct, API change

[libavcodec/packet_internal.h]
typedef struct PacketListEntry {
    AVPacket pkt;
    struct PacketListEntry *next;
} PacketListEntry; // Essentially what's currently AVPacketList

struct AVPacketList {
    PacketListEntry *head;
    PacketListEntry *tail;
};

AVPacketList *avpriv_packet_list_alloc(void);
int av_packet_list_put(AVPacketList *pktl, AVPacket *pkt, int flags);
int av_packet_list_get(AVPacketList *pktl, AVPacket *pkt);
int av_packet_list_peek(AVPacketList *pktl, AVPacket *pkt);
void av_packet_list_free(AVPacketList **pktl);

But special care would need to be given to some lists used in
libavformat/mux.c and libavformat/utils.c, one of which is even exposed in
avformat.h

Also, I'd rather not bikeshed too much about this API for the sake of the
following patch.

 libavcodec/avpacket.c        | 64 ++++++++++++++++++++++++++
 libavcodec/packet.h          |  5 ++
 libavcodec/packet_internal.h | 45 ++++++++++++++++++
 libavformat/aiffenc.c        |  5 +-
 libavformat/avformat.h       |  6 ---
 libavformat/flacenc.c        |  7 +--
 libavformat/internal.h       | 42 -----------------
 libavformat/matroskadec.c    | 11 +++--
 libavformat/mp3enc.c         |  7 +--
 libavformat/ttaenc.c         |  7 +--
 libavformat/utils.c          | 88 ++++++------------------------------
 11 files changed, 148 insertions(+), 139 deletions(-)

Comments

Andreas Rheinhardt Sept. 1, 2020, 5 p.m. UTC | #1
James Almer:
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> Not making these public because someone mentioned that the current signature
> for these helpers was ugly (two AVPacketList pointers the caller needs to keep
> around to track the list), and changing it would either require modifying a
> public struct, introducing a new one, or making incredibly inefficient function
> helpers that navigate the entire list to reach the end every time a new entry is
> added.
> 
> A possible approach could be something like:
> 
> [libavcodec/packet.h]
> typedef struct AVPacketList AVPacketList; // Opaque struct, API change
> 
> [libavcodec/packet_internal.h]
> typedef struct PacketListEntry {
>     AVPacket pkt;
>     struct PacketListEntry *next;
> } PacketListEntry; // Essentially what's currently AVPacketList
> 
> struct AVPacketList {
>     PacketListEntry *head;
>     PacketListEntry *tail;
> };
> 
> AVPacketList *avpriv_packet_list_alloc(void);
> int av_packet_list_put(AVPacketList *pktl, AVPacket *pkt, int flags);
> int av_packet_list_get(AVPacketList *pktl, AVPacket *pkt);
> int av_packet_list_peek(AVPacketList *pktl, AVPacket *pkt);
> void av_packet_list_free(AVPacketList **pktl);
> 
> But special care would need to be given to some lists used in
> libavformat/mux.c and libavformat/utils.c, one of which is even exposed in
> avformat.h

The last_in_packet_buffer is not part of the public API and could be
moved to AVStreamInternal (AVStream is currently kind of broken: ffmpeg
(the cli tool) accesses several of its internal fields (pts_wrap_bits,
first_dts, cur_dts, codec_info_nb_frames), so that one can not even add
new public fields to it; yet last_in_packet_buffer is after these three
elemts, so it could be moved); yet this very pointer to an AVPacketList
is special because it is not one of a heads+tails combination, but just
a pointer in the middle of this list; so it just doesn't work with your
proposal.
(The muxing queue itself is special because (afaik) it is the only queue
where new elements are added in the middle. (Has it actually ever been
tested whether it would be advantageouos to have one list for each
stream and just inspect each of these lists every time one wants to mux
a packet?))

> 
> Also, I'd rather not bikeshed too much about this API for the sake of the
> following patch.
> 
>  libavcodec/avpacket.c        | 64 ++++++++++++++++++++++++++
>  libavcodec/packet.h          |  5 ++
>  libavcodec/packet_internal.h | 45 ++++++++++++++++++
>  libavformat/aiffenc.c        |  5 +-
>  libavformat/avformat.h       |  6 ---
>  libavformat/flacenc.c        |  7 +--
>  libavformat/internal.h       | 42 -----------------
>  libavformat/matroskadec.c    | 11 +++--
>  libavformat/mp3enc.c         |  7 +--
>  libavformat/ttaenc.c         |  7 +--
>  libavformat/utils.c          | 88 ++++++------------------------------
>  11 files changed, 148 insertions(+), 139 deletions(-)
> 
> diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
> index 4801163227..473ce01227 100644
> --- a/libavcodec/avpacket.c
> +++ b/libavcodec/avpacket.c
> @@ -726,6 +726,70 @@ FF_ENABLE_DEPRECATION_WARNINGS
>  #endif
>  }
>  
> +int avpriv_packet_list_put(AVPacketList **packet_buffer,
> +                           AVPacketList **plast_pktl,
> +                           AVPacket      *pkt, int flags)
> +{
> +    AVPacketList *pktl = av_mallocz(sizeof(AVPacketList));
> +    int ret;
> +
> +    if (!pktl)
> +        return AVERROR(ENOMEM);
> +
> +    if (flags & FF_PACKETLIST_FLAG_REF_PACKET) {
> +        if ((ret = av_packet_ref(&pktl->pkt, pkt)) < 0) {
> +            av_free(pktl);
> +            return ret;
> +        }
> +    } else {
> +        ret = av_packet_make_refcounted(pkt);
> +        if (ret < 0) {
> +            av_free(pktl);
> +            return ret;
> +        }
> +        av_packet_move_ref(&pktl->pkt, pkt);
> +    }
> +
> +    if (*packet_buffer)
> +        (*plast_pktl)->next = pktl;
> +    else
> +        *packet_buffer = pktl;
> +
> +    /* Add the packet in the buffered packet list. */
> +    *plast_pktl = pktl;
> +    return 0;
> +}
> +
> +int avpriv_packet_list_get(AVPacketList **pkt_buffer,
> +                           AVPacketList **pkt_buffer_end,
> +                           AVPacket      *pkt)
> +{
> +    AVPacketList *pktl;
> +    if (!*pkt_buffer)
> +        return AVERROR(EAGAIN);
> +    pktl        = *pkt_buffer;
> +    *pkt        = pktl->pkt;
> +    *pkt_buffer = pktl->next;
> +    if (!pktl->next)
> +        *pkt_buffer_end = NULL;
> +    av_freep(&pktl);
> +    return 0;
> +}
> +
> +void avpriv_packet_list_free(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end)
> +{
> +    AVPacketList *tmp = *pkt_buf;
> +
> +    while (tmp) {
> +        AVPacketList *pktl = tmp;
> +        tmp = pktl->next;
> +        av_packet_unref(&pktl->pkt);
> +        av_freep(&pktl);
> +    }
> +    *pkt_buf     = NULL;
> +    *pkt_buf_end = NULL;
> +}
> +
>  int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type)
>  {
>      uint8_t *side_data;
> diff --git a/libavcodec/packet.h b/libavcodec/packet.h
> index 0a19a0eff3..b9d4c9c2c8 100644
> --- a/libavcodec/packet.h
> +++ b/libavcodec/packet.h
> @@ -393,6 +393,11 @@ typedef struct AVPacket {
>  #endif
>  } AVPacket;
>  
> +typedef struct AVPacketList {
> +    AVPacket pkt;
> +    struct AVPacketList *next;
> +} AVPacketList;
> +
>  #define AV_PKT_FLAG_KEY     0x0001 ///< The packet contains a keyframe
>  #define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted
>  /**
> diff --git a/libavcodec/packet_internal.h b/libavcodec/packet_internal.h
> index cdb9a27f2f..387b63169a 100644
> --- a/libavcodec/packet_internal.h
> +++ b/libavcodec/packet_internal.h
> @@ -23,6 +23,51 @@
>  
>  #include "packet.h"
>  
> +
> +/** Create a new reference for the packet instead of
> + * transferring the ownership of the existing one to the
> + * list.
> + */
> +#define FF_PACKETLIST_FLAG_REF_PACKET (1 << 0)
> +
> +/**
> + * Append an AVPacket to the list.
> + *
> + * @param head  List head element
> + * @param tail  List tail element
> + * @param pkt   The packet being appended. The data described in it will
> + *              be made reference counted if it isn't already.
> + * @param flags Any combination of FF_PACKETLIST_FLAG_* flags
> + * @return 0 on success, negative AVERROR value on failure. On failure,
> +           the list is unchanged
> + */
> +int avpriv_packet_list_put(AVPacketList **head, AVPacketList **tail,
> +                           AVPacket *pkt, int flags);
> +
> +/**
> + * Remove the oldest AVPacket in the list and return it.
> + *
> + * @note The pkt will be overwritten completely on success. The caller
> + *       owns the packet and must unref it by itself.
> + *
> + * @param head List head element
> + * @param tail List tail element
> + * @param pkt  Pointer to an AVPacket struct
> + * @return 0 on success. AVERROR(EAGAIN) if nothing is returned. Another
> + *         negative AVERROR code on failure. On failure, the list is
> + *         unchanged

I really dislike that you are removing the guarantee that one can always
remove a packet from a list if the list is not empty. This means that
one would now have to add unnecessary checks to several existing callers
of this function.

Furthermore, your wording is weird: If nothing is returned, the return
value is AVERROR(EAGAIN). This implies that if some other AVERROR code
were to be returned, something is returned, i.e. the packet will be changed.

> + */
> +int avpriv_packet_list_get(AVPacketList **head, AVPacketList **tail,
> +                           AVPacket *pkt);
> +
> +/**
> + * Wipe the list and unref all the packets in it.
> + *
> + * @param head List head element
> + * @param tail List tail element
> + */
> +void avpriv_packet_list_free(AVPacketList **head, AVPacketList **tail);
> +
>  int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type);
>  
>  int ff_side_data_set_prft(AVPacket *pkt, int64_t timestamp);
> diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
> index 88c45df334..1dc7eb4597 100644
> --- a/libavformat/aiffenc.c
> +++ b/libavformat/aiffenc.c
> @@ -23,6 +23,7 @@
>  
>  #include "libavutil/intfloat.h"
>  #include "libavutil/opt.h"
> +#include "libavcodec/packet_internal.h"
>  #include "avformat.h"
>  #include "internal.h"
>  #include "aiff.h"
> @@ -220,7 +221,7 @@ static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt)
>          if (s->streams[pkt->stream_index]->nb_frames >= 1)
>              return 0;
>  
> -        return ff_packet_list_put(&aiff->pict_list, &aiff->pict_list_end,
> +        return avpriv_packet_list_put(&aiff->pict_list, &aiff->pict_list_end,
>                                    pkt, FF_PACKETLIST_FLAG_REF_PACKET);
>      }
>  
> @@ -272,7 +273,7 @@ static void aiff_deinit(AVFormatContext *s)
>  {
>      AIFFOutputContext *aiff = s->priv_data;
>  
> -    ff_packet_list_free(&aiff->pict_list, &aiff->pict_list_end);
> +    avpriv_packet_list_free(&aiff->pict_list, &aiff->pict_list_end);
>  }
>  
>  #define OFFSET(x) offsetof(AIFFOutputContext, x)
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index e91e7f1d33..c8c0b6c08d 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -2007,12 +2007,6 @@ void av_format_inject_global_side_data(AVFormatContext *s);
>   */
>  enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx);
>  
> -typedef struct AVPacketList {
> -    AVPacket pkt;
> -    struct AVPacketList *next;
> -} AVPacketList;
> -
> -
>  /**
>   * @defgroup lavf_core Core functions
>   * @ingroup libavf
> diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
> index b947a3b067..d6f1659c14 100644
> --- a/libavformat/flacenc.c
> +++ b/libavformat/flacenc.c
> @@ -23,6 +23,7 @@
>  #include "libavutil/opt.h"
>  #include "libavutil/pixdesc.h"
>  #include "libavcodec/flac.h"
> +#include "libavcodec/packet_internal.h"
>  #include "avformat.h"
>  #include "avio_internal.h"
>  #include "flacenc.h"
> @@ -305,7 +306,7 @@ static int flac_queue_flush(AVFormatContext *s)
>          write = 0;
>  
>      while (c->queue) {
> -        ff_packet_list_get(&c->queue, &c->queue_end, &pkt);
> +        avpriv_packet_list_get(&c->queue, &c->queue_end, &pkt);
>          if (write && (ret = flac_write_audio_packet(s, &pkt)) < 0)
>              write = 0;
>          av_packet_unref(&pkt);
> @@ -345,7 +346,7 @@ static void flac_deinit(struct AVFormatContext *s)
>  {
>      FlacMuxerContext *c = s->priv_data;
>  
> -    ff_packet_list_free(&c->queue, &c->queue_end);
> +    avpriv_packet_list_free(&c->queue, &c->queue_end);
>  }
>  
>  static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt)
> @@ -356,7 +357,7 @@ static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt)
>      if (pkt->stream_index == c->audio_stream_idx) {
>          if (c->waiting_pics) {
>              /* buffer audio packets until we get all the pictures */
> -            ret = ff_packet_list_put(&c->queue, &c->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET);
> +            ret = avpriv_packet_list_put(&c->queue, &c->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET);
>              if (ret < 0) {
>                  av_log(s, AV_LOG_ERROR, "Out of memory in packet queue; skipping attached pictures\n");
>                  c->waiting_pics = 0;
> diff --git a/libavformat/internal.h b/libavformat/internal.h
> index 17a6ab07d3..f4174628e0 100644
> --- a/libavformat/internal.h
> +++ b/libavformat/internal.h
> @@ -730,48 +730,6 @@ int ff_unlock_avformat(void);
>   */
>  void ff_format_set_url(AVFormatContext *s, char *url);
>  
> -#define FF_PACKETLIST_FLAG_REF_PACKET (1 << 0) /**< Create a new reference for the packet instead of
> -                                                    transferring the ownership of the existing one to the
> -                                                    list. */
> -
> -/**
> - * Append an AVPacket to the list.
> - *
> - * @param head  List head element
> - * @param tail  List tail element
> - * @param pkt   The packet being appended. The data described in it will
> - *              be made reference counted if it isn't already.
> - * @param flags Any combination of FF_PACKETLIST_FLAG_* flags
> - * @return 0 on success, negative AVERROR value on failure. On failure,
> -           the list is unchanged
> - */
> -int ff_packet_list_put(AVPacketList **head, AVPacketList **tail,
> -                       AVPacket *pkt, int flags);
> -
> -/**
> - * Remove the oldest AVPacket in the list and return it.
> - * The behaviour is undefined if the packet list is empty.
> - *
> - * @note The pkt will be overwritten completely. The caller owns the
> - *       packet and must unref it by itself.
> - *
> - * @param head List head element
> - * @param tail List tail element
> - * @param pkt  Pointer to an AVPacket struct
> - * @return 0 on success. Success is guaranteed
> - *         if the packet list is not empty.
> - */
> -int ff_packet_list_get(AVPacketList **head, AVPacketList **tail,
> -                       AVPacket *pkt);
> -
> -/**
> - * Wipe the list and unref all the packets in it.
> - *
> - * @param head List head element
> - * @param tail List tail element
> - */
> -void ff_packet_list_free(AVPacketList **head, AVPacketList **tail);
> -
>  void avpriv_register_devices(const AVOutputFormat * const o[], const AVInputFormat * const i[]);
>  
>  #endif /* AVFORMAT_INTERNAL_H */
> diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
> index b1ef344aa7..7582e5d89b 100644
> --- a/libavformat/matroskadec.c
> +++ b/libavformat/matroskadec.c
> @@ -48,6 +48,7 @@
>  #include "libavcodec/bytestream.h"
>  #include "libavcodec/flac.h"
>  #include "libavcodec/mpeg4audio.h"
> +#include "libavcodec/packet_internal.h"
>  
>  #include "avformat.h"
>  #include "avio_internal.h"
> @@ -2991,7 +2992,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
>          MatroskaTrack *tracks = matroska->tracks.elem;
>          MatroskaTrack *track;
>  
> -        ff_packet_list_get(&matroska->queue, &matroska->queue_end, pkt);
> +        avpriv_packet_list_get(&matroska->queue, &matroska->queue_end, pkt);
>          track = &tracks[pkt->stream_index];
>          if (track->has_palette) {
>              uint8_t *pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
> @@ -3013,7 +3014,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
>   */
>  static void matroska_clear_queue(MatroskaDemuxContext *matroska)
>  {
> -    ff_packet_list_free(&matroska->queue, &matroska->queue_end);
> +    avpriv_packet_list_free(&matroska->queue, &matroska->queue_end);
>  }
>  
>  static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
> @@ -3179,7 +3180,7 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
>          track->audio.buf_timecode = AV_NOPTS_VALUE;
>          pkt->pos                  = pos;
>          pkt->stream_index         = st->index;
> -        ret = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
> +        ret = avpriv_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
>          if (ret < 0) {
>              av_packet_unref(pkt);
>              return AVERROR(ENOMEM);
> @@ -3401,7 +3402,7 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska,
>      pkt->duration = duration;
>      pkt->pos = pos;
>  
> -    err = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
> +    err = avpriv_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
>      if (err < 0) {
>          av_packet_unref(pkt);
>          return AVERROR(ENOMEM);
> @@ -3512,7 +3513,7 @@ FF_DISABLE_DEPRECATION_WARNINGS
>  FF_ENABLE_DEPRECATION_WARNINGS
>  #endif
>  
> -    res = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
> +    res = avpriv_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
>      if (res < 0) {
>          av_packet_unref(pkt);
>          return AVERROR(ENOMEM);
> diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
> index a3586e1f86..5a0567e72f 100644
> --- a/libavformat/mp3enc.c
> +++ b/libavformat/mp3enc.c
> @@ -28,6 +28,7 @@
>  #include "libavcodec/mpegaudio.h"
>  #include "libavcodec/mpegaudiodata.h"
>  #include "libavcodec/mpegaudiodecheader.h"
> +#include "libavcodec/packet_internal.h"
>  #include "libavutil/intreadwrite.h"
>  #include "libavutil/opt.h"
>  #include "libavutil/dict.h"
> @@ -387,7 +388,7 @@ static int mp3_queue_flush(AVFormatContext *s)
>      mp3_write_xing(s);
>  
>      while (mp3->queue) {
> -        ff_packet_list_get(&mp3->queue, &mp3->queue_end, &pkt);
> +        avpriv_packet_list_get(&mp3->queue, &mp3->queue_end, &pkt);
>          if (write && (ret = mp3_write_audio_packet(s, &pkt)) < 0)
>              write = 0;
>          av_packet_unref(&pkt);
> @@ -522,7 +523,7 @@ static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt)
>      if (pkt->stream_index == mp3->audio_stream_idx) {
>          if (mp3->pics_to_write) {
>              /* buffer audio packets until we get all the pictures */
> -            int ret = ff_packet_list_put(&mp3->queue, &mp3->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET);
> +            int ret = avpriv_packet_list_put(&mp3->queue, &mp3->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET);
>  
>              if (ret < 0) {
>                  av_log(s, AV_LOG_WARNING, "Not enough memory to buffer audio. Skipping picture streams\n");
> @@ -630,7 +631,7 @@ static void mp3_deinit(struct AVFormatContext *s)
>  {
>      MP3Context *mp3 = s->priv_data;
>  
> -    ff_packet_list_free(&mp3->queue, &mp3->queue_end);
> +    avpriv_packet_list_free(&mp3->queue, &mp3->queue_end);
>      av_freep(&mp3->xing_frame);
>  }
>  
> diff --git a/libavformat/ttaenc.c b/libavformat/ttaenc.c
> index becd3e7153..589a3b334f 100644
> --- a/libavformat/ttaenc.c
> +++ b/libavformat/ttaenc.c
> @@ -22,6 +22,7 @@
>  #include "libavutil/crc.h"
>  #include "libavutil/intreadwrite.h"
>  
> +#include "libavcodec/packet_internal.h"
>  #include "apetag.h"
>  #include "avformat.h"
>  #include "avio_internal.h"
> @@ -93,7 +94,7 @@ static int tta_write_packet(AVFormatContext *s, AVPacket *pkt)
>      TTAMuxContext *tta = s->priv_data;
>      int ret;
>  
> -    ret = ff_packet_list_put(&tta->queue, &tta->queue_end, pkt,
> +    ret = avpriv_packet_list_put(&tta->queue, &tta->queue_end, pkt,
>                               FF_PACKETLIST_FLAG_REF_PACKET);
>      if (ret < 0) {
>          return ret;
> @@ -125,7 +126,7 @@ static void tta_queue_flush(AVFormatContext *s)
>      AVPacket pkt;
>  
>      while (tta->queue) {
> -        ff_packet_list_get(&tta->queue, &tta->queue_end, &pkt);
> +        avpriv_packet_list_get(&tta->queue, &tta->queue_end, &pkt);
>          avio_write(s->pb, pkt.data, pkt.size);
>          av_packet_unref(&pkt);
>      }
> @@ -161,7 +162,7 @@ static void tta_deinit(AVFormatContext *s)
>      TTAMuxContext *tta = s->priv_data;
>  
>      ffio_free_dyn_buf(&tta->seek_table);
> -    ff_packet_list_free(&tta->queue, &tta->queue_end);
> +    avpriv_packet_list_free(&tta->queue, &tta->queue_end);
>  }
>  
>  AVOutputFormat ff_tta_muxer = {
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index 807d9f10cb..b1f48d88bd 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -37,6 +37,7 @@
>  
>  #include "libavcodec/bytestream.h"
>  #include "libavcodec/internal.h"
> +#include "libavcodec/packet_internal.h"
>  #include "libavcodec/raw.h"
>  
>  #include "avformat.h"
> @@ -438,40 +439,6 @@ static int init_input(AVFormatContext *s, const char *filename,
>                                   s, 0, s->format_probesize);
>  }
>  
> -int ff_packet_list_put(AVPacketList **packet_buffer,
> -                       AVPacketList **plast_pktl,
> -                       AVPacket      *pkt, int flags)
> -{
> -    AVPacketList *pktl = av_mallocz(sizeof(AVPacketList));
> -    int ret;
> -
> -    if (!pktl)
> -        return AVERROR(ENOMEM);
> -
> -    if (flags & FF_PACKETLIST_FLAG_REF_PACKET) {
> -        if ((ret = av_packet_ref(&pktl->pkt, pkt)) < 0) {
> -            av_free(pktl);
> -            return ret;
> -        }
> -    } else {
> -        ret = av_packet_make_refcounted(pkt);
> -        if (ret < 0) {
> -            av_free(pktl);
> -            return ret;
> -        }
> -        av_packet_move_ref(&pktl->pkt, pkt);
> -    }
> -
> -    if (*packet_buffer)
> -        (*plast_pktl)->next = pktl;
> -    else
> -        *packet_buffer = pktl;
> -
> -    /* Add the packet in the buffered packet list. */
> -    *plast_pktl = pktl;
> -    return 0;
> -}
> -
>  int avformat_queue_attached_pictures(AVFormatContext *s)
>  {
>      int i, ret;
> @@ -485,7 +452,7 @@ int avformat_queue_attached_pictures(AVFormatContext *s)
>                  continue;
>              }
>  
> -            ret = ff_packet_list_put(&s->internal->raw_packet_buffer,
> +            ret = avpriv_packet_list_put(&s->internal->raw_packet_buffer,
>                                       &s->internal->raw_packet_buffer_end,
>                                       &s->streams[i]->attached_pic,
>                                       FF_PACKETLIST_FLAG_REF_PACKET);
> @@ -841,7 +808,7 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
>                  if ((err = probe_codec(s, st, NULL)) < 0)
>                      return err;
>              if (st->request_probe <= 0) {
> -                ff_packet_list_get(&s->internal->raw_packet_buffer,
> +                avpriv_packet_list_get(&s->internal->raw_packet_buffer,
>                                     &s->internal->raw_packet_buffer_end, pkt);
>                  s->internal->raw_packet_buffer_remaining_size += pkt->size;
>                  return 0;
> @@ -914,7 +881,7 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
>          if (!pktl && st->request_probe <= 0)
>              return ret;
>  
> -        err = ff_packet_list_put(&s->internal->raw_packet_buffer,
> +        err = avpriv_packet_list_put(&s->internal->raw_packet_buffer,
>                                   &s->internal->raw_packet_buffer_end,
>                                   pkt, 0);
>          if (err < 0) {
> @@ -1420,20 +1387,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
>  #endif
>  }
>  
> -void ff_packet_list_free(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end)
> -{
> -    AVPacketList *tmp = *pkt_buf;
> -
> -    while (tmp) {
> -        AVPacketList *pktl = tmp;
> -        tmp = pktl->next;
> -        av_packet_unref(&pktl->pkt);
> -        av_freep(&pktl);
> -    }
> -    *pkt_buf     = NULL;
> -    *pkt_buf_end = NULL;
> -}
> -
>  /**
>   * Parse a packet, add all split parts to parse_queue.
>   *
> @@ -1530,7 +1483,7 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
>  
>          compute_pkt_fields(s, st, st->parser, &out_pkt, next_dts, next_pts);
>  
> -        ret = ff_packet_list_put(&s->internal->parse_queue,
> +        ret = avpriv_packet_list_put(&s->internal->parse_queue,
>                                   &s->internal->parse_queue_end,
>                                   &out_pkt, 0);
>          if (ret < 0) {
> @@ -1550,21 +1503,6 @@ fail:
>      return ret;
>  }
>  
> -int ff_packet_list_get(AVPacketList **pkt_buffer,
> -                       AVPacketList **pkt_buffer_end,
> -                       AVPacket      *pkt)
> -{
> -    AVPacketList *pktl;
> -    av_assert0(*pkt_buffer);
> -    pktl        = *pkt_buffer;
> -    *pkt        = pktl->pkt;
> -    *pkt_buffer = pktl->next;
> -    if (!pktl->next)
> -        *pkt_buffer_end = NULL;
> -    av_freep(&pktl);
> -    return 0;
> -}
> -
>  static int64_t ts_to_samples(AVStream *st, int64_t ts)
>  {
>      return av_rescale(ts, st->time_base.num * st->codecpar->sample_rate, st->time_base.den);
> @@ -1695,7 +1633,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
>      }
>  
>      if (!got_packet && s->internal->parse_queue)
> -        ret = ff_packet_list_get(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt);
> +        ret = avpriv_packet_list_get(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt);
>  
>      if (ret >= 0) {
>          AVStream *st = s->streams[pkt->stream_index];
> @@ -1779,7 +1717,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
>  
>      if (!genpts) {
>          ret = s->internal->packet_buffer
> -              ? ff_packet_list_get(&s->internal->packet_buffer,
> +              ? avpriv_packet_list_get(&s->internal->packet_buffer,
>                                          &s->internal->packet_buffer_end, pkt)
>                : read_frame_internal(s, pkt);
>          if (ret < 0)
> @@ -1828,7 +1766,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
>              st = s->streams[next_pkt->stream_index];
>              if (!(next_pkt->pts == AV_NOPTS_VALUE && st->discard < AVDISCARD_ALL &&
>                    next_pkt->dts != AV_NOPTS_VALUE && !eof)) {
> -                ret = ff_packet_list_get(&s->internal->packet_buffer,
> +                ret = avpriv_packet_list_get(&s->internal->packet_buffer,
>                                                 &s->internal->packet_buffer_end, pkt);
>                  goto return_packet;
>              }
> @@ -1843,7 +1781,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
>                  return ret;
>          }
>  
> -        ret = ff_packet_list_put(&s->internal->packet_buffer,
> +        ret = avpriv_packet_list_put(&s->internal->packet_buffer,
>                                   &s->internal->packet_buffer_end,
>                                   pkt, 0);
>          if (ret < 0) {
> @@ -1873,9 +1811,9 @@ static void flush_packet_queue(AVFormatContext *s)
>  {
>      if (!s->internal)
>          return;
> -    ff_packet_list_free(&s->internal->parse_queue,       &s->internal->parse_queue_end);
> -    ff_packet_list_free(&s->internal->packet_buffer,     &s->internal->packet_buffer_end);
> -    ff_packet_list_free(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end);
> +    avpriv_packet_list_free(&s->internal->parse_queue,       &s->internal->parse_queue_end);
> +    avpriv_packet_list_free(&s->internal->packet_buffer,     &s->internal->packet_buffer_end);
> +    avpriv_packet_list_free(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end);
>  
>      s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
>  }
> @@ -3832,7 +3770,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
>          }
>  
>          if (!(ic->flags & AVFMT_FLAG_NOBUFFER)) {
> -            ret = ff_packet_list_put(&ic->internal->packet_buffer,
> +            ret = avpriv_packet_list_put(&ic->internal->packet_buffer,
>                                       &ic->internal->packet_buffer_end,
>                                       &pkt1, 0);
>              if (ret < 0)
>
James Almer Sept. 1, 2020, 5:19 p.m. UTC | #2
On 9/1/2020 2:00 PM, Andreas Rheinhardt wrote:
> James Almer:
>> diff --git a/libavcodec/packet_internal.h b/libavcodec/packet_internal.h
>> index cdb9a27f2f..387b63169a 100644
>> --- a/libavcodec/packet_internal.h
>> +++ b/libavcodec/packet_internal.h
>> @@ -23,6 +23,51 @@
>>  
>>  #include "packet.h"
>>  
>> +
>> +/** Create a new reference for the packet instead of
>> + * transferring the ownership of the existing one to the
>> + * list.
>> + */
>> +#define FF_PACKETLIST_FLAG_REF_PACKET (1 << 0)
>> +
>> +/**
>> + * Append an AVPacket to the list.
>> + *
>> + * @param head  List head element
>> + * @param tail  List tail element
>> + * @param pkt   The packet being appended. The data described in it will
>> + *              be made reference counted if it isn't already.
>> + * @param flags Any combination of FF_PACKETLIST_FLAG_* flags
>> + * @return 0 on success, negative AVERROR value on failure. On failure,
>> +           the list is unchanged
>> + */
>> +int avpriv_packet_list_put(AVPacketList **head, AVPacketList **tail,
>> +                           AVPacket *pkt, int flags);
>> +
>> +/**
>> + * Remove the oldest AVPacket in the list and return it.
>> + *
>> + * @note The pkt will be overwritten completely on success. The caller
>> + *       owns the packet and must unref it by itself.
>> + *
>> + * @param head List head element
>> + * @param tail List tail element
>> + * @param pkt  Pointer to an AVPacket struct
>> + * @return 0 on success. AVERROR(EAGAIN) if nothing is returned. Another
>> + *         negative AVERROR code on failure. On failure, the list is
>> + *         unchanged
> 
> I really dislike that you are removing the guarantee that one can always
> remove a packet from a list if the list is not empty. This means that
> one would now have to add unnecessary checks to several existing callers
> of this function.
> 
> Furthermore, your wording is weird: If nothing is returned, the return
> value is AVERROR(EAGAIN). This implies that if some other AVERROR code
> were to be returned, something is returned, i.e. the packet will be changed.

I can remove the "another negative AVERROR" part. Just added it for the
sake of being extensible, but since it's private it doesn't matter.

And sure, can also change the EAGAIN part so it's clear what it means.
diff mbox series

Patch

diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index 4801163227..473ce01227 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -726,6 +726,70 @@  FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 }
 
+int avpriv_packet_list_put(AVPacketList **packet_buffer,
+                           AVPacketList **plast_pktl,
+                           AVPacket      *pkt, int flags)
+{
+    AVPacketList *pktl = av_mallocz(sizeof(AVPacketList));
+    int ret;
+
+    if (!pktl)
+        return AVERROR(ENOMEM);
+
+    if (flags & FF_PACKETLIST_FLAG_REF_PACKET) {
+        if ((ret = av_packet_ref(&pktl->pkt, pkt)) < 0) {
+            av_free(pktl);
+            return ret;
+        }
+    } else {
+        ret = av_packet_make_refcounted(pkt);
+        if (ret < 0) {
+            av_free(pktl);
+            return ret;
+        }
+        av_packet_move_ref(&pktl->pkt, pkt);
+    }
+
+    if (*packet_buffer)
+        (*plast_pktl)->next = pktl;
+    else
+        *packet_buffer = pktl;
+
+    /* Add the packet in the buffered packet list. */
+    *plast_pktl = pktl;
+    return 0;
+}
+
+int avpriv_packet_list_get(AVPacketList **pkt_buffer,
+                           AVPacketList **pkt_buffer_end,
+                           AVPacket      *pkt)
+{
+    AVPacketList *pktl;
+    if (!*pkt_buffer)
+        return AVERROR(EAGAIN);
+    pktl        = *pkt_buffer;
+    *pkt        = pktl->pkt;
+    *pkt_buffer = pktl->next;
+    if (!pktl->next)
+        *pkt_buffer_end = NULL;
+    av_freep(&pktl);
+    return 0;
+}
+
+void avpriv_packet_list_free(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end)
+{
+    AVPacketList *tmp = *pkt_buf;
+
+    while (tmp) {
+        AVPacketList *pktl = tmp;
+        tmp = pktl->next;
+        av_packet_unref(&pktl->pkt);
+        av_freep(&pktl);
+    }
+    *pkt_buf     = NULL;
+    *pkt_buf_end = NULL;
+}
+
 int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type)
 {
     uint8_t *side_data;
diff --git a/libavcodec/packet.h b/libavcodec/packet.h
index 0a19a0eff3..b9d4c9c2c8 100644
--- a/libavcodec/packet.h
+++ b/libavcodec/packet.h
@@ -393,6 +393,11 @@  typedef struct AVPacket {
 #endif
 } AVPacket;
 
+typedef struct AVPacketList {
+    AVPacket pkt;
+    struct AVPacketList *next;
+} AVPacketList;
+
 #define AV_PKT_FLAG_KEY     0x0001 ///< The packet contains a keyframe
 #define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted
 /**
diff --git a/libavcodec/packet_internal.h b/libavcodec/packet_internal.h
index cdb9a27f2f..387b63169a 100644
--- a/libavcodec/packet_internal.h
+++ b/libavcodec/packet_internal.h
@@ -23,6 +23,51 @@ 
 
 #include "packet.h"
 
+
+/** Create a new reference for the packet instead of
+ * transferring the ownership of the existing one to the
+ * list.
+ */
+#define FF_PACKETLIST_FLAG_REF_PACKET (1 << 0)
+
+/**
+ * Append an AVPacket to the list.
+ *
+ * @param head  List head element
+ * @param tail  List tail element
+ * @param pkt   The packet being appended. The data described in it will
+ *              be made reference counted if it isn't already.
+ * @param flags Any combination of FF_PACKETLIST_FLAG_* flags
+ * @return 0 on success, negative AVERROR value on failure. On failure,
+           the list is unchanged
+ */
+int avpriv_packet_list_put(AVPacketList **head, AVPacketList **tail,
+                           AVPacket *pkt, int flags);
+
+/**
+ * Remove the oldest AVPacket in the list and return it.
+ *
+ * @note The pkt will be overwritten completely on success. The caller
+ *       owns the packet and must unref it by itself.
+ *
+ * @param head List head element
+ * @param tail List tail element
+ * @param pkt  Pointer to an AVPacket struct
+ * @return 0 on success. AVERROR(EAGAIN) if nothing is returned. Another
+ *         negative AVERROR code on failure. On failure, the list is
+ *         unchanged
+ */
+int avpriv_packet_list_get(AVPacketList **head, AVPacketList **tail,
+                           AVPacket *pkt);
+
+/**
+ * Wipe the list and unref all the packets in it.
+ *
+ * @param head List head element
+ * @param tail List tail element
+ */
+void avpriv_packet_list_free(AVPacketList **head, AVPacketList **tail);
+
 int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type);
 
 int ff_side_data_set_prft(AVPacket *pkt, int64_t timestamp);
diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
index 88c45df334..1dc7eb4597 100644
--- a/libavformat/aiffenc.c
+++ b/libavformat/aiffenc.c
@@ -23,6 +23,7 @@ 
 
 #include "libavutil/intfloat.h"
 #include "libavutil/opt.h"
+#include "libavcodec/packet_internal.h"
 #include "avformat.h"
 #include "internal.h"
 #include "aiff.h"
@@ -220,7 +221,7 @@  static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt)
         if (s->streams[pkt->stream_index]->nb_frames >= 1)
             return 0;
 
-        return ff_packet_list_put(&aiff->pict_list, &aiff->pict_list_end,
+        return avpriv_packet_list_put(&aiff->pict_list, &aiff->pict_list_end,
                                   pkt, FF_PACKETLIST_FLAG_REF_PACKET);
     }
 
@@ -272,7 +273,7 @@  static void aiff_deinit(AVFormatContext *s)
 {
     AIFFOutputContext *aiff = s->priv_data;
 
-    ff_packet_list_free(&aiff->pict_list, &aiff->pict_list_end);
+    avpriv_packet_list_free(&aiff->pict_list, &aiff->pict_list_end);
 }
 
 #define OFFSET(x) offsetof(AIFFOutputContext, x)
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index e91e7f1d33..c8c0b6c08d 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -2007,12 +2007,6 @@  void av_format_inject_global_side_data(AVFormatContext *s);
  */
 enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx);
 
-typedef struct AVPacketList {
-    AVPacket pkt;
-    struct AVPacketList *next;
-} AVPacketList;
-
-
 /**
  * @defgroup lavf_core Core functions
  * @ingroup libavf
diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
index b947a3b067..d6f1659c14 100644
--- a/libavformat/flacenc.c
+++ b/libavformat/flacenc.c
@@ -23,6 +23,7 @@ 
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavcodec/flac.h"
+#include "libavcodec/packet_internal.h"
 #include "avformat.h"
 #include "avio_internal.h"
 #include "flacenc.h"
@@ -305,7 +306,7 @@  static int flac_queue_flush(AVFormatContext *s)
         write = 0;
 
     while (c->queue) {
-        ff_packet_list_get(&c->queue, &c->queue_end, &pkt);
+        avpriv_packet_list_get(&c->queue, &c->queue_end, &pkt);
         if (write && (ret = flac_write_audio_packet(s, &pkt)) < 0)
             write = 0;
         av_packet_unref(&pkt);
@@ -345,7 +346,7 @@  static void flac_deinit(struct AVFormatContext *s)
 {
     FlacMuxerContext *c = s->priv_data;
 
-    ff_packet_list_free(&c->queue, &c->queue_end);
+    avpriv_packet_list_free(&c->queue, &c->queue_end);
 }
 
 static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt)
@@ -356,7 +357,7 @@  static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt)
     if (pkt->stream_index == c->audio_stream_idx) {
         if (c->waiting_pics) {
             /* buffer audio packets until we get all the pictures */
-            ret = ff_packet_list_put(&c->queue, &c->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET);
+            ret = avpriv_packet_list_put(&c->queue, &c->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET);
             if (ret < 0) {
                 av_log(s, AV_LOG_ERROR, "Out of memory in packet queue; skipping attached pictures\n");
                 c->waiting_pics = 0;
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 17a6ab07d3..f4174628e0 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -730,48 +730,6 @@  int ff_unlock_avformat(void);
  */
 void ff_format_set_url(AVFormatContext *s, char *url);
 
-#define FF_PACKETLIST_FLAG_REF_PACKET (1 << 0) /**< Create a new reference for the packet instead of
-                                                    transferring the ownership of the existing one to the
-                                                    list. */
-
-/**
- * Append an AVPacket to the list.
- *
- * @param head  List head element
- * @param tail  List tail element
- * @param pkt   The packet being appended. The data described in it will
- *              be made reference counted if it isn't already.
- * @param flags Any combination of FF_PACKETLIST_FLAG_* flags
- * @return 0 on success, negative AVERROR value on failure. On failure,
-           the list is unchanged
- */
-int ff_packet_list_put(AVPacketList **head, AVPacketList **tail,
-                       AVPacket *pkt, int flags);
-
-/**
- * Remove the oldest AVPacket in the list and return it.
- * The behaviour is undefined if the packet list is empty.
- *
- * @note The pkt will be overwritten completely. The caller owns the
- *       packet and must unref it by itself.
- *
- * @param head List head element
- * @param tail List tail element
- * @param pkt  Pointer to an AVPacket struct
- * @return 0 on success. Success is guaranteed
- *         if the packet list is not empty.
- */
-int ff_packet_list_get(AVPacketList **head, AVPacketList **tail,
-                       AVPacket *pkt);
-
-/**
- * Wipe the list and unref all the packets in it.
- *
- * @param head List head element
- * @param tail List tail element
- */
-void ff_packet_list_free(AVPacketList **head, AVPacketList **tail);
-
 void avpriv_register_devices(const AVOutputFormat * const o[], const AVInputFormat * const i[]);
 
 #endif /* AVFORMAT_INTERNAL_H */
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index b1ef344aa7..7582e5d89b 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -48,6 +48,7 @@ 
 #include "libavcodec/bytestream.h"
 #include "libavcodec/flac.h"
 #include "libavcodec/mpeg4audio.h"
+#include "libavcodec/packet_internal.h"
 
 #include "avformat.h"
 #include "avio_internal.h"
@@ -2991,7 +2992,7 @@  static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
         MatroskaTrack *tracks = matroska->tracks.elem;
         MatroskaTrack *track;
 
-        ff_packet_list_get(&matroska->queue, &matroska->queue_end, pkt);
+        avpriv_packet_list_get(&matroska->queue, &matroska->queue_end, pkt);
         track = &tracks[pkt->stream_index];
         if (track->has_palette) {
             uint8_t *pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
@@ -3013,7 +3014,7 @@  static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
  */
 static void matroska_clear_queue(MatroskaDemuxContext *matroska)
 {
-    ff_packet_list_free(&matroska->queue, &matroska->queue_end);
+    avpriv_packet_list_free(&matroska->queue, &matroska->queue_end);
 }
 
 static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
@@ -3179,7 +3180,7 @@  static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
         track->audio.buf_timecode = AV_NOPTS_VALUE;
         pkt->pos                  = pos;
         pkt->stream_index         = st->index;
-        ret = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
+        ret = avpriv_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
         if (ret < 0) {
             av_packet_unref(pkt);
             return AVERROR(ENOMEM);
@@ -3401,7 +3402,7 @@  static int matroska_parse_webvtt(MatroskaDemuxContext *matroska,
     pkt->duration = duration;
     pkt->pos = pos;
 
-    err = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
+    err = avpriv_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
     if (err < 0) {
         av_packet_unref(pkt);
         return AVERROR(ENOMEM);
@@ -3512,7 +3513,7 @@  FF_DISABLE_DEPRECATION_WARNINGS
 FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
-    res = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
+    res = avpriv_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
     if (res < 0) {
         av_packet_unref(pkt);
         return AVERROR(ENOMEM);
diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
index a3586e1f86..5a0567e72f 100644
--- a/libavformat/mp3enc.c
+++ b/libavformat/mp3enc.c
@@ -28,6 +28,7 @@ 
 #include "libavcodec/mpegaudio.h"
 #include "libavcodec/mpegaudiodata.h"
 #include "libavcodec/mpegaudiodecheader.h"
+#include "libavcodec/packet_internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/opt.h"
 #include "libavutil/dict.h"
@@ -387,7 +388,7 @@  static int mp3_queue_flush(AVFormatContext *s)
     mp3_write_xing(s);
 
     while (mp3->queue) {
-        ff_packet_list_get(&mp3->queue, &mp3->queue_end, &pkt);
+        avpriv_packet_list_get(&mp3->queue, &mp3->queue_end, &pkt);
         if (write && (ret = mp3_write_audio_packet(s, &pkt)) < 0)
             write = 0;
         av_packet_unref(&pkt);
@@ -522,7 +523,7 @@  static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt)
     if (pkt->stream_index == mp3->audio_stream_idx) {
         if (mp3->pics_to_write) {
             /* buffer audio packets until we get all the pictures */
-            int ret = ff_packet_list_put(&mp3->queue, &mp3->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET);
+            int ret = avpriv_packet_list_put(&mp3->queue, &mp3->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET);
 
             if (ret < 0) {
                 av_log(s, AV_LOG_WARNING, "Not enough memory to buffer audio. Skipping picture streams\n");
@@ -630,7 +631,7 @@  static void mp3_deinit(struct AVFormatContext *s)
 {
     MP3Context *mp3 = s->priv_data;
 
-    ff_packet_list_free(&mp3->queue, &mp3->queue_end);
+    avpriv_packet_list_free(&mp3->queue, &mp3->queue_end);
     av_freep(&mp3->xing_frame);
 }
 
diff --git a/libavformat/ttaenc.c b/libavformat/ttaenc.c
index becd3e7153..589a3b334f 100644
--- a/libavformat/ttaenc.c
+++ b/libavformat/ttaenc.c
@@ -22,6 +22,7 @@ 
 #include "libavutil/crc.h"
 #include "libavutil/intreadwrite.h"
 
+#include "libavcodec/packet_internal.h"
 #include "apetag.h"
 #include "avformat.h"
 #include "avio_internal.h"
@@ -93,7 +94,7 @@  static int tta_write_packet(AVFormatContext *s, AVPacket *pkt)
     TTAMuxContext *tta = s->priv_data;
     int ret;
 
-    ret = ff_packet_list_put(&tta->queue, &tta->queue_end, pkt,
+    ret = avpriv_packet_list_put(&tta->queue, &tta->queue_end, pkt,
                              FF_PACKETLIST_FLAG_REF_PACKET);
     if (ret < 0) {
         return ret;
@@ -125,7 +126,7 @@  static void tta_queue_flush(AVFormatContext *s)
     AVPacket pkt;
 
     while (tta->queue) {
-        ff_packet_list_get(&tta->queue, &tta->queue_end, &pkt);
+        avpriv_packet_list_get(&tta->queue, &tta->queue_end, &pkt);
         avio_write(s->pb, pkt.data, pkt.size);
         av_packet_unref(&pkt);
     }
@@ -161,7 +162,7 @@  static void tta_deinit(AVFormatContext *s)
     TTAMuxContext *tta = s->priv_data;
 
     ffio_free_dyn_buf(&tta->seek_table);
-    ff_packet_list_free(&tta->queue, &tta->queue_end);
+    avpriv_packet_list_free(&tta->queue, &tta->queue_end);
 }
 
 AVOutputFormat ff_tta_muxer = {
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 807d9f10cb..b1f48d88bd 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -37,6 +37,7 @@ 
 
 #include "libavcodec/bytestream.h"
 #include "libavcodec/internal.h"
+#include "libavcodec/packet_internal.h"
 #include "libavcodec/raw.h"
 
 #include "avformat.h"
@@ -438,40 +439,6 @@  static int init_input(AVFormatContext *s, const char *filename,
                                  s, 0, s->format_probesize);
 }
 
-int ff_packet_list_put(AVPacketList **packet_buffer,
-                       AVPacketList **plast_pktl,
-                       AVPacket      *pkt, int flags)
-{
-    AVPacketList *pktl = av_mallocz(sizeof(AVPacketList));
-    int ret;
-
-    if (!pktl)
-        return AVERROR(ENOMEM);
-
-    if (flags & FF_PACKETLIST_FLAG_REF_PACKET) {
-        if ((ret = av_packet_ref(&pktl->pkt, pkt)) < 0) {
-            av_free(pktl);
-            return ret;
-        }
-    } else {
-        ret = av_packet_make_refcounted(pkt);
-        if (ret < 0) {
-            av_free(pktl);
-            return ret;
-        }
-        av_packet_move_ref(&pktl->pkt, pkt);
-    }
-
-    if (*packet_buffer)
-        (*plast_pktl)->next = pktl;
-    else
-        *packet_buffer = pktl;
-
-    /* Add the packet in the buffered packet list. */
-    *plast_pktl = pktl;
-    return 0;
-}
-
 int avformat_queue_attached_pictures(AVFormatContext *s)
 {
     int i, ret;
@@ -485,7 +452,7 @@  int avformat_queue_attached_pictures(AVFormatContext *s)
                 continue;
             }
 
-            ret = ff_packet_list_put(&s->internal->raw_packet_buffer,
+            ret = avpriv_packet_list_put(&s->internal->raw_packet_buffer,
                                      &s->internal->raw_packet_buffer_end,
                                      &s->streams[i]->attached_pic,
                                      FF_PACKETLIST_FLAG_REF_PACKET);
@@ -841,7 +808,7 @@  int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
                 if ((err = probe_codec(s, st, NULL)) < 0)
                     return err;
             if (st->request_probe <= 0) {
-                ff_packet_list_get(&s->internal->raw_packet_buffer,
+                avpriv_packet_list_get(&s->internal->raw_packet_buffer,
                                    &s->internal->raw_packet_buffer_end, pkt);
                 s->internal->raw_packet_buffer_remaining_size += pkt->size;
                 return 0;
@@ -914,7 +881,7 @@  int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
         if (!pktl && st->request_probe <= 0)
             return ret;
 
-        err = ff_packet_list_put(&s->internal->raw_packet_buffer,
+        err = avpriv_packet_list_put(&s->internal->raw_packet_buffer,
                                  &s->internal->raw_packet_buffer_end,
                                  pkt, 0);
         if (err < 0) {
@@ -1420,20 +1387,6 @@  FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 }
 
-void ff_packet_list_free(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end)
-{
-    AVPacketList *tmp = *pkt_buf;
-
-    while (tmp) {
-        AVPacketList *pktl = tmp;
-        tmp = pktl->next;
-        av_packet_unref(&pktl->pkt);
-        av_freep(&pktl);
-    }
-    *pkt_buf     = NULL;
-    *pkt_buf_end = NULL;
-}
-
 /**
  * Parse a packet, add all split parts to parse_queue.
  *
@@ -1530,7 +1483,7 @@  static int parse_packet(AVFormatContext *s, AVPacket *pkt,
 
         compute_pkt_fields(s, st, st->parser, &out_pkt, next_dts, next_pts);
 
-        ret = ff_packet_list_put(&s->internal->parse_queue,
+        ret = avpriv_packet_list_put(&s->internal->parse_queue,
                                  &s->internal->parse_queue_end,
                                  &out_pkt, 0);
         if (ret < 0) {
@@ -1550,21 +1503,6 @@  fail:
     return ret;
 }
 
-int ff_packet_list_get(AVPacketList **pkt_buffer,
-                       AVPacketList **pkt_buffer_end,
-                       AVPacket      *pkt)
-{
-    AVPacketList *pktl;
-    av_assert0(*pkt_buffer);
-    pktl        = *pkt_buffer;
-    *pkt        = pktl->pkt;
-    *pkt_buffer = pktl->next;
-    if (!pktl->next)
-        *pkt_buffer_end = NULL;
-    av_freep(&pktl);
-    return 0;
-}
-
 static int64_t ts_to_samples(AVStream *st, int64_t ts)
 {
     return av_rescale(ts, st->time_base.num * st->codecpar->sample_rate, st->time_base.den);
@@ -1695,7 +1633,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
     }
 
     if (!got_packet && s->internal->parse_queue)
-        ret = ff_packet_list_get(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt);
+        ret = avpriv_packet_list_get(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt);
 
     if (ret >= 0) {
         AVStream *st = s->streams[pkt->stream_index];
@@ -1779,7 +1717,7 @@  int av_read_frame(AVFormatContext *s, AVPacket *pkt)
 
     if (!genpts) {
         ret = s->internal->packet_buffer
-              ? ff_packet_list_get(&s->internal->packet_buffer,
+              ? avpriv_packet_list_get(&s->internal->packet_buffer,
                                         &s->internal->packet_buffer_end, pkt)
               : read_frame_internal(s, pkt);
         if (ret < 0)
@@ -1828,7 +1766,7 @@  int av_read_frame(AVFormatContext *s, AVPacket *pkt)
             st = s->streams[next_pkt->stream_index];
             if (!(next_pkt->pts == AV_NOPTS_VALUE && st->discard < AVDISCARD_ALL &&
                   next_pkt->dts != AV_NOPTS_VALUE && !eof)) {
-                ret = ff_packet_list_get(&s->internal->packet_buffer,
+                ret = avpriv_packet_list_get(&s->internal->packet_buffer,
                                                &s->internal->packet_buffer_end, pkt);
                 goto return_packet;
             }
@@ -1843,7 +1781,7 @@  int av_read_frame(AVFormatContext *s, AVPacket *pkt)
                 return ret;
         }
 
-        ret = ff_packet_list_put(&s->internal->packet_buffer,
+        ret = avpriv_packet_list_put(&s->internal->packet_buffer,
                                  &s->internal->packet_buffer_end,
                                  pkt, 0);
         if (ret < 0) {
@@ -1873,9 +1811,9 @@  static void flush_packet_queue(AVFormatContext *s)
 {
     if (!s->internal)
         return;
-    ff_packet_list_free(&s->internal->parse_queue,       &s->internal->parse_queue_end);
-    ff_packet_list_free(&s->internal->packet_buffer,     &s->internal->packet_buffer_end);
-    ff_packet_list_free(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end);
+    avpriv_packet_list_free(&s->internal->parse_queue,       &s->internal->parse_queue_end);
+    avpriv_packet_list_free(&s->internal->packet_buffer,     &s->internal->packet_buffer_end);
+    avpriv_packet_list_free(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end);
 
     s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
 }
@@ -3832,7 +3770,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
         }
 
         if (!(ic->flags & AVFMT_FLAG_NOBUFFER)) {
-            ret = ff_packet_list_put(&ic->internal->packet_buffer,
+            ret = avpriv_packet_list_put(&ic->internal->packet_buffer,
                                      &ic->internal->packet_buffer_end,
                                      &pkt1, 0);
             if (ret < 0)