[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