aboutsummaryrefslogtreecommitdiffstats
path: root/libavfilter/framequeue.h
blob: c49d872e854a0cd86c6b0cdb717b8543e7b0dc93 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
 * Generic frame queue
 * Copyright (c) 2016 Nicolas George
 *
 * 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 AVFILTER_FRAMEQUEUE_H
#define AVFILTER_FRAMEQUEUE_H

/**
 * FFFrameQueue: simple AVFrame queue API
 *
 * Note: this API is not thread-safe. Concurrent access to the same queue
 * must be protected by a mutex or any synchronization mechanism.
 */

#include "libavutil/frame.h"

typedef struct FFFrameBucket {
    AVFrame *frame;
} FFFrameBucket;

/**
 * Structure to hold global options and statistics for frame queues.
 *
 * This structure is intended to allow implementing global control of the
 * frame queues, including memory consumption caps.
 *
 * It is currently empty.
 */
typedef struct FFFrameQueueGlobal {
    char dummy; /* C does not allow empty structs */
} FFFrameQueueGlobal;

/**
 * Queue of AVFrame pointers.
 */
typedef struct FFFrameQueue {

    /**
     * Array of allocated buckets, used as a circular buffer.
     */
    FFFrameBucket *queue;

    /**
     * Size of the array of buckets.
     */
    size_t allocated;

    /**
     * Tail of the queue.
     * It is the index in the array of the next frame to take.
     */
    size_t tail;

    /**
     * Number of currently queued frames.
     */
    size_t queued;

    /**
     * Pre-allocated bucket for queues of size 1.
     */
    FFFrameBucket first_bucket;

    /**
     * Total number of frames entered in the queue.
     */
    uint64_t total_frames_head;

    /**
     * Total number of frames dequeued from the queue.
     * queued = total_frames_head - total_frames_tail
     */
    uint64_t total_frames_tail;

    /**
     * Total number of samples entered in the queue.
     */
    uint64_t total_samples_head;

    /**
     * Total number of samples dequeued from the queue.
     * queued_samples = total_samples_head - total_samples_tail
     */
    uint64_t total_samples_tail;

    /**
     * Indicate that samples are skipped
     */
    int samples_skipped;

} FFFrameQueue;

/**
 * Init a global structure.
 */
void ff_framequeue_global_init(FFFrameQueueGlobal *fqg);

/**
 * Init a frame queue and attach it to a global structure.
 */
void ff_framequeue_init(FFFrameQueue *fq, FFFrameQueueGlobal *fqg);

/**
 * Free the queue and all queued frames.
 */
void ff_framequeue_free(FFFrameQueue *fq);

/**
 * Add a frame.
 * @return  >=0 or an AVERROR code.
 */
int ff_framequeue_add(FFFrameQueue *fq, AVFrame *frame);

/**
 * Take the first frame in the queue.
 * Must not be used with empty queues.
 */
AVFrame *ff_framequeue_take(FFFrameQueue *fq);

/**
 * Access a frame in the queue, without removing it.
 * The first frame is numbered 0; the designated frame must exist.
 */
AVFrame *ff_framequeue_peek(FFFrameQueue *fq, size_t idx);

/**
 * Get the number of queued frames.
 */
static inline size_t ff_framequeue_queued_frames(const FFFrameQueue *fq)
{
    return fq->queued;
}

/**
 * Get the number of queued samples.
 */
static inline uint64_t ff_framequeue_queued_samples(const FFFrameQueue *fq)
{
    return fq->total_samples_head - fq->total_samples_tail;
}

/**
 * Update the statistics after a frame accessed using ff_framequeue_peek()
 * was modified.
 * Currently used only as a marker.
 */
static inline void ff_framequeue_update_peeked(FFFrameQueue *fq, size_t idx)
{
}

/**
 * Skip samples from the first frame in the queue.
 *
 * This function must be used when the first frame was accessed using
 * ff_framequeue_peek() and samples were consumed from it.
 * It adapts the data pointers and timestamps of the head frame to account
 * for the skipped samples.
 */
void ff_framequeue_skip_samples(FFFrameQueue *fq, size_t samples, AVRational time_base);

#endif /* AVFILTER_FRAMEQUEUE_H */