changeset 868:dfe7d66da6f0 libavcodec

YV12 support (warning this is experimental & wont work with offical huffyuv but there is a approx. 20% speed & compression gain) 10l flush_put_bits()
author michaelni
date Thu, 14 Nov 2002 22:25:20 +0000
parents 48215b2c3888
children 028638e65523
files huffyuv.c
diffstat 1 files changed, 116 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/huffyuv.c	Thu Nov 14 19:46:14 2002 +0000
+++ b/huffyuv.c	Thu Nov 14 22:25:20 2002 +0000
@@ -328,7 +328,7 @@
 //if(avctx->extradata)
 //  printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
     if(avctx->extradata_size){
-        if(avctx->bits_per_sample&7)
+        if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12)
             s->version=1; // do such files exist at all?
         else
             s->version=2;
@@ -473,6 +473,13 @@
     s->version=2;
     
     switch(avctx->pix_fmt){
+    case PIX_FMT_YUV420P:
+        if(avctx->strict_std_compliance>=0){
+            fprintf(stderr, "YV12-huffyuv is experimental, there WILL be no compatbility! (use (v)strict=-1)\n");
+            return -1;
+        }
+        s->bitstream_bpp= 12;
+        break;
     case PIX_FMT_YUV422P:
         s->bitstream_bpp= 16;
         break;
@@ -554,6 +561,17 @@
     }
 }
 
+static void decode_gray_bitstream(HYuvContext *s, int count){
+    int i;
+    
+    count/=2;
+    
+    for(i=0; i<count; i++){
+        s->temp[0][2*i  ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); 
+        s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); 
+    }
+}
+
 static void encode_422_bitstream(HYuvContext *s, int count){
     int i;
     
@@ -575,6 +593,23 @@
     }
 }
 
+static void encode_gray_bitstream(HYuvContext *s, int count){
+    int i;
+    
+    count/=2;
+    if(s->flags&CODEC_FLAG_PASS1){
+        for(i=0; i<count; i++){
+            s->stats[0][ s->temp[0][2*i  ] ]++;
+            s->stats[0][ s->temp[0][2*i+1] ]++;
+        }
+    }else{
+        for(i=0; i<count; i++){
+            put_bits(&s->pb, s->len[0][ s->temp[0][2*i  ] ], s->bits[0][ s->temp[0][2*i  ] ]);
+            put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
+        }
+    }
+}
+
 static void decode_bgr_bitstream(HYuvContext *s, int count){
     int i;
     
@@ -634,7 +669,7 @@
     init_get_bits(&s->gb, s->bitstream_buffer, buf_size);
     
     if(s->bitstream_bpp<24){
-        int y;
+        int y, cy;
         int lefty, leftu, leftv;
         int lefttopy, lefttopu, lefttopv;
         
@@ -663,13 +698,28 @@
                     leftv= add_left_prediction(s->picture[2] + 1, s->temp[2], width2-1, leftv);
                 }
 
-                for(y=1; y<s->height; y++){
+                for(cy=y=1; y<s->height; y++,cy++){
                     uint8_t *ydst, *udst, *vdst;
-                    decode_422_bitstream(s, width);
+                    
+                    if(s->bitstream_bpp==12){
+                        decode_gray_bitstream(s, width);
+                    
+                        ydst= s->picture[0] + s->linesize[0]*y;
+
+                        lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
+                        if(s->predictor == PLANE){
+                            if(y>s->interlaced)
+                                s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
+                        }
+                        y++;
+                        if(y>=s->height) break;
+                    }
                     
                     ydst= s->picture[0] + s->linesize[0]*y;
-                    udst= s->picture[1] + s->linesize[1]*y;
-                    vdst= s->picture[2] + s->linesize[2]*y;
+                    udst= s->picture[1] + s->linesize[1]*cy;
+                    vdst= s->picture[2] + s->linesize[2]*cy;
+                    
+                    decode_422_bitstream(s, width);
 
                     lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
                     if(!(s->flags&CODEC_FLAG_GRAY)){
@@ -677,7 +727,7 @@
                         leftv= add_left_prediction(vdst, s->temp[2], width2, leftv);
                     }
                     if(s->predictor == PLANE){
-                        if(y>s->interlaced){
+                        if(cy>s->interlaced){
                             s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
                             if(!(s->flags&CODEC_FLAG_GRAY)){
                                 s->dsp.add_bytes(udst, udst - fake_ustride, width2);
@@ -696,7 +746,7 @@
                     leftv= add_left_prediction(s->picture[2] + 1, s->temp[2], width2-1, leftv);
                 }
                 
-                y=1;
+                cy=y=1;
                 
                 /* second line is left predicted for interlaced case */
                 if(s->interlaced){
@@ -706,7 +756,7 @@
                         leftu= add_left_prediction(s->picture[1] + s->linesize[2], s->temp[1], width2, leftu);
                         leftv= add_left_prediction(s->picture[2] + s->linesize[1], s->temp[2], width2, leftv);
                     }
-                    y++;
+                    y++; cy++;
                 }
 
                 /* next 4 pixels are left predicted too */
@@ -727,15 +777,26 @@
                     add_median_prediction(s->picture[1] + fake_ustride+2, s->picture[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
                     add_median_prediction(s->picture[2] + fake_vstride+2, s->picture[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
                 }
-                y++;
+                y++; cy++;
+                
+                for(; y<height; y++,cy++){
+                    uint8_t *ydst, *udst, *vdst;
 
-                for(; y<height; y++){
-                    uint8_t *ydst, *udst, *vdst;
+                    if(s->bitstream_bpp==12){
+                        while(2*cy > y){
+                            decode_gray_bitstream(s, width);
+                            ydst= s->picture[0] + s->linesize[0]*y;
+                            add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
+                            y++;
+                        }
+                        if(y>=height) break;
+                    }
+
                     decode_422_bitstream(s, width);
-                    
+
                     ydst= s->picture[0] + s->linesize[0]*y;
-                    udst= s->picture[1] + s->linesize[1]*y;
-                    vdst= s->picture[2] + s->linesize[2]*y;
+                    udst= s->picture[1] + s->linesize[1]*cy;
+                    vdst= s->picture[2] + s->linesize[2]*cy;
 
                     add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
                     if(!(s->flags&CODEC_FLAG_GRAY)){
@@ -834,8 +895,8 @@
         s->linesize[i]= pict->linesize[i];
     }
     
-    if(avctx->pix_fmt == PIX_FMT_YUV422P){
-        int lefty, leftu, leftv, y;
+    if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
+        int lefty, leftu, leftv, y, cy;
 
         put_bits(&s->pb, 8, leftv= s->picture[2][0]);
         put_bits(&s->pb, 8, lefty= s->picture[0][1]);
@@ -850,14 +911,14 @@
         
         if(s->predictor==MEDIAN){
             int lefttopy, lefttopu, lefttopv;
-            y=1;
+            cy=y=1;
             if(s->interlaced){
                 lefty= sub_left_prediction(s->temp[0], s->picture[0]+s->linesize[0], width , lefty);
                 leftu= sub_left_prediction(s->temp[1], s->picture[1]+s->linesize[1], width2, leftu);
                 leftv= sub_left_prediction(s->temp[2], s->picture[2]+s->linesize[2], width2, leftv);
         
                 encode_422_bitstream(s, width);
-                y++;
+                y++; cy++;
             }
             
             lefty= sub_left_prediction(s->temp[0], s->picture[0]+fake_ystride, 4, lefty);
@@ -865,7 +926,7 @@
             leftv= sub_left_prediction(s->temp[2], s->picture[2]+fake_ystride, 2, leftv);
         
             encode_422_bitstream(s, 4);
-                        
+
             lefttopy= s->picture[0][3];
             lefttopu= s->picture[1][1];
             lefttopv= s->picture[2][1];
@@ -873,14 +934,23 @@
             sub_median_prediction(s->temp[1], s->picture[1]+2, s->picture[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
             sub_median_prediction(s->temp[2], s->picture[2]+2, s->picture[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
             encode_422_bitstream(s, width-4);
-            y++;
+            y++; cy++;
 
-            for(; y<height; y++){
+            for(; y<height; y++,cy++){
                 uint8_t *ydst, *udst, *vdst;
                     
+                if(s->bitstream_bpp==12){
+                    while(2*cy > y){
+                        ydst= s->picture[0] + s->linesize[0]*y;
+                        sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
+                        encode_gray_bitstream(s, width);
+                        y++;
+                    }
+                    if(y>=height) break;
+                }
                 ydst= s->picture[0] + s->linesize[0]*y;
-                udst= s->picture[1] + s->linesize[1]*y;
-                vdst= s->picture[2] + s->linesize[2]*y;
+                udst= s->picture[1] + s->linesize[1]*cy;
+                vdst= s->picture[2] + s->linesize[2]*cy;
 
                 sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
                 sub_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
@@ -889,14 +959,30 @@
                 encode_422_bitstream(s, width);
             }
         }else{
-            for(y=1; y<height; y++){
+            for(cy=y=1; y<height; y++,cy++){
                 uint8_t *ydst, *udst, *vdst;
-                    
+                
+                /* encode a luma only line & y++ */
+                if(s->bitstream_bpp==12){
+                    ydst= s->picture[0] + s->linesize[0]*y;
+
+                    if(s->predictor == PLANE && s->interlaced < y){
+                        s->dsp.diff_bytes(s->temp[0], ydst, ydst - fake_ystride, width);
+
+                        lefty= sub_left_prediction(s->temp[0], s->temp[0], width , lefty);
+                    }else{
+                        lefty= sub_left_prediction(s->temp[0], ydst, width , lefty);
+                    }
+                    encode_gray_bitstream(s, width);
+                    y++;
+                    if(y>=height) break;
+                }
+                
                 ydst= s->picture[0] + s->linesize[0]*y;
-                udst= s->picture[1] + s->linesize[1]*y;
-                vdst= s->picture[2] + s->linesize[2]*y;
+                udst= s->picture[1] + s->linesize[1]*cy;
+                vdst= s->picture[2] + s->linesize[2]*cy;
 
-                if(s->predictor == PLANE && s->interlaced < y){
+                if(s->predictor == PLANE && s->interlaced < cy){
                     s->dsp.diff_bytes(s->temp[0], ydst, ydst - fake_ystride, width);
                     s->dsp.diff_bytes(s->temp[1], udst, udst - fake_ustride, width2);
                     s->dsp.diff_bytes(s->temp[2], vdst, vdst - fake_vstride, width2);
@@ -933,6 +1019,7 @@
             p++;
         }
     }else{
+        flush_put_bits(&s->pb);
         bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
     }