liveMedia/MP3Internals.cpp

Go to the documentation of this file.
00001 /**********
00002 This library is free software; you can redistribute it and/or modify it under
00003 the terms of the GNU Lesser General Public License as published by the
00004 Free Software Foundation; either version 2.1 of the License, or (at your
00005 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
00006 
00007 This library is distributed in the hope that it will be useful, but WITHOUT
00008 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00009 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
00010 more details.
00011 
00012 You should have received a copy of the GNU Lesser General Public License
00013 along with this library; if not, write to the Free Software Foundation, Inc.,
00014 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
00015 **********/
00016 // "liveMedia"
00017 // Copyright (c) 1996-2013 Live Networks, Inc.  All rights reserved.
00018 // MP3 internal implementation details
00019 // Implementation
00020 
00021 #include "MP3InternalsHuffman.hh"
00022 
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include <stdio.h>
00026 #include <string.h>
00027 
00028 // This is crufty old code that needs to be cleaned up #####
00029 
00030 static unsigned const live_tabsel[2][3][16] = {
00031    { {32,32,64,96,128,160,192,224,256,288,320,352,384,416,448,448},
00032      {32,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,384},
00033      {32,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,320} },
00034 
00035    { {32,32,48,56,64,80,96,112,128,144,160,176,192,224,256,256},
00036      {8,8,16,24,32,40,48,56,64,80,96,112,128,144,160,160},
00037      {8,8,16,24,32,40,48,56,64,80,96,112,128,144,160,160} }
00038 };
00039 /* Note: live_tabsel[*][*][0 or 15] shouldn't occur; use dummy values there */
00040 
00041 static long const live_freqs[]
00042 = { 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000, 0 };
00043 
00044 struct bandInfoStruct {
00045   int longIdx[23];
00046   int longDiff[22];
00047   int shortIdx[14];
00048   int shortDiff[13];
00049 };
00050 
00051 static struct bandInfoStruct const bandInfo[7] = {
00052 /* MPEG 1.0 */
00053  { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576},
00054    {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158},
00055    {0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3},
00056    {4,4,4,4,6,8,10,12,14,18,22,30,56} } ,
00057 
00058  { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576},
00059    {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192},
00060    {0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3},
00061    {4,4,4,4,6,6,10,12,14,16,20,26,66} } ,
00062 
00063  { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} ,
00064    {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} ,
00065    {0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3} ,
00066    {4,4,4,4,6,8,12,16,20,26,34,42,12} }  ,
00067 
00068 /* MPEG 2.0 */
00069  { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
00070    {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
00071    {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} ,
00072    {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
00073 
00074  { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},
00075    {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } ,
00076    {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3} ,
00077    {4,4,4,6,8,10,12,14,18,24,32,44,12 } } ,
00078 
00079  { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
00080    {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 },
00081    {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3},
00082    {4,4,4,6,8,10,12,14,18,24,30,40,18 } } ,
00083 
00084 /* MPEG 2.5, wrong! table (it's just a copy of MPEG 2.0/44.1kHz) */
00085  { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
00086    {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
00087    {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} ,
00088    {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
00089 };
00090 
00091 unsigned int n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */
00092 unsigned int i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */
00093 
00094 #define MPG_MD_MONO 3
00095 
00096 
00098 
00099 MP3FrameParams::MP3FrameParams()
00100   : bv(frameBytes, 0, sizeof frameBytes) /* by default */ {
00101   oldHdr = firstHdr = 0;
00102 
00103   static Boolean doneInit = False;
00104   if (doneInit) return;
00105 
00106   int i,j,k,l;
00107 
00108   for (i=0;i<5;i++) {
00109     for (j=0;j<6;j++) {
00110       for (k=0;k<6;k++) {
00111         int n = k + j * 6 + i * 36;
00112         i_slen2[n] = i|(j<<3)|(k<<6)|(3<<12);
00113       }
00114     }
00115   }
00116   for (i=0;i<4;i++) {
00117     for (j=0;j<4;j++) {
00118       for (k=0;k<4;k++) {
00119         int n = k + j * 4 + i * 16;
00120         i_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12);
00121       }
00122     }
00123   }
00124   for (i=0;i<4;i++) {
00125     for (j=0;j<3;j++) {
00126       int n = j + i * 3;
00127       i_slen2[n+244] = i|(j<<3) | (5<<12);
00128       n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15);
00129     }
00130   }
00131 
00132   for (i=0;i<5;i++) {
00133     for (j=0;j<5;j++) {
00134       for (k=0;k<4;k++) {
00135         for (l=0;l<4;l++) {
00136           int n = l + k * 4 + j * 16 + i * 80;
00137           n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12);
00138         }
00139       }
00140     }
00141   }
00142   for (i=0;i<5;i++) {
00143     for (j=0;j<5;j++) {
00144       for (k=0;k<4;k++) {
00145         int n = k + j * 4 + i * 20;
00146         n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12);
00147       }
00148     }
00149   }
00150   doneInit = True;
00151 }
00152 
00153 MP3FrameParams::~MP3FrameParams() {
00154 }
00155 
00156 void MP3FrameParams::setParamsFromHeader() {
00157   if (hdr & (1<<20)) {
00158     isMPEG2 = (hdr & (1<<19)) ? 0x0 : 0x1;
00159     isMPEG2_5 = 0;
00160   }
00161   else {
00162     isMPEG2 = 1;
00163     isMPEG2_5 = 1;
00164   }
00165 
00166   layer = 4-((hdr>>17)&3);
00167   if (layer == 4) layer = 3; // layer==4 is not allowed
00168   bitrateIndex = ((hdr>>12)&0xf);
00169 
00170   if (isMPEG2_5) {
00171     samplingFreqIndex = ((hdr>>10)&0x3) + 6;
00172   } else {
00173     samplingFreqIndex = ((hdr>>10)&0x3) + (isMPEG2*3);
00174   }
00175 
00176   hasCRC = (hdr & 0x10000) == 0;
00177 
00178   padding   = ((hdr>>9)&0x1);
00179   extension = ((hdr>>8)&0x1);
00180   mode      = ((hdr>>6)&0x3);
00181   mode_ext  = ((hdr>>4)&0x3);
00182   copyright = ((hdr>>3)&0x1);
00183   original  = ((hdr>>2)&0x1);
00184   emphasis  = hdr & 0x3;
00185 
00186   stereo    = (mode == MPG_MD_MONO) ? 1 : 2;
00187 
00188   if (((hdr>>10)&0x3) == 0x3) {
00189 #ifdef DEBUG_ERRORS
00190     fprintf(stderr,"Stream error - hdr: 0x%08x\n", hdr);
00191 #endif
00192   }
00193 
00194   bitrate = live_tabsel[isMPEG2][layer-1][bitrateIndex];
00195   samplingFreq = live_freqs[samplingFreqIndex];
00196   isStereo = (stereo > 1);
00197   isFreeFormat = (bitrateIndex == 0);
00198   frameSize
00199     = ComputeFrameSize(bitrate, samplingFreq, padding, isMPEG2, layer);
00200   sideInfoSize = computeSideInfoSize();
00201  }
00202 
00203 unsigned MP3FrameParams::computeSideInfoSize() {
00204   unsigned size;
00205 
00206   if (isMPEG2) {
00207     size = isStereo ? 17 : 9;
00208   } else {
00209     size = isStereo ? 32 : 17;
00210   }
00211 
00212   if (hasCRC) {
00213     size += 2;
00214   }
00215 
00216   return size;
00217 }
00218 
00219 unsigned ComputeFrameSize(unsigned bitrate, unsigned samplingFreq,
00220                           Boolean usePadding, Boolean isMPEG2,
00221                           unsigned char layer) {
00222   if (samplingFreq == 0) return 0;
00223   unsigned const bitrateMultiplier = (layer == 1) ? 12000*4 : 144000;
00224   unsigned framesize;
00225 
00226   framesize = bitrate*bitrateMultiplier;
00227   framesize /= samplingFreq<<(isMPEG2 ? 1 : 0);
00228   framesize = framesize + usePadding - 4;
00229 
00230   return framesize;
00231 }
00232 
00233 #define TRUNC_FAIRLY
00234 static unsigned updateSideInfoSizes(MP3SideInfo& sideInfo, Boolean isMPEG2,
00235                                     unsigned char const* mainDataPtr,
00236                                     unsigned allowedNumBits,
00237                                     unsigned& part23Length0a,
00238                                     unsigned& part23Length0aTruncation,
00239                                     unsigned& part23Length0b,
00240                                     unsigned& part23Length0bTruncation,
00241                                     unsigned& part23Length1a,
00242                                     unsigned& part23Length1aTruncation,
00243                                     unsigned& part23Length1b,
00244                                     unsigned& part23Length1bTruncation) {
00245   unsigned p23L0, p23L1 = 0, p23L0Trunc = 0, p23L1Trunc = 0;
00246 
00247   p23L0 = sideInfo.ch[0].gr[0].part2_3_length;
00248   p23L1 = isMPEG2 ? 0 : sideInfo.ch[0].gr[1].part2_3_length;
00249 #ifdef TRUNC_ONLY0
00250   if (p23L0 < allowedNumBits)
00251     allowedNumBits = p23L0;
00252 #endif
00253 #ifdef TRUNC_ONLY1
00254   if (p23L1 < allowedNumBits)
00255     allowedNumBits = p23L1;
00256 #endif
00257   if (p23L0 + p23L1 > allowedNumBits) {
00258     /* We need to shorten one or both fields */
00259     unsigned truncation = p23L0 + p23L1 - allowedNumBits;
00260 #ifdef TRUNC_FAIRLY
00261     p23L0Trunc = (truncation*p23L0)/(p23L0 + p23L1);
00262     p23L1Trunc = truncation - p23L0Trunc;
00263 #endif
00264 #if defined(TRUNC_FAVOR0) || defined(TRUNC_ONLY0)
00265     p23L1Trunc = (truncation>p23L1) ? p23L1 : truncation;
00266     p23L0Trunc = truncation - p23L1Trunc;
00267 #endif
00268 #if defined(TRUNC_FAVOR1) || defined(TRUNC_ONLY1)
00269     p23L0Trunc = (truncation>p23L0) ? p23L0 : truncation;
00270     p23L1Trunc = truncation - p23L0Trunc;
00271 #endif
00272   }
00273 
00274   /* ASSERT: (p23L0Trunc <= p23L0) && (p23l1Trunc <= p23L1) */
00275   p23L0 -= p23L0Trunc; p23L1 -= p23L1Trunc;
00276 #ifdef DEBUG
00277   fprintf(stderr, "updateSideInfoSizes (allowed: %d): %d->%d, %d->%d\n", allowedNumBits, p23L0+p23L0Trunc, p23L0, p23L1+p23L1Trunc, p23L1);
00278 #endif
00279 
00280   // The truncations computed above are still estimates.  We need to
00281   // adjust them so that the new fields will continue to end on
00282   // Huffman-encoded sample boundaries:
00283   updateSideInfoForHuffman(sideInfo, isMPEG2, mainDataPtr,
00284                            p23L0, p23L1,
00285                            part23Length0a, part23Length0aTruncation,
00286                            part23Length0b, part23Length0bTruncation,
00287                            part23Length1a, part23Length1aTruncation,
00288                            part23Length1b, part23Length1bTruncation);
00289   p23L0 = part23Length0a + part23Length0b;
00290   p23L1 = part23Length1a + part23Length1b;
00291 
00292   sideInfo.ch[0].gr[0].part2_3_length = p23L0;
00293   sideInfo.ch[0].gr[1].part2_3_length = p23L1;
00294   part23Length0bTruncation
00295     += sideInfo.ch[1].gr[0].part2_3_length; /* allow for stereo */
00296   sideInfo.ch[1].gr[0].part2_3_length = 0; /* output mono */
00297   sideInfo.ch[1].gr[1].part2_3_length = 0; /* output mono */
00298 
00299   return p23L0 + p23L1;
00300 }
00301 
00302 
00303 Boolean GetADUInfoFromMP3Frame(unsigned char const* framePtr,
00304                                unsigned totFrameSize,
00305                                unsigned& hdr, unsigned& frameSize,
00306                                MP3SideInfo& sideInfo, unsigned& sideInfoSize,
00307                                unsigned& backpointer, unsigned& aduSize) {
00308   if (totFrameSize < 4) return False; // there's not enough data
00309 
00310   MP3FrameParams fr;
00311   fr.hdr =   ((unsigned)framePtr[0] << 24) | ((unsigned)framePtr[1] << 16)
00312            | ((unsigned)framePtr[2] << 8) | (unsigned)framePtr[3];
00313   fr.setParamsFromHeader();
00314   fr.setBytePointer(framePtr + 4, totFrameSize - 4); // skip hdr
00315 
00316   frameSize = 4 + fr.frameSize;
00317 
00318   if (fr.layer != 3) {
00319     // Special case for non-layer III frames
00320     backpointer = 0;
00321     sideInfoSize = 0;
00322     aduSize = fr.frameSize;
00323     return True;
00324   }
00325 
00326   sideInfoSize = fr.sideInfoSize;
00327   if (totFrameSize < 4 + sideInfoSize) return False; // not enough data
00328 
00329   fr.getSideInfo(sideInfo);
00330 
00331   hdr = fr.hdr;
00332   backpointer = sideInfo.main_data_begin;
00333   unsigned numBits = sideInfo.ch[0].gr[0].part2_3_length;
00334   numBits += sideInfo.ch[0].gr[1].part2_3_length;
00335   numBits += sideInfo.ch[1].gr[0].part2_3_length;
00336   numBits += sideInfo.ch[1].gr[1].part2_3_length;
00337   aduSize = (numBits+7)/8;
00338 #ifdef DEBUG
00339   fprintf(stderr, "mp3GetADUInfoFromFrame: hdr: %08x, frameSize: %d, part2_3_lengths: %d,%d,%d,%d, aduSize: %d, backpointer: %d\n", hdr, frameSize, sideInfo.ch[0].gr[0].part2_3_length, sideInfo.ch[0].gr[1].part2_3_length, sideInfo.ch[1].gr[0].part2_3_length, sideInfo.ch[1].gr[1].part2_3_length, aduSize, backpointer);
00340 #endif
00341 
00342   return True;
00343 }
00344 
00345 
00346 static void getSideInfo1(MP3FrameParams& fr, MP3SideInfo& si,
00347                          int stereo, int ms_stereo, long sfreq,
00348                          int /*single*/) {
00349    int ch, gr;
00350 #if 0
00351    int powdiff = (single == 3) ? 4 : 0;
00352 #endif
00353 
00354    /* initialize all four "part2_3_length" fields to zero: */
00355    si.ch[0].gr[0].part2_3_length = 0; si.ch[1].gr[0].part2_3_length = 0;
00356    si.ch[0].gr[1].part2_3_length = 0; si.ch[1].gr[1].part2_3_length = 0;
00357 
00358    si.main_data_begin = fr.getBits(9);
00359    if (stereo == 1)
00360      si.private_bits = fr.getBits(5);
00361    else
00362      si.private_bits = fr.getBits(3);
00363 
00364    for (ch=0; ch<stereo; ch++) {
00365        si.ch[ch].gr[0].scfsi = -1;
00366        si.ch[ch].gr[1].scfsi = fr.getBits(4);
00367    }
00368 
00369    for (gr=0; gr<2; gr++) {
00370      for (ch=0; ch<stereo; ch++) {
00371        MP3SideInfo::gr_info_s_t& gr_info = si.ch[ch].gr[gr];
00372 
00373        gr_info.part2_3_length = fr.getBits(12);
00374        gr_info.big_values = fr.getBits(9);
00375        gr_info.global_gain = fr.getBits(8);
00376 #if 0
00377        gr_info.pow2gain = gainpow2+256 - gr_info.global_gain + powdiff;
00378        if (ms_stereo) gr_info.pow2gain += 2;
00379 #endif
00380        gr_info.scalefac_compress = fr.getBits(4);
00381 /* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
00382        gr_info.window_switching_flag = fr.get1Bit();
00383        if (gr_info.window_switching_flag) {
00384          int i;
00385          gr_info.block_type = fr.getBits(2);
00386          gr_info.mixed_block_flag = fr.get1Bit();
00387          gr_info.table_select[0] = fr.getBits(5);
00388          gr_info.table_select[1] = fr.getBits(5);
00389          /*
00390           * table_select[2] not needed, because there is no region2,
00391           * but to satisfy some verifications tools we set it either.
00392           */
00393          gr_info.table_select[2] = 0;
00394          for (i=0;i<3;i++) {
00395            gr_info.subblock_gain[i] = fr.getBits(3);
00396            gr_info.full_gain[i]
00397              = gr_info.pow2gain + ((gr_info.subblock_gain[i])<<3);
00398          }
00399 
00400 #ifdef DEBUG_ERRORS
00401          if (gr_info.block_type == 0) {
00402            fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
00403          }
00404 #endif
00405          /* region_count/start parameters are implicit in this case. */
00406          gr_info.region1start = 36>>1;
00407          gr_info.region2start = 576>>1;
00408        }
00409        else
00410        {
00411          int i,r0c,r1c;
00412          for (i=0; i<3; i++) {
00413            gr_info.table_select[i] = fr.getBits(5);
00414          }
00415          r0c = gr_info.region0_count = fr.getBits(4);
00416          r1c = gr_info.region1_count = fr.getBits(3);
00417          gr_info.region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
00418          gr_info.region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
00419          gr_info.block_type = 0;
00420          gr_info.mixed_block_flag = 0;
00421        }
00422        gr_info.preflag = fr.get1Bit();
00423        gr_info.scalefac_scale = fr.get1Bit();
00424        gr_info.count1table_select = fr.get1Bit();
00425      }
00426    }
00427 }
00428 
00429 static void getSideInfo2(MP3FrameParams& fr, MP3SideInfo& si,
00430                          int stereo, int ms_stereo, long sfreq,
00431                          int /*single*/) {
00432    int ch;
00433 #if 0
00434    int powdiff = (single == 3) ? 4 : 0;
00435 #endif
00436 
00437    /* initialize all four "part2_3_length" fields to zero: */
00438    si.ch[0].gr[0].part2_3_length = 0; si.ch[1].gr[0].part2_3_length = 0;
00439    si.ch[0].gr[1].part2_3_length = 0; si.ch[1].gr[1].part2_3_length = 0;
00440 
00441    si.main_data_begin = fr.getBits(8);
00442    if (stereo == 1)
00443      si.private_bits = fr.get1Bit();
00444    else
00445      si.private_bits = fr.getBits(2);
00446 
00447    for (ch=0; ch<stereo; ch++) {
00448        MP3SideInfo::gr_info_s_t& gr_info = si.ch[ch].gr[0];
00449 
00450        gr_info.part2_3_length = fr.getBits(12);
00451        si.ch[ch].gr[1].part2_3_length = 0; /* to ensure granule 1 unused */
00452 
00453        gr_info.big_values = fr.getBits(9);
00454        gr_info.global_gain = fr.getBits(8);
00455 #if 0
00456        gr_info.pow2gain = gainpow2+256 - gr_info.global_gain + powdiff;
00457        if (ms_stereo) gr_info.pow2gain += 2;
00458 #endif
00459        gr_info.scalefac_compress = fr.getBits(9);
00460 /* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
00461        gr_info.window_switching_flag = fr.get1Bit();
00462        if (gr_info.window_switching_flag) {
00463          int i;
00464          gr_info.block_type = fr.getBits(2);
00465          gr_info.mixed_block_flag = fr.get1Bit();
00466          gr_info.table_select[0] = fr.getBits(5);
00467          gr_info.table_select[1] = fr.getBits(5);
00468          /*
00469           * table_select[2] not needed, because there is no region2,
00470           * but to satisfy some verifications tools we set it either.
00471           */
00472          gr_info.table_select[2] = 0;
00473          for (i=0;i<3;i++) {
00474            gr_info.subblock_gain[i] = fr.getBits(3);
00475            gr_info.full_gain[i]
00476              = gr_info.pow2gain + ((gr_info.subblock_gain[i])<<3);
00477          }
00478 
00479 #ifdef DEBUG_ERRORS
00480          if (gr_info.block_type == 0) {
00481            fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
00482          }
00483 #endif
00484          /* region_count/start parameters are implicit in this case. */
00485 /* check this again! */
00486          if (gr_info.block_type == 2)
00487            gr_info.region1start = 36>>1;
00488          else {
00489            gr_info.region1start = 54>>1;
00490          }
00491          gr_info.region2start = 576>>1;
00492        }
00493        else
00494        {
00495          int i,r0c,r1c;
00496          for (i=0; i<3; i++) {
00497            gr_info.table_select[i] = fr.getBits(5);
00498          }
00499          r0c = gr_info.region0_count = fr.getBits(4);
00500          r1c = gr_info.region1_count = fr.getBits(3);
00501          gr_info.region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
00502          gr_info.region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
00503          gr_info.block_type = 0;
00504          gr_info.mixed_block_flag = 0;
00505        }
00506        gr_info.scalefac_scale = fr.get1Bit();
00507        gr_info.count1table_select = fr.get1Bit();
00508    }
00509 }
00510 
00511 
00512 #define         MPG_MD_JOINT_STEREO     1
00513 
00514 void MP3FrameParams::getSideInfo(MP3SideInfo& si) {
00515   // First skip over the CRC if present:
00516   if (hasCRC) getBits(16);
00517 
00518   int single = -1;
00519   int ms_stereo;
00520   int sfreq = samplingFreqIndex;
00521 
00522   if (stereo == 1) {
00523     single = 0;
00524   }
00525 
00526   ms_stereo = (mode == MPG_MD_JOINT_STEREO) && (mode_ext & 0x2);
00527 
00528   if (isMPEG2) {
00529     getSideInfo2(*this, si, stereo, ms_stereo, sfreq, single);
00530   } else {
00531     getSideInfo1(*this, si, stereo, ms_stereo, sfreq, single);
00532   }
00533 }
00534 
00535 static void putSideInfo1(BitVector& bv,
00536                          MP3SideInfo const& si, Boolean isStereo) {
00537   int ch, gr, i;
00538   int stereo = isStereo ? 2 : 1;
00539 
00540   bv.putBits(si.main_data_begin,9);
00541   if (stereo == 1)
00542     bv.putBits(si.private_bits, 5);
00543   else
00544     bv.putBits(si.private_bits, 3);
00545 
00546   for (ch=0; ch<stereo; ch++) {
00547     bv.putBits(si.ch[ch].gr[1].scfsi, 4);
00548   }
00549 
00550   for (gr=0; gr<2; gr++) {
00551     for (ch=0; ch<stereo; ch++) {
00552       MP3SideInfo::gr_info_s_t const& gr_info = si.ch[ch].gr[gr];
00553 
00554       bv.putBits(gr_info.part2_3_length, 12);
00555       bv.putBits(gr_info.big_values, 9);
00556       bv.putBits(gr_info.global_gain, 8);
00557       bv.putBits(gr_info.scalefac_compress, 4);
00558       bv.put1Bit(gr_info.window_switching_flag);
00559       if (gr_info.window_switching_flag) {
00560         bv.putBits(gr_info.block_type, 2);
00561         bv.put1Bit(gr_info.mixed_block_flag);
00562         for (i=0; i<2; i++)
00563           bv.putBits(gr_info.table_select[i], 5);
00564         for (i=0; i<3; i++)
00565           bv.putBits(gr_info.subblock_gain[i], 3);
00566       }
00567       else {
00568         for (i=0; i<3; i++)
00569           bv.putBits(gr_info.table_select[i], 5);
00570         bv.putBits(gr_info.region0_count, 4);
00571         bv.putBits(gr_info.region1_count, 3);
00572       }
00573 
00574       bv.put1Bit(gr_info.preflag);
00575       bv.put1Bit(gr_info.scalefac_scale);
00576       bv.put1Bit(gr_info.count1table_select);
00577     }
00578   }
00579 }
00580 
00581 static void putSideInfo2(BitVector& bv,
00582                          MP3SideInfo const& si, Boolean isStereo) {
00583   int ch, i;
00584   int stereo = isStereo ? 2 : 1;
00585 
00586   bv.putBits(si.main_data_begin,8);
00587   if (stereo == 1)
00588     bv.put1Bit(si.private_bits);
00589   else
00590     bv.putBits(si.private_bits, 2);
00591 
00592   for (ch=0; ch<stereo; ch++) {
00593     MP3SideInfo::gr_info_s_t const& gr_info = si.ch[ch].gr[0];
00594 
00595     bv.putBits(gr_info.part2_3_length, 12);
00596     bv.putBits(gr_info.big_values, 9);
00597     bv.putBits(gr_info.global_gain, 8);
00598     bv.putBits(gr_info.scalefac_compress, 9);
00599     bv.put1Bit(gr_info.window_switching_flag);
00600     if (gr_info.window_switching_flag) {
00601       bv.putBits(gr_info.block_type, 2);
00602       bv.put1Bit(gr_info.mixed_block_flag);
00603       for (i=0; i<2; i++)
00604         bv.putBits(gr_info.table_select[i], 5);
00605       for (i=0; i<3; i++)
00606         bv.putBits(gr_info.subblock_gain[i], 3);
00607     }
00608     else {
00609       for (i=0; i<3; i++)
00610         bv.putBits(gr_info.table_select[i], 5);
00611       bv.putBits(gr_info.region0_count, 4);
00612       bv.putBits(gr_info.region1_count, 3);
00613     }
00614 
00615     bv.put1Bit(gr_info.scalefac_scale);
00616     bv.put1Bit(gr_info.count1table_select);
00617   }
00618 }
00619 
00620 static void PutMP3SideInfoIntoFrame(MP3SideInfo const& si,
00621                                     MP3FrameParams const& fr,
00622                                     unsigned char* framePtr) {
00623   if (fr.hasCRC) framePtr += 2; // skip CRC
00624 
00625   BitVector bv(framePtr, 0, 8*fr.sideInfoSize);
00626 
00627   if (fr.isMPEG2) {
00628     putSideInfo2(bv, si, fr.isStereo);
00629   } else {
00630     putSideInfo1(bv, si, fr.isStereo);
00631   }
00632 }
00633 
00634 
00635 Boolean ZeroOutMP3SideInfo(unsigned char* framePtr, unsigned totFrameSize,
00636                            unsigned newBackpointer) {
00637   if (totFrameSize < 4) return False; // there's not enough data
00638 
00639   MP3FrameParams fr;
00640   fr.hdr =   ((unsigned)framePtr[0] << 24) | ((unsigned)framePtr[1] << 16)
00641            | ((unsigned)framePtr[2] << 8) | (unsigned)framePtr[3];
00642   fr.setParamsFromHeader();
00643   fr.setBytePointer(framePtr + 4, totFrameSize - 4); // skip hdr
00644 
00645   if (totFrameSize < 4 + fr.sideInfoSize) return False; // not enough data
00646 
00647   MP3SideInfo si;
00648   fr.getSideInfo(si);
00649 
00650   si.main_data_begin = newBackpointer; /* backpointer */
00651   /* set all four "part2_3_length" and "big_values" fields to zero: */
00652   si.ch[0].gr[0].part2_3_length = si.ch[0].gr[0].big_values = 0;
00653   si.ch[1].gr[0].part2_3_length = si.ch[1].gr[0].big_values = 0;
00654   si.ch[0].gr[1].part2_3_length = si.ch[0].gr[1].big_values = 0;
00655   si.ch[1].gr[1].part2_3_length = si.ch[1].gr[1].big_values = 0;
00656 
00657   PutMP3SideInfoIntoFrame(si, fr, framePtr + 4);
00658 
00659   return True;
00660 }
00661 
00662 
00663 static unsigned MP3BitrateToBitrateIndex(unsigned bitrate /* in kbps */,
00664                                          Boolean isMPEG2) {
00665   for (unsigned i = 1; i < 15; ++i) {
00666     if (live_tabsel[isMPEG2][2][i] >= bitrate)
00667       return i;
00668   }
00669 
00670   // "bitrate" was larger than any possible, so return the largest possible:
00671   return 14;
00672 }
00673 
00674 static void outputHeader(unsigned char* toPtr, unsigned hdr) {
00675   toPtr[0] = (unsigned char)(hdr>>24);
00676   toPtr[1] = (unsigned char)(hdr>>16);
00677   toPtr[2] = (unsigned char)(hdr>>8);
00678   toPtr[3] = (unsigned char)(hdr);
00679 }
00680 
00681 static void assignADUBackpointer(MP3FrameParams const& fr,
00682                                  unsigned aduSize,
00683                                  MP3SideInfo& sideInfo,
00684                                  unsigned& availableBytesForBackpointer) {
00685   // Give the ADU as large a backpointer as possible:
00686   unsigned maxBackpointerSize = fr.isMPEG2 ? 255 : 511;
00687 
00688   unsigned backpointerSize = availableBytesForBackpointer;
00689   if (backpointerSize > maxBackpointerSize) {
00690     backpointerSize = maxBackpointerSize;
00691   }
00692 
00693   // Store the new backpointer now:
00694   sideInfo.main_data_begin = backpointerSize;
00695 
00696   // Figure out how many bytes are available for the *next* ADU's backpointer:
00697   availableBytesForBackpointer
00698     = backpointerSize + fr.frameSize - fr.sideInfoSize ;
00699   if (availableBytesForBackpointer < aduSize) {
00700     availableBytesForBackpointer = 0;
00701   } else {
00702     availableBytesForBackpointer -= aduSize;
00703   }
00704 }
00705 
00706 unsigned TranscodeMP3ADU(unsigned char const* fromPtr, unsigned fromSize,
00707                       unsigned toBitrate,
00708                       unsigned char* toPtr, unsigned toMaxSize,
00709                       unsigned& availableBytesForBackpointer) {
00710   // Begin by parsing the input ADU's parameters:
00711   unsigned hdr, inFrameSize, inSideInfoSize, backpointer, inAduSize;
00712   MP3SideInfo sideInfo;
00713   if (!GetADUInfoFromMP3Frame(fromPtr, fromSize,
00714                               hdr, inFrameSize, sideInfo, inSideInfoSize,
00715                               backpointer, inAduSize)) {
00716     return 0;
00717   }
00718   fromPtr += (4+inSideInfoSize); // skip to 'main data'
00719 
00720   // Alter the 4-byte MPEG header to reflect the output ADU:
00721   // (different bitrate; mono; no CRC)
00722   Boolean isMPEG2 = ((hdr&0x00080000) == 0);
00723   unsigned toBitrateIndex = MP3BitrateToBitrateIndex(toBitrate, isMPEG2);
00724   hdr &=~ 0xF000; hdr |= (toBitrateIndex<<12); // set bitrate index
00725   hdr |= 0x10200; // turn on !error-prot and padding bits
00726   hdr &=~ 0xC0; hdr |= 0xC0; // set mode to 3 (mono)
00727 
00728   // Set up the rest of the parameters of the new ADU:
00729   MP3FrameParams outFr;
00730   outFr.hdr = hdr;
00731   outFr.setParamsFromHeader();
00732 
00733   // Figure out how big to make the output ADU:
00734   unsigned inAveAduSize = inFrameSize - inSideInfoSize;
00735   unsigned outAveAduSize = outFr.frameSize - outFr.sideInfoSize;
00736   unsigned desiredOutAduSize /*=inAduSize*outAveAduSize/inAveAduSize*/
00737     = (2*inAduSize*outAveAduSize + inAveAduSize)/(2*inAveAduSize);
00738       // this rounds to the nearest integer
00739 
00740   if (toMaxSize < (4 + outFr.sideInfoSize)) return 0;
00741   unsigned maxOutAduSize = toMaxSize - (4 + outFr.sideInfoSize);
00742   if (desiredOutAduSize > maxOutAduSize) {
00743     desiredOutAduSize = maxOutAduSize;
00744   }
00745 
00746   // Figure out the new sizes of the various 'part23 lengths',
00747   // and how much they are truncated:
00748   unsigned part23Length0a, part23Length0aTruncation;
00749   unsigned part23Length0b, part23Length0bTruncation;
00750   unsigned part23Length1a, part23Length1aTruncation;
00751   unsigned part23Length1b, part23Length1bTruncation;
00752   unsigned numAduBits
00753     = updateSideInfoSizes(sideInfo, outFr.isMPEG2,
00754                           fromPtr, 8*desiredOutAduSize,
00755                           part23Length0a, part23Length0aTruncation,
00756                           part23Length0b, part23Length0bTruncation,
00757                           part23Length1a, part23Length1aTruncation,
00758                           part23Length1b, part23Length1bTruncation);
00759 #ifdef DEBUG
00760 fprintf(stderr, "shrinkage %d->%d [(%d,%d),(%d,%d)] (trunc: [(%d,%d),(%d,%d)]) {%d}\n", inAduSize, (numAduBits+7)/8,
00761               part23Length0a, part23Length0b, part23Length1a, part23Length1b,
00762               part23Length0aTruncation, part23Length0bTruncation,
00763               part23Length1aTruncation, part23Length1bTruncation,
00764               maxOutAduSize);
00765 #endif
00766  unsigned actualOutAduSize = (numAduBits+7)/8;
00767 
00768  // Give the new ADU an appropriate 'backpointer':
00769  assignADUBackpointer(outFr, actualOutAduSize, sideInfo, availableBytesForBackpointer);
00770 
00772 
00773  // 4-byte header
00774  outputHeader(toPtr, hdr); toPtr += 4;
00775 
00776  // side info
00777  PutMP3SideInfoIntoFrame(sideInfo, outFr, toPtr); toPtr += outFr.sideInfoSize;
00778 
00779  // 'main data', using the new lengths
00780  unsigned toBitOffset = 0;
00781  unsigned fromBitOffset = 0;
00782 
00783  /* rebuild portion 0a: */
00784  memmove(toPtr, fromPtr, (part23Length0a+7)/8);
00785  toBitOffset += part23Length0a;
00786  fromBitOffset += part23Length0a + part23Length0aTruncation;
00787 
00788  /* rebuild portion 0b: */
00789  shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length0b);
00790  toBitOffset += part23Length0b;
00791  fromBitOffset += part23Length0b + part23Length0bTruncation;
00792 
00793  /* rebuild portion 1a: */
00794  shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length1a);
00795  toBitOffset += part23Length1a;
00796  fromBitOffset += part23Length1a + part23Length1aTruncation;
00797 
00798  /* rebuild portion 1b: */
00799  shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length1b);
00800  toBitOffset += part23Length1b;
00801 
00802  /* zero out any remaining bits (probably unnecessary, but...) */
00803  unsigned char const zero = '\0';
00804  shiftBits(toPtr, toBitOffset, &zero, 0,
00805            actualOutAduSize*8 - numAduBits);
00806 
00807  return 4 + outFr.sideInfoSize + actualOutAduSize;
00808 }

Generated on Tue Jun 18 13:16:51 2013 for live by  doxygen 1.5.2