FFmpeg  4.0
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 {
45  AVFilterContext *ctx = inlink->dst;
46  ShufflePlanesContext *s = ctx->priv;
47  const AVPixFmtDescriptor *desc;
48  int used[4] = { 0 };
49  int i;
50 
51  s->copy = 0;
53  desc = av_pix_fmt_desc_get(inlink->format);
54 
55  for (i = 0; i < s->planes; i++) {
56  if (s->map[i] >= s->planes) {
57  av_log(ctx, AV_LOG_ERROR,
58  "Non-existing input plane #%d mapped to output plane #%d.\n",
59  s->map[i], i);
60  return AVERROR(EINVAL);
61  }
62 
63  if ((desc->log2_chroma_h || desc->log2_chroma_w) &&
64  (i == 1 || i == 2) != (s->map[i] == 1 || s->map[i] == 2)) {
65  av_log(ctx, AV_LOG_ERROR,
66  "Cannot map between a subsampled chroma plane and a luma "
67  "or alpha plane.\n");
68  return AVERROR(EINVAL);
69  }
70 
71  if ((desc->flags & AV_PIX_FMT_FLAG_PAL ||
72  desc->flags & FF_PSEUDOPAL) &&
73  (i == 1) != (s->map[i] == 1)) {
74  av_log(ctx, AV_LOG_ERROR,
75  "Cannot map between a palette plane and a data plane.\n");
76  return AVERROR(EINVAL);
77  }
78  if (used[s->map[i]])
79  s->copy = 1;
80  used[s->map[i]]++;
81  }
82 
83  return 0;
84 }
85 
87 {
88  AVFilterContext *ctx = inlink->dst;
89  ShufflePlanesContext *s = ctx->priv;
90  uint8_t *shuffled_data[4] = { NULL };
91  int shuffled_linesize[4] = { 0 };
92  int i, ret;
93 
94  for (i = 0; i < s->planes; i++) {
95  shuffled_data[i] = frame->data[s->map[i]];
96  shuffled_linesize[i] = frame->linesize[s->map[i]];
97  }
98  memcpy(frame->data, shuffled_data, sizeof(shuffled_data));
99  memcpy(frame->linesize, shuffled_linesize, sizeof(shuffled_linesize));
100 
101  if (s->copy) {
102  AVFrame *copy = ff_get_video_buffer(ctx->outputs[0], frame->width, frame->height);
103 
104  if (!copy) {
105  ret = AVERROR(ENOMEM);
106  goto fail;
107  }
108 
109  av_frame_copy(copy, frame);
110 
111  ret = av_frame_copy_props(copy, frame);
112  if (ret < 0) {
113  av_frame_free(&copy);
114  goto fail;
115  }
116 
117  av_frame_free(&frame);
118  frame = copy;
119  }
120 
121  return ff_filter_frame(ctx->outputs[0], frame);
122 fail:
123  av_frame_free(&frame);
124  return ret;
125 }
126 
127 #define OFFSET(x) offsetof(ShufflePlanesContext, x)
128 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
129 static const AVOption shuffleplanes_options[] = {
130  { "map0", "Index of the input plane to be used as the first output plane ", OFFSET(map[0]), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 4, FLAGS },
131  { "map1", "Index of the input plane to be used as the second output plane ", OFFSET(map[1]), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 4, FLAGS },
132  { "map2", "Index of the input plane to be used as the third output plane ", OFFSET(map[2]), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, 4, FLAGS },
133  { "map3", "Index of the input plane to be used as the fourth output plane ", OFFSET(map[3]), AV_OPT_TYPE_INT, { .i64 = 3 }, 0, 4, FLAGS },
134  { NULL },
135 };
136 
137 AVFILTER_DEFINE_CLASS(shuffleplanes);
138 
140  {
141  .name = "default",
142  .type = AVMEDIA_TYPE_VIDEO,
143  .config_props = shuffleplanes_config_input,
144  .filter_frame = shuffleplanes_filter_frame,
145  .get_video_buffer = ff_null_get_video_buffer,
146  },
147  { NULL },
148 };
149 
151  {
152  .name = "default",
153  .type = AVMEDIA_TYPE_VIDEO,
154  },
155  { NULL },
156 };
157 
159  .name = "shuffleplanes",
160  .description = NULL_IF_CONFIG_SMALL("Shuffle video planes."),
161 
162  .priv_size = sizeof(ShufflePlanesContext),
163  .priv_class = &shuffleplanes_class,
164 
165  .inputs = shuffleplanes_inputs,
166  .outputs = shuffleplanes_outputs,
167 };
#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 char * s
Definition: avisynth_c.h:768
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2363
This structure describes decoded (raw) audio or video data.
Definition: frame.h:218
AVOption.
Definition: opt.h:246
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2403
Main libavfilter public API header.
const char * desc
Definition: nvenc.c:65
AVFrame * ff_null_get_video_buffer(AVFilterLink *link, int w, int h)
Definition: video.c:39
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
const char * name
Pad name.
Definition: internal.h:60
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
uint8_t
#define av_cold
Definition: attributes.h:82
AVOptions.
static AVFrame * frame
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
AVFilter ff_vf_shuffleplanes
int width
Definition: frame.h:276
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
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: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 const AVOption shuffleplanes_options[]
#define fail()
Definition: checkasm.h:116
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:790
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 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:249
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
const char * name
Filter name.
Definition: avfilter.h:148
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:232
common internal and external API header
static av_cold int shuffleplanes_config_input(AVFilterLink *inlink)
static const AVFilterPad shuffleplanes_inputs[]
#define FF_PSEUDOPAL
Definition: internal.h:367
pixel format definitions
An instance of a filter.
Definition: avfilter.h:338
int height
Definition: frame.h:276
internal API functions
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:652