FFmpeg
vf_normalize.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Richard Ling
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /*
22  * Normalize RGB video (aka histogram stretching, contrast stretching).
23  * See: https://en.wikipedia.org/wiki/Normalization_(image_processing)
24  *
25  * For each channel of each frame, the filter computes the input range and maps
26  * it linearly to the user-specified output range. The output range defaults
27  * to the full dynamic range from pure black to pure white.
28  *
29  * Naively maximising the dynamic range of each frame of video in isolation
30  * may cause flickering (rapid changes in brightness of static objects in the
31  * scene) when small dark or bright objects enter or leave the scene. This
32  * filter can apply temporal smoothing to the input range to reduce flickering.
33  * Temporal smoothing is similar to the auto-exposure (automatic gain control)
34  * on a video camera, which performs the same function; and, like a video
35  * camera, it may cause a period of over- or under-exposure of the video.
36  *
37  * The filter can normalize the R,G,B channels independently, which may cause
38  * color shifting, or link them together as a single channel, which prevents
39  * color shifting. More precisely, linked normalization preserves hue (as it's
40  * defined in HSV/HSL color spaces) while independent normalization does not.
41  * Independent normalization can be used to remove color casts, such as the
42  * blue cast from underwater video, restoring more natural colors. The filter
43  * can also combine independent and linked normalization in any ratio.
44  *
45  * Finally the overall strength of the filter can be adjusted, from no effect
46  * to full normalization.
47  *
48  * The 5 AVOptions are:
49  * blackpt, Colors which define the output range. The minimum input value
50  * whitept is mapped to the blackpt. The maximum input value is mapped to
51  * the whitept. The defaults are black and white respectively.
52  * Specifying white for blackpt and black for whitept will give
53  * color-inverted, normalized video. Shades of grey can be used
54  * to reduce the dynamic range (contrast). Specifying saturated
55  * colors here can create some interesting effects.
56  *
57  * smoothing The amount of temporal smoothing, expressed in frames (>=0).
58  * the minimum and maximum input values of each channel are
59  * smoothed using a rolling average over the current frame and
60  * that many previous frames of video. Defaults to 0 (no temporal
61  * smoothing).
62  *
63  * independence
64  * Controls the ratio of independent (color shifting) channel
65  * normalization to linked (color preserving) normalization. 0.0
66  * is fully linked, 1.0 is fully independent. Defaults to fully
67  * independent.
68  *
69  * strength Overall strength of the filter. 1.0 is full strength. 0.0 is
70  * a rather expensive no-op. Values in between can give a gentle
71  * boost to low-contrast video without creating an artificial
72  * over-processed look. The default is full strength.
73  */
74 
75 #include "libavutil/imgutils.h"
76 #include "libavutil/opt.h"
77 #include "libavutil/pixdesc.h"
78 #include "avfilter.h"
79 #include "drawutils.h"
80 #include "formats.h"
81 #include "internal.h"
82 #include "video.h"
83 
84 typedef struct NormalizeContext {
85  const AVClass *class;
86 
87  // Storage for the corresponding AVOptions
90  int smoothing;
91  float independence;
92  float strength;
93 
94  uint8_t co[4]; // Offsets to R,G,B,A bytes respectively in each pixel
95  int num_components; // Number of components in the pixel format
96  int step;
97  int history_len; // Number of frames to average; based on smoothing factor
98  int frame_num; // Increments on each frame, starting from 0.
99 
100  // Per-extremum, per-channel history, for temporal smoothing.
101  struct {
102  uint8_t *history; // History entries.
103  uint32_t history_sum; // Sum of history entries.
104  } min[3], max[3]; // Min and max for each channel in {R,G,B}.
105  uint8_t *history_mem; // Single allocation for above history entries
106 
108 
109 #define OFFSET(x) offsetof(NormalizeContext, x)
110 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
111 
112 static const AVOption normalize_options[] = {
113  { "blackpt", "output color to which darkest input color is mapped", OFFSET(blackpt), AV_OPT_TYPE_COLOR, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS },
114  { "whitept", "output color to which brightest input color is mapped", OFFSET(whitept), AV_OPT_TYPE_COLOR, { .str = "white" }, CHAR_MIN, CHAR_MAX, FLAGS },
115  { "smoothing", "amount of temporal smoothing of the input range, to reduce flicker", OFFSET(smoothing), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX/8, FLAGS },
116  { "independence", "proportion of independent to linked channel normalization", OFFSET(independence), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, 0.0, 1.0, FLAGS },
117  { "strength", "strength of filter, from no effect to full normalization", OFFSET(strength), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, 0.0, 1.0, FLAGS },
118  { NULL }
119 };
120 
122 
123 // This function is the main guts of the filter. Normalizes the input frame
124 // into the output frame. The frames are known to have the same dimensions
125 // and pixel format.
127 {
128  // Per-extremum, per-channel local variables.
129  struct {
130  uint8_t in; // Original input byte value for this frame.
131  float smoothed; // Smoothed input value [0,255].
132  float out; // Output value [0,255].
133  } min[3], max[3]; // Min and max for each channel in {R,G,B}.
134 
135  float rgb_min_smoothed; // Min input range for linked normalization
136  float rgb_max_smoothed; // Max input range for linked normalization
137  uint8_t lut[3][256]; // Lookup table
138  int x, y, c;
139 
140  // First, scan the input frame to find, for each channel, the minimum
141  // (min.in) and maximum (max.in) values present in the channel.
142  for (c = 0; c < 3; c++)
143  min[c].in = max[c].in = in->data[0][s->co[c]];
144  for (y = 0; y < in->height; y++) {
145  uint8_t *inp = in->data[0] + y * in->linesize[0];
146  uint8_t *outp = out->data[0] + y * out->linesize[0];
147  for (x = 0; x < in->width; x++) {
148  for (c = 0; c < 3; c++) {
149  min[c].in = FFMIN(min[c].in, inp[s->co[c]]);
150  max[c].in = FFMAX(max[c].in, inp[s->co[c]]);
151  }
152  inp += s->step;
153  outp += s->step;
154  }
155  }
156 
157  // Next, for each channel, push min.in and max.in into their respective
158  // histories, to determine the min.smoothed and max.smoothed for this frame.
159  {
160  int history_idx = s->frame_num % s->history_len;
161  // Assume the history is not yet full; num_history_vals is the number
162  // of frames received so far including the current frame.
163  int num_history_vals = s->frame_num + 1;
164  if (s->frame_num >= s->history_len) {
165  //The history is full; drop oldest value and cap num_history_vals.
166  for (c = 0; c < 3; c++) {
167  s->min[c].history_sum -= s->min[c].history[history_idx];
168  s->max[c].history_sum -= s->max[c].history[history_idx];
169  }
170  num_history_vals = s->history_len;
171  }
172  // For each extremum, update history_sum and calculate smoothed value
173  // as the rolling average of the history entries.
174  for (c = 0; c < 3; c++) {
175  s->min[c].history_sum += (s->min[c].history[history_idx] = min[c].in);
176  min[c].smoothed = s->min[c].history_sum / (float)num_history_vals;
177  s->max[c].history_sum += (s->max[c].history[history_idx] = max[c].in);
178  max[c].smoothed = s->max[c].history_sum / (float)num_history_vals;
179  }
180  }
181 
182  // Determine the input range for linked normalization. This is simply the
183  // minimum of the per-channel minimums, and the maximum of the per-channel
184  // maximums.
185  rgb_min_smoothed = FFMIN3(min[0].smoothed, min[1].smoothed, min[2].smoothed);
186  rgb_max_smoothed = FFMAX3(max[0].smoothed, max[1].smoothed, max[2].smoothed);
187 
188  // Now, process each channel to determine the input and output range and
189  // build the lookup tables.
190  for (c = 0; c < 3; c++) {
191  int in_val;
192  // Adjust the input range for this channel [min.smoothed,max.smoothed]
193  // by mixing in the correct proportion of the linked normalization
194  // input range [rgb_min_smoothed,rgb_max_smoothed].
195  min[c].smoothed = (min[c].smoothed * s->independence)
196  + (rgb_min_smoothed * (1.0f - s->independence));
197  max[c].smoothed = (max[c].smoothed * s->independence)
198  + (rgb_max_smoothed * (1.0f - s->independence));
199 
200  // Calculate the output range [min.out,max.out] as a ratio of the full-
201  // strength output range [blackpt,whitept] and the original input range
202  // [min.in,max.in], based on the user-specified filter strength.
203  min[c].out = (s->blackpt[c] * s->strength)
204  + (min[c].in * (1.0f - s->strength));
205  max[c].out = (s->whitept[c] * s->strength)
206  + (max[c].in * (1.0f - s->strength));
207 
208  // Now, build a lookup table which linearly maps the adjusted input range
209  // [min.smoothed,max.smoothed] to the output range [min.out,max.out].
210  // Perform the linear interpolation for each x:
211  // lut[x] = (int)(float(x - min.smoothed) * scale + max.out + 0.5)
212  // where scale = (max.out - min.out) / (max.smoothed - min.smoothed)
213  if (min[c].smoothed == max[c].smoothed) {
214  // There is no dynamic range to expand. No mapping for this channel.
215  for (in_val = min[c].in; in_val <= max[c].in; in_val++)
216  lut[c][in_val] = min[c].out;
217  } else {
218  // We must set lookup values for all values in the original input
219  // range [min.in,max.in]. Since the original input range may be
220  // larger than [min.smoothed,max.smoothed], some output values may
221  // fall outside the [0,255] dynamic range. We need to clamp them.
222  float scale = (max[c].out - min[c].out) / (max[c].smoothed - min[c].smoothed);
223  for (in_val = min[c].in; in_val <= max[c].in; in_val++) {
224  int out_val = (in_val - min[c].smoothed) * scale + min[c].out + 0.5f;
225  out_val = FFMAX(out_val, 0);
226  out_val = FFMIN(out_val, 255);
227  lut[c][in_val] = out_val;
228  }
229  }
230  }
231 
232  // Finally, process the pixels of the input frame using the lookup tables.
233  for (y = 0; y < in->height; y++) {
234  uint8_t *inp = in->data[0] + y * in->linesize[0];
235  uint8_t *outp = out->data[0] + y * out->linesize[0];
236  for (x = 0; x < in->width; x++) {
237  for (c = 0; c < 3; c++)
238  outp[s->co[c]] = lut[c][inp[s->co[c]]];
239  if (s->num_components == 4)
240  // Copy alpha as-is.
241  outp[s->co[3]] = inp[s->co[3]];
242  inp += s->step;
243  outp += s->step;
244  }
245  }
246 
247  s->frame_num++;
248 }
249 
250 // Now we define all the functions accessible from the ff_vf_normalize class,
251 // which is ffmpeg's interface to our filter. See doc/filter_design.txt and
252 // doc/writing_filters.txt for descriptions of what these interface functions
253 // are expected to do.
254 
255 // Set the pixel formats that our filter supports. We should be able to process
256 // any 8-bit RGB formats. 16-bit support might be useful one day.
258 {
259  static const enum AVPixelFormat pixel_fmts[] = {
271  };
272  // According to filter_design.txt, using ff_set_common_formats() this way
273  // ensures the pixel formats of the input and output will be the same. That
274  // saves a bit of effort possibly needing to handle format conversions.
276  if (!formats)
277  return AVERROR(ENOMEM);
279 }
280 
281 // At this point we know the pixel format used for both input and output. We
282 // can also access the frame rate of the input video and allocate some memory
283 // appropriately
285 {
286  NormalizeContext *s = inlink->dst->priv;
287  // Store offsets to R,G,B,A bytes respectively in each pixel
289  int c;
290 
291  ff_fill_rgba_map(s->co, inlink->format);
292  s->num_components = desc->nb_components;
293  s->step = av_get_padded_bits_per_pixel(desc) >> 3;
294  // Convert smoothing value to history_len (a count of frames to average,
295  // must be at least 1). Currently this is a direct assignment, but the
296  // smoothing value was originally envisaged as a number of seconds. In
297  // future it would be nice to set history_len using a number of seconds,
298  // but VFR video is currently an obstacle to doing so.
299  s->history_len = s->smoothing + 1;
300  // Allocate the history buffers -- there are 6 -- one for each extrema.
301  // s->smoothing is limited to INT_MAX/8, so that (s->history_len * 6)
302  // can't overflow on 32bit causing a too-small allocation.
303  s->history_mem = av_malloc(s->history_len * 6);
304  if (s->history_mem == NULL)
305  return AVERROR(ENOMEM);
306 
307  for (c = 0; c < 3; c++) {
308  s->min[c].history = s->history_mem + (c*2) * s->history_len;
309  s->max[c].history = s->history_mem + (c*2+1) * s->history_len;
310  }
311  return 0;
312 }
313 
314 // Free any memory allocations here
316 {
317  NormalizeContext *s = ctx->priv;
318 
319  av_freep(&s->history_mem);
320 }
321 
322 // This function is pretty much standard from doc/writing_filters.txt. It
323 // tries to do in-place filtering where possible, only allocating a new output
324 // frame when absolutely necessary.
326 {
327  AVFilterContext *ctx = inlink->dst;
328  AVFilterLink *outlink = ctx->outputs[0];
329  NormalizeContext *s = ctx->priv;
330  AVFrame *out;
331  // Set 'direct' if we can modify the input frame in-place. Otherwise we
332  // need to retrieve a new frame from the output link.
333  int direct = av_frame_is_writable(in) && !ctx->is_disabled;
334 
335  if (direct) {
336  out = in;
337  } else {
338  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
339  if (!out) {
340  av_frame_free(&in);
341  return AVERROR(ENOMEM);
342  }
344  }
345 
346  // Now we've got the input and output frames (which may be the same frame)
347  // perform the filtering with our custom function.
348  normalize(s, in, out);
349 
350  if (ctx->is_disabled) {
351  av_frame_free(&out);
352  return ff_filter_frame(outlink, in);
353  }
354 
355  if (!direct)
356  av_frame_free(&in);
357 
358  return ff_filter_frame(outlink, out);
359 }
360 
361 static const AVFilterPad inputs[] = {
362  {
363  .name = "default",
364  .type = AVMEDIA_TYPE_VIDEO,
365  .filter_frame = filter_frame,
366  .config_props = config_input,
367  },
368  { NULL }
369 };
370 
371 static const AVFilterPad outputs[] = {
372  {
373  .name = "default",
374  .type = AVMEDIA_TYPE_VIDEO,
375  },
376  { NULL }
377 };
378 
380  .name = "normalize",
381  .description = NULL_IF_CONFIG_SMALL("Normalize RGB video."),
382  .priv_size = sizeof(NormalizeContext),
383  .priv_class = &normalize_class,
384  .uninit = uninit,
386  .inputs = inputs,
387  .outputs = outputs,
389 };
formats
formats
Definition: signature.h:48
ff_get_video_buffer
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
NormalizeContext
Definition: vf_normalize.c:84
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
NormalizeContext::min
struct NormalizeContext::@237 min[3]
AVERROR
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
opt.h
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
out
FILE * out
Definition: movenc.c:54
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
inlink
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
Definition: filter_design.txt:212
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
NormalizeContext::history_len
int history_len
Definition: vf_normalize.c:97
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
pixdesc.h
NormalizeContext::history
uint8_t * history
Definition: vf_normalize.c:102
AVOption
AVOption.
Definition: opt.h:246
NormalizeContext::whitept
uint8_t whitept[4]
Definition: vf_normalize.c:89
normalize_options
static const AVOption normalize_options[]
Definition: vf_normalize.c:112
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
max
#define max(a, b)
Definition: cuda_runtime.h:33
NormalizeContext::max
struct NormalizeContext::@237 max[3]
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:148
video.h
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
formats.h
NormalizeContext::history_mem
uint8_t * history_mem
Definition: vf_normalize.c:105
FFMIN3
#define FFMIN3(a, b, c)
Definition: common.h:97
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
NormalizeContext::history_sum
uint32_t history_sum
Definition: vf_normalize.c:103
av_cold
#define av_cold
Definition: attributes.h:84
ff_set_common_formats
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:568
outputs
static const AVFilterPad outputs[]
Definition: vf_normalize.c:371
FFMAX3
#define FFMAX3(a, b, c)
Definition: common.h:95
s
#define s(width, name)
Definition: cbs_vp9.c:257
ff_vf_normalize
AVFilter ff_vf_normalize
Definition: vf_normalize.c:379
NormalizeContext::independence
float independence
Definition: vf_normalize.c:91
ctx
AVFormatContext * ctx
Definition: movenc.c:48
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_normalize.c:257
f
#define f(width, name)
Definition: cbs_vp9.c:255
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
if
if(ret)
Definition: filter_design.txt:179
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
AV_OPT_TYPE_COLOR
@ AV_OPT_TYPE_COLOR
Definition: opt.h:238
inputs
static const AVFilterPad inputs[]
Definition: vf_normalize.c:361
NormalizeContext::step
int step
Definition: vf_normalize.c:96
NormalizeContext::blackpt
uint8_t blackpt[4]
Definition: vf_normalize.c:88
AV_PIX_FMT_BGR0
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:240
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
OFFSET
#define OFFSET(x)
Definition: vf_normalize.c:109
desc
const char * desc
Definition: nvenc.c:68
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
av_get_padded_bits_per_pixel
int av_get_padded_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel for the pixel format described by pixdesc, including any padding ...
Definition: pixdesc.c:2487
FLAGS
#define FLAGS
Definition: vf_normalize.c:110
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_normalize.c:315
av_frame_is_writable
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:594
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_normalize.c:325
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:238
NormalizeContext::co
uint8_t co[4]
Definition: vf_normalize.c:94
internal.h
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:226
in
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
Definition: audio_convert.c:326
normalize
Definition: normalize.py:1
NormalizeContext::smoothing
int smoothing
Definition: vf_normalize.c:90
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_normalize.c:284
uint8_t
uint8_t
Definition: audio_convert.c:194
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
AVFilter
Filter definition.
Definition: avfilter.h:144
AV_PIX_FMT_0BGR
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:239
normalize
static void normalize(NormalizeContext *s, AVFrame *in, AVFrame *out)
Definition: vf_normalize.c:126
NormalizeContext::frame_num
int frame_num
Definition: vf_normalize.c:98
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
NormalizeContext::num_components
int num_components
Definition: vf_normalize.c:95
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
avfilter.h
NormalizeContext::strength
float strength
Definition: vf_normalize.c:92
AVFilterContext
An instance of a filter.
Definition: avfilter.h:338
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:35
AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
Definition: avfilter.h:133
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
AV_PIX_FMT_0RGB
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:237
drawutils.h
min
float min
Definition: vorbis_enc_data.h:456
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(normalize)