[Ffmpeg-devel] [RFC] RGB48 support
    Michael Niedermayer 
    michaelni
       
    Tue Apr 10 23:13:30 CEST 2007
    
    
  
Hi
On Tue, Apr 10, 2007 at 06:15:35PM +0200, Ivo wrote:
> Hi,
> 
> On Monday 09 April 2007 23:46, Michael Niedermayer wrote:
> > On Mon, Apr 09, 2007 at 08:16:30PM +0200, Ivo wrote:
> > > Any comments?
> >
> > the only thing in swscale which you must implement is the new format->yuv
> > code, swscale uses yuv internally (see svn log of swscale for some
> > examples on how other formats where added)
> >
> > the rgb->rgb code is optional but surely a good idea ...
> >
> > also the rgb48->yuv can be done in 2 ways
> > A. -> 8bit based yuv
> > B. -> internal yuv (which uses >8bits per component) but will need
> >    slightly more work, also theres no example in svn for this yet ...
> >
> > PS: this has nothing to do with yuv2rgb*.c ! the code you need to change
> > is in swscale*
> 
> Here's my progress. I implemented conversion both to and from 8-bit based 
> yuv for now (your option A.) so in the end I did touch yuv2rgb*.c too ;-)
> 
> I noticed several lines of:
> 
> src2= formatConvBuffer+2048;
> 
> in swscale_template.c. If I understand the code correctly, this constant is 
> arbitrarily chosen and swscale will fail if you feed it very large images 
> (like an 8k 70mm film scan). Is that correct?
yes, the 2048 stuff should be changed to a #defined constant (or variable but
that will be more difficult and likely somewhat slower, so constant is better)
> 
> I will continue to work on the missing rgb2rgb functions, including some MMX 
> acceleration for some of the important ones. 
:)
> Any comments on the code so 
did you test the yuv2rgb.c code ?
[...]
> Index: libavutil/avutil.h
> ===================================================================
> --- libavutil/avutil.h	(revision 8705)
> +++ libavutil/avutil.h	(working copy)
> @@ -107,6 +107,8 @@
>  
>      PIX_FMT_GRAY16BE,  ///<        Y        , 16bpp, big-endian
>      PIX_FMT_GRAY16LE,  ///<        Y        , 16bpp, little-endian
> +    PIX_FMT_RGB48BE,   ///< Packed RGB 16:16:16, 48bpp, big-endian
> +    PIX_FMT_RGB48LE,   ///< Packed RGB 16:16:16, 48bpp, little-endian
iam fine with this but i think the comments could be clearer
[...]
> +static inline void RENAME(rgb48to48)(const uint8_t *src, uint8_t *dst, long src_size)
> +{
> +    uint8_t *d = dst, *s = (uint8_t *) src;
> +    const uint8_t *end = s + src_size;
> +
> +    for (; s<end; s+=2, d+=2) {
> +        *d     = *(s+1);
> +        *(d+1) = *s;
> +    }
> +}
hmm try:
unsigned int a= *(uint32_t*)s;
*(uint32_t*)d= ((a>>8)&0x00FF00FF) + ((a<<8)&0xFF00FF00);
> +
> +static inline void RENAME(rgb48beto24)(const uint8_t *src, uint8_t *dst, long src_size)
> +{
> +    uint8_t *d = dst, *s = (uint8_t *) src;
> +    const uint8_t *end = s + src_size;
> +
> +    for (; s<end; s+=2, d++)
> +        *d = *s;
> +}
> +
> +static inline void RENAME(rgb48leto24)(const uint8_t *src, uint8_t *dst, long src_size)
> +{
> +    uint8_t *d = dst, *s = (uint8_t *) src;
> +    const uint8_t *end = s + src_size;
> +
> +    for (; s<end; s+=2, d++)
> +        *d = *(s+1);
> +}
hmmmmm, isnt this the same as the gray conversation stuff? if yes please
avoid the code duplication / use it for both gray and rgb
> +
> +static inline void RENAME(rgb24to48)(const uint8_t *src, uint8_t *dst, long src_size)
> +{
> +    uint8_t *d = dst, *s = (uint8_t *) src;
> +    const uint8_t *end = s + src_size;
> +    {START_TIMER
> +#ifdef HAVE_MMX
> +    __asm __volatile(PREFETCH" %0"    : :"m"(*s) :"memory");
> +    while(s < end - 23)
> +    {
> +    __asm __volatile(
> +		PREFETCH"	32%1		\n"
> +	"	movd	 	  %1,   %%mm0	\n"
> +	"	movd	 	 4%1,   %%mm1	\n"
> +	"	movd 		 8%1,   %%mm2	\n"
> +	"	movd 		12%1,   %%mm3	\n"
> +	"	movd 		16%1,   %%mm4	\n"
> +	"	movd 		20%1,   %%mm5	\n"
> +	"	movq		%%mm0,  %%mm6	\n"
> +	"	movq		%%mm1,  %%mm7	\n"
> +	"	punpcklbw	%%mm0,  %%mm6	\n"
> +	"	punpcklbw	%%mm1,  %%mm7	\n"
hmm try:
punpcklbw	%%mm0,  %%mm0
[...]
> +    d += 48;
> +    s += 24;
> +    }
please write the whole loop in asm, i hate c-loop + asm code as gcc tends
to make a quite suboptimal mess out of it most of the time ...
> +    __asm __volatile(SFENCE:::"memory");
> +    __asm __volatile(EMMS:::"memory");
> +#endif
> +    for (; s<end; s++, d+=2) {
> +        register uint8_t x = *s;
a simple int should do
> +        *((uint16_t *)d) = (x << 8) + x;
> +    }
> +    STOP_TIMER("rgb24to48")}
iam happy that you benchmark your code but this shouldnt be in the patches
you send :)
[...]
> +static inline void RENAME(rgb48leToY)(uint8_t *dst, uint8_t *src, int width)
> +{
> +	int i;
> +	for(i=0; i<width; i++)
> +	{
> +		int r= src[i*6+1];
> +		int g= src[i*6+3];
> +		int b= src[i*6+5];
> +
> +		dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)) )>>RGB2YUV_SHIFT);
> +	}
> +}
code duplication rgb48beToY(+1) will work too (of course alternative 
high accuracy code which scales the 16bits rgb to internal yuv is welcome 
too ...)
[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
No great genius has ever existed without some touch of madness. -- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070410/dc514d6c/attachment.pgp>
    
    
More information about the ffmpeg-devel
mailing list