xref: /haiku/src/add-ons/media/plugins/ffmpeg/gfx_conv_mmx.cpp (revision 56187df6ebd9d1fb16bf954fce8df0999e9e3048)
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