Mercurial > mplayer.hg
changeset 28661:20787bd5c506
Add statistics audio filter that prints information about the audio stream.
patch by Nicolas George, nicolas.george normalesup org
author | diego |
---|---|
date | Sat, 21 Feb 2009 21:27:27 +0000 |
parents | 0812215421d7 |
children | 595d419c0610 |
files | Changelog DOCS/man/en/mplayer.1 Makefile libaf/af.c libaf/af_stats.c |
diffstat | 5 files changed, 169 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/Changelog Sat Feb 21 21:03:57 2009 +0000 +++ b/Changelog Sat Feb 21 21:27:27 2009 +0000 @@ -62,6 +62,7 @@ * change vf_screenshot dependency from libpng to lavc * add af_scaletempo which maintains audio pitch when changing playback speed * fix multi-channel reordering + * af_stats, filter to print information about the audio stream Streaming: * tv:// support for Windows
--- a/DOCS/man/en/mplayer.1 Sat Feb 21 21:03:57 2009 +0000 +++ b/DOCS/man/en/mplayer.1 Sat Feb 21 21:27:27 2009 +0000 @@ -5486,6 +5486,13 @@ .RE .PD 1 . +.TP +.B "stats\ \ " +Collects and prints statistics about the audio stream, especially the volume. +These statistics are especially intended to help adjusting the volume while +avoiding clipping. +The volumes are printed in dB and compatible with the volume audio filter. +. . . .SH "VIDEO FILTERS"
--- a/Makefile Sat Feb 21 21:03:57 2009 +0000 +++ b/Makefile Sat Feb 21 21:27:27 2009 +0000 @@ -68,6 +68,7 @@ libaf/af_resample.c \ libaf/af_scaletempo.c \ libaf/af_sinesuppress.c \ + libaf/af_stats.c \ libaf/af_sub.c \ libaf/af_surround.c \ libaf/af_sweep.c \
--- a/libaf/af.c Sat Feb 21 21:03:57 2009 +0000 +++ b/libaf/af.c Sat Feb 21 21:27:27 2009 +0000 @@ -51,6 +51,7 @@ extern af_info_t af_info_sinesuppress; extern af_info_t af_info_karaoke; extern af_info_t af_info_scaletempo; +extern af_info_t af_info_stats; static af_info_t* filter_list[]={ &af_info_dummy, @@ -85,6 +86,7 @@ &af_info_sinesuppress, &af_info_karaoke, &af_info_scaletempo, + &af_info_stats, NULL };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libaf/af_stats.c Sat Feb 21 21:27:27 2009 +0000 @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2009 Nicolas George <nicolas.george@normalesup.org> + * + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <inttypes.h> +#include <math.h> + +#include "af.h" + +#define MAX_DB 80 +#define MIN_VAL 1E-8 + +struct af_stats +{ + long long n_samples; + double tsquare; + int max; + long long histogram[65536]; +}; + +static inline int logdb(double v) +{ + return v > 1 ? 0 : v <= MIN_VAL ? MAX_DB - 1 : + log(v) / -0.23025850929940456840179914546843642076; +} + +static int stats_init(af_instance_t *af, struct af_stats *s, af_data_t *data) +{ + int i; + + if (!data) + return AF_ERROR; + *(af->data) = *data; + af->data->format = AF_FORMAT_S16_NE; + af->data->bps = 2; + s->n_samples = 0; + s->tsquare = 0; + s->max = 0; + for (i = 0; i < 65536; i++) + s->histogram[i] = 0; + return af_test_output(af, data); +} + +static void stats_print(struct af_stats *s) +{ + int i; + long long sum; + float v; + long long h[MAX_DB]; + + s->tsquare /= 32768 * 32768; + mp_msg(MSGT_AFILTER, MSGL_INFO, "stats: n_samples: %lld\n", s->n_samples); + if (s->n_samples == 0) + return; + mp_msg(MSGT_AFILTER, MSGL_INFO, "stats: mean_volume: -%d dB\n", + logdb(s->tsquare / s->n_samples)); + mp_msg(MSGT_AFILTER, MSGL_INFO, "stats: max_volume: -%d dB\n", + logdb(s->max / 32768.0)); + for (i = 0; i < MAX_DB; i++) + h[i] = 0; + for (i = 0; i < 65536; i++) { + v = (i - 32768) / 32768.0; + h[logdb(v * v)] += s->histogram[i]; + } + for (i = 0; i < MAX_DB; i++) + if (h[i] != 0) + break; + sum = 0; + for (; i < MAX_DB; i++) { + sum += h[i]; + mp_msg(MSGT_AFILTER, MSGL_INFO, "stats:histogram_%ddb: %lld\n", + i, h[i]); + if (sum > s->n_samples / 1000) + break; + } +} + +static int control(struct af_instance_s *af, int cmd, void *arg) +{ + struct af_stats *s = (struct af_stats *)af->setup; + + switch(cmd) { + case AF_CONTROL_REINIT: + return stats_init(af, s, arg); + + case AF_CONTROL_PRE_DESTROY: + stats_print(s); + return AF_OK; + } + return AF_UNKNOWN; +} + +static void uninit(struct af_instance_s *af) +{ + if (af->data) + free(af->data); + if (af->setup) + free(af->setup); +} + +static af_data_t *play(struct af_instance_s *af, af_data_t *data) +{ + struct af_stats *s = (struct af_stats *)af->setup; + int16_t *a, *aend; + int v, v2; + + a = data->audio; + aend = (int16_t *)((char *)data->audio + data->len); + s->n_samples += aend - a; + for (; a < aend; a++) { + v = *a; + v2 = v * v; + s->tsquare += v2; + s->histogram[v + 32768]++; + if (v2 > s->max) + s->max = v2; + } + return data; +} + +static int af_open(af_instance_t* af){ + af->control = control; + af->uninit = uninit; + af->play = play; + af->mul = 1; + af->data = malloc(sizeof(af_data_t)); + af->setup = malloc(sizeof(struct af_stats)); + if (af->data == NULL || af->setup == NULL) + return AF_ERROR; + return AF_OK; +} + +af_info_t af_info_stats = { + "Statistics audio filter", + "stats", + "Nicolas George", + "", + 0, + af_open +};