Browse code

Add rc_stat2 to ffv1 this will be needed for finding good initial contexts in 2 pass mode.

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

Michael Niedermayer authored on 2010/10/27 08:01:07
Showing 1 changed files
... ...
@@ -233,6 +233,7 @@ typedef struct FFV1Context{
233 233
     GetBitContext gb;
234 234
     PutBitContext pb;
235 235
     uint64_t rc_stat[256][2];
236
+    uint64_t (*rc_stat2[MAX_QUANT_TABLES])[32][2];
236 237
     int version;
237 238
     int width, height;
238 239
     int chroma_h_shift, chroma_v_shift;
... ...
@@ -299,13 +300,14 @@ static inline int get_context(PlaneContext *p, int_fast16_t *src, int_fast16_t *
299 299
         return p->quant_table[0][(L-LT) & 0xFF] + p->quant_table[1][(LT-T) & 0xFF] + p->quant_table[2][(T-RT) & 0xFF];
300 300
 }
301 301
 
302
-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]){
302
+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]){
303 303
     int i;
304 304
 
305 305
 #define put_rac(C,S,B) \
306 306
 do{\
307 307
     if(rc_stat){\
308 308
     rc_stat[*(S)][B]++;\
309
+        rc_stat2[(S)-state][B]++;\
309 310
     }\
310 311
     put_rac(C,S,B);\
311 312
 }while(0)
... ...
@@ -346,7 +348,7 @@ do{\
346 346
 }
347 347
 
348 348
 static void av_noinline put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
349
-    put_symbol_inline(c, state, v, is_signed, NULL);
349
+    put_symbol_inline(c, state, v, is_signed, NULL, NULL);
350 350
 }
351 351
 
352 352
 static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state, int is_signed){
... ...
@@ -495,9 +497,9 @@ static av_always_inline int encode_line(FFV1Context *s, int w, int_fast16_t *sam
495 495
 
496 496
         if(s->ac){
497 497
             if(s->flags & CODEC_FLAG_PASS1){
498
-            put_symbol_inline(c, p->state[context], diff, 1, s->rc_stat);
498
+                put_symbol_inline(c, p->state[context], diff, 1, s->rc_stat, s->rc_stat2[p->quant_table_index][context]);
499 499
             }else{
500
-                put_symbol_inline(c, p->state[context], diff, 1, NULL);
500
+                put_symbol_inline(c, p->state[context], diff, 1, NULL, NULL);
501 501
             }
502 502
         }else{
503 503
             if(context == 0) run_mode=1;
... ...
@@ -945,8 +947,18 @@ static av_cold int encode_init(AVCodecContext *avctx)
945 945
         return -1;
946 946
 
947 947
 #define STATS_OUT_SIZE 1024*30
948
-    if(avctx->flags & CODEC_FLAG_PASS1)
948
+    if(avctx->flags & CODEC_FLAG_PASS1){
949 949
     avctx->stats_out= av_mallocz(STATS_OUT_SIZE);
950
+        for(i=0; i<s->quant_table_count; i++){
951
+            for(j=0; j<s->slice_count; j++){
952
+                FFV1Context *sf= s->slice_context[j];
953
+                av_assert0(!sf->rc_stat2[i]);
954
+                sf->rc_stat2[i]= av_mallocz(s->context_count[i]*sizeof(*sf->rc_stat2[i]));
955
+                if(!sf->rc_stat2[i])
956
+                    return AVERROR(ENOMEM);
957
+            }
958
+        }
959
+    }
950 960
 
951 961
     return 0;
952 962
 }
... ...
@@ -1124,6 +1136,12 @@ static av_cold int common_end(AVCodecContext *avctx){
1124 1124
     }
1125 1125
 
1126 1126
     av_freep(&avctx->stats_out);
1127
+    for(j=0; j<s->quant_table_count; j++){
1128
+        for(i=0; i<s->slice_count; i++){
1129
+            FFV1Context *sf= s->slice_context[i];
1130
+            av_freep(&sf->rc_stat2[j]);
1131
+        }
1132
+    }
1127 1133
 
1128 1134
     return 0;
1129 1135
 }