liveMedia/MP3InternalsHuffman.hh File Reference

#include "MP3Internals.hh"

Include dependency graph for MP3InternalsHuffman.hh:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

class  MP3HuffmanEncodingInfo

Defines

#define SSLIMIT   18
#define BYTES_PER_SAMPLE_VALUE   1

Functions

void 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)
void MP3HuffmanDecode (MP3SideInfo::gr_info_s_t *gr, Boolean isMPEG2, unsigned char const *fromBasePtr, unsigned fromBitOffset, unsigned fromLength, unsigned &scaleFactorsLength, MP3HuffmanEncodingInfo &hei)

Variables

unsigned char huffdec []


Define Documentation

#define BYTES_PER_SAMPLE_VALUE   1

Definition at line 71 of file MP3InternalsHuffman.hh.

#define SSLIMIT   18

Definition at line 40 of file MP3InternalsHuffman.hh.

Referenced by MP3HuffmanEncodingInfo::MP3HuffmanEncodingInfo().


Function Documentation

void MP3HuffmanDecode ( MP3SideInfo::gr_info_s_t gr,
Boolean  isMPEG2,
unsigned char const *  fromBasePtr,
unsigned  fromBitOffset,
unsigned  fromLength,
unsigned &  scaleFactorsLength,
MP3HuffmanEncodingInfo hei 
)

Definition at line 541 of file MP3InternalsHuffman.cpp.

References MP3HuffmanEncodingInfo::allBitOffsets, MP3SideInfo::gr_info_s::big_values, BitVector::curBitIndex(), MP3HuffmanEncodingInfo::decodedValues, getScaleFactorsLength(), if(), initialize_huffman(), NULL, MP3HuffmanEncodingInfo::numSamples, MP3HuffmanEncodingInfo::reg1Start, MP3HuffmanEncodingInfo::reg2Start, MP3SideInfo::gr_info_s::region1start, MP3SideInfo::gr_info_s::region2start, rsf_ht, rsf_huffman_decoder(), BitVector::skipBits(), and MP3SideInfo::gr_info_s::table_select.

Referenced by updateSideInfoForHuffman().

00545                                                    {
00546    unsigned i;
00547    int x, y, v, w;
00548    struct huffcodetab *h;
00549    BitVector bv((unsigned char*)fromBasePtr, fromBitOffset, fromLength);
00550 
00551    /* Compute the size of the scale factors (& also advance bv): */
00552    scaleFactorsLength = getScaleFactorsLength(gr, isMPEG2);
00553    bv.skipBits(scaleFactorsLength);
00554 
00555    initialize_huffman();
00556 
00557    hei.reg1Start = hei.reg2Start = hei.numSamples = 0;
00558 
00559    /* Read bigvalues area. */
00560    if (gr->big_values < gr->region1start + gr->region2start) {
00561      gr->big_values = gr->region1start + gr->region2start; /* sanity check */
00562    }
00563    for (i = 0; i < gr->big_values; ++i) {
00564      if (i < gr->region1start) {
00565        /* in region 0 */
00566        h = &rsf_ht[gr->table_select[0]];
00567      } else if (i < gr->region2start) {
00568        /* in region 1 */
00569        h = &rsf_ht[gr->table_select[1]];
00570        if (hei.reg1Start == 0) {
00571          hei.reg1Start = bv.curBitIndex();
00572        }
00573      } else {
00574        /* in region 2 */
00575        h = &rsf_ht[gr->table_select[2]];
00576        if (hei.reg2Start == 0) {
00577          hei.reg2Start = bv.curBitIndex();
00578        }
00579      }
00580 
00581      hei.allBitOffsets[i] = bv.curBitIndex();
00582      rsf_huffman_decoder(bv, h, &x, &y, &v, &w);
00583      if (hei.decodedValues != NULL) {
00584        // Record the decoded values:
00585        unsigned* ptr = &hei.decodedValues[4*i];
00586        ptr[0] = x; ptr[1] = y; ptr[2] = v; ptr[3] = w;
00587      }
00588    }
00589    hei.bigvalStart = bv.curBitIndex();
00590 
00591    /* Read count1 area. */
00592    h = &rsf_ht[gr->count1table_select+32];
00593    while (bv.curBitIndex() < bv.totNumBits() &&  i < SSLIMIT*SBLIMIT) {
00594      hei.allBitOffsets[i] = bv.curBitIndex();
00595      rsf_huffman_decoder(bv, h, &x, &y, &v, &w);
00596      if (hei.decodedValues != NULL) {
00597        // Record the decoded values:
00598        unsigned* ptr = &hei.decodedValues[4*i];
00599        ptr[0] = x; ptr[1] = y; ptr[2] = v; ptr[3] = w;
00600      }
00601      ++i;
00602    }
00603 
00604    hei.allBitOffsets[i] = bv.curBitIndex();
00605    hei.numSamples = i;
00606 }

void 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 
)

Definition at line 45 of file MP3InternalsHuffman.cpp.

References MP3HuffmanEncodingInfo::allBitOffsets, MP3SideInfo::gr_info_s::big_values, MP3HuffmanEncodingInfo::bigvalStart, MP3SideInfo::ch, debugCount, MP3SideInfo::gr, MP3HuffmanDecode(), MP3HuffmanEncodingInfo::numSamples, MP3SideInfo::gr_info_s::part2_3_length, MP3HuffmanEncodingInfo::reg1Start, and MP3HuffmanEncodingInfo::reg2Start.

Referenced by updateSideInfoSizes().

00055                                                                   {
00056   int i, j;
00057   unsigned sfLength, origTotABsize, adjustment;
00058   MP3SideInfo::gr_info_s_t* gr;
00059 
00060   /* First, Huffman-decode each part of the segment's main data,
00061      to see at which bit-boundaries the samples appear:
00062    */
00063   MP3HuffmanEncodingInfo hei;
00064 
00065   ++debugCount;
00066 #ifdef DEBUG
00067   fprintf(stderr, "usifh-start: p23L0: %d, p23L1: %d\n", p23L0, p23L1);
00068 #endif
00069 
00070   /* Process granule 0 */
00071   {
00072     gr = &(sideInfo.ch[0].gr[0]);
00073     origTotABsize = gr->part2_3_length;
00074 
00075     MP3HuffmanDecode(gr, isMPEG2, mainDataPtr, 0, origTotABsize, sfLength, hei);
00076 
00077     /* Begin by computing new sizes for parts a & b (& their truncations) */
00078 #ifdef DEBUG
00079     fprintf(stderr, "usifh-0: %d, %d:%d, %d:%d, %d:%d, %d:%d, %d:%d\n",
00080             hei.numSamples,
00081             sfLength/8, sfLength%8,
00082             hei.reg1Start/8, hei.reg1Start%8,
00083             hei.reg2Start/8, hei.reg2Start%8,
00084             hei.bigvalStart/8, hei.bigvalStart%8,
00085             origTotABsize/8, origTotABsize%8);
00086 #endif
00087     if (p23L0 < sfLength) {
00088       /* We can't use this, so give it all to the next granule: */
00089       p23L1 += p23L0;
00090       p23L0 = 0;
00091     }
00092 
00093     part23Length0a = hei.bigvalStart;
00094     part23Length0b = origTotABsize - hei.bigvalStart;
00095     part23Length0aTruncation = part23Length0bTruncation = 0;
00096     if (origTotABsize > p23L0) {
00097       /* We need to shorten one or both of fields a & b */
00098       unsigned truncation = origTotABsize - p23L0;
00099 #ifdef TRUNC_FAIRLY
00100       part23Length0aTruncation  = (truncation*(part23Length0a-sfLength))
00101                                   /(origTotABsize-sfLength);
00102       part23Length0bTruncation = truncation - part23Length0aTruncation;
00103 #endif
00104 #ifdef TRUNC_FAVORa
00105       part23Length0bTruncation
00106         = (truncation > part23Length0b) ? part23Length0b : truncation;
00107       part23Length0aTruncation = truncation - part23Length0bTruncation;
00108 #endif
00109 #ifdef TRUNC_FAVORb
00110       part23Length0aTruncation  = (truncation > part23Length0a-sfLength)
00111         ? (part23Length0a-sfLength) : truncation;
00112       part23Length0bTruncation = truncation - part23Length0aTruncation;
00113 #endif
00114     }
00115     /* ASSERT:  part23Length0xTruncation <= part23Length0x */
00116     part23Length0a -= part23Length0aTruncation;
00117     part23Length0b -= part23Length0bTruncation;
00118 #ifdef DEBUG
00119     fprintf(stderr, "usifh-0: interim sizes: %d (%d), %d (%d)\n",
00120             part23Length0a, part23Length0aTruncation,
00121             part23Length0b, part23Length0bTruncation);
00122 #endif
00123 
00124     /* Adjust these new lengths so they end on sample bit boundaries: */
00125     for (i = 0; i < (int)hei.numSamples; ++i) {
00126       if (hei.allBitOffsets[i] == part23Length0a) break;
00127       else if (hei.allBitOffsets[i] > part23Length0a) {--i; break;}
00128     }
00129     if (i < 0) { /* should happen only if we couldn't fit sfLength */
00130       i = 0; adjustment = 0;
00131     } else {
00132       adjustment = part23Length0a - hei.allBitOffsets[i];
00133     }
00134 #ifdef DEBUG
00135     fprintf(stderr, "%d usifh-0: adjustment 1: %d\n", debugCount, adjustment);
00136 #endif
00137     part23Length0a -= adjustment;
00138     part23Length0aTruncation += adjustment;
00139     /* Assign the bits we just shaved to field b and granule 1: */
00140     if (part23Length0bTruncation < adjustment) {
00141       p23L1 += (adjustment - part23Length0bTruncation);
00142       adjustment = part23Length0bTruncation;
00143     }
00144     part23Length0b += adjustment;
00145     part23Length0bTruncation -= adjustment;
00146     for (j = i; j < (int)hei.numSamples; ++j) {
00147       if (hei.allBitOffsets[j]
00148           == part23Length0a + part23Length0aTruncation + part23Length0b)
00149         break;
00150       else if (hei.allBitOffsets[j]
00151           > part23Length0a + part23Length0aTruncation + part23Length0b)
00152         {--j; break;}
00153     }
00154     if (j < 0) { /* should happen only if we couldn't fit sfLength */
00155       j = 0; adjustment = 0;
00156     } else {
00157       adjustment = part23Length0a+part23Length0aTruncation+part23Length0b
00158                    - hei.allBitOffsets[j];
00159     }
00160 #ifdef DEBUG
00161     fprintf(stderr, "%d usifh-0: adjustment 2: %d\n", debugCount, adjustment);
00162 #endif
00163     if (adjustment > part23Length0b) adjustment = part23Length0b; /*sanity*/
00164     part23Length0b -= adjustment;
00165     part23Length0bTruncation += adjustment;
00166     /* Assign the bits we just shaved to granule 1 */
00167     p23L1 += adjustment;
00168 
00169     if (part23Length0aTruncation > 0) {
00170       /* Change the granule's 'big_values' field to reflect the truncation */
00171       gr->big_values = i;
00172     }
00173   }
00174 
00175   /* Process granule 1 (MPEG-1 only) */
00176 
00177   if (isMPEG2) {
00178     part23Length1a = part23Length1b = 0;
00179     part23Length1aTruncation = part23Length1bTruncation = 0;
00180   } else {
00181     unsigned granule1Offset
00182       = origTotABsize + sideInfo.ch[1].gr[0].part2_3_length;
00183 
00184     gr = &(sideInfo.ch[0].gr[1]);
00185     origTotABsize = gr->part2_3_length;
00186 
00187     MP3HuffmanDecode(gr, isMPEG2, mainDataPtr, granule1Offset,
00188                      origTotABsize, sfLength, hei);
00189 
00190     /* Begin by computing new sizes for parts a & b (& their truncations) */
00191 #ifdef DEBUG
00192     fprintf(stderr, "usifh-1: %d, %d:%d, %d:%d, %d:%d, %d:%d, %d:%d\n",
00193             hei.numSamples,
00194             sfLength/8, sfLength%8,
00195             hei.reg1Start/8, hei.reg1Start%8,
00196             hei.reg2Start/8, hei.reg2Start%8,
00197             hei.bigvalStart/8, hei.bigvalStart%8,
00198             origTotABsize/8, origTotABsize%8);
00199 #endif
00200     if (p23L1 < sfLength) {
00201       /* We can't use this, so give up on this granule: */
00202       p23L1 = 0;
00203     }
00204 
00205     part23Length1a = hei.bigvalStart;
00206     part23Length1b = origTotABsize - hei.bigvalStart;
00207     part23Length1aTruncation = part23Length1bTruncation = 0;
00208     if (origTotABsize > p23L1) {
00209       /* We need to shorten one or both of fields a & b */
00210       unsigned truncation = origTotABsize - p23L1;
00211 #ifdef TRUNC_FAIRLY
00212       part23Length1aTruncation  = (truncation*(part23Length1a-sfLength))
00213                                   /(origTotABsize-sfLength);
00214       part23Length1bTruncation = truncation - part23Length1aTruncation;
00215 #endif
00216 #ifdef TRUNC_FAVORa
00217       part23Length1bTruncation
00218         = (truncation > part23Length1b) ? part23Length1b : truncation;
00219       part23Length1aTruncation = truncation - part23Length1bTruncation;
00220 #endif
00221 #ifdef TRUNC_FAVORb
00222       part23Length1aTruncation  = (truncation > part23Length1a-sfLength)
00223         ? (part23Length1a-sfLength) : truncation;
00224       part23Length1bTruncation = truncation - part23Length1aTruncation;
00225 #endif
00226     }
00227     /* ASSERT:  part23Length1xTruncation <= part23Length1x */
00228     part23Length1a -= part23Length1aTruncation;
00229     part23Length1b -= part23Length1bTruncation;
00230 #ifdef DEBUG
00231     fprintf(stderr, "usifh-1: interim sizes: %d (%d), %d (%d)\n",
00232             part23Length1a, part23Length1aTruncation,
00233             part23Length1b, part23Length1bTruncation);
00234 #endif
00235 
00236     /* Adjust these new lengths so they end on sample bit boundaries: */
00237     for (i = 0; i < (int)hei.numSamples; ++i) {
00238       if (hei.allBitOffsets[i] == part23Length1a) break;
00239       else if (hei.allBitOffsets[i] > part23Length1a) {--i; break;}
00240     }
00241     if (i < 0) { /* should happen only if we couldn't fit sfLength */
00242       i = 0; adjustment = 0;
00243     } else {
00244       adjustment = part23Length1a - hei.allBitOffsets[i];
00245     }
00246 #ifdef DEBUG
00247     fprintf(stderr, "%d usifh-1: adjustment 0: %d\n", debugCount, adjustment);
00248 #endif
00249     part23Length1a -= adjustment;
00250     part23Length1aTruncation += adjustment;
00251     /* Assign the bits we just shaved to field b: */
00252     if (part23Length1bTruncation < adjustment) {
00253       adjustment = part23Length1bTruncation;
00254     }
00255     part23Length1b += adjustment;
00256     part23Length1bTruncation -= adjustment;
00257     for (j = i; j < (int)hei.numSamples; ++j) {
00258       if (hei.allBitOffsets[j]
00259           == part23Length1a + part23Length1aTruncation + part23Length1b)
00260         break;
00261       else if (hei.allBitOffsets[j]
00262           > part23Length1a + part23Length1aTruncation + part23Length1b)
00263         {--j; break;}
00264     }
00265     if (j < 0) { /* should happen only if we couldn't fit sfLength */
00266       j = 0; adjustment = 0;
00267     } else {
00268       adjustment = part23Length1a+part23Length1aTruncation+part23Length1b
00269                    - hei.allBitOffsets[j];
00270     }
00271 #ifdef DEBUG
00272     fprintf(stderr, "%d usifh-1: adjustment 1: %d\n", debugCount, adjustment);
00273 #endif
00274     if (adjustment > part23Length1b) adjustment = part23Length1b; /*sanity*/
00275     part23Length1b -= adjustment;
00276     part23Length1bTruncation += adjustment;
00277 
00278     if (part23Length1aTruncation > 0) {
00279       /* Change the granule's 'big_values' field to reflect the truncation */
00280       gr->big_values = i;
00281     }
00282   }
00283 #ifdef DEBUG
00284   fprintf(stderr, "usifh-end, new vals: %d (%d), %d (%d), %d (%d), %d (%d)\n",
00285           part23Length0a, part23Length0aTruncation,
00286           part23Length0b, part23Length0bTruncation,
00287           part23Length1a, part23Length1aTruncation,
00288           part23Length1b, part23Length1bTruncation);
00289 #endif
00290 }


Variable Documentation

unsigned char huffdec[]

Definition at line 23 of file MP3InternalsHuffmanTable.cpp.

Referenced by initialize_huffman().


Generated on Mon Apr 29 13:30:21 2013 for live by  doxygen 1.5.2