34 static const char *
const var_names[] = {
"VOLUME",
"CHANNEL",
"PEAK",
NULL };
69 #define OFFSET(x) offsetof(ShowVolumeContext, x)
70 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
83 {
"dmc",
"set color of the max value line",
OFFSET(persistant_max_rgba),
AV_OPT_TYPE_COLOR, {.str =
"orange"}, CHAR_MIN, CHAR_MAX,
FLAGS },
149 for (i = 0; i < nb_samples; i++)
157 for (i = 0; i < nb_samples; i++)
158 *rms += factor * (src[i] * src[i] - *rms);
216 for (ch = 0; ch < inlink->
channels; ch++) {
219 for (i = 0; i < s->
w; i++) {
220 float max = i / (float)(s->
w - 1);
240 for (i = 0; txt[i]; i++) {
244 for (char_y = font_height - 1; char_y >= 0; char_y--) {
246 for (mask = 0x80;
mask; mask >>= 1) {
247 if (font[txt[i] * font_height + font_height - 1 - char_y] & mask)
254 for (char_y = 0; char_y < font_height; char_y++) {
255 for (mask = 0x80;
mask; mask >>= 1) {
256 if (font[txt[i] * font_height + char_y] & mask)
269 const uint32_t bg = (uint32_t)(s->
bgopacity * 255) << 24;
271 for (i = 0; i < outlink->
h; i++) {
273 for (j = 0; j < outlink->
w; j++)
284 max_val = av_clipf(0.21 * log10(max) + 1, 0, 1);
287 return outlink->
h - outlink->
h * max_val;
289 return s->
w * max_val;
309 for (k = 0; k < s->
h; k++) {
313 for (k = 0; k < s->
h; k++) {
325 const int step = s->
step;
326 int c, j, k, max_draw;
341 if ((s->
f < 1.) && (s->
f > 0.)) {
342 for (j = 0; j < outlink->
h; j++) {
346 for (k = 0; k < outlink->
w; k++) {
347 dst[k * 4 + 0] =
FFMAX(dst[k * 4 + 0] * s->
f, 0);
348 dst[k * 4 + 1] =
FFMAX(dst[k * 4 + 1] * s->
f, 0);
349 dst[k * 4 + 2] =
FFMAX(dst[k * 4 + 2] * s->
f, 0);
350 dst[k * 4 + 3] =
FFMAX(dst[k * 4 + 3] * s->
f, alpha);
353 }
else if (s->
f == 0.) {
358 for (c = 0; c < inlink->
channels; c++) {
367 max = av_clipf(max, 0, 1);
370 for (j = max_draw; j < s->
w; j++) {
372 for (k = 0; k < s->
h; k++) {
373 AV_WN32A(&dst[k * 4], lut[s->
w - j - 1]);
383 drawtext(s->
out, c * (s->
h + s->
b) + (s->
h - 10) / 2, outlink->
h - 35, channel_name, 1);
393 for (c = 0; c < inlink->
channels; c++) {
402 max = av_clipf(max, 0, 1);
405 for (j = 0; j < s->
h; j++) {
408 for (k = 0; k < max_draw; k++) {
419 drawtext(s->
out, 2, c * (s->
h + s->
b) + (s->
h - 8) / 2, channel_name, 0);
442 drawtext(out, c * (s->
h + s->
b) + (s->
h - 8) / 2, 2, buf, 1);
445 drawtext(out,
FFMAX(0, s->
w - 8 * (
int)strlen(buf)), c * (s->
h + s->
b) + (s->
h - 8) / 2, buf, 0);
483 .
name =
"showvolume",
489 .
inputs = showvolume_inputs,
491 .priv_class = &showvolume_class,
uint8_t persistant_max_rgba[4]
static float alpha(float a)
This structure describes decoded (raw) audio or video data.
AVFilter ff_avf_showvolume
Main libavfilter public API header.
int max_samples
Maximum number of samples to filter at once.
int h
agreed upon image height
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
static void drawtext(AVFrame *pic, int x, int y, const char *txt, int o)
static void calc_persistent_max(ShowVolumeContext *s, float max, int channel)
static const AVOption showvolume_options[]
static void find_rms(float *src, int nb_samples, float *rms, float factor)
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
const char * name
Pad name.
AVFilterLink ** inputs
array of pointers to input links
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
static const AVFilterPad showvolume_outputs[]
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
static double av_q2d(AVRational a)
Convert an AVRational to a double.
A filter pad used for either input or output.
A link between two filters.
const uint8_t avpriv_cga_font[2048]
int min_samples
Minimum number of samples to filter at once.
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable; if left to 0/0, will be automatically copied from the first input of the source filter if it exists.
int sample_rate
samples per second
static const uint16_t mask[17]
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#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
struct AVFilterChannelLayouts * out_channel_layouts
static void draw_max_line(ShowVolumeContext *s, int max_draw, int channel)
AVFilterFormats * in_formats
Lists of formats and channel layouts supported by the input and output filters respectively.
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
uint64_t channel_layout
Channel layout of the audio data.
int w
agreed upon image width
audio channel layout utility functions
static void find_peak(float *src, int nb_samples, float *peak, float factor)
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
AVFilterContext * src
source filter
int partial_buf_size
Size of the partial buffer to allocate.
static const AVFilterPad showvolume_inputs[]
static int config_output(AVFilterLink *outlink)
static const AVFilterPad inputs[]
AVFilterFormats * out_samplerates
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
static const AVFilterPad outputs[]
A list of supported channel layouts.
static void clear_picture(ShowVolumeContext *s, AVFilterLink *outlink)
int persistent_max_frames
AVSampleFormat
Audio sample formats.
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
static int query_formats(AVFilterContext *ctx)
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
static void draw_text(FFDrawContext *draw, AVFrame *frame, FFDrawColor *color, int x0, int y0, const uint8_t *text, int vertical)
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Describe the class of an AVClass context structure.
Rational number (pair of numerator and denominator).
static int calc_max_draw(ShowVolumeContext *s, AVFilterLink *outlink, float max)
offset must point to AVRational
static av_cold int init(AVFilterContext *ctx)
static const int factor[16]
const char * name
Filter name.
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
AVFilterLink ** outputs
array of pointers to output links
enum MovChannelLayoutTag * layouts
static enum AVPixelFormat pix_fmts[]
int * nb_frames_max_display
int av_frame_make_writable(AVFrame *frame)
Ensure that the frame data is writable, avoiding data copy if possible.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
double draw_persistent_duration
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout.
channel
Use these values when setting the channel map with ebur128_set_channel().
static int config_input(AVFilterLink *inlink)
int channels
Number of channels.
static av_cold void uninit(AVFilterContext *ctx)
static const char *const var_names[]
const char * av_get_channel_name(uint64_t channel)
Get the name of a given channel.
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
AVFilterContext * dst
dest filter
static enum AVSampleFormat sample_fmts[]
void(* meter)(float *src, int nb_samples, float *max, float factor)
uint8_t ** extended_data
pointers to the data planes/channels.
AVPixelFormat
Pixel format.
mode
Use these values in ebur128_init (or'ed).
int nb_samples
number of audio samples (per channel) described by this frame
AVFILTER_DEFINE_CLASS(showvolume)
CGA/EGA/VGA ROM font data.
AVFilterFormats * out_formats
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(constuint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(constint16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(constint32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(constint64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(constint64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(constint64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(constfloat *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(constdouble *) pi *(INT64_C(1)<< 63)))#defineFMT_PAIR_FUNC(out, in) staticconv_func_type *constfmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64),};staticvoidcpy1(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, len);}staticvoidcpy2(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 2 *len);}staticvoidcpy4(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 4 *len);}staticvoidcpy8(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, constint *ch_map, intflags){AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) returnNULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) returnNULL;if(channels==1){in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);}ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map){switch(av_get_bytes_per_sample(in_fmt)){case1:ctx->simd_f=cpy1;break;case2:ctx->simd_f=cpy2;break;case4:ctx->simd_f=cpy4;break;case8:ctx->simd_f=cpy8;break;}}if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);returnctx;}voidswri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}intswri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, intlen){intch;intoff=0;constintos=(out->planar?1:out->ch_count)*out->bps;unsignedmisaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){intplanes=in->planar?in->ch_count:1;unsignedm=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;}if(ctx->out_simd_align_mask){intplanes=out->planar?out->ch_count:1;unsignedm=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;}if(ctx->simd_f &&!ctx->ch_map &&!misaligned){off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){if(out->planar==in->planar){intplanes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
simple arithmetic expression evaluator