00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <errno.h>
00028 #include <string.h>
00029 #include <stdlib.h>
00030
00031 #include <vlc/vlc.h>
00032 #include <vlc/vout.h>
00033
00034 #define SRC_FOURCC "I420,IYUV,YV12"
00035 #define DEST_FOURCC "YMGA"
00036
00037
00038
00039
00040 static int Activate ( vlc_object_t * );
00041 static void I420_YMGA ( vout_thread_t *, picture_t *, picture_t * );
00042
00043
00044
00045
00046 vlc_module_begin();
00047 #if defined (MODULE_NAME_IS_i420_ymga)
00048 set_description( _("Conversions from " SRC_FOURCC " to " DEST_FOURCC) );
00049 set_capability( "chroma", 80 );
00050 #elif defined (MODULE_NAME_IS_i420_ymga_mmx)
00051 set_description( _("MMX conversions from " SRC_FOURCC " to " DEST_FOURCC) );
00052 set_capability( "chroma", 100 );
00053 add_requirement( MMX );
00054 #endif
00055 set_callbacks( Activate, NULL );
00056 vlc_module_end();
00057
00058
00059
00060
00061
00062
00063 static int Activate( vlc_object_t *p_this )
00064 {
00065 vout_thread_t *p_vout = (vout_thread_t *)p_this;
00066
00067 if( p_vout->render.i_width & 1 || p_vout->render.i_height & 1 )
00068 {
00069 return -1;
00070 }
00071
00072 switch( p_vout->render.i_chroma )
00073 {
00074 case VLC_FOURCC('Y','V','1','2'):
00075 case VLC_FOURCC('I','4','2','0'):
00076 case VLC_FOURCC('I','Y','U','V'):
00077 switch( p_vout->output.i_chroma )
00078 {
00079 case VLC_FOURCC('Y','M','G','A'):
00080 p_vout->chroma.pf_convert = I420_YMGA;
00081 break;
00082
00083 default:
00084 return -1;
00085 }
00086 break;
00087
00088 default:
00089 return -1;
00090 }
00091
00092 return 0;
00093 }
00094
00095
00096
00097
00098
00099
00100 static void I420_YMGA( vout_thread_t *p_vout, picture_t *p_source,
00101 picture_t *p_dest )
00102 {
00103 uint8_t *p_uv = p_dest->U_PIXELS;
00104 uint8_t *p_u = p_source->U_PIXELS;
00105 uint8_t *p_v = p_source->V_PIXELS;
00106
00107 int i_x;
00108
00109
00110 p_vout->p_vlc->pf_memcpy( p_dest->Y_PIXELS, p_source->Y_PIXELS,
00111 p_dest->p[Y_PLANE].i_pitch * p_dest->p[Y_PLANE].i_visible_lines );
00112
00113
00114 for( i_x = p_dest->p[U_PLANE].i_pitch * p_dest->p[U_PLANE].i_visible_lines / 64;
00115 i_x--; )
00116 {
00117 #if defined (MODULE_NAME_IS_i420_ymga)
00118 *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
00119 *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
00120 *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
00121 *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
00122 *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
00123 *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
00124 *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
00125 *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
00126 #else
00127 __asm__( ".align 32 \n\
00128 movd (%0), %%mm0 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
00129 movd 4(%0), %%mm2 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
00130 movd 8(%0), %%mm4 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
00131 movd 12(%0), %%mm6 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
00132 movd (%1), %%mm1 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
00133 movd 4(%1), %%mm3 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
00134 movd 8(%1), %%mm5 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
00135 movd 12(%1), %%mm7 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
00136 punpcklbw %%mm1, %%mm0 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
00137 punpcklbw %%mm3, %%mm2 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
00138 punpcklbw %%mm5, %%mm4 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
00139 punpcklbw %%mm7, %%mm6 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
00140 movq %%mm0, (%2) # Store CrCb \n\
00141 movq %%mm2, 8(%2) # Store CrCb \n\
00142 movq %%mm4, 16(%2) # Store CrCb \n\
00143 movq %%mm6, 24(%2) # Store CrCb"
00144 : : "r" (p_v), "r" (p_u), "r" (p_uv) );
00145
00146 p_v += 16; p_u += 16; p_uv += 32;
00147 #endif
00148 }
00149 }
00150