[FFmpeg-devel] Extend/optimize RGB to RGB conversions funcs into rgb2rgb.c

yann.lepetitcorps at free.fr yann.lepetitcorps at free.fr
Sat Sep 8 19:28:51 CEST 2012


Hi,

I plan to use FFMPEG on Android plateforms and have begin to look about
possibles rgb[8/16/24/32]torgb[8/16/24/32]() funcs optimisations that I have
found on the FFMPEG 0.8 version forAndroid.

I think that rgb24to32() and rgb32to24() funcs in the libswscale/rgb2rgb.c
source file can be rewrited something like this :
(it's very more simpler to understand how they work on this form + this is
certainly very more speed)

void rgb24to32(const uint8_t *src, uint8_t *dst, int src_size )
{
    int i;
    uint8_t *psrc = src;

    for ( i = 0 ; i < src_size ; i += 3, psrc +=3, dst +=4 )
    {
#if HAVE_BIGENDIAN
        /* RGB24 (= R,G,B) -> BGR32 (= 255,R,G,B) */
        dst[0] = 255;
        dst[1] = psrc[0];
        dst[2] = psrc[1];
        dst[3] = psrc[2];
#else
        dst[0] = psrc[2];
        dst[1] = psrc[1];
        dst[2] = psrc[0];
        dst[3] = 255;
#endif
    }
}

void rgb32to24(const uint8_t *src, uint8_t *dst, int src_size)
{
    int i;
    uint8_t *psrc = src;

   for ( i = 0 ; i  < src_size ; i += 4 , psrc += 4, dst +=3  )
   {
#if HAVE_BIGENDIAN
        /* RGB32 (= A,B,G,R) -> BGR24 (= B,G,R) */
        dst[0] = psrc[1];
        dst[1] = psrc[2];
        dst[2] = psrc[3];
#else
        dst[0] = psrc[2];
        dst[1] = psrc[1];
        dst[2] = psrc[0];
#endif
    }
}


And make too some fonctions for to extend conversions's possibilities :

void rgb24to32_alpha(const uint8_t *src, uint8_t *dst, int src_size, uint8_t
alpha)
{
    int i;
    uint8_t *psrc = src;

    for ( i = 0 ; i < src_size ; i += 3, src +=3, dst +=4 )
    {

        /* RGB24 (= R,G,B) -> BGR32 (= alpha,R,G,B) */

#if HAVE_BIGENDIAN
        dst[0] = alpha;
        dst[1] = psrc[0];
        dst[2] = psrc[1];
        dst[3] = psrc[2];
#else
        dst[0] = psrc[2];
        dst[1] = psrc[1];
        dst[2] = psrc[0];
        dst[3] = alpha;
#endif
    }
}


void rgb24to24_luminance(const uint8_t *src, uint8_t *dst, int src_size, int
minlum)
{
    int i, lum;
    uint8_t *psrc = src;

    for ( i = 0 ; i < src_size ; i += 3, src +=3, dst +=4 )
    {

        /* RGB24 (= R,G,B) -> BGR32 (= 255,R,G,B) [or no update if
luminance(RGB) < overlay] */

#if HAVE_BIGENDIAN
	lum = (66 * psrc[0] + 129 * psrc[1] + 25 * psrc[2] + 128) >> 8 + 16;
#else
	lum = (66 * psrc[2] + 129 * psrc[1] + 25 * psrc[0] + 128) >> 8 + 16;
#endif

	if ( lum >= minlum )
	{
        	dst[0] = psrc[0];
        	dst[1] = psrc[1];
        	dst[2] = psrc[2];
	}
    }
}

void rgb24to32_overlay(const uint8_t *src, uint8_t *dst, int src_size, int
overlay)
{
    int i;
    uint8_t *psrc = src;

    for ( i = 0 ; i < src_size ; i += 3, src +=3, dst +=4 )
    {

        /* RGB24 (= R,G,B) -> BGR32 (= 255,R,G,B) [or no update if dst alpha
already > overlay] */

#if HAVE_BIGENDIAN

	if ( dst[0] < overlay )
	{
		dst[0] = 255;
        	dst[1] = psrc[0];
        	dst[2] = psrc[1];
        	dst[3] = psrc[2];
	}
#else
	if ( dst[3] < overlay )
	{
        	dst[0] = psrc[2];
	        dst[1] = psrc[1];
        	dst[2] = psrc[0];
		dst[3] = 255;
	}
#endif
    }
}

void rgb24to32_luminance(const uint8_t *src, uint8_t *dst, int src_size, int
minlum)
{
    int i, lum;
    uint8_t *psrc = src;

    for ( i = 0 ; i < src_size ; i += 3, src +=3, dst +=4 )
    {

        /* RGB24 (= R,G,B) -> BGR32 (= 255,R,G,B) [or no update if
luminance(RGB) < overlay] */

#if HAVE_BIGENDIAN

	lum = (66 * psrc[0] + 129 * psrc[1] + 25 * psrc[2] + 128) >> 8 + 16;

	if ( lum >= minlum )
	{
		dst[0] = 255;
        	dst[1] = psrc[0];
        	dst[2] = psrc[1];
        	dst[3] = psrc[2];
	}
#else

	lum = (66 * psrc[2] + 129 * psrc[1] + 25 * psrc[0] + 128) >> 8 + 16;

	if ( lum >= minlum )
	{
        	dst[0] = psrc[2];
	        dst[1] = psrc[1];
        	dst[2] = psrc[0];
		dst[3] = 255;
	}
#endif
    }
}


void rgb32to24_overlay(const uint8_t *src, uint8_t *dst, int src_size, uint8_t
overlay)
{
    int i;
    uint8_t *psrc = src;

   for ( i = 0 ; i  < src_size ; i += 4 , psrc += 4, dst +=3  )
   {
        /* RGB32 (= A,B,G,R) -> BGR24 (= B,G,R) [or nothing if src alpha <
overlay] */

#if HAVE_BIGENDIAN

	if( psrc[0] >= overlay )
	{
	        dst[0] = psrc[1];
	        dst[1] = psrc[2];
	        dst[2] = psrc[3];
	}
#else
	if( psrc[3] >= overlay )
	{
	        dst[0] = psrc[2];
	        dst[1] = psrc[1];
	        dst[2] = psrc[0];
	}
#endif
    }
}

void rgb32to32_overlay(const uint8_t *src, uint8_t *dst, int src_size, int
overlay)
{
    int i;
    uint8_t *psrc = src;

    for ( i = 0 ; i < src_size ; i += 3, src +=3, dst +=4 )
    {

        /* RGB24 (= R,G,B) -> BGR32 (= 255,R,G,B) [or no update if dst alpha
already > overlay] */

#if HAVE_BIGENDIAN

	if ( src[0] < overlay )
	{
		dst[0] = 255;
        	dst[1] = psrc[1];
        	dst[2] = psrc[2];
        	dst[3] = psrc[3];
	}
#else
	if ( src[3] < overlay )
	{
        	dst[0] = psrc[0];
	        dst[1] = psrc[1];
        	dst[2] = psrc[2];
		dst[3] = 255;
	}
#endif
    }
}

void rgb32to32_overlay2(const uint8_t *src, uint8_t *dst, int src_size, int
overlay)
{
    int i;
    uint8_t *psrc = src;

    for ( i = 0 ; i < src_size ; i += 3, src +=3, dst +=4 )
    {

        /* RGB24 (= R,G,B) -> BGR32 (= 255,R,G,B) [or no update if src alpha >
dst alpha] */

#if HAVE_BIGENDIAN

	if ( (src[0] & overlay)  >= (dst[0] & overlay) )
	{
		dst[0] = psrc[0];
        	dst[1] = psrc[1];
        	dst[2] = psrc[2];
        	dst[3] = psrc[3];
	}
#else
	if ( (src[3] & overlay) >= (dst[3] & overlay) )
	{
        	dst[0] = psrc[0];
	        dst[1] = psrc[1];
        	dst[2] = psrc[2];
		dst[3] = psrc|3];
	}
#endif
    }
}

Was the 0.8 version of FFMPEG the more adapted for Android developments or
newers version of FFMPEG are better ?
(I have found this version into a tuto that explain how to use FFMPEG with JNI
calls on Android plateform)


@+
Yannoo


More information about the ffmpeg-devel mailing list