diff options
author | Anton Khirnov <anton@khirnov.net> | 2012-10-23 21:37:26 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2012-10-29 21:29:58 +0100 |
commit | 20dd41af8513de427b00ee598339c9bc5778bdc5 (patch) | |
tree | fd749810dc37b040c215e399941474189023413a | |
parent | 9b500b8f6c9806f3979f9d1fb874b7f4a802c656 (diff) | |
download | ffmpeg-20dd41af8513de427b00ee598339c9bc5778bdc5.tar.gz |
lavfi: add ashowinfo filter
It can be useful for debugging.
Based on a patch by Stefano Sabatini <stefano.sabatini-lala@poste.it>
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | doc/filters.texi | 41 | ||||
-rw-r--r-- | libavfilter/Makefile | 1 | ||||
-rw-r--r-- | libavfilter/af_ashowinfo.c | 136 | ||||
-rw-r--r-- | libavfilter/allfilters.c | 1 | ||||
-rw-r--r-- | libavfilter/version.h | 2 |
6 files changed, 181 insertions, 1 deletions
@@ -4,6 +4,7 @@ releases are sorted from youngest to oldest. version <next>: - metadata (INFO tag) support in WAV muxer - support for building DLLs using MSVC +- ashowinfo audio filter version 9_beta1: diff --git a/doc/filters.texi b/doc/filters.texi index 8f90e84956..85c8ae0b9b 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -175,6 +175,47 @@ stream ends. The default value is 2 seconds. Pass the audio source unchanged to the output. +@section ashowinfo + +Show a line containing various information for each input audio frame. +The input audio is not modified. + +The shown line contains a sequence of key/value pairs of the form +@var{key}:@var{value}. + +A description of each shown parameter follows: + +@table @option +@item n +sequential number of the input frame, starting from 0 + +@item pts +Presentation timestamp of the input frame, in time base units; the time base +depends on the filter input pad, and is usually 1/@var{sample_rate}. + +@item pts_time +presentation timestamp of the input frame in seconds + +@item fmt +sample format + +@item chlayout +channel layout + +@item rate +sample rate for the audio frame + +@item nb_samples +number of samples (per channel) in the frame + +@item checksum +Adler-32 checksum (printed in hexadecimal) of the audio data. For planar audio +the data is treated as if all the planes were concatenated. + +@item plane_checksums +A list of Adler-32 checksums for each data plane. +@end table + @section asplit Split input audio into several identical outputs. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 530aa576ae..9770e1ffc9 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -28,6 +28,7 @@ OBJS-$(CONFIG_AFIFO_FILTER) += fifo.o OBJS-$(CONFIG_AFORMAT_FILTER) += af_aformat.o OBJS-$(CONFIG_AMIX_FILTER) += af_amix.o OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o +OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o OBJS-$(CONFIG_ASPLIT_FILTER) += split.o OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o OBJS-$(CONFIG_CHANNELMAP_FILTER) += af_channelmap.o 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 <inttypes.h> +#include <stddef.h> + +#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, +}; diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 94b31154df..e7599315a7 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -39,6 +39,7 @@ void avfilter_register_all(void) REGISTER_FILTER (AFORMAT, aformat, af); REGISTER_FILTER (AMIX, amix, af); REGISTER_FILTER (ANULL, anull, af); + REGISTER_FILTER (ASHOWINFO, ashowinfo, af); REGISTER_FILTER (ASPLIT, asplit, af); REGISTER_FILTER (ASYNCTS, asyncts, af); REGISTER_FILTER (CHANNELMAP, channelmap, af); diff --git a/libavfilter/version.h b/libavfilter/version.h index 0e72a47916..eb5326bda8 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBAVFILTER_VERSION_MAJOR 3 -#define LIBAVFILTER_VERSION_MINOR 1 +#define LIBAVFILTER_VERSION_MINOR 2 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |