FFmpeg  4.2.3
f_sidedata.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /**
20  * @file
21  * filter for manipulating frame side data
22  */
23 
24 #include "libavutil/avassert.h"
25 #include "libavutil/internal.h"
26 #include "libavutil/frame.h"
27 #include "libavutil/opt.h"
28 #include "avfilter.h"
29 #include "formats.h"
30 #include "internal.h"
31 
36 };
37 
38 typedef struct SideDataContext {
39  const AVClass *class;
40 
41  int mode;
44 
45 #define OFFSET(x) offsetof(SideDataContext, x)
46 #if FF_API_FRAME_QP
47 #define DEFINE_OPTIONS(filt_name, FLAGS) \
48 static const AVOption filt_name##_options[] = { \
49  { "mode", "set a mode of operation", OFFSET(mode), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, SIDEDATA_NB-1, FLAGS, "mode" }, \
50  { "select", "select frame", 0, AV_OPT_TYPE_CONST, {.i64 = SIDEDATA_SELECT }, 0, 0, FLAGS, "mode" }, \
51  { "delete", "delete side data", 0, AV_OPT_TYPE_CONST, {.i64 = SIDEDATA_DELETE }, 0, 0, FLAGS, "mode" }, \
52  { "type", "set side data type", OFFSET(type), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, INT_MAX, FLAGS, "type" }, \
53  { "PANSCAN", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_PANSCAN }, 0, 0, FLAGS, "type" }, \
54  { "A53_CC", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_A53_CC }, 0, 0, FLAGS, "type" }, \
55  { "STEREO3D", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_STEREO3D }, 0, 0, FLAGS, "type" }, \
56  { "MATRIXENCODING", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_MATRIXENCODING }, 0, 0, FLAGS, "type" }, \
57  { "DOWNMIX_INFO", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_DOWNMIX_INFO }, 0, 0, FLAGS, "type" }, \
58  { "REPLAYGAIN", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_REPLAYGAIN }, 0, 0, FLAGS, "type" }, \
59  { "DISPLAYMATRIX", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_DISPLAYMATRIX }, 0, 0, FLAGS, "type" }, \
60  { "AFD", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_AFD }, 0, 0, FLAGS, "type" }, \
61  { "MOTION_VECTORS", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_MOTION_VECTORS }, 0, 0, FLAGS, "type" }, \
62  { "SKIP_SAMPLES", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_SKIP_SAMPLES }, 0, 0, FLAGS, "type" }, \
63  { "AUDIO_SERVICE_TYPE", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, 0, 0, FLAGS, "type" }, \
64  { "MASTERING_DISPLAY_METADATA", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_MASTERING_DISPLAY_METADATA }, 0, 0, FLAGS, "type" }, \
65  { "GOP_TIMECODE", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_GOP_TIMECODE }, 0, 0, FLAGS, "type" }, \
66  { "SPHERICAL", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_SPHERICAL }, 0, 0, FLAGS, "type" }, \
67  { "CONTENT_LIGHT_LEVEL", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_CONTENT_LIGHT_LEVEL }, 0, 0, FLAGS, "type" }, \
68  { "ICC_PROFILE", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_ICC_PROFILE }, 0, 0, FLAGS, "type" }, \
69  { "QP_TABLE_PROPERTIES", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_QP_TABLE_PROPERTIES }, 0, 0, FLAGS, "type" }, \
70  { "QP_TABLE_DATA", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_QP_TABLE_DATA }, 0, 0, FLAGS, "type" }, \
71  { "S12M_TIMECOD", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_S12M_TIMECODE }, 0, 0, FLAGS, "type" }, \
72  { "DYNAMIC_HDR_PLUS", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_DYNAMIC_HDR_PLUS }, 0, 0, FLAGS, "type" }, \
73  { "REGIONS_OF_INTEREST", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_REGIONS_OF_INTEREST }, 0, 0, FLAGS, "type" }, \
74  { NULL } \
75 }
76 #else
77 #define DEFINE_OPTIONS(filt_name, FLAGS) \
78 static const AVOption filt_name##_options[] = { \
79  { "mode", "set a mode of operation", OFFSET(mode), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, SIDEDATA_NB-1, FLAGS, "mode" }, \
80  { "select", "select frame", 0, AV_OPT_TYPE_CONST, {.i64 = SIDEDATA_SELECT }, 0, 0, FLAGS, "mode" }, \
81  { "delete", "delete side data", 0, AV_OPT_TYPE_CONST, {.i64 = SIDEDATA_DELETE }, 0, 0, FLAGS, "mode" }, \
82  { "type", "set side data type", OFFSET(type), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, INT_MAX, FLAGS, "type" }, \
83  { "PANSCAN", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_PANSCAN }, 0, 0, FLAGS, "type" }, \
84  { "A53_CC", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_A53_CC }, 0, 0, FLAGS, "type" }, \
85  { "STEREO3D", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_STEREO3D }, 0, 0, FLAGS, "type" }, \
86  { "MATRIXENCODING", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_MATRIXENCODING }, 0, 0, FLAGS, "type" }, \
87  { "DOWNMIX_INFO", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_DOWNMIX_INFO }, 0, 0, FLAGS, "type" }, \
88  { "REPLAYGAIN", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_REPLAYGAIN }, 0, 0, FLAGS, "type" }, \
89  { "DISPLAYMATRIX", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_DISPLAYMATRIX }, 0, 0, FLAGS, "type" }, \
90  { "AFD", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_AFD }, 0, 0, FLAGS, "type" }, \
91  { "MOTION_VECTORS", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_MOTION_VECTORS }, 0, 0, FLAGS, "type" }, \
92  { "SKIP_SAMPLES", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_SKIP_SAMPLES }, 0, 0, FLAGS, "type" }, \
93  { "AUDIO_SERVICE_TYPE", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, 0, 0, FLAGS, "type" }, \
94  { "MASTERING_DISPLAY_METADATA", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_MASTERING_DISPLAY_METADATA }, 0, 0, FLAGS, "type" }, \
95  { "GOP_TIMECODE", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_GOP_TIMECODE }, 0, 0, FLAGS, "type" }, \
96  { "SPHERICAL", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_SPHERICAL }, 0, 0, FLAGS, "type" }, \
97  { "CONTENT_LIGHT_LEVEL", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_CONTENT_LIGHT_LEVEL }, 0, 0, FLAGS, "type" }, \
98  { "ICC_PROFILE", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_ICC_PROFILE }, 0, 0, FLAGS, "type" }, \
99  { "S12M_TIMECOD", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_S12M_TIMECODE }, 0, 0, FLAGS, "type" }, \
100  { "DYNAMIC_HDR_PLUS", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_DYNAMIC_HDR_PLUS }, 0, 0, FLAGS, "type" }, \
101  { "REGIONS_OF_INTEREST", "", 0, AV_OPT_TYPE_CONST, {.i64 = AV_FRAME_DATA_REGIONS_OF_INTEREST }, 0, 0, FLAGS, "type" }, \
102  { NULL } \
103 }
104 #endif
105 
107 {
108  SideDataContext *s = ctx->priv;
109 
110  if (s->type == -1 && s->mode != SIDEDATA_DELETE) {
111  av_log(ctx, AV_LOG_ERROR, "Side data type must be set\n");
112  return AVERROR(EINVAL);
113  }
114 
115  return 0;
116 }
117 
118 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
119 {
120  AVFilterContext *ctx = inlink->dst;
121  AVFilterLink *outlink = ctx->outputs[0];
122  SideDataContext *s = ctx->priv;
123  AVFrameSideData *sd = NULL;
124 
125  if (s->type != -1)
126  sd = av_frame_get_side_data(frame, s->type);
127 
128  switch (s->mode) {
129  case SIDEDATA_SELECT:
130  if (sd) {
131  return ff_filter_frame(outlink, frame);
132  }
133  break;
134  case SIDEDATA_DELETE:
135  if (s->type == -1) {
136  while (frame->nb_side_data)
137  av_frame_remove_side_data(frame, frame->side_data[0]->type);
138  } else if (sd) {
139  av_frame_remove_side_data(frame, s->type);
140  }
141  return ff_filter_frame(outlink, frame);
142  break;
143  default:
144  av_assert0(0);
145  };
146 
147  av_frame_free(&frame);
148 
149  return 0;
150 }
151 
152 #if CONFIG_ASIDEDATA_FILTER
153 
155 AVFILTER_DEFINE_CLASS(asidedata);
156 
157 static const AVFilterPad ainputs[] = {
158  {
159  .name = "default",
160  .type = AVMEDIA_TYPE_AUDIO,
161  .filter_frame = filter_frame,
162  },
163  { NULL }
164 };
165 
166 static const AVFilterPad aoutputs[] = {
167  {
168  .name = "default",
169  .type = AVMEDIA_TYPE_AUDIO,
170  },
171  { NULL }
172 };
173 
175  .name = "asidedata",
176  .description = NULL_IF_CONFIG_SMALL("Manipulate audio frame side data."),
177  .priv_size = sizeof(SideDataContext),
178  .priv_class = &asidedata_class,
179  .init = init,
180  .inputs = ainputs,
181  .outputs = aoutputs,
183 };
184 #endif /* CONFIG_ASIDEDATA_FILTER */
185 
186 #if CONFIG_SIDEDATA_FILTER
187 
189 AVFILTER_DEFINE_CLASS(sidedata);
190 
191 static const AVFilterPad inputs[] = {
192  {
193  .name = "default",
194  .type = AVMEDIA_TYPE_VIDEO,
195  .filter_frame = filter_frame,
196  },
197  { NULL }
198 };
199 
200 static const AVFilterPad outputs[] = {
201  {
202  .name = "default",
203  .type = AVMEDIA_TYPE_VIDEO,
204  },
205  { NULL }
206 };
207 
209  .name = "sidedata",
210  .description = NULL_IF_CONFIG_SMALL("Manipulate video frame side data."),
211  .priv_size = sizeof(SideDataContext),
212  .priv_class = &sidedata_class,
213  .init = init,
214  .inputs = inputs,
215  .outputs = outputs,
217 };
218 #endif /* CONFIG_SIDEDATA_FILTER */
#define NULL
Definition: coverity.c:32
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
Main libavfilter public API header.
#define DEFINE_OPTIONS(filt_name, FLAGS)
Definition: f_sidedata.c:77
AVFilter ff_vf_sidedata
#define AV_OPT_FLAG_AUDIO_PARAM
Definition: opt.h:278
AVFilter ff_af_asidedata
static av_cold int init(AVFilterContext *ctx)
Definition: f_sidedata.c:106
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:734
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition: avfilter.h:125
const char * name
Pad name.
Definition: internal.h:60
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
#define av_cold
Definition: attributes.h:82
AVOptions.
static AVFrame * frame
Structure to hold side data for an AVFrame.
Definition: frame.h:201
int nb_side_data
Definition: frame.h:507
AVFrameSideData ** side_data
Definition: frame.h:506
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AV_OPT_FLAG_FILTERING_PARAM
a generic parameter which can be set by the user for filtering
Definition: opt.h:291
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void * priv
private data for use by the filter
Definition: avfilter.h:353
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition: f_sidedata.c:118
simple assert() macros that are a bit more flexible than ISO C assert().
reference-counted frame API
common internal API header
AVFormatContext * ctx
Definition: movenc.c:48
AVFrameSideDataType
Definition: frame.h:48
#define s(width, name)
Definition: cbs_vp9.c:257
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define AV_OPT_FLAG_VIDEO_PARAM
Definition: opt.h:279
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
If side data of the supplied type exists in the frame, free it and remove it from the frame...
Definition: frame.c:805
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
const char * name
Filter name.
Definition: avfilter.h:148
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
enum AVFrameSideDataType type
Definition: frame.h:202
#define flags(name, subs,...)
Definition: cbs_av1.c:564
#define AVFILTER_DEFINE_CLASS(fname)
Definition: internal.h:334
enum AVFrameSideDataType type
Definition: f_sidedata.c:42
An instance of a filter.
Definition: avfilter.h:338
SideDataMode
Definition: f_sidedata.c:32
internal API functions