Browse code

Try to find a bit better initial states in ffv1 2pass. Difference in filesizes to foreman ffv1 version=2, context=1 coder=1 18637016 adv-pass2-g300.avi 18638806 adv-pass1-g300.avi 18640534 ref-pass2-g300.avi 18918214 adv-pass2-g1.avi 18982048 ref-pass2-g1.avi 21516230 adv-pass1-g1.avi

Originally committed as revision 25594 to svn://svn.ffmpeg.org/ffmpeg/trunk

Michael Niedermayer authored on 2010/10/28 21:15:47
Showing 1 changed files
... ...
@@ -302,6 +302,48 @@ static inline int get_context(PlaneContext *p, int_fast16_t *src, int_fast16_t *
302 302
         return p->quant_table[0][(L-LT) & 0xFF] + p->quant_table[1][(LT-T) & 0xFF] + p->quant_table[2][(T-RT) & 0xFF];
303 303
 }
304 304
 
305
+static void find_best_state(uint8_t best_state[256][256], const uint8_t one_state[256]){
306
+    int i,j,k,m;
307
+    double l2tab[256];
308
+
309
+    for(i=1; i<256; i++)
310
+        l2tab[i]= log2(i/256.0);
311
+
312
+    for(i=0; i<256; i++){
313
+        double best_len[256];
314
+        double p= i/256.0;
315
+
316
+        for(j=0; j<256; j++)
317
+            best_len[j]= 1<<30;
318
+
319
+        for(j=FFMAX(i-10,1); j<FFMIN(i+11,256); j++){
320
+            double occ[256]={0};
321
+            double len=0;
322
+            occ[j]=1.0;
323
+            for(k=0; k<256; k++){
324
+                double newocc[256]={0};
325
+                for(m=0; m<256; m++){
326
+                    if(occ[m]){
327
+                        len -=occ[m]*(     p *l2tab[    m]
328
+                                      + (1-p)*l2tab[256-m]);
329
+                    }
330
+                }
331
+                if(len < best_len[k]){
332
+                    best_len[k]= len;
333
+                    best_state[i][k]= j;
334
+                }
335
+                for(m=0; m<256; m++){
336
+                    if(occ[m]){
337
+                        newocc[    one_state[    m]] += occ[m]*   p ;
338
+                        newocc[256-one_state[256-m]] += occ[m]*(1-p);
339
+                    }
340
+                }
341
+                memcpy(occ, newocc, sizeof(occ));
342
+            }
343
+        }
344
+    }
345
+}
346
+
305 347
 static av_always_inline av_flatten void put_symbol_inline(RangeCoder *c, uint8_t *state, int v, int is_signed, uint64_t rc_stat[256][2], uint64_t rc_stat2[32][2]){
306 348
     int i;
307 349
 
... ...
@@ -961,6 +1003,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
961 961
     }
962 962
     if(avctx->stats_in){
963 963
         char *p= avctx->stats_in;
964
+        uint8_t best_state[256][256];
964 965
         int gob_count=0;
965 966
         char *next;
966 967
 
... ...
@@ -1002,15 +1045,16 @@ static av_cold int encode_init(AVCodecContext *avctx)
1002 1002
         }
1003 1003
         sort_stt(s, s->state_transition);
1004 1004
 
1005
+        find_best_state(best_state, s->state_transition);
1006
+
1005 1007
         for(i=0; i<s->quant_table_count; i++){
1006 1008
             for(j=0; j<s->context_count[i]; j++){
1007 1009
                 for(k=0; k<32; k++){
1008
-                    int p= 128;
1010
+                    double p= 128;
1009 1011
                     if(s->rc_stat2[i][j][k][0]+s->rc_stat2[i][j][k][1]){
1010
-                        p=256*s->rc_stat2[i][j][k][1] / (s->rc_stat2[i][j][k][0]+s->rc_stat2[i][j][k][1]);
1012
+                        p=256.0*s->rc_stat2[i][j][k][1] / (s->rc_stat2[i][j][k][0]+s->rc_stat2[i][j][k][1]);
1011 1013
                     }
1012
-                    p= av_clip(p, 1, 254);
1013
-                    s->initial_states[i][j][k]= p;
1014
+                    s->initial_states[i][j][k]= best_state[av_clip(round(p), 1, 255)][av_clip((s->rc_stat2[i][j][k][0]+s->rc_stat2[i][j][k][1])/gob_count, 0, 255)];
1014 1015
                 }
1015 1016
             }
1016 1017
         }