1 #include "gfx_conv_mmx.h" 2 #include "gfx_conv_c.h" 3 4 5 extern "C" void _Convert_YUV420P_RGBA32_SSE2(void *fromYPtr, void *fromUPtr, 6 void *fromVPtr, void *toPtr, int width); 7 extern "C" void _Convert_YUV422_RGBA32_SSE2(void *fromYPtr, void *toPtr, 8 int width); 9 extern "C" void _Convert_YUV420P_RGBA32_SSE(void *fromYPtr, void *fromUPtr, 10 void *fromVPtr, void *toPtr, int width); 11 extern "C" void _Convert_YUV422_RGBA32_SSE(void *fromYPtr, void *toPtr, 12 int width); 13 14 15 void 16 gfx_conv_yuv420p_rgba32_sse2(AVFrame *in, AVFrame *out, int width, int height) 17 { 18 // Planar YUV420 19 20 // in and out buffers must be aligned to 32 bytes, 21 // in should be as ffmpeg allocates it 22 if ((off_t)out->data[0] % 32 != 0) { 23 gfx_conv_YCbCr420p_RGB32_c(in, out, width, height); 24 return; 25 } 26 27 uint8 *ybase = (uint8 *)in->data[0]; 28 uint8 *ubase = (uint8 *)in->data[1]; 29 uint8 *vbase = (uint8 *)in->data[2]; 30 uint8 *rgbbase = (uint8 *)out->data[0]; 31 32 int yBaseInc = in->linesize[0]; 33 int uBaseInc = in->linesize[1]; 34 int vBaseInc = in->linesize[2]; 35 int rgbBaseInc = out->linesize[0]; 36 37 for (int i=0;i<height;i+=2) { 38 // First Y row 39 _Convert_YUV420P_RGBA32_SSE2(ybase, ubase, vbase, rgbbase, width); 40 ybase += yBaseInc; 41 rgbbase += rgbBaseInc; 42 43 // Second Y row but same u and v row 44 _Convert_YUV420P_RGBA32_SSE2(ybase, ubase, vbase, rgbbase, width); 45 ybase += yBaseInc; 46 ubase += uBaseInc; 47 vbase += vBaseInc; 48 rgbbase += rgbBaseInc; 49 } 50 } 51 52 53 void 54 gfx_conv_yuv422p_rgba32_sse2(AVFrame *in, AVFrame *out, int width, int height) 55 { 56 // Packed YUV422 57 58 // in and out buffers must be aligned to 32 bytes, 59 // in should be as ffmpeg allocates it 60 if ((off_t)out->data[0] % 32 != 0) { 61 gfx_conv_YCbCr422_RGB32_c(in, out, width, height); 62 return; 63 } 64 65 uint8 *ybase = (uint8 *)in->data[0]; 66 uint8 *rgbbase = (uint8 *)out->data[0]; 67 68 for (int i = 0; i <= height; i++) { 69 _Convert_YUV422_RGBA32_SSE2(ybase, rgbbase, width); 70 ybase += in->linesize[0]; 71 rgbbase += out->linesize[0]; 72 } 73 } 74 75 76 void 77 gfx_conv_yuv420p_rgba32_sse(AVFrame *in, AVFrame *out, int width, int height) 78 { 79 // Planar YUV420 80 81 // in and out buffers must be aligned to 16 bytes, 82 // in should be as ffmpeg allocates it 83 if ((off_t)out->data[0] % 16 != 0) { 84 gfx_conv_YCbCr420p_RGB32_c(in, out, width, height); 85 return; 86 } 87 88 uint8 *ybase = (uint8 *)in->data[0]; 89 uint8 *ubase = (uint8 *)in->data[1]; 90 uint8 *vbase = (uint8 *)in->data[2]; 91 uint8 *rgbbase = (uint8 *)out->data[0]; 92 93 int yBaseInc = in->linesize[0]; 94 int uBaseInc = in->linesize[1]; 95 int vBaseInc = in->linesize[2]; 96 int rgbBaseInc = out->linesize[0]; 97 98 for (int i=0;i<height;i+=2) { 99 // First Y row 100 _Convert_YUV420P_RGBA32_SSE(ybase, ubase, vbase, rgbbase, width); 101 ybase += yBaseInc; 102 rgbbase += rgbBaseInc; 103 104 // Second Y row but same u and v row 105 _Convert_YUV420P_RGBA32_SSE(ybase, ubase, vbase, rgbbase, width); 106 ybase += yBaseInc; 107 ubase += uBaseInc; 108 vbase += vBaseInc; 109 rgbbase += rgbBaseInc; 110 } 111 } 112 113 114 void 115 gfx_conv_yuv422p_rgba32_sse(AVFrame *in, AVFrame *out, int width, int height) 116 { 117 // Packed YUV422 118 119 // in and out buffers must be aligned to 16 bytes, 120 // in should be as ffmpeg allocates it 121 if ((off_t)out->data[0] % 16 != 0) { 122 gfx_conv_YCbCr422_RGB32_c(in, out, width, height); 123 return; 124 } 125 126 uint8 *ybase = (uint8 *)in->data[0]; 127 uint8 *rgbbase = (uint8 *)out->data[0]; 128 129 for (int i = 0; i <= height; i++) { 130 _Convert_YUV422_RGBA32_SSE(ybase, rgbbase, width); 131 ybase += in->linesize[0]; 132 rgbbase += out->linesize[0]; 133 } 134 } 135