[FFmpeg-devel] lavfi state of affairs

Kostya kostya.shishkov
Sun Feb 8 12:31:48 CET 2009


On Sun, Feb 08, 2009 at 02:54:57AM +0100, Michael Niedermayer wrote:
> On Sat, Feb 07, 2009 at 07:30:51PM +0200, Kostya wrote:
> > 
> > Current table generator (judging from table output, haven't tried seeing the code)
> > generates one table for scaled Y component and uint8_t* tables are used to point to
> > the different parts of it.
> > 
> > R = 1.164(Y - 16 + 1.596/1.164(V - 128)) = 1.164(Y + 1.371*V + 192)
> > G = 1.164(Y - 16 - 0.813/1.164(V - 128) - 0.391/1.164(U - 128)) = 1.164(Y - 0.698*V - 0.336*U + 116)
> > B = 1.164(Y - 16 + 2.018/1.164(U - 128)) = 1.164(Y + 1.734*U - 238)
> > 
> > With this formulae I think I will write (maybe not so nice) table generator that
> > will differ by +-1 
> 
> +-1 difference is ok, especially if you are more accurate than the current code
> 
> 
> > but licensed under WTFPL2 (http://sam.zoy.org/wtfpl/)
> 
> very good!
 
Here's the patch (for RGB24/BGR24 only for now), seems to work but testing and
comments are welcome.
 
> also dont forget brightness/contrast/saturation/full_range

It was easy (both to forget and to implement)

> [...]
> -- 
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
-------------- next part --------------
Index: yuv2rgb.c
===================================================================
--- yuv2rgb.c	(revision 28473)
+++ yuv2rgb.c	(working copy)
@@ -563,6 +563,97 @@
         return -((-dividend + (divisor>>1)) / divisor);
 }
 
+static void fill_table(uint8_t* table[256], int elemsize, int inc, uint8_t *y_table)
+{
+    int i;
+    int64_t cb = 0;
+
+    y_table -= inc >> 9;
+
+    for(i = 0; i < 256; i++){
+        table[i] = y_table + elemsize * ((cb + 0x8000) >> 16);
+        cb += inc;
+    }
+}
+
+static void fill_gv_table(int table[256], int elemsize, int inc, int off)
+{
+    int i;
+    int64_t cb = 0;
+
+    off -= inc >> 9;
+
+    for(i = 0; i < 256; i++){
+        table[i] = elemsize * (off + ((cb + 0x8000) >> 16));
+        cb += inc;
+    }
+}
+
+int my_yuv2rgb_c_init_tables (SwsContext *c, const int inv_table[4], int fullRange, int brightness, int contrast, int saturation)
+{
+    /*const int isRgb =      c->dstFormat==PIX_FMT_RGB32
+                        || c->dstFormat==PIX_FMT_RGB32_1
+                        || c->dstFormat==PIX_FMT_BGR24
+                        || c->dstFormat==PIX_FMT_RGB565
+                        || c->dstFormat==PIX_FMT_RGB555
+                        || c->dstFormat==PIX_FMT_RGB8
+                        || c->dstFormat==PIX_FMT_RGB4
+                        || c->dstFormat==PIX_FMT_RGB4_BYTE
+                        || c->dstFormat==PIX_FMT_MONOBLACK;*/
+    const int bpp = fmt_depth(c->dstFormat);
+    uint8_t *y_table;
+    int i;
+
+    int64_t crv =  inv_table[0];
+    int64_t cbu =  inv_table[1];
+    int64_t cgu = -inv_table[2];
+    int64_t cgv = -inv_table[3];
+    int64_t cy  = 1<<16;
+    int64_t oy  = 0;
+
+    int64_t yb = 0;
+
+    if (!fullRange){
+        cy= (cy*255) / 219;
+        oy= 16<<16;
+    }else{
+        crv= (crv*224) / 255;
+        cbu= (cbu*224) / 255;
+        cgu= (cgu*224) / 255;
+        cgv= (cgv*224) / 255;
+    }
+
+    cy = (cy *contrast             )>>16;
+    crv= (crv*contrast * saturation)>>32;
+    cbu= (cbu*contrast * saturation)>>32;
+    cgu= (cgu*contrast * saturation)>>32;
+    cgv= (cgv*contrast * saturation)>>32;
+    oy -= 256*brightness;
+
+    //scale coefficients by cy
+    crv = (crv << 16) / cy;
+    cbu = (cbu << 16) / cy;
+    cgu = (cgu << 16) / cy;
+    cgv = (cgv << 16) / cy;
+
+    switch(bpp){
+    case 24:
+        c->yuvTable = av_malloc(1024);
+        y_table = c->yuvTable;
+        yb = -(384<<16) - oy;
+        for(i = 0; i < 1024; i++){
+            y_table[i] = av_clip_uint8((yb + 0x8000) >> 16);
+            yb += cy;
+        }
+        fill_table(c->table_rV, 1, crv, y_table + 384);// - (oy >> 16));
+        fill_table(c->table_gU, 1, cgu, y_table + 384);// - (oy >> 16));
+        fill_table(c->table_bU, 1, cbu, y_table + 384);// - (oy >> 16));
+        fill_gv_table(c->table_gV, 1, cgv, 16);
+        break;
+    }
+    return 0;
+}
+
 int yuv2rgb_c_init_tables (SwsContext *c, const int inv_table[4], int fullRange, int brightness, int contrast, int saturation)
 {
     const int isRgb =      c->dstFormat==PIX_FMT_RGB32
@@ -593,6 +684,8 @@
     int64_t cgv = -inv_table[3];
     int64_t cy  = 1<<16;
     int64_t oy  = 0;
+    
+    if(bpp == 24)return my_yuv2rgb_c_init_tables(c, inv_table, fullRange, brightness, contrast, saturation);
 
 //printf("%lld %lld %lld %lld %lld\n", cy, crv, cbu, cgu, cgv);
     if (!fullRange){



More information about the ffmpeg-devel mailing list