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 sets up the ProgressFrame, i.e. gets ProgressFrame.f
106  * and also calls ff_thread_get_buffer() on the frame.
107  *
108  * @note: This must only be called by codecs with the
109  * FF_CODEC_CAP_USES_PROGRESSFRAMES internal cap.
110  */
112  ProgressFrame *f, int flags);
113 
114 /**
115  * Give up a reference to the underlying frame contained in a ProgressFrame
116  * and reset the ProgressFrame, setting all pointers to NULL.
117  *
118  * @note: This implies that when using this API the check for whether
119  * a frame exists is by checking ProgressFrame.f and not
120  * ProgressFrame.f->data[0] or ProgressFrame.f->buf[0].
121  */
123 
124 /**
125  * Set dst->f to src->f and make dst a co-owner of src->f.
126  * dst can then be used to wait on progress of the underlying frame.
127  *
128  * @note: There is no underlying av_frame_ref() here. dst->f and src->f
129  * really point to the same AVFrame. Typically this means that
130  * the decoding thread is allowed to set all the properties of
131  * the AVFrame until it has indicated to have finished decoding.
132  * Afterwards later threads may read all of these fields.
133  * Access to the frame's data is governed by
134  * ff_thread_progress_report/await().
135  */
137 
138 /**
139  * Do nothing if dst and src already refer to the same AVFrame;
140  * otherwise unreference dst and if src is not blank, put a reference
141  * to src's AVFrame in its place (in case src is not blank).
142  */
144 
145 #endif /* AVCODEC_PROGRESSFRAME_H */
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
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:1698
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:1740
ProgressFrame::progress
struct ProgressInternal * progress
Definition: progressframe.h:75
ProgressInternal
Definition: decode.c:1673
f
f
Definition: af_crystalizer.c:121
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:1730
ProgressInternal::progress
ThreadProgress progress
Definition: decode.c:1674
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:1745
ProgressFrame::f
struct AVFrame * f
Definition: progressframe.h:74
AVCodecContext
main external API structure.
Definition: avcodec.h:445
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:1723
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:1715
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474