avfilter/showspectrum: add blackman window.
[ffmpeg.git] / libavfilter / af_ashowinfo.c
1 /*
2  * Copyright (c) 2011 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  * filter for showing textual audio frame information
24  */
25
26 #include <inttypes.h>
27 #include <stddef.h>
28
29 #include "libavutil/adler32.h"
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/common.h"
33 #include "libavutil/mem.h"
34 #include "libavutil/timestamp.h"
35 #include "libavutil/samplefmt.h"
36
37 #include "audio.h"
38 #include "avfilter.h"
39 #include "internal.h"
40
41 typedef struct AShowInfoContext {
42     /**
43      * Scratch space for individual plane checksums for planar audio
44      */
45     uint32_t *plane_checksums;
46 } AShowInfoContext;
47
48 static av_cold void uninit(AVFilterContext *ctx)
49 {
50     AShowInfoContext *s = ctx->priv;
51     av_freep(&s->plane_checksums);
52 }
53
54 static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
55 {
56     AVFilterContext *ctx = inlink->dst;
57     AShowInfoContext *s  = ctx->priv;
58     char chlayout_str[128];
59     uint32_t checksum = 0;
60     int channels    = inlink->channels;
61     int planar      = av_sample_fmt_is_planar(buf->format);
62     int block_align = av_get_bytes_per_sample(buf->format) * (planar ? 1 : channels);
63     int data_size   = buf->nb_samples * block_align;
64     int planes      = planar ? channels : 1;
65     int i;
66     void *tmp_ptr = av_realloc(s->plane_checksums, channels * sizeof(*s->plane_checksums));
67
68     if (!tmp_ptr)
69         return AVERROR(ENOMEM);
70     s->plane_checksums = tmp_ptr;
71
72     for (i = 0; i < planes; i++) {
73         uint8_t *data = buf->extended_data[i];
74
75         s->plane_checksums[i] = av_adler32_update(0, data, data_size);
76         checksum = i ? av_adler32_update(checksum, data, data_size) :
77                        s->plane_checksums[0];
78     }
79
80     av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), -1,
81                                  buf->channel_layout);
82
83     av_log(ctx, AV_LOG_INFO,
84            "n:%"PRId64" pts:%s pts_time:%s pos:%"PRId64" "
85            "fmt:%s channels:%d chlayout:%s rate:%d nb_samples:%d "
86            "checksum:%08X ",
87            inlink->frame_count,
88            av_ts2str(buf->pts), av_ts2timestr(buf->pts, &inlink->time_base),
89            av_frame_get_pkt_pos(buf),
90            av_get_sample_fmt_name(buf->format), av_frame_get_channels(buf), chlayout_str,
91            buf->sample_rate, buf->nb_samples,
92            checksum);
93
94     av_log(ctx, AV_LOG_INFO, "plane_checksums: [ ");
95     for (i = 0; i < planes; i++)
96         av_log(ctx, AV_LOG_INFO, "%08X ", s->plane_checksums[i]);
97     av_log(ctx, AV_LOG_INFO, "]\n");
98
99     return ff_filter_frame(inlink->dst->outputs[0], buf);
100 }
101
102 static const AVFilterPad inputs[] = {
103     {
104         .name         = "default",
105         .type         = AVMEDIA_TYPE_AUDIO,
106         .filter_frame = filter_frame,
107     },
108     { NULL }
109 };
110
111 static const AVFilterPad outputs[] = {
112     {
113         .name = "default",
114         .type = AVMEDIA_TYPE_AUDIO,
115     },
116     { NULL }
117 };
118
119 AVFilter ff_af_ashowinfo = {
120     .name        = "ashowinfo",
121     .description = NULL_IF_CONFIG_SMALL("Show textual information for each audio frame."),
122     .priv_size   = sizeof(AShowInfoContext),
123     .uninit      = uninit,
124     .inputs      = inputs,
125     .outputs     = outputs,
126 };