1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00
Commit Graph

126 Commits

Author SHA1 Message Date
Rostislav Pehlivanov
27d23ae074 aacenc: add support for encoding files using Long Term Prediction
Long Term Prediction allows for prediction of spectral coefficients
via the previously decoded time-dependent samples. This feature
works well with harmonic content 2 or more frames long, like speech,
human or non-human, piano music or any constant tones at very low
bitrates.

It should be noted that the current coder is highly efficient and
the rate control system is unable to encode files at extremely
low bitrates (less than 14kbps seems to be impossible) so this
extension isn't capable of optimum operation. Dramatic difference
is observable with some types of audio and speech but for the most
part the audiable differences are subtle. The spectrum looks better
however so the encoder is able to harvest the additional bits that
this feature provies, should the user choose to enable it. So
it's best to enable this feature only if encoding at the absolutely
lowest bitrate that the encoder is capable of.
2015-10-17 02:31:20 +01:00
Rostislav Pehlivanov
93e6b23c9f aacenc: shorten name of ff_aac_adjust_common_prediction
To keep it similar to the other functions which are all named *_pred.
2015-10-12 23:33:07 +01:00
Claudio Freire
01ecb7172b AAC encoder: Extensive improvements
This finalizes merging of the work in the patches in ticket #2686.

Improvements to twoloop and RC logic are extensive.

The non-exhaustive list of twoloop improvments includes:
 - Tweaks to distortion limits on the RD optimization phase of twoloop
 - Deeper search in twoloop
 - PNS information marking to let twoloop decide when to use it
   (turned out having the decision made separately wasn't working)
 - Tonal band detection and priorization
 - Better band energy conservation rules
 - Strict hole avoidance

For rate control:
 - Use psymodel's bit allocation to allow proper use of the bit
   reservoir. Don't work against the bit reservoir by moving lambda
   in the opposite direction when psymodel decides to allocate more/less
   bits to a frame.
 - Retry the encode if the effective rate lies outside a reasonable
   margin of psymodel's allocation or the selected ABR.
 - Log average lambda at the end. Useful info for everyone, but especially
   for tuning of the various encoder constants that relate to lambda
   feedback.

Psy:
 - Do not apply lowpass with a FIR filter, instead just let the coder
   zero bands above the cutoff. The FIR filter induces group delay,
   and while zeroing bands causes ripple, it's lost in the quantization
   noise.
 - Experimental VBR bit allocation code
 - Tweak automatic lowpass filter threshold to maximize audio bandwidth
   at all bitrates while still providing acceptable, stable quality.

I/S:
 - Phase decision fixes. Unrelated to #2686, but the bugs only surfaced
   when the merge was finalized. Measure I/S band energy accounting for
   phase, and prevent I/S and M/S from being applied both.

PNS:
 - Avoid marking short bands with PNS when they're part of a window
   group in which there's a large variation of energy from one window
   to the next. PNS can't preserve those and the effect is extremely
   noticeable.

M/S:
 - Implement BMLD protection similar to the specified in
   ISO-IEC/13818:7-2003, Appendix C Section 6.1. Since M/S decision
   doesn't conform to section 6.1, a different method had to be
   implemented, but should provide equivalent protection.
 - Move the decision logic closer to the method specified in
   ISO-IEC/13818:7-2003, Appendix C Section 6.1. Specifically,
   make sure M/S needs less bits than dual stereo.
 - Don't apply M/S in bands that are using I/S

Now, this of course needed adjustments in the compare targets and
fuzz factors of the AAC encoder's fate tests, but if wondering why
the targets go up (more distortion), consider the previous coder
was using too many bits on LF content (far more than required by
psy), and thus those signals will now be more distorted, not less.

The extra distortion isn't audible though, I carried extensive
ABX testing to make sure.

A very similar patch was also extensively tested by Kamendo2 in
the context of #2686.
2015-10-11 17:29:50 -03:00
Claudio Freire
0f98fd30e2 AAC encoder: fix OOB access in search_for_pns
Fix out of bounds access caused by wrongful usage
of swb_offset constants when computing scalefactor
positions.
2015-09-26 04:49:16 -03:00
Claudio Freire
9458a62dec AAC encoder: tweak PNS usage to be more aggressive
This patch tweaks search_for_pns to be both more
aggressive and more careful when applying PNS. On
the one side, it will again try to use PNS on zero
(or effectively zero) bands. For this, both zeroes
and band_type have to be checked (some ZERO bands
aren't marked in zeroes). On the other side, a more
accurate rate-distortion measure avoids using PNS
where it would cause audible distortion.

Also fixed a small bug in the computation of freq
that caused PNS usage on low-frequency bands during
8-short windows. This allows re-enabling PNS during
8-short.
2015-09-25 03:56:32 -03:00
Claudio Freire
8df9bf8e39 AAC encoder: refactor to resynchronize MIPS port
This patch refactors the AAC coders to reuse code
between the MIPS port and the regular, portable C code.
There were two main functions that had to use
hand-optimized versions of quantization code:
 - search_for_quantizers_twoloop
 - codebook_trellis_rate

Those two were split into their own template header
files so they can be inlined inside both the MIPS port
and the generic code. In each context, they'll link
to their specialized implementations, and thus be
optimized by the compiler.

This approach I believe is better than maintaining
several copies of each function. As past experience has
proven, having to keep those in sync was error prone.
In this way, they will remain in sync by default.

Also, an implementation of the dequantized output
argument for the optimized quantize_and_encode
functions is included in the patch. While the current
implementation of search_for_pred still isn't using
it, future iterations of main prediction probably will.
It should not imply any measurable performance hit while
not being used.
2015-09-16 23:14:26 -03:00
Rostislav Pehlivanov
8180b113e1 aaccoder: respect cutoff when marking bands as PNS
Makes more sense as users usually set the -cutoff option
to low pass filter the signal. The encoder will still over
shoot slightly when encoding normal coefficients however
that's normal.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-09-11 18:59:15 +01:00
Rostislav Pehlivanov
da64bd6a99 aaccoder: tweak PNS implementation further
This commit changes a few things about the noise substitution
logic:
 - Brings back the quantization factor (reduced to 3) during
   scalefactor index calculations.
 - Rejects any zeroed bands. They should be inaudiable and it's
   a waste transmitting the scalefactor indices for these.
 - Uses swb_offsets instead of incrementing a 'start' with every
   window group size.
 - Rejects all PNS during short windows.
Overall improves quality. There was a plan to use the lfg system
to create the random numbers instead of using whatever the decoder
uses but for now this works fine. Entropy is far from important here.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-09-09 10:44:33 +01:00
Rostislav Pehlivanov
b6cc8ec7ec aaccoder: add frequency scaling and quantization correction for PNS
This commit once again improves the PNS implementation by scaling the
thresholds with frequency. The thresholds get looser as the frequency
increases since higher frequencies are basically noise to human ears.

Also, this introduces quantization error correction for PNS. Should
the error be too much, no PNS will be used. The energy_ratio is used
to regulate the actual encoded PNS energy: if the generated PNS
energy is higher than the energy from the psy system, energy_ratio
is used to correct it so that hopefully once requantized and
transmitted the value in the decoder will be closer to what the
encoder has.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-09-07 12:44:09 +01:00
Rostislav Pehlivanov
033e58941e aaccoder: rewrite PNS implementation
This commit rewrites the PNS implementation and significantly
improves sonic quality.

The previous implementation marked an incredibly big amount
of SFBs to predict when there was no need for this and this
resulted in quite a large amount of artifacts. Also the
quantization was incorrect (av_clip(4+log2f(...))) which
led to 3x the intensity for PNS values leading to even more
artifacts.

This commit rewrites the PNS search function and introduces
a major change: the PNS values are synthesized and are compared
to the current coefficients in addition to passing through
the revised checks to see whether PNS can be used.

This decreases distortions and makes the current PNS implementation
mainly focused on replacing any low-power non-zero bands as well
as adding any zeroed bands back.

The current encoder's performance is enough (especially with
IS) so PNS isn't really required except to fill in the occasional
few bands as well as extend any zeroed high frequency, so this
combination which is already enabled by default works
to get as much quality as it can within the bits allowed.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-09-06 15:30:26 +01:00
Rostislav Pehlivanov
b9b1fd1183 aaccoder: use roundf() instead of ceilf()
The specifications explicitly state to use roundf() which
also rounds half-integer values away from zero.
This does fix a few IS artifacts.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-09-06 15:30:26 +01:00
Rostislav Pehlivanov
f20b67173c aacenc_tns: rework the way coefficients are calculated
This commit abandons the way the specifications state to
quantize the coefficients, makes use of the new LPC float
functions and is much better.

The original way of converting non-normalized float samples
to int32_t which out LPC system expects was wrong and it was
wrong to assume the coefficients that are generated are also
valid. It was essentially a full garbage-in, garbage-out
system and it definitely shows when looking at spectrals
and listening. The high frequencies were very overattenuated.
The new LPC function performs the analysis directly.

The specifications state to quantize the coefficients into
four bit index values using an asin() function which of course
had to have ugly ternary operators because the function turns
negative if the coefficients are negative which when encoding
causes invalid bitstream to get generated.

This deviates from this by using the direct TNS tables, which
are fairly small since you only have 4 bits at most for index
values. The LPC values are directly quantized against the tables
and are then used to perform filtering after the requantization,
which simply fetches the array values.

The end result is that TNS works much better now and doesn't
attenuate anything but the actual signal, e.g. TNS removes
quantization errors and does it's job correctly now.

It might be enabled by default soon since it doesn't hurt and
helps reduce nastyness at low bitrates.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-08-29 06:47:31 +01:00
Rostislav Pehlivanov
44ddee945a aacenc_pred: rework the way prediction is done
This commit completely alters the algorithm of prediction.
The original commit which introduced prediction was completely
incorrect to even remotely care about what the actual coefficients
contain or whether any options were enabled. Not my actual fault.

This commit treats prediction the way the decoder does and expects
to do: like lossy encryption. Everything related to prediction now
happens at the very end but just before quantization and encoding
of coefficients. On the decoder side, prediction happens before
anything has had a chance to even access the coefficients.

Also the original implementation had problems because it actually
touched the band_type of special bands which already had their
scalefactor indices marked and it's a wonder the asserion wasn't
triggered when transmitting those.

Overall, this now drastically increases audio quality and you should
think about enabling it if you don't plan on playing anything encoded
on really old low power ultra-embedded devices since they might not
support decoding of prediction or AAC-Main. Though the specifications
were written ages ago and as times change so do the FLOPS.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-08-29 06:34:08 +01:00
Timothy Gu
21dd5279c3 aacenc: Add missing ff_ prefixes
Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
Reviewed-by: Ganesh Ajjanagadde <gajjanag@mit.edu>
2015-08-22 06:11:23 +01:00
Rostislav Pehlivanov
76b81b10d9 aacenc: implement the complete AAC-Main profile
This commit finalizes AAC-Main profile encoding support
by implementing all mandatory and optional tools available
in the specifications and current decoders.

The AAC-Main profile reqires that prediction support be
present (although decoders don't require it to be enabled)
for an encoder to be deemed capable of AAC-Main encoding,
as well as TNS, PNS and IS, all of which were implemented
with previous commits or earlier of this year.

Users are encouraged to test the new functionality using either
-profile:a aac_main or -aac_pred 1, the former of which will enable
the prediction option by default and the latter will change the
profile to AAC-Main. No other options shall be changed by enabling
either, it's currently up to the users to decide what's best.

The current implementation works best using M/S and/or IS,
so users are also welcome to enable both options and any
other options (TNS, PNS) for maximum quality.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-08-21 19:38:05 +01:00
Rostislav Pehlivanov
a1c487e921 aacenc_tns: implement temporal noise shaping
This commit implements temporal noise shaping support in the
encoder, along with an -aac_tns option to toggle it on or off
(off by default for now). TNS will increase audio quality
and reduce quantization noise by applying a multitap FIR filter
across allowed coefficients and transmit side information to the
decoder so it could create an inverse filter.

Users are encouraged to test the new functionality by enabling
-aac_tns 1 during encoding.

No major bugs are observable at this time so after a while if no
new problems appear and if the current implementation is deemed
of high enough quality and stability it will be enabled by default,
possibly at the same time the encoder has its experimental flag
removed and becomes the standard aac encoder in ffmpeg.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-08-21 19:27:38 +01:00
Rostislav Pehlivanov
d1ca7142ac aaccoder: move the Intensity Stereo implementation out
This commit moves the intensity stereo implementation
out from aaccoder and into a separate file. This was
possible using the previous commits.

This commit also drastically improves the IS implementation
by making it phase invariant e.g. it will always choose the
best possible phase regardless of whether M/S coding is on
or most of the coefficients have identical phases.
This also increases the quality and reduces any distortions
introduced by enablind intensity stereo.

Users are encouraged to test it out using the -aac_is 1
parameter as it has always been.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-08-21 19:13:26 +01:00
Rostislav Pehlivanov
43b378a0d3 aaccoder: move the quantization functions to a separate file
This commit moves the quantizer to a separate header file.
This allows the quantizer to be used from a separate files outside
of aaccoder without having to put another function pointer and will
result in a slight speedup as the compiler can do more optimizations.

This is required for commits following.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-08-21 18:53:14 +01:00
Rostislav Pehlivanov
e6c9f3a166 aacenc: reset special bands in the main frame encoding function
This commit moves the resetting of special bands (above RESERVED_BT)
to the main frame encoding function rather than the way it was done
previously in their corresponding search_for_... functions.

The reason why special bands need to be reset is that while normal
bands get chosen for every frame by the coder (twoloop by default)
the coders do not touch any special sfbs and will therefore
make them persist throughout the file.

If we zero them out any bands left unmarked will be chosen by
the second part of the coder (the trellis function in aaccoder.c).

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-08-21 18:36:09 +01:00
Rostislav Pehlivanov
32be264cea aacenc: coding style changes
This commit only changes the coding style to a saner way
of accessing coefficients (makes more sense to get the
memory address of a coefficients and start from there
rather than adding arbitrary numbers to offset a pointer).
Some compilers might detect an out of bounds access easier.

Also the way M/S and IS coefficients are calculated has been
changed, but should still have the same result (with the exception
that IS now applies from the normal coefficients rather than the
pristine ones, this is needed for upcoming commits).

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2015-08-21 18:30:51 +01:00
Rostislav Pehlivanov
ef8e5a61c8 aacenc: Move small misc. functions to a separate file
As well as tables littered everywhere, functions were spread
out all across the encoder's files. This moves them to a single
place where they can be used by either the encoder's main files
or additional encoder files. Additionally, it changes the type
of some to 'inline' to enable us to simply put them in a header
file and possibly gain some speed due to compiler optimizations.

Signed-off-by: Claudio Freire <klaussfreire@gmail.com>
2015-08-11 00:22:05 -03:00
Rostislav Pehlivanov
c47c781e83 aacenc: Move local encoder specific tables to a separate file
This commit moves any tables specific to the encoder from aacenc
and aaccoder to a separate file called 'aacenctab.c/.h'.
This was done as a clean up attempt as the encoder was filled with
tables pasted in between functions which made it confusing to follow
and track where each table and definition had been used.
This commit solves this by simply exporting the smaller tables out to
the aacenctab.h while the larger ones are compiled using aacenctab.c
and are referenced from the header file.

Signed-off-by: Claudio Freire <klaussfreire@gmail.com>
2015-08-07 03:58:07 -03:00
Rostislav Pehlivanov
6d175158e9 aacenc: remove redundant argument from coder functions
This commit removes a redundant argument from the functions in aaccoder.
The argument lambda was redundant as it was just a copy of s->lambda,
to which all functions have access to anyway. This cleans up the function
pointers a bit which is helpful as there are a lot of other search_for_*
functions under development and with them populated it gets messy.

Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2015-08-01 02:54:35 +02:00
Claudio Freire
59216e0525 AAC Encoder: clipping avoidance
Avoid clipping due to quantization noise to produce audible
artifacts, by detecting near-clipping signals and both attenuating
them a little and encoding escape-encoded bands (usually the
loudest) rounding towards zero instead of nearest, which tends to
decrease overall energy and thus clipping.

Currently fate tests measure numerical error so this change makes
tests using asynth (which are near clipping) report higher error
not less, because of window attenuation. Yet, they sound better,
not worse (albeit subtle, other samples aren't subtle at all).
Only measuring psychoacoustically weighted error would make for
a representative test, so that will be left for a future patch.

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2015-07-27 19:13:48 +02:00
Rostislav Pehlivanov
331c1e7494 aacenc: move the generation of ff_aac_pow34sf_tab[]
This commit moves the generation of ff_aac_pow34sf_tab[] out of the
encoder and into the table generator. The original commit log for
this table in 2011 actually mentions that it should be moved outside
but this never happened.

This is the first commit which cleans up the encoder a little.

Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2015-07-21 13:53:04 +02:00
Rostislav Pehlivanov
e8576dc8df aacenc: implement Intensity Stereo encoding support
This commit implements intensity stereo coding support
to the native aac encoder. This is a way to increase the efficiency
of the encoder by zeroing the right channel's spectral coefficients
(in a channel pair) and rederiving them in the decoder using information
from the scalefactor indices of special band types. This commit
confomrs to the official ISO 13818-7 specifications, although due to
their ambiguity certain deviations have been taken to ensure maximum
sound quality. This commit has been extensively tested and has shown
to not result in audiable audio artifacts unless in extreme cases.
This commit also adds an option, aac_is, which has the value of
0 by default. Intensity Stereo is part of the scalable aac profile
and is thus non-default.

The way IS coding works is that it rederives the right channel's
spectral coefficients from the left channel via the scalefactor
index values left in the right channel. Since an entire band's
spectral coefficients do not need to be coded, the encoder's
efficiency jumps up and it unzeroes some high frequency values
which it previously did not have enough bits to encode. That way
less information is lost than the information lost by rederiving
the spectral coefficients with some error. This is why the
filesize of files encoded with IS do not decrease significantly.
Users wishing that IS coding should reduce filesize are expected
to reduce their encoding bitrates appropriately.

This is V2 of the commit. The old version did not mark ms_mask as
0 since M/S and IS coding are incompactible, which resulted in
distortions with M/S coding enabled. This version also improves
phase detection by measuring it for every spectral coefficient in
the band and using a simple majority rule to determine whether the
coefficients are in or out of phase. Also, the energy values per
spectral coefficient were changed as to reflect the
official specifications.

Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-07-05 16:59:26 +02:00
Rostislav Pehlivanov
38fd4c2e66 aaccoder: add a new perceptual noise substitution implementation
This commit finalizes the PNS implementation previously added to the encoder
by moving it to a seperate function search_for_pns() and thus making it
coder-generic. This new implementation makes use of the spread field of
the psy bands and the lambda quality feedback paremeter. The spread of the
spectrum in a band prevents PNS from being used excessively and thus preserve
more phase information in high frequencies.  The lambda parameter allows
the number of PNS-marked bands to vary based on the lambda parameter and the
amount of bits available, making better choices on which bands are to be marked
as noise. Comparisons with the previous PNS implementation can be found
here: https://trac.ffmpeg.org/attachment/wiki/Encode/AAC/

This is V2 of the patch, the changes from the previous version being that this
version uses the new band->spread metric from aacpsy and normalizes the
energy using the group size. These changes were suggested by Claudio Freire
on the mailing list. Another change is the use of lambda to alter the
frequency threshold. This change makes the actual threshold frequencies
vary between +-2Khz of what's specified, depending on frame encoding performance.

Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-07-05 16:39:06 +02:00
Rostislav Pehlivanov
117b15f4a8 aaccoder: remove previous PNS implementation from twoloop
This commit undoes commit c5d4f87e81
and removes PNS band marking from the twoloop coder, which has
been reimplemented in a better way in this series of patches.

Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-07-05 16:38:32 +02:00
Rostislav Pehlivanov
e06578e392 aacenc: use the new function for setting special band scalefactor indices
This commit enables the function added with commit 7c10b87 and uses that
new function for setting any special scalefactor indices. This commit does
not change the behaviour of the encoder since no bands are being marked as
either NOISE_BT(due to the previous PNS implementation removed in the
previous commit) or INTENSITY_BT2/INTENSITY_BT.

Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-07-05 16:36:38 +02:00
Rostislav Pehlivanov
57848ef3c6 aaccoder: fix M/S coding
There were some mistakes in the code for M/S stereo, this commit fixes them.
The start variable was not being reset for every window and every access to
the coefficients was incorrect as well. This fixes that by properly
addressing the coefficients using both windows and setting the start on every window to zero.

Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-07-03 13:27:25 +02:00
Rostislav Pehlivanov
7c10b87b57 aacenc: add support for coding of intensity stereo scalefactor indices
This commit adds support for the coding of intensity stereo scalefactor indices.
It does not do any marking of such bands and as such does no functional changes
to the encoder. It removes any old twoloop specific code for PNS and moves it
into a seperate function which handles setting of scalefactor indices for
PNS and IS bands.

Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-06-29 16:44:40 +02:00
Rostislav Pehlivanov
55397b0e76 aaccoder: add intensity stereo support to encode_window_bands_info quantizer
This commit adds support for both PNS and IS (intensity stereo) codebooks to the
encode_window_bands_info() quantizer, used by the faast, faac and anmr non-default,
native coders. This does not mean that both extensions now work with those coders,
some are simply unsuited and will trigger an assertion in the encoder while
others simply ignore the changed scalefactor indices and band types.
This commit simply adds support for encoding said band types with the alternative
coders. Future commits to the coders will be required to make them suitable.

Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-06-28 21:15:58 +02:00
Rostislav Pehlivanov
305859c0d4 aaccoder: add intensity stereo coding support for the trellis quantizer
This commit extends the trellis quantizer (used by the default twoloop coder)
 to accept and correctly encode codebooks needed for intensity stereo and perceptual noise substitution.

Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-06-28 21:15:40 +02:00
James Almer
6863249b34 aaccoder: use put_sbits()
Reviewed-by: Michael Niedermayer <michaelni@gmx.at>
Signed-off-by: James Almer <jamrial@gmail.com>
2015-04-18 14:13:59 -03:00
Rostislav Pehlivanov
c5d4f87e81 aaccoder: Implement Perceptual Noise Substitution for AAC
This commit implements the perceptual noise substitution AAC extension. This is a proof of concept
implementation, and as such, is not enabled by default. This is the fourth revision of this patch,
made after some problems were noted out. Any changes made since the previous revisions have been indicated.

In order to extend the encoder to use an additional codebook, the array holding each codebook has been
modified with two additional entries - 13 for the NOISE_BT codebook and 12 which has a placeholder function.
The cost system was modified to skip the 12th entry using an array to map the input and outputs it has. It
also does not accept using the 13th codebook for any band which is not marked as containing noise, thereby
restricting its ability to arbitrarily choose it for bands. The use of arrays allows the system to be easily
extended to allow for intensity stereo encoding, which uses additional codebooks.

The 12th entry in the codebook function array points to a function which stops the execution of the program
by calling an assert with an always 'false' argument. It was pointed out in an email discussion with
Claudio Freire that having a 'NULL' entry can result in unexpected behaviour and could be used as
a security hole. There is no danger of this function being called during encoding due to the codebook maps introduced.

Another change from version 1 of the patch is the addition of an argument to the encoder, '-aac_pns' to
enable and disable the PNS. This currently defaults to disable the PNS, as it is experimental.
The switch will be removed in the future, when the algorithm to select noise bands has been improved.
The current algorithm simply compares the energy to the threshold (multiplied by a constant) to determine
noise, however the FFPsyBand structure contains other useful figures to determine which bands carry noise more accurately.

Some of the sample files provided triggered an assertion when the parameter to tune the threshold was set to
a value of '2.2'. Claudio Freire reported the problem's source could be in the range of the scalefactor
indices for noise and advised to measure the minimal index and clip anything above the maximum allowed
value. This has been implemented and all the files which used to trigger the asserion now encode without error.

The third revision of the problem also removes unneded variabes and comparisons. All of them were
redundant and were of little use for when the PNS implementation would be extended.

The fourth revision moved the clipping of the noise scalefactors outside the second loop of the two-loop
algorithm in order to prevent their redundant calculations. Also, freq_mult has been changed to a float
variable due to the fact that rounding errors can prove to be a problem at low frequencies.
Considerations were taken whether the entire expression could be evaluated inside the expression
, but in the end it was decided that it would be for the best if just the type of the variable were
to change. Claudio Freire reported the two problems. There is no change of functionality
(except for low sampling frequencies) so the spectral demonstrations at the end of this commit's message were not updated.

Finally, the way energy values are converted to scalefactor indices has changed since the first commit,
as per the suggestion of Claudio Freire. This may still have some drawbacks, but unlike the first commit
it works without having redundant offsets and outputs what the decoder expects to have, in terms of the
ranges of the scalefactor indices.

Some spectral comparisons: https://trac.ffmpeg.org/attachment/wiki/Encode/AAC/Original.png (original),
https://trac.ffmpeg.org/attachment/wiki/Encode/AAC/PNS_NO.png (encoded without PNS),
https://trac.ffmpeg.org/attachment/wiki/Encode/AAC/PNS1.2.png (encoded with PNS, const = 1.2),
https://trac.ffmpeg.org/attachment/wiki/Encode/AAC/Difference1.png (spectral difference).
The constant is the value which multiplies the threshold when it gets compared to the energy, larger
values means more noise will be substituded by PNS values. Example when const = 2.2:
https://trac.ffmpeg.org/attachment/wiki/Encode/AAC/PNS_2.2.png

Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-15 19:59:44 +02:00
Claudio Freire
6394acaf36 AAC: Fix M/S stereo encoding
This patch fixes a pointer arithmetic bug in adjust_frame_information that resulted in heavily corrupted audio when using M/S encoding. Also, a backup copy of untransformed coefficients has to be kept around or attempts at re-processing the frame (which happens when hevavily overspending bits during transients) will result in re-encoding of the coefficients and subsequent corruption of the resulting stream.

A/B testing shows the bug as corrected, but still cannot prove that M/S coding is a win at least in numbers. Limited listening tests do show improvement on M/S encoded samples in lower bitrates, but they're hidden among the other artifacts that remain to be corrected in the encoder.

Some of the regressions flagged in the report do show poor stereo image (but not buggy), so M/S encoding is clearly not good enough yet to be defaulted to auto.

In numbers, Patched against Unpatched, stereo_mode auto:

  Files: 114
  Bitrates: 6
  Tests: 683

  Serious Regressions: 0 (0%)
  Regressions: 0 (0%)
  Improvements: 227 (33%)
  Big improvements: 92 (13%)
  Worst regression - mybloodrusts.wv - 256k
    - StdDev: 28.61       pSNR: -0.43     maxdiff: 1372.00
  Best improvement - 60.wv - 384k
    - StdDev: -369.57     pSNR: 45.02     maxdiff: -13322.00
  Average          - StdDev: -80.56       pSNR: 2.49      maxdiff: -8858.00

Patched against Unpatched stereo_mode ms_off shows no difference.

Patched stereo_mode auto vs Unpatched stereo_mode ms_off shows a small average improvement, just not too significant:

  Serious Regressions: 0 (0%)
  Regressions: 10 (1%)
  Improvements: 45 (6%)
  Big improvements: 2 (0%)
  Worst regression - Illinois.wv - 256k
    - StdDev: 33.20       pSNR: -2.03     maxdiff: 477.00
  Best improvement - song_of_circomstances.flac - 384k
    - StdDev: -3.97       pSNR: 7.61      maxdiff: -826.00
  Average          - StdDev: -10.25       pSNR: 0.20      maxdiff: -281.00

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-03 13:57:42 +01:00
Michael Niedermayer
66d79aa2e1 Merge commit '9abc80f1ed673141326341e26a05c3e1f78576d0'
* commit '9abc80f1ed673141326341e26a05c3e1f78576d0':
  libavcodec: Make use of av_clip functions

Conflicts:
	libavcodec/takdec.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
2015-02-21 11:27:24 +01:00
Peter Meerwald
9abc80f1ed libavcodec: Make use of av_clip functions
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
2015-02-21 00:54:40 +01:00
Reimar Döffinger
d9e2aceb7f Add missing "const" all over the place.
Only "./configure --enable-gpl" on x86 was tested.

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
2014-08-29 18:57:25 +02:00
Timothy Gu
1b03448385 aaccoder: remove unused assignment
Signed-off-by: Timothy Gu <timothygu99@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2014-07-16 20:55:24 +02:00
Timothy Gu
4bd910d83d aacenc: add AAC_CODER_(FAAC|ANMR|etc.) macros
Signed-off-by: Timothy Gu <timothygu99@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2013-09-12 17:22:36 +02:00
Claudio Freire
f4d0a63b5b aacenc: Fix target bitrate for twoloop quantiser search
This fixes a case where multichannel bitrate isn't accurately
targetted by psy model alone, never achieving the target bitrate.

Signed-off-by: Martin Storsjö <martin@martin.st>
2013-05-14 12:42:04 +03:00
Claudio Freire
1ef82cc60d AAC encoder: Fix rate control on twoloop.
Fixes a case where multichannel bitrate isn't accurately
targetted by psy model alone, never achieving the target bitrate.
Now fixed.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2013-05-05 04:19:34 +02:00
Michael Niedermayer
31ab1575e5 Merge remote-tracking branch 'qatar/master'
* qatar/master:
  avcodec: Convert some commented-out printf/av_log instances to av_dlog
  avcodec: Drop silly and/or broken printf debug output
  avcodec: Drop some silly commented-out av_log() invocations
  avformat: Convert some commented-out printf/av_log instances to av_dlog
  avformat: Remove non-compiling and/or silly commented-out printf/av_log statements
  Remove some silly disabled code.
  ac3dec: ensure get_buffer() gets a buffer for the correct number of channels

Conflicts:
	libavcodec/dnxhddec.c
	libavcodec/ffv1.c
	libavcodec/h264.c
	libavcodec/h264_parser.c
	libavcodec/mjpegdec.c
	libavcodec/motion_est_template.c
	libavcodec/mpegaudiodec.c
	libavcodec/mpegvideo_enc.c
	libavcodec/put_bits.h
	libavcodec/ratecontrol.c
	libavcodec/wmaenc.c
	libavdevice/timefilter.c
	libavformat/asfdec.c
	libavformat/avidec.c
	libavformat/avienc.c
	libavformat/flvenc.c
	libavformat/utils.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
2012-10-01 16:12:38 +02:00
Diego Biurrun
6f6b0311a3 avcodec: Drop some silly commented-out av_log() invocations 2012-10-01 10:24:28 +02:00
Michael Niedermayer
688cb71252 aaccoder: switch to av_assert
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2012-09-04 04:38:28 +02:00
Michael Niedermayer
33775c3507 search_for_quantizers_faac: fix curband
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2012-06-06 18:35:05 +02:00
Reimar Döffinger
0f96f0d996 aacenc: Fix issues with huge values of bit_rate.
Do not pointlessly call ff_alloc_packet multiple times,
and fix an infinite loop by clamping the maximum
number of bits to target in the algorithm that does
not use lambda.

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
2012-04-17 10:25:28 -04:00
Reimar Döffinger
ecd7455e96 aacenc: Fix issues with huge values of bit_rate.
Do not pointlessly call ff_alloc_packet2 multiple times,
and fix an infinite loop by clamping the maximum
number of bits to target in the algorithm that does
not use lambda.

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
2012-04-07 11:48:20 +02:00
Michael Niedermayer
d40ff29cac Merge remote-tracking branch 'qatar/master'
* qatar/master:
  asf: only set index_read if the index contained entries.
  cabac: add overread protection to BRANCHLESS_GET_CABAC().
  cabac: increment jump locations by one in callers of BRANCHLESS_GET_CABAC().
  cabac: remove unused argument from BRANCHLESS_GET_CABAC_UPDATE().
  cabac: use struct+offset instead of memory operand in BRANCHLESS_GET_CABAC().
  h264: add overread protection to get_cabac_bypass_sign_x86().
  h264: reindent get_cabac_bypass_sign_x86().
  h264: use struct offsets in get_cabac_bypass_sign_x86().
  h264: fix overreads in cabac reader.
  wmall: fix seeking.
  lagarith: fix buffer overreads.
  dvdec: drop unnecessary dv_tablegen.h #include
  build: fix doc generation errors in parallel builds
  Replace memset(0) by zero initializations.
  faandct: Remove FAAN_POSTSCALE define and related code.
  dvenc: print allowed profiles if the video doesn't conform to any of them.
  avcodec_encode_{audio,video}: only reallocate output packet when it has non-zero size.
  FATE: add a test for vp8 with changing frame size.
  fate: add kgv1 fate test.
  oggdec: calculate correct timestamps in Ogg/FLAC

Conflicts:
	libavcodec/4xm.c
	libavcodec/cook.c
	libavcodec/dvdata.c
	libavcodec/dvdsubdec.c
	libavcodec/lagarith.c
	libavcodec/lagarithrac.c
	libavcodec/utils.c
	tests/fate/video.mak

Merged-by: Michael Niedermayer <michaelni@gmx.at>
2012-03-29 04:11:10 +02:00