⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hcr.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
** 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 + -