vf_il.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
3  * Copyright (c) 2013 Paul B Mahol
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * (de)interleave fields filter
25  */
26 
27 #include "libavutil/opt.h"
28 #include "libavutil/imgutils.h"
29 #include "libavutil/pixdesc.h"
30 #include "avfilter.h"
31 #include "internal.h"
32 
33 enum FilterMode {
37 };
38 
39 typedef struct {
40  const AVClass *class;
41  enum FilterMode luma_mode, chroma_mode, alpha_mode;
42  int luma_swap, chroma_swap, alpha_swap;
43  int nb_planes;
44  int linesize[4], chroma_height;
45  int has_alpha;
46 } IlContext;
47 
48 #define OFFSET(x) offsetof(IlContext, x)
49 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
50 
51 static const AVOption il_options[] = {
52  {"luma_mode", "select luma mode", OFFSET(luma_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "luma_mode"},
53  {"l", "select luma mode", OFFSET(luma_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "luma_mode"},
54  {"none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_NONE}, 0, 0, FLAGS, "luma_mode"},
55  {"interleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE}, 0, 0, FLAGS, "luma_mode"},
56  {"i", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE}, 0, 0, FLAGS, "luma_mode"},
57  {"deinterleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "luma_mode"},
58  {"d", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "luma_mode"},
59  {"chroma_mode", "select chroma mode", OFFSET(chroma_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "chroma_mode"},
60  {"c", "select chroma mode", OFFSET(chroma_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "chroma_mode"},
61  {"none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_NONE}, 0, 0, FLAGS, "chroma_mode"},
62  {"interleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE}, 0, 0, FLAGS, "chroma_mode"},
63  {"i", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE}, 0, 0, FLAGS, "chroma_mode"},
64  {"deinterleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "chroma_mode"},
65  {"d", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "chroma_mode"},
66  {"alpha_mode", "select alpha mode", OFFSET(alpha_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "alpha_mode"},
67  {"a", "select alpha mode", OFFSET(alpha_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "alpha_mode"},
68  {"none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_NONE}, 0, 0, FLAGS, "alpha_mode"},
69  {"interleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE}, 0, 0, FLAGS, "alpha_mode"},
70  {"i", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE}, 0, 0, FLAGS, "alpha_mode"},
71  {"deinterleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "alpha_mode"},
72  {"d", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "alpha_mode"},
73  {"luma_swap", "swap luma fields", OFFSET(luma_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
74  {"ls", "swap luma fields", OFFSET(luma_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
75  {"chroma_swap", "swap chroma fields", OFFSET(chroma_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
76  {"cs", "swap chroma fields", OFFSET(chroma_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
77  {"alpha_swap", "swap alpha fields", OFFSET(alpha_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
78  {"as", "swap alpha fields", OFFSET(alpha_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
79  {NULL}
80 };
81 
83 
85 {
87  int fmt;
88 
89  for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) {
90  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
91  if (!(desc->flags & PIX_FMT_PAL) && !(desc->flags & PIX_FMT_HWACCEL))
92  ff_add_format(&formats, fmt);
93  }
94 
95  ff_set_common_formats(ctx, formats);
96  return 0;
97 }
98 
99 static int config_input(AVFilterLink *inlink)
100 {
101  IlContext *il = inlink->dst->priv;
102  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
103  int i, ret;
104 
105  for (i = 0; i < desc->nb_components; i++)
106  il->nb_planes = FFMAX(il->nb_planes, desc->comp[i].plane);
107  il->nb_planes++;
108 
109  il->has_alpha = !!(desc->flags & PIX_FMT_ALPHA);
110  if ((ret = av_image_fill_linesizes(il->linesize, inlink->format, inlink->w)) < 0)
111  return ret;
112 
113  il->chroma_height = inlink->h >> desc->log2_chroma_h;
114 
115  return 0;
116 }
117 
118 static void interleave(uint8_t *dst, uint8_t *src, int w, int h,
119  int dst_linesize, int src_linesize,
120  enum FilterMode mode, int swap)
121 {
122  const int a = swap;
123  const int b = 1 - a;
124  const int m = h >> 1;
125  int y;
126 
127  switch (mode) {
128  case MODE_DEINTERLEAVE:
129  for (y = 0; y < m; y++) {
130  memcpy(dst + dst_linesize * y , src + src_linesize * (y * 2 + a), w);
131  memcpy(dst + dst_linesize * (y + m), src + src_linesize * (y * 2 + b), w);
132  }
133  break;
134  case MODE_NONE:
135  for (y = 0; y < m; y++) {
136  memcpy(dst + dst_linesize * y * 2 , src + src_linesize * (y * 2 + a), w);
137  memcpy(dst + dst_linesize * (y * 2 + 1), src + src_linesize * (y * 2 + b), w);
138  }
139  break;
140  case MODE_INTERLEAVE:
141  for (y = 0; y < m; y++) {
142  memcpy(dst + dst_linesize * (y * 2 + a), src + src_linesize * y , w);
143  memcpy(dst + dst_linesize * (y * 2 + b), src + src_linesize * (y + m), w);
144  }
145  break;
146  }
147 }
148 
149 static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
150 {
151  IlContext *il = inlink->dst->priv;
152  AVFilterLink *outlink = inlink->dst->outputs[0];
153  AVFrame *out;
154  int comp;
155 
156  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
157  if (!out) {
158  av_frame_free(&inpicref);
159  return AVERROR(ENOMEM);
160  }
161  av_frame_copy_props(out, inpicref);
162 
163  interleave(out->data[0], inpicref->data[0],
164  il->linesize[0], inlink->h,
165  out->linesize[0], inpicref->linesize[0],
166  il->luma_mode, il->luma_swap);
167 
168  for (comp = 1; comp < (il->nb_planes - il->has_alpha); comp++) {
169  interleave(out->data[comp], inpicref->data[comp],
170  il->linesize[comp], il->chroma_height,
171  out->linesize[comp], inpicref->linesize[comp],
172  il->chroma_mode, il->chroma_swap);
173  }
174 
175  if (il->has_alpha) {
176  comp = il->nb_planes - 1;
177  interleave(out->data[comp], inpicref->data[comp],
178  il->linesize[comp], inlink->h,
179  out->linesize[comp], inpicref->linesize[comp],
180  il->alpha_mode, il->alpha_swap);
181  }
182 
183  av_frame_free(&inpicref);
184  return ff_filter_frame(outlink, out);
185 }
186 
187 static const AVFilterPad inputs[] = {
188  {
189  .name = "default",
190  .type = AVMEDIA_TYPE_VIDEO,
191  .get_video_buffer = ff_null_get_video_buffer,
192  .filter_frame = filter_frame,
193  .config_props = config_input,
194  },
195  { NULL }
196 };
197 
198 static const AVFilterPad outputs[] = {
199  {
200  .name = "default",
201  .type = AVMEDIA_TYPE_VIDEO,
202  },
203  { NULL }
204 };
205 
207  .name = "il",
208  .description = NULL_IF_CONFIG_SMALL("Deinterleave or interleave fields."),
209  .priv_size = sizeof(IlContext),
211  .inputs = inputs,
212  .outputs = outputs,
213  .priv_class = &il_class,
214 };
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:424
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1778
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
static int query_formats(AVFilterContext *ctx)
Definition: vf_il.c:84
AVOption.
Definition: opt.h:251
const char * fmt
Definition: avisynth_c.h:669
misc image utilities
external API header
AVFrame * ff_null_get_video_buffer(AVFilterLink *link, int w, int h)
Definition: video.c:35
enum FilterMode luma_mode chroma_mode alpha_mode
Definition: vf_il.c:41
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:143
AVFILTER_DEFINE_CLASS(il)
output residual component w
const char * name
Pad name.
static void interleave(uint8_t *dst, uint8_t *src, int w, int h, int dst_linesize, int src_linesize, enum FilterMode mode, int swap)
Definition: vf_il.c:118
int chroma_swap
Definition: vf_il.c:42
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:86
uint8_t
it can be given away to ff_start_frame *A reference passed to ff_filter_frame(or the deprecated ff_start_frame) is given away and must no longer be used.*A reference created with avfilter_ref_buffer belongs to the code that created it.*A reference obtained with ff_get_video_buffer or ff_get_audio_buffer belongs to the code that requested it.*A reference given as return value by the get_video_buffer or get_audio_buffer method is given away and must no longer be used.Link reference fields---------------------The AVFilterLink structure has a few AVFilterBufferRef fields.The cur_buf and out_buf were used with the deprecated start_frame/draw_slice/end_frame API and should no longer be used.src_buf
mode
Definition: f_perms.c:27
AVOptions.
window constants for m
#define b
Definition: input.c:42
static const AVOption il_options[]
Definition: vf_il.c:51
int luma_swap
Definition: vf_il.c:42
void 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:545
static int config_input(AVFilterLink *inlink)
Definition: vf_il.c:99
A filter pad used for either input or output.
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:75
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void * priv
private data for use by the filter
Definition: avfilter.h:545
#define PIX_FMT_PAL
Pixel format has a palette in data[1], values are indexes in this palette.
Definition: pixdesc.h:90
int ff_add_format(AVFilterFormats **avff, int64_t fmt)
Add fmt to the list of media formats contained in *avff.
Definition: formats.c:344
#define FFMAX(a, b)
Definition: common.h:56
int nb_planes
Definition: vf_il.c:43
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:57
ret
Definition: avfilter.c:821
int linesize[4]
Definition: vf_il.c:44
static const AVFilterPad outputs[]
Definition: vf_il.c:198
#define PIX_FMT_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:92
NULL
Definition: eval.c:55
FilterMode
Definition: vf_il.c:33
int alpha_swap
Definition: vf_il.c:42
#define FLAGS
Definition: vf_il.c:49
AVS_Value src
Definition: avisynth_c.h:523
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
uint8_t flags
Definition: pixdesc.h:76
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:55
Describe the class of an AVClass context structure.
Definition: log.h:50
Filter definition.
Definition: avfilter.h:436
int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
Fill plane linesizes for an image with pixel format pix_fmt and width width.
Definition: imgutils.c:86
synthesis window for stochastic i
const char * name
filter name
Definition: avfilter.h:437
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:539
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
#define OFFSET(x)
Definition: vf_il.c:48
uint16_t plane
which of the 4 planes contains the component
Definition: pixdesc.h:29
The official guide to swscale for confused that consecutive non overlapping rectangles of slice_bottom special converter These generally are unscaled converters of common formats
Definition: swscale.txt:33
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:108
#define PIX_FMT_ALPHA
The pixel format has an alpha channel.
Definition: pixdesc.h:102
function y
Definition: D.m:1
AVFilter avfilter_vf_il
Definition: vf_il.c:206
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
int has_alpha
Definition: vf_il.c:45
int chroma_height
Definition: vf_il.c:44
A list of supported formats for one end of a filter link.
Definition: formats.h:64
An instance of a filter.
Definition: avfilter.h:524
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Definition: pixfmt.h:237
static void comp(unsigned char *dst, int dst_stride, unsigned char *src, int src_stride, int add)
Definition: eamad.c:71
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> out
internal API functions
static const AVFilterPad inputs[]
Definition: vf_il.c:187
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
Definition: vf_il.c:149