comparison libmpcodecs/vf_ilpack.c @ 9933:3548701a13fe

1. new alternate approach to inverse telecine! much better! 2. interlaced 4:2:0 planar to 4:2:2 packer. makes it possible to watch interlaced movies without horrible chroma artifacts, provided you have an interlaced display device.
author rfelker
date Sat, 19 Apr 2003 01:39:37 +0000
parents
children 3ddfe9316ca9
comparison
equal deleted inserted replaced
9932:208fcee0aa2d 9933:3548701a13fe
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <inttypes.h>
5
6 #include "../config.h"
7 #include "../mp_msg.h"
8 #include "../cpudetect.h"
9
10 #include "img_format.h"
11 #include "mp_image.h"
12 #include "vf.h"
13
14 #include "../libvo/fastmemcpy.h"
15 #include "../postproc/rgb2rgb.h"
16
17 #ifdef HAVE_MMX
18 static void pack_MMX(unsigned char *dst, unsigned char *y,
19 unsigned char *u, unsigned char *v, int w)
20 {
21 int j;
22 asm (""
23 "pxor %%mm0, %%mm0 \n\t"
24 ".balign 16 \n\t"
25 "1: \n\t"
26 "movq (%0), %%mm1 \n\t"
27 "movq (%0), %%mm2 \n\t"
28 "punpcklbw %%mm0, %%mm1 \n\t"
29 "punpckhbw %%mm0, %%mm2 \n\t"
30
31 "movq (%1), %%mm3 \n\t"
32 "movq (%2), %%mm5 \n\t"
33 "punpcklbw %%mm0, %%mm3 \n\t"
34 "punpcklbw %%mm0, %%mm5 \n\t"
35 "movq %%mm3, %%mm4 \n\t"
36 "movq %%mm5, %%mm6 \n\t"
37 "punpcklwd %%mm0, %%mm3 \n\t"
38 "punpckhwd %%mm0, %%mm4 \n\t"
39 "punpcklwd %%mm0, %%mm5 \n\t"
40 "punpckhwd %%mm0, %%mm6 \n\t"
41 "pslld $8, %%mm3 \n\t"
42 "pslld $8, %%mm4 \n\t"
43 "pslld $24, %%mm5 \n\t"
44 "pslld $24, %%mm6 \n\t"
45
46 "por %%mm3, %%mm1 \n\t"
47 "por %%mm4, %%mm2 \n\t"
48 "por %%mm5, %%mm1 \n\t"
49 "por %%mm6, %%mm2 \n\t"
50
51 "addl $8, %0 \n\t"
52 "addl $4, %1 \n\t"
53 "addl $4, %2 \n\t"
54 "movq %%mm1, (%3) \n\t"
55 "movq %%mm2, 8(%3) \n\t"
56 "addl $16, %3 \n\t"
57 "decl %4 \n\t"
58 "jnz 1b \n\t"
59 :
60 : "r" (y), "r" (u), "r" (v), "r" (dst), "r" (w/8)
61 : "memory"
62 );
63 for (j = (w&7)/2; j; j--) {
64 *dst++ = *y++;
65 *dst++ = *u++;
66 *dst++ = *y++;
67 *dst++ = *v++;
68 }
69 asm volatile ( "emms \n\t" ::: "memory" );
70 }
71 #endif
72
73 static void pack_C(unsigned char *dst, unsigned char *y,
74 unsigned char *u, unsigned char *v, int w)
75 {
76 int j;
77 for (j = w/2; j; j--) {
78 *dst++ = *y++;
79 *dst++ = *u++;
80 *dst++ = *y++;
81 *dst++ = *v++;
82 }
83 }
84
85 static void (*pack)(unsigned char *dst, unsigned char *y,
86 unsigned char *u, unsigned char *v, int w);
87
88 static void ilpack(unsigned char *dst, unsigned char *src[3],
89 unsigned int dststride, unsigned int srcstride[3], int w, int h)
90 {
91 int i;
92 unsigned char *y, *u, *v;
93
94 y = src[0];
95 u = src[1];
96 v = src[2];
97
98 for (i=0; i<h; i++) {
99 pack(dst, y, u, v, w);
100 y += srcstride[0];
101 if ((i&3) == 1) {
102 u -= srcstride[1];
103 v -= srcstride[2];
104 } else {
105 u += srcstride[1];
106 v += srcstride[2];
107 }
108 dst += dststride;
109 }
110 }
111
112
113 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi)
114 {
115 mp_image_t *dmpi;
116
117 // hope we'll get DR buffer:
118 dmpi=vf_get_image(vf->next, IMGFMT_YUY2,
119 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
120 mpi->w, mpi->h);
121
122 ilpack(dmpi->planes[0], mpi->planes, dmpi->stride[0], mpi->stride, mpi->w, mpi->h);
123
124 return vf_next_put_image(vf,dmpi);
125 }
126
127 static int config(struct vf_instance_s* vf,
128 int width, int height, int d_width, int d_height,
129 unsigned int flags, unsigned int outfmt)
130 {
131 /* FIXME - also support UYVY output? */
132 return vf_next_config(vf, width, height, d_width, d_height, flags, IMGFMT_YUY2);
133 }
134
135
136 static int query_format(struct vf_instance_s* vf, unsigned int fmt)
137 {
138 /* FIXME - really any YUV 4:2:0 input format should work */
139 switch (fmt) {
140 case IMGFMT_YV12:
141 case IMGFMT_IYUV:
142 case IMGFMT_I420:
143 return vf_next_query_format(vf,IMGFMT_YUY2);
144 }
145 return 0;
146 }
147
148 static int open(vf_instance_t *vf, char* args)
149 {
150 vf->config=config;
151 vf->query_format=query_format;
152 vf->put_image=put_image;
153
154 pack = pack_C;
155 #ifdef HAVE_MMX
156 if(gCpuCaps.hasMMX) pack = pack_MMX;
157 #endif
158 return 1;
159 }
160
161 vf_info_t vf_info_ilpack = {
162 "4:2:0 planar -> 4:2:2 packed reinterlacer",
163 "ilpack",
164 "Richard Felker",
165 "",
166 open,
167 NULL
168 };
169