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

📄 mp3internalshuffman.cpp

📁 流媒体传输协议的实现代码,非常有用.可以支持rtsp mms等流媒体传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**********This library is free software; you can redistribute it and/or modify it underthe terms of the GNU Lesser General Public License as published by theFree Software Foundation; either version 2.1 of the License, or (at youroption) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)This library is distributed in the hope that it will be useful, but WITHOUTANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESSFOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License formore details.You should have received a copy of the GNU Lesser General Public Licensealong with this library; if not, write to the Free Software Foundation, Inc.,59 Temple Place, Suite 330, Boston, MA  02111-1307  USA**********/// "liveMedia"// Copyright (c) 1996-2004 Live Networks, Inc.  All rights reserved.// MP3 internal implementation details (Huffman encoding)// Implementation#include "MP3InternalsHuffman.hh"#include <stdio.h>#include <string.h>#include <stdlib.h>MP3HuffmanEncodingInfo::MP3HuffmanEncodingInfo(Boolean includeDecodedValues) {  if (includeDecodedValues) {    decodedValues = new unsigned[(SBLIMIT*SSLIMIT + 1)*4];  } else {    decodedValues = NULL;  }}MP3HuffmanEncodingInfo::~MP3HuffmanEncodingInfo() {  delete[] decodedValues;}// This is crufty old code that needs to be cleaned up #####static unsigned debugCount = 0; /* for debugging */#define TRUNC_FAVORavoid updateSideInfoForHuffman(MP3SideInfo& sideInfo, Boolean isMPEG2,			      unsigned char const* mainDataPtr,			      unsigned p23L0, unsigned p23L1,			      unsigned& part23Length0a,			      unsigned& part23Length0aTruncation,			      unsigned& part23Length0b,			      unsigned& part23Length0bTruncation,			      unsigned& part23Length1a,			      unsigned& part23Length1aTruncation,			      unsigned& part23Length1b,			      unsigned& part23Length1bTruncation) {  int i, j;  unsigned sfLength, origTotABsize, adjustment;  MP3SideInfo::gr_info_s_t* gr;  /* First, Huffman-decode each part of the segment's main data,     to see at which bit-boundaries the samples appear:   */  MP3HuffmanEncodingInfo hei;  ++debugCount;#ifdef DEBUG  fprintf(stderr, "usifh-start: p23L0: %d, p23L1: %d\n", p23L0, p23L1);#endif  /* Process granule 0 */  {    gr = &(sideInfo.ch[0].gr[0]);    origTotABsize = gr->part2_3_length;    MP3HuffmanDecode(gr, isMPEG2, mainDataPtr, 0, origTotABsize, sfLength, hei);    /* Begin by computing new sizes for parts a & b (& their truncations) */#ifdef DEBUG    fprintf(stderr, "usifh-0: %d, %d:%d, %d:%d, %d:%d, %d:%d, %d:%d\n",	    hei.numSamples,	    sfLength/8, sfLength%8,	    hei.reg1Start/8, hei.reg1Start%8,	    hei.reg2Start/8, hei.reg2Start%8,	    hei.bigvalStart/8, hei.bigvalStart%8,	    origTotABsize/8, origTotABsize%8);#ifdef undef    {      unsigned k;      for (k = 0; k < hei.numSamples; ++k) {	fprintf(stderr, " %d:%d",		hei.allBitOffsets[k]/8, hei.allBitOffsets[k]%8);      }      fprintf(stderr, "\n");    }#endif#endif    if (p23L0 < sfLength) {      /* We can't use this, so give it all to the next granule: */      p23L1 += p23L0;      p23L0 = 0;    }    part23Length0a = hei.bigvalStart;    part23Length0b = origTotABsize - hei.bigvalStart;    part23Length0aTruncation = part23Length0bTruncation = 0;    if (origTotABsize > p23L0) {      /* We need to shorten one or both of fields a & b */      unsigned truncation = origTotABsize - p23L0;#ifdef TRUNC_FAIRLY      part23Length0aTruncation	= (truncation*(part23Length0a-sfLength))	                          /(origTotABsize-sfLength);      part23Length0bTruncation = truncation - part23Length0aTruncation;#endif#ifdef TRUNC_FAVORa      part23Length0bTruncation	= (truncation > part23Length0b) ? part23Length0b : truncation;      part23Length0aTruncation = truncation - part23Length0bTruncation;#endif#ifdef TRUNC_FAVORb      part23Length0aTruncation	= (truncation > part23Length0a-sfLength)	? (part23Length0a-sfLength) : truncation;      part23Length0bTruncation = truncation - part23Length0aTruncation;#endif    }    /* ASSERT:  part23Length0xTruncation <= part23Length0x */    part23Length0a -= part23Length0aTruncation;    part23Length0b -= part23Length0bTruncation;#ifdef DEBUG    fprintf(stderr, "usifh-0: interim sizes: %d (%d), %d (%d)\n",	    part23Length0a, part23Length0aTruncation,	    part23Length0b, part23Length0bTruncation);#endif    /* Adjust these new lengths so they end on sample bit boundaries: */    for (i = 0; i < (int)hei.numSamples; ++i) {      if (hei.allBitOffsets[i] == part23Length0a) break;      else if (hei.allBitOffsets[i] > part23Length0a) {--i; break;}    }    if (i < 0) { /* should happen only if we couldn't fit sfLength */      i = 0; adjustment = 0;    } else {      adjustment = part23Length0a - hei.allBitOffsets[i];    }#ifdef DEBUG    fprintf(stderr, "%d usifh-0: adjustment 1: %d\n", debugCount, adjustment);#endif    part23Length0a -= adjustment;    part23Length0aTruncation += adjustment;    /* Assign the bits we just shaved to field b and granule 1: */    if (part23Length0bTruncation < adjustment) {      p23L1 += (adjustment - part23Length0bTruncation);      adjustment = part23Length0bTruncation;    }    part23Length0b += adjustment;    part23Length0bTruncation -= adjustment;    for (j = i; j < (int)hei.numSamples; ++j) {      if (hei.allBitOffsets[j]	  == part23Length0a + part23Length0aTruncation + part23Length0b)	break;      else if (hei.allBitOffsets[j]	  > part23Length0a + part23Length0aTruncation + part23Length0b)	{--j; break;}    }    if (j < 0) { /* should happen only if we couldn't fit sfLength */      j = 0; adjustment = 0;    } else {      adjustment = part23Length0a+part23Length0aTruncation+part23Length0b                   - hei.allBitOffsets[j];    }#ifdef DEBUG    fprintf(stderr, "%d usifh-0: adjustment 2: %d\n", debugCount, adjustment);#endif    if (adjustment > part23Length0b) adjustment = part23Length0b; /*sanity*/    part23Length0b -= adjustment;    part23Length0bTruncation += adjustment;    /* Assign the bits we just shaved to granule 1 */    p23L1 += adjustment;        if (part23Length0aTruncation > 0) {      /* Change the granule's 'big_values' field to reflect the truncation */      gr->big_values = i;    }  }	    /* Process granule 1 (MPEG-1 only) */    if (isMPEG2) {    part23Length1a = part23Length1b = 0;    part23Length1aTruncation = part23Length1bTruncation = 0;  } else {    unsigned granule1Offset      = origTotABsize + sideInfo.ch[1].gr[0].part2_3_length;    gr = &(sideInfo.ch[0].gr[1]);    origTotABsize = gr->part2_3_length;    MP3HuffmanDecode(gr, isMPEG2, mainDataPtr, granule1Offset,		     origTotABsize, sfLength, hei);    /* Begin by computing new sizes for parts a & b (& their truncations) */#ifdef DEBUG    fprintf(stderr, "usifh-1: %d, %d:%d, %d:%d, %d:%d, %d:%d, %d:%d\n",	    hei.numSamples,	    sfLength/8, sfLength%8,	    hei.reg1Start/8, hei.reg1Start%8,	    hei.reg2Start/8, hei.reg2Start%8,	    hei.bigvalStart/8, hei.bigvalStart%8,	    origTotABsize/8, origTotABsize%8);#ifdef undef    {      unsigned k;      for (k = 0; k < hei.numSamples; ++k) {	fprintf(stderr, " %d:%d",		hei.allBitOffsets[k]/8, hei.allBitOffsets[k]%8);      }      fprintf(stderr, "\n");    }#endif#endif    if (p23L1 < sfLength) {      /* We can't use this, so give up on this granule: */      p23L1 = 0;    }    part23Length1a = hei.bigvalStart;    part23Length1b = origTotABsize - hei.bigvalStart;    part23Length1aTruncation = part23Length1bTruncation = 0;    if (origTotABsize > p23L1) {      /* We need to shorten one or both of fields a & b */      unsigned truncation = origTotABsize - p23L1;#ifdef TRUNC_FAIRLY      part23Length1aTruncation	= (truncation*(part23Length1a-sfLength))	                          /(origTotABsize-sfLength);      part23Length1bTruncation = truncation - part23Length1aTruncation;#endif#ifdef TRUNC_FAVORa      part23Length1bTruncation	= (truncation > part23Length1b) ? part23Length1b : truncation;      part23Length1aTruncation = truncation - part23Length1bTruncation;#endif#ifdef TRUNC_FAVORb      part23Length1aTruncation	= (truncation > part23Length1a-sfLength)	? (part23Length1a-sfLength) : truncation;      part23Length1bTruncation = truncation - part23Length1aTruncation;#endif    }    /* ASSERT:  part23Length1xTruncation <= part23Length1x */    part23Length1a -= part23Length1aTruncation;    part23Length1b -= part23Length1bTruncation;#ifdef DEBUG    fprintf(stderr, "usifh-1: interim sizes: %d (%d), %d (%d)\n",	    part23Length1a, part23Length1aTruncation,	    part23Length1b, part23Length1bTruncation);#endif    /* Adjust these new lengths so they end on sample bit boundaries: */    for (i = 0; i < (int)hei.numSamples; ++i) {      if (hei.allBitOffsets[i] == part23Length1a) break;      else if (hei.allBitOffsets[i] > part23Length1a) {--i; break;}    }    if (i < 0) { /* should happen only if we couldn't fit sfLength */      i = 0; adjustment = 0;    } else {      adjustment = part23Length1a - hei.allBitOffsets[i];    }#ifdef DEBUG    fprintf(stderr, "%d usifh-1: adjustment 0: %d\n", debugCount, adjustment);#endif    part23Length1a -= adjustment;    part23Length1aTruncation += adjustment;    /* Assign the bits we just shaved to field b: */    if (part23Length1bTruncation < adjustment) {      adjustment = part23Length1bTruncation;    }    part23Length1b += adjustment;    part23Length1bTruncation -= adjustment;    for (j = i; j < (int)hei.numSamples; ++j) {      if (hei.allBitOffsets[j]	  == part23Length1a + part23Length1aTruncation + part23Length1b)	break;      else if (hei.allBitOffsets[j]	  > part23Length1a + part23Length1aTruncation + part23Length1b)	{--j; break;}    }    if (j < 0) { /* should happen only if we couldn't fit sfLength */      j = 0; adjustment = 0;    } else {      adjustment = part23Length1a+part23Length1aTruncation+part23Length1b                   - hei.allBitOffsets[j];    }#ifdef DEBUG    fprintf(stderr, "%d usifh-1: adjustment 1: %d\n", debugCount, adjustment);#endif    if (adjustment > part23Length1b) adjustment = part23Length1b; /*sanity*/    part23Length1b -= adjustment;    part23Length1bTruncation += adjustment;        if (part23Length1aTruncation > 0) {      /* Change the granule's 'big_values' field to reflect the truncation */      gr->big_values = i;    }  }#ifdef DEBUG  fprintf(stderr, "usifh-end, new vals: %d (%d), %d (%d), %d (%d), %d (%d)\n",	  part23Length0a, part23Length0aTruncation,	  part23Length0b, part23Length0bTruncation,	  part23Length1a, part23Length1aTruncation,	  part23Length1b, part23Length1bTruncation);#endif}static void rsf_getline(char* line, unsigned max, unsigned char**fi) {  unsigned i;  for (i = 0; i < max; ++i) {    line[i] = *(*fi)++;    if (line[i] == '\n') {      line[i++] = '\0';      return;    }  }  line[i] = '\0';}static void rsfscanf(unsigned char **fi, unsigned int* v) {  while (sscanf((char*)*fi, "%x", v) == 0) {    /* skip past the next '\0' */    while (*(*fi)++ != '\0') {}  }  /* skip past any white-space before the value: */  while (*(*fi) <= ' ') ++(*fi);  /* skip past the value: */  while (*(*fi) > ' ') ++(*fi);}#define HUFFBITS unsigned long int#define SIZEOF_HUFFBITS 4#define HTN     34#define MXOFF   250struct huffcodetab {  char tablename[3];	/*string, containing table_description	*/  unsigned int xlen; 	/*max. x-index+			      	*/   unsigned int ylen;	/*max. y-index+				*/  unsigned int linbits; /*number of linbits			*/  unsigned int linmax;	/*max number to be stored in linbits	*/  int ref;		/*a positive value indicates a reference*/  HUFFBITS *table;	/*pointer to array[xlen][ylen]		*/  unsigned char *hlen;	/*pointer to array[xlen][ylen]		*/  unsigned char(*val)[2];/*decoder tree				*/   unsigned int treelen;	/*length of decoder tree		*/};static struct huffcodetab rsf_ht[HTN]; // array of all huffcodetable headers				/* 0..31 Huffman code table 0..31	*/				/* 32,33 count1-tables			*//* read the huffman decoder table */static int read_decoder_table(unsigned char* fi) {   int n,i,nn,t;  unsigned int v0,v1;  char command[100],line[100];  for (n=0;n<HTN;n++) {    rsf_ht[n].table = NULL;    rsf_ht[n].hlen = NULL;    /* .table number treelen xlen ylen linbits */     do {      rsf_getline(line,99,&fi);    } while ((line[0] == '#') || (line[0] < ' '));         sscanf(line,"%s %s %u %u %u %u",command,rsf_ht[n].tablename,           &rsf_ht[n].treelen, &rsf_ht[n].xlen, &rsf_ht[n].ylen, &rsf_ht[n].linbits);    if (strcmp(command,".end")==0)      return n;    else if (strcmp(command,".table")!=0) {#ifdef DEBUG      fprintf(stderr,"huffman table %u data corrupted\n",n);#endif      return -1;    }    rsf_ht[n].linmax = (1<<rsf_ht[n].linbits)-1;       sscanf(rsf_ht[n].tablename,"%u",&nn);    if (nn != n) {#ifdef DEBUG      fprintf(stderr,"wrong table number %u\n",n);#endif      return(-2);    }     do {      rsf_getline(line,99,&fi);    } while ((line[0] == '#') || (line[0] < ' '));    sscanf(line,"%s %u",command,&t);    if (strcmp(command,".reference")==0) {      rsf_ht[n].ref   = t;      rsf_ht[n].val   = rsf_ht[t].val;      rsf_ht[n].treelen  = rsf_ht[t].treelen;      if ( (rsf_ht[n].xlen != rsf_ht[t].xlen) ||           (rsf_ht[n].ylen != rsf_ht[t].ylen)  ) {#ifdef DEBUG        fprintf(stderr,"wrong table %u reference\n",n);#endif        return (-3);      };      while ((line[0] == '#') || (line[0] < ' ') ) {        rsf_getline(line,99,&fi);      }    }        else if (strcmp(command,".treedata")==0) {      rsf_ht[n].ref  = -1;      rsf_ht[n].val = (unsigned char (*)[2])         new unsigned char[2*(rsf_ht[n].treelen)];      if ((rsf_ht[n].val == NULL) && ( rsf_ht[n].treelen != 0 )){#ifdef DEBUG    	fprintf(stderr, "heaperror at table %d\n",n);#endif    	exit (-10);      }      for (i=0;(unsigned)i<rsf_ht[n].treelen; i++) {        rsfscanf(&fi, &v0);        rsfscanf(&fi, &v1);/*replaces        fscanf(fi,"%x %x",&v0, &v1);*/        rsf_ht[n].val[i][0]=(unsigned char)v0;        rsf_ht[n].val[i][1]=(unsigned char)v1;      }      rsf_getline(line,99,&fi); /* read the rest of the line */    }    else {#ifdef DEBUG      fprintf(stderr,"huffman decodertable error at table %d\n",n);#endif    }  }  return n;}static void initialize_huffman() {  static Boolean huffman_initialized = False;   if (huffman_initialized) return;   if (read_decoder_table(huffdec) != HTN) {#ifdef DEBUG      fprintf(stderr,"decoder table read error\n");#endif      exit(4);      }   huffman_initialized = True;}static unsigned char const slen[2][16] = {  {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4},  {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3}};static unsigned char const stab[3][6][4] = {  { { 6, 5, 5,5 } , { 6, 5, 7,3 } , { 11,10,0,0} ,    { 7, 7, 7,0 } , { 6, 6, 6,3 } , {  8, 8,5,0} } ,  { { 9, 9, 9,9 } , { 9, 9,12,6 } , { 18,18,0,0} ,    {12,12,12,0 } , {12, 9, 9,6 } , { 15,12,9,0} } ,  { { 6, 9, 9,9 } , { 6, 9,12,6 } , { 15,18,0,0} ,    { 6,15,12,0 } , { 6,12, 9,6 } , {  6,18,9,0} }}; static unsigned rsf_get_scale_factors_1(MP3SideInfo::gr_info_s_t *gr_info) {   int numbits;   int num0 = slen[0][gr_info->scalefac_compress];   int num1 = slen[1][gr_info->scalefac_compress];    if (gr_info->block_type == 2)     {      numbits = (num0 + num1) * 18;      if (gr_info->mixed_block_flag) {         numbits -= num0; /* num0 * 17 + num1 * 18 */      }    }    else     {      int scfsi = gr_info->scfsi;      if(scfsi < 0) { /* scfsi < 0 => granule == 0 */         numbits = (num0 + num1) * 10 + num0;      }      else {        numbits = 0;        if(!(scfsi & 0x8)) {          numbits += num0 * 6;        }        else {        }        if(!(scfsi & 0x4)) {          numbits += num0 * 5;        }        else {        }        if(!(scfsi & 0x2)) {          numbits += num1 * 5;        }        else {        }        if(!(scfsi & 0x1)) {          numbits += num1 * 5;        }        else {        }      }    }    return numbits;}extern unsigned n_slen2[];extern unsigned i_slen2[];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -