00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include <inttypes.h>
00027 #include <stddef.h>
00028
00029 #include "libavutil/adler32.h"
00030 #include "libavutil/channel_layout.h"
00031 #include "libavutil/common.h"
00032 #include "libavutil/mem.h"
00033 #include "libavutil/timestamp.h"
00034 #include "libavutil/samplefmt.h"
00035
00036 #include "audio.h"
00037 #include "avfilter.h"
00038 #include "internal.h"
00039
00040 typedef struct AShowInfoContext {
00044 uint32_t *plane_checksums;
00045
00049 uint64_t frame;
00050 } AShowInfoContext;
00051
00052 static void uninit(AVFilterContext *ctx)
00053 {
00054 AShowInfoContext *s = ctx->priv;
00055 av_freep(&s->plane_checksums);
00056 }
00057
00058 static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
00059 {
00060 AVFilterContext *ctx = inlink->dst;
00061 AShowInfoContext *s = ctx->priv;
00062 char chlayout_str[128];
00063 uint32_t checksum = 0;
00064 int channels = av_get_channel_layout_nb_channels(buf->audio->channel_layout);
00065 int planar = av_sample_fmt_is_planar(buf->format);
00066 int block_align = av_get_bytes_per_sample(buf->format) * (planar ? 1 : channels);
00067 int data_size = buf->audio->nb_samples * block_align;
00068 int planes = planar ? channels : 1;
00069 int i;
00070 void *tmp_ptr = av_realloc(s->plane_checksums, channels * sizeof(*s->plane_checksums));
00071
00072 if (!tmp_ptr)
00073 return AVERROR(ENOMEM);
00074 s->plane_checksums = tmp_ptr;
00075
00076 for (i = 0; i < planes; i++) {
00077 uint8_t *data = buf->extended_data[i];
00078
00079 s->plane_checksums[i] = av_adler32_update(0, data, data_size);
00080 checksum = i ? av_adler32_update(checksum, data, data_size) :
00081 s->plane_checksums[0];
00082 }
00083
00084 av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), -1,
00085 buf->audio->channel_layout);
00086
00087 av_log(ctx, AV_LOG_INFO,
00088 "n:%"PRIu64" pts:%s pts_time:%s pos:%"PRId64" "
00089 "fmt:%s channels:%d chlayout:%s rate:%d nb_samples:%d "
00090 "checksum:%08X ",
00091 s->frame,
00092 av_ts2str(buf->pts), av_ts2timestr(buf->pts, &inlink->time_base),
00093 buf->pos,
00094 av_get_sample_fmt_name(buf->format), buf->audio->channels, chlayout_str,
00095 buf->audio->sample_rate, buf->audio->nb_samples,
00096 checksum);
00097
00098 av_log(ctx, AV_LOG_INFO, "plane_checksums: [ ");
00099 for (i = 0; i < planes; i++)
00100 av_log(ctx, AV_LOG_INFO, "%08X ", s->plane_checksums[i]);
00101 av_log(ctx, AV_LOG_INFO, "]\n");
00102
00103 s->frame++;
00104 return ff_filter_frame(inlink->dst->outputs[0], buf);
00105 }
00106
00107 static const AVFilterPad inputs[] = {
00108 {
00109 .name = "default",
00110 .type = AVMEDIA_TYPE_AUDIO,
00111 .get_audio_buffer = ff_null_get_audio_buffer,
00112 .filter_frame = filter_frame,
00113 .min_perms = AV_PERM_READ,
00114 },
00115 { NULL },
00116 };
00117
00118 static const AVFilterPad outputs[] = {
00119 {
00120 .name = "default",
00121 .type = AVMEDIA_TYPE_AUDIO,
00122 },
00123 { NULL },
00124 };
00125
00126 AVFilter avfilter_af_ashowinfo = {
00127 .name = "ashowinfo",
00128 .description = NULL_IF_CONFIG_SMALL("Show textual information for each audio frame."),
00129 .priv_size = sizeof(AShowInfoContext),
00130 .uninit = uninit,
00131 .inputs = inputs,
00132 .outputs = outputs,
00133 };