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

📄 mp3internals.cpp

📁 流媒体传输协议的实现代码,非常有用.可以支持rtsp mms等流媒体传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
         gr_info.region2start = 576>>1;       }       else        {         int i,r0c,r1c;         for (i=0; i<3; i++) {	   gr_info.table_select[i] = fr.getBits(5);	 }         r0c = gr_info.region0_count = fr.getBits(4);         r1c = gr_info.region1_count = fr.getBits(3);         gr_info.region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;         gr_info.region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;         gr_info.block_type = 0;         gr_info.mixed_block_flag = 0;       }       gr_info.preflag = fr.get1Bit();       gr_info.scalefac_scale = fr.get1Bit();       gr_info.count1table_select = fr.get1Bit();     }   }}static void getSideInfo2(MP3FrameParams& fr, MP3SideInfo& si,			 int stereo, int ms_stereo, long sfreq,			 int /*single*/) {   int ch;#if 0   int powdiff = (single == 3) ? 4 : 0;#endif   /* initialize all four "part2_3_length" fields to zero: */   si.ch[0].gr[0].part2_3_length = 0; si.ch[1].gr[0].part2_3_length = 0;   si.ch[0].gr[1].part2_3_length = 0; si.ch[1].gr[1].part2_3_length = 0;   si.main_data_begin = fr.getBits(8);   if (stereo == 1)     si.private_bits = fr.get1Bit();   else      si.private_bits = fr.getBits(2);   for (ch=0; ch<stereo; ch++) {       MP3SideInfo::gr_info_s_t& gr_info = si.ch[ch].gr[0];       gr_info.part2_3_length = fr.getBits(12);       si.ch[ch].gr[1].part2_3_length = 0; /* to ensure granule 1 unused */       gr_info.big_values = fr.getBits(9);       gr_info.global_gain = fr.getBits(8);#if 0       gr_info.pow2gain = gainpow2+256 - gr_info.global_gain + powdiff;       if (ms_stereo) gr_info.pow2gain += 2;#endif       gr_info.scalefac_compress = fr.getBits(9);/* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */       gr_info.window_switching_flag = fr.get1Bit();       if (gr_info.window_switching_flag) {         int i;         gr_info.block_type = fr.getBits(2);         gr_info.mixed_block_flag = fr.get1Bit();         gr_info.table_select[0] = fr.getBits(5);         gr_info.table_select[1] = fr.getBits(5);         /*          * table_select[2] not needed, because there is no region2,          * but to satisfy some verifications tools we set it either.          */         gr_info.table_select[2] = 0;         for (i=0;i<3;i++) {	   gr_info.subblock_gain[i] = fr.getBits(3);           gr_info.full_gain[i]	     = gr_info.pow2gain + ((gr_info.subblock_gain[i])<<3);	 }#ifdef DEBUG_ERRORS         if (gr_info.block_type == 0) {           fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");         }#endif         /* region_count/start parameters are implicit in this case. */       /* check this again! */         if (gr_info.block_type == 2)           gr_info.region1start = 36>>1;         else {           gr_info.region1start = 54>>1;         }         gr_info.region2start = 576>>1;       }       else        {         int i,r0c,r1c;         for (i=0; i<3; i++) {           gr_info.table_select[i] = fr.getBits(5);	 }         r0c = gr_info.region0_count = fr.getBits(4);         r1c = gr_info.region1_count = fr.getBits(3);         gr_info.region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;         gr_info.region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;         gr_info.block_type = 0;         gr_info.mixed_block_flag = 0;       }       gr_info.scalefac_scale = fr.get1Bit();       gr_info.count1table_select = fr.get1Bit();   }}#define         MPG_MD_JOINT_STEREO     1void MP3FrameParams::getSideInfo(MP3SideInfo& si) {  // First skip over the CRC if present:  if (hasCRC) getBits(16);  int single = -1;  int ms_stereo, i_stereo;  int sfreq = samplingFreqIndex;  if (stereo == 1) {    single = 0;  }  ms_stereo = (mode == MPG_MD_JOINT_STEREO) && (mode_ext & 0x2);  i_stereo = (mode == MPG_MD_JOINT_STEREO) && (mode_ext & 0x1);  if (isMPEG2) {    getSideInfo2(*this, si, stereo, ms_stereo, sfreq, single);  } else {    getSideInfo1(*this, si, stereo, ms_stereo, sfreq, single);  }}static void putSideInfo1(BitVector& bv,			 MP3SideInfo const& si, Boolean isStereo) {  int ch, gr, i;  int stereo = isStereo ? 2 : 1;    bv.putBits(si.main_data_begin,9);  if (stereo == 1)    bv.putBits(si.private_bits, 5);  else    bv.putBits(si.private_bits, 3);    for (ch=0; ch<stereo; ch++) {    bv.putBits(si.ch[ch].gr[1].scfsi, 4);  }    for (gr=0; gr<2; gr++) {    for (ch=0; ch<stereo; ch++) {      MP3SideInfo::gr_info_s_t const& gr_info = si.ch[ch].gr[gr];      bv.putBits(gr_info.part2_3_length, 12);      bv.putBits(gr_info.big_values, 9);      bv.putBits(gr_info.global_gain, 8);      bv.putBits(gr_info.scalefac_compress, 4);      bv.put1Bit(gr_info.window_switching_flag);      if (gr_info.window_switching_flag) {	bv.putBits(gr_info.block_type, 2);	bv.put1Bit(gr_info.mixed_block_flag);	for (i=0; i<2; i++)	  bv.putBits(gr_info.table_select[i], 5);	for (i=0; i<3; i++)	  bv.putBits(gr_info.subblock_gain[i], 3);      }      else {	for (i=0; i<3; i++)	  bv.putBits(gr_info.table_select[i], 5);	bv.putBits(gr_info.region0_count, 4);	bv.putBits(gr_info.region1_count, 3);      }                  bv.put1Bit(gr_info.preflag);      bv.put1Bit(gr_info.scalefac_scale);      bv.put1Bit(gr_info.count1table_select);    }  }}static void putSideInfo2(BitVector& bv,			 MP3SideInfo const& si, Boolean isStereo) {  int ch, i;  int stereo = isStereo ? 2 : 1;    bv.putBits(si.main_data_begin,8);  if (stereo == 1)    bv.put1Bit(si.private_bits);  else    bv.putBits(si.private_bits, 2);    for (ch=0; ch<stereo; ch++) {    MP3SideInfo::gr_info_s_t const& gr_info = si.ch[ch].gr[0];        bv.putBits(gr_info.part2_3_length, 12);    bv.putBits(gr_info.big_values, 9);    bv.putBits(gr_info.global_gain, 8);    bv.putBits(gr_info.scalefac_compress, 9);    bv.put1Bit(gr_info.window_switching_flag);    if (gr_info.window_switching_flag) {      bv.putBits(gr_info.block_type, 2);      bv.put1Bit(gr_info.mixed_block_flag);      for (i=0; i<2; i++)	bv.putBits(gr_info.table_select[i], 5);      for (i=0; i<3; i++)	bv.putBits(gr_info.subblock_gain[i], 3);    }    else {      for (i=0; i<3; i++)	bv.putBits(gr_info.table_select[i], 5);      bv.putBits(gr_info.region0_count, 4);      bv.putBits(gr_info.region1_count, 3);    }              bv.put1Bit(gr_info.scalefac_scale);    bv.put1Bit(gr_info.count1table_select);  }}static void PutMP3SideInfoIntoFrame(MP3SideInfo const& si,				    MP3FrameParams const& fr,				    unsigned char* framePtr) {  if (fr.hasCRC) framePtr += 2; // skip CRC  BitVector bv(framePtr, 0, 8*fr.sideInfoSize);  if (fr.isMPEG2) {    putSideInfo2(bv, si, fr.isStereo);  } else {    putSideInfo1(bv, si, fr.isStereo);  }}Boolean ZeroOutMP3SideInfo(unsigned char* framePtr, unsigned totFrameSize,                           unsigned newBackpointer) {  if (totFrameSize < 4) return False; // there's not enough data  MP3FrameParams fr;  fr.hdr =   ((unsigned)framePtr[0] << 24) | ((unsigned)framePtr[1] << 16)           | ((unsigned)framePtr[2] << 8) | (unsigned)framePtr[3];  fr.setParamsFromHeader();  fr.setBytePointer(framePtr + 4, totFrameSize - 4); // skip hdr  if (totFrameSize < 4 + fr.sideInfoSize) return False; // not enough data  MP3SideInfo si;  fr.getSideInfo(si);  si.main_data_begin = newBackpointer; /* backpointer */  /* set all four "part2_3_length" and "big_values" fields to zero: */  si.ch[0].gr[0].part2_3_length = si.ch[0].gr[0].big_values = 0;  si.ch[1].gr[0].part2_3_length = si.ch[1].gr[0].big_values = 0;  si.ch[0].gr[1].part2_3_length = si.ch[0].gr[1].big_values = 0;  si.ch[1].gr[1].part2_3_length = si.ch[1].gr[1].big_values = 0;  PutMP3SideInfoIntoFrame(si, fr, framePtr + 4);  return True;}static unsigned MP3BitrateToBitrateIndex(unsigned bitrate /* in kbps */,					 Boolean isMPEG2) {  for (unsigned i = 1; i < 15; ++i) {    if (live_tabsel[isMPEG2][2][i] >= bitrate)      return i;  }  // "bitrate" was larger than any possible, so return the largest possible:  return 14;}           static void outputHeader(unsigned char* toPtr, unsigned hdr) {  toPtr[0] = (unsigned char)(hdr>>24);  toPtr[1] = (unsigned char)(hdr>>16);  toPtr[2] = (unsigned char)(hdr>>8);  toPtr[3] = (unsigned char)(hdr);}static void assignADUBackpointer(MP3FrameParams const& fr,				 unsigned aduSize,				 MP3SideInfo& sideInfo,				 unsigned& availableBytesForBackpointer) {  // Give the ADU as large a backpointer as possible:  unsigned maxBackpointerSize = fr.isMPEG2 ? 255 : 511;  unsigned backpointerSize = availableBytesForBackpointer;  if (backpointerSize > maxBackpointerSize) {    backpointerSize = maxBackpointerSize;   }  // Store the new backpointer now:  sideInfo.main_data_begin = backpointerSize;  // Figure out how many bytes are available for the *next* ADU's backpointer:  availableBytesForBackpointer    = backpointerSize + fr.frameSize - fr.sideInfoSize ;  if (availableBytesForBackpointer < aduSize) {    availableBytesForBackpointer = 0;  } else {    availableBytesForBackpointer -= aduSize;  }}unsigned TranscodeMP3ADU(unsigned char const* fromPtr, unsigned fromSize,                      unsigned toBitrate,		      unsigned char* toPtr, unsigned toMaxSize,		      unsigned& availableBytesForBackpointer) {  // Begin by parsing the input ADU's parameters:  unsigned hdr, inFrameSize, inSideInfoSize, backpointer, inAduSize;  MP3SideInfo sideInfo;  if (!GetADUInfoFromMP3Frame(fromPtr, fromSize,                              hdr, inFrameSize, sideInfo, inSideInfoSize,			      backpointer, inAduSize)) {    return 0;  }  fromPtr += (4+inSideInfoSize); // skip to 'main data'  // Alter the 4-byte MPEG header to reflect the output ADU:  // (different bitrate; mono; no CRC)  Boolean isMPEG2 = ((hdr&0x00080000) == 0);  unsigned toBitrateIndex = MP3BitrateToBitrateIndex(toBitrate, isMPEG2);  hdr &=~ 0xF000; hdr |= (toBitrateIndex<<12); // set bitrate index  hdr |= 0x10200; // turn on !error-prot and padding bits  hdr &=~ 0xC0; hdr |= 0xC0; // set mode to 3 (mono)  // Set up the rest of the parameters of the new ADU:  MP3FrameParams outFr;  outFr.hdr = hdr;  outFr.setParamsFromHeader();  // Figure out how big to make the output ADU:  unsigned inAveAduSize = inFrameSize - inSideInfoSize;  unsigned outAveAduSize = outFr.frameSize - outFr.sideInfoSize;  unsigned desiredOutAduSize /*=inAduSize*outAveAduSize/inAveAduSize*/    = (2*inAduSize*outAveAduSize + inAveAduSize)/(2*inAveAduSize);      // this rounds to the nearest integer  if (toMaxSize < (4 + outFr.sideInfoSize)) return 0;  unsigned maxOutAduSize = toMaxSize - (4 + outFr.sideInfoSize);  if (desiredOutAduSize > maxOutAduSize) {    desiredOutAduSize = maxOutAduSize;  }  // Figure out the new sizes of the various 'part23 lengths',  // and how much they are truncated:  unsigned part23Length0a, part23Length0aTruncation;  unsigned part23Length0b, part23Length0bTruncation;  unsigned part23Length1a, part23Length1aTruncation;  unsigned part23Length1b, part23Length1bTruncation;  unsigned numAduBits    = updateSideInfoSizes(sideInfo, outFr.isMPEG2,			  fromPtr, 8*desiredOutAduSize,			  part23Length0a, part23Length0aTruncation,			  part23Length0b, part23Length0bTruncation,			  part23Length1a, part23Length1aTruncation,			  part23Length1b, part23Length1bTruncation);#ifdef DEBUGfprintf(stderr, "shrinkage %d->%d [(%d,%d),(%d,%d)] (trunc: [(%d,%d),(%d,%d)]) {%d}\n", inAduSize, (numAduBits+7)/8,	      part23Length0a, part23Length0b, part23Length1a, part23Length1b,	      part23Length0aTruncation, part23Length0bTruncation,	      part23Length1aTruncation, part23Length1bTruncation,	      maxOutAduSize);#endif unsigned actualOutAduSize = (numAduBits+7)/8; // Give the new ADU an appropriate 'backpointer': assignADUBackpointer(outFr, actualOutAduSize, sideInfo, availableBytesForBackpointer); ///// Now output the new ADU: // 4-byte header outputHeader(toPtr, hdr); toPtr += 4; // side info PutMP3SideInfoIntoFrame(sideInfo, outFr, toPtr); toPtr += outFr.sideInfoSize; // 'main data', using the new lengths unsigned toBitOffset = 0; unsigned fromBitOffset = 0;  /* rebuild portion 0a: */ memmove(toPtr, fromPtr, (part23Length0a+7)/8); toBitOffset += part23Length0a; fromBitOffset += part23Length0a + part23Length0aTruncation;  /* rebuild portion 0b: */ shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length0b); toBitOffset += part23Length0b; fromBitOffset += part23Length0b + part23Length0bTruncation;  /* rebuild portion 1a: */ shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length1a); toBitOffset += part23Length1a; fromBitOffset += part23Length1a + part23Length1aTruncation;  /* rebuild portion 1b: */ shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length1b); toBitOffset += part23Length1b; /* zero out any remaining bits (probably unnecessary, but...) */ unsigned char const zero = '\0'; shiftBits(toPtr, toBitOffset, &zero, 0,	   actualOutAduSize*8 - numAduBits); return 4 + outFr.sideInfoSize + actualOutAduSize;}

⌨️ 快捷键说明

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