FFmpeg
Loading...
Searching...
No Matches
framequeue.c
Go to the documentation of this file.
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#include "libavutil/avassert.h"
23#include "libavutil/mem.h"
24#include "framequeue.h"
25
26static inline FFFrameBucket *bucket(FFFrameQueue *fq, size_t idx)
27{
28 return &fq->queue[(fq->tail + idx) & (fq->allocated - 1)];
29}
30
32{
33 fqg->max_queued = SIZE_MAX;
34 fqg->queued = 0;
35}
36
38{
39#if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2
40 uint64_t nb_samples = 0;
41 size_t i;
42
44 for (i = 0; i < fq->queued; i++)
45 nb_samples += bucket(fq, i)->frame->nb_samples;
46 av_assert0(nb_samples == fq->total_samples_head - fq->total_samples_tail);
47#endif
48}
49
51{
52 fq->queue = &fq->first_bucket;
53 fq->allocated = 1;
54 fq->global = fqg;
55}
56
58{
59 while (fq->queued) {
62 }
63 if (fq->queue != &fq->first_bucket)
64 av_freep(&fq->queue);
65}
66
68{
70
72 if (fq->global->queued >= fq->global->max_queued)
73 return AVERROR(ENOMEM);
74 if (fq->queued == fq->allocated) {
75 if (fq->allocated == 1) {
76 size_t na = 8;
77 FFFrameBucket *nq = av_realloc_array(NULL, na, sizeof(*nq));
78 if (!nq)
79 return AVERROR(ENOMEM);
80 nq[0] = fq->queue[0];
81 fq->queue = nq;
82 fq->allocated = na;
83 } else {
84 size_t na = fq->allocated << 1;
85 FFFrameBucket *nq = av_realloc_array(fq->queue, na, sizeof(*nq));
86 if (!nq)
87 return AVERROR(ENOMEM);
88 if (fq->tail)
89 memmove(nq + fq->allocated, nq, fq->tail * sizeof(*nq));
90 fq->queue = nq;
91 fq->allocated = na;
92 }
93 }
94 b = bucket(fq, fq->queued);
95 b->frame = frame;
96 fq->queued++;
97 fq->global->queued++;
99 fq->total_samples_head += frame->nb_samples;
101 return 0;
102}
103
105{
107
109 av_assert1(fq->queued);
110 b = bucket(fq, 0);
111 fq->queued--;
112 fq->global->queued--;
113 fq->tail++;
114 fq->tail &= fq->allocated - 1;
115 fq->total_frames_tail++;
116 fq->total_samples_tail += b->frame->nb_samples;
117 fq->samples_skipped = 0;
119 return b->frame;
120}
121
123{
125
127 av_assert1(idx < fq->queued);
128 b = bucket(fq, idx);
130 return b->frame;
131}
132
133void ff_framequeue_skip_samples(FFFrameQueue *fq, size_t samples, AVRational time_base)
134{
136 size_t bytes;
137 int planar, planes, i;
138
140 av_assert1(fq->queued);
141 b = bucket(fq, 0);
142 av_assert1(samples < b->frame->nb_samples);
143 planar = av_sample_fmt_is_planar(b->frame->format);
144 planes = planar ? b->frame->ch_layout.nb_channels : 1;
145 bytes = samples * av_get_bytes_per_sample(b->frame->format);
146 if (!planar)
147 bytes *= b->frame->ch_layout.nb_channels;
148 if (b->frame->pts != AV_NOPTS_VALUE)
149 b->frame->pts += av_rescale_q(samples, av_make_q(1, b->frame->sample_rate), time_base);
150 b->frame->nb_samples -= samples;
151 b->frame->linesize[0] -= bytes;
152 for (i = 0; i < planes; i++)
153 b->frame->extended_data[i] += bytes;
154 for (i = 0; i < planes && i < AV_NUM_DATA_POINTERS; i++)
155 b->frame->data[i] = b->frame->extended_data[i];
156 fq->total_samples_tail += samples;
157 fq->samples_skipped = 1;
159}
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
static AVFrame * frame
#define AV_NUM_DATA_POINTERS
Definition frame.h:473
AVFrame * ff_framequeue_take(FFFrameQueue *fq)
Take the first frame in the queue.
Definition framequeue.c:104
void ff_framequeue_init(FFFrameQueue *fq, FFFrameQueueGlobal *fqg)
Init a frame queue and attach it to a global structure.
Definition framequeue.c:50
int ff_framequeue_add(FFFrameQueue *fq, AVFrame *frame)
Add a frame.
Definition framequeue.c:67
void ff_framequeue_free(FFFrameQueue *fq)
Free the queue and all queued frames.
Definition framequeue.c:57
void ff_framequeue_global_init(FFFrameQueueGlobal *fqg)
Init a global structure.
Definition framequeue.c:31
AVFrame * ff_framequeue_peek(FFFrameQueue *fq, size_t idx)
Access a frame in the queue, without removing it.
Definition framequeue.c:122
void ff_framequeue_skip_samples(FFFrameQueue *fq, size_t samples, AVRational time_base)
Skip samples from the first frame in the queue.
Definition framequeue.c:133
static void check_consistency(FFFrameQueue *fq)
Definition framequeue.c:37
static FFFrameBucket * bucket(FFFrameQueue *fq, size_t idx)
Definition framequeue.c:26
static void ff_framequeue_update_peeked(FFFrameQueue *fq, size_t idx)
Update the statistics after a frame accessed using ff_framequeue_peek() was modified.
Definition framequeue.h:176
#define AVERROR(e)
Definition error.h:45
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:217
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition samplefmt.c:115
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition samplefmt.c:109
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define b
Definition input.c:43
static const struct @257111027162314367033347246032313251342043035002 planes[]
Memory handling functions.
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int nb_samples
number of audio samples (per channel) described by this frame
Definition frame.h:552
Rational number (pair of numerator and denominator).
Definition rational.h:58
FFFrameQueue: simple AVFrame queue API.
Definition framequeue.h:34
AVFrame * frame
Definition framequeue.h:35
Structure to hold global options and statistics for frame queues.
Definition framequeue.h:44
size_t queued
Total number of queued frames in the queues combined.
Definition framequeue.h:54
size_t max_queued
Maximum number of allowed frames in the queues combined.
Definition framequeue.h:49
Queue of AVFrame pointers.
Definition framequeue.h:60
size_t tail
Tail of the queue.
Definition framequeue.h:81
size_t allocated
Size of the array of buckets.
Definition framequeue.h:75
FFFrameQueueGlobal * global
Pointer to the global frame queue struct holding statistics and limits.
Definition framequeue.h:65
int samples_skipped
Indicate that samples are skipped.
Definition framequeue.h:118
size_t queued
Number of currently queued frames.
Definition framequeue.h:86
uint64_t total_samples_tail
Total number of samples dequeued from the queue.
Definition framequeue.h:113
uint64_t total_samples_head
Total number of samples entered in the queue.
Definition framequeue.h:107
FFFrameBucket first_bucket
Pre-allocated bucket for queues of size 1.
Definition framequeue.h:91
uint64_t total_frames_head
Total number of frames entered in the queue.
Definition framequeue.h:96
uint64_t total_frames_tail
Total number of frames dequeued from the queue.
Definition framequeue.h:102
FFFrameBucket * queue
Array of allocated buckets, used as a circular buffer.
Definition framequeue.h:70
#define av_freep(p)