xref: /haiku/src/add-ons/media/plugins/ffmpeg/gfx_conv_mmx.cpp (revision b5be9fe6ffa8b1f99a6d52bf72503674cddf6b11)
1 #include "gfx_conv_mmx.h"
2 #include "gfx_conv_c.h"
3 
4 extern "C" void _Convert_YUV420P_RGBA32_SSE2(void *fromYPtr, void *fromUPtr, void *fromVPtr, void *toPtr, int width);
5 extern "C" void _Convert_YUV422_RGBA32_SSE2(void *fromYPtr, void *toPtr, int width);
6 
7 void gfx_conv_null_mmx(AVFrame *in, AVFrame *out, int width, int height) {
8 	memcpy(out->data[0], in->data[0], height * in->linesize[0]);
9 }
10 
11 void gfx_conv_yuv410p_ycbcr422_mmx(AVFrame *in, AVFrame *out, int width, int height)
12 {
13 //	img_convert((AVPicture *)out,PIX_FMT_YUV422P,(const AVPicture *)in,PIX_FMT_YUV410P,width,height);
14 }
15 
16 void gfx_conv_yuv411p_ycbcr422_mmx(AVFrame *in, AVFrame *out, int width, int height)
17 {
18 //	img_convert((AVPicture *)out,PIX_FMT_YUV422P,(const AVPicture *)in,PIX_FMT_YUV411P,width,height);
19 }
20 
21 void gfx_conv_yuv420p_ycbcr422_mmx(AVFrame *in, AVFrame *out, int width, int height)
22 {
23 //	img_convert((AVPicture *)out,PIX_FMT_YUV422P,(const AVPicture *)in,PIX_FMT_YUV420P,width,height);
24 }
25 
26 void gfx_conv_yuv410p_rgb32_mmx(AVFrame *in, AVFrame *out, int width, int height)
27 {
28 //	img_convert((AVPicture *)out,PIX_FMT_RGB32,(const AVPicture *)in,PIX_FMT_YUV410P,width,height);
29 }
30 
31 void gfx_conv_yuv411p_rgb32_mmx(AVFrame *in, AVFrame *out, int width, int height)
32 {
33 //	img_convert((AVPicture *)out,PIX_FMT_RGB32,(const AVPicture *)in,PIX_FMT_YUV411P,width,height);
34 }
35 
36 void gfx_conv_yuv420p_rgb32_mmx(AVFrame *in, AVFrame *out, int width, int height)
37 {
38 //	img_convert((AVPicture *)out,PIX_FMT_RGB32,(const AVPicture *)in,PIX_FMT_YUV420P,width,height);
39 }
40 
41 // Planar YUV420
42 void gfx_conv_yuv420p_rgba32_sse2(AVFrame *in, AVFrame *out, int width, int height)
43 {
44 	// in and out buffers must be aligned to 32 bytes, in should be as ffmpeg allocates it
45 	if ((off_t)out->data[0] % 32 == 0) {
46 
47 		uint8 *ybase = (uint8 *)in->data[0];
48 		uint8 *ubase = (uint8 *)in->data[1];
49 		uint8 *vbase = (uint8 *)in->data[2];
50 		uint8 *rgbbase = (uint8 *)out->data[0];
51 
52 		int yBaseInc = in->linesize[0];
53 		int uBaseInc = in->linesize[1];
54 		int vBaseInc = in->linesize[2];
55 		int rgbBaseInc = out->linesize[0];
56 
57 		for (int i=0;i<height;i+=2) {
58 			_Convert_YUV420P_RGBA32_SSE2(ybase, ubase, vbase, rgbbase, width);	// First Y row
59 			ybase += yBaseInc;
60 			rgbbase += rgbBaseInc;
61 
62 			_Convert_YUV420P_RGBA32_SSE2(ybase, ubase, vbase, rgbbase, width);	// Second Y row but same u and v row
63 			ybase += yBaseInc;
64 			ubase += uBaseInc;
65 			vbase += vBaseInc;
66 			rgbbase += rgbBaseInc;
67 		}
68 	} else {
69 		gfx_conv_YCbCr420p_RGB32_c(in, out, width, height);
70 	}
71 }
72 
73 // Packed YUV422
74 void gfx_conv_yuv422p_rgba32_sse2(AVFrame *in, AVFrame *out, int width, int height)
75 {
76 	// in and out buffers must be aligned to 32 bytes, in should be as ffmpeg allocates it
77 	if ((off_t)out->data[0] % 32 == 0) {
78 
79 		uint8 *ybase = (uint8 *)in->data[0];
80 		uint8 *rgbbase = (uint8 *)out->data[0];
81 
82 		for (int i = 0; i <= height; i++) {
83 			_Convert_YUV422_RGBA32_SSE2(ybase, rgbbase, width);
84 			ybase += in->linesize[0];
85 			rgbbase += out->linesize[0];
86 		}
87 	} else {
88 		gfx_conv_YCbCr422_RGB32_c(in, out, width, height);
89 	}
90 }
91