On Mon, 31 Mar 2014 12:48:57 +0200, Alessandro Ghedini <[email protected]> 
wrote:
> According to the ReplayGain spec, the peak amplitude may overflow and may 
> result
> in peak amplitude values greater than 1.0 with psychoacoustically coded audio,
> such as MP3. Fully compliant decoders must allow peak overflows.
> 
> Additionally, having peak values in the 0<->UINT32_MAX scale makes it more
> difficult for applications to actually use the peak values (e.g. when
> implementing clipping prevention) since values have to be rescaled down.
> 
> This patch corrects the peak parsing by removing the rescaling of the decoded
> values between 0 and UINT32_MAX and the 1.0 upper limit.
> ---
> Merged parse_gain() and parse_peak() into parse_value(), lavu minor version
> bump, APIchanges update, better peak documentation in replaygain.h
> 
>  doc/APIchanges           |  4 ++++
>  libavformat/replaygain.c | 56 
> +++++++++++-------------------------------------
>  libavutil/replaygain.h   |  4 ++--
>  libavutil/version.h      |  2 +-
>  4 files changed, 20 insertions(+), 46 deletions(-)
> 
> diff --git a/doc/APIchanges b/doc/APIchanges
> index d800253..e999c7e 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -13,6 +13,10 @@ libavutil:     2013-12-xx
>  
>  API changes, most recent first:
>  
> +2014-03-xx - xxxxxxx - lavu 53.09.0 - replaygain.h
> +  Full scale for peak values is now 100000 (instead of UINT32_MAX) and values
> +  may overflow.
> +
>  2014-02-xx - xxxxxxx - lavu 53.08.0 - frame.h
>    Add av_frame_remove_side_data() for removing a single side data
>    instance from a frame.
> diff --git a/libavformat/replaygain.c b/libavformat/replaygain.c
> index cf4dbf8..5e4bccd 100644
> --- a/libavformat/replaygain.c
> +++ b/libavformat/replaygain.c
> @@ -35,19 +35,19 @@
>  #include "avformat.h"
>  #include "replaygain.h"
>  
> -static int32_t parse_gain(const char *gain)
> +static int32_t parse_value(const char *value, int32_t min)
>  {
>      char *fraction;
>      int  scale = 10000;
>      int32_t mb = 0;
>      int db;
>  
> -    if (!gain)
> -        return INT32_MIN;
> +    if (!value)
> +        return min;
>  
> -    gain += strspn(gain, " \t");
> +    value += strspn(value, " \t");
>  
> -    db = strtol(gain, &fraction, 0);
> +    db = strtol(value, &fraction, 0);
>      if (*fraction++ == '.') {
>          while (av_isdigit(*fraction) && scale) {
>              mb += scale * (*fraction - '0');
> @@ -57,41 +57,11 @@ static int32_t parse_gain(const char *gain)
>      }
>  
>      if (abs(db) > (INT32_MAX - mb) / 100000)
> -        return INT32_MIN;
> +        return min;
>  
> -    return db * 100000 + FFSIGN(db) * mb;
> -}
> -
> -static uint32_t parse_peak(const uint8_t *peak)
> -{
> -    int64_t val = 0;
> -    int64_t scale = 1;
> -
> -    if (!peak)
> -        return 0;
> -
> -    peak += strspn(peak, " \t");
> -
> -    if (peak[0] == '1' && peak[1] == '.')
> -        return UINT32_MAX;
> -    else if (!(peak[0] == '0' && peak[1] == '.'))
> -        return 0;
> -
> -    peak += 2;
> -
> -    while (av_isdigit(*peak)) {
> -        int digit = *peak - '0';
> -
> -        if (scale > INT64_MAX / 10)
> -            break;
> -
> -        val    = 10 * val + digit;
> -        scale *= 10;
> -
> -        peak++;
> -    }
> -
> -    return av_rescale(val, UINT32_MAX, scale);
> +    return (min == 0) ?
> +            db * 100000 + mb :
> +            db * 100000 + FFSIGN(db) * mb;

Why the check here?
It will only make a difference if db is negative, in which case the result will
be borked anyway.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to