FFmpeg
vf_unsharp.c
Go to the documentation of this file.
1 /*
2  * Original copyright (c) 2002 Remi Guyomarch <rguyom@pobox.com>
3  * Port copyright (c) 2010 Daniel G. Taylor <dan@programmer-art.org>
4  * Relicensed to the LGPL with permission from Remi Guyomarch.
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 /**
24  * @file
25  * blur / sharpen filter, ported to FFmpeg from MPlayer
26  * libmpcodecs/unsharp.c.
27  *
28  * This code is based on:
29  *
30  * An Efficient algorithm for Gaussian blur using finite-state machines
31  * Frederick M. Waltz and John W. V. Miller
32  *
33  * SPIE Conf. on Machine Vision Systems for Inspection and Metrology VII
34  * Originally published Boston, Nov 98
35  *
36  * http://www.engin.umd.umich.edu/~jwvm/ece581/21_GBlur.pdf
37  */
38 
39 #include "avfilter.h"
40 #include "formats.h"
41 #include "internal.h"
42 #include "video.h"
43 #include "libavutil/common.h"
44 #include "libavutil/imgutils.h"
45 #include "libavutil/mem.h"
46 #include "libavutil/opt.h"
47 #include "libavutil/pixdesc.h"
48 #include "unsharp.h"
49 
50 typedef struct TheadData {
52  uint8_t *dst;
53  const uint8_t *src;
56  int width;
57  int height;
58 } ThreadData;
59 
60 #define DEF_UNSHARP_SLICE_FUNC(name, nbits) \
61 static int name##_##nbits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
62 { \
63  ThreadData *td = arg; \
64  UnsharpFilterParam *fp = td->fp; \
65  UnsharpContext *s = ctx->priv; \
66  uint32_t **sc = fp->sc; \
67  uint32_t *sr = fp->sr; \
68  const uint##nbits##_t *src2 = NULL; \
69  const int amount = fp->amount; \
70  const int steps_x = fp->steps_x; \
71  const int steps_y = fp->steps_y; \
72  const int scalebits = fp->scalebits; \
73  const int32_t halfscale = fp->halfscale; \
74  \
75  uint##nbits##_t *dst = (uint##nbits##_t*)td->dst; \
76  const uint##nbits##_t *src = (const uint##nbits##_t *)td->src; \
77  int dst_stride = td->dst_stride; \
78  int src_stride = td->src_stride; \
79  const int width = td->width; \
80  const int height = td->height; \
81  const int sc_offset = jobnr * 2 * steps_y; \
82  const int sr_offset = jobnr * (MAX_MATRIX_SIZE - 1); \
83  const int slice_start = (height * jobnr) / nb_jobs; \
84  const int slice_end = (height * (jobnr+1)) / nb_jobs; \
85  \
86  int32_t res; \
87  int x, y, z; \
88  uint32_t tmp1, tmp2; \
89  \
90  if (!amount) { \
91  av_image_copy_plane(td->dst + slice_start * dst_stride, dst_stride, \
92  td->src + slice_start * src_stride, src_stride, \
93  width * s->bps, slice_end - slice_start); \
94  return 0; \
95  } \
96  \
97  for (y = 0; y < 2 * steps_y; y++) \
98  memset(sc[sc_offset + y], 0, sizeof(sc[y][0]) * (width + 2 * steps_x)); \
99  \
100  dst_stride = dst_stride / s->bps; \
101  src_stride = src_stride / s->bps; \
102  /* if this is not the first tile, we start from (slice_start - steps_y) */ \
103  /* so we can get smooth result at slice boundary */ \
104  if (slice_start > steps_y) { \
105  src += (slice_start - steps_y) * src_stride; \
106  dst += (slice_start - steps_y) * dst_stride; \
107  } \
108  \
109  for (y = -steps_y + slice_start; y < steps_y + slice_end; y++) { \
110  if (y < height) \
111  src2 = src; \
112  \
113  memset(sr + sr_offset, 0, sizeof(sr[0]) * (2 * steps_x - 1)); \
114  for (x = -steps_x; x < width + steps_x; x++) { \
115  tmp1 = x <= 0 ? src2[0] : x >= width ? src2[width-1] : src2[x]; \
116  for (z = 0; z < steps_x * 2; z += 2) { \
117  tmp2 = sr[sr_offset + z + 0] + tmp1; sr[sr_offset + z + 0] = tmp1; \
118  tmp1 = sr[sr_offset + z + 1] + tmp2; sr[sr_offset + z + 1] = tmp2; \
119  } \
120  for (z = 0; z < steps_y * 2; z += 2) { \
121  tmp2 = sc[sc_offset + z + 0][x + steps_x] + tmp1; \
122  sc[sc_offset + z + 0][x + steps_x] = tmp1; \
123  tmp1 = sc[sc_offset + z + 1][x + steps_x] + tmp2; \
124  sc[sc_offset + z + 1][x + steps_x] = tmp2; \
125  } \
126  if (x >= steps_x && y >= (steps_y + slice_start)) { \
127  const uint##nbits##_t *srx = src - steps_y * src_stride + x - steps_x; \
128  uint##nbits##_t *dsx = dst - steps_y * dst_stride + x - steps_x; \
129  \
130  res = (int32_t)*srx + ((((int32_t) * srx - \
131  (int32_t)((tmp1 + halfscale) >> scalebits)) * amount) >> (8+nbits)); \
132  *dsx = av_clip_uint##nbits(res); \
133  } \
134  } \
135  if (y >= 0) { \
136  dst += dst_stride; \
137  src += src_stride; \
138  } \
139  } \
140  return 0; \
141 }
142 DEF_UNSHARP_SLICE_FUNC(unsharp_slice, 16)
143 DEF_UNSHARP_SLICE_FUNC(unsharp_slice, 8)
144 
146 {
147  AVFilterLink *inlink = ctx->inputs[0];
148  UnsharpContext *s = ctx->priv;
149  int i, plane_w[3], plane_h[3];
151  ThreadData td;
152 
153  plane_w[0] = inlink->w;
154  plane_w[1] = plane_w[2] = AV_CEIL_RSHIFT(inlink->w, s->hsub);
155  plane_h[0] = inlink->h;
156  plane_h[1] = plane_h[2] = AV_CEIL_RSHIFT(inlink->h, s->vsub);
157  fp[0] = &s->luma;
158  fp[1] = fp[2] = &s->chroma;
159  for (i = 0; i < 3; i++) {
160  td.fp = fp[i];
161  td.dst = out->data[i];
162  td.src = in->data[i];
163  td.width = plane_w[i];
164  td.height = plane_h[i];
165  td.dst_stride = out->linesize[i];
166  td.src_stride = in->linesize[i];
167  ctx->internal->execute(ctx, s->unsharp_slice, &td, NULL, FFMIN(plane_h[i], s->nb_threads));
168  }
169  return 0;
170 }
171 
172 static void set_filter_param(UnsharpFilterParam *fp, int msize_x, int msize_y, float amount)
173 {
174  fp->msize_x = msize_x;
175  fp->msize_y = msize_y;
176  fp->amount = amount * 65536.0;
177 
178  fp->steps_x = msize_x / 2;
179  fp->steps_y = msize_y / 2;
180  fp->scalebits = (fp->steps_x + fp->steps_y) * 2;
181  fp->halfscale = 1 << (fp->scalebits - 1);
182 }
183 
185 {
186  UnsharpContext *s = ctx->priv;
187 
188  set_filter_param(&s->luma, s->lmsize_x, s->lmsize_y, s->lamount);
190 
191  if (s->luma.scalebits >= 26 || s->chroma.scalebits >= 26) {
192  av_log(ctx, AV_LOG_ERROR, "luma or chroma matrix size too big\n");
193  return AVERROR(EINVAL);
194  }
196  return 0;
197 }
198 
200 {
201  static const enum AVPixelFormat pix_fmts[] = {
209  };
210 
211  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
212  if (!fmts_list)
213  return AVERROR(ENOMEM);
214  return ff_set_common_formats(ctx, fmts_list);
215 }
216 
217 static int init_filter_param(AVFilterContext *ctx, UnsharpFilterParam *fp, const char *effect_type, int width)
218 {
219  int z;
220  UnsharpContext *s = ctx->priv;
221  const char *effect = fp->amount == 0 ? "none" : fp->amount < 0 ? "blur" : "sharpen";
222 
223  if (!(fp->msize_x & fp->msize_y & 1)) {
224  av_log(ctx, AV_LOG_ERROR,
225  "Invalid even size for %s matrix size %dx%d\n",
226  effect_type, fp->msize_x, fp->msize_y);
227  return AVERROR(EINVAL);
228  }
229 
230  av_log(ctx, AV_LOG_VERBOSE, "effect:%s type:%s msize_x:%d msize_y:%d amount:%0.2f\n",
231  effect, effect_type, fp->msize_x, fp->msize_y, fp->amount / 65535.0);
232 
233  fp->sr = av_malloc_array((MAX_MATRIX_SIZE - 1) * s->nb_threads, sizeof(uint32_t));
234  fp->sc = av_mallocz_array(2 * fp->steps_y * s->nb_threads, sizeof(uint32_t *));
235  if (!fp->sr || !fp->sc)
236  return AVERROR(ENOMEM);
237 
238  for (z = 0; z < 2 * fp->steps_y * s->nb_threads; z++)
239  if (!(fp->sc[z] = av_malloc_array(width + 2 * fp->steps_x,
240  sizeof(*(fp->sc[z])))))
241  return AVERROR(ENOMEM);
242 
243  return 0;
244 }
245 
247 {
248  UnsharpContext *s = inlink->dst->priv;
250  int ret;
251 
252  s->hsub = desc->log2_chroma_w;
253  s->vsub = desc->log2_chroma_h;
254  s->bitdepth = desc->comp[0].depth;
255  s->bps = s->bitdepth > 8 ? 2 : 1;
256  s->unsharp_slice = s->bitdepth > 8 ? unsharp_slice_16 : unsharp_slice_8;
257 
258  // ensure (height / nb_threads) > 4 * steps_y,
259  // so that we don't have too much overlap between two threads
261  inlink->h / (4 * s->luma.steps_y));
262 
263  ret = init_filter_param(inlink->dst, &s->luma, "luma", inlink->w);
264  if (ret < 0)
265  return ret;
266  ret = init_filter_param(inlink->dst, &s->chroma, "chroma", AV_CEIL_RSHIFT(inlink->w, s->hsub));
267  if (ret < 0)
268  return ret;
269 
270  return 0;
271 }
272 
273 static void free_filter_param(UnsharpFilterParam *fp, int nb_threads)
274 {
275  int z;
276 
277  if (fp->sc) {
278  for (z = 0; z < 2 * fp->steps_y * nb_threads; z++)
279  av_freep(&fp->sc[z]);
280  av_freep(&fp->sc);
281  }
282  av_freep(&fp->sr);
283 }
284 
286 {
287  UnsharpContext *s = ctx->priv;
288 
291 }
292 
294 {
295  UnsharpContext *s = link->dst->priv;
296  AVFilterLink *outlink = link->dst->outputs[0];
297  AVFrame *out;
298  int ret = 0;
299 
300  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
301  if (!out) {
302  av_frame_free(&in);
303  return AVERROR(ENOMEM);
304  }
305  av_frame_copy_props(out, in);
306 
307  ret = s->apply_unsharp(link->dst, in, out);
308 
309  av_frame_free(&in);
310 
311  if (ret < 0) {
312  av_frame_free(&out);
313  return ret;
314  }
315  return ff_filter_frame(outlink, out);
316 }
317 
318 #define OFFSET(x) offsetof(UnsharpContext, x)
319 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
320 #define MIN_SIZE 3
321 #define MAX_SIZE 23
322 static const AVOption unsharp_options[] = {
323  { "luma_msize_x", "set luma matrix horizontal size", OFFSET(lmsize_x), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
324  { "lx", "set luma matrix horizontal size", OFFSET(lmsize_x), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
325  { "luma_msize_y", "set luma matrix vertical size", OFFSET(lmsize_y), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
326  { "ly", "set luma matrix vertical size", OFFSET(lmsize_y), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
327  { "luma_amount", "set luma effect strength", OFFSET(lamount), AV_OPT_TYPE_FLOAT, { .dbl = 1 }, -2, 5, FLAGS },
328  { "la", "set luma effect strength", OFFSET(lamount), AV_OPT_TYPE_FLOAT, { .dbl = 1 }, -2, 5, FLAGS },
329  { "chroma_msize_x", "set chroma matrix horizontal size", OFFSET(cmsize_x), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
330  { "cx", "set chroma matrix horizontal size", OFFSET(cmsize_x), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
331  { "chroma_msize_y", "set chroma matrix vertical size", OFFSET(cmsize_y), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
332  { "cy", "set chroma matrix vertical size", OFFSET(cmsize_y), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
333  { "chroma_amount", "set chroma effect strength", OFFSET(camount), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, -2, 5, FLAGS },
334  { "ca", "set chroma effect strength", OFFSET(camount), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, -2, 5, FLAGS },
335  { "opencl", "ignored", OFFSET(opencl), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
336  { NULL }
337 };
338 
339 AVFILTER_DEFINE_CLASS(unsharp);
340 
342  {
343  .name = "default",
344  .type = AVMEDIA_TYPE_VIDEO,
345  .filter_frame = filter_frame,
346  .config_props = config_input,
347  },
348  { NULL }
349 };
350 
352  {
353  .name = "default",
354  .type = AVMEDIA_TYPE_VIDEO,
355  },
356  { NULL }
357 };
358 
360  .name = "unsharp",
361  .description = NULL_IF_CONFIG_SMALL("Sharpen or blur the input video."),
362  .priv_size = sizeof(UnsharpContext),
363  .priv_class = &unsharp_class,
364  .init = init,
365  .uninit = uninit,
367  .inputs = avfilter_vf_unsharp_inputs,
368  .outputs = avfilter_vf_unsharp_outputs,
370 };
#define NULL
Definition: coverity.c:32
int(* unsharp_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: unsharp.h:56
#define AV_PIX_FMT_YUV440P10
Definition: pixfmt.h:401
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
This structure describes decoded (raw) audio or video data.
Definition: frame.h:314
static const AVFilterPad avfilter_vf_unsharp_inputs[]
Definition: vf_unsharp.c:341
int lmsize_x
Definition: unsharp.h:46
AVOption.
Definition: opt.h:248
#define FLAGS
Definition: vf_unsharp.c:319
const char * desc
Definition: libsvtav1.c:79
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
misc image utilities
Main libavfilter public API header.
Memory handling functions.
static void free_filter_param(UnsharpFilterParam *fp, int nb_threads)
Definition: vf_unsharp.c:273
static av_cold int init(AVFilterContext *ctx)
Definition: vf_unsharp.c:184
UnsharpFilterParam luma
luma parameters (width, height, amount)
Definition: unsharp.h:48
int msize_y
matrix height
Definition: unsharp.h:34
float lamount
Definition: unsharp.h:47
uint32_t * sr
finite state machine storage within a row
Definition: unsharp.h:40
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:403
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
int src_stride
Definition: vf_unsharp.c:55
#define MAX_SIZE
Definition: vf_unsharp.c:321
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
int(* apply_unsharp)(AVFilterContext *ctx, AVFrame *in, AVFrame *out)
Definition: unsharp.h:55
int lmsize_y
Definition: unsharp.h:46
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:287
#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
const char * name
Pad name.
Definition: internal.h:60
int steps_x
horizontal step count
Definition: unsharp.h:36
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1094
#define DEF_UNSHARP_SLICE_FUNC(name, nbits)
Definition: vf_unsharp.c:60
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
#define av_cold
Definition: attributes.h:88
AVOptions.
#define OFFSET(x)
Definition: vf_unsharp.c:318
AVFilter ff_vf_unsharp
Definition: vf_unsharp.c:359
int height
Definition: vf_avgblur.c:61
static const AVFilterPad avfilter_vf_unsharp_outputs[]
Definition: vf_unsharp.c:351
#define height
AVFrame * dst
Definition: vf_blend.c:56
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range...
Definition: pixfmt.h:100
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:412
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:404
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
int bitdepth
Definition: unsharp.h:51
#define src
Definition: vp8dsp.c:255
int scalebits
bits to shift pixel
Definition: unsharp.h:38
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
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:588
#define td
Definition: regdef.h:70
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
int32_t halfscale
amount to add to pixel
Definition: unsharp.h:39
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:115
const uint8_t * src
Definition: vf_bm3d.c:56
#define MIN_SIZE
Definition: vf_unsharp.c:320
void * priv
private data for use by the filter
Definition: avfilter.h:356
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:402
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:397
int amount
effect amount
Definition: unsharp.h:35
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
#define FFMIN(a, b)
Definition: common.h:105
int cmsize_x
Definition: unsharp.h:46
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
#define width
uint32_t ** sc
finite state machine storage across rows
Definition: unsharp.h:41
float camount
Definition: unsharp.h:47
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_unsharp.c:285
AVFormatContext * ctx
Definition: movenc.c:48
#define s(width, name)
Definition: cbs_vp9.c:257
static int apply_unsharp_c(AVFilterContext *ctx, AVFrame *in, AVFrame *out)
Definition: vf_unsharp.c:145
static int filter_frame(AVFilterLink *link, AVFrame *in)
Definition: vf_unsharp.c:293
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:398
static const AVOption unsharp_options[]
Definition: vf_unsharp.c:322
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
AVFILTER_DEFINE_CLASS(unsharp)
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:410
Used for passing data between threads.
Definition: dsddec.c:67
static int config_input(AVFilterLink *inlink)
Definition: vf_unsharp.c:246
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
int steps_y
vertical step count
Definition: unsharp.h:37
#define fp
Definition: regdef.h:44
int msize_x
matrix width
Definition: unsharp.h:33
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
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=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);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_AARCH64) ff_audio_convert_init_aarch64(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_log(ac->avr, AV_LOG_TRACE,"%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-> in
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:399
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
Filter definition.
Definition: avfilter.h:145
static void set_filter_param(UnsharpFilterParam *fp, int msize_x, int msize_y, float amount)
Definition: vf_unsharp.c:172
static int init_filter_param(AVFilterContext *ctx, UnsharpFilterParam *fp, const char *effect_type, int width)
Definition: vf_unsharp.c:217
UnsharpFilterParam chroma
chroma parameters (width, height, amount)
Definition: unsharp.h:49
static int query_formats(AVFilterContext *ctx)
Definition: vf_unsharp.c:199
const char * name
Filter name.
Definition: avfilter.h:149
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:405
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:396
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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 link
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:353
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:303
int cmsize_y
Definition: unsharp.h:46
#define flags(name, subs,...)
Definition: cbs_av1.c:561
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:400
#define MAX_MATRIX_SIZE
Definition: unsharp.h:29
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:406
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:328
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
common internal and external API header
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
A list of supported formats for one end of a filter link.
Definition: formats.h:65
An instance of a filter.
Definition: avfilter.h:341
FILE * out
Definition: movenc.c:54
#define av_freep(p)
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
#define av_malloc_array(a, b)
int dst_stride
Definition: vf_unsharp.c:54
internal API functions
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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.Frame references ownership and permissions
int depth
Number of bits in the component.
Definition: pixdesc.h:58
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
UnsharpFilterParam * fp
Definition: vf_unsharp.c:51
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:411
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:658
int i
Definition: input.c:407
int nb_threads
Definition: unsharp.h:53
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:190
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58