From 54849fe663b21ecd456099c4d40d510fc2afe533 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 21 Jun 2026 12:39:23 +0200 Subject: [PATCH] avcodec/avformat: Unavpriv avpriv_packet_list_*() The avpriv_packet_list_put/get/free() functions and the PacketList type were implemented in libavcodec and exported via the avpriv_ mechanism solely so that libavformat (and decklink in libavdevice) could use them; libavcodec itself has no users of them. Exporting them across the library boundary has the usual drawbacks for shared builds (export/import overhead and having to keep them around for ABI stability even once unneeded). Move the implementation and the PacketList/PacketListEntry types to libavformat and rename the functions to ff_packet_list_*(). libavformat is the primary user and compiles the new packet_list.c directly; decklink, the only libavdevice user, gets a private copy for shared builds via the SHLIBOBJS scheme already used for reverse.o and ccfifo.o (static builds resolve the symbols from libavformat). AVPACKET_IS_EMPTY() and ff_side_data_set_prft() remain in libavcodec/packet_internal.h as they are libavcodec-internal. --- libavcodec/packet.c | 76 --------------------- libavcodec/packet_internal.h | 45 ------------- libavdevice/Makefile | 4 +- libavdevice/decklink_common.cpp | 6 +- libavdevice/decklink_common.h | 2 +- libavdevice/decklink_dec.cpp | 2 +- libavdevice/dshow_capture.h | 2 +- libavdevice/packet_list.c | 22 ++++++ libavdevice/vfwcap.c | 2 +- libavformat/Makefile | 1 + libavformat/aiffenc.c | 6 +- libavformat/avformat.c | 10 +-- libavformat/demux.c | 20 +++--- libavformat/demux_utils.c | 4 +- libavformat/flacenc.c | 8 +-- libavformat/internal.h | 2 +- libavformat/matroskadec.c | 12 ++-- libavformat/movenc.c | 4 +- libavformat/movenc.h | 2 +- libavformat/movenc_ttml.c | 14 ++-- libavformat/mp3enc.c | 8 +-- libavformat/mux.c | 4 +- libavformat/mxfenc.c | 4 +- libavformat/packet_internal.h | 69 +++++++++++++++++++ libavformat/packet_list.c | 114 ++++++++++++++++++++++++++++++++ libavformat/ttaenc.c | 8 +-- 26 files changed, 268 insertions(+), 183 deletions(-) create mode 100644 libavdevice/packet_list.c create mode 100644 libavformat/packet_internal.h create mode 100644 libavformat/packet_list.c diff --git a/libavcodec/packet.c b/libavcodec/packet.c index deb369ff05..49b5a814e3 100644 --- a/libavcodec/packet.c +++ b/libavcodec/packet.c @@ -545,82 +545,6 @@ void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb) pkt->duration = av_rescale_q(pkt->duration, src_tb, dst_tb); } -int avpriv_packet_list_put(PacketList *packet_buffer, - AVPacket *pkt, - int (*copy)(AVPacket *dst, const AVPacket *src), - int flags) -{ - PacketListEntry *pktl = av_malloc(sizeof(*pktl)); - unsigned int update_end_point = 1; - int ret; - - if (!pktl) - return AVERROR(ENOMEM); - - if (copy) { - get_packet_defaults(&pktl->pkt); - ret = copy(&pktl->pkt, pkt); - if (ret < 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); - } - - pktl->next = NULL; - - if (packet_buffer->head) { - if (flags & FF_PACKETLIST_FLAG_PREPEND) { - pktl->next = packet_buffer->head; - packet_buffer->head = pktl; - update_end_point = 0; - } else { - packet_buffer->tail->next = pktl; - } - } else - packet_buffer->head = pktl; - - if (update_end_point) { - /* Add the packet in the buffered packet list. */ - packet_buffer->tail = pktl; - } - - return 0; -} - -int avpriv_packet_list_get(PacketList *pkt_buffer, - AVPacket *pkt) -{ - PacketListEntry *pktl = pkt_buffer->head; - if (!pktl) - return AVERROR(EAGAIN); - *pkt = pktl->pkt; - pkt_buffer->head = pktl->next; - if (!pkt_buffer->head) - pkt_buffer->tail = NULL; - av_freep(&pktl); - return 0; -} - -void avpriv_packet_list_free(PacketList *pkt_buf) -{ - PacketListEntry *tmp = pkt_buf->head; - - while (tmp) { - PacketListEntry *pktl = tmp; - tmp = pktl->next; - av_packet_unref(&pktl->pkt); - av_freep(&pktl); - } - pkt_buf->head = pkt_buf->tail = NULL; -} - int ff_side_data_set_prft(AVPacket *pkt, int64_t timestamp) { AVProducerReferenceTime *prft; diff --git a/libavcodec/packet_internal.h b/libavcodec/packet_internal.h index 02471ed6df..dbaf744ee9 100644 --- a/libavcodec/packet_internal.h +++ b/libavcodec/packet_internal.h @@ -25,51 +25,6 @@ #define AVPACKET_IS_EMPTY(pkt) (!(pkt)->data && !(pkt)->side_data_elems) -typedef struct PacketListEntry { - struct PacketListEntry *next; - AVPacket pkt; -} PacketListEntry; - -typedef struct PacketList { - PacketListEntry *head, *tail; -} PacketList; - -#define FF_PACKETLIST_FLAG_PREPEND (1 << 0) /**< Prepend created AVPacketList instead of appending */ - -/** - * Append an AVPacket to the list. - * - * @param list A PacketList - * @param pkt The packet being appended. The data described in it will - * be made reference counted if it isn't already. - * @param copy A callback to copy the contents of the packet to the list. - May be null, in which case the packet's reference will be - moved to the list. - * @return 0 on success, negative AVERROR value on failure. On failure, - the packet and the list are unchanged. - */ -int avpriv_packet_list_put(PacketList *list, AVPacket *pkt, - int (*copy)(AVPacket *dst, const AVPacket *src), - 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 A pointer to a PacketList struct - * @param pkt Pointer to an AVPacket struct - * @return 0 on success, and a packet is returned. AVERROR(EAGAIN) if - * the list was empty. - */ -int avpriv_packet_list_get(PacketList *list, AVPacket *pkt); - -/** - * Wipe the list and unref all the packets in it. - */ -void avpriv_packet_list_free(PacketList *list); - int ff_side_data_set_prft(AVPacket *pkt, int64_t timestamp); #endif // AVCODEC_PACKET_INTERNAL_H diff --git a/libavdevice/Makefile b/libavdevice/Makefile index a226368d16..256c8e7bea 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -53,8 +53,8 @@ OBJS-$(CONFIG_LIBCDIO_INDEV) += libcdio.o OBJS-$(CONFIG_LIBDC1394_INDEV) += libdc1394.o # Objects duplicated from other libraries for shared builds -SHLIBOBJS-$(CONFIG_DECKLINK_INDEV) += reverse.o -SHLIBOBJS-$(CONFIG_DECKLINK_OUTDEV) += ccfifo.o +SHLIBOBJS-$(CONFIG_DECKLINK_INDEV) += reverse.o packet_list.o +SHLIBOBJS-$(CONFIG_DECKLINK_OUTDEV) += ccfifo.o packet_list.o # Windows resource file SHLIBOBJS-$(HAVE_GNU_WINDRES) += avdeviceres.o diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index fe187cd2c9..9d81174630 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -409,7 +409,7 @@ void ff_decklink_packet_queue_flush(DecklinkPacketQueue *q) AVPacket pkt; pthread_mutex_lock(&q->mutex); - while (avpriv_packet_list_get(&q->pkt_list, &pkt) == 0) { + while (ff_packet_list_get(&q->pkt_list, &pkt) == 0) { av_packet_unref(&pkt); } q->nb_packets = 0; @@ -452,7 +452,7 @@ int ff_decklink_packet_queue_put(DecklinkPacketQueue *q, AVPacket *pkt) pthread_mutex_lock(&q->mutex); - ret = avpriv_packet_list_put(&q->pkt_list, pkt, NULL, 0); + ret = ff_packet_list_put(&q->pkt_list, pkt, NULL, 0); if (ret == 0) { q->nb_packets++; q->size += pkt_size + sizeof(AVPacket); @@ -472,7 +472,7 @@ int ff_decklink_packet_queue_get(DecklinkPacketQueue *q, AVPacket *pkt, int bloc pthread_mutex_lock(&q->mutex); for (;; ) { - ret = avpriv_packet_list_get(&q->pkt_list, pkt); + ret = ff_packet_list_get(&q->pkt_list, pkt); if (ret == 0) { q->nb_packets--; q->size -= pkt->size + sizeof(AVPacket); diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h index 095b438bce..11430787ce 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -48,7 +48,7 @@ extern "C" { #include "libavutil/mem.h" -#include "libavcodec/packet_internal.h" +#include "libavformat/packet_internal.h" #include "libavfilter/ccfifo.h" } #include "libavutil/thread.h" diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 8830779990..d1b7a67cd6 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -39,7 +39,7 @@ extern "C" { extern "C" { #include "config.h" -#include "libavcodec/packet_internal.h" +#include "libavformat/packet_internal.h" #include "libavformat/avformat.h" #include "libavutil/avassert.h" #include "libavutil/avutil.h" diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h index bb39d4947a..056d821aa0 100644 --- a/libavdevice/dshow_capture.h +++ b/libavdevice/dshow_capture.h @@ -33,7 +33,7 @@ #include #include "libavcodec/internal.h" -#include "libavcodec/packet_internal.h" +#include "libavformat/packet_internal.h" /* EC_DEVICE_LOST is not defined in MinGW dshow headers. */ #ifndef EC_DEVICE_LOST diff --git a/libavdevice/packet_list.c b/libavdevice/packet_list.c new file mode 100644 index 0000000000..fbccf65fbd --- /dev/null +++ b/libavdevice/packet_list.c @@ -0,0 +1,22 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* decklink is the only libavdevice user of the ff_packet_list_*() API, which + * lives in libavformat; compile a private copy into libavdevice for shared + * builds (static builds resolve the symbols from libavformat). */ +#include "libavformat/packet_list.c" diff --git a/libavdevice/vfwcap.c b/libavdevice/vfwcap.c index 1fda90efa1..888436bcd2 100644 --- a/libavdevice/vfwcap.c +++ b/libavdevice/vfwcap.c @@ -25,7 +25,7 @@ #include "libavutil/opt.h" #include "libavutil/parseutils.h" -#include "libavcodec/packet_internal.h" +#include "libavformat/packet_internal.h" #include "libavformat/demux.h" #include "libavformat/internal.h" diff --git a/libavformat/Makefile b/libavformat/Makefile index 0db0c7c2a9..752436cf5f 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -27,6 +27,7 @@ OBJS = allformats.o \ nal.o \ options.o \ os_support.o \ + packet_list.o \ protocols.o \ riff.o \ sdp.o \ diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c index db65c09f11..3368e28404 100644 --- a/libavformat/aiffenc.c +++ b/libavformat/aiffenc.c @@ -23,7 +23,7 @@ #include "libavutil/intfloat.h" #include "libavutil/opt.h" -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" #include "avformat.h" #include "internal.h" #include "aiff.h" @@ -223,7 +223,7 @@ static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt) if (s->streams[pkt->stream_index]->nb_frames >= 1) return 0; - return avpriv_packet_list_put(&aiff->pict_list, pkt, NULL, 0); + return ff_packet_list_put(&aiff->pict_list, pkt, NULL, 0); } return 0; @@ -269,7 +269,7 @@ static void aiff_deinit(AVFormatContext *s) { AIFFOutputContext *aiff = s->priv_data; - avpriv_packet_list_free(&aiff->pict_list); + ff_packet_list_free(&aiff->pict_list); } #define OFFSET(x) offsetof(AIFFOutputContext, x) diff --git a/libavformat/avformat.c b/libavformat/avformat.c index 15806aa6f6..bb574e0c7b 100644 --- a/libavformat/avformat.c +++ b/libavformat/avformat.c @@ -33,7 +33,7 @@ #include "libavcodec/codec.h" #include "libavcodec/bsf.h" #include "libavcodec/codec_desc.h" -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" #include "avformat.h" #include "avformat_internal.h" #include "avio.h" @@ -138,9 +138,9 @@ void ff_flush_packet_queue(AVFormatContext *s) { FormatContextInternal *const fci = ff_fc_internal(s); FFFormatContext *const si = &fci->fc; - avpriv_packet_list_free(&fci->parse_queue); - avpriv_packet_list_free(&si->packet_buffer); - avpriv_packet_list_free(&fci->raw_packet_buffer); + ff_packet_list_free(&fci->parse_queue); + ff_packet_list_free(&si->packet_buffer); + ff_packet_list_free(&fci->raw_packet_buffer); fci->raw_packet_buffer_size = 0; } @@ -189,7 +189,7 @@ void avformat_free_context(AVFormatContext *s) av_dict_free(&si->id3v2_meta); av_packet_free(&si->pkt); av_packet_free(&si->parse_pkt); - avpriv_packet_list_free(&si->packet_buffer); + ff_packet_list_free(&si->packet_buffer); av_freep(&s->streams); av_freep(&s->stream_groups); if (s->iformat) diff --git a/libavformat/demux.c b/libavformat/demux.c index 516f286e19..193fd17739 100644 --- a/libavformat/demux.c +++ b/libavformat/demux.c @@ -39,7 +39,7 @@ #include "libavcodec/bsf.h" #include "libavcodec/codec_desc.h" #include "libavcodec/internal.h" -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" #include "libavcodec/raw.h" #include "avformat.h" @@ -603,7 +603,7 @@ static int handle_new_packet(AVFormatContext *s, AVPacket *pkt, int allow_passth if (sti->request_probe <= 0 && allow_passthrough && !fci->raw_packet_buffer.head) return 0; - err = avpriv_packet_list_put(&fci->raw_packet_buffer, pkt, NULL, 0); + err = ff_packet_list_put(&fci->raw_packet_buffer, pkt, NULL, 0); if (err < 0) { av_packet_unref(pkt); return err; @@ -650,7 +650,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if ((err = probe_codec(s, st, NULL)) < 0) return err; if (ffstream(st)->request_probe <= 0) { - avpriv_packet_list_get(&fci->raw_packet_buffer, pkt); + ff_packet_list_get(&fci->raw_packet_buffer, pkt); fci->raw_packet_buffer_size -= pkt->size; return 0; } @@ -1195,7 +1195,7 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, // Theora has valid 0-sized packets that need to be output if (st->codecpar->codec_id == AV_CODEC_ID_THEORA) { - ret = avpriv_packet_list_put(&fci->parse_queue, + ret = ff_packet_list_put(&fci->parse_queue, pkt, NULL, 0); if (ret < 0) goto fail; @@ -1303,7 +1303,7 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, compute_pkt_fields(s, st, sti->parser, out_pkt, next_dts, next_pts); - ret = avpriv_packet_list_put(&fci->parse_queue, + ret = ff_packet_list_put(&fci->parse_queue, out_pkt, NULL, 0); if (ret < 0) goto fail; @@ -1527,7 +1527,7 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) } if (!got_packet && fci->parse_queue.head) - ret = avpriv_packet_list_get(&fci->parse_queue, pkt); + ret = ff_packet_list_get(&fci->parse_queue, pkt); if (ret >= 0) { AVStream *const st = s->streams[pkt->stream_index]; @@ -1595,7 +1595,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) if (!genpts) { ret = si->packet_buffer.head - ? avpriv_packet_list_get(&si->packet_buffer, pkt) + ? ff_packet_list_get(&si->packet_buffer, pkt) : read_frame_internal(s, pkt); if (ret < 0) return ret; @@ -1643,7 +1643,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 = avpriv_packet_list_get(&si->packet_buffer, pkt); + ret = ff_packet_list_get(&si->packet_buffer, pkt); goto return_packet; } } @@ -1657,7 +1657,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) return ret; } - ret = avpriv_packet_list_put(&si->packet_buffer, + ret = ff_packet_list_put(&si->packet_buffer, pkt, NULL, 0); if (ret < 0) { av_packet_unref(pkt); @@ -2808,7 +2808,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) } if (!(ic->flags & AVFMT_FLAG_NOBUFFER)) { - ret = avpriv_packet_list_put(&si->packet_buffer, + ret = ff_packet_list_put(&si->packet_buffer, pkt1, NULL, 0); if (ret < 0) goto unref_then_goto_end; diff --git a/libavformat/demux_utils.c b/libavformat/demux_utils.c index 639fed35fd..0f22304e56 100644 --- a/libavformat/demux_utils.c +++ b/libavformat/demux_utils.c @@ -23,7 +23,7 @@ #include "libavutil/avassert.h" #include "libavcodec/bytestream.h" -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" #include "avformat.h" #include "avformat_internal.h" #include "avio_internal.h" @@ -95,7 +95,7 @@ int avformat_queue_attached_pictures(AVFormatContext *s) continue; } - ret = avpriv_packet_list_put(&fci->raw_packet_buffer, + ret = ff_packet_list_put(&fci->raw_packet_buffer, &s->streams[i]->attached_pic, av_packet_ref, 0); if (ret < 0) diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c index 711119efec..5397213fa5 100644 --- a/libavformat/flacenc.c +++ b/libavformat/flacenc.c @@ -24,7 +24,7 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavcodec/flac.h" -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" #include "avformat.h" #include "avio_internal.h" #include "flacenc.h" @@ -311,7 +311,7 @@ static int flac_queue_flush(AVFormatContext *s) write = 0; while (c->queue.head) { - avpriv_packet_list_get(&c->queue, pkt); + ff_packet_list_get(&c->queue, pkt); if (write && (ret = flac_write_audio_packet(s, pkt)) < 0) write = 0; av_packet_unref(pkt); @@ -351,7 +351,7 @@ static void flac_deinit(struct AVFormatContext *s) { FlacMuxerContext *c = s->priv_data; - avpriv_packet_list_free(&c->queue); + ff_packet_list_free(&c->queue); for (unsigned i = 0; i < s->nb_streams; i++) av_packet_free((AVPacket **)&s->streams[i]->priv_data); } @@ -364,7 +364,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 = avpriv_packet_list_put(&c->queue, pkt, NULL, 0); + ret = ff_packet_list_put(&c->queue, pkt, NULL, 0); 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 4f46c19808..a04343989b 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -23,7 +23,7 @@ #include -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" #include "avformat.h" diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 90fdb6c8ae..18849af689 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -57,7 +57,7 @@ #include "libavcodec/flac.h" #include "libavcodec/itut35.h" #include "libavcodec/mpeg4audio.h" -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" #include "avformat.h" #include "avio_internal.h" @@ -3584,7 +3584,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska, MatroskaTrack *tracks = matroska->tracks.elem; MatroskaTrack *track; - avpriv_packet_list_get(&matroska->queue, pkt); + ff_packet_list_get(&matroska->queue, 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); @@ -3606,7 +3606,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska, */ static void matroska_clear_queue(MatroskaDemuxContext *matroska) { - avpriv_packet_list_free(&matroska->queue); + ff_packet_list_free(&matroska->queue); } static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf, @@ -3772,7 +3772,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 = avpriv_packet_list_put(&matroska->queue, pkt, NULL, 0); + ret = ff_packet_list_put(&matroska->queue, pkt, NULL, 0); if (ret < 0) { av_packet_unref(pkt); return AVERROR(ENOMEM); @@ -3991,7 +3991,7 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, pkt->duration = duration; pkt->pos = pos; - err = avpriv_packet_list_put(&matroska->queue, pkt, NULL, 0); + err = ff_packet_list_put(&matroska->queue, pkt, NULL, 0); if (err < 0) { av_packet_unref(pkt); return AVERROR(ENOMEM); @@ -4255,7 +4255,7 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, pkt->pos = pos; pkt->duration = lace_duration; - res = avpriv_packet_list_put(&matroska->queue, pkt, NULL, 0); + res = ff_packet_list_put(&matroska->queue, pkt, NULL, 0); if (res < 0) { av_packet_unref(pkt); return AVERROR(ENOMEM); diff --git a/libavformat/movenc.c b/libavformat/movenc.c index d5247ad45e..66820b3c7b 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -7660,7 +7660,7 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) /* The following will reset pkt and is only allowed to be used * because we return immediately. afterwards. */ - if ((ret = avpriv_packet_list_put(&trk->squashed_packet_queue, + if ((ret = ff_packet_list_put(&trk->squashed_packet_queue, pkt, NULL, 0)) < 0) { return ret; } @@ -7960,7 +7960,7 @@ static void mov_free(AVFormatContext *s) #endif ff_isom_close_apvc(&track->apv); - avpriv_packet_list_free(&track->squashed_packet_queue); + ff_packet_list_free(&track->squashed_packet_queue); } av_freep(&mov->tracks); diff --git a/libavformat/movenc.h b/libavformat/movenc.h index 12b591b4da..5d1e7099b4 100644 --- a/libavformat/movenc.h +++ b/libavformat/movenc.h @@ -26,7 +26,7 @@ #include "avformat.h" #include "movenccenc.h" -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" #define MOV_FRAG_INFO_ALLOC_INCREMENT 64 #define MOV_INDEX_CLUSTER_SIZE 1024 diff --git a/libavformat/movenc_ttml.c b/libavformat/movenc_ttml.c index ff09c14fa2..5d6d5f71be 100644 --- a/libavformat/movenc_ttml.c +++ b/libavformat/movenc_ttml.c @@ -25,7 +25,7 @@ #include "isom.h" #include "movenc.h" #include "movenc_ttml.h" -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" static const unsigned char empty_ttml_document[] = ""; @@ -122,7 +122,7 @@ static int mov_write_ttml_document_from_queue(AVFormatContext *s, return ret; } - while (!avpriv_packet_list_get(&track->squashed_packet_queue, pkt)) { + while (!ff_packet_list_get(&track->squashed_packet_queue, pkt)) { int64_t pts_before = pkt->pts; int64_t duration_before = pkt->duration; @@ -139,7 +139,7 @@ static int mov_write_ttml_document_from_queue(AVFormatContext *s, continue; } else if (pkt->pts >= end_ts) { // starts after this fragment, put back to original queue - ret = avpriv_packet_list_put(&track->squashed_packet_queue, + ret = ff_packet_list_put(&track->squashed_packet_queue, pkt, NULL, FF_PACKETLIST_FLAG_PREPEND); if (ret < 0) @@ -160,7 +160,7 @@ static int mov_write_ttml_document_from_queue(AVFormatContext *s, // order to handle multiple subtitles at the same time. int64_t offset = end_ts - pkt->pts; - ret = avpriv_packet_list_put(&back_to_queue_list, + ret = ff_packet_list_put(&back_to_queue_list, pkt, av_packet_ref, FF_PACKETLIST_FLAG_PREPEND); if (ret < 0) @@ -216,8 +216,8 @@ static int mov_write_ttml_document_from_queue(AVFormatContext *s, cleanup: av_packet_unref(pkt); - while (!avpriv_packet_list_get(&back_to_queue_list, pkt)) { - ret = avpriv_packet_list_put(&track->squashed_packet_queue, + while (!ff_packet_list_get(&back_to_queue_list, pkt)) { + ret = ff_packet_list_put(&track->squashed_packet_queue, pkt, av_packet_ref, FF_PACKETLIST_FLAG_PREPEND); @@ -226,7 +226,7 @@ cleanup: av_packet_unref(pkt); if (ret < 0) { - avpriv_packet_list_free(&back_to_queue_list); + ff_packet_list_free(&back_to_queue_list); break; } } diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index 724c7269dc..87c13f92bd 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -30,7 +30,7 @@ #include "libavcodec/mpegaudio.h" #include "libavcodec/mpegaudiodata.h" #include "libavcodec/mpegaudiodecheader.h" -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/opt.h" #include "libavutil/dict.h" @@ -389,7 +389,7 @@ static int mp3_queue_flush(AVFormatContext *s) mp3_write_xing(s); while (mp3->queue.head) { - avpriv_packet_list_get(&mp3->queue, pkt); + ff_packet_list_get(&mp3->queue, pkt); if (write && (ret = mp3_write_audio_packet(s, pkt)) < 0) write = 0; av_packet_unref(pkt); @@ -531,7 +531,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 = avpriv_packet_list_put(&mp3->queue, pkt, NULL, 0); + int ret = ff_packet_list_put(&mp3->queue, pkt, NULL, 0); if (ret < 0) { av_log(s, AV_LOG_WARNING, "Not enough memory to buffer audio. Skipping picture streams\n"); @@ -639,7 +639,7 @@ static void mp3_deinit(struct AVFormatContext *s) { MP3Context *mp3 = s->priv_data; - avpriv_packet_list_free(&mp3->queue); + ff_packet_list_free(&mp3->queue); av_freep(&mp3->xing_frame); } diff --git a/libavformat/mux.c b/libavformat/mux.c index 363e5e1a57..ea9838e380 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -27,7 +27,7 @@ #include "libavcodec/bsf.h" #include "libavcodec/codec_desc.h" #include "libavcodec/internal.h" -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" #include "libavutil/mem.h" #include "libavutil/opt.h" #include "libavutil/dict.h" @@ -1010,7 +1010,7 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *pkt, if (sti->last_in_packet_buffer == pktl) sti->last_in_packet_buffer = NULL; - avpriv_packet_list_get(&si->packet_buffer, pkt); + ff_packet_list_get(&si->packet_buffer, pkt); return 1; } else { diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 1552d24e0c..48043a7d47 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -55,7 +55,7 @@ #include "libavcodec/golomb.h" #include "libavcodec/h264.h" #include "libavcodec/jpeg2000.h" -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" #include "libavcodec/rangecoder.h" #include "libavcodec/startcode.h" #include "avformat.h" @@ -3596,7 +3596,7 @@ static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, int flus if (ffstream(s->streams[pktl->pkt.stream_index])->last_in_packet_buffer == pktl) ffstream(s->streams[pktl->pkt.stream_index])->last_in_packet_buffer = NULL; - avpriv_packet_list_get(&si->packet_buffer, out); + ff_packet_list_get(&si->packet_buffer, out); av_log(s, AV_LOG_TRACE, "out st:%d dts:%"PRId64"\n", out->stream_index, out->dts); return 1; } else { diff --git a/libavformat/packet_internal.h b/libavformat/packet_internal.h new file mode 100644 index 0000000000..1f6ab56a4f --- /dev/null +++ b/libavformat/packet_internal.h @@ -0,0 +1,69 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFORMAT_PACKET_INTERNAL_H +#define AVFORMAT_PACKET_INTERNAL_H + +#include "libavcodec/packet.h" + +typedef struct PacketListEntry { + struct PacketListEntry *next; + AVPacket pkt; +} PacketListEntry; + +typedef struct PacketList { + PacketListEntry *head, *tail; +} PacketList; + +#define FF_PACKETLIST_FLAG_PREPEND (1 << 0) /**< Prepend created AVPacketList instead of appending */ + +/** + * Append an AVPacket to the list. + * + * @param list A PacketList + * @param pkt The packet being appended. The data described in it will + * be made reference counted if it isn't already. + * @param copy A callback to copy the contents of the packet to the list. + May be null, in which case the packet's reference will be + moved to the list. + * @return 0 on success, negative AVERROR value on failure. On failure, + the packet and the list are unchanged. + */ +int ff_packet_list_put(PacketList *list, AVPacket *pkt, + int (*copy)(AVPacket *dst, const AVPacket *src), + 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 A pointer to a PacketList struct + * @param pkt Pointer to an AVPacket struct + * @return 0 on success, and a packet is returned. AVERROR(EAGAIN) if + * the list was empty. + */ +int ff_packet_list_get(PacketList *list, AVPacket *pkt); + +/** + * Wipe the list and unref all the packets in it. + */ +void ff_packet_list_free(PacketList *list); + +#endif // AVFORMAT_PACKET_INTERNAL_H diff --git a/libavformat/packet_list.c b/libavformat/packet_list.c new file mode 100644 index 0000000000..13c0552af6 --- /dev/null +++ b/libavformat/packet_list.c @@ -0,0 +1,114 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/avutil.h" +#include "libavutil/error.h" +#include "libavutil/mem.h" +#include "libavutil/rational.h" + +#include "libavcodec/packet.h" + +#include "packet_internal.h" + +static void get_packet_defaults(AVPacket *pkt) +{ + memset(pkt, 0, sizeof(*pkt)); + + pkt->pts = AV_NOPTS_VALUE; + pkt->dts = AV_NOPTS_VALUE; + pkt->pos = -1; + pkt->time_base = av_make_q(0, 1); +} + +int ff_packet_list_put(PacketList *packet_buffer, + AVPacket *pkt, + int (*copy)(AVPacket *dst, const AVPacket *src), + int flags) +{ + PacketListEntry *pktl = av_malloc(sizeof(*pktl)); + unsigned int update_end_point = 1; + int ret; + + if (!pktl) + return AVERROR(ENOMEM); + + if (copy) { + get_packet_defaults(&pktl->pkt); + ret = copy(&pktl->pkt, pkt); + if (ret < 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); + } + + pktl->next = NULL; + + if (packet_buffer->head) { + if (flags & FF_PACKETLIST_FLAG_PREPEND) { + pktl->next = packet_buffer->head; + packet_buffer->head = pktl; + update_end_point = 0; + } else { + packet_buffer->tail->next = pktl; + } + } else + packet_buffer->head = pktl; + + if (update_end_point) { + /* Add the packet in the buffered packet list. */ + packet_buffer->tail = pktl; + } + + return 0; +} + +int ff_packet_list_get(PacketList *pkt_buffer, + AVPacket *pkt) +{ + PacketListEntry *pktl = pkt_buffer->head; + if (!pktl) + return AVERROR(EAGAIN); + *pkt = pktl->pkt; + pkt_buffer->head = pktl->next; + if (!pkt_buffer->head) + pkt_buffer->tail = NULL; + av_freep(&pktl); + return 0; +} + +void ff_packet_list_free(PacketList *pkt_buf) +{ + PacketListEntry *tmp = pkt_buf->head; + + while (tmp) { + PacketListEntry *pktl = tmp; + tmp = pktl->next; + av_packet_unref(&pktl->pkt); + av_freep(&pktl); + } + pkt_buf->head = pkt_buf->tail = NULL; +} diff --git a/libavformat/ttaenc.c b/libavformat/ttaenc.c index efc5aac88c..b7eb2c5130 100644 --- a/libavformat/ttaenc.c +++ b/libavformat/ttaenc.c @@ -22,7 +22,7 @@ #include "libavutil/crc.h" #include "libavutil/intreadwrite.h" -#include "libavcodec/packet_internal.h" +#include "packet_internal.h" #include "apetag.h" #include "avformat.h" #include "avio_internal.h" @@ -89,7 +89,7 @@ static int tta_write_packet(AVFormatContext *s, AVPacket *pkt) TTAMuxContext *tta = s->priv_data; int ret; - ret = avpriv_packet_list_put(&tta->queue, pkt, NULL, 0); + ret = ff_packet_list_put(&tta->queue, pkt, NULL, 0); if (ret < 0) { return ret; } @@ -121,7 +121,7 @@ static void tta_queue_flush(AVFormatContext *s) AVPacket *const pkt = ffformatcontext(s)->pkt; while (tta->queue.head) { - avpriv_packet_list_get(&tta->queue, pkt); + ff_packet_list_get(&tta->queue, pkt); avio_write(s->pb, pkt->data, pkt->size); av_packet_unref(pkt); } @@ -157,7 +157,7 @@ static void tta_deinit(AVFormatContext *s) TTAMuxContext *tta = s->priv_data; ffio_free_dyn_buf(&tta->seek_table); - avpriv_packet_list_free(&tta->queue); + ff_packet_list_free(&tta->queue); } const FFOutputFormat ff_tta_muxer = {