FFmpeg
progressframe.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #ifndef AVCODEC_PROGRESSFRAME_H
22 #define AVCODEC_PROGRESSFRAME_H
23 
24 /**
25  * ProgressFrame is an API to easily share frames without an underlying
26  * av_frame_ref(). Its main usecase is in frame-threading scenarios,
27  * yet it could also be used for purely single-threaded decoders that
28  * want to keep multiple references to the same frame.
29  *
30  * The underlying principle behind the API is that all that is needed
31  * to share a frame is a reference count and a contract between all parties.
32  * The ProgressFrame provides the reference count and the frame is unreferenced
33  * via ff_thread_release_buffer() when the reference count reaches zero.
34  *
35  * In order to make this API also usable for frame-threaded decoders it also
36  * provides a way of exchanging simple information about the state of
37  * decoding the frame via ff_thread_progress_report() and
38  * ff_thread_progress_await().
39  *
40  * The typical contract for frame-threaded decoders is as follows:
41  * Thread A initializes a ProgressFrame via ff_thread_progress_get_buffer()
42  * (which already allocates the AVFrame's data buffers), calls
43  * ff_thread_finish_setup() and starts decoding the frame. Later threads
44  * receive a reference to this frame, which means they get a pointer
45  * to the AVFrame and the internal reference count gets incremented.
46  * Later threads whose frames use A's frame as reference as well as
47  * the thread that will eventually output A's frame will wait for
48  * progress on said frame reported by A. As soon as A has reported
49  * that it has finished decoding its frame, it must no longer modify it
50  * (neither its data nor its properties).
51  *
52  * Because creating a reference with this API does not involve reads
53  * from the actual AVFrame, the decoding thread may modify the properties
54  * (i.e. non-data fields) until it has indicated to be done with this
55  * frame. This is important for e.g. propagating decode_error_flags;
56  * it also allows to add side-data late.
57  */
58 
59 struct AVCodecContext;
60 
61 /**
62  * The ProgressFrame structure.
63  * Hint: It is guaranteed that the AVFrame pointer is at the start
64  * of ProgressFrame. This allows to use an unnamed
65  * union {
66  * struct {
67  * AVFrame *f;
68  * };
69  * ProgressFrame pf;
70  * };
71  * to simplify accessing the embedded AVFrame.
72  */
73 typedef struct ProgressFrame {
74  struct AVFrame *f;
77 
78 /**
79  * Notify later decoding threads when part of their reference frame is ready.
80  * Call this when some part of the frame is finished decoding.
81  * Later calls with lower values of progress have no effect.
82  *
83  * @param f The frame being decoded.
84  * @param progress Value, in arbitrary units, of how much of the frame has decoded.
85  *
86  * @warning Calling this on a blank ProgressFrame causes undefined behaviour
87  */
89 
90 /**
91  * Wait for earlier decoding threads to finish reference frames.
92  * Call this before accessing some part of a frame, with a given
93  * value for progress, and it will return after the responsible decoding
94  * thread calls ff_thread_progress_report() with the same or
95  * higher value for progress.
96  *
97  * @param f The frame being referenced.
98  * @param progress Value, in arbitrary units, to wait for.
99  *
100  * @warning Calling this on a blank ProgressFrame causes undefined behaviour
101  */
103 
104 /**
105  * This function allocates ProgressFrame.f
106  * May be called before ff_progress_frame_get_buffer() in the cases where the
107  * AVFrame needs to be accessed before the ff_thread_get_buffer() call in
108  * ff_progress_frame_alloc().
109  *
110  * @note: This must only be called by codecs with the
111  * FF_CODEC_CAP_USES_PROGRESSFRAMES internal cap.
112  */
114 
115 /**
116  * This function sets up the ProgressFrame, i.e. allocates ProgressFrame.f
117  * if needed, and also calls ff_thread_get_buffer() on the frame.
118  *
119  * @note: This must only be called by codecs with the
120  * FF_CODEC_CAP_USES_PROGRESSFRAMES internal cap.
121  * @see ff_progress_frame_alloc
122  */
124  ProgressFrame *f, int flags);
125 
126 /**
127  * Give up a reference to the underlying frame contained in a ProgressFrame
128  * and reset the ProgressFrame, setting all pointers to NULL.
129  *
130  * @note: This implies that when using this API the check for whether
131  * a frame exists is by checking ProgressFrame.f and not
132  * ProgressFrame.f->data[0] or ProgressFrame.f->buf[0].
133  */
135 
136 /**
137  * Set dst->f to src->f and make dst a co-owner of src->f.
138  * dst can then be used to wait on progress of the underlying frame.
139  *
140  * @note: There is no underlying av_frame_ref() here. dst->f and src->f
141  * really point to the same AVFrame. Typically this means that
142  * the decoding thread is allowed to set all the properties of
143  * the AVFrame until it has indicated to have finished decoding.
144  * Afterwards later threads may read all of these fields.
145  * Access to the frame's data is governed by
146  * ff_thread_progress_report/await().
147  */
149 
150 /**
151  * Do nothing if dst and src already refer to the same AVFrame;
152  * otherwise unreference dst and if src is not blank, put a reference
153  * to src's AVFrame in its place (in case src is not blank).
154  */
156 
157 #endif /* AVCODEC_PROGRESSFRAME_H */
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
ff_progress_frame_get_buffer
int ff_progress_frame_get_buffer(struct AVCodecContext *avctx, ProgressFrame *f, int flags)
This function sets up the ProgressFrame, i.e.
Definition: decode.c:1848
ff_progress_frame_report
void ff_progress_frame_report(ProgressFrame *f, int progress)
Notify later decoding threads when part of their reference frame is ready.
Definition: decode.c:1893
ProgressFrame::progress
struct ProgressInternal * progress
Definition: progressframe.h:75
ProgressInternal
Definition: decode.c:1823
f
f
Definition: af_crystalizer.c:122
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
ff_progress_frame_replace
void ff_progress_frame_replace(ProgressFrame *dst, const ProgressFrame *src)
Do nothing if dst and src already refer to the same AVFrame; otherwise unreference dst and if src is ...
Definition: decode.c:1883
ProgressInternal::progress
ThreadProgress progress
Definition: decode.c:1824
ff_progress_frame_alloc
int ff_progress_frame_alloc(struct AVCodecContext *avctx, ProgressFrame *f)
This function allocates ProgressFrame.f May be called before ff_progress_frame_get_buffer() in the ca...
Definition: decode.c:1834
ff_progress_frame_await
void ff_progress_frame_await(const ProgressFrame *f, int progress)
Wait for earlier decoding threads to finish reference frames.
Definition: decode.c:1898
ProgressFrame::f
struct AVFrame * f
Definition: progressframe.h:74
AVCodecContext
main external API structure.
Definition: avcodec.h:451
ff_progress_frame_unref
void ff_progress_frame_unref(ProgressFrame *f)
Give up a reference to the underlying frame contained in a ProgressFrame and reset the ProgressFrame,...
Definition: decode.c:1876
ProgressFrame
The ProgressFrame structure.
Definition: progressframe.h:73
ff_progress_frame_ref
void ff_progress_frame_ref(ProgressFrame *dst, const ProgressFrame *src)
Set dst->f to src->f and make dst a co-owner of src->f.
Definition: decode.c:1868
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
src
#define src
Definition: vp8dsp.c:248