• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/vorbis.c

Go to the documentation of this file.
00001 
00023 #undef V_DEBUG
00024 //#define V_DEBUG
00025 
00026 #define ALT_BITSTREAM_READER_LE
00027 #include "avcodec.h"
00028 #include "get_bits.h"
00029 
00030 #include "vorbis.h"
00031 
00032 
00033 /* Helper functions */
00034 
00035 // x^(1/n)
00036 unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n)
00037 {
00038     unsigned int ret = 0, i, j;
00039 
00040     do {
00041         ++ret;
00042         for (i = 0, j = ret; i < n - 1; i++)
00043             j *= ret;
00044     } while (j <= x);
00045 
00046     return ret - 1;
00047 }
00048 
00049 // Generate vlc codes from vorbis huffman code lengths
00050 
00051 // the two bits[p] > 32 checks should be redundant, all calling code should
00052 // already ensure that, but since it allows overwriting the stack it seems
00053 // reasonable to check redundantly.
00054 int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, uint_fast32_t num)
00055 {
00056     uint_fast32_t exit_at_level[33] = {
00057         404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00058           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
00059 
00060     uint_fast8_t i, j;
00061     uint_fast32_t code, p;
00062 
00063 #ifdef V_DEBUG
00064     GetBitContext gb;
00065 #endif
00066 
00067     for (p = 0; (bits[p] == 0) && (p < num); ++p)
00068         ;
00069     if (p == num) {
00070 //        av_log(vc->avccontext, AV_LOG_INFO, "An empty codebook. Heh?! \n");
00071         return 0;
00072     }
00073 
00074     codes[p] = 0;
00075     if (bits[p] > 32)
00076         return 1;
00077     for (i = 0; i < bits[p]; ++i)
00078         exit_at_level[i+1] = 1 << i;
00079 
00080 #ifdef V_DEBUG
00081     av_log(NULL, AV_LOG_INFO, " %d. of %d code len %d code %d - ", p, num, bits[p], codes[p]);
00082     init_get_bits(&gb, (uint_fast8_t *)&codes[p], bits[p]);
00083     for (i = 0; i < bits[p]; ++i)
00084         av_log(NULL, AV_LOG_INFO, "%s", get_bits1(&gb) ? "1" : "0");
00085     av_log(NULL, AV_LOG_INFO, "\n");
00086 #endif
00087 
00088     ++p;
00089 
00090     for (; p < num; ++p) {
00091         if (bits[p] > 32)
00092              return 1;
00093         if (bits[p] == 0)
00094              continue;
00095         // find corresponding exit(node which the tree can grow further from)
00096         for (i = bits[p]; i > 0; --i)
00097             if (exit_at_level[i])
00098                 break;
00099         if (!i) // overspecified tree
00100              return 1;
00101         code = exit_at_level[i];
00102         exit_at_level[i] = 0;
00103         // construct code (append 0s to end) and introduce new exits
00104         for (j = i + 1 ;j <= bits[p]; ++j)
00105             exit_at_level[j] = code + (1 << (j - 1));
00106         codes[p] = code;
00107 
00108 #ifdef V_DEBUG
00109         av_log(NULL, AV_LOG_INFO, " %d. code len %d code %d - ", p, bits[p], codes[p]);
00110         init_get_bits(&gb, (uint_fast8_t *)&codes[p], bits[p]);
00111         for (i = 0; i < bits[p]; ++i)
00112             av_log(NULL, AV_LOG_INFO, "%s", get_bits1(&gb) ? "1" : "0");
00113         av_log(NULL, AV_LOG_INFO, "\n");
00114 #endif
00115 
00116     }
00117 
00118     //no exits should be left (underspecified tree - ie. unused valid vlcs - not allowed by SPEC)
00119     for (p = 1; p < 33; p++)
00120         if (exit_at_level[p])
00121             return 1;
00122 
00123     return 0;
00124 }
00125 
00126 void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values)
00127 {
00128     int i;
00129     list[0].sort = 0;
00130     list[1].sort = 1;
00131     for (i = 2; i < values; i++) {
00132         int j;
00133         list[i].low  = 0;
00134         list[i].high = 1;
00135         list[i].sort = i;
00136         for (j = 2; j < i; j++) {
00137             int tmp = list[j].x;
00138             if (tmp < list[i].x) {
00139                 if (tmp > list[list[i].low].x)
00140                     list[i].low  =  j;
00141             } else {
00142                 if (tmp < list[list[i].high].x)
00143                     list[i].high = j;
00144             }
00145         }
00146     }
00147     for (i = 0; i < values - 1; i++) {
00148         int j;
00149         for (j = i + 1; j < values; j++) {
00150             if (list[list[i].sort].x > list[list[j].sort].x) {
00151                 int tmp = list[i].sort;
00152                 list[i].sort = list[j].sort;
00153                 list[j].sort = tmp;
00154             }
00155         }
00156     }
00157 }
00158 
00159 static inline void render_line_unrolled(intptr_t x, intptr_t y, int x1,
00160                                         intptr_t sy, int ady, int adx,
00161                                         float *buf)
00162 {
00163     int err = -adx;
00164     x -= x1 - 1;
00165     buf += x1 - 1;
00166     while (++x < 0) {
00167         err += ady;
00168         if (err >= 0) {
00169             err += ady - adx;
00170             y   += sy;
00171             buf[x++] = ff_vorbis_floor1_inverse_db_table[y];
00172         }
00173         buf[x] = ff_vorbis_floor1_inverse_db_table[y];
00174     }
00175     if (x <= 0) {
00176         if (err + ady >= 0)
00177             y += sy;
00178         buf[x] = ff_vorbis_floor1_inverse_db_table[y];
00179     }
00180 }
00181 
00182 static void render_line(int x0, int y0, int x1, int y1, float *buf)
00183 {
00184     int dy  = y1 - y0;
00185     int adx = x1 - x0;
00186     int ady = FFABS(dy);
00187     int sy  = dy < 0 ? -1 : 1;
00188     buf[x0] = ff_vorbis_floor1_inverse_db_table[y0];
00189     if (ady*2 <= adx) { // optimized common case
00190         render_line_unrolled(x0, y0, x1, sy, ady, adx, buf);
00191     } else {
00192         int base = dy / adx;
00193         int x    = x0;
00194         int y    = y0;
00195         int err  = -adx;
00196         ady -= FFABS(base) * adx;
00197         while (++x < x1) {
00198             y += base;
00199             err += ady;
00200             if (err >= 0) {
00201                 err -= adx;
00202                 y   += sy;
00203             }
00204             buf[x] = ff_vorbis_floor1_inverse_db_table[y];
00205         }
00206     }
00207 }
00208 
00209 void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values,
00210                                   uint_fast16_t *y_list, int *flag,
00211                                   int multiplier, float *out, int samples)
00212 {
00213     int lx, ly, i;
00214     lx = 0;
00215     ly = y_list[0] * multiplier;
00216     for (i = 1; i < values; i++) {
00217         int pos = list[i].sort;
00218         if (flag[pos]) {
00219             int x1 = list[pos].x;
00220             int y1 = y_list[pos] * multiplier;
00221             if (lx < samples)
00222                 render_line(lx, ly, FFMIN(x1,samples), y1, out);
00223             lx = x1;
00224             ly = y1;
00225         }
00226         if (lx >= samples)
00227             break;
00228     }
00229     if (lx < samples)
00230         render_line(lx, ly, samples, ly, out);
00231 }

Generated on Fri Sep 16 2011 17:17:45 for FFmpeg by  doxygen 1.7.1