Mercurial > mplayer.hg
comparison libmpcodecs/vf_pullup.c @ 10664:d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
(pullup.[ch]) is not mplayer-specific and is designed to work well
with g2; vf_pullup.c is the g1 wrapper. see man page for details, and
keep in mind, this is a work in progress.
author | rfelker |
---|---|
date | Mon, 18 Aug 2003 15:24:08 +0000 |
parents | |
children | b6b68224033d |
comparison
equal
deleted
inserted
replaced
10663:711159267b2d | 10664:d47ca466c97b |
---|---|
1 #include <stdio.h> | |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 | |
5 #include "../config.h" | |
6 #include "../mp_msg.h" | |
7 #include "../cpudetect.h" | |
8 | |
9 #include "img_format.h" | |
10 #include "mp_image.h" | |
11 #include "vf.h" | |
12 | |
13 #include "../libvo/fastmemcpy.h" | |
14 | |
15 #include "pullup.h" | |
16 | |
17 struct vf_priv_s { | |
18 struct pullup_context *ctx; | |
19 int init; | |
20 int fakecount; | |
21 }; | |
22 | |
23 static inline void *my_memcpy_pic(void * dst, void * src, int bytesPerLine, int height, int dstStride, int srcStride) | |
24 { | |
25 int i; | |
26 void *retval=dst; | |
27 | |
28 for(i=0; i<height; i++) | |
29 { | |
30 memcpy(dst, src, bytesPerLine); | |
31 src+= srcStride; | |
32 dst+= dstStride; | |
33 } | |
34 | |
35 return retval; | |
36 } | |
37 | |
38 static void init_pullup(struct vf_instance_s* vf, mp_image_t *mpi) | |
39 { | |
40 struct pullup_context *c = vf->priv->ctx; | |
41 | |
42 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
43 c->format = PULLUP_FMT_Y; | |
44 c->nplanes = 3; | |
45 pullup_preinit_context(c); | |
46 c->bpp[0] = c->bpp[1] = c->bpp[2] = 8; | |
47 c->w[0] = mpi->w; | |
48 c->h[0] = mpi->h; | |
49 c->w[1] = c->w[2] = mpi->chroma_width; | |
50 c->h[1] = c->h[2] = mpi->chroma_height; | |
51 c->stride[0] = mpi->width; | |
52 c->stride[1] = c->stride[2] = mpi->chroma_width; | |
53 c->background[1] = c->background[2] = 128; | |
54 } | |
55 | |
56 c->junk_left = c->junk_right = 1; | |
57 c->junk_top = c->junk_bottom = 4; | |
58 | |
59 if (gCpuCaps.hasMMX) c->cpu |= PULLUP_CPU_MMX; | |
60 if (gCpuCaps.hasMMX2) c->cpu |= PULLUP_CPU_MMX2; | |
61 if (gCpuCaps.has3DNow) c->cpu |= PULLUP_CPU_3DNOW; | |
62 if (gCpuCaps.has3DNowExt) c->cpu |= PULLUP_CPU_3DNOWEXT; | |
63 if (gCpuCaps.hasSSE) c->cpu |= PULLUP_CPU_SSE; | |
64 if (gCpuCaps.hasSSE2) c->cpu |= PULLUP_CPU_SSE2; | |
65 | |
66 pullup_init_context(c); | |
67 | |
68 vf->priv->init = 1; | |
69 } | |
70 | |
71 | |
72 static void get_image(struct vf_instance_s* vf, mp_image_t *mpi) | |
73 { | |
74 struct pullup_context *c = vf->priv->ctx; | |
75 struct pullup_buffer *b; | |
76 | |
77 if (mpi->type == MP_IMGTYPE_STATIC) return; | |
78 | |
79 if (!vf->priv->init) init_pullup(vf, mpi); | |
80 | |
81 b = pullup_get_buffer(c, 2); | |
82 if (!b) return; /* shouldn't happen... */ | |
83 | |
84 mpi->priv = b; | |
85 | |
86 mpi->planes[0] = b->planes[0]; | |
87 mpi->planes[1] = b->planes[1]; | |
88 mpi->planes[2] = b->planes[2]; | |
89 mpi->stride[0] = c->stride[0]; | |
90 mpi->stride[1] = c->stride[1]; | |
91 mpi->stride[2] = c->stride[2]; | |
92 | |
93 mpi->flags |= MP_IMGFLAG_DIRECT; | |
94 mpi->flags &= ~MP_IMGFLAG_DRAW_CALLBACK; | |
95 | |
96 //mpi->width = mpi->stride[0]; | |
97 } | |
98 | |
99 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi) | |
100 { | |
101 struct pullup_context *c = vf->priv->ctx; | |
102 struct pullup_buffer *b; | |
103 struct pullup_frame *f; | |
104 mp_image_t *dmpi; | |
105 int ret; | |
106 int p; | |
107 | |
108 if (!vf->priv->init) init_pullup(vf, mpi); | |
109 | |
110 if (mpi->flags & MP_IMGFLAG_DIRECT) { | |
111 b = mpi->priv; | |
112 mpi->priv = 0; | |
113 } else { | |
114 b = pullup_get_buffer(c, 2); | |
115 if (!b) { | |
116 mp_msg(MSGT_VFILTER,MSGL_ERR,"Could not get buffer from pullup!\n"); | |
117 f = pullup_get_frame(c); | |
118 pullup_release_frame(f); | |
119 return 0; | |
120 } | |
121 memcpy_pic(b->planes[0], mpi->planes[0], mpi->w, mpi->h, | |
122 c->stride[0], mpi->stride[0]); | |
123 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
124 memcpy_pic(b->planes[1], mpi->planes[1], | |
125 mpi->chroma_width, mpi->chroma_height, | |
126 c->stride[1], mpi->stride[1]); | |
127 memcpy_pic(b->planes[2], mpi->planes[2], | |
128 mpi->chroma_width, mpi->chroma_height, | |
129 c->stride[2], mpi->stride[2]); | |
130 } | |
131 } | |
132 | |
133 p = mpi->fields & MP_IMGFIELD_TOP_FIRST ? 0 : | |
134 (mpi->fields & MP_IMGFIELD_ORDERED ? 1 : 0); | |
135 //printf("p=%d\n", p); | |
136 pullup_submit_field(c, b, p); | |
137 pullup_submit_field(c, b, p^1); | |
138 if (mpi->fields & MP_IMGFIELD_REPEAT_FIRST) | |
139 pullup_submit_field(c, b, p); | |
140 | |
141 pullup_release_buffer(b, 2); | |
142 | |
143 f = pullup_get_frame(c); | |
144 | |
145 /* Fake yes for first few frames (buffer depth) to keep from | |
146 * breaking A/V sync with G1's bad architecture... */ | |
147 if (!f) return vf->priv->fakecount ? (--vf->priv->fakecount,1) : 0; | |
148 | |
149 if (f->length < 2) { | |
150 pullup_release_frame(f); | |
151 f = pullup_get_frame(c); | |
152 if (!f) return 0; | |
153 if (f->length < 2) { | |
154 pullup_release_frame(f); | |
155 return 0; | |
156 } | |
157 } | |
158 | |
159 /* If the frame isn't already exportable... */ | |
160 if (!f->buffer) { | |
161 /* FIXME: DR disabled for now */ | |
162 if (0) { | |
163 dmpi = vf_get_image(vf->next, mpi->imgfmt, | |
164 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, | |
165 mpi->width, mpi->height); | |
166 /* FIXME: draw into DR buffer */ | |
167 return vf_next_put_image(vf, dmpi); | |
168 } | |
169 pullup_pack_frame(c, f); | |
170 } | |
171 dmpi = vf_get_image(vf->next, mpi->imgfmt, | |
172 MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE, | |
173 mpi->width, mpi->height); | |
174 | |
175 dmpi->planes[0] = f->buffer->planes[0]; | |
176 dmpi->planes[1] = f->buffer->planes[1]; | |
177 dmpi->planes[2] = f->buffer->planes[2]; | |
178 | |
179 dmpi->stride[0] = c->stride[0]; | |
180 dmpi->stride[1] = c->stride[1]; | |
181 dmpi->stride[2] = c->stride[2]; | |
182 | |
183 ret = vf_next_put_image(vf, dmpi); | |
184 pullup_release_frame(f); | |
185 return ret; | |
186 } | |
187 | |
188 static int query_format(struct vf_instance_s* vf, unsigned int fmt) | |
189 { | |
190 /* FIXME - support more formats */ | |
191 switch (fmt) { | |
192 case IMGFMT_YV12: | |
193 case IMGFMT_IYUV: | |
194 case IMGFMT_I420: | |
195 return vf_next_query_format(vf, fmt); | |
196 } | |
197 return 0; | |
198 } | |
199 | |
200 static int config(struct vf_instance_s* vf, | |
201 int width, int height, int d_width, int d_height, | |
202 unsigned int flags, unsigned int outfmt) | |
203 { | |
204 if (height&3) return 0; | |
205 return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt); | |
206 } | |
207 | |
208 static void uninit(struct vf_instance_s* vf) | |
209 { | |
210 pullup_free_context(vf->priv->ctx); | |
211 free(vf->priv); | |
212 } | |
213 | |
214 static int open(vf_instance_t *vf, char* args) | |
215 { | |
216 struct vf_priv_s *p; | |
217 vf->get_image = get_image; | |
218 vf->put_image = put_image; | |
219 vf->config = config; | |
220 vf->query_format = query_format; | |
221 vf->uninit = uninit; | |
222 vf->default_reqs = VFCAP_ACCEPT_STRIDE; | |
223 vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); | |
224 p->ctx = pullup_alloc_context(); | |
225 p->fakecount = 2; | |
226 return 1; | |
227 } | |
228 | |
229 vf_info_t vf_info_pullup = { | |
230 "pullup (from field sequence to frames)", | |
231 "pullup", | |
232 "Rich Felker", | |
233 "", | |
234 open, | |
235 NULL | |
236 }; | |
237 | |
238 |