[FFmpeg-devel] Extend/optimize RGB to RGB conversions funcs into rgb2rgb.c
yann.lepetitcorps at free.fr
yann.lepetitcorps at free.fr
Sun Sep 9 00:12:22 CEST 2012
I have make a verification on the 0.11.1.git version and found that the
rgb32to24() and rgb24to32() are identics to the 0.8 version
I think too that rgb[15,16]tobgr[24,32]() funcs can perhaps to be
optimised by the use of one table conversion of 64K entries where the input rgb
color with a format of 12/15/16 bits can to be used as an index into a
conversion table that directly give us the converted 12/15/16/24/32 value in
output
(cf. this economize at lot of ">>", "<<", "&" or others "|" computations)
Note, that the same idea can be used for rgb[12,15,16]tobgr[12,15,16] funcs
I think too modify f_fill_line_with_color() func into
libavfilter/drawutils.c for to unroll the "for (plane = 0; plane < 4; plane++)"
loop and to economize the hsub1 computation half of the time when this isn't a
packet format
(same thing on ff_draw_rectangle() and ff_copy_rectangle() funcs for to always
economize a lot of >> computations and pixelstep[plane] access)
=> I make a test and benchmark this for to see if this is really more
speed than the actual implementation of them
PS : I have see some new blending funcs such as blend_line/rectangle/pixel()
into drawutils.c, so the overlay extension seem already to be here :)
@+
Yannoo
> 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