]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/vorbis.c
Use bicubic MC (should also remove those ringing artifacts) when needed
[ffmpeg] / libavcodec / vorbis.c
index cf4801ea8ae0108f79adcf3d898c4f50192a60b7..de3688c9137cca53e03266769ec3375df7caf1bb 100644 (file)
@@ -20,6 +20,8 @@
  */
 
 #undef V_DEBUG
+//#define V_DEBUG
+//#define AV_DEBUG(...) av_log(NULL, AV_LOG_INFO, __VA_ARGS__)
 
 #include <math.h>
 
@@ -170,7 +172,8 @@ static void vorbis_free(vorbis_context *vc) {
 
     for(i=0;i<vc->floor_count;++i) {
         if(vc->floors[i].floor_type==0) {
-            av_free(vc->floors[i].data.t0.map);
+            av_free(vc->floors[i].data.t0.map[0]);
+            av_free(vc->floors[i].data.t0.map[1]);
             av_free(vc->floors[i].data.t0.book_list);
             av_free(vc->floors[i].data.t0.lsp);
         }
@@ -418,6 +421,7 @@ static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc) {
 
 static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc,
                                          vorbis_floor_data *vfu, float *vec);
+static void create_map( vorbis_context * vc, uint_fast8_t floor_number );
 static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc,
                                          vorbis_floor_data *vfu, float *vec);
 static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) {
@@ -471,7 +475,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) {
                 }
 
                 for(k=0;k<(1<<floor_setup->data.t1.class_subclasses[j]);++k) {
-                    floor_setup->data.t1.subclass_books[j][k]=get_bits(gb, 8)-1;
+                    floor_setup->data.t1.subclass_books[j][k]=(int16_t)get_bits(gb, 8)-1;
 
                     AV_DEBUG("    book %d. : %d \n", k, floor_setup->data.t1.subclass_books[j][k]);
                 }
@@ -574,6 +578,8 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) {
                 }
             }
 
+            create_map( vc, i );
+
             /* allocate mem for lsp coefficients */
             {
                 /* codebook dim is for padding if codebook dim doesn't *
@@ -740,21 +746,23 @@ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc) {
 
 // Process modes part
 
-static void create_map( vorbis_context * vc, uint_fast8_t mode_number )
+static void create_map( vorbis_context * vc, uint_fast8_t floor_number )
 {
     vorbis_floor * floors=vc->floors;
     vorbis_floor0 * vf;
     int idx;
+    int_fast8_t blockflag;
     int_fast32_t * map;
     int_fast32_t n; //TODO: could theoretically be smaller?
 
-    n=(vc->modes[mode_number].blockflag ?
-       vc->blocksize_1 : vc->blocksize_0) / 2;
-    floors[mode_number].data.t0.map=
+    for (blockflag=0;blockflag<2;++blockflag)
+    {
+    n=(blockflag ? vc->blocksize_1 : vc->blocksize_0) / 2;
+    floors[floor_number].data.t0.map[blockflag]=
         av_malloc((n+1) * sizeof(int_fast32_t)); // n+sentinel
 
-    map=floors[mode_number].data.t0.map;
-    vf=&floors[mode_number].data.t0;
+    map=floors[floor_number].data.t0.map[blockflag];
+    vf=&floors[floor_number].data.t0;
 
     for (idx=0; idx<n;++idx) {
         map[idx]=floor( BARK((vf->rate*idx)/(2.0f*n)) *
@@ -765,7 +773,8 @@ static void create_map( vorbis_context * vc, uint_fast8_t mode_number )
         }
     }
     map[n]=-1;
-    vf->map_size=n;
+    vf->map_size[blockflag]=n;
+    }
 
 #   ifdef V_DEBUG
     for(idx=0;idx<=n;++idx) {
@@ -793,8 +802,6 @@ static int vorbis_parse_setup_hdr_modes(vorbis_context *vc) {
         mode_setup->mapping=get_bits(gb, 8); //FIXME check
 
         AV_DEBUG(" %d mode: blockflag %d, windowtype %d, transformtype %d, mapping %d \n", i, mode_setup->blockflag, mode_setup->windowtype, mode_setup->transformtype, mode_setup->mapping);
-
-        if (vc->floors[i].floor_type == 0) { create_map( vc, i ); }
     }
     return 0;
 }
@@ -867,10 +874,17 @@ static int vorbis_parse_id_hdr(vorbis_context *vc){
     bl1=get_bits(gb, 4);
     vc->blocksize_0=(1<<bl0);
     vc->blocksize_1=(1<<bl1);
-    if (bl0>13 || bl0<6 || bl1>13 || bl1<6) {
+    if (bl0>13 || bl0<6 || bl1>13 || bl1<6 || bl1<bl0) {
         av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n");
         return 3;
     }
+    // output format int16
+    if (vc->blocksize_1/2 * vc->audio_channels * 2 >
+                                             AVCODEC_MAX_AUDIO_FRAME_SIZE) {
+        av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis channel count makes "
+               "output packets too large.\n");
+        return 4;
+    }
     vc->swin=vwin[bl0-6];
     vc->lwin=vwin[bl1-6];
 
@@ -991,6 +1005,7 @@ static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc,
     float * lsp=vf->lsp;
     uint_fast32_t amplitude;
     uint_fast32_t book_idx;
+    uint_fast8_t blockflag=vc->modes[vc->mode_number].blockflag;
 
     amplitude=get_bits(&vc->gb, vf->amplitude_bits);
     if (amplitude>0) {
@@ -1049,8 +1064,8 @@ static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc,
                      vf->map_size, order, wstep);
 
             i=0;
-            while(i<vf->map_size) {
-                int j, iter_cond=vf->map[i];
+            while(i<vf->map_size[blockflag]) {
+                int j, iter_cond=vf->map[blockflag][i];
                 float p=0.5f;
                 float q=0.5f;
                 float two_cos_w=2.0f*cos(wstep*iter_cond); // needed all times
@@ -1082,7 +1097,7 @@ static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc,
                 }
 
                 /* fill vector */
-                do { vec[i]=q; ++i; }while(vf->map[i]==iter_cond);
+                do { vec[i]=q; ++i; }while(vf->map[blockflag][i]==iter_cond);
             }
         }
     }
@@ -1339,12 +1354,14 @@ static int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr, uint_fa
 
                         AV_DEBUG("Classword: %d \n", temp);
 
-                        assert(vr->classifications > 1 && vr->classifications<256 && temp<=65536); //needed for inverse[]
+                        assert(vr->classifications > 1 && temp<=65536); //needed for inverse[]
                         for(i=0;i<c_p_c;++i) {
                             uint_fast32_t temp2;
 
                             temp2=(((uint_fast64_t)temp) * inverse[vr->classifications])>>32;
-                            classifs[j_times_ptns_to_read+partition_count+c_p_c-1-i]=temp-temp2*vr->classifications;
+                            if (partition_count+c_p_c-1-i < ptns_to_read) {
+                                classifs[j_times_ptns_to_read+partition_count+c_p_c-1-i]=temp-temp2*vr->classifications;
+                            }
                             temp=temp2;
                         }
                     }
@@ -1456,6 +1473,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) {
     } else {
         mode_number=get_bits(gb, ilog(vc->mode_count-1));
     }
+    vc->mode_number=mode_number;
     mapping=&vc->mappings[vc->modes[mode_number].mapping];
 
     AV_DEBUG(" Mode number: %d , mapping: %d , blocktype %d \n", mode_number, vc->modes[mode_number].mapping, vc->modes[mode_number].blockflag);