📄 hcr.c
字号:
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2004 G.C. Pascutto, Ahead Software AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program 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 General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
** $Id: hcr.c,v 1.18 2004/09/04 14:56:28 menno Exp $
**/
#include "common.h"
#include "structs.h"
#include <stdlib.h>
#include <string.h>
#include "specrec.h"
#include "huffman.h"
/* ISO/IEC 14496-3/Amd.1
* 8.5.3.3: Huffman Codeword Reordering for AAC spectral data (HCR)
*
* HCR devides the spectral data in known fixed size segments, and
* sorts it by the importance of the data. The importance is firstly
* the (lower) position in the spectrum, and secondly the largest
* value in the used codebook.
* The most important data is written at the start of each segment
* (at known positions), the remaining data is interleaved inbetween,
* with the writing direction alternating.
* Data length is not increased.
*/
#ifdef ERROR_RESILIENCE
/* 8.5.3.3.1 Pre-sorting */
#define NUM_CB 6
#define NUM_CB_ER 22
#define MAX_CB 32
#define VCB11_FIRST 16
#define VCB11_LAST 31
static const uint8_t PreSortCB_STD[NUM_CB] =
{ 11, 9, 7, 5, 3, 1};
static const uint8_t PreSortCB_ER[NUM_CB_ER] =
{ 11, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 9, 7, 5, 3, 1};
/* 8.5.3.3.2 Derivation of segment width */
static const uint8_t maxCwLen[MAX_CB] = {0, 11, 9, 20, 16, 13, 11, 14, 12, 17, 14, 49,
0, 0, 0, 0, 14, 17, 21, 21, 25, 25, 29, 29, 29, 29, 33, 33, 33, 37, 37, 41};
#define segmentWidth(cb) min(maxCwLen[cb], ics->length_of_longest_codeword)
/* bit-twiddling helpers */
static const uint8_t S[] = {1, 2, 4, 8, 16};
static const uint32_t B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF};
typedef struct
{
uint8_t cb;
uint8_t decoded;
uint16_t sp_offset;
bits_t bits;
} codeword_t;
/* rewind and reverse */
/* 32 bit version */
static uint32_t rewrev_word(uint32_t v, const uint8_t len)
{
/* 32 bit reverse */
v = ((v >> S[0]) & B[0]) | ((v << S[0]) & ~B[0]);
v = ((v >> S[1]) & B[1]) | ((v << S[1]) & ~B[1]);
v = ((v >> S[2]) & B[2]) | ((v << S[2]) & ~B[2]);
v = ((v >> S[3]) & B[3]) | ((v << S[3]) & ~B[3]);
v = ((v >> S[4]) & B[4]) | ((v << S[4]) & ~B[4]);
/* shift off low bits */
v >>= (32 - len);
return v;
}
/* 64 bit version */
static void rewrev_lword(uint32_t *hi, uint32_t *lo, const uint8_t len)
{
if (len <= 32) {
*hi = 0;
*lo = rewrev_word(*lo, len);
} else
{
uint32_t t = *hi, v = *lo;
/* double 32 bit reverse */
v = ((v >> S[0]) & B[0]) | ((v << S[0]) & ~B[0]);
t = ((t >> S[0]) & B[0]) | ((t << S[0]) & ~B[0]);
v = ((v >> S[1]) & B[1]) | ((v << S[1]) & ~B[1]);
t = ((t >> S[1]) & B[1]) | ((t << S[1]) & ~B[1]);
v = ((v >> S[2]) & B[2]) | ((v << S[2]) & ~B[2]);
t = ((t >> S[2]) & B[2]) | ((t << S[2]) & ~B[2]);
v = ((v >> S[3]) & B[3]) | ((v << S[3]) & ~B[3]);
t = ((t >> S[3]) & B[3]) | ((t << S[3]) & ~B[3]);
v = ((v >> S[4]) & B[4]) | ((v << S[4]) & ~B[4]);
t = ((t >> S[4]) & B[4]) | ((t << S[4]) & ~B[4]);
/* last 32<>32 bit swap is implicit below */
/* shift off low bits (this is really only one 64 bit shift) */
*lo = (t >> (64 - len)) | (v << (len - 32));
*hi = v >> (64 - len);
}
}
/* bits_t version */
static void rewrev_bits(bits_t *bits)
{
if (bits->len == 0) return;
rewrev_lword(&bits->bufb, &bits->bufa, bits->len);
}
/* merge bits of a to b */
static void concat_bits(bits_t *b, bits_t *a)
{
uint32_t bl, bh, al, ah;
if (a->len == 0) return;
al = a->bufa;
ah = a->bufb;
if (b->len > 32)
{
/* maskoff superfluous high b bits */
bl = b->bufa;
bh = b->bufb & ((1 << (b->len-32)) - 1);
/* left shift a b->len bits */
ah = al << (b->len - 32);
al = 0;
} else {
bl = b->bufa & ((1 << (b->len)) - 1);
bh = 0;
ah = (ah << (b->len)) | (al >> (32 - b->len));
al = al << b->len;
}
/* merge */
b->bufa = bl | al;
b->bufb = bh | ah;
b->len += a->len;
}
uint8_t is_good_cb(uint8_t this_CB, uint8_t this_sec_CB)
{
/* only want spectral data CB's */
if ((this_sec_CB > ZERO_HCB && this_sec_CB <= ESC_HCB) || (this_sec_CB >= VCB11_FIRST && this_sec_CB <= VCB11_LAST))
{
if (this_CB < ESC_HCB)
{
/* normal codebook pairs */
return ((this_sec_CB == this_CB) || (this_sec_CB == this_CB + 1));
} else
{
/* escape codebook */
return (this_sec_CB == this_CB);
}
}
return 0;
}
void read_segment(bits_t *segment, uint8_t segwidth, bitfile *ld)
{
segment->len = segwidth;
if (segwidth > 32)
{
segment->bufb = faad_getbits(ld, segwidth - 32);
segment->bufa = faad_getbits(ld, 32);
} else {
segment->bufa = faad_getbits(ld, segwidth);
segment->bufb = 0;
}
}
void fill_in_codeword(codeword_t *codeword, uint16_t index, uint16_t sp, uint8_t cb)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -