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

📄 mp3internals.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
         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;}#if 0static unsigned MP3BitrateToBitrateIndex(unsigned bitrate /* in kbps */,					 Boolean isMPEG2) {  for (unsigned i = 1; i < 15; ++i) {    if (tabsel_123[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;}#endif

⌨️ 快捷键说明

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