[FFmpeg-devel] [PATCH]Make 16bit encoding to ffv1 easier

Carl Eugen Hoyos cehoyos at ag.or.at
Thu Feb 9 14:01:25 CET 2012


Hi!

It is currently difficult to encode 16bit ffv1, because typically 
bits_per_raw_sample is not set.

Please review, Carl Eugen
-------------- next part --------------
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index 586a296..1a58a7e 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -196,6 +196,7 @@ typedef struct FFV1Context{
     int slice_height;
     int slice_x;
     int slice_y;
+    int bits_per_raw_sample;
 }FFV1Context;
 
 static av_always_inline int fold(int diff, int bits){
@@ -540,7 +541,7 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride,
         sample[0][-1]= sample[1][0  ];
         sample[1][ w]= sample[1][w-1];
 //{START_TIMER
-        if(s->avctx->bits_per_raw_sample<=8){
+        if(s->bits_per_raw_sample<=8){
             for(x=0; x<w; x++){
                 sample[0][x]= src[x + stride*y];
             }
@@ -552,10 +553,10 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride,
                 }
             }else{
                 for(x=0; x<w; x++){
-                    sample[0][x]= ((uint16_t*)(src + stride*y))[x] >> (16 - s->avctx->bits_per_raw_sample);
+                    sample[0][x]= ((uint16_t*)(src + stride*y))[x] >> (16 - s->bits_per_raw_sample);
                 }
             }
-            encode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample);
+            encode_line(s, w, sample, plane_index, s->bits_per_raw_sample);
         }
 //STOP_TIMER("encode line")}
     }
@@ -640,7 +641,7 @@ static void write_header(FFV1Context *f){
         }
         put_symbol(c, state, f->colorspace, 0); //YUV cs type
         if(f->version>0)
-            put_symbol(c, state, f->avctx->bits_per_raw_sample, 0);
+            put_symbol(c, state, f->bits_per_raw_sample, 0);
         put_rac(c, state, f->chroma_planes);
         put_symbol(c, state, f->chroma_h_shift, 0);
         put_symbol(c, state, f->chroma_v_shift, 0);
@@ -782,7 +783,7 @@ static int write_extra_header(FFV1Context *f){
         }
     }
     put_symbol(c, state, f->colorspace, 0); //YUV cs type
-    put_symbol(c, state, f->avctx->bits_per_raw_sample, 0);
+    put_symbol(c, state, f->bits_per_raw_sample, 0);
     put_rac(c, state, f->chroma_planes);
     put_symbol(c, state, f->chroma_h_shift, 0);
     put_symbol(c, state, f->chroma_v_shift, 0);
@@ -874,54 +875,25 @@ static av_cold int encode_init(AVCodecContext *avctx)
             s->state_transition[i]=ver2_state[i];
 
     s->plane_count=3;
-    for(i=0; i<256; i++){
-        s->quant_table_count=2;
-        if(avctx->bits_per_raw_sample <=8){
-            s->quant_tables[0][0][i]=           quant11[i];
-            s->quant_tables[0][1][i]=        11*quant11[i];
-            s->quant_tables[0][2][i]=     11*11*quant11[i];
-            s->quant_tables[1][0][i]=           quant11[i];
-            s->quant_tables[1][1][i]=        11*quant11[i];
-            s->quant_tables[1][2][i]=     11*11*quant5 [i];
-            s->quant_tables[1][3][i]=   5*11*11*quant5 [i];
-            s->quant_tables[1][4][i]= 5*5*11*11*quant5 [i];
-        }else{
-            s->quant_tables[0][0][i]=           quant9_10bit[i];
-            s->quant_tables[0][1][i]=        11*quant9_10bit[i];
-            s->quant_tables[0][2][i]=     11*11*quant9_10bit[i];
-            s->quant_tables[1][0][i]=           quant9_10bit[i];
-            s->quant_tables[1][1][i]=        11*quant9_10bit[i];
-            s->quant_tables[1][2][i]=     11*11*quant5_10bit[i];
-            s->quant_tables[1][3][i]=   5*11*11*quant5_10bit[i];
-            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));
-        p->quant_table_index= avctx->context_model;
-        p->context_count= s->context_count[p->quant_table_index];
-    }
-
-    if(allocate_initial_states(s) < 0)
-        return AVERROR(ENOMEM);
-
-    avctx->coded_frame= &s->picture;
     switch(avctx->pix_fmt){
     case PIX_FMT_YUV420P9:
+        if (!avctx->bits_per_raw_sample)
+            s->bits_per_raw_sample = 9;
     case PIX_FMT_YUV420P10:
     case PIX_FMT_YUV422P10:
         s->packed_at_lsb = 1;
+        if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample)
+            s->bits_per_raw_sample = 10;
     case PIX_FMT_GRAY16:
     case PIX_FMT_YUV444P16:
     case PIX_FMT_YUV422P16:
     case PIX_FMT_YUV420P16:
-        if(avctx->bits_per_raw_sample <=8){
+        if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) {
+            s->bits_per_raw_sample = 16;
+        } else if (!s->bits_per_raw_sample){
+            s->bits_per_raw_sample = avctx->bits_per_raw_sample;
+        }
+        if(s->bits_per_raw_sample <=8){
             av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample invalid\n");
             return -1;
         }
@@ -956,6 +928,44 @@ static av_cold int encode_init(AVCodecContext *avctx)
         av_log(avctx, AV_LOG_ERROR, "format not supported\n");
         return -1;
     }
+    for(i=0; i<256; i++){
+        s->quant_table_count=2;
+        if(s->bits_per_raw_sample <=8){
+            s->quant_tables[0][0][i]=           quant11[i];
+            s->quant_tables[0][1][i]=        11*quant11[i];
+            s->quant_tables[0][2][i]=     11*11*quant11[i];
+            s->quant_tables[1][0][i]=           quant11[i];
+            s->quant_tables[1][1][i]=        11*quant11[i];
+            s->quant_tables[1][2][i]=     11*11*quant5 [i];
+            s->quant_tables[1][3][i]=   5*11*11*quant5 [i];
+            s->quant_tables[1][4][i]= 5*5*11*11*quant5 [i];
+        }else{
+            s->quant_tables[0][0][i]=           quant9_10bit[i];
+            s->quant_tables[0][1][i]=        11*quant9_10bit[i];
+            s->quant_tables[0][2][i]=     11*11*quant9_10bit[i];
+            s->quant_tables[1][0][i]=           quant9_10bit[i];
+            s->quant_tables[1][1][i]=        11*quant9_10bit[i];
+            s->quant_tables[1][2][i]=     11*11*quant5_10bit[i];
+            s->quant_tables[1][3][i]=   5*11*11*quant5_10bit[i];
+            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));
+        p->quant_table_index= avctx->context_model;
+        p->context_count= s->context_count[p->quant_table_index];
+    }
+
+    if(allocate_initial_states(s) < 0)
+        return AVERROR(ENOMEM);
+
+    avctx->coded_frame= &s->picture;
     if(!s->transparency)
         s->plane_count= 2;
     avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift);
@@ -1095,7 +1105,7 @@ static int encode_slice(AVCodecContext *c, void *arg){
     int x= fs->slice_x;
     int y= fs->slice_y;
     AVFrame * const p= &f->picture;
-    const int ps= (c->bits_per_raw_sample>8)+1;
+    const int ps= (f->bits_per_raw_sample>8)+1;
 
     if(f->colorspace==0){
         const int chroma_width = -((-width )>>f->chroma_h_shift);
@@ -1517,6 +1527,7 @@ static int read_extra_header(FFV1Context *f){
         }
     }
     f->colorspace= get_symbol(c, state, 0); //YUV cs type
+    f->bits_per_raw_sample=
     f->avctx->bits_per_raw_sample= get_symbol(c, state, 0);
     get_rac(c, state); //no chroma = false
     f->chroma_h_shift= get_symbol(c, state, 0);
@@ -1573,8 +1584,10 @@ static int read_header(FFV1Context *f){
             }
         }
         f->colorspace= get_symbol(c, state, 0); //YUV cs type
-        if(f->version>0)
+        if(f->version>0) {
+            f->bits_per_raw_sample=
             f->avctx->bits_per_raw_sample= get_symbol(c, state, 0);
+        }
         f->chroma_planes= get_rac(c, state);
         f->chroma_h_shift= get_symbol(c, state, 0);
         f->chroma_v_shift= get_symbol(c, state, 0);
@@ -1583,9 +1596,9 @@ static int read_header(FFV1Context *f){
     }
 
     if(f->colorspace==0){
-        if(f->avctx->bits_per_raw_sample>8 && !f->transparency && !f->chroma_planes){
+        if(f->bits_per_raw_sample>8 && !f->transparency && !f->chroma_planes){
             f->avctx->pix_fmt= PIX_FMT_GRAY16;
-        }else if(f->avctx->bits_per_raw_sample<=8 && !f->transparency){
+        }else if(f->bits_per_raw_sample<=8 && !f->transparency){
             switch(16*f->chroma_h_shift + f->chroma_v_shift){
             case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P; break;
             case 0x01: f->avctx->pix_fmt= PIX_FMT_YUV440P; break;
@@ -1597,7 +1610,7 @@ static int read_header(FFV1Context *f){
                 av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
                 return -1;
             }
-        }else if(f->avctx->bits_per_raw_sample<=8 && f->transparency){
+        }else if(f->bits_per_raw_sample<=8 && f->transparency){
             switch(16*f->chroma_h_shift + f->chroma_v_shift){
             case 0x00: f->avctx->pix_fmt= PIX_FMT_YUVA444P; break;
             case 0x11: f->avctx->pix_fmt= PIX_FMT_YUVA420P; break;
@@ -1605,7 +1618,7 @@ static int read_header(FFV1Context *f){
                 av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
                 return -1;
             }
-        }else if(f->avctx->bits_per_raw_sample==9) {
+        }else if(f->bits_per_raw_sample==9) {
             switch(16*f->chroma_h_shift + f->chroma_v_shift){
             case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break;
             case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P16; break;
@@ -1614,7 +1627,7 @@ static int read_header(FFV1Context *f){
                 av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
                 return -1;
             }
-        }else if(f->avctx->bits_per_raw_sample==10) {
+        }else if(f->bits_per_raw_sample==10) {
             switch(16*f->chroma_h_shift + f->chroma_v_shift){
             case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break;
             case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P10; f->packed_at_lsb=1; break;


More information about the ffmpeg-devel mailing list