avf_showwaves.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Stefano Sabatini
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  * @file
23  * audio to video multimedia filter
24  */
25 
27 #include "libavutil/opt.h"
28 #include "libavutil/parseutils.h"
29 #include "avfilter.h"
30 #include "formats.h"
31 #include "audio.h"
32 #include "video.h"
33 #include "internal.h"
34 
39 };
40 
41 typedef struct {
42  const AVClass *class;
43  int w, h;
45  int buf_idx;
48  int n;
52 
53 #define OFFSET(x) offsetof(ShowWavesContext, x)
54 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
55 
56 static const AVOption showwaves_options[] = {
57  { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "600x240"}, 0, 0, FLAGS },
58  { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "600x240"}, 0, 0, FLAGS },
59  { "mode", "select display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_POINT}, 0, MODE_NB-1, FLAGS, "mode"},
60  { "point", "draw a point for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_POINT}, .flags=FLAGS, .unit="mode"},
61  { "line", "draw a line for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_LINE}, .flags=FLAGS, .unit="mode"},
62  { "n", "set how many samples to show in the same point", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS },
63  { "rate", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },
64  { "r", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },
65  { NULL },
66 };
67 
68 AVFILTER_DEFINE_CLASS(showwaves);
69 
70 static av_cold void uninit(AVFilterContext *ctx)
71 {
72  ShowWavesContext *showwaves = ctx->priv;
73 
74  av_frame_free(&showwaves->outpicref);
75 }
76 
78 {
81  AVFilterLink *inlink = ctx->inputs[0];
82  AVFilterLink *outlink = ctx->outputs[0];
84  static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
85 
86  /* set input audio formats */
87  formats = ff_make_format_list(sample_fmts);
88  if (!formats)
89  return AVERROR(ENOMEM);
90  ff_formats_ref(formats, &inlink->out_formats);
91 
92  layouts = ff_all_channel_layouts();
93  if (!layouts)
94  return AVERROR(ENOMEM);
96 
97  formats = ff_all_samplerates();
98  if (!formats)
99  return AVERROR(ENOMEM);
100  ff_formats_ref(formats, &inlink->out_samplerates);
101 
102  /* set output video format */
103  formats = ff_make_format_list(pix_fmts);
104  if (!formats)
105  return AVERROR(ENOMEM);
106  ff_formats_ref(formats, &outlink->in_formats);
107 
108  return 0;
109 }
110 
111 static int config_output(AVFilterLink *outlink)
112 {
113  AVFilterContext *ctx = outlink->src;
114  AVFilterLink *inlink = ctx->inputs[0];
115  ShowWavesContext *showwaves = ctx->priv;
116 
117  if (!showwaves->n)
118  showwaves->n = FFMAX(1, ((double)inlink->sample_rate / (showwaves->w * av_q2d(showwaves->rate))) + 0.5);
119 
120  showwaves->buf_idx = 0;
121  outlink->w = showwaves->w;
122  outlink->h = showwaves->h;
123  outlink->sample_aspect_ratio = (AVRational){1,1};
124 
125  outlink->frame_rate = av_div_q((AVRational){inlink->sample_rate,showwaves->n},
126  (AVRational){showwaves->w,1});
127 
128  av_log(ctx, AV_LOG_VERBOSE, "s:%dx%d r:%f n:%d\n",
129  showwaves->w, showwaves->h, av_q2d(outlink->frame_rate), showwaves->n);
130  return 0;
131 }
132 
133 inline static int push_frame(AVFilterLink *outlink)
134 {
135  ShowWavesContext *showwaves = outlink->src->priv;
136  int ret;
137 
138  if ((ret = ff_filter_frame(outlink, showwaves->outpicref)) >= 0)
139  showwaves->req_fullfilled = 1;
140  showwaves->outpicref = NULL;
141  showwaves->buf_idx = 0;
142  return ret;
143 }
144 
145 static int request_frame(AVFilterLink *outlink)
146 {
147  ShowWavesContext *showwaves = outlink->src->priv;
148  AVFilterLink *inlink = outlink->src->inputs[0];
149  int ret;
150 
151  showwaves->req_fullfilled = 0;
152  do {
153  ret = ff_request_frame(inlink);
154  } while (!showwaves->req_fullfilled && ret >= 0);
155 
156  if (ret == AVERROR_EOF && showwaves->outpicref)
157  push_frame(outlink);
158  return ret;
159 }
160 
161 #define MAX_INT16 ((1<<15) -1)
162 
163 static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
164 {
165  AVFilterContext *ctx = inlink->dst;
166  AVFilterLink *outlink = ctx->outputs[0];
167  ShowWavesContext *showwaves = ctx->priv;
168  const int nb_samples = insamples->nb_samples;
169  AVFrame *outpicref = showwaves->outpicref;
170  int linesize = outpicref ? outpicref->linesize[0] : 0;
171  int16_t *p = (int16_t *)insamples->data[0];
173  int i, j, k, h, ret = 0;
174  const int n = showwaves->n;
175  const int x = 255 / (nb_channels * n); /* multiplication factor, pre-computed to avoid in-loop divisions */
176 
177  /* draw data in the buffer */
178  for (i = 0; i < nb_samples; i++) {
179  if (!showwaves->outpicref) {
180  showwaves->outpicref = outpicref =
181  ff_get_video_buffer(outlink, outlink->w, outlink->h);
182  if (!outpicref)
183  return AVERROR(ENOMEM);
184  outpicref->width = outlink->w;
185  outpicref->height = outlink->h;
186  outpicref->pts = insamples->pts +
187  av_rescale_q((p - (int16_t *)insamples->data[0]) / nb_channels,
188  (AVRational){ 1, inlink->sample_rate },
189  outlink->time_base);
190  linesize = outpicref->linesize[0];
191  memset(outpicref->data[0], 0, showwaves->h*linesize);
192  }
193  for (j = 0; j < nb_channels; j++) {
194  h = showwaves->h/2 - av_rescale(*p++, showwaves->h/2, MAX_INT16);
195  switch (showwaves->mode) {
196  case MODE_POINT:
197  if (h >= 0 && h < outlink->h)
198  *(outpicref->data[0] + showwaves->buf_idx + h * linesize) += x;
199  break;
200 
201  case MODE_LINE:
202  {
203  int start = showwaves->h/2, end = av_clip(h, 0, outlink->h-1);
204  if (start > end) FFSWAP(int16_t, start, end);
205  for (k = start; k < end; k++)
206  *(outpicref->data[0] + showwaves->buf_idx + k * linesize) += x;
207  break;
208  }
209  }
210  }
211 
212  showwaves->sample_count_mod++;
213  if (showwaves->sample_count_mod == n) {
214  showwaves->sample_count_mod = 0;
215  showwaves->buf_idx++;
216  }
217  if (showwaves->buf_idx == showwaves->w)
218  if ((ret = push_frame(outlink)) < 0)
219  break;
220  outpicref = showwaves->outpicref;
221  }
222 
223  av_frame_free(&insamples);
224  return ret;
225 }
226 
227 static const AVFilterPad showwaves_inputs[] = {
228  {
229  .name = "default",
230  .type = AVMEDIA_TYPE_AUDIO,
231  .filter_frame = filter_frame,
232  },
233  { NULL }
234 };
235 
236 static const AVFilterPad showwaves_outputs[] = {
237  {
238  .name = "default",
239  .type = AVMEDIA_TYPE_VIDEO,
240  .config_props = config_output,
241  .request_frame = request_frame,
242  },
243  { NULL }
244 };
245 
247  .name = "showwaves",
248  .description = NULL_IF_CONFIG_SMALL("Convert input audio to a video output."),
249  .uninit = uninit,
250  .query_formats = query_formats,
251  .priv_size = sizeof(ShowWavesContext),
252  .inputs = showwaves_inputs,
253  .outputs = showwaves_outputs,
254  .priv_class = &showwaves_class,
255 };
Definition: start.py:1
ShowWavesMode
Definition: avf_showwaves.c:35
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
AVOption.
Definition: opt.h:251
static const AVFilterPad outputs[]
Definition: af_ashowinfo.c:117
#define OFFSET(x)
Definition: avf_showwaves.c:53
external API header
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
signed 16 bits
Definition: samplefmt.h:52
output residual component w
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:308
AVFilter avfilter_avf_showwaves
const char * name
Pad name.
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:532
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
#define av_cold
Definition: attributes.h:78
mode
Definition: f_perms.c:27
AVOptions.
end end
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:159
static av_cold void uninit(AVFilterContext *ctx)
Definition: avf_showwaves.c:70
void ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:427
static double av_q2d(AVRational a)
Convert rational to double.
Definition: rational.h:69
#define AVERROR_EOF
End of file.
Definition: error.h:55
A filter pad used for either input or output.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:130
Discrete Time axis x
AVRational rate
Definition: avf_showwaves.c:44
int width
width and height of the video frame
Definition: frame.h:122
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition: rational.c:88
void * priv
private data for use by the filter
Definition: avfilter.h:545
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
#define FFMAX(a, b)
Definition: common.h:56
uint64_t channel_layout
Channel layout of the audio data.
Definition: frame.h:331
#define AV_LOG_VERBOSE
Definition: log.h:157
AVFrame * outpicref
Definition: avf_showwaves.c:46
struct AVRational AVRational
rational number numerator/denominator
audio channel layout utility functions
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:118
ret
Definition: avfilter.c:821
AVFilterChannelLayouts * ff_all_channel_layouts(void)
Construct an empty AVFilterChannelLayouts/AVFilterFormats struct – representing any channel layout (...
Definition: formats.c:402
A list of supported channel layouts.
Definition: formats.h:85
for k
NULL
Definition: eval.c:55
static const AVFilterPad showwaves_outputs[]
void ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:432
static int config_output(AVFilterLink *outlink)
static int push_frame(AVFilterLink *outlink)
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
static int request_frame(AVFilterLink *outlink)
AVFILTER_DEFINE_CLASS(showwaves)
Describe the class of an AVClass context structure.
Definition: log.h:50
Filter definition.
Definition: avfilter.h:436
synthesis window for stochastic i
rational number numerator/denominator
Definition: rational.h:43
static int query_formats(AVFilterContext *ctx)
Definition: avf_showwaves.c:77
offset must point to AVRational
Definition: opt.h:233
const char * name
filter name
Definition: avfilter.h:437
offset must point to two consecutive integers
Definition: opt.h:230
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
misc parsing utilities
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:539
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:396
#define MAX_INT16
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
static const AVFilterPad showwaves_inputs[]
Y , 8bpp.
Definition: pixfmt.h:76
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
AVSampleFormat
Audio Sample Formats.
Definition: samplefmt.h:49
enum ShowWavesMode mode
Definition: avf_showwaves.c:50
#define FLAGS
Definition: avf_showwaves.c:54
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
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:700
int height
Definition: frame.h:122
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:319
#define FFSWAP(type, a, b)
Definition: common.h:61
int nb_channels
internal API functions
static const AVOption showwaves_options[]
Definition: avf_showwaves.c:56
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
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
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:127