Re: [FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder

2020-02-19 Thread Lynne
Feb 19, 2020, 17:58 by jamr...@gmail.com:

 +AVCodec ff_siren_decoder = {
 +.name   = "siren",
 +.long_name  = NULL_IF_CONFIG_SMALL("Siren"),
 +.priv_data_size = sizeof(SirenContext),
 +.type   = AVMEDIA_TYPE_AUDIO,
 +.id = AV_CODEC_ID_SIREN,
 +.init   = siren_init,
 +.close  = siren_close,
 +.decode = siren_decode,

>>>
>>> Missing a flush() function to clear s->backup_frame, s->imdct_in,
>>> s->imdct_out and s->imdct_prev.
>>>
>>
>> DO not like that.
>>

You kind of need to do that to support proper seeking.
You can keep s->imdct_in as is however since I don't see it used as anything 
other than per-frame storage.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder

2020-02-19 Thread James Almer
On 2/19/2020 1:50 PM, Paul B Mahol wrote:
> On 2/19/20, James Almer  wrote:
>> On 2/19/2020 7:30 AM, Paul B Mahol wrote:
>>> Signed-off-by: Paul B Mahol 
>>> +static int siren_decode(AVCodecContext *avctx, void *data,
>>> +int *got_frame, AVPacket *avpkt)
>>> +{
>>> +SirenContext *s = avctx->priv_data;
>>> +GetBitContext *gb = >gb;
>>> +AVFrame *frame = data;
>>> +int ret, number_of_valid_coefs = 20 * s->number_of_regions;
>>> +int frame_error = 0, rate_control = 0;
>>> +
>>> +if ((ret = init_get_bits8(gb, avpkt->data, avpkt->size)) < 0)
>>> +return ret;
>>> +
>>> +decode_envelope(s, gb, s->number_of_regions,
>>> +s->decoder_standard_deviation,
>>> +s->absolute_region_power_index, s->esf_adjustment);
>>> +
>>> +rate_control = get_bits(gb, 4);
>>> +
>>> +categorize_regions(s->number_of_regions, get_bits_left(gb),
>>> +   s->absolute_region_power_index,
>>> s->power_categories,
>>> +   s->category_balance);
>>> +
>>> +for (int i = 0; i < rate_control; i++) {
>>> +s->power_categories[s->category_balance[i]]++;
>>> +}
>>> +
>>> +ret = decode_vector(s, s->number_of_regions, get_bits_left(gb),
>>> +s->decoder_standard_deviation,
>>> s->power_categories,
>>> +s->imdct_in, s->scale_factor);
>>> +if (ret < 0)
>>> +return ret;
>>> +
>>> +if (get_bits_left(gb) > 0) {
>>> +do {
>>> +if (!get_bits1(gb))
>>> +frame_error = 1;
>>> +} while (get_bits_left(gb) > 0);
>>> +} else if (get_bits_left(gb) < 0 &&
>>> +   rate_control + 1 < s->rate_control_possibilities) {
>>> +frame_error |= 2;
>>> +}
>>> +
>>> +for (int i = 0; i < s->number_of_regions; i++) {
>>> +if (s->absolute_region_power_index[i] > 33 ||
>>> +s->absolute_region_power_index[i] < -31)
>>> +frame_error |= 4;
>>> +}
>>> +
>>> +if (frame_error) {
>>
>> You're not really doing anything different depending on the kind of
>> error you saw above, so may as well just make frame_error 0 or 1.
> 
> DO not like that.
> 
>>
>> Also, you may want to abort decoding if err_detect is set to explode.
> 
> DO not like that.
> 
>>
>>> +for (int i = 0; i < number_of_valid_coefs; i++) {
>>> +s->imdct_in[i] = s->backup_frame[i];
>>> +s->backup_frame[i] = 0;
>>> +}
>>> +} else {
>>> +for (int i = 0; i < number_of_valid_coefs; i++)
>>> +s->backup_frame[i] = s->imdct_in[i];
>>> +}
>>> +
>>> +frame->nb_samples = FRAME_SIZE;
>>> +if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
>>> +return ret;
>>> +
>>> +for (int i = 0; i < 320; i += 2)
>>> +s->imdct_in[i] *= -1;
>>> +
>>> +s->tx_fn(s->tx_ctx, s->imdct_out, s->imdct_in, sizeof(float));
>>> +s->fdsp->vector_fmul_window((float *)frame->data[0],
>>> +s->imdct_prev + (FRAME_SIZE >> 1),
>>> +s->imdct_out, s->window,
>>> +FRAME_SIZE >> 1);
>>> +FFSWAP(float *, s->imdct_out, s->imdct_prev);
>>
>> Instead of this, can't you keep an AVFrame reference in SirenContext and
>> use ff_reget_buffer()? With or without read only flag depending on
>> frame_error.
> 
> DO not like that.
> 
>>
>>> +
>>> +*got_frame = 1;
>>> +
>>> +return avpkt->size;
>>> +}
>>> +
>>> +static av_cold int siren_close(AVCodecContext *avctx)
>>> +{
>>> +SirenContext *s = avctx->priv_data;
>>> +
>>> +av_freep(>fdsp);
>>> +av_tx_uninit(>tx_ctx);
>>> +
>>> +return 0;
>>> +}
>>> +
>>> +AVCodec ff_siren_decoder = {
>>> +.name   = "siren",
>>> +.long_name  = NULL_IF_CONFIG_SMALL("Siren"),
>>> +.priv_data_size = sizeof(SirenContext),
>>> +.type   = AVMEDIA_TYPE_AUDIO,
>>> +.id = AV_CODEC_ID_SIREN,
>>> +.init   = siren_init,
>>> +.close  = siren_close,
>>> +.decode = siren_decode,
>>
>> Missing a flush() function to clear s->backup_frame, s->imdct_in,
>> s->imdct_out and s->imdct_prev.
> 
> DO not like that.
>>
>>> +.capabilities   = AV_CODEC_CAP_DR1,
>>
>> Also init thread safe caps_internal.
> DO not like that.

At some point you'll have to realize there's a difference between being
funny and being insufferable.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder

2020-02-19 Thread Paul B Mahol
On 2/19/20, James Almer  wrote:
> On 2/19/2020 7:30 AM, Paul B Mahol wrote:
>> Signed-off-by: Paul B Mahol 
>> ---
>>  libavcodec/Makefile |   1 +
>>  libavcodec/allcodecs.c  |   1 +
>>  libavcodec/avcodec.h|   1 +
>>  libavcodec/codec_desc.c |   7 +
>>  libavcodec/siren.c  | 776 
>>  libavformat/vivo.c  |   5 +
>>  6 files changed, 791 insertions(+)
>>  create mode 100644 libavcodec/siren.c
>>
>> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
>> index 46da42570f..2dae3b2d5d 100644
>> --- a/libavcodec/Makefile
>> +++ b/libavcodec/Makefile
>> @@ -584,6 +584,7 @@ OBJS-$(CONFIG_SIPR_DECODER)+= sipr.o
>> acelp_pitch_delay.o \
>>celp_math.o acelp_vectors.o \
>>acelp_filters.o celp_filters.o
>> \
>>sipr16k.o
>> +OBJS-$(CONFIG_SIREN_DECODER)   += siren.o
>>  OBJS-$(CONFIG_SMACKAUD_DECODER)+= smacker.o
>>  OBJS-$(CONFIG_SMACKER_DECODER) += smacker.o
>>  OBJS-$(CONFIG_SMC_DECODER) += smc.o
>> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
>> index 103f34fd32..94e196202a 100644
>> --- a/libavcodec/allcodecs.c
>> +++ b/libavcodec/allcodecs.c
>> @@ -474,6 +474,7 @@ extern AVCodec ff_sbc_encoder;
>>  extern AVCodec ff_sbc_decoder;
>>  extern AVCodec ff_shorten_decoder;
>>  extern AVCodec ff_sipr_decoder;
>> +extern AVCodec ff_siren_decoder;
>>  extern AVCodec ff_smackaud_decoder;
>>  extern AVCodec ff_sonic_encoder;
>>  extern AVCodec ff_sonic_decoder;
>> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
>> index 368341ba93..978f36d12a 100644
>> --- a/libavcodec/avcodec.h
>> +++ b/libavcodec/avcodec.h
>> @@ -661,6 +661,7 @@ enum AVCodecID {
>>  AV_CODEC_ID_HCOM,
>>  AV_CODEC_ID_ACELP_KELVIN,
>>  AV_CODEC_ID_MPEGH_3D_AUDIO,
>> +AV_CODEC_ID_SIREN,
>>
>>  /* subtitle codecs */
>>  AV_CODEC_ID_FIRST_SUBTITLE = 0x17000,  ///< A dummy ID
>> pointing at the start of subtitle codecs.
>> diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
>> index 609c7501fd..89bdfa3fce 100644
>> --- a/libavcodec/codec_desc.c
>> +++ b/libavcodec/codec_desc.c
>> @@ -3044,6 +3044,13 @@ static const AVCodecDescriptor codec_descriptors[]
>> = {
>>  .long_name = NULL_IF_CONFIG_SMALL("MPEG-H 3D Audio"),
>>  .props = AV_CODEC_PROP_LOSSY,
>>  },
>> +{
>> +.id= AV_CODEC_ID_SIREN,
>> +.type  = AVMEDIA_TYPE_AUDIO,
>> +.name  = "siren",
>> +.long_name = NULL_IF_CONFIG_SMALL("Siren"),
>> +.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
>> +},
>>
>>  /* subtitle codecs */
>>  {
>> diff --git a/libavcodec/siren.c b/libavcodec/siren.c
>> new file mode 100644
>> index 00..8bff7729df
>> --- /dev/null
>> +++ b/libavcodec/siren.c
>> @@ -0,0 +1,776 @@
>> +/*
>> + * Siren audio decoder
>> + * Copyright (c) 2012 Youness Alaoui 
>> + * Copyright (c) 2018 Paul B Mahol
>> + * Copyright (c) 2019 Lynne 
>> + *
>> + * This file is part of FFmpeg.
>> + *
>> + * FFmpeg 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.
>> + *
>> + * FFmpeg 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 FFmpeg; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> 02110-1301 USA
>> + */
>> +
>> +#include "libavutil/tx.h"
>> +#include "libavutil/float_dsp.h"
>> +
>> +#include "avcodec.h"
>> +#include "get_bits.h"
>> +#include "internal.h"
>> +#include "mathops.h"
>> +
>> +static const uint8_t index_table[8] = {4, 4, 3, 3, 2, 2, 1, 0};
>> +static const uint8_t vector_dimension[8] = { 2, 2, 2, 4, 4, 5, 5, 1 };
>> +static const uint8_t number_of_vectors[8] = { 10, 10, 10, 5, 5, 4, 4, 20
>> };
>> +static const uint8_t expected_bits_table[8] = { 52, 47, 43, 37, 29, 22,
>> 16, 0 };
>> +static const int8_t differential_decoder_tree[27][24][2] = {
>> +{
>> +{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, -12}, {-11, -10},
>> {-8, -9}, {-7, -6}, {-13, 12},
>> +{-5, -4}, {0, 13}, {-3, -14}, {-2, 14}, {-1, 15}, {-15, 16},
>> {-16, 17}, {-17, 18}, {19, 20},
>> +{21, 22}, {-18, -19}, {-20, -21}, {-22, -23}, {-32, -32}
>> +},
>> +{
>> +{1, 2}, {3, 4}, {5, 6}, {7, 8}, {-10, -9}, {-8, -11}, {-7, -6},
>> {9, -5}, {10, -12}, {-4, 11},
>> +{-13, -3}, {12, -2}, {13, -14}, {-1, 14}, {15, 

Re: [FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder

2020-02-19 Thread James Almer
On 2/19/2020 7:30 AM, Paul B Mahol wrote:
> Signed-off-by: Paul B Mahol 
> ---
>  libavcodec/Makefile |   1 +
>  libavcodec/allcodecs.c  |   1 +
>  libavcodec/avcodec.h|   1 +
>  libavcodec/codec_desc.c |   7 +
>  libavcodec/siren.c  | 776 
>  libavformat/vivo.c  |   5 +
>  6 files changed, 791 insertions(+)
>  create mode 100644 libavcodec/siren.c
> 
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 46da42570f..2dae3b2d5d 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -584,6 +584,7 @@ OBJS-$(CONFIG_SIPR_DECODER)+= sipr.o 
> acelp_pitch_delay.o \
>celp_math.o acelp_vectors.o \
>acelp_filters.o celp_filters.o \
>sipr16k.o
> +OBJS-$(CONFIG_SIREN_DECODER)   += siren.o
>  OBJS-$(CONFIG_SMACKAUD_DECODER)+= smacker.o
>  OBJS-$(CONFIG_SMACKER_DECODER) += smacker.o
>  OBJS-$(CONFIG_SMC_DECODER) += smc.o
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index 103f34fd32..94e196202a 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -474,6 +474,7 @@ extern AVCodec ff_sbc_encoder;
>  extern AVCodec ff_sbc_decoder;
>  extern AVCodec ff_shorten_decoder;
>  extern AVCodec ff_sipr_decoder;
> +extern AVCodec ff_siren_decoder;
>  extern AVCodec ff_smackaud_decoder;
>  extern AVCodec ff_sonic_encoder;
>  extern AVCodec ff_sonic_decoder;
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 368341ba93..978f36d12a 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -661,6 +661,7 @@ enum AVCodecID {
>  AV_CODEC_ID_HCOM,
>  AV_CODEC_ID_ACELP_KELVIN,
>  AV_CODEC_ID_MPEGH_3D_AUDIO,
> +AV_CODEC_ID_SIREN,
>  
>  /* subtitle codecs */
>  AV_CODEC_ID_FIRST_SUBTITLE = 0x17000,  ///< A dummy ID pointing 
> at the start of subtitle codecs.
> diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
> index 609c7501fd..89bdfa3fce 100644
> --- a/libavcodec/codec_desc.c
> +++ b/libavcodec/codec_desc.c
> @@ -3044,6 +3044,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
>  .long_name = NULL_IF_CONFIG_SMALL("MPEG-H 3D Audio"),
>  .props = AV_CODEC_PROP_LOSSY,
>  },
> +{
> +.id= AV_CODEC_ID_SIREN,
> +.type  = AVMEDIA_TYPE_AUDIO,
> +.name  = "siren",
> +.long_name = NULL_IF_CONFIG_SMALL("Siren"),
> +.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
> +},
>  
>  /* subtitle codecs */
>  {
> diff --git a/libavcodec/siren.c b/libavcodec/siren.c
> new file mode 100644
> index 00..8bff7729df
> --- /dev/null
> +++ b/libavcodec/siren.c
> @@ -0,0 +1,776 @@
> +/*
> + * Siren audio decoder
> + * Copyright (c) 2012 Youness Alaoui 
> + * Copyright (c) 2018 Paul B Mahol
> + * Copyright (c) 2019 Lynne 
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg 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.
> + *
> + * FFmpeg 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 FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +#include "libavutil/tx.h"
> +#include "libavutil/float_dsp.h"
> +
> +#include "avcodec.h"
> +#include "get_bits.h"
> +#include "internal.h"
> +#include "mathops.h"
> +
> +static const uint8_t index_table[8] = {4, 4, 3, 3, 2, 2, 1, 0};
> +static const uint8_t vector_dimension[8] = { 2, 2, 2, 4, 4, 5, 5, 1 };
> +static const uint8_t number_of_vectors[8] = { 10, 10, 10, 5, 5, 4, 4, 20 };
> +static const uint8_t expected_bits_table[8] = { 52, 47, 43, 37, 29, 22, 16, 
> 0 };
> +static const int8_t differential_decoder_tree[27][24][2] = {
> +{
> +{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, -12}, {-11, -10}, {-8, 
> -9}, {-7, -6}, {-13, 12},
> +{-5, -4}, {0, 13}, {-3, -14}, {-2, 14}, {-1, 15}, {-15, 16}, {-16, 
> 17}, {-17, 18}, {19, 20},
> +{21, 22}, {-18, -19}, {-20, -21}, {-22, -23}, {-32, -32}
> +},
> +{
> +{1, 2}, {3, 4}, {5, 6}, {7, 8}, {-10, -9}, {-8, -11}, {-7, -6}, {9, 
> -5}, {10, -12}, {-4, 11},
> +{-13, -3}, {12, -2}, {13, -14}, {-1, 14}, {15, -15}, {0, 16}, {-16, 
> 17}, {-17, 18}, {-18, 19},
> +{20, 21},{22, -19}, {-20, -21}, {-22, -23}, {-32, -32}
> +},
> +{
> +{1, 2}, 

Re: [FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder

2020-02-19 Thread Lynne
Feb 19, 2020, 10:30 by one...@gmail.com:

> Signed-off-by: Paul B Mahol <> one...@gmail.com> >
> ---
> libavcodec/Makefile |   1 +
> libavcodec/allcodecs.c  |   1 +
> libavcodec/avcodec.h|   1 +
> libavcodec/codec_desc.c |   7 +
> libavcodec/siren.c  | 776 
> libavformat/vivo.c  |   5 +
> 6 files changed, 791 insertions(+)
> create mode 100644 libavcodec/siren.c
>
>
> +
> +for (i = 0; i < 64; i++) {
> +float region_power = powf(10, (i - 24) * 0.3010299957);
> +
> +s->standard_deviation[i] = sqrtf(region_power);
> +}
>

Remove the stray newline?



> +
> +for (int i = 0; i < rate_control; i++) {
> +s->power_categories[s->category_balance[i]]++;
> +}
>

No need for brackets.



> +
> +ret = decode_vector(s, s->number_of_regions, get_bits_left(gb),
> +s->decoder_standard_deviation, s->power_categories,
> +s->imdct_in, s->scale_factor);
> +if (ret < 0)
> +return ret;
> +
> +if (get_bits_left(gb) > 0) {
> +do {
> +if (!get_bits1(gb))
> +frame_error = 1;
>

frame_error |= !get_bits1(gb);



>
> +
> +if (frame_error) {
> +for (int i = 0; i < number_of_valid_coefs; i++) {
> +s->imdct_in[i] = s->backup_frame[i];
> +s->backup_frame[i] = 0;
>

memcpy(s->imdct_in, s->backup_frame, number_of_valid_coefs*sizeof(float));
memset(s->backup_frame, 0, number_of_valid_coefs*sizeof(float));



> +}
> +} else {
> +for (int i = 0; i < number_of_valid_coefs; i++)
> +s->backup_frame[i] = s->imdct_in[i];
>

memcpy(s->backup_frame, s->imdct_in, number_of_valid_coefs*sizeof(float));



> +}
> +
> +frame->nb_samples = FRAME_SIZE;
> +if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
> +return ret;
> +
> +for (int i = 0; i < 320; i += 2)
> +s->imdct_in[i] *= -1;
> +
> +s->tx_fn(s->tx_ctx, s->imdct_out, s->imdct_in, sizeof(float));
> +s->fdsp->vector_fmul_window((float *)frame->data[0],
> +s->imdct_prev + (FRAME_SIZE >> 1),
> +s->imdct_out, s->window,
> +FRAME_SIZE >> 1);
> +FFSWAP(float *, s->imdct_out, s->imdct_prev);
> +
> +*got_frame = 1;
> +
> +return avpkt->size;
>

Return AVERROR_INVALIDDATA if frame_error == 1?




> +
> +coefs_ptr = coefs + (region * s->region_size);
> +
> +if (category == 5) {
> +i = 0;
> +for (j = 0; j < s->region_size; j++) {
> +if (*coefs_ptr != 0) {
> +i++;
> +}
>

No need for brackets here.



> +coefs_ptr++;
> +}
> +
> +noise = decoder_standard_deviation[region] * noise_category5[i];
> +} else if (category == 6) {
> +i = 0;
> +for (j = 0; j < s->region_size; j++) {
> +if (*coefs_ptr++ != 0)
> +i++;
> +}
> +
> +noise = decoder_standard_deviation[region] * noise_category6[i];
> +} else if (category == 7) {
> +noise = decoder_standard_deviation[region] * 0.70711f;
> +} else {
> +noise = 0;
> +}
> +
> +coefs_ptr = coefs + (region * s->region_size);
> +
> +if (category == 5 || category == 6 || category == 7) {
> +dw1 = get_dw(s);
> +dw2 = get_dw(s);
> +
> +for (j = 0; j < 10; j++) {
> +if (category == 7 || *coefs_ptr == 0) {
> +if (dw1 & 1)
> +*coefs_ptr = noise;
> +else
> +*coefs_ptr = -noise;
> +}
>

*coefs_ptr = dw1 & 1 ? noise : -noise;


> +coefs_ptr++;
> +dw1 >>= 1;
> +
> +if (category == 7 || *coefs_ptr == 0) {
> +if (dw2 & 1)
> +*coefs_ptr = noise;
> +else
> +*coefs_ptr = -noise;
> +}
> +coefs_ptr++;
> +dw2 >>= 1;
>

Same.


Apart from that patch LGTM.

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder

2020-02-19 Thread Paul B Mahol
Signed-off-by: Paul B Mahol 
---
 libavcodec/Makefile |   1 +
 libavcodec/allcodecs.c  |   1 +
 libavcodec/avcodec.h|   1 +
 libavcodec/codec_desc.c |   7 +
 libavcodec/siren.c  | 776 
 libavformat/vivo.c  |   5 +
 6 files changed, 791 insertions(+)
 create mode 100644 libavcodec/siren.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 46da42570f..2dae3b2d5d 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -584,6 +584,7 @@ OBJS-$(CONFIG_SIPR_DECODER)+= sipr.o 
acelp_pitch_delay.o \
   celp_math.o acelp_vectors.o \
   acelp_filters.o celp_filters.o \
   sipr16k.o
+OBJS-$(CONFIG_SIREN_DECODER)   += siren.o
 OBJS-$(CONFIG_SMACKAUD_DECODER)+= smacker.o
 OBJS-$(CONFIG_SMACKER_DECODER) += smacker.o
 OBJS-$(CONFIG_SMC_DECODER) += smc.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 103f34fd32..94e196202a 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -474,6 +474,7 @@ extern AVCodec ff_sbc_encoder;
 extern AVCodec ff_sbc_decoder;
 extern AVCodec ff_shorten_decoder;
 extern AVCodec ff_sipr_decoder;
+extern AVCodec ff_siren_decoder;
 extern AVCodec ff_smackaud_decoder;
 extern AVCodec ff_sonic_encoder;
 extern AVCodec ff_sonic_decoder;
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 368341ba93..978f36d12a 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -661,6 +661,7 @@ enum AVCodecID {
 AV_CODEC_ID_HCOM,
 AV_CODEC_ID_ACELP_KELVIN,
 AV_CODEC_ID_MPEGH_3D_AUDIO,
+AV_CODEC_ID_SIREN,
 
 /* subtitle codecs */
 AV_CODEC_ID_FIRST_SUBTITLE = 0x17000,  ///< A dummy ID pointing at 
the start of subtitle codecs.
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 609c7501fd..89bdfa3fce 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -3044,6 +3044,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
 .long_name = NULL_IF_CONFIG_SMALL("MPEG-H 3D Audio"),
 .props = AV_CODEC_PROP_LOSSY,
 },
+{
+.id= AV_CODEC_ID_SIREN,
+.type  = AVMEDIA_TYPE_AUDIO,
+.name  = "siren",
+.long_name = NULL_IF_CONFIG_SMALL("Siren"),
+.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+},
 
 /* subtitle codecs */
 {
diff --git a/libavcodec/siren.c b/libavcodec/siren.c
new file mode 100644
index 00..8bff7729df
--- /dev/null
+++ b/libavcodec/siren.c
@@ -0,0 +1,776 @@
+/*
+ * Siren audio decoder
+ * Copyright (c) 2012 Youness Alaoui 
+ * Copyright (c) 2018 Paul B Mahol
+ * Copyright (c) 2019 Lynne 
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/tx.h"
+#include "libavutil/float_dsp.h"
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "mathops.h"
+
+static const uint8_t index_table[8] = {4, 4, 3, 3, 2, 2, 1, 0};
+static const uint8_t vector_dimension[8] = { 2, 2, 2, 4, 4, 5, 5, 1 };
+static const uint8_t number_of_vectors[8] = { 10, 10, 10, 5, 5, 4, 4, 20 };
+static const uint8_t expected_bits_table[8] = { 52, 47, 43, 37, 29, 22, 16, 0 
};
+static const int8_t differential_decoder_tree[27][24][2] = {
+{
+{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, -12}, {-11, -10}, {-8, 
-9}, {-7, -6}, {-13, 12},
+{-5, -4}, {0, 13}, {-3, -14}, {-2, 14}, {-1, 15}, {-15, 16}, {-16, 
17}, {-17, 18}, {19, 20},
+{21, 22}, {-18, -19}, {-20, -21}, {-22, -23}, {-32, -32}
+},
+{
+{1, 2}, {3, 4}, {5, 6}, {7, 8}, {-10, -9}, {-8, -11}, {-7, -6}, {9, 
-5}, {10, -12}, {-4, 11},
+{-13, -3}, {12, -2}, {13, -14}, {-1, 14}, {15, -15}, {0, 16}, {-16, 
17}, {-17, 18}, {-18, 19},
+{20, 21},{22, -19}, {-20, -21}, {-22, -23}, {-32, -32}
+},
+{
+{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {-12, 11}, {-11, -13}, {-10, 
-9}, {12, -14}, {-8, -7},
+{-15, -6}, {13, -5}, {-16, -4}, {14, -17}, {15, -3}, {16, -18}, {-2, 
17}, {18, -19}, {-1, 19},
+{-20, 20}, {0, 21}, {22, -21}, {-22, -23}, {-32, -32}
+},
+{
+{1, 2}, {3, 4}, 

Re: [FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder

2018-04-11 Thread Rostislav Pehlivanov
On 4 April 2018 at 15:09, Paul B Mahol  wrote:

> Signed-off-by: Paul B Mahol 
> ---
>  libavcodec/Makefile |   1 +
>  libavcodec/allcodecs.c  |   1 +
>  libavcodec/avcodec.h|   1 +
>  libavcodec/codec_desc.c |   8 +
>  libavcodec/siren.c  | 847 ++
> ++
>  5 files changed, 858 insertions(+)
>  create mode 100644 libavcodec/siren.c
>

You should wait until I submit my patch for even FFTs and MDCTs in lavu
before resubmitting. Sorry I'm holding it back.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder

2018-04-06 Thread Compn
On Wed,  4 Apr 2018 16:09:35 +0200, Paul B Mahol 
wrote:

> Signed-off-by: Paul B Mahol 
> ---
>  libavcodec/Makefile |   1 +
>  libavcodec/allcodecs.c  |   1 +
>  libavcodec/avcodec.h|   1 +
>  libavcodec/codec_desc.c |   8 +
>  libavcodec/siren.c  | 847 
> 
>  5 files changed, 858 insertions(+)

does this also decode msnsiren? or no?
did you use this patch ? 
https://lists.ffmpeg.org/pipermail/ffmpeg-devel/2012-July/127801.html

good work paul!

-compn
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder

2018-04-04 Thread Paul B Mahol
On 4/4/18, James Almer  wrote:
> On 4/4/2018 11:09 AM, Paul B Mahol wrote:
>> Signed-off-by: Paul B Mahol 
>> ---
>>  libavcodec/Makefile |   1 +
>>  libavcodec/allcodecs.c  |   1 +
>>  libavcodec/avcodec.h|   1 +
>>  libavcodec/codec_desc.c |   8 +
>>  libavcodec/siren.c  | 847
>> 
>>  5 files changed, 858 insertions(+)
>>  create mode 100644 libavcodec/siren.c
>
> [...]
>
>> +static av_cold int siren_init(AVCodecContext *avctx)
>> +{
>> +SirenContext *s = avctx->priv_data;
>> +int i;
>> +
>> +avctx->channels   = 1;
>> +avctx->channel_layout = AV_CH_LAYOUT_MONO;
>> +avctx->sample_fmt = AV_SAMPLE_FMT_S16;
>> +
>> +s->number_of_coefs = 320;
>> +s->rate_control_bits = 4;
>> +s->rate_control_possibilities = 16;
>> +s->checksum_bits = 0;
>> +s->esf_adjustment = 7;
>> +s->number_of_regions = 14;
>> +s->scale_factor = 1;
>> +s->bits_per_frame = avctx->sample_rate / 50;
>> +s->region_size = 20;
>> +s->dw1 = s->dw2 = s->dw3 = s->dw4 = 1;
>> +
>> +for (i = 0; i < 64; i++) {
>> +float region_power = powf(10, (i - 24) * STEPSIZE);
>> +
>> +s->standard_deviation[i] = sqrtf(region_power);
>> +s->deviation_inverse[i] = 1.f / s->standard_deviation[i];
>> +}
>> +
>> +for (i = 0; i < 320; i++) {
>> +float angle = ((i + 0.5f) * M_PI_2) / 320.f;
>> +s->window[i] = sinf(angle);
>> +}
>> +
>> +ff_fft_init(>fft_ctx, 10, 0);
>
> Missing fft dependency in configure.

ok


>
>> +
>> +return 0;
>> +}
>
> [...]
>
>> +
>> +static int categorize_regions(int number_of_regions, int
>> number_of_available_bits,
>> +  int *absolute_region_power_index, int
>> *power_categories,
>> +  int *category_balance)
>> +{
>> +int region, delta, i, temp;
>> +int expected_number_of_code_bits;
>> +int min, max;
>> +int offset,
>> +num_rate_control_possibilities,
>> +raw_value, raw_max_idx = 0, raw_min_idx = 0;
>> +int max_rate_categories[28];
>> +int min_rate_categories[28];
>> +int temp_category_balances[64];
>> +int *min_rate_ptr = NULL;
>> +int *max_rate_ptr = NULL;
>> +
>> +if (number_of_regions == 14) {
>> +num_rate_control_possibilities = 16;
>> +if (number_of_available_bits > 320)
>> +number_of_available_bits =
>> +((number_of_available_bits - 320) * 5 / 8) + 320;
>> +} else {
>> +num_rate_control_possibilities = 32;
>> +if (number_of_regions == 28 && number_of_available_bits > 640)
>> +number_of_available_bits =
>> +((number_of_available_bits - 640) * 5 / 8) + 640;
>> +}
>> +
>> +offset = -32;
>> +for (delta = 32; number_of_regions > 0 && delta > 0; delta /= 2) {
>> +expected_number_of_code_bits = 0;
>> +for (region = 0; region < number_of_regions; region++) {
>> +i = (delta + offset -
>> + absolute_region_power_index[region]) >> 1;
>> +if (i > 7)
>> +i = 7;
>> +else if (i < 0)
>> +i = 0;
>
> av_clip_uintp2()

ok


>
>> +
>> +power_categories[region] = i;
>> +expected_number_of_code_bits += expected_bits_table[i];
>> +
>> +}
>> +if (expected_number_of_code_bits >= number_of_available_bits -
>> 32)
>> +offset += delta;
>> +}
>> +
>> +expected_number_of_code_bits = 0;
>> +for (region = 0; region < number_of_regions; region++) {
>> +i = (offset - absolute_region_power_index[region]) >> 1;
>> +if (i > 7)
>> +i = 7;
>> +else if (i < 0)
>> +i = 0;
>
> Same.

ok

>
>> +max_rate_categories[region] = min_rate_categories[region] =
>> +power_categories[region] = i;
>> +expected_number_of_code_bits += expected_bits_table[i];
>> +}
>
> [...]
>
>> +static int siren_decode(AVCodecContext *avctx, void *data,
>> +int *got_frame, AVPacket *pkt)
>> +{
>> +SirenContext *s = avctx->priv_data;
>> +AVFrame *frame = data;
>> +int number_of_valid_coefs = 20 * s->number_of_regions;
>> +int number_of_available_bits =
>> +s->bits_per_frame - s->sample_rate_bits - s->checksum_bits;
>
> s->checksum_bits seems to always be 0, unless I'm missing something.
>
>> +int envelope_bits, ret;
>> +int frame_error = 0, i, rate_control = 0;
>> +int checksum, calculated_checksum;
>> +
>> +if (s->checksum_bits > 0)
>> +memcpy(s->input_frame, pkt->data, FFMIN(pkt->size, 80));
>
> sizeof(s->input_frame) instead of 80?
>

ok


>> +if ((ret = init_get_bits8(>gb, pkt->data, pkt->size)) < 0)
>> +return ret;
>> +
>> +envelope_bits =
>> +decode_envelope(s, >gb, s->number_of_regions,
>> +

Re: [FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder

2018-04-04 Thread James Almer
On 4/4/2018 11:09 AM, Paul B Mahol wrote:
> Signed-off-by: Paul B Mahol 
> ---
>  libavcodec/Makefile |   1 +
>  libavcodec/allcodecs.c  |   1 +
>  libavcodec/avcodec.h|   1 +
>  libavcodec/codec_desc.c |   8 +
>  libavcodec/siren.c  | 847 
> 
>  5 files changed, 858 insertions(+)
>  create mode 100644 libavcodec/siren.c

[...]

> +static av_cold int siren_init(AVCodecContext *avctx)
> +{
> +SirenContext *s = avctx->priv_data;
> +int i;
> +
> +avctx->channels   = 1;
> +avctx->channel_layout = AV_CH_LAYOUT_MONO;
> +avctx->sample_fmt = AV_SAMPLE_FMT_S16;
> +
> +s->number_of_coefs = 320;
> +s->rate_control_bits = 4;
> +s->rate_control_possibilities = 16;
> +s->checksum_bits = 0;
> +s->esf_adjustment = 7;
> +s->number_of_regions = 14;
> +s->scale_factor = 1;
> +s->bits_per_frame = avctx->sample_rate / 50;
> +s->region_size = 20;
> +s->dw1 = s->dw2 = s->dw3 = s->dw4 = 1;
> +
> +for (i = 0; i < 64; i++) {
> +float region_power = powf(10, (i - 24) * STEPSIZE);
> +
> +s->standard_deviation[i] = sqrtf(region_power);
> +s->deviation_inverse[i] = 1.f / s->standard_deviation[i];
> +}
> +
> +for (i = 0; i < 320; i++) {
> +float angle = ((i + 0.5f) * M_PI_2) / 320.f;
> +s->window[i] = sinf(angle);
> +}
> +
> +ff_fft_init(>fft_ctx, 10, 0);

Missing fft dependency in configure.

> +
> +return 0;
> +}

[...]

> +
> +static int categorize_regions(int number_of_regions, int 
> number_of_available_bits,
> +  int *absolute_region_power_index, int 
> *power_categories,
> +  int *category_balance)
> +{
> +int region, delta, i, temp;
> +int expected_number_of_code_bits;
> +int min, max;
> +int offset,
> +num_rate_control_possibilities,
> +raw_value, raw_max_idx = 0, raw_min_idx = 0;
> +int max_rate_categories[28];
> +int min_rate_categories[28];
> +int temp_category_balances[64];
> +int *min_rate_ptr = NULL;
> +int *max_rate_ptr = NULL;
> +
> +if (number_of_regions == 14) {
> +num_rate_control_possibilities = 16;
> +if (number_of_available_bits > 320)
> +number_of_available_bits =
> +((number_of_available_bits - 320) * 5 / 8) + 320;
> +} else {
> +num_rate_control_possibilities = 32;
> +if (number_of_regions == 28 && number_of_available_bits > 640)
> +number_of_available_bits =
> +((number_of_available_bits - 640) * 5 / 8) + 640;
> +}
> +
> +offset = -32;
> +for (delta = 32; number_of_regions > 0 && delta > 0; delta /= 2) {
> +expected_number_of_code_bits = 0;
> +for (region = 0; region < number_of_regions; region++) {
> +i = (delta + offset -
> + absolute_region_power_index[region]) >> 1;
> +if (i > 7)
> +i = 7;
> +else if (i < 0)
> +i = 0;

av_clip_uintp2()

> +
> +power_categories[region] = i;
> +expected_number_of_code_bits += expected_bits_table[i];
> +
> +}
> +if (expected_number_of_code_bits >= number_of_available_bits - 32)
> +offset += delta;
> +}
> +
> +expected_number_of_code_bits = 0;
> +for (region = 0; region < number_of_regions; region++) {
> +i = (offset - absolute_region_power_index[region]) >> 1;
> +if (i > 7)
> +i = 7;
> +else if (i < 0)
> +i = 0;

Same.

> +max_rate_categories[region] = min_rate_categories[region] =
> +power_categories[region] = i;
> +expected_number_of_code_bits += expected_bits_table[i];
> +}

[...]

> +static int siren_decode(AVCodecContext *avctx, void *data,
> +int *got_frame, AVPacket *pkt)
> +{
> +SirenContext *s = avctx->priv_data;
> +AVFrame *frame = data;
> +int number_of_valid_coefs = 20 * s->number_of_regions;
> +int number_of_available_bits =
> +s->bits_per_frame - s->sample_rate_bits - s->checksum_bits;

s->checksum_bits seems to always be 0, unless I'm missing something.

> +int envelope_bits, ret;
> +int frame_error = 0, i, rate_control = 0;
> +int checksum, calculated_checksum;
> +
> +if (s->checksum_bits > 0)
> +memcpy(s->input_frame, pkt->data, FFMIN(pkt->size, 80));

sizeof(s->input_frame) instead of 80?

> +if ((ret = init_get_bits8(>gb, pkt->data, pkt->size)) < 0)
> +return ret;
> +
> +envelope_bits =
> +decode_envelope(s, >gb, s->number_of_regions,
> +s->decoder_standard_deviation,
> +s->absolute_region_power_index, s->esf_adjustment);
> +
> +number_of_available_bits -= envelope_bits;
> +
> +for (i = 0; i < s->rate_control_bits; i++) {
> +rate_control <<= 

[FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder

2018-04-04 Thread Paul B Mahol
Signed-off-by: Paul B Mahol 
---
 libavcodec/Makefile |   1 +
 libavcodec/allcodecs.c  |   1 +
 libavcodec/avcodec.h|   1 +
 libavcodec/codec_desc.c |   8 +
 libavcodec/siren.c  | 847 
 5 files changed, 858 insertions(+)
 create mode 100644 libavcodec/siren.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 4b8ad121db..86cea2d1aa 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -563,6 +563,7 @@ OBJS-$(CONFIG_SIPR_DECODER)+= sipr.o 
acelp_pitch_delay.o \
   celp_math.o acelp_vectors.o \
   acelp_filters.o celp_filters.o \
   sipr16k.o
+OBJS-$(CONFIG_SIREN_DECODER)   += siren.o
 OBJS-$(CONFIG_SMACKAUD_DECODER)+= smacker.o
 OBJS-$(CONFIG_SMACKER_DECODER) += smacker.o
 OBJS-$(CONFIG_SMC_DECODER) += smc.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 4d4ef530e4..830c84ed45 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -457,6 +457,7 @@ extern AVCodec ff_sbc_encoder;
 extern AVCodec ff_sbc_decoder;
 extern AVCodec ff_shorten_decoder;
 extern AVCodec ff_sipr_decoder;
+extern AVCodec ff_siren_decoder;
 extern AVCodec ff_smackaud_decoder;
 extern AVCodec ff_sonic_encoder;
 extern AVCodec ff_sonic_decoder;
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index fb0c6fae70..b63746b105 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -637,6 +637,7 @@ enum AVCodecID {
 AV_CODEC_ID_APTX,
 AV_CODEC_ID_APTX_HD,
 AV_CODEC_ID_SBC,
+AV_CODEC_ID_SIREN,
 
 /* subtitle codecs */
 AV_CODEC_ID_FIRST_SUBTITLE = 0x17000,  ///< A dummy ID pointing at 
the start of subtitle codecs.
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 79552a910d..730cf5482a 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2878,6 +2878,14 @@ static const AVCodecDescriptor codec_descriptors[] = {
 .long_name = NULL_IF_CONFIG_SMALL("SBC (low-complexity subband 
codec)"),
 .props = AV_CODEC_PROP_LOSSY,
 },
+{
+.id= AV_CODEC_ID_SIREN,
+.type  = AVMEDIA_TYPE_AUDIO,
+.name  = "siren",
+.long_name = NULL_IF_CONFIG_SMALL("Siren"),
+.props = AV_CODEC_PROP_LOSSY,
+},
+
 
 /* subtitle codecs */
 {
diff --git a/libavcodec/siren.c b/libavcodec/siren.c
new file mode 100644
index 00..d49a26f2a9
--- /dev/null
+++ b/libavcodec/siren.c
@@ -0,0 +1,847 @@
+/*
+ * Siren audio decoder
+ * Copyright (c) 2012 Youness Alaoui 
+ * Copyright (c) 2018 Paul B Mahol
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avcodec.h"
+#include "fft.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "mathops.h"
+
+#define STEPSIZE0.3010299957
+
+static uint16_t checksum_table[4] = { 0x7F80, 0x7878, 0x, 0x };
+static const uint8_t index_table[8] = {4, 4, 3, 3, 2, 2, 1, 0};
+static const uint8_t vector_dimension[8] = { 2, 2, 2, 4, 4, 5, 5, 1 };
+static const uint8_t number_of_vectors[8] = { 10, 10, 10, 5, 5, 4, 4, 20 };
+static const uint8_t expected_bits_table[8] = { 52, 47, 43, 37, 29, 22, 16, 0 
};
+static const int8_t differential_decoder_tree[27][24][2] = {
+  {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, -12}, {-11, -10}, {-8, -9}, 
{-7, -6}, {-13, 12}, {-5, -4}, {0, 13}, {-3, -14}, {-2, 14}, {-1, 15}, {-15, 
16}, {-16, 17}, {-17, 18}, {19, 20}, {21, 22}, {-18, -19}, {-20, -21}, {-22, 
-23}, {-32, -32}},
+  {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {-10, -9}, {-8, -11}, {-7, -6}, {9, -5}, 
{10, -12}, {-4, 11}, {-13, -3}, {12, -2}, {13, -14}, {-1, 14}, {15, -15}, {0, 
16}, {-16, 17}, {-17, 18}, {-18, 19}, {20, 21},{22, -19}, {-20, -21}, {-22, 
-23}, {-32, -32}},
+  {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {-12, 11}, {-11, -13}, {-10, -9}, 
{12, -14}, {-8, -7}, {-15, -6}, {13, -5}, {-16, -4}, {14, -17}, {15, -3}, {16, 
-18}, {-2, 17}, {18, -19}, {-1, 19}, {-20, 20}, {0, 21}, {22, -21}, {-22, -23}, 
{-32, -32}},
+  {{1, 2}, {3, 4}, {5, 6}, {-11, -10}, {7, -12}, {8, -9}, {9, -13}, {-14, 10}, 
{-8, -15}, {-16,