FFmpeg  4.3
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  ff_formats_unref(&formats);
68  return ret;
69  }
70  }
71  }
72 
73  return ff_set_common_formats(ctx, formats);
74 }
75 
77 {
78  AVFilterContext *ctx = inlink->dst;
79  ShufflePlanesContext *s = ctx->priv;
80  int used[4] = { 0 };
81  int i;
82 
83  s->copy = 0;
85 
86  for (i = 0; i < s->planes; i++) {
87  if (used[s->map[i]])
88  s->copy = 1;
89  used[s->map[i]]++;
90  }
91 
92  return 0;
93 }
94 
96 {
97  AVFilterContext *ctx = inlink->dst;
98  ShufflePlanesContext *s = ctx->priv;
99  uint8_t *shuffled_data[4] = { NULL };
100  int shuffled_linesize[4] = { 0 };
101  int i, ret;
102 
103  for (i = 0; i < s->planes; i++) {
104  shuffled_data[i] = frame->data[s->map[i]];
105  shuffled_linesize[i] = frame->linesize[s->map[i]];
106  }
107  memcpy(frame->data, shuffled_data, sizeof(shuffled_data));
108  memcpy(frame->linesize, shuffled_linesize, sizeof(shuffled_linesize));
109 
110  if (s->copy) {
111  AVFrame *copy = ff_get_video_buffer(ctx->outputs[0], frame->width, frame->height);
112 
113  if (!copy) {
114  ret = AVERROR(ENOMEM);
115  goto fail;
116  }
117 
118  av_frame_copy(copy, frame);
119 
120  ret = av_frame_copy_props(copy, frame);
121  if (ret < 0) {
122  av_frame_free(&copy);
123  goto fail;
124  }
125 
126  av_frame_free(&frame);
127  frame = copy;
128  }
129 
130  return ff_filter_frame(ctx->outputs[0], frame);
131 fail:
132  av_frame_free(&frame);
133  return ret;
134 }
135 
136 #define OFFSET(x) offsetof(ShufflePlanesContext, x)
137 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
138 static const AVOption shuffleplanes_options[] = {
139  { "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 },
140  { "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 },
141  { "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 },
142  { "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 },
143  { NULL },
144 };
145 
146 AVFILTER_DEFINE_CLASS(shuffleplanes);
147 
149  {
150  .name = "default",
151  .type = AVMEDIA_TYPE_VIDEO,
152  .config_props = shuffleplanes_config_input,
153  .filter_frame = shuffleplanes_filter_frame,
154  },
155  { NULL },
156 };
157 
159  {
160  .name = "default",
161  .type = AVMEDIA_TYPE_VIDEO,
162  },
163  { NULL },
164 };
165 
167  .name = "shuffleplanes",
168  .description = NULL_IF_CONFIG_SMALL("Shuffle video planes."),
169  .priv_size = sizeof(ShufflePlanesContext),
170  .priv_class = &shuffleplanes_class,
172  .inputs = shuffleplanes_inputs,
173  .outputs = shuffleplanes_outputs,
175 };
#define AV_PIX_FMT_FLAG_PAL
Pixel format has a palette in data[1], values are indexes in this palette.
Definition: pixdesc.h:132
#define NULL
Definition: coverity.c:32
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2549
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
AVOption.
Definition: opt.h:246
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2589
Main libavfilter public API header.
const char * desc
Definition: nvenc.c:79
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
#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
static int query_formats(AVFilterContext *ctx)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1075
uint8_t
#define av_cold
Definition: attributes.h:88
AVOptions.
static AVFrame * frame
A filter pad used for either input or output.
Definition: internal.h:54
AVFilter ff_vf_shuffleplanes
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
int width
Definition: frame.h:358
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:600
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
#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
#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 const AVOption shuffleplanes_options[]
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:140
int ff_add_format(AVFilterFormats **avff, int64_t fmt)
Add fmt to the list of media formats contained in *avff.
Definition: formats.c:336
#define fail()
Definition: checkasm.h:123
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:800
common internal API header
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:106
static int shuffleplanes_filter_frame(AVFilterLink *inlink, AVFrame *frame)
#define OFFSET(x)
AVFILTER_DEFINE_CLASS(shuffleplanes)
AVFormatContext * ctx
Definition: movenc.c:48
#define s(width, name)
Definition: cbs_vp9.c:257
#define FLAGS
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
static const AVFilterPad shuffleplanes_outputs[]
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:331
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
void ff_formats_unref(AVFilterFormats **ref)
If *ref is non-NULL, remove *ref as a reference to the format list it currently points to...
Definition: formats.c:506
const char * name
Filter name.
Definition: avfilter.h:148
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
#define flags(name, subs,...)
Definition: cbs_av1.c:564
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:314
common internal and external API header
static av_cold int shuffleplanes_config_input(AVFilterLink *inlink)
static const AVFilterPad shuffleplanes_inputs[]
pixel format definitions
A list of supported formats for one end of a filter link.
Definition: formats.h:64
An instance of a filter.
Definition: avfilter.h:338
int height
Definition: frame.h:358
formats
Definition: signature.h:48
internal API functions
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:659