mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-05-13 21:26:33 +02:00
lavfi/showwaves: add display mode option and mode=line
This commit is contained in:
parent
13aca070ab
commit
b7d34b328b
@ -5716,6 +5716,19 @@ Convert input audio to a video output, representing the samples waves.
|
|||||||
|
|
||||||
The filter accepts the following named parameters:
|
The filter accepts the following named parameters:
|
||||||
@table @option
|
@table @option
|
||||||
|
@item mode
|
||||||
|
Set display mode.
|
||||||
|
|
||||||
|
Available values are:
|
||||||
|
@table @samp
|
||||||
|
@item point
|
||||||
|
Draw a point for each sample.
|
||||||
|
|
||||||
|
@item line
|
||||||
|
Draw a vertical line for each sample.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
Default value is @code{point}.
|
||||||
|
|
||||||
@item n
|
@item n
|
||||||
Set the number of samples which are printed on the same column. A
|
Set the number of samples which are printed on the same column. A
|
||||||
|
@ -32,6 +32,12 @@
|
|||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
enum ShowWavesMode {
|
||||||
|
MODE_POINT,
|
||||||
|
MODE_LINE,
|
||||||
|
MODE_NB,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
int w, h;
|
int w, h;
|
||||||
@ -42,6 +48,7 @@ typedef struct {
|
|||||||
int req_fullfilled;
|
int req_fullfilled;
|
||||||
int n;
|
int n;
|
||||||
int sample_count_mod;
|
int sample_count_mod;
|
||||||
|
enum ShowWavesMode mode;
|
||||||
} ShowWavesContext;
|
} ShowWavesContext;
|
||||||
|
|
||||||
#define OFFSET(x) offsetof(ShowWavesContext, x)
|
#define OFFSET(x) offsetof(ShowWavesContext, x)
|
||||||
@ -53,6 +60,10 @@ static const AVOption showwaves_options[] = {
|
|||||||
{ "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "600x240"}, 0, 0, FLAGS },
|
{ "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "600x240"}, 0, 0, FLAGS },
|
||||||
{ "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "600x240"}, 0, 0, FLAGS },
|
{ "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "600x240"}, 0, 0, FLAGS },
|
||||||
{ "n", "set how many samples to show in the same point", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS },
|
{ "n", "set how many samples to show in the same point", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS },
|
||||||
|
|
||||||
|
{"mode", "select display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_POINT}, 0, MODE_NB-1, FLAGS, "mode"},
|
||||||
|
{"point", "draw a point for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_POINT}, .flags=FLAGS, .unit="mode"},
|
||||||
|
{"line", "draw a line for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_LINE}, .flags=FLAGS, .unit="mode"},
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -187,7 +198,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
|||||||
int linesize = outpicref ? outpicref->linesize[0] : 0;
|
int linesize = outpicref ? outpicref->linesize[0] : 0;
|
||||||
int16_t *p = (int16_t *)insamples->data[0];
|
int16_t *p = (int16_t *)insamples->data[0];
|
||||||
int nb_channels = av_get_channel_layout_nb_channels(insamples->audio->channel_layout);
|
int nb_channels = av_get_channel_layout_nb_channels(insamples->audio->channel_layout);
|
||||||
int i, j, h;
|
int i, j, k, h;
|
||||||
const int n = showwaves->n;
|
const int n = showwaves->n;
|
||||||
const int x = 255 / (nb_channels * n); /* multiplication factor, pre-computed to avoid in-loop divisions */
|
const int x = 255 / (nb_channels * n); /* multiplication factor, pre-computed to avoid in-loop divisions */
|
||||||
|
|
||||||
@ -210,9 +221,23 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
|||||||
}
|
}
|
||||||
for (j = 0; j < nb_channels; j++) {
|
for (j = 0; j < nb_channels; j++) {
|
||||||
h = showwaves->h/2 - av_rescale(*p++, showwaves->h/2, MAX_INT16);
|
h = showwaves->h/2 - av_rescale(*p++, showwaves->h/2, MAX_INT16);
|
||||||
if (h >= 0 && h < outlink->h)
|
switch (showwaves->mode) {
|
||||||
*(outpicref->data[0] + showwaves->buf_idx + h * linesize) += x;
|
case MODE_POINT:
|
||||||
|
if (h >= 0 && h < outlink->h)
|
||||||
|
*(outpicref->data[0] + showwaves->buf_idx + h * linesize) += x;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODE_LINE:
|
||||||
|
{
|
||||||
|
int start = showwaves->h/2, end = av_clip(h, 0, outlink->h-1);
|
||||||
|
if (start > end) FFSWAP(int16_t, start, end);
|
||||||
|
for (k = start; k < end; k++)
|
||||||
|
*(outpicref->data[0] + showwaves->buf_idx + k * linesize) += x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showwaves->sample_count_mod++;
|
showwaves->sample_count_mod++;
|
||||||
if (showwaves->sample_count_mod == n) {
|
if (showwaves->sample_count_mod == n) {
|
||||||
showwaves->sample_count_mod = 0;
|
showwaves->sample_count_mod = 0;
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#define LIBAVFILTER_VERSION_MAJOR 3
|
#define LIBAVFILTER_VERSION_MAJOR 3
|
||||||
#define LIBAVFILTER_VERSION_MINOR 33
|
#define LIBAVFILTER_VERSION_MINOR 33
|
||||||
#define LIBAVFILTER_VERSION_MICRO 100
|
#define LIBAVFILTER_VERSION_MICRO 101
|
||||||
|
|
||||||
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
|
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
|
||||||
LIBAVFILTER_VERSION_MINOR, \
|
LIBAVFILTER_VERSION_MINOR, \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user