summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorRostislav Pehlivanov <atomnuker@gmail.com>2015-04-12 05:50:34 +0100
committerMichael Niedermayer <michaelni@gmx.at>2015-04-13 04:14:27 +0200
commitf7f71b5795d708763eb0c55fe5e2cb051b2b69f4 (patch)
tree8df18b1a8d27c0b8ef6cf1256d153caf705733f3 /libavcodec
parentc919cc61a155c45147913841003f742e0a53ac0d (diff)
aacenc: Add support for Perceptual Noise Substitution energy values
This commit implements support for writing the noise energy values used in PNS. The difference between regular scalefactors and noise energy values is that the latter require a small preamble (NOISE_PRE + energy_value_diff) to be written as the first noise-containing band. Any following noise energy values use the previous one to base their "diff" on. Ordinary scalefactors remain unchanged other than that they ignore the noise values. This commit should not change anything by itself, the following commits will bring it in use. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/aac.h3
-rw-r--r--libavcodec/aacenc.c17
2 files changed, 17 insertions, 3 deletions
diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index b25b40c9c6..2701386376 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -141,6 +141,9 @@ typedef struct PredictorState {
#define SCALE_MAX_DIFF 60 ///< maximum scalefactor difference allowed by standard
#define SCALE_DIFF_ZERO 60 ///< codebook index corresponding to zero scalefactor indices difference
+#define NOISE_PRE 256 ///< preamble for NOISE_BT, put in bitstream with the first noise band
+#define NOISE_PRE_BITS 9 ///< length of preamble
+
/**
* Long Term Prediction
*/
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 7015a2789c..5288afb4a2 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -388,15 +388,26 @@ static void encode_band_info(AACEncContext *s, SingleChannelElement *sce)
static void encode_scale_factors(AVCodecContext *avctx, AACEncContext *s,
SingleChannelElement *sce)
{
- int off = sce->sf_idx[0], diff;
+ int diff, off_sf = sce->sf_idx[0], off_pns = sce->sf_idx[0];
+ int noise_flag = 1;
int i, w;
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
for (i = 0; i < sce->ics.max_sfb; i++) {
if (!sce->zeroes[w*16 + i]) {
- diff = sce->sf_idx[w*16 + i] - off + SCALE_DIFF_ZERO;
+ if (sce->band_type[w*16 + i] == NOISE_BT) {
+ diff = sce->sf_idx[w*16 + i] - off_pns;
+ off_pns = sce->sf_idx[w*16 + i];
+ if (noise_flag-- > 0) {
+ put_bits(&s->pb, NOISE_PRE_BITS, diff + NOISE_PRE);
+ continue;
+ }
+ } else {
+ diff = sce->sf_idx[w*16 + i] - off_sf;
+ off_sf = sce->sf_idx[w*16 + i];
+ }
+ diff += SCALE_DIFF_ZERO;
av_assert0(diff >= 0 && diff <= 120);
- off = sce->sf_idx[w*16 + i];
put_bits(&s->pb, ff_aac_scalefactor_bits[diff], ff_aac_scalefactor_code[diff]);
}
}