History

fftools/sync_queue: switch from AVFifo+ObjPool to AVContainerFifo

Remove now-unused objpool.

Anton Khirnov committed 1 year ago

Commit 8ad34e91 parent 8e0ccef4 files · +29 −233Browse files

Unified · Split

4 files
  1. fftools/Makefile +0 −1
  2. fftools/objpool.c +0 −131
  3. fftools/objpool.h +0 −37
  4. fftools/sync_queue.c +29 −64
fftools/Makefile+0−1
@@ -19,7 +19,6 @@ OBJS-ffmpeg += \ · 18 unmodified lines
19 fftools/ffmpeg_mux_init.o \19 fftools/ffmpeg_mux_init.o \
20 fftools/ffmpeg_opt.o \20 fftools/ffmpeg_opt.o \
21 fftools/ffmpeg_sched.o \21 fftools/ffmpeg_sched.o \
22 fftools/objpool.o \
23 fftools/sync_queue.o \22 fftools/sync_queue.o \
24 fftools/thread_queue.o \23 fftools/thread_queue.o \
25 24
fftools/objpool.c+0−131
@@ -1,131 +0,0 @@
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include <stdint.h>
20
21#include "libavcodec/packet.h"
22
23#include "libavutil/common.h"
24#include "libavutil/error.h"
25#include "libavutil/frame.h"
26#include "libavutil/mem.h"
27
28#include "objpool.h"
29
30struct ObjPool {
31 void *pool[32];
32 unsigned int pool_count;
33
34 ObjPoolCBAlloc alloc;
35 ObjPoolCBReset reset;
36 ObjPoolCBFree free;
37};
38
39ObjPool *objpool_alloc(ObjPoolCBAlloc cb_alloc, ObjPoolCBReset cb_reset,
40 ObjPoolCBFree cb_free)
41{
42 ObjPool *op = av_mallocz(sizeof(*op));
43
44 if (!op)
45 return NULL;
46
47 op->alloc = cb_alloc;
48 op->reset = cb_reset;
49 op->free = cb_free;
50
51 return op;
52}
53
54void objpool_free(ObjPool **pop)
55{
56 ObjPool *op = *pop;
57
58 if (!op)
59 return;
60
61 for (unsigned int i = 0; i < op->pool_count; i++)
62 op->free(&op->pool[i]);
63
64 av_freep(pop);
65}
66
67int objpool_get(ObjPool *op, void **obj)
68{
69 if (op->pool_count) {
70 *obj = op->pool[--op->pool_count];
71 op->pool[op->pool_count] = NULL;
72 } else
73 *obj = op->alloc();
74
75 return *obj ? 0 : AVERROR(ENOMEM);
76}
77
78void objpool_release(ObjPool *op, void **obj)
79{
80 if (!*obj)
81 return;
82
83 op->reset(*obj);
84
85 if (op->pool_count < FF_ARRAY_ELEMS(op->pool))
86 op->pool[op->pool_count++] = *obj;
87 else
88 op->free(obj);
89
90 *obj = NULL;
91}
92
93static void *alloc_packet(void)
94{
95 return av_packet_alloc();
96}
97static void *alloc_frame(void)
98{
99 return av_frame_alloc();
100}
101
102static void reset_packet(void *obj)
103{
104 av_packet_unref(obj);
105}
106static void reset_frame(void *obj)
107{
108 av_frame_unref(obj);
109}
110
111static void free_packet(void **obj)
112{
113 AVPacket *pkt = *obj;
114 av_packet_free(&pkt);
115 *obj = NULL;
116}
117static void free_frame(void **obj)
118{
119 AVFrame *frame = *obj;
120 av_frame_free(&frame);
121 *obj = NULL;
122}
123
124ObjPool *objpool_alloc_packets(void)
125{
126 return objpool_alloc(alloc_packet, reset_packet, free_packet);
127}
128ObjPool *objpool_alloc_frames(void)
129{
130 return objpool_alloc(alloc_frame, reset_frame, free_frame);
131}
fftools/objpool.h+0−37
@@ -1,37 +0,0 @@
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#ifndef FFTOOLS_OBJPOOL_H
20#define FFTOOLS_OBJPOOL_H
21
22typedef struct ObjPool ObjPool;
23
24typedef void* (*ObjPoolCBAlloc)(void);
25typedef void (*ObjPoolCBReset)(void *);
26typedef void (*ObjPoolCBFree)(void **);
27
28void objpool_free(ObjPool **op);
29ObjPool *objpool_alloc(ObjPoolCBAlloc cb_alloc, ObjPoolCBReset cb_reset,
30 ObjPoolCBFree cb_free);
31ObjPool *objpool_alloc_packets(void);
32ObjPool *objpool_alloc_frames(void);
33
34int objpool_get(ObjPool *op, void **obj);
35void objpool_release(ObjPool *op, void **obj);
36
37#endif // FFTOOLS_OBJPOOL_H
fftools/sync_queue.c+29−64
@@ -20,16 +20,15 @@ · 19 unmodified lines
20#include <string.h>20#include <string.h>
21 21
22#include "libavutil/avassert.h"22#include "libavutil/avassert.h"
23#include "libavutil/container_fifo.h"
23#include "libavutil/channel_layout.h"24#include "libavutil/channel_layout.h"
24#include "libavutil/cpu.h"25#include "libavutil/cpu.h"
25#include "libavutil/error.h"26#include "libavutil/error.h"
26#include "libavutil/fifo.h"
27#include "libavutil/mathematics.h"27#include "libavutil/mathematics.h"
28#include "libavutil/mem.h"28#include "libavutil/mem.h"
29#include "libavutil/samplefmt.h"29#include "libavutil/samplefmt.h"
30#include "libavutil/timestamp.h"30#include "libavutil/timestamp.h"
31 31
32#include "objpool.h"
33#include "sync_queue.h"32#include "sync_queue.h"
34 33
35/*34/*
@@ -67,8 +66,11 @@ · 31 unmodified lines
67 * frame from stream 1, and all 4 frames from stream 2.66 * frame from stream 1, and all 4 frames from stream 2.
68 */67 */
69 68
69#define SQPTR(sq, frame) ((sq->type == SYNC_QUEUE_FRAMES) ? \
70 (void*)frame.f : (void*)frame.p)
71
70typedef struct SyncQueueStream {72typedef struct SyncQueueStream {
71 AVFifo *fifo;73 AVContainerFifo *fifo;
72 AVRational tb;74 AVRational tb;
73 75
74 /* number of audio samples in fifo */76 /* number of audio samples in fifo */
@@ -104,23 +106,11 @@ struct SyncQueue { · 29 unmodified lines
104 SyncQueueStream *streams;106 SyncQueueStream *streams;
105 unsigned int nb_streams;107 unsigned int nb_streams;
106 108
107 // pool of preallocated frames to avoid constant allocations
108 ObjPool *pool;
109
110 int have_limiting;109 int have_limiting;
111 110
112 uintptr_t align_mask;111 uintptr_t align_mask;
113};112};
114 113
115static void frame_move(const SyncQueue *sq, SyncQueueFrame dst,
116 SyncQueueFrame src)
117{
118 if (sq->type == SYNC_QUEUE_PACKETS)
119 av_packet_move_ref(dst.p, src.p);
120 else
121 av_frame_move_ref(dst.f, src.f);
122}
123
124/**114/**
125 * Compute the end timestamp of a frame. If nb_samples is provided, consider115 * Compute the end timestamp of a frame. If nb_samples is provided, consider
126 * the frame to have this number of audio samples, otherwise use frame duration.116 * 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, · 33 unmodified lines
160 return;150 return;
161 151
162 // timebase should not change after the first frame152 // timebase should not change after the first frame
163 av_assert0(!av_fifo_can_read(st->fifo));153 av_assert0(!av_container_fifo_can_read(st->fifo));
164 154
165 if (st->head_ts != AV_NOPTS_VALUE)155 if (st->head_ts != AV_NOPTS_VALUE)
166 st->head_ts = av_rescale_q(st->head_ts, st->tb, tb);156 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) · 141 unmodified lines
308 298
309 /* get the chosen stream's tail timestamp */299 /* get the chosen stream's tail timestamp */
310 for (size_t i = 0; tail_ts == AV_NOPTS_VALUE &&300 for (size_t i = 0; tail_ts == AV_NOPTS_VALUE &&
311 av_fifo_peek(st->fifo, &frame, 1, i) >= 0; i++)301 av_container_fifo_peek(st->fifo, (void**)&frame, i) >= 0; i++)
312 tail_ts = frame_end(sq, frame, 0);302 tail_ts = frame_end(sq, frame, 0);
313 303
314 /* overflow triggers when the tail is over specified duration behind the head */304 /* 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) · 28 unmodified lines
343int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame)333int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame)
344{334{
345 SyncQueueStream *st;335 SyncQueueStream *st;
346 SyncQueueFrame dst;
347 int64_t ts;336 int64_t ts;
348 int ret, nb_samples;337 int ret, nb_samples;
349 338
@@ -360,31 +349,22 @@ int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame) · 10 unmodified lines
360 349
361 tb_update(sq, st, frame);350 tb_update(sq, st, frame);
362 351
363 ret = objpool_get(sq->pool, (void**)&dst);352 nb_samples = frame_samples(sq, frame);
364 if (ret < 0)
365 return ret;
366
367 frame_move(sq, dst, frame);
368
369 nb_samples = frame_samples(sq, dst);
370 // make sure frame duration is consistent with sample count353 // make sure frame duration is consistent with sample count
371 if (nb_samples) {354 if (nb_samples) {
372 av_assert0(dst.f->sample_rate > 0);355 av_assert0(frame.f->sample_rate > 0);
373 dst.f->duration = av_rescale_q(nb_samples, (AVRational){ 1, dst.f->sample_rate },356 frame.f->duration = av_rescale_q(nb_samples, (AVRational){ 1, frame.f->sample_rate },
374 dst.f->time_base);357 frame.f->time_base);
375 }358 }
376 359
377 ts = frame_end(sq, dst, 0);360 ts = frame_end(sq, frame, 0);
378 361
379 av_log(sq->logctx, AV_LOG_DEBUG, "sq: send %u ts %s\n", stream_idx,362 av_log(sq->logctx, AV_LOG_DEBUG, "sq: send %u ts %s\n", stream_idx,
380 av_ts2timestr(ts, &st->tb));363 av_ts2timestr(ts, &st->tb));
381 364
382 ret = av_fifo_write(st->fifo, &dst, 1);365 ret = av_container_fifo_write(st->fifo, SQPTR(sq, frame), 0);
383 if (ret < 0) {366 if (ret < 0)
384 frame_move(sq, frame, dst);
385 objpool_release(sq->pool, (void**)&dst);
386 return ret;367 return ret;
387 }
388 368
389 stream_update_ts(sq, stream_idx, ts);369 stream_update_ts(sq, stream_idx, ts);
390 370
@@ -453,7 +433,7 @@ static int receive_samples(SyncQueue *sq, SyncQueueStream *st, · 62 unmodified lines
453 433
454 av_assert0(st->samples_queued >= nb_samples);434 av_assert0(st->samples_queued >= nb_samples);
455 435
456 ret = av_fifo_peek(st->fifo, &src, 1, 0);436 ret = av_container_fifo_peek(st->fifo, (void**)&src, 0);
457 av_assert0(ret >= 0);437 av_assert0(ret >= 0);
458 438
459 // peeked frame has enough samples and its data is aligned439 // peeked frame has enough samples and its data is aligned
@@ -490,7 +470,7 @@ static int receive_samples(SyncQueue *sq, SyncQueueStream *st, · 30 unmodified lines
490 while (dst->nb_samples < nb_samples) {470 while (dst->nb_samples < nb_samples) {
491 int to_copy;471 int to_copy;
492 472
493 ret = av_fifo_peek(st->fifo, &src, 1, 0);473 ret = av_container_fifo_peek(st->fifo, (void**)&src, 0);
494 av_assert0(ret >= 0);474 av_assert0(ret >= 0);
495 475
496 to_copy = FFMIN(nb_samples - dst->nb_samples, src.f->nb_samples);476 to_copy = FFMIN(nb_samples - dst->nb_samples, src.f->nb_samples);
@@ -500,11 +480,9 @@ static int receive_samples(SyncQueue *sq, SyncQueueStream *st, · 3 unmodified lines
500 480
501 if (to_copy < src.f->nb_samples)481 if (to_copy < src.f->nb_samples)
502 offset_audio(src.f, to_copy);482 offset_audio(src.f, to_copy);
503 else {483 else
504 av_frame_unref(src.f);484 av_container_fifo_drain(st->fifo, 1);
505 objpool_release(sq->pool, (void**)&src);485
506 av_fifo_drain2(st->fifo, 1);
507 }
508 st->samples_queued -= to_copy;486 st->samples_queued -= to_copy;
509 487
510 dst->nb_samples += to_copy;488 dst->nb_samples += to_copy;
@@ -531,7 +509,7 @@ static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx, · 20 unmodified lines
531 av_assert0(stream_idx < sq->nb_streams);509 av_assert0(stream_idx < sq->nb_streams);
532 st = &sq->streams[stream_idx];510 st = &sq->streams[stream_idx];
533 511
534 if (av_fifo_can_read(st->fifo) &&512 if (av_container_fifo_can_read(st->fifo) &&
535 (st->frame_samples <= st->samples_queued || st->finished)) {513 (st->frame_samples <= st->samples_queued || st->finished)) {
536 int nb_samples = st->frame_samples;514 int nb_samples = st->frame_samples;
537 SyncQueueFrame peek;515 SyncQueueFrame peek;
@@ -541,7 +519,7 @@ static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx, · 3 unmodified lines
541 if (st->finished)519 if (st->finished)
542 nb_samples = FFMIN(nb_samples, st->samples_queued);520 nb_samples = FFMIN(nb_samples, st->samples_queued);
543 521
544 av_fifo_peek(st->fifo, &peek, 1, 0);522 av_container_fifo_peek(st->fifo, (void**)&peek, 0);
545 ts = frame_end(sq, peek, nb_samples);523 ts = frame_end(sq, peek, nb_samples);
546 524
547 /* check if this stream's tail timestamp does not overtake525 /* 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, · 12 unmodified lines
560 if (ret < 0)538 if (ret < 0)
561 return ret;539 return ret;
562 } else {540 } else {
563 frame_move(sq, frame, peek);541 int ret = av_container_fifo_read(st->fifo, SQPTR(sq, frame), 0);
564 objpool_release(sq->pool, (void**)&peek);542 av_assert0(ret >= 0);
565 av_fifo_drain2(st->fifo, 1);543
566 av_assert0(st->samples_queued >= frame_samples(sq, frame));544 av_assert0(st->samples_queued >= frame_samples(sq, frame));
567 st->samples_queued -= frame_samples(sq, frame);545 st->samples_queued -= frame_samples(sq, frame);
568 }546 }
@@ -577,7 +555,7 @@ static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx, · 8 unmodified lines
577 }555 }
578 }556 }
579 557
580 return (sq->finished || (st->finished && !av_fifo_can_read(st->fifo))) ?558 return (sq->finished || (st->finished && !av_container_fifo_can_read(st->fifo))) ?
581 AVERROR_EOF : AVERROR(EAGAIN);559 AVERROR_EOF : AVERROR(EAGAIN);
582}560}
583 561
@@ -629,7 +607,8 @@ int sq_add_stream(SyncQueue *sq, int limiting) · 45 unmodified lines
629 st = &sq->streams[sq->nb_streams];607 st = &sq->streams[sq->nb_streams];
630 memset(st, 0, sizeof(*st));608 memset(st, 0, sizeof(*st));
631 609
632 st->fifo = av_fifo_alloc2(1, sizeof(SyncQueueFrame), AV_FIFO_FLAG_AUTO_GROW);610 st->fifo = (sq->type == SYNC_QUEUE_FRAMES) ?
611 av_container_fifo_alloc_avframe(0) : av_container_fifo_alloc_avpacket(0);
633 if (!st->fifo)612 if (!st->fifo)
634 return AVERROR(ENOMEM);613 return AVERROR(ENOMEM);
635 614
@@ -686,13 +665,6 @@ SyncQueue *sq_alloc(enum SyncQueueType type, int64_t buf_size_us, void *logctx) · 50 unmodified lines
686 sq->head_stream = -1;665 sq->head_stream = -1;
687 sq->head_finished_stream = -1;666 sq->head_finished_stream = -1;
688 667
689 sq->pool = (type == SYNC_QUEUE_PACKETS) ? objpool_alloc_packets() :
690 objpool_alloc_frames();
691 if (!sq->pool) {
692 av_freep(&sq);
693 return NULL;
694 }
695
696 return sq;668 return sq;
697}669}
698 670
@@ -703,17 +675,10 @@ void sq_free(SyncQueue **psq) · 4 unmodified lines
703 if (!sq)675 if (!sq)
704 return;676 return;
705 677
706 for (unsigned int i = 0; i < sq->nb_streams; i++) {678 for (unsigned int i = 0; i < sq->nb_streams; i++)
707 SyncQueueFrame frame;679 av_container_fifo_free(&sq->streams[i].fifo);
708 while (av_fifo_read(sq->streams[i].fifo, &frame, 1) >= 0)
709 objpool_release(sq->pool, (void**)&frame);
710
711 av_fifo_freep2(&sq->streams[i].fifo);
712 }
713 680
714 av_freep(&sq->streams);681 av_freep(&sq->streams);
715 682
716 objpool_free(&sq->pool);
717
718 av_freep(psq);683 av_freep(psq);
719}684}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t