[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