diff --git a/fftools/Makefile b/fftools/Makefile index 083a1368ce..4499799818 100644 --- a/fftools/Makefile +++ b/fftools/Makefile @@ -19,7 +19,6 @@ OBJS-ffmpeg += \ fftools/ffmpeg_mux_init.o \ fftools/ffmpeg_opt.o \ fftools/ffmpeg_sched.o \ - fftools/objpool.o \ fftools/sync_queue.o \ fftools/thread_queue.o \ diff --git a/fftools/objpool.c b/fftools/objpool.c deleted file mode 100644 index 87237cf724..0000000000 --- a/fftools/objpool.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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 "libavcodec/packet.h" - -#include "libavutil/common.h" -#include "libavutil/error.h" -#include "libavutil/frame.h" -#include "libavutil/mem.h" - -#include "objpool.h" - -struct ObjPool { - void *pool[32]; - unsigned int pool_count; - - ObjPoolCBAlloc alloc; - ObjPoolCBReset reset; - ObjPoolCBFree free; -}; - -ObjPool *objpool_alloc(ObjPoolCBAlloc cb_alloc, ObjPoolCBReset cb_reset, - ObjPoolCBFree cb_free) -{ - ObjPool *op = av_mallocz(sizeof(*op)); - - if (!op) - return NULL; - - op->alloc = cb_alloc; - op->reset = cb_reset; - op->free = cb_free; - - return op; -} - -void objpool_free(ObjPool **pop) -{ - ObjPool *op = *pop; - - if (!op) - return; - - for (unsigned int i = 0; i < op->pool_count; i++) - op->free(&op->pool[i]); - - av_freep(pop); -} - -int objpool_get(ObjPool *op, void **obj) -{ - if (op->pool_count) { - *obj = op->pool[--op->pool_count]; - op->pool[op->pool_count] = NULL; - } else - *obj = op->alloc(); - - return *obj ? 0 : AVERROR(ENOMEM); -} - -void objpool_release(ObjPool *op, void **obj) -{ - if (!*obj) - return; - - op->reset(*obj); - - if (op->pool_count < FF_ARRAY_ELEMS(op->pool)) - op->pool[op->pool_count++] = *obj; - else - op->free(obj); - - *obj = NULL; -} - -static void *alloc_packet(void) -{ - return av_packet_alloc(); -} -static void *alloc_frame(void) -{ - return av_frame_alloc(); -} - -static void reset_packet(void *obj) -{ - av_packet_unref(obj); -} -static void reset_frame(void *obj) -{ - av_frame_unref(obj); -} - -static void free_packet(void **obj) -{ - AVPacket *pkt = *obj; - av_packet_free(&pkt); - *obj = NULL; -} -static void free_frame(void **obj) -{ - AVFrame *frame = *obj; - av_frame_free(&frame); - *obj = NULL; -} - -ObjPool *objpool_alloc_packets(void) -{ - return objpool_alloc(alloc_packet, reset_packet, free_packet); -} -ObjPool *objpool_alloc_frames(void) -{ - return objpool_alloc(alloc_frame, reset_frame, free_frame); -} diff --git a/fftools/objpool.h b/fftools/objpool.h deleted file mode 100644 index 1b2aea6aca..0000000000 --- a/fftools/objpool.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 FFTOOLS_OBJPOOL_H -#define FFTOOLS_OBJPOOL_H - -typedef struct ObjPool ObjPool; - -typedef void* (*ObjPoolCBAlloc)(void); -typedef void (*ObjPoolCBReset)(void *); -typedef void (*ObjPoolCBFree)(void **); - -void objpool_free(ObjPool **op); -ObjPool *objpool_alloc(ObjPoolCBAlloc cb_alloc, ObjPoolCBReset cb_reset, - ObjPoolCBFree cb_free); -ObjPool *objpool_alloc_packets(void); -ObjPool *objpool_alloc_frames(void); - -int objpool_get(ObjPool *op, void **obj); -void objpool_release(ObjPool *op, void **obj); - -#endif // FFTOOLS_OBJPOOL_H diff --git a/fftools/sync_queue.c b/fftools/sync_queue.c index 0e35b5b1cb..fbf288c6d1 100644 --- a/fftools/sync_queue.c +++ b/fftools/sync_queue.c @@ -20,16 +20,15 @@ #include #include "libavutil/avassert.h" +#include "libavutil/container_fifo.h" #include "libavutil/channel_layout.h" #include "libavutil/cpu.h" #include "libavutil/error.h" -#include "libavutil/fifo.h" #include "libavutil/mathematics.h" #include "libavutil/mem.h" #include "libavutil/samplefmt.h" #include "libavutil/timestamp.h" -#include "objpool.h" #include "sync_queue.h" /* @@ -67,8 +66,11 @@ * frame from stream 1, and all 4 frames from stream 2. */ +#define SQPTR(sq, frame) ((sq->type == SYNC_QUEUE_FRAMES) ? \ + (void*)frame.f : (void*)frame.p) + typedef struct SyncQueueStream { - AVFifo *fifo; + AVContainerFifo *fifo; AVRational tb; /* number of audio samples in fifo */ @@ -104,23 +106,11 @@ struct SyncQueue { SyncQueueStream *streams; unsigned int nb_streams; - // pool of preallocated frames to avoid constant allocations - ObjPool *pool; - int have_limiting; uintptr_t align_mask; }; -static void frame_move(const SyncQueue *sq, SyncQueueFrame dst, - SyncQueueFrame src) -{ - if (sq->type == SYNC_QUEUE_PACKETS) - av_packet_move_ref(dst.p, src.p); - else - av_frame_move_ref(dst.f, src.f); -} - /** * Compute the end timestamp of a frame. If nb_samples is provided, consider * the frame to have this number of audio samples, otherwise use frame duration. @@ -160,7 +150,7 @@ static void tb_update(const SyncQueue *sq, SyncQueueStream *st, return; // timebase should not change after the first frame - av_assert0(!av_fifo_can_read(st->fifo)); + av_assert0(!av_container_fifo_can_read(st->fifo)); if (st->head_ts != AV_NOPTS_VALUE) st->head_ts = av_rescale_q(st->head_ts, st->tb, tb); @@ -308,7 +298,7 @@ static int overflow_heartbeat(SyncQueue *sq, int stream_idx) /* get the chosen stream's tail timestamp */ for (size_t i = 0; tail_ts == AV_NOPTS_VALUE && - av_fifo_peek(st->fifo, &frame, 1, i) >= 0; i++) + av_container_fifo_peek(st->fifo, (void**)&frame, i) >= 0; i++) tail_ts = frame_end(sq, frame, 0); /* overflow triggers when the tail is over specified duration behind the head */ @@ -343,7 +333,6 @@ static int overflow_heartbeat(SyncQueue *sq, int stream_idx) int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame) { SyncQueueStream *st; - SyncQueueFrame dst; int64_t ts; int ret, nb_samples; @@ -360,31 +349,22 @@ int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame) tb_update(sq, st, frame); - ret = objpool_get(sq->pool, (void**)&dst); - if (ret < 0) - return ret; - - frame_move(sq, dst, frame); - - nb_samples = frame_samples(sq, dst); + nb_samples = frame_samples(sq, frame); // make sure frame duration is consistent with sample count if (nb_samples) { - av_assert0(dst.f->sample_rate > 0); - dst.f->duration = av_rescale_q(nb_samples, (AVRational){ 1, dst.f->sample_rate }, - dst.f->time_base); + av_assert0(frame.f->sample_rate > 0); + frame.f->duration = av_rescale_q(nb_samples, (AVRational){ 1, frame.f->sample_rate }, + frame.f->time_base); } - ts = frame_end(sq, dst, 0); + ts = frame_end(sq, frame, 0); av_log(sq->logctx, AV_LOG_DEBUG, "sq: send %u ts %s\n", stream_idx, av_ts2timestr(ts, &st->tb)); - ret = av_fifo_write(st->fifo, &dst, 1); - if (ret < 0) { - frame_move(sq, frame, dst); - objpool_release(sq->pool, (void**)&dst); + ret = av_container_fifo_write(st->fifo, SQPTR(sq, frame), 0); + if (ret < 0) return ret; - } stream_update_ts(sq, stream_idx, ts); @@ -453,7 +433,7 @@ static int receive_samples(SyncQueue *sq, SyncQueueStream *st, av_assert0(st->samples_queued >= nb_samples); - ret = av_fifo_peek(st->fifo, &src, 1, 0); + ret = av_container_fifo_peek(st->fifo, (void**)&src, 0); av_assert0(ret >= 0); // peeked frame has enough samples and its data is aligned @@ -490,7 +470,7 @@ static int receive_samples(SyncQueue *sq, SyncQueueStream *st, while (dst->nb_samples < nb_samples) { int to_copy; - ret = av_fifo_peek(st->fifo, &src, 1, 0); + ret = av_container_fifo_peek(st->fifo, (void**)&src, 0); av_assert0(ret >= 0); to_copy = FFMIN(nb_samples - dst->nb_samples, src.f->nb_samples); @@ -500,11 +480,9 @@ static int receive_samples(SyncQueue *sq, SyncQueueStream *st, if (to_copy < src.f->nb_samples) offset_audio(src.f, to_copy); - else { - av_frame_unref(src.f); - objpool_release(sq->pool, (void**)&src); - av_fifo_drain2(st->fifo, 1); - } + else + av_container_fifo_drain(st->fifo, 1); + st->samples_queued -= to_copy; dst->nb_samples += to_copy; @@ -531,7 +509,7 @@ static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx, av_assert0(stream_idx < sq->nb_streams); st = &sq->streams[stream_idx]; - if (av_fifo_can_read(st->fifo) && + if (av_container_fifo_can_read(st->fifo) && (st->frame_samples <= st->samples_queued || st->finished)) { int nb_samples = st->frame_samples; SyncQueueFrame peek; @@ -541,7 +519,7 @@ static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx, if (st->finished) nb_samples = FFMIN(nb_samples, st->samples_queued); - av_fifo_peek(st->fifo, &peek, 1, 0); + av_container_fifo_peek(st->fifo, (void**)&peek, 0); ts = frame_end(sq, peek, nb_samples); /* check if this stream's tail timestamp does not overtake @@ -560,9 +538,9 @@ static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx, if (ret < 0) return ret; } else { - frame_move(sq, frame, peek); - objpool_release(sq->pool, (void**)&peek); - av_fifo_drain2(st->fifo, 1); + int ret = av_container_fifo_read(st->fifo, SQPTR(sq, frame), 0); + av_assert0(ret >= 0); + av_assert0(st->samples_queued >= frame_samples(sq, frame)); st->samples_queued -= frame_samples(sq, frame); } @@ -577,7 +555,7 @@ static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx, } } - return (sq->finished || (st->finished && !av_fifo_can_read(st->fifo))) ? + return (sq->finished || (st->finished && !av_container_fifo_can_read(st->fifo))) ? AVERROR_EOF : AVERROR(EAGAIN); } @@ -629,7 +607,8 @@ int sq_add_stream(SyncQueue *sq, int limiting) st = &sq->streams[sq->nb_streams]; memset(st, 0, sizeof(*st)); - st->fifo = av_fifo_alloc2(1, sizeof(SyncQueueFrame), AV_FIFO_FLAG_AUTO_GROW); + st->fifo = (sq->type == SYNC_QUEUE_FRAMES) ? + av_container_fifo_alloc_avframe(0) : av_container_fifo_alloc_avpacket(0); if (!st->fifo) return AVERROR(ENOMEM); @@ -686,13 +665,6 @@ SyncQueue *sq_alloc(enum SyncQueueType type, int64_t buf_size_us, void *logctx) sq->head_stream = -1; sq->head_finished_stream = -1; - sq->pool = (type == SYNC_QUEUE_PACKETS) ? objpool_alloc_packets() : - objpool_alloc_frames(); - if (!sq->pool) { - av_freep(&sq); - return NULL; - } - return sq; } @@ -703,17 +675,10 @@ void sq_free(SyncQueue **psq) if (!sq) return; - for (unsigned int i = 0; i < sq->nb_streams; i++) { - SyncQueueFrame frame; - while (av_fifo_read(sq->streams[i].fifo, &frame, 1) >= 0) - objpool_release(sq->pool, (void**)&frame); - - av_fifo_freep2(&sq->streams[i].fifo); - } + for (unsigned int i = 0; i < sq->nb_streams; i++) + av_container_fifo_free(&sq->streams[i].fifo); av_freep(&sq->streams); - objpool_free(&sq->pool); - av_freep(psq); }