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

📄 mp3internalshuffman.cpp

📁 流媒体传输协议的实现代码,非常有用.可以支持rtsp mms等流媒体传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
static unsigned rsf_get_scale_factors_2(MP3SideInfo::gr_info_s_t *gr_info) {  unsigned char const* pnt;  int i;  unsigned int slen;  int n = 0;  int numbits = 0;#ifdef undef  if(i_stereo) /* i_stereo AND second channel -> do_layer3() checks this */    slen = i_slen2[gr_info->scalefac_compress>>1];  else#endif    slen = n_slen2[gr_info->scalefac_compress];  gr_info->preflag = (slen>>15) & 0x1;  n = 0;    if( gr_info->block_type == 2 ) {    n++;    if(gr_info->mixed_block_flag)      n++;  }  pnt = stab[n][(slen>>12)&0x7];  for(i=0;i<4;i++) {    int num = slen & 0x7;    slen >>= 3;    numbits += pnt[i] * num;  }  return numbits;}static unsigned getScaleFactorsLength(MP3SideInfo::gr_info_s_t* gr,				      Boolean isMPEG2) {  return isMPEG2 ? rsf_get_scale_factors_2(gr)                 : rsf_get_scale_factors_1(gr);}static int rsf_huffman_decoder(BitVector& bv,			       struct huffcodetab const* h,			       int* x, int* y, int* v, int* w); // forwardvoid MP3HuffmanDecode(MP3SideInfo::gr_info_s_t* gr, int isMPEG2,		      unsigned char const* fromBasePtr,		      unsigned fromBitOffset, unsigned fromLength,		      unsigned& scaleFactorsLength,		      MP3HuffmanEncodingInfo& hei) {   unsigned i;   int x, y, v, w;   struct huffcodetab *h;   BitVector bv((unsigned char*)fromBasePtr, fromBitOffset, fromLength);   /* Compute the size of the scale factors (& also advance bv): */   scaleFactorsLength = getScaleFactorsLength(gr, isMPEG2);   bv.skipBits(scaleFactorsLength);   initialize_huffman();   hei.reg1Start = hei.reg2Start = hei.numSamples = 0;   /* Read bigvalues area. */   if (gr->big_values < gr->region1start + gr->region2start) {     gr->big_values = gr->region1start + gr->region2start; /* sanity check */   }   for (i = 0; i < gr->big_values; ++i) {     if (i < gr->region1start) {       /* in region 0 */       h = &rsf_ht[gr->table_select[0]];     } else if (i < gr->region2start) {       /* in region 1 */       h = &rsf_ht[gr->table_select[1]];       if (hei.reg1Start == 0) {	 hei.reg1Start = bv.curBitIndex();       }     } else {       /* in region 2 */       h = &rsf_ht[gr->table_select[2]];       if (hei.reg2Start == 0) {	 hei.reg2Start = bv.curBitIndex();       }     }          hei.allBitOffsets[i] = bv.curBitIndex();     rsf_huffman_decoder(bv, h, &x, &y, &v, &w);     if (hei.decodedValues != NULL) {       // Record the decoded values:       unsigned* ptr = &hei.decodedValues[4*i];       ptr[0] = x; ptr[1] = y; ptr[2] = v; ptr[3] = w;     }   }   hei.bigvalStart = bv.curBitIndex();      /* Read count1 area. */   h = &rsf_ht[gr->count1table_select+32];   while (bv.curBitIndex() < bv.totNumBits() &&  i < SSLIMIT*SBLIMIT) {     hei.allBitOffsets[i] = bv.curBitIndex();     rsf_huffman_decoder(bv, h, &x, &y, &v, &w);     if (hei.decodedValues != NULL) {       // Record the decoded values:       unsigned* ptr = &hei.decodedValues[4*i];       ptr[0] = x; ptr[1] = y; ptr[2] = v; ptr[3] = w;     }     ++i;   }   hei.allBitOffsets[i] = bv.curBitIndex();   hei.numSamples = i;}HUFFBITS dmask = 1 << (SIZEOF_HUFFBITS*8-1);unsigned int hs = SIZEOF_HUFFBITS*8;/* do the huffman-decoding 						*/static int rsf_huffman_decoder(BitVector& bv,		struct huffcodetab const* h, // ptr to huffman code record			/* unsigned */ int *x, // returns decoded x value			/* unsigned */ int *y,  // returns decoded y value			       int* v, int* w) {  HUFFBITS level;  unsigned point = 0;  int error = 1;  level     = dmask;  *x = *y = *v = *w = 0;  if (h->val == NULL) return 2;  /* table 0 needs no bits */  if (h->treelen == 0) return 0;  /* Lookup in Huffman table. */  do {    if (h->val[point][0]==0) {   /*end of tree*/      *x = h->val[point][1] >> 4;      *y = h->val[point][1] & 0xf;      error = 0;      break;    }     if (bv.get1Bit()) {      while (h->val[point][1] >= MXOFF) point += h->val[point][1];       point += h->val[point][1];    }    else {      while (h->val[point][0] >= MXOFF) point += h->val[point][0];       point += h->val[point][0];    }    level >>= 1;  } while (level  || (point < h->treelen) );/////  } while (level  || (point < rsf_ht->treelen) );    /* Check for error. */    if (error) { /* set x and y to a medium value as a simple concealment */    printf("Illegal Huffman code in data.\n");    *x = ((h->xlen-1) << 1);    *y = ((h->ylen-1) << 1);  }  /* Process sign encodings for quadruples tables. */  if (h->tablename[0] == '3'      && (h->tablename[1] == '2' || h->tablename[1] == '3')) {     *v = (*y>>3) & 1;     *w = (*y>>2) & 1;     *x = (*y>>1) & 1;     *y = *y & 1;     if (*v)        if (bv.get1Bit() == 1) *v = -*v;     if (*w)        if (bv.get1Bit() == 1) *w = -*w;     if (*x)        if (bv.get1Bit() == 1) *x = -*x;     if (*y)        if (bv.get1Bit() == 1) *y = -*y;     }       /* Process sign and escape encodings for dual tables. */    else {     if (h->linbits)       if ((h->xlen-1) == (unsigned)*x)          *x += bv.getBits(h->linbits);     if (*x)        if (bv.get1Bit() == 1) *x = -*x;     if (h->linbits)	         if ((h->ylen-1) == (unsigned)*y)         *y += bv.getBits(h->linbits);     if (*y)        if (bv.get1Bit() == 1) *y = -*y;  }	    return error;  }#ifdef DO_HUFFMAN_ENCODINGinline int getNextSample(unsigned char const*& fromPtr) {  int sample#ifdef FOUR_BYTE_SAMPLES    = (fromPtr[0]<<24) | (fromPtr[1]<<16) | (fromPtr[2]<<8) | fromPtr[3];#else#ifdef TWO_BYTE_SAMPLES    = (fromPtr[0]<<8) | fromPtr[1];#else    // ONE_BYTE_SAMPLES    = fromPtr[0];#endif#endif  fromPtr += BYTES_PER_SAMPLE_VALUE;  return sample;}static void rsf_huffman_encoder(BitVector& bv,				struct huffcodetab* h,				int x, int y, int v, int w); // forwardunsigned MP3HuffmanEncode(MP3SideInfo::gr_info_s_t const* gr,			  unsigned char const* fromPtr,			  unsigned char* toPtr, unsigned toBitOffset,			  unsigned numHuffBits) {   unsigned i;   struct huffcodetab *h;   int x, y, v, w;   BitVector bv(toPtr, toBitOffset, numHuffBits);   initialize_huffman();   // Encode big_values area:   unsigned big_values = gr->big_values;   if (big_values < gr->region1start + gr->region2start) {     big_values = gr->region1start + gr->region2start; /* sanity check */   }   for (i = 0; i < big_values; ++i) {     if (i < gr->region1start) {       /* in region 0 */       h = &rsf_ht[gr->table_select[0]];     } else if (i < gr->region2start) {       /* in region 1 */       h = &rsf_ht[gr->table_select[1]];     } else {       /* in region 2 */       h = &rsf_ht[gr->table_select[2]];     }          x = getNextSample(fromPtr);     y = getNextSample(fromPtr);     v = getNextSample(fromPtr);     w = getNextSample(fromPtr);     rsf_huffman_encoder(bv, h, x, y, v, w);   }      // Encode count1 area:   h = &rsf_ht[gr->count1table_select+32];   while (bv.curBitIndex() < bv.totNumBits() &&  i < SSLIMIT*SBLIMIT) {     x = getNextSample(fromPtr);     y = getNextSample(fromPtr);     v = getNextSample(fromPtr);     w = getNextSample(fromPtr);     rsf_huffman_encoder(bv, h, x, y, v, w);     ++i;   }   return i;}static Boolean lookupHuffmanTableEntry(struct huffcodetab const* h,				       HUFFBITS bits, unsigned bitsLength,				       unsigned char& xy) {  unsigned point = 0;  unsigned mask = 1;  unsigned numBitsTestedSoFar = 0;  do {    if (h->val[point][0]==0) { // end of tree      xy = h->val[point][1];      if (h->hlen[xy] == 0) { // this entry hasn't already been used	h->table[xy] = bits;	h->hlen[xy] = bitsLength;	return True;      } else { // this entry has already been seen	return False;      }    }        if (numBitsTestedSoFar++ == bitsLength) {      // We don't yet have enough bits for this prefix      return False;    }    if (bits&mask) {      while (h->val[point][1] >= MXOFF) point += h->val[point][1];       point += h->val[point][1];    } else {      while (h->val[point][0] >= MXOFF) point += h->val[point][0];       point += h->val[point][0];    }    mask <<= 1;  } while (mask || (point < h->treelen));  return False;}static void buildHuffmanEncodingTable(struct huffcodetab* h) {  h->table = new unsigned long[256];  h->hlen = new unsigned char[256];  if (h->table == NULL || h->hlen == NULL) { h->table = NULL; return; }  for (unsigned i = 0; i < 256; ++i) {    h->table[i] = 0; h->hlen[i] = 0;  }  // Look up entries for each possible bit sequence length:  unsigned maxNumEntries = h->xlen * h->ylen;  unsigned numEntries = 0;  unsigned powerOf2 = 1;  for (unsigned bitsLength = 1;       bitsLength <= 8*SIZEOF_HUFFBITS; ++bitsLength) {    powerOf2 *= 2;    for (HUFFBITS bits = 0; bits < powerOf2; ++bits) {      // Find the table value - if any - for 'bits' (length 'bitsLength'):      unsigned char xy;      if (lookupHuffmanTableEntry(h, bits, bitsLength, xy)) {	++numEntries;	if (numEntries == maxNumEntries) return; // we're done      }    }  }#ifdef DEBUG  fprintf(stderr, "Didn't find enough entries!\n"); // shouldn't happen#endif}static void lookupXYandPutBits(BitVector& bv, struct huffcodetab const* h,			       unsigned char xy) {  HUFFBITS bits = h->table[xy];  unsigned bitsLength = h->hlen[xy];  // Note that "bits" is in reverse order, so read them from right-to-left:  while (bitsLength-- > 0) {    bv.put1Bit(bits&0x00000001);    bits >>= 1;  }}static void putLinbits(BitVector& bv, struct huffcodetab const* h,		       HUFFBITS bits) {  bv.putBits(bits, h->linbits);}static void rsf_huffman_encoder(BitVector& bv,				struct huffcodetab* h,				int x, int y, int v, int w) {  if (h->val == NULL) return;  /* table 0 produces no bits */  if (h->treelen == 0) return;  if (h->table == NULL) {    // We haven't yet built the encoding array for this table; do it now:    buildHuffmanEncodingTable(h);    if (h->table == NULL) return;  }  Boolean xIsNeg = False, yIsNeg = False, vIsNeg = False, wIsNeg = False;  unsigned char xy;#ifdef FOUR_BYTE_SAMPLES#else#ifdef TWO_BYTE_SAMPLES  // Convert 2-byte negative numbers to their 4-byte equivalents:  if (x&0x8000) x |= 0xFFFF0000;  if (y&0x8000) y |= 0xFFFF0000;  if (v&0x8000) v |= 0xFFFF0000;  if (w&0x8000) w |= 0xFFFF0000;#else  // ONE_BYTE_SAMPLES  // Convert 1-byte negative numbers to their 4-byte equivalents:  if (x&0x80) x |= 0xFFFFFF00;  if (y&0x80) y |= 0xFFFFFF00;  if (v&0x80) v |= 0xFFFFFF00;  if (w&0x80) w |= 0xFFFFFF00;#endif#endif  if (h->tablename[0] == '3'      && (h->tablename[1] == '2' || h->tablename[1] == '3')) {// quad tables    if (x < 0) { xIsNeg = True; x = -x; }    if (y < 0) { yIsNeg = True; y = -y; }    if (v < 0) { vIsNeg = True; v = -v; }    if (w < 0) { wIsNeg = True; w = -w; }    // Sanity check: x,y,v,w must all be 0 or 1:    if (x>1 || y>1 || v>1 || w>1) {#ifdef DEBUG      fprintf(stderr, "rsf_huffman_encoder quad sanity check fails: %x,%x,%x,%x\n", x, y, v, w);#endif    }    xy = (v<<3)|(w<<2)|(x<<1)|y;    lookupXYandPutBits(bv, h, xy);    if (v) bv.put1Bit(vIsNeg);    if (w) bv.put1Bit(wIsNeg);    if (x) bv.put1Bit(xIsNeg);    if (y) bv.put1Bit(yIsNeg);  } else { // dual tables    // Sanity check: v and w must be 0:    if (v != 0 || w != 0) {#ifdef DEBUG      fprintf(stderr, "rsf_huffman_encoder dual sanity check 1 fails: %x,%x,%x,%x\n", x, y, v, w);#endif    }    if (x < 0) { xIsNeg = True; x = -x; }    if (y < 0) { yIsNeg = True; y = -y; }    // Sanity check: x and y must be <= 255:    if (x > 255 || y > 255) {#ifdef DEBUG      fprintf(stderr, "rsf_huffman_encoder dual sanity check 2 fails: %x,%x,%x,%x\n", x, y, v, w);#endif    }    int xl1 = h->xlen-1;    int yl1 = h->ylen-1;    unsigned linbitsX = 0; unsigned linbitsY = 0;    if (((x < xl1) || (xl1 == 0)) && (y < yl1)) {      // normal case      xy = (x<<4)|y;      lookupXYandPutBits(bv, h, xy);      if (x) bv.put1Bit(xIsNeg);      if (y) bv.put1Bit(yIsNeg);    } else if (x >= xl1) {      linbitsX = (unsigned)(x - xl1);      if (linbitsX > h->linmax) {#ifdef DEBUG	fprintf(stderr,"warning: Huffman X table overflow\n");#endif	linbitsX = h->linmax;      };      if (y >= yl1) {	xy = (xl1<<4)|yl1;	lookupXYandPutBits(bv, h, xy);	linbitsY = (unsigned)(y - yl1);	if (linbitsY > h->linmax) {#ifdef DEBUG	  fprintf(stderr,"warning: Huffman Y table overflow\n");#endif	  linbitsY = h->linmax;	};	if (h->linbits) putLinbits(bv, h, linbitsX);	if (x) bv.put1Bit(xIsNeg);	if (h->linbits) putLinbits(bv, h, linbitsY);	if (y) bv.put1Bit(yIsNeg);      } else { /* x >= h->xlen, y < h->ylen */	xy = (xl1<<4)|y;	lookupXYandPutBits(bv, h, xy);	if (h->linbits) putLinbits(bv, h, linbitsX);	if (x) bv.put1Bit(xIsNeg);	if (y) bv.put1Bit(yIsNeg);      }    } else { /* ((x < h->xlen) && (y >= h->ylen)) */      xy = (x<<4)|yl1;      lookupXYandPutBits(bv, h, xy);      linbitsY = y-yl1;      if (linbitsY > h->linmax) {#ifdef DEBUG	fprintf(stderr,"warning: Huffman Y table overflow\n");#endif	linbitsY = h->linmax;      };      if (x) bv.put1Bit(xIsNeg);      if (h->linbits) putLinbits(bv, h, linbitsY);      if (y) bv.put1Bit(yIsNeg);    }  }}#endif#ifdef undef/* The system uses a variety of data files.  By opening them via this   function, we can accommodate various locations. */FILE *OpenTableFile(name)char *name;{char fulname[80];FILE *f;     fulname[0] = '\0';    strcat(fulname, name);    if( (f=fopen(fulname,"r"))==NULL ) {        fprintf(stderr,"OpenTable: could not find %s\n", fulname);    }/* The following was used to generate an internal version of the file #####*/    {FILE *testfd = fopen("rsf_hufftab.c", "w");unsigned char buf[100];unsigned i;for (i = 0; i < 100; ++i) buf[i] = '\0';while (fgets(buf, 100, f) != NULL) {  unsigned j;  for (j = 0; buf[j] != '\0'; ++j) {    fprintf(testfd, "0x%02x, ", buf[j]);  }  for (i = 0; i < 100; ++i) buf[i] = '\0';}fclose(testfd);exit(0);    }/*#####*/    return f;}#endif

⌨️ 快捷键说明

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