blob: 5aa2c725a70cd81fcd83a8cc5227bdec91afd3f9
1 | /* |
2 | * Generic frame queue |
3 | * Copyright (c) 2016 Nicolas George |
4 | * |
5 | * This file is part of FFmpeg. |
6 | * |
7 | * FFmpeg is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Lesser General Public License |
9 | * as published by the Free Software Foundation; either |
10 | * version 2.1 of the License, or (at your option) any later version. |
11 | * |
12 | * FFmpeg is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU Lesser General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Lesser General Public License |
18 | * along with FFmpeg; if not, write to the Free Software Foundation, Inc., |
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | */ |
21 | |
22 | #ifndef AVFILTER_FRAMEQUEUE_H |
23 | #define AVFILTER_FRAMEQUEUE_H |
24 | |
25 | /** |
26 | * FFFrameQueue: simple AVFrame queue API |
27 | * |
28 | * Note: this API is not thread-safe. Concurrent access to the same queue |
29 | * must be protected by a mutex or any synchronization mechanism. |
30 | */ |
31 | |
32 | #include "libavutil/frame.h" |
33 | |
34 | typedef struct FFFrameBucket { |
35 | AVFrame *frame; |
36 | } FFFrameBucket; |
37 | |
38 | /** |
39 | * Structure to hold global options and statistics for frame queues. |
40 | * |
41 | * This structure is intended to allow implementing global control of the |
42 | * frame queues, including memory consumption caps. |
43 | * |
44 | * It is currently empty. |
45 | */ |
46 | typedef struct FFFrameQueueGlobal { |
47 | char dummy; /* C does not allow empty structs */ |
48 | } FFFrameQueueGlobal; |
49 | |
50 | /** |
51 | * Queue of AVFrame pointers. |
52 | */ |
53 | typedef struct FFFrameQueue { |
54 | |
55 | /** |
56 | * Array of allocated buckets, used as a circular buffer. |
57 | */ |
58 | FFFrameBucket *queue; |
59 | |
60 | /** |
61 | * Size of the array of buckets. |
62 | */ |
63 | size_t allocated; |
64 | |
65 | /** |
66 | * Tail of the queue. |
67 | * It is the index in the array of the next frame to take. |
68 | */ |
69 | size_t tail; |
70 | |
71 | /** |
72 | * Number of currently queued frames. |
73 | */ |
74 | size_t queued; |
75 | |
76 | /** |
77 | * Pre-allocated bucket for queues of size 1. |
78 | */ |
79 | FFFrameBucket first_bucket; |
80 | |
81 | /** |
82 | * Total number of frames entered in the queue. |
83 | */ |
84 | uint64_t total_frames_head; |
85 | |
86 | /** |
87 | * Total number of frames dequeued from the queue. |
88 | * queued = total_frames_head - total_frames_tail |
89 | */ |
90 | uint64_t total_frames_tail; |
91 | |
92 | /** |
93 | * Total number of samples entered in the queue. |
94 | */ |
95 | uint64_t total_samples_head; |
96 | |
97 | /** |
98 | * Total number of samples dequeued from the queue. |
99 | * queued_samples = total_samples_head - total_samples_tail |
100 | */ |
101 | uint64_t total_samples_tail; |
102 | |
103 | } FFFrameQueue; |
104 | |
105 | /** |
106 | * Init a global structure. |
107 | */ |
108 | void ff_framequeue_global_init(FFFrameQueueGlobal *fqg); |
109 | |
110 | /** |
111 | * Init a frame queue and attach it to a global structure. |
112 | */ |
113 | void ff_framequeue_init(FFFrameQueue *fq, FFFrameQueueGlobal *fqg); |
114 | |
115 | /** |
116 | * Free the queue and all queued frames. |
117 | */ |
118 | void ff_framequeue_free(FFFrameQueue *fq); |
119 | |
120 | /** |
121 | * Add a frame. |
122 | * @return >=0 or an AVERROR code. |
123 | */ |
124 | int ff_framequeue_add(FFFrameQueue *fq, AVFrame *frame); |
125 | |
126 | /** |
127 | * Take the first frame in the queue. |
128 | * Must not be used with empty queues. |
129 | */ |
130 | AVFrame *ff_framequeue_take(FFFrameQueue *fq); |
131 | |
132 | /** |
133 | * Access a frame in the queue, without removing it. |
134 | * The first frame is numbered 0; the designated frame must exist. |
135 | */ |
136 | AVFrame *ff_framequeue_peek(FFFrameQueue *fq, size_t idx); |
137 | |
138 | /** |
139 | * Get the number of queued frames. |
140 | */ |
141 | static inline size_t ff_framequeue_queued_frames(const FFFrameQueue *fq) |
142 | { |
143 | return fq->queued; |
144 | } |
145 | |
146 | /** |
147 | * Get the number of queued samples. |
148 | */ |
149 | static inline uint64_t ff_framequeue_queued_samples(const FFFrameQueue *fq) |
150 | { |
151 | return fq->total_samples_head - fq->total_samples_tail; |
152 | } |
153 | |
154 | /** |
155 | * Update the statistics after a frame accessed using ff_framequeue_peek() |
156 | * was modified. |
157 | * Currently used only as a marker. |
158 | */ |
159 | static inline void ff_framequeue_update_peeked(FFFrameQueue *fq, size_t idx) |
160 | { |
161 | } |
162 | |
163 | /** |
164 | * Skip samples from the first frame in the queue. |
165 | * |
166 | * This function must be used when the first frame was accessed using |
167 | * ff_framequeue_peek() and samples were consumed from it. |
168 | * It adapts the data pointers and timestamps of the head frame to account |
169 | * for the skipped samples. |
170 | */ |
171 | void ff_framequeue_skip_samples(FFFrameQueue *fq, size_t samples, AVRational time_base); |
172 | |
173 | #endif /* AVFILTER_FRAMEQUEUE_H */ |
174 |