yading@10: /* yading@10: * Copyright (c) 2011 Stefano Sabatini yading@10: * yading@10: * This file is part of FFmpeg. yading@10: * yading@10: * FFmpeg is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * FFmpeg is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with FFmpeg; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: /** yading@10: * @file yading@10: * filter for showing textual audio frame information yading@10: */ yading@10: yading@10: #include yading@10: #include yading@10: yading@10: #include "libavutil/adler32.h" yading@10: #include "libavutil/channel_layout.h" yading@10: #include "libavutil/common.h" yading@10: #include "libavutil/mem.h" yading@10: #include "libavutil/timestamp.h" yading@10: #include "libavutil/samplefmt.h" yading@10: yading@10: #include "audio.h" yading@10: #include "avfilter.h" yading@10: #include "internal.h" yading@10: yading@10: typedef struct AShowInfoContext { yading@10: /** yading@10: * Scratch space for individual plane checksums for planar audio yading@10: */ yading@10: uint32_t *plane_checksums; yading@10: yading@10: /** yading@10: * Frame counter yading@10: */ yading@10: uint64_t frame; yading@10: } AShowInfoContext; yading@10: yading@10: static void uninit(AVFilterContext *ctx) yading@10: { yading@10: AShowInfoContext *s = ctx->priv; yading@10: av_freep(&s->plane_checksums); yading@10: } yading@10: yading@10: static int filter_frame(AVFilterLink *inlink, AVFrame *buf) yading@10: { yading@10: AVFilterContext *ctx = inlink->dst; yading@10: AShowInfoContext *s = ctx->priv; yading@10: char chlayout_str[128]; yading@10: uint32_t checksum = 0; yading@10: int channels = av_get_channel_layout_nb_channels(buf->channel_layout); yading@10: int planar = av_sample_fmt_is_planar(buf->format); yading@10: int block_align = av_get_bytes_per_sample(buf->format) * (planar ? 1 : channels); yading@10: int data_size = buf->nb_samples * block_align; yading@10: int planes = planar ? channels : 1; yading@10: int i; yading@10: void *tmp_ptr = av_realloc(s->plane_checksums, channels * sizeof(*s->plane_checksums)); yading@10: yading@10: if (!tmp_ptr) yading@10: return AVERROR(ENOMEM); yading@10: s->plane_checksums = tmp_ptr; yading@10: yading@10: for (i = 0; i < planes; i++) { yading@10: uint8_t *data = buf->extended_data[i]; yading@10: yading@10: s->plane_checksums[i] = av_adler32_update(0, data, data_size); yading@10: checksum = i ? av_adler32_update(checksum, data, data_size) : yading@10: s->plane_checksums[0]; yading@10: } yading@10: yading@10: av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), -1, yading@10: buf->channel_layout); yading@10: yading@10: av_log(ctx, AV_LOG_INFO, yading@10: "n:%"PRIu64" pts:%s pts_time:%s pos:%"PRId64" " yading@10: "fmt:%s channels:%d chlayout:%s rate:%d nb_samples:%d " yading@10: "checksum:%08X ", yading@10: s->frame, yading@10: av_ts2str(buf->pts), av_ts2timestr(buf->pts, &inlink->time_base), yading@10: av_frame_get_pkt_pos(buf), yading@10: av_get_sample_fmt_name(buf->format), av_frame_get_channels(buf), chlayout_str, yading@10: buf->sample_rate, buf->nb_samples, yading@10: checksum); yading@10: yading@10: av_log(ctx, AV_LOG_INFO, "plane_checksums: [ "); yading@10: for (i = 0; i < planes; i++) yading@10: av_log(ctx, AV_LOG_INFO, "%08X ", s->plane_checksums[i]); yading@10: av_log(ctx, AV_LOG_INFO, "]\n"); yading@10: yading@10: s->frame++; yading@10: return ff_filter_frame(inlink->dst->outputs[0], buf); yading@10: } yading@10: yading@10: static const AVFilterPad inputs[] = { yading@10: { yading@10: .name = "default", yading@10: .type = AVMEDIA_TYPE_AUDIO, yading@10: .get_audio_buffer = ff_null_get_audio_buffer, yading@10: .filter_frame = filter_frame, yading@10: }, yading@10: { NULL }, yading@10: }; yading@10: yading@10: static const AVFilterPad outputs[] = { yading@10: { yading@10: .name = "default", yading@10: .type = AVMEDIA_TYPE_AUDIO, yading@10: }, yading@10: { NULL }, yading@10: }; yading@10: yading@10: AVFilter avfilter_af_ashowinfo = { yading@10: .name = "ashowinfo", yading@10: .description = NULL_IF_CONFIG_SMALL("Show textual information for each audio frame."), yading@10: .priv_size = sizeof(AShowInfoContext), yading@10: .uninit = uninit, yading@10: .inputs = inputs, yading@10: .outputs = outputs, yading@10: };