diff mbox series

[FFmpeg-devel,2/2] avcodec: remove sonic lossy/lossless audio

Message ID 20240228125616.458327-2-jdek@itanimul.li
State New
Headers show
Series [FFmpeg-devel,1/2] MAINTAINERS: remove inactive developer | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

J. Dekker Feb. 28, 2024, 12:56 p.m. UTC
This was an experimental/research codec of which ffmpeg is the only
encoder and decoder, development has stalled and these files don't exist
in the wild.

Signed-off-by: J. Dekker <jdek@itanimul.li>
---
 Changelog               |    1 +
 configure               |    3 -
 libavcodec/Makefile     |    3 -
 libavcodec/allcodecs.c  |    3 -
 libavcodec/codec_desc.c |   14 -
 libavcodec/sonic.c      | 1125 ---------------------------------------
 6 files changed, 1 insertion(+), 1148 deletions(-)
 delete mode 100644 libavcodec/sonic.c

Comments

Andreas Rheinhardt Feb. 28, 2024, 1:23 p.m. UTC | #1
J. Dekker:
> This was an experimental/research codec of which ffmpeg is the only
> encoder and decoder, development has stalled and these files don't exist
> in the wild.
> 
> Signed-off-by: J. Dekker <jdek@itanimul.li>
> ---
>  Changelog               |    1 +
>  configure               |    3 -
>  libavcodec/Makefile     |    3 -
>  libavcodec/allcodecs.c  |    3 -
>  libavcodec/codec_desc.c |   14 -
>  libavcodec/sonic.c      | 1125 ---------------------------------------
>  6 files changed, 1 insertion(+), 1148 deletions(-)
>  delete mode 100644 libavcodec/sonic.c
> 
> diff --git a/Changelog b/Changelog
> index 610ee61dd6..e2096f249a 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -27,6 +27,7 @@ version <next>:
>  - a C11-compliant compiler is now required; note that this requirement
>    will be bumped to C17 in the near future, so consider updating your
>    build environment if it lacks C17 support
> +- sonic lossy/lossless audio codec removed
>  
>  version 6.1:
>  - libaribcaption decoder
> diff --git a/configure b/configure
> index bb5e630bad..e639a5e2b7 100755
> --- a/configure
> +++ b/configure
> @@ -2991,9 +2991,6 @@ sipr_decoder_select="lsp"
>  smvjpeg_decoder_select="mjpeg_decoder"
>  snow_decoder_select="dwt h264qpel rangecoder videodsp"
>  snow_encoder_select="dwt h264qpel hpeldsp me_cmp mpegvideoenc rangecoder videodsp"
> -sonic_decoder_select="golomb rangecoder"
> -sonic_encoder_select="golomb rangecoder"
> -sonic_ls_encoder_select="golomb rangecoder"
>  sp5x_decoder_select="mjpeg_decoder"
>  speedhq_decoder_select="blockdsp idctdsp"
>  speedhq_encoder_select="mpegvideoenc"
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 09ae5270b3..3fc716ee68 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -687,9 +687,6 @@ OBJS-$(CONFIG_SNOW_DECODER)            += snowdec.o snow.o snow_dwt.o
>  OBJS-$(CONFIG_SNOW_ENCODER)            += snowenc.o snow.o snow_dwt.o             \
>                                            h263.o h263data.o ituh263enc.o
>  OBJS-$(CONFIG_SOL_DPCM_DECODER)        += dpcm.o
> -OBJS-$(CONFIG_SONIC_DECODER)           += sonic.o
> -OBJS-$(CONFIG_SONIC_ENCODER)           += sonic.o
> -OBJS-$(CONFIG_SONIC_LS_ENCODER)        += sonic.o
>  OBJS-$(CONFIG_SPEEDHQ_DECODER)         += speedhqdec.o speedhq.o mpeg12.o \
>                                            mpeg12data.o
>  OBJS-$(CONFIG_SPEEDHQ_ENCODER)         += speedhq.o mpeg12data.o mpeg12enc.o speedhqenc.o
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index ef8c3a6d7d..e0a4a5421d 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -535,9 +535,6 @@ extern const FFCodec ff_shorten_decoder;
>  extern const FFCodec ff_sipr_decoder;
>  extern const FFCodec ff_siren_decoder;
>  extern const FFCodec ff_smackaud_decoder;
> -extern const FFCodec ff_sonic_encoder;
> -extern const FFCodec ff_sonic_decoder;
> -extern const FFCodec ff_sonic_ls_encoder;
>  extern const FFCodec ff_tak_decoder;
>  extern const FFCodec ff_truehd_encoder;
>  extern const FFCodec ff_truehd_decoder;
> diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
> index 033344304c..9b456616be 100644
> --- a/libavcodec/codec_desc.c
> +++ b/libavcodec/codec_desc.c
> @@ -3175,20 +3175,6 @@ static const AVCodecDescriptor codec_descriptors[] = {
>          .long_name = NULL_IF_CONFIG_SMALL("Wave synthesis pseudo-codec"),
>          .props     = AV_CODEC_PROP_INTRA_ONLY,
>      },
> -    {
> -        .id        = AV_CODEC_ID_SONIC,
> -        .type      = AVMEDIA_TYPE_AUDIO,
> -        .name      = "sonic",
> -        .long_name = NULL_IF_CONFIG_SMALL("Sonic"),
> -        .props     = AV_CODEC_PROP_INTRA_ONLY,
> -    },
> -    {
> -        .id        = AV_CODEC_ID_SONIC_LS,
> -        .type      = AVMEDIA_TYPE_AUDIO,
> -        .name      = "sonicls",
> -        .long_name = NULL_IF_CONFIG_SMALL("Sonic lossless"),
> -        .props     = AV_CODEC_PROP_INTRA_ONLY,
> -    },
>      {
>          .id        = AV_CODEC_ID_EVRC,
>          .type      = AVMEDIA_TYPE_AUDIO,

You can't remove the codec descriptors as long as the codec id exists
(every codec id should have a codec descriptor, even if there is no codec).
Should the codec id be deprecated, too?

- Andreas
Michael Niedermayer Feb. 28, 2024, 1:29 p.m. UTC | #2
On Wed, Feb 28, 2024 at 01:56:10PM +0100, J. Dekker wrote:
> This was an experimental/research codec of which ffmpeg is the only
> encoder and decoder,


> development has stalled

Thats not true, there was private dicussion making sonic the most
advanced audio codec in FFmpeg a few months ago.
Iam not saying that will happen, i am just saying there was a
discussion about it. And that iam in principle interrested in
working on this. Its possible i will not have enough time ...

thx

[...]
J. Dekker Feb. 28, 2024, 1:31 p.m. UTC | #3
Michael Niedermayer <michael@niedermayer.cc> writes:

> [[PGP Signed Part:Undecided]]
> On Wed, Feb 28, 2024 at 01:56:10PM +0100, J. Dekker wrote:
>> This was an experimental/research codec of which ffmpeg is the only
>> encoder and decoder,
>
>
>> development has stalled
>
> Thats not true, there was private dicussion making sonic the most
> advanced audio codec in FFmpeg a few months ago.
> Iam not saying that will happen, i am just saying there was a
> discussion about it. And that iam in principle interrested in
> working on this. Its possible i will not have enough time ...
>

The last commit which actually changed the codec was
6026a5ad4f135476c7a1f51f8cfa7f4cc2ca0283 by you in 2013 which is over 10
years ago. For an experimental codec I think it's pretty safe to say
that development has stalled.

Keeping the codec around based on 'what if?'s doesn't seem
reasonable. Besides, if you do make sonic the most advanced audio codec
in FFmpeg there's nothing which says you couldn't re-add it at a later
date when it's being actively developed again.
Nicolas George Feb. 28, 2024, 1:41 p.m. UTC | #4
J. Dekker (12024-02-28):
> Keeping the codec around based on 'what if?'s doesn't seem
> reasonable.

Spending your efforts on it, even if it is just to remove it, is a waste
of your time.
Vittorio Giovara Feb. 28, 2024, 1:57 p.m. UTC | #5
On Wed, Feb 28, 2024 at 2:38 PM J. Dekker <jdek@itanimul.li> wrote:

>
> Michael Niedermayer <michael@niedermayer.cc> writes:
>
> > [[PGP Signed Part:Undecided]]
> > On Wed, Feb 28, 2024 at 01:56:10PM +0100, J. Dekker wrote:
> >> This was an experimental/research codec of which ffmpeg is the only
> >> encoder and decoder,
> >
> >
> >> development has stalled
> >
> > Thats not true, there was private dicussion making sonic the most
> > advanced audio codec in FFmpeg a few months ago.
> > Iam not saying that will happen, i am just saying there was a
> > discussion about it. And that iam in principle interrested in
> > working on this. Its possible i will not have enough time ...
> >
>
> The last commit which actually changed the codec was
> 6026a5ad4f135476c7a1f51f8cfa7f4cc2ca0283 by you in 2013 which is over 10
> years ago. For an experimental codec I think it's pretty safe to say
> that development has stalled.
>
> Keeping the codec around based on 'what if?'s doesn't seem
> reasonable. Besides, if you do make sonic the most advanced audio codec
> in FFmpeg there's nothing which says you couldn't re-add it at a later
> date when it's being actively developed again.
>

+1

but please do the deprecation dance as suggested
J. Dekker Feb. 28, 2024, 2:08 p.m. UTC | #6
Vittorio Giovara <vittorio.giovara@gmail.com> writes:

> On Wed, Feb 28, 2024 at 2:38 PM J. Dekker <jdek@itanimul.li> wrote:
>
>>
>> Michael Niedermayer <michael@niedermayer.cc> writes:
>>
>> > [[PGP Signed Part:Undecided]]
>> > On Wed, Feb 28, 2024 at 01:56:10PM +0100, J. Dekker wrote:
>> >> This was an experimental/research codec of which ffmpeg is the only
>> >> encoder and decoder,
>> >
>> >
>> >> development has stalled
>> >
>> > Thats not true, there was private dicussion making sonic the most
>> > advanced audio codec in FFmpeg a few months ago.
>> > Iam not saying that will happen, i am just saying there was a
>> > discussion about it. And that iam in principle interrested in
>> > working on this. Its possible i will not have enough time ...
>> >
>>
>> The last commit which actually changed the codec was
>> 6026a5ad4f135476c7a1f51f8cfa7f4cc2ca0283 by you in 2013 which is over 10
>> years ago. For an experimental codec I think it's pretty safe to say
>> that development has stalled.
>>
>> Keeping the codec around based on 'what if?'s doesn't seem
>> reasonable. Besides, if you do make sonic the most advanced audio codec
>> in FFmpeg there's nothing which says you couldn't re-add it at a later
>> date when it's being actively developed again.
>>
>
> +1
>
> but please do the deprecation dance as suggested

As mentioned on IRC the suggestion was to leave the codec IDs as-is so
that they can still be identified even if we cannot decode them. So
there is no need to deprecate anything here, public API is left
untouched and codec removed as if it were disabled at compile time. Will
post an updated patch.
James Almer Feb. 28, 2024, 5:55 p.m. UTC | #7
On 2/28/2024 10:31 AM, J. Dekker wrote:
> 
> Michael Niedermayer <michael@niedermayer.cc> writes:
> 
>> [[PGP Signed Part:Undecided]]
>> On Wed, Feb 28, 2024 at 01:56:10PM +0100, J. Dekker wrote:
>>> This was an experimental/research codec of which ffmpeg is the only
>>> encoder and decoder,
>>
>>
>>> development has stalled
>>
>> Thats not true, there was private dicussion making sonic the most
>> advanced audio codec in FFmpeg a few months ago.
>> Iam not saying that will happen, i am just saying there was a
>> discussion about it. And that iam in principle interrested in
>> working on this. Its possible i will not have enough time ...
>>
> 
> The last commit which actually changed the codec was
> 6026a5ad4f135476c7a1f51f8cfa7f4cc2ca0283 by you in 2013 which is over 10
> years ago. For an experimental codec I think it's pretty safe to say
> that development has stalled.
> 
> Keeping the codec around based on 'what if?'s doesn't seem
> reasonable. Besides, if you do make sonic the most advanced audio codec
> in FFmpeg there's nothing which says you couldn't re-add it at a later
> date when it's being actively developed again.

Does it hurt keeping it around? If it can at some point be developed 
again, then removing the codec id to re-add it later will be a bit dirty.

IMO, just disable both modules by default during configure, or tag the 
encoder as experimental to prevent new streams to be created unless 
explicitly requested knowing that it's an unfinished format.
Jean-Baptiste Kempf Feb. 28, 2024, 6:36 p.m. UTC | #8
On Wed, 28 Feb 2024, at 18:55, James Almer wrote:
> On 2/28/2024 10:31 AM, J. Dekker wrote:
>> 
>> Michael Niedermayer <michael@niedermayer.cc> writes:
>> 
>>> [[PGP Signed Part:Undecided]]
>>> On Wed, Feb 28, 2024 at 01:56:10PM +0100, J. Dekker wrote:
>>>> This was an experimental/research codec of which ffmpeg is the only
>>>> encoder and decoder,
>>>
>>>
>>>> development has stalled
>>>
>>> Thats not true, there was private dicussion making sonic the most
>>> advanced audio codec in FFmpeg a few months ago.
>>> Iam not saying that will happen, i am just saying there was a
>>> discussion about it. And that iam in principle interrested in
>>> working on this. Its possible i will not have enough time ...
>>>
>> 
>> The last commit which actually changed the codec was
>> 6026a5ad4f135476c7a1f51f8cfa7f4cc2ca0283 by you in 2013 which is over 10
>> years ago. For an experimental codec I think it's pretty safe to say
>> that development has stalled.
>> 
>> Keeping the codec around based on 'what if?'s doesn't seem
>> reasonable. Besides, if you do make sonic the most advanced audio codec
>> in FFmpeg there's nothing which says you couldn't re-add it at a later
>> date when it's being actively developed again.
>
> Does it hurt keeping it around? If it can at some point be developed 
> again, then removing the codec id to re-add it later will be a bit dirty.
>
> IMO, just disable both modules by default during configure, or tag the 
> encoder as experimental to prevent new streams to be created unless 
> explicitly requested knowing that it's an unfinished format.

+1
Rémi Denis-Courmont Feb. 28, 2024, 8:23 p.m. UTC | #9
Le keskiviikkona 28. helmikuuta 2024, 19.55.11 EET James Almer a écrit :
> > The last commit which actually changed the codec was
> > 6026a5ad4f135476c7a1f51f8cfa7f4cc2ca0283 by you in 2013 which is over 10
> > years ago. For an experimental codec I think it's pretty safe to say
> > that development has stalled.
> > 
> > Keeping the codec around based on 'what if?'s doesn't seem
> > reasonable. Besides, if you do make sonic the most advanced audio codec
> > in FFmpeg there's nothing which says you couldn't re-add it at a later
> > date when it's being actively developed again.
> 
> Does it hurt keeping it around?

Considering the sheer number of audio codecs in libavcodec, the difference is 
peanuts. But in principle, any dead code is an extra maintenance burden, 
whether it be reported security vulnerabilities that "need" to be fixed to 
appease Linux distros and corporate freeloaders, or to update the internal 
interfaces.

> If it can at some point be developed
> again, then removing the codec id to re-add it later will be a bit dirty.

Slightly, but the chance of that seem almost zero. Also compared to moving 
stuff in and out of staging like the kernel does, or between good, bad and ugly 
like a certain competing OSS framework does, it's pretty much nothing. People 
are not going to ditch FFmpeg on the basis of misusing the VCS over that 
hypothetical.
Lynne Feb. 28, 2024, 10:13 p.m. UTC | #10
Feb 28, 2024, 14:29 by michael@niedermayer.cc:

> On Wed, Feb 28, 2024 at 01:56:10PM +0100, J. Dekker wrote:
>
>> This was an experimental/research codec of which ffmpeg is the only
>> encoder and decoder,
>>
>
>
>> development has stalled
>>
>
> Thats not true, there was private dicussion making sonic the most
> advanced audio codec in FFmpeg a few months ago.
> Iam not saying that will happen, i am just saying there was a
> discussion about it. And that iam in principle interrested in
> working on this. Its possible i will not have enough time ...
>

I would strongly prefer for it to be kept around as well.

Otherwise it creates precedence to throw out codecs if they're
not popular enough, and we're known for being able to play
most formats ever created.
Vittorio Giovara Feb. 29, 2024, 1:50 a.m. UTC | #11
On Wed, Feb 28, 2024 at 11:13 PM Lynne <dev@lynne.ee> wrote:

> Feb 28, 2024, 14:29 by michael@niedermayer.cc:
>
> > On Wed, Feb 28, 2024 at 01:56:10PM +0100, J. Dekker wrote:
> >
> >> This was an experimental/research codec of which ffmpeg is the only
> >> encoder and decoder,
> >>
> >
> >
> >> development has stalled
> >>
> >
> > Thats not true, there was private dicussion making sonic the most
> > advanced audio codec in FFmpeg a few months ago.
> > Iam not saying that will happen, i am just saying there was a
> > discussion about it. And that iam in principle interrested in
> > working on this. Its possible i will not have enough time ...
> >
>
> I would strongly prefer for it to be kept around as well.
>
> Otherwise it creates precedence to throw out codecs if they're
> not popular enough, and we're known for being able to play
> most formats ever created.
>

IMO there is a big difference between a game codec and an experimental
codec that hasn't come out of ffmpeg
Lynne Feb. 29, 2024, 1:30 p.m. UTC | #12
Feb 29, 2024, 02:50 by vittorio.giovara@gmail.com:

> On Wed, Feb 28, 2024 at 11:13 PM Lynne <dev@lynne.ee> wrote:
>
>> Feb 28, 2024, 14:29 by michael@niedermayer.cc:
>>
>> > On Wed, Feb 28, 2024 at 01:56:10PM +0100, J. Dekker wrote:
>> >
>> >> This was an experimental/research codec of which ffmpeg is the only
>> >> encoder and decoder,
>> >>
>> >
>> >
>> >> development has stalled
>> >>
>> >
>> > Thats not true, there was private dicussion making sonic the most
>> > advanced audio codec in FFmpeg a few months ago.
>> > Iam not saying that will happen, i am just saying there was a
>> > discussion about it. And that iam in principle interrested in
>> > working on this. Its possible i will not have enough time ...
>> >
>>
>> I would strongly prefer for it to be kept around as well.
>>
>> Otherwise it creates precedence to throw out codecs if they're
>> not popular enough, and we're known for being able to play
>> most formats ever created.
>>
>
> IMO there is a big difference between a game codec and an experimental
> codec that hasn't come out of ffmpeg
>

We offer support for it. Someone must have used it.
I'm sure there are less used game codecs we support than Sonic.
Vittorio Giovara Feb. 29, 2024, 2:44 p.m. UTC | #13
On Thu, Feb 29, 2024 at 2:31 PM Lynne <dev@lynne.ee> wrote:

> Feb 29, 2024, 02:50 by vittorio.giovara@gmail.com:
>
> > On Wed, Feb 28, 2024 at 11:13 PM Lynne <dev@lynne.ee> wrote:
> >
> >> Feb 28, 2024, 14:29 by michael@niedermayer.cc:
> >>
> >> > On Wed, Feb 28, 2024 at 01:56:10PM +0100, J. Dekker wrote:
> >> >
> >> >> This was an experimental/research codec of which ffmpeg is the only
> >> >> encoder and decoder,
> >> >>
> >> >
> >> >
> >> >> development has stalled
> >> >>
> >> >
> >> > Thats not true, there was private dicussion making sonic the most
> >> > advanced audio codec in FFmpeg a few months ago.
> >> > Iam not saying that will happen, i am just saying there was a
> >> > discussion about it. And that iam in principle interrested in
> >> > working on this. Its possible i will not have enough time ...
> >> >
> >>
> >> I would strongly prefer for it to be kept around as well.
> >>
> >> Otherwise it creates precedence to throw out codecs if they're
> >> not popular enough, and we're known for being able to play
> >> most formats ever created.
> >>
> >
> > IMO there is a big difference between a game codec and an experimental
> > codec that hasn't come out of ffmpeg
> >
>
> We offer support for it. Someone must have used it.
> I'm sure there are less used game codecs we support than Sonic.
>

the point here is that game codecs are part of digital preservation and and
effort against digital obsolescence
an "experimental codec" that nobody (read: a very limited amount of users)
used except ffmpeg devs as playground does not warrant it being in the
codebase (but rather a branch or personal fork) IMO
Michael Niedermayer March 1, 2024, 1:13 a.m. UTC | #14
On Thu, Feb 29, 2024 at 03:44:46PM +0100, Vittorio Giovara wrote:
> On Thu, Feb 29, 2024 at 2:31 PM Lynne <dev@lynne.ee> wrote:
> 
> > Feb 29, 2024, 02:50 by vittorio.giovara@gmail.com:
> >
> > > On Wed, Feb 28, 2024 at 11:13 PM Lynne <dev@lynne.ee> wrote:
> > >
> > >> Feb 28, 2024, 14:29 by michael@niedermayer.cc:
> > >>
> > >> > On Wed, Feb 28, 2024 at 01:56:10PM +0100, J. Dekker wrote:
> > >> >
> > >> >> This was an experimental/research codec of which ffmpeg is the only
> > >> >> encoder and decoder,
> > >> >>
> > >> >
> > >> >
> > >> >> development has stalled
> > >> >>
> > >> >
> > >> > Thats not true, there was private dicussion making sonic the most
> > >> > advanced audio codec in FFmpeg a few months ago.
> > >> > Iam not saying that will happen, i am just saying there was a
> > >> > discussion about it. And that iam in principle interrested in
> > >> > working on this. Its possible i will not have enough time ...
> > >> >
> > >>
> > >> I would strongly prefer for it to be kept around as well.
> > >>
> > >> Otherwise it creates precedence to throw out codecs if they're
> > >> not popular enough, and we're known for being able to play
> > >> most formats ever created.
> > >>
> > >
> > > IMO there is a big difference between a game codec and an experimental
> > > codec that hasn't come out of ffmpeg
> > >
> >
> > We offer support for it. Someone must have used it.
> > I'm sure there are less used game codecs we support than Sonic.
> >
> 
> the point here is that game codecs are part of digital preservation and and
> effort against digital obsolescence

> an "experimental codec" that nobody (read: a very limited amount of users)

Every codec we develop is experimental and used by nobody
then by nobody outside ffmpeg
and if we dont allow this then we can never create a new codec.

FFv1 would not exist if we could not have added it at ta time
noone used it. FFv1 would not have become widely used if it was in
someones personal repository and main FFmpeg did not support it

thx

[...]
Anton Khirnov March 1, 2024, 6:59 p.m. UTC | #15
Quoting Lynne (2024-02-29 14:30:55)
> We offer support for it. Someone must have used it.
> I'm sure there are less used game codecs we support than Sonic.

[citation needed]

Is there any evidence that it was used for anything other than
development and testing? That anyone has any actual samples in it they'd
like to play?
Nicolas George March 1, 2024, 7:03 p.m. UTC | #16
Anton Khirnov (12024-03-01):
> Is there any evidence that it was used for anything other than
> development and testing? That anyone has any actual samples in it they'd
> like to play?

Wrong question. The burden of proof is on whoever wants to remove, not
on the status quo.

And good luck proving nobody in the whole world ever chose to try this
codec and kept the file. Maybe they are not even subscribed to this list
right now. I know, shocking!
Lynne March 1, 2024, 7:41 p.m. UTC | #17
Mar 1, 2024, 19:59 by anton@khirnov.net:

> Quoting Lynne (2024-02-29 14:30:55)
>
>> We offer support for it. Someone must have used it.
>> I'm sure there are less used game codecs we support than Sonic.
>>
>
> [citation needed]
>
> Is there any evidence that it was used for anything other than
> development and testing? That anyone has any actual samples in it they'd
> like to play?
>

There's always the possibility that someone encoded samples years
ago and deleted the originals. Same as with Snow.

My only concern is that this sets a sensitive precedent to get rid of
old codec code with low weight under unclear conditions. Where do
we draw the line?
SMPTE? ISO/IEC standardization? IETF? AOM?
Having *a* spec (Sonic doesn't, but neither did FFv1 until a few years
ago)?
A single company pushing for it many years ago with no spec,
like SpeedHQ, or the many niche lossless/intra-only codecs?

Or simply having one single implementation in FFmpeg, and no spec at all,
and having an experimental flag, and no activity for a very long amount of time?

If it's the last case, or simply being a one-off, I can agree with deprecating
and remove it next bump. But if the developer thinks they will have time and
have motivation to work on it in the future, I think we should leave it at just
deprecation plus disabling  building the encoder by default, until the issue is
brought up again at say, after the next version bump.
After all, CELT started out more than 10 years before Opus was standardized,
and its EC code has made it all the way to AV2 despite its core remaining
visibly similar over the years. And FFv1 was used as an inspiration for FLIC,
which went on to become JPEG-XL.
Tomas Härdin March 1, 2024, 8:14 p.m. UTC | #18
ons 2024-02-28 klockan 13:56 +0100 skrev J. Dekker:
> This was an experimental/research codec of which ffmpeg is the only
> encoder and decoder, development has stalled and these files don't
> exist
> in the wild.
> 
> Signed-off-by: J. Dekker <jdek@itanimul.li>
> ---
>  Changelog               |    1 +
>  configure               |    3 -
>  libavcodec/Makefile     |    3 -
>  libavcodec/allcodecs.c  |    3 -
>  libavcodec/codec_desc.c |   14 -
>  libavcodec/sonic.c      | 1125 -------------------------------------
> --
>  6 files changed, 1 insertion(+), 1148 deletions(-)
>  delete mode 100644 libavcodec/sonic.c

+1, modulo some technical points like not removing CodeIDs

/Tomas
Anton Khirnov March 1, 2024, 8:33 p.m. UTC | #19
Quoting Lynne (2024-03-01 20:41:53)
> Mar 1, 2024, 19:59 by anton@khirnov.net:
> 
> > Quoting Lynne (2024-02-29 14:30:55)
> >
> >> We offer support for it. Someone must have used it.
> >> I'm sure there are less used game codecs we support than Sonic.
> >>
> >
> > [citation needed]
> >
> > Is there any evidence that it was used for anything other than
> > development and testing? That anyone has any actual samples in it they'd
> > like to play?
> >
> 
> There's always the possibility that someone encoded samples years
> ago and deleted the originals. Same as with Snow.
> 
> My only concern is that this sets a sensitive precedent to get rid of
> old codec code with low weight under unclear conditions. Where do
> we draw the line?
> SMPTE? ISO/IEC standardization? IETF? AOM?
> Having *a* spec (Sonic doesn't, but neither did FFv1 until a few years
> ago)?
> A single company pushing for it many years ago with no spec,
> like SpeedHQ, or the many niche lossless/intra-only codecs?
> 
> Or simply having one single implementation in FFmpeg, and no spec at all,
> and having an experimental flag, and no activity for a very long amount of time?

I'd draw the line somewhere around what I said above - some evidence
that it was used "seriously".

> If it's the last case, or simply being a one-off, I can agree with deprecating
> and remove it next bump. But if the developer thinks they will have time and
> have motivation to work on it in the future, I think we should leave it at just
> deprecation plus disabling  building the encoder by default, until the issue is
> brought up again at say, after the next version bump.
> After all, CELT started out more than 10 years before Opus was standardized,
> and its EC code has made it all the way to AV2 despite its core remaining
> visibly similar over the years. And FFv1 was used as an inspiration for FLIC,
> which went on to become JPEG-XL.

Sure, but there was active interest in all of these. I see no active
interest in Sonic.
Lynne March 1, 2024, 9:34 p.m. UTC | #20
Mar 1, 2024, 21:33 by anton@khirnov.net:

> Quoting Lynne (2024-03-01 20:41:53)
>
>> Mar 1, 2024, 19:59 by anton@khirnov.net:
>>
>> > Quoting Lynne (2024-02-29 14:30:55)
>> >
>> >> We offer support for it. Someone must have used it.
>> >> I'm sure there are less used game codecs we support than Sonic.
>> >>
>> >
>> > [citation needed]
>> >
>> > Is there any evidence that it was used for anything other than
>> > development and testing? That anyone has any actual samples in it they'd
>> > like to play?
>> >
>>
>> There's always the possibility that someone encoded samples years
>> ago and deleted the originals. Same as with Snow.
>>
>> My only concern is that this sets a sensitive precedent to get rid of
>> old codec code with low weight under unclear conditions. Where do
>> we draw the line?
>> SMPTE? ISO/IEC standardization? IETF? AOM?
>> Having *a* spec (Sonic doesn't, but neither did FFv1 until a few years
>> ago)?
>> A single company pushing for it many years ago with no spec,
>> like SpeedHQ, or the many niche lossless/intra-only codecs?
>>
>> Or simply having one single implementation in FFmpeg, and no spec at all,
>> and having an experimental flag, and no activity for a very long amount of time?
>>
>
> I'd draw the line somewhere around what I said above - some evidence
> that it was used "seriously".
>

That is something I cannot agree with - it cuts off 70% of all codecs we support,
and zeroes out any potential chance of any codecs being developed by us.


>> If it's the last case, or simply being a one-off, I can agree with deprecating
>> and remove it next bump. But if the developer thinks they will have time and
>> have motivation to work on it in the future, I think we should leave it at just
>> deprecation plus disabling  building the encoder by default, until the issue is
>> brought up again at say, after the next version bump.
>> After all, CELT started out more than 10 years before Opus was standardized,
>> and its EC code has made it all the way to AV2 despite its core remaining
>> visibly similar over the years. And FFv1 was used as an inspiration for FLIC,
>> which went on to become JPEG-XL.
>>
>
> Sure, but there was active interest in all of these. I see no active
> interest in Sonic.
>

No one had any interest in CELT for years until it was used in Mumble,
or Speex initially, or FLIC, as it they were not competitive enough on its own,
and Vorbis, or Opus for the first few years.

The developer has said there's interest in continuing to work on it
in the future.
I don't see why we shouldn't give him a chance to work on it for
a bit longer before we bring it up again for removal. It's a simple
codec with no oddities like self-modifying assembly, codec to
demuxer to codec avpriv interaction or special API user considerations.
Vittorio Giovara March 2, 2024, 1:33 p.m. UTC | #21
On Fri, Mar 1, 2024 at 10:34 PM Lynne <dev@lynne.ee> wrote:

> >> If it's the last case, or simply being a one-off, I can agree with
> deprecating
> >> and remove it next bump. But if the developer thinks they will have
> time and
> >> have motivation to work on it in the future, I think we should leave it
> at just
> >> deprecation plus disabling  building the encoder by default, until the
> issue is
> >> brought up again at say, after the next version bump.
> >> After all, CELT started out more than 10 years before Opus was
> standardized,
> >> and its EC code has made it all the way to AV2 despite its core
> remaining
> >> visibly similar over the years. And FFv1 was used as an inspiration for
> FLIC,
> >> which went on to become JPEG-XL.
> >>
> >
> > Sure, but there was active interest in all of these. I see no active
> > interest in Sonic.
> >
>
> No one had any interest in CELT for years until it was used in Mumble,
> or Speex initially, or FLIC, as it they were not competitive enough on its
> own,
> and Vorbis, or Opus for the first few years.
>

There is nothing stopping developers to work on their own fork and release
the codec when ready, or at least there is moderate interest

The developer has said there's interest in continuing to work on it
> in the future.
>

The developer expressed interest in literally everything in ffmpeg, there
needs to be a threshold in what is reasonably expected to be worked on in a
lifetime.

I don't see why we shouldn't give him a chance to work on it for
> a bit longer before we bring it up again for removal.
>

Because people had 10 years to work on it a bit longer and they didn't.
Claiming interest only because there is an active removal process is not
very healthy for the codebase (or the community).
Alexander Strasser March 10, 2024, 1:12 p.m. UTC | #22
On 2024-02-28 19:36 +0100, Jean-Baptiste Kempf wrote:
>
> On Wed, 28 Feb 2024, at 18:55, James Almer wrote:
> > On 2/28/2024 10:31 AM, J. Dekker wrote:
> >>
> >> Michael Niedermayer <michael@niedermayer.cc> writes:
> >>
> >>> [[PGP Signed Part:Undecided]]
> >>> On Wed, Feb 28, 2024 at 01:56:10PM +0100, J. Dekker wrote:
> >>>> This was an experimental/research codec of which ffmpeg is the only
> >>>> encoder and decoder,
> >>>
> >>>
> >>>> development has stalled
> >>>
> >>> Thats not true, there was private dicussion making sonic the most
> >>> advanced audio codec in FFmpeg a few months ago.
> >>> Iam not saying that will happen, i am just saying there was a
> >>> discussion about it. And that iam in principle interrested in
> >>> working on this. Its possible i will not have enough time ...
> >>>
> >>
> >> The last commit which actually changed the codec was
> >> 6026a5ad4f135476c7a1f51f8cfa7f4cc2ca0283 by you in 2013 which is over 10
> >> years ago. For an experimental codec I think it's pretty safe to say
> >> that development has stalled.
> >>
> >> Keeping the codec around based on 'what if?'s doesn't seem
> >> reasonable. Besides, if you do make sonic the most advanced audio codec
> >> in FFmpeg there's nothing which says you couldn't re-add it at a later
> >> date when it's being actively developed again.
> >
> > Does it hurt keeping it around? If it can at some point be developed
> > again, then removing the codec id to re-add it later will be a bit dirty.
> >
> > IMO, just disable both modules by default during configure, or tag the
> > encoder as experimental to prevent new streams to be created unless
> > explicitly requested knowing that it's an unfinished format.
>
> +1

+1

But if it stays it should be regularly compiled (at least on a fate client).


  Alexander
Leo Izen March 10, 2024, 7:45 p.m. UTC | #23
On 2/29/24 20:13, Michael Niedermayer wrote:
> 
> Every codec we develop is experimental and used by nobody
> then by nobody outside ffmpeg
> and if we dont allow this then we can never create a new codec.
> 
> FFv1 would not exist if we could not have added it at ta time
> noone used it. FFv1 would not have become widely used if it was in
> someones personal repository and main FFmpeg did not support it
> 
> thx
> 


This is true, but also the code hasn't been touched in more than ten 
years, which makes it a bit different than, say, ffv1 which was actively 
developed for a while and still is.

- Leo Izen (Traneptora)
diff mbox series

Patch

diff --git a/Changelog b/Changelog
index 610ee61dd6..e2096f249a 100644
--- a/Changelog
+++ b/Changelog
@@ -27,6 +27,7 @@  version <next>:
 - a C11-compliant compiler is now required; note that this requirement
   will be bumped to C17 in the near future, so consider updating your
   build environment if it lacks C17 support
+- sonic lossy/lossless audio codec removed
 
 version 6.1:
 - libaribcaption decoder
diff --git a/configure b/configure
index bb5e630bad..e639a5e2b7 100755
--- a/configure
+++ b/configure
@@ -2991,9 +2991,6 @@  sipr_decoder_select="lsp"
 smvjpeg_decoder_select="mjpeg_decoder"
 snow_decoder_select="dwt h264qpel rangecoder videodsp"
 snow_encoder_select="dwt h264qpel hpeldsp me_cmp mpegvideoenc rangecoder videodsp"
-sonic_decoder_select="golomb rangecoder"
-sonic_encoder_select="golomb rangecoder"
-sonic_ls_encoder_select="golomb rangecoder"
 sp5x_decoder_select="mjpeg_decoder"
 speedhq_decoder_select="blockdsp idctdsp"
 speedhq_encoder_select="mpegvideoenc"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 09ae5270b3..3fc716ee68 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -687,9 +687,6 @@  OBJS-$(CONFIG_SNOW_DECODER)            += snowdec.o snow.o snow_dwt.o
 OBJS-$(CONFIG_SNOW_ENCODER)            += snowenc.o snow.o snow_dwt.o             \
                                           h263.o h263data.o ituh263enc.o
 OBJS-$(CONFIG_SOL_DPCM_DECODER)        += dpcm.o
-OBJS-$(CONFIG_SONIC_DECODER)           += sonic.o
-OBJS-$(CONFIG_SONIC_ENCODER)           += sonic.o
-OBJS-$(CONFIG_SONIC_LS_ENCODER)        += sonic.o
 OBJS-$(CONFIG_SPEEDHQ_DECODER)         += speedhqdec.o speedhq.o mpeg12.o \
                                           mpeg12data.o
 OBJS-$(CONFIG_SPEEDHQ_ENCODER)         += speedhq.o mpeg12data.o mpeg12enc.o speedhqenc.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index ef8c3a6d7d..e0a4a5421d 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -535,9 +535,6 @@  extern const FFCodec ff_shorten_decoder;
 extern const FFCodec ff_sipr_decoder;
 extern const FFCodec ff_siren_decoder;
 extern const FFCodec ff_smackaud_decoder;
-extern const FFCodec ff_sonic_encoder;
-extern const FFCodec ff_sonic_decoder;
-extern const FFCodec ff_sonic_ls_encoder;
 extern const FFCodec ff_tak_decoder;
 extern const FFCodec ff_truehd_encoder;
 extern const FFCodec ff_truehd_decoder;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 033344304c..9b456616be 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -3175,20 +3175,6 @@  static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("Wave synthesis pseudo-codec"),
         .props     = AV_CODEC_PROP_INTRA_ONLY,
     },
-    {
-        .id        = AV_CODEC_ID_SONIC,
-        .type      = AVMEDIA_TYPE_AUDIO,
-        .name      = "sonic",
-        .long_name = NULL_IF_CONFIG_SMALL("Sonic"),
-        .props     = AV_CODEC_PROP_INTRA_ONLY,
-    },
-    {
-        .id        = AV_CODEC_ID_SONIC_LS,
-        .type      = AVMEDIA_TYPE_AUDIO,
-        .name      = "sonicls",
-        .long_name = NULL_IF_CONFIG_SMALL("Sonic lossless"),
-        .props     = AV_CODEC_PROP_INTRA_ONLY,
-    },
     {
         .id        = AV_CODEC_ID_EVRC,
         .type      = AVMEDIA_TYPE_AUDIO,
diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c
deleted file mode 100644
index 0544fecf46..0000000000
--- a/libavcodec/sonic.c
+++ /dev/null
@@ -1,1125 +0,0 @@ 
-/*
- * Simple free lossless/lossy audio codec
- * Copyright (c) 2004 Alex Beregszaszi
- *
- * 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 "config_components.h"
-
-#include "avcodec.h"
-#include "codec_internal.h"
-#include "decode.h"
-#include "encode.h"
-#include "get_bits.h"
-#include "golomb.h"
-#include "put_golomb.h"
-#include "rangecoder.h"
-
-
-/**
- * @file
- * Simple free lossless/lossy audio codec
- * Based on Paul Francis Harrison's Bonk (http://www.logarithmic.net/pfh/bonk)
- * Written and designed by Alex Beregszaszi
- *
- * TODO:
- *  - CABAC put/get_symbol
- *  - independent quantizer for channels
- *  - >2 channels support
- *  - more decorrelation types
- *  - more tap_quant tests
- *  - selectable intlist writers/readers (bonk-style, golomb, cabac)
- */
-
-#define MAX_CHANNELS 2
-
-#define MID_SIDE 0
-#define LEFT_SIDE 1
-#define RIGHT_SIDE 2
-
-typedef struct SonicContext {
-    int version;
-    int minor_version;
-    int lossless, decorrelation;
-
-    int num_taps, downsampling;
-    double quantization;
-
-    int channels, samplerate, block_align, frame_size;
-
-    int *tap_quant;
-    int *int_samples;
-    int *coded_samples[MAX_CHANNELS];
-
-    // for encoding
-    int *tail;
-    int tail_size;
-    int *window;
-    int window_size;
-
-    // for decoding
-    int *predictor_k;
-    int *predictor_state[MAX_CHANNELS];
-} SonicContext;
-
-#define LATTICE_SHIFT   10
-#define SAMPLE_SHIFT    4
-#define LATTICE_FACTOR  (1 << LATTICE_SHIFT)
-#define SAMPLE_FACTOR   (1 << SAMPLE_SHIFT)
-
-#define BASE_QUANT      0.6
-#define RATE_VARIATION  3.0
-
-static inline int shift(int a,int b)
-{
-    return (a+(1<<(b-1))) >> b;
-}
-
-static inline int shift_down(int a,int b)
-{
-    return (a>>b)+(a<0);
-}
-
-static av_always_inline av_flatten void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed, uint64_t rc_stat[256][2], uint64_t rc_stat2[32][2]){
-    int i;
-
-#define put_rac(C,S,B) \
-do{\
-    if(rc_stat){\
-        rc_stat[*(S)][B]++;\
-        rc_stat2[(S)-state][B]++;\
-    }\
-    put_rac(C,S,B);\
-}while(0)
-
-    if(v){
-        const int a= FFABS(v);
-        const int e= av_log2(a);
-        put_rac(c, state+0, 0);
-        if(e<=9){
-            for(i=0; i<e; i++){
-                put_rac(c, state+1+i, 1);  //1..10
-            }
-            put_rac(c, state+1+i, 0);
-
-            for(i=e-1; i>=0; i--){
-                put_rac(c, state+22+i, (a>>i)&1); //22..31
-            }
-
-            if(is_signed)
-                put_rac(c, state+11 + e, v < 0); //11..21
-        }else{
-            for(i=0; i<e; i++){
-                put_rac(c, state+1+FFMIN(i,9), 1);  //1..10
-            }
-            put_rac(c, state+1+9, 0);
-
-            for(i=e-1; i>=0; i--){
-                put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31
-            }
-
-            if(is_signed)
-                put_rac(c, state+11 + 10, v < 0); //11..21
-        }
-    }else{
-        put_rac(c, state+0, 1);
-    }
-#undef put_rac
-}
-
-static inline av_flatten int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){
-    if(get_rac(c, state+0))
-        return 0;
-    else{
-        int i, e;
-        unsigned a;
-        e= 0;
-        while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10
-            e++;
-            if (e > 31)
-                return AVERROR_INVALIDDATA;
-        }
-
-        a= 1;
-        for(i=e-1; i>=0; i--){
-            a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31
-        }
-
-        e= -(is_signed && get_rac(c, state+11 + FFMIN(e, 10))); //11..21
-        return (a^e)-e;
-    }
-}
-
-#if 1
-static inline int intlist_write(RangeCoder *c, uint8_t *state, int *buf, int entries, int base_2_part)
-{
-    int i;
-
-    for (i = 0; i < entries; i++)
-        put_symbol(c, state, buf[i], 1, NULL, NULL);
-
-    return 1;
-}
-
-static inline int intlist_read(RangeCoder *c, uint8_t *state, int *buf, int entries, int base_2_part)
-{
-    int i;
-
-    for (i = 0; i < entries; i++)
-        buf[i] = get_symbol(c, state, 1);
-
-    return 1;
-}
-#elif 1
-static inline int intlist_write(PutBitContext *pb, int *buf, int entries, int base_2_part)
-{
-    int i;
-
-    for (i = 0; i < entries; i++)
-        set_se_golomb(pb, buf[i]);
-
-    return 1;
-}
-
-static inline int intlist_read(GetBitContext *gb, int *buf, int entries, int base_2_part)
-{
-    int i;
-
-    for (i = 0; i < entries; i++)
-        buf[i] = get_se_golomb(gb);
-
-    return 1;
-}
-
-#else
-
-#define ADAPT_LEVEL 8
-
-static int bits_to_store(uint64_t x)
-{
-    int res = 0;
-
-    while(x)
-    {
-        res++;
-        x >>= 1;
-    }
-    return res;
-}
-
-static void write_uint_max(PutBitContext *pb, unsigned int value, unsigned int max)
-{
-    int i, bits;
-
-    if (!max)
-        return;
-
-    bits = bits_to_store(max);
-
-    for (i = 0; i < bits-1; i++)
-        put_bits(pb, 1, value & (1 << i));
-
-    if ( (value | (1 << (bits-1))) <= max)
-        put_bits(pb, 1, value & (1 << (bits-1)));
-}
-
-static unsigned int read_uint_max(GetBitContext *gb, int max)
-{
-    int i, bits, value = 0;
-
-    if (!max)
-        return 0;
-
-    bits = bits_to_store(max);
-
-    for (i = 0; i < bits-1; i++)
-        if (get_bits1(gb))
-            value += 1 << i;
-
-    if ( (value | (1<<(bits-1))) <= max)
-        if (get_bits1(gb))
-            value += 1 << (bits-1);
-
-    return value;
-}
-
-static int intlist_write(PutBitContext *pb, int *buf, int entries, int base_2_part)
-{
-    int i, j, x = 0, low_bits = 0, max = 0;
-    int step = 256, pos = 0, dominant = 0, any = 0;
-    int *copy, *bits;
-
-    copy = av_calloc(entries, sizeof(*copy));
-    if (!copy)
-        return AVERROR(ENOMEM);
-
-    if (base_2_part)
-    {
-        int energy = 0;
-
-        for (i = 0; i < entries; i++)
-            energy += abs(buf[i]);
-
-        low_bits = bits_to_store(energy / (entries * 2));
-        if (low_bits > 15)
-            low_bits = 15;
-
-        put_bits(pb, 4, low_bits);
-    }
-
-    for (i = 0; i < entries; i++)
-    {
-        put_bits(pb, low_bits, abs(buf[i]));
-        copy[i] = abs(buf[i]) >> low_bits;
-        if (copy[i] > max)
-            max = abs(copy[i]);
-    }
-
-    bits = av_calloc(entries*max, sizeof(*bits));
-    if (!bits)
-    {
-        av_free(copy);
-        return AVERROR(ENOMEM);
-    }
-
-    for (i = 0; i <= max; i++)
-    {
-        for (j = 0; j < entries; j++)
-            if (copy[j] >= i)
-                bits[x++] = copy[j] > i;
-    }
-
-    // store bitstream
-    while (pos < x)
-    {
-        int steplet = step >> 8;
-
-        if (pos + steplet > x)
-            steplet = x - pos;
-
-        for (i = 0; i < steplet; i++)
-            if (bits[i+pos] != dominant)
-                any = 1;
-
-        put_bits(pb, 1, any);
-
-        if (!any)
-        {
-            pos += steplet;
-            step += step / ADAPT_LEVEL;
-        }
-        else
-        {
-            int interloper = 0;
-
-            while (((pos + interloper) < x) && (bits[pos + interloper] == dominant))
-                interloper++;
-
-            // note change
-            write_uint_max(pb, interloper, (step >> 8) - 1);
-
-            pos += interloper + 1;
-            step -= step / ADAPT_LEVEL;
-        }
-
-        if (step < 256)
-        {
-            step = 65536 / step;
-            dominant = !dominant;
-        }
-    }
-
-    // store signs
-    for (i = 0; i < entries; i++)
-        if (buf[i])
-            put_bits(pb, 1, buf[i] < 0);
-
-    av_free(bits);
-    av_free(copy);
-
-    return 0;
-}
-
-static int intlist_read(GetBitContext *gb, int *buf, int entries, int base_2_part)
-{
-    int i, low_bits = 0, x = 0;
-    int n_zeros = 0, step = 256, dominant = 0;
-    int pos = 0, level = 0;
-    int *bits = av_calloc(entries, sizeof(*bits));
-
-    if (!bits)
-        return AVERROR(ENOMEM);
-
-    if (base_2_part)
-    {
-        low_bits = get_bits(gb, 4);
-
-        if (low_bits)
-            for (i = 0; i < entries; i++)
-                buf[i] = get_bits(gb, low_bits);
-    }
-
-//    av_log(NULL, AV_LOG_INFO, "entries: %d, low bits: %d\n", entries, low_bits);
-
-    while (n_zeros < entries)
-    {
-        int steplet = step >> 8;
-
-        if (!get_bits1(gb))
-        {
-            for (i = 0; i < steplet; i++)
-                bits[x++] = dominant;
-
-            if (!dominant)
-                n_zeros += steplet;
-
-            step += step / ADAPT_LEVEL;
-        }
-        else
-        {
-            int actual_run = read_uint_max(gb, steplet-1);
-
-//            av_log(NULL, AV_LOG_INFO, "actual run: %d\n", actual_run);
-
-            for (i = 0; i < actual_run; i++)
-                bits[x++] = dominant;
-
-            bits[x++] = !dominant;
-
-            if (!dominant)
-                n_zeros += actual_run;
-            else
-                n_zeros++;
-
-            step -= step / ADAPT_LEVEL;
-        }
-
-        if (step < 256)
-        {
-            step = 65536 / step;
-            dominant = !dominant;
-        }
-    }
-
-    // reconstruct unsigned values
-    n_zeros = 0;
-    for (i = 0; n_zeros < entries; i++)
-    {
-        while(1)
-        {
-            if (pos >= entries)
-            {
-                pos = 0;
-                level += 1 << low_bits;
-            }
-
-            if (buf[pos] >= level)
-                break;
-
-            pos++;
-        }
-
-        if (bits[i])
-            buf[pos] += 1 << low_bits;
-        else
-            n_zeros++;
-
-        pos++;
-    }
-    av_free(bits);
-
-    // read signs
-    for (i = 0; i < entries; i++)
-        if (buf[i] && get_bits1(gb))
-            buf[i] = -buf[i];
-
-//    av_log(NULL, AV_LOG_INFO, "zeros: %d pos: %d\n", n_zeros, pos);
-
-    return 0;
-}
-#endif
-
-static void predictor_init_state(int *k, int *state, int order)
-{
-    int i;
-
-    for (i = order-2; i >= 0; i--)
-    {
-        int j, p, x = state[i];
-
-        for (j = 0, p = i+1; p < order; j++,p++)
-            {
-            int tmp = x + shift_down(k[j] * (unsigned)state[p], LATTICE_SHIFT);
-            state[p] += shift_down(k[j]* (unsigned)x, LATTICE_SHIFT);
-            x = tmp;
-        }
-    }
-}
-
-static int predictor_calc_error(int *k, int *state, int order, int error)
-{
-    int i, x = error - (unsigned)shift_down(k[order-1] *  (unsigned)state[order-1], LATTICE_SHIFT);
-
-#if 1
-    int *k_ptr = &(k[order-2]),
-        *state_ptr = &(state[order-2]);
-    for (i = order-2; i >= 0; i--, k_ptr--, state_ptr--)
-    {
-        int k_value = *k_ptr, state_value = *state_ptr;
-        x -= (unsigned)shift_down(k_value * (unsigned)state_value, LATTICE_SHIFT);
-        state_ptr[1] = state_value + shift_down(k_value * (unsigned)x, LATTICE_SHIFT);
-    }
-#else
-    for (i = order-2; i >= 0; i--)
-    {
-        x -= (unsigned)shift_down(k[i] * state[i], LATTICE_SHIFT);
-        state[i+1] = state[i] + shift_down(k[i] * x, LATTICE_SHIFT);
-    }
-#endif
-
-    // don't drift too far, to avoid overflows
-    if (x >  (SAMPLE_FACTOR<<16)) x =  (SAMPLE_FACTOR<<16);
-    if (x < -(SAMPLE_FACTOR<<16)) x = -(SAMPLE_FACTOR<<16);
-
-    state[0] = x;
-
-    return x;
-}
-
-#if CONFIG_SONIC_ENCODER || CONFIG_SONIC_LS_ENCODER
-// Heavily modified Levinson-Durbin algorithm which
-// copes better with quantization, and calculates the
-// actual whitened result as it goes.
-
-static void modified_levinson_durbin(int *window, int window_entries,
-        int *out, int out_entries, int channels, int *tap_quant)
-{
-    int i;
-    int *state = window + window_entries;
-
-    memcpy(state, window, window_entries * sizeof(*state));
-
-    for (i = 0; i < out_entries; i++)
-    {
-        int step = (i+1)*channels, k, j;
-        double xx = 0.0, xy = 0.0;
-#if 1
-        int *x_ptr = &(window[step]);
-        int *state_ptr = &(state[0]);
-        j = window_entries - step;
-        for (;j>0;j--,x_ptr++,state_ptr++)
-        {
-            double x_value = *x_ptr;
-            double state_value = *state_ptr;
-            xx += state_value*state_value;
-            xy += x_value*state_value;
-        }
-#else
-        for (j = 0; j <= (window_entries - step); j++);
-        {
-            double stepval = window[step+j];
-            double stateval = window[j];
-//            xx += (double)window[j]*(double)window[j];
-//            xy += (double)window[step+j]*(double)window[j];
-            xx += stateval*stateval;
-            xy += stepval*stateval;
-        }
-#endif
-        if (xx == 0.0)
-            k = 0;
-        else
-            k = (int)(floor(-xy/xx * (double)LATTICE_FACTOR / (double)(tap_quant[i]) + 0.5));
-
-        if (k > (LATTICE_FACTOR/tap_quant[i]))
-            k = LATTICE_FACTOR/tap_quant[i];
-        if (-k > (LATTICE_FACTOR/tap_quant[i]))
-            k = -(LATTICE_FACTOR/tap_quant[i]);
-
-        out[i] = k;
-        k *= tap_quant[i];
-
-#if 1
-        x_ptr = &(window[step]);
-        state_ptr = &(state[0]);
-        j = window_entries - step;
-        for (;j>0;j--,x_ptr++,state_ptr++)
-        {
-            int x_value = *x_ptr;
-            int state_value = *state_ptr;
-            *x_ptr = x_value + shift_down(k*state_value,LATTICE_SHIFT);
-            *state_ptr = state_value + shift_down(k*x_value, LATTICE_SHIFT);
-        }
-#else
-        for (j=0; j <= (window_entries - step); j++)
-        {
-            int stepval = window[step+j];
-            int stateval=state[j];
-            window[step+j] += shift_down(k * stateval, LATTICE_SHIFT);
-            state[j] += shift_down(k * stepval, LATTICE_SHIFT);
-        }
-#endif
-    }
-}
-
-static inline int code_samplerate(int samplerate)
-{
-    switch (samplerate)
-    {
-        case 44100: return 0;
-        case 22050: return 1;
-        case 11025: return 2;
-        case 96000: return 3;
-        case 48000: return 4;
-        case 32000: return 5;
-        case 24000: return 6;
-        case 16000: return 7;
-        case 8000: return 8;
-    }
-    return AVERROR(EINVAL);
-}
-
-static av_cold int sonic_encode_init(AVCodecContext *avctx)
-{
-    SonicContext *s = avctx->priv_data;
-    int *coded_samples;
-    PutBitContext pb;
-    int i;
-
-    s->version = 2;
-
-    if (avctx->ch_layout.nb_channels > MAX_CHANNELS)
-    {
-        av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n");
-        return AVERROR(EINVAL); /* only stereo or mono for now */
-    }
-
-    if (avctx->ch_layout.nb_channels == 2)
-        s->decorrelation = MID_SIDE;
-    else
-        s->decorrelation = 3;
-
-    if (avctx->codec->id == AV_CODEC_ID_SONIC_LS)
-    {
-        s->lossless = 1;
-        s->num_taps = 32;
-        s->downsampling = 1;
-        s->quantization = 0.0;
-    }
-    else
-    {
-        s->num_taps = 128;
-        s->downsampling = 2;
-        s->quantization = 1.0;
-    }
-
-    // max tap 2048
-    if (s->num_taps < 32 || s->num_taps > 1024 || s->num_taps % 32) {
-        av_log(avctx, AV_LOG_ERROR, "Invalid number of taps\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    // generate taps
-    s->tap_quant = av_calloc(s->num_taps, sizeof(*s->tap_quant));
-    if (!s->tap_quant)
-        return AVERROR(ENOMEM);
-
-    for (i = 0; i < s->num_taps; i++)
-        s->tap_quant[i] = ff_sqrt(i+1);
-
-    s->channels = avctx->ch_layout.nb_channels;
-    s->samplerate = avctx->sample_rate;
-
-    s->block_align = 2048LL*s->samplerate/(44100*s->downsampling);
-    s->frame_size = s->channels*s->block_align*s->downsampling;
-
-    s->tail_size = s->num_taps*s->channels;
-    s->tail = av_calloc(s->tail_size, sizeof(*s->tail));
-    if (!s->tail)
-        return AVERROR(ENOMEM);
-
-    s->predictor_k = av_calloc(s->num_taps, sizeof(*s->predictor_k) );
-    if (!s->predictor_k)
-        return AVERROR(ENOMEM);
-
-    coded_samples = av_calloc(s->block_align, s->channels * sizeof(**s->coded_samples));
-    if (!coded_samples)
-        return AVERROR(ENOMEM);
-    for (i = 0; i < s->channels; i++, coded_samples += s->block_align)
-        s->coded_samples[i] = coded_samples;
-
-    s->int_samples = av_calloc(s->frame_size, sizeof(*s->int_samples));
-
-    s->window_size = ((2*s->tail_size)+s->frame_size);
-    s->window = av_calloc(s->window_size, 2 * sizeof(*s->window));
-    if (!s->window || !s->int_samples)
-        return AVERROR(ENOMEM);
-
-    avctx->extradata = av_mallocz(16);
-    if (!avctx->extradata)
-        return AVERROR(ENOMEM);
-    init_put_bits(&pb, avctx->extradata, 16*8);
-
-    put_bits(&pb, 2, s->version); // version
-    if (s->version >= 1)
-    {
-        if (s->version >= 2) {
-            put_bits(&pb, 8, s->version);
-            put_bits(&pb, 8, s->minor_version);
-        }
-        put_bits(&pb, 2, s->channels);
-        put_bits(&pb, 4, code_samplerate(s->samplerate));
-    }
-    put_bits(&pb, 1, s->lossless);
-    if (!s->lossless)
-        put_bits(&pb, 3, SAMPLE_SHIFT); // XXX FIXME: sample precision
-    put_bits(&pb, 2, s->decorrelation);
-    put_bits(&pb, 2, s->downsampling);
-    put_bits(&pb, 5, (s->num_taps >> 5)-1); // 32..1024
-    put_bits(&pb, 1, 0); // XXX FIXME: no custom tap quant table
-
-    flush_put_bits(&pb);
-    avctx->extradata_size = put_bytes_output(&pb);
-
-    av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d.%d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n",
-        s->version, s->minor_version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling);
-
-    avctx->frame_size = s->block_align*s->downsampling;
-
-    return 0;
-}
-
-static av_cold int sonic_encode_close(AVCodecContext *avctx)
-{
-    SonicContext *s = avctx->priv_data;
-
-    av_freep(&s->coded_samples[0]);
-    av_freep(&s->predictor_k);
-    av_freep(&s->tail);
-    av_freep(&s->tap_quant);
-    av_freep(&s->window);
-    av_freep(&s->int_samples);
-
-    return 0;
-}
-
-static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
-                              const AVFrame *frame, int *got_packet_ptr)
-{
-    SonicContext *s = avctx->priv_data;
-    RangeCoder c;
-    int i, j, ch, quant = 0, x = 0;
-    int ret;
-    const short *samples = (const int16_t*)frame->data[0];
-    uint8_t state[32];
-
-    if ((ret = ff_alloc_packet(avctx, avpkt, s->frame_size * 5 + 1000)) < 0)
-        return ret;
-
-    ff_init_range_encoder(&c, avpkt->data, avpkt->size);
-    ff_build_rac_states(&c, 0.05*(1LL<<32), 256-8);
-    memset(state, 128, sizeof(state));
-
-    // short -> internal
-    for (i = 0; i < s->frame_size; i++)
-        s->int_samples[i] = samples[i];
-
-    if (!s->lossless)
-        for (i = 0; i < s->frame_size; i++)
-            s->int_samples[i] = s->int_samples[i] << SAMPLE_SHIFT;
-
-    switch(s->decorrelation)
-    {
-        case MID_SIDE:
-            for (i = 0; i < s->frame_size; i += s->channels)
-            {
-                s->int_samples[i] += s->int_samples[i+1];
-                s->int_samples[i+1] -= shift(s->int_samples[i], 1);
-            }
-            break;
-        case LEFT_SIDE:
-            for (i = 0; i < s->frame_size; i += s->channels)
-                s->int_samples[i+1] -= s->int_samples[i];
-            break;
-        case RIGHT_SIDE:
-            for (i = 0; i < s->frame_size; i += s->channels)
-                s->int_samples[i] -= s->int_samples[i+1];
-            break;
-    }
-
-    memset(s->window, 0, s->window_size * sizeof(*s->window));
-
-    for (i = 0; i < s->tail_size; i++)
-        s->window[x++] = s->tail[i];
-
-    for (i = 0; i < s->frame_size; i++)
-        s->window[x++] = s->int_samples[i];
-
-    for (i = 0; i < s->tail_size; i++)
-        s->window[x++] = 0;
-
-    for (i = 0; i < s->tail_size; i++)
-        s->tail[i] = s->int_samples[s->frame_size - s->tail_size + i];
-
-    // generate taps
-    modified_levinson_durbin(s->window, s->window_size,
-                s->predictor_k, s->num_taps, s->channels, s->tap_quant);
-
-    if ((ret = intlist_write(&c, state, s->predictor_k, s->num_taps, 0)) < 0)
-        return ret;
-
-    for (ch = 0; ch < s->channels; ch++)
-    {
-        x = s->tail_size+ch;
-        for (i = 0; i < s->block_align; i++)
-        {
-            int sum = 0;
-            for (j = 0; j < s->downsampling; j++, x += s->channels)
-                sum += s->window[x];
-            s->coded_samples[ch][i] = sum;
-        }
-    }
-
-    // simple rate control code
-    if (!s->lossless)
-    {
-        double energy1 = 0.0, energy2 = 0.0;
-        for (ch = 0; ch < s->channels; ch++)
-        {
-            for (i = 0; i < s->block_align; i++)
-            {
-                double sample = s->coded_samples[ch][i];
-                energy2 += sample*sample;
-                energy1 += fabs(sample);
-            }
-        }
-
-        energy2 = sqrt(energy2/(s->channels*s->block_align));
-        energy1 = M_SQRT2*energy1/(s->channels*s->block_align);
-
-        // increase bitrate when samples are like a gaussian distribution
-        // reduce bitrate when samples are like a two-tailed exponential distribution
-
-        if (energy2 > energy1)
-            energy2 += (energy2-energy1)*RATE_VARIATION;
-
-        quant = (int)(BASE_QUANT*s->quantization*energy2/SAMPLE_FACTOR);
-//        av_log(avctx, AV_LOG_DEBUG, "quant: %d energy: %f / %f\n", quant, energy1, energy2);
-
-        quant = av_clip(quant, 1, 65534);
-
-        put_symbol(&c, state, quant, 0, NULL, NULL);
-
-        quant *= SAMPLE_FACTOR;
-    }
-
-    // write out coded samples
-    for (ch = 0; ch < s->channels; ch++)
-    {
-        if (!s->lossless)
-            for (i = 0; i < s->block_align; i++)
-                s->coded_samples[ch][i] = ROUNDED_DIV(s->coded_samples[ch][i], quant);
-
-        if ((ret = intlist_write(&c, state, s->coded_samples[ch], s->block_align, 1)) < 0)
-            return ret;
-    }
-
-    avpkt->size = ff_rac_terminate(&c, 0);
-    *got_packet_ptr = 1;
-    return 0;
-
-}
-#endif /* CONFIG_SONIC_ENCODER || CONFIG_SONIC_LS_ENCODER */
-
-#if CONFIG_SONIC_DECODER
-static const int samplerate_table[] =
-    { 44100, 22050, 11025, 96000, 48000, 32000, 24000, 16000, 8000 };
-
-static av_cold int sonic_decode_init(AVCodecContext *avctx)
-{
-    SonicContext *s = avctx->priv_data;
-    int *tmp;
-    GetBitContext gb;
-    int i;
-    int ret;
-
-    s->channels = avctx->ch_layout.nb_channels;
-    s->samplerate = avctx->sample_rate;
-
-    if (!avctx->extradata)
-    {
-        av_log(avctx, AV_LOG_ERROR, "No mandatory headers present\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    ret = init_get_bits8(&gb, avctx->extradata, avctx->extradata_size);
-    if (ret < 0)
-        return ret;
-
-    s->version = get_bits(&gb, 2);
-    if (s->version >= 2) {
-        s->version       = get_bits(&gb, 8);
-        s->minor_version = get_bits(&gb, 8);
-    }
-    if (s->version != 2)
-    {
-        av_log(avctx, AV_LOG_ERROR, "Unsupported Sonic version, please report\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    if (s->version >= 1)
-    {
-        int sample_rate_index;
-        s->channels = get_bits(&gb, 2);
-        sample_rate_index = get_bits(&gb, 4);
-        if (sample_rate_index >= FF_ARRAY_ELEMS(samplerate_table)) {
-            av_log(avctx, AV_LOG_ERROR, "Invalid sample_rate_index %d\n", sample_rate_index);
-            return AVERROR_INVALIDDATA;
-        }
-        s->samplerate = samplerate_table[sample_rate_index];
-        av_log(avctx, AV_LOG_INFO, "Sonicv2 chans: %d samprate: %d\n",
-            s->channels, s->samplerate);
-    }
-
-    if (s->channels > MAX_CHANNELS || s->channels < 1)
-    {
-        av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n");
-        return AVERROR_INVALIDDATA;
-    }
-    av_channel_layout_uninit(&avctx->ch_layout);
-    avctx->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
-    avctx->ch_layout.nb_channels = s->channels;
-
-    s->lossless = get_bits1(&gb);
-    if (!s->lossless)
-        skip_bits(&gb, 3); // XXX FIXME
-    s->decorrelation = get_bits(&gb, 2);
-    if (s->decorrelation != 3 && s->channels != 2) {
-        av_log(avctx, AV_LOG_ERROR, "invalid decorrelation %d\n", s->decorrelation);
-        return AVERROR_INVALIDDATA;
-    }
-
-    s->downsampling = get_bits(&gb, 2);
-    if (!s->downsampling) {
-        av_log(avctx, AV_LOG_ERROR, "invalid downsampling value\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    s->num_taps = (get_bits(&gb, 5)+1)<<5;
-    if (get_bits1(&gb)) // XXX FIXME
-        av_log(avctx, AV_LOG_INFO, "Custom quant table\n");
-
-    s->block_align = 2048LL*s->samplerate/(44100*s->downsampling);
-    s->frame_size = s->channels*s->block_align*s->downsampling;
-//    avctx->frame_size = s->block_align;
-
-    if (s->num_taps * s->channels > s->frame_size) {
-        av_log(avctx, AV_LOG_ERROR,
-               "number of taps times channels (%d * %d) larger than frame size %d\n",
-               s->num_taps, s->channels, s->frame_size);
-        return AVERROR_INVALIDDATA;
-    }
-
-    av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d.%d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n",
-        s->version, s->minor_version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling);
-
-    // generate taps
-    s->tap_quant = av_calloc(s->num_taps, sizeof(*s->tap_quant));
-    if (!s->tap_quant)
-        return AVERROR(ENOMEM);
-
-    for (i = 0; i < s->num_taps; i++)
-        s->tap_quant[i] = ff_sqrt(i+1);
-
-    s->predictor_k = av_calloc(s->num_taps, sizeof(*s->predictor_k));
-
-    tmp = av_calloc(s->num_taps, s->channels * sizeof(**s->predictor_state));
-    if (!tmp)
-        return AVERROR(ENOMEM);
-    for (i = 0; i < s->channels; i++, tmp += s->num_taps)
-        s->predictor_state[i] = tmp;
-
-    tmp = av_calloc(s->block_align, s->channels * sizeof(**s->coded_samples));
-    if (!tmp)
-        return AVERROR(ENOMEM);
-    for (i = 0; i < s->channels; i++, tmp += s->block_align)
-        s->coded_samples[i]   = tmp;
-
-    s->int_samples = av_calloc(s->frame_size, sizeof(*s->int_samples));
-    if (!s->int_samples)
-        return AVERROR(ENOMEM);
-
-    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-    return 0;
-}
-
-static av_cold int sonic_decode_close(AVCodecContext *avctx)
-{
-    SonicContext *s = avctx->priv_data;
-
-    av_freep(&s->int_samples);
-    av_freep(&s->tap_quant);
-    av_freep(&s->predictor_k);
-    av_freep(&s->predictor_state[0]);
-    av_freep(&s->coded_samples[0]);
-
-    return 0;
-}
-
-static int sonic_decode_frame(AVCodecContext *avctx, AVFrame *frame,
-                              int *got_frame_ptr, AVPacket *avpkt)
-{
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    SonicContext *s = avctx->priv_data;
-    RangeCoder c;
-    uint8_t state[32];
-    int i, quant, ch, j, ret;
-    int16_t *samples;
-
-    if (buf_size == 0) return 0;
-
-    frame->nb_samples = s->frame_size / avctx->ch_layout.nb_channels;
-    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
-        return ret;
-    samples = (int16_t *)frame->data[0];
-
-//    av_log(NULL, AV_LOG_INFO, "buf_size: %d\n", buf_size);
-
-    memset(state, 128, sizeof(state));
-    ff_init_range_decoder(&c, buf, buf_size);
-    ff_build_rac_states(&c, 0.05*(1LL<<32), 256-8);
-
-    intlist_read(&c, state, s->predictor_k, s->num_taps, 0);
-
-    // dequantize
-    for (i = 0; i < s->num_taps; i++)
-        s->predictor_k[i] *= (unsigned) s->tap_quant[i];
-
-    if (s->lossless)
-        quant = 1;
-    else
-        quant = get_symbol(&c, state, 0) * (unsigned)SAMPLE_FACTOR;
-
-//    av_log(NULL, AV_LOG_INFO, "quant: %d\n", quant);
-
-    for (ch = 0; ch < s->channels; ch++)
-    {
-        int x = ch;
-
-        if (c.overread > MAX_OVERREAD)
-            return AVERROR_INVALIDDATA;
-
-        predictor_init_state(s->predictor_k, s->predictor_state[ch], s->num_taps);
-
-        intlist_read(&c, state, s->coded_samples[ch], s->block_align, 1);
-
-        for (i = 0; i < s->block_align; i++)
-        {
-            for (j = 0; j < s->downsampling - 1; j++)
-            {
-                s->int_samples[x] = predictor_calc_error(s->predictor_k, s->predictor_state[ch], s->num_taps, 0);
-                x += s->channels;
-            }
-
-            s->int_samples[x] = predictor_calc_error(s->predictor_k, s->predictor_state[ch], s->num_taps, s->coded_samples[ch][i] * (unsigned)quant);
-            x += s->channels;
-        }
-
-        for (i = 0; i < s->num_taps; i++)
-            s->predictor_state[ch][i] = s->int_samples[s->frame_size - s->channels + ch - i*s->channels];
-    }
-
-    switch(s->decorrelation)
-    {
-        case MID_SIDE:
-            for (i = 0; i < s->frame_size; i += s->channels)
-            {
-                s->int_samples[i+1] += shift(s->int_samples[i], 1);
-                s->int_samples[i] -= s->int_samples[i+1];
-            }
-            break;
-        case LEFT_SIDE:
-            for (i = 0; i < s->frame_size; i += s->channels)
-                s->int_samples[i+1] += s->int_samples[i];
-            break;
-        case RIGHT_SIDE:
-            for (i = 0; i < s->frame_size; i += s->channels)
-                s->int_samples[i] += s->int_samples[i+1];
-            break;
-    }
-
-    if (!s->lossless)
-        for (i = 0; i < s->frame_size; i++)
-            s->int_samples[i] = shift(s->int_samples[i], SAMPLE_SHIFT);
-
-    // internal -> short
-    for (i = 0; i < s->frame_size; i++)
-        samples[i] = av_clip_int16(s->int_samples[i]);
-
-    *got_frame_ptr = 1;
-
-    return buf_size;
-}
-
-const FFCodec ff_sonic_decoder = {
-    .p.name         = "sonic",
-    CODEC_LONG_NAME("Sonic"),
-    .p.type         = AVMEDIA_TYPE_AUDIO,
-    .p.id           = AV_CODEC_ID_SONIC,
-    .priv_data_size = sizeof(SonicContext),
-    .init           = sonic_decode_init,
-    .close          = sonic_decode_close,
-    FF_CODEC_DECODE_CB(sonic_decode_frame),
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL | AV_CODEC_CAP_CHANNEL_CONF,
-    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
-};
-#endif /* CONFIG_SONIC_DECODER */
-
-#if CONFIG_SONIC_ENCODER
-const FFCodec ff_sonic_encoder = {
-    .p.name         = "sonic",
-    CODEC_LONG_NAME("Sonic"),
-    .p.type         = AVMEDIA_TYPE_AUDIO,
-    .p.id           = AV_CODEC_ID_SONIC,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL |
-                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
-    .priv_data_size = sizeof(SonicContext),
-    .init           = sonic_encode_init,
-    FF_CODEC_ENCODE_CB(sonic_encode_frame),
-    .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
-    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
-    .close          = sonic_encode_close,
-};
-#endif
-
-#if CONFIG_SONIC_LS_ENCODER
-const FFCodec ff_sonic_ls_encoder = {
-    .p.name         = "sonicls",
-    CODEC_LONG_NAME("Sonic lossless"),
-    .p.type         = AVMEDIA_TYPE_AUDIO,
-    .p.id           = AV_CODEC_ID_SONIC_LS,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL |
-                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
-    .priv_data_size = sizeof(SonicContext),
-    .init           = sonic_encode_init,
-    FF_CODEC_ENCODE_CB(sonic_encode_frame),
-    .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
-    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
-    .close          = sonic_encode_close,
-};
-#endif