From 20dd41af8513de427b00ee598339c9bc5778bdc5 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 23 Oct 2012 21:37:26 +0200 Subject: lavfi: add ashowinfo filter It can be useful for debugging. Based on a patch by Stefano Sabatini --- libavfilter/af_ashowinfo.c | 136 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 libavfilter/af_ashowinfo.c (limited to 'libavfilter/af_ashowinfo.c') diff --git a/libavfilter/af_ashowinfo.c b/libavfilter/af_ashowinfo.c new file mode 100644 index 0000000000..00e0322f5c --- /dev/null +++ b/libavfilter/af_ashowinfo.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2011 Stefano Sabatini + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * filter for showing textual audio frame information + */ + +#include +#include + +#include "libavutil/adler32.h" +#include "libavutil/audioconvert.h" +#include "libavutil/common.h" +#include "libavutil/mem.h" +#include "libavutil/samplefmt.h" + +#include "audio.h" +#include "avfilter.h" + +typedef struct AShowInfoContext { + /** + * Scratch space for individual plane checksums for planar audio + */ + uint32_t *plane_checksums; + + /** + * Frame counter + */ + uint64_t frame; +} AShowInfoContext; + +static int config_input(AVFilterLink *inlink) +{ + AShowInfoContext *s = inlink->dst->priv; + int channels = av_get_channel_layout_nb_channels(inlink->channel_layout); + s->plane_checksums = av_malloc(channels * sizeof(*s->plane_checksums)); + if (!s->plane_checksums) + return AVERROR(ENOMEM); + + return 0; +} + +static void uninit(AVFilterContext *ctx) +{ + AShowInfoContext *s = ctx->priv; + av_freep(&s->plane_checksums); +} + +static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf) +{ + AVFilterContext *ctx = inlink->dst; + AShowInfoContext *s = ctx->priv; + char chlayout_str[128]; + uint32_t checksum = 0; + int channels = av_get_channel_layout_nb_channels(buf->audio->channel_layout); + int planar = av_sample_fmt_is_planar(buf->format); + int block_align = av_get_bytes_per_sample(buf->format) * (planar ? 1 : channels); + int data_size = buf->audio->nb_samples * block_align; + int planes = planar ? channels : 1; + int i; + + for (i = 0; i < planes; i++) { + uint8_t *data = buf->extended_data[i]; + + s->plane_checksums[i] = av_adler32_update(0, data, data_size); + checksum = i ? av_adler32_update(checksum, data, data_size) : + s->plane_checksums[0]; + } + + av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), -1, + buf->audio->channel_layout); + + av_log(ctx, AV_LOG_INFO, + "n:%"PRIu64" pts:%"PRId64" pts_time:%f " + "fmt:%s chlayout:%s rate:%d nb_samples:%d " + "checksum:%08X ", + s->frame, buf->pts, buf->pts * av_q2d(inlink->time_base), + av_get_sample_fmt_name(buf->format), chlayout_str, + buf->audio->sample_rate, buf->audio->nb_samples, + checksum); + + av_log(ctx, AV_LOG_INFO, "plane_checksums: [ "); + for (i = 0; i < planes; i++) + av_log(ctx, AV_LOG_INFO, "%08X ", s->plane_checksums[i]); + av_log(ctx, AV_LOG_INFO, "]\n"); + + s->frame++; + return ff_filter_samples(inlink->dst->outputs[0], buf); +} + +static const AVFilterPad inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .get_audio_buffer = ff_null_get_audio_buffer, + .config_props = config_input, + .filter_samples = filter_samples, + .min_perms = AV_PERM_READ, + }, + { NULL }, +}; + +static const AVFilterPad outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + }, + { NULL }, +}; + +AVFilter avfilter_af_ashowinfo = { + .name = "ashowinfo", + .description = NULL_IF_CONFIG_SMALL("Show textual information for each audio frame."), + .priv_size = sizeof(AShowInfoContext), + .uninit = uninit, + .inputs = inputs, + .outputs = outputs, +}; -- cgit v1.2.3