Make 1pass statistic collection in ffv1 put_symbol_inline() conditional to avoid...
[ffmpeg.git] / libavcodec / ffv1.c
index 825b926..0f1433b 100644 (file)
@@ -218,6 +218,7 @@ typedef struct VlcState{
 
 typedef struct PlaneContext{
     int16_t quant_table[MAX_CONTEXT_INPUTS][256];
+    int quant_table_index;
     int context_count;
     uint8_t (*state)[CONTEXT_SIZE];
     VlcState *vlc_state;
@@ -298,12 +299,14 @@ static inline int get_context(PlaneContext *p, int_fast16_t *src, int_fast16_t *
         return p->quant_table[0][(L-LT) & 0xFF] + p->quant_table[1][(LT-T) & 0xFF] + p->quant_table[2][(T-RT) & 0xFF];
 }
 
-static inline void put_symbol_inline(RangeCoder *c, uint8_t *state, int v, int is_signed, uint64_t rc_stat[256][2]){
+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]){
     int i;
 
 #define put_rac(C,S,B) \
 do{\
+    if(rc_stat){\
     rc_stat[*(S)][B]++;\
+    }\
     put_rac(C,S,B);\
 }while(0)
 
@@ -343,8 +346,7 @@ do{\
 }
 
 static void av_noinline put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
-    uint64_t rc_stat[256][2]; //we dont bother counting header bits.
-    put_symbol_inline(c, state, v, is_signed, rc_stat);
+    put_symbol_inline(c, state, v, is_signed, NULL);
 }
 
 static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state, int is_signed){
@@ -458,7 +460,7 @@ static inline int get_vlc_symbol(GetBitContext *gb, VlcState * const state, int
 }
 
 #if CONFIG_FFV1_ENCODER
-static inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){
+static av_always_inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){
     PlaneContext * const p= &s->plane[plane_index];
     RangeCoder * const c= &s->c;
     int x;
@@ -492,7 +494,11 @@ static inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], in
         diff= fold(diff, bits);
 
         if(s->ac){
+            if(s->flags & CODEC_FLAG_PASS1){
             put_symbol_inline(c, p->state[context], diff, 1, s->rc_stat);
+            }else{
+                put_symbol_inline(c, p->state[context], diff, 1, NULL);
+            }
         }else{
             if(context == 0) run_mode=1;
 
@@ -658,8 +664,10 @@ static void write_header(FFV1Context *f){
             put_symbol(c, state, (fs->slice_y     +1)*f->num_v_slices / f->height  , 0);
             put_symbol(c, state, (fs->slice_width +1)*f->num_h_slices / f->width -1, 0);
             put_symbol(c, state, (fs->slice_height+1)*f->num_v_slices / f->height-1, 0);
-            for(j=0; j<f->plane_count; j++)
-            put_symbol(c, state, f->avctx->context_model, 0);
+            for(j=0; j<f->plane_count; j++){
+                put_symbol(c, state, f->plane[j].quant_table_index, 0);
+                av_assert0(f->plane[j].quant_table_index == f->avctx->context_model);
+            }
         }
     }
 }
@@ -860,17 +868,16 @@ static av_cold int encode_init(AVCodecContext *avctx)
             s->quant_tables[1][4][i]= 5*5*11*11*quant5_10bit[i];
         }
     }
+    s->context_count[0]= (11*11*11+1)/2;
+    s->context_count[1]= (11*11*5*5*5+1)/2;
     memcpy(s->quant_table, s->quant_tables[avctx->context_model], sizeof(s->quant_table));
 
     for(i=0; i<s->plane_count; i++){
         PlaneContext * const p= &s->plane[i];
 
         memcpy(p->quant_table, s->quant_table, sizeof(p->quant_table));
-        if(avctx->context_model==0){
-            p->context_count= (11*11*11+1)/2;
-        }else{
-            p->context_count= (11*11*5*5*5+1)/2;
-        }
+        p->quant_table_index= avctx->context_model;
+        p->context_count= s->context_count[p->quant_table_index];
     }
 
     avctx->coded_frame= &s->picture;
@@ -1468,6 +1475,7 @@ static int read_header(FFV1Context *f){
                     av_log(f->avctx, AV_LOG_ERROR, "quant_table_index out of range\n");
                     return -1;
                 }
+                p->quant_table_index= idx;
                 memcpy(p->quant_table, f->quant_tables[idx], sizeof(p->quant_table));
                 context_count= f->context_count[idx];
             }else{