FFmpeg  4.4.6
vf_shuffleplanes.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 #include "libavutil/avstring.h"
20 #include "libavutil/common.h"
21 #include "libavutil/internal.h"
22 #include "libavutil/opt.h"
23 #include "libavutil/pixdesc.h"
24 #include "libavutil/pixfmt.h"
25 
26 #include "avfilter.h"
27 #include "internal.h"
28 #include "video.h"
29 
30 typedef struct ShufflePlanesContext {
31  const AVClass *class;
32 
33  /* number of planes in the selected pixel format */
34  int planes;
35 
36  /* mapping indices */
37  int map[4];
38 
39  /* set to 1 if some plane is used more than once, so we need to make a copy */
40  int copy;
42 
44 {
46  ShufflePlanesContext *s = ctx->priv;
47  int fmt, ret, i;
48 
49  for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) {
52 
53  if (!(desc->flags & AV_PIX_FMT_FLAG_PAL) &&
54  !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
55  for (i = 0; i < 4; i++) {
56  if (s->map[i] >= planes)
57  break;
58 
59  if ((desc->log2_chroma_h || desc->log2_chroma_w) &&
60  (i == 1 || i == 2) != (s->map[i] == 1 || s->map[i] == 2))
61  break;
62  }
63 
64  if (i != 4)
65  continue;
66  if ((ret = ff_add_format(&formats, fmt)) < 0) {
67  return ret;
68  }
69  }
70  }
71 
73 }
74 
76 {
77  AVFilterContext *ctx = inlink->dst;
78  ShufflePlanesContext *s = ctx->priv;
79  int used[4] = { 0 };
80  int i;
81 
82  s->copy = 0;
83  s->planes = av_pix_fmt_count_planes(inlink->format);
84 
85  for (i = 0; i < s->planes; i++) {
86  if (used[s->map[i]])
87  s->copy = 1;
88  used[s->map[i]]++;
89  }
90 
91  return 0;
92 }
93 
95 {
96  AVFilterContext *ctx = inlink->dst;
97  ShufflePlanesContext *s = ctx->priv;
98  uint8_t *shuffled_data[4] = { NULL };
99  int shuffled_linesize[4] = { 0 };
100  int i, ret;
101 
102  for (i = 0; i < s->planes; i++) {
103  shuffled_data[i] = frame->data[s->map[i]];
104  shuffled_linesize[i] = frame->linesize[s->map[i]];
105  }
106  memcpy(frame->data, shuffled_data, sizeof(shuffled_data));
107  memcpy(frame->linesize, shuffled_linesize, sizeof(shuffled_linesize));
108 
109  if (s->copy) {
111 
112  if (!copy) {
113  ret = AVERROR(ENOMEM);
114  goto fail;
115  }
116 
118 
120  if (ret < 0) {
122  goto fail;
123  }
124 
126  frame = copy;
127  }
128 
129  return ff_filter_frame(ctx->outputs[0], frame);
130 fail:
132  return ret;
133 }
134 
135 #define OFFSET(x) offsetof(ShufflePlanesContext, x)
136 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
137 static const AVOption shuffleplanes_options[] = {
138  { "map0", "Index of the input plane to be used as the first output plane ", OFFSET(map[0]), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 3, FLAGS },
139  { "map1", "Index of the input plane to be used as the second output plane ", OFFSET(map[1]), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 3, FLAGS },
140  { "map2", "Index of the input plane to be used as the third output plane ", OFFSET(map[2]), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, 3, FLAGS },
141  { "map3", "Index of the input plane to be used as the fourth output plane ", OFFSET(map[3]), AV_OPT_TYPE_INT, { .i64 = 3 }, 0, 3, FLAGS },
142  { NULL },
143 };
144 
145 AVFILTER_DEFINE_CLASS(shuffleplanes);
146 
148  {
149  .name = "default",
150  .type = AVMEDIA_TYPE_VIDEO,
151  .config_props = shuffleplanes_config_input,
152  .filter_frame = shuffleplanes_filter_frame,
153  },
154  { NULL },
155 };
156 
158  {
159  .name = "default",
160  .type = AVMEDIA_TYPE_VIDEO,
161  },
162  { NULL },
163 };
164 
166  .name = "shuffleplanes",
167  .description = NULL_IF_CONFIG_SMALL("Shuffle video planes."),
168  .priv_size = sizeof(ShufflePlanesContext),
169  .priv_class = &shuffleplanes_class,
174 };
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define av_cold
Definition: attributes.h:88
uint8_t
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1096
Main libavfilter public API header.
#define flags(name, subs,...)
Definition: cbs_av1.c:572
#define s(width, name)
Definition: cbs_vp9.c:257
#define fail()
Definition: checkasm.h:133
common internal and external API header
#define NULL
Definition: coverity.c:32
static AVFrame * frame
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:587
int ff_add_format(AVFilterFormats **avff, int64_t fmt)
Add fmt to the list of media formats contained in *avff.
Definition: formats.c:332
@ AV_OPT_TYPE_INT
Definition: opt.h:225
#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:126
#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:203
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:658
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:799
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
const VDPAUPixFmtMap * map
int i
Definition: input.c:407
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
const char * desc
Definition: libsvtav1.c:79
static const struct @322 planes[]
AVOptions.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2613
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:140
#define AV_PIX_FMT_FLAG_PAL
Pixel format has a palette in data[1], values are indexes in this palette.
Definition: pixdesc.h:132
pixel format definitions
formats
Definition: signature.h:48
Describe the class of an AVClass context structure.
Definition: log.h:67
An instance of a filter.
Definition: avfilter.h:341
A list of supported formats for one end of a filter link.
Definition: formats.h:65
A filter pad used for either input or output.
Definition: internal.h:54
const char * name
Pad name.
Definition: internal.h:60
Filter definition.
Definition: avfilter.h:145
const char * name
Filter name.
Definition: avfilter.h:149
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
int width
Definition: frame.h:376
int height
Definition: frame.h:376
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:349
AVOption.
Definition: opt.h:248
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
AVFormatContext * ctx
Definition: movenc.c:48
static const AVOption shuffleplanes_options[]
AVFILTER_DEFINE_CLASS(shuffleplanes)
static int query_formats(AVFilterContext *ctx)
#define FLAGS
static int shuffleplanes_filter_frame(AVFilterLink *inlink, AVFrame *frame)
static av_cold int shuffleplanes_config_input(AVFilterLink *inlink)
static const AVFilterPad shuffleplanes_inputs[]
AVFilter ff_vf_shuffleplanes
static const AVFilterPad shuffleplanes_outputs[]
#define OFFSET(x)
static void copy(const float *p1, float *p2, const int length)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:104