Mercurial > mplayer.hg
annotate libmpcodecs/vd_xvid4.c @ 26277:644426c3261c
Rename HAVE_XVMC_ACCEL to HAVE_XVMC for consistency and to sync with FFmpeg.
author | diego |
---|---|
date | Mon, 31 Mar 2008 17:19:51 +0000 |
parents | bb7c65f2a289 |
children | 82601a38e2a7 |
rev | line source |
---|---|
11437 | 1 /***************************************************************************** |
2 * | |
13652 | 3 * - XviD 1.x decoder module for mplayer/mencoder - |
11437 | 4 * |
13652 | 5 * Copyright(C) 2003 Marco Belli <elcabesa@inwind.it> |
6 * 2003-2004 Edouard Gomez <ed.gomez@free.fr> | |
11437 | 7 * |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
19614 | 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
11437 | 21 * |
22 *****************************************************************************/ | |
23 | |
24 /***************************************************************************** | |
25 * Includes | |
26 ****************************************************************************/ | |
27 | |
28 #include <stdio.h> | |
29 #include <stdlib.h> | |
30 | |
31 #include "config.h" | |
32 #include "mp_msg.h" | |
33 | |
34 #include "vd_internal.h" | |
35 #include "m_option.h" | |
36 | |
37 #include <xvid.h> | |
38 | |
39 /***************************************************************************** | |
40 * Configuration options | |
41 ****************************************************************************/ | |
42 | |
43 static int do_dr2 = 1; | |
11967
4f4b81257d19
Adds support for the film grain effect and deblocking filters in xvid
attila
parents:
11437
diff
changeset
|
44 static int filmeffect = 0; |
4f4b81257d19
Adds support for the film grain effect and deblocking filters in xvid
attila
parents:
11437
diff
changeset
|
45 static int lumadeblock = 0; |
4f4b81257d19
Adds support for the film grain effect and deblocking filters in xvid
attila
parents:
11437
diff
changeset
|
46 static int chromadeblock = 0; |
13652 | 47 static int lumadering = 0; |
48 static int chromadering = 0; | |
11437 | 49 |
25241
bb7c65f2a289
Make m_option_t arrays referenced by cfg-common.h const
reimar
parents:
19614
diff
changeset
|
50 const m_option_t xvid_dec_opts[] = { |
11437 | 51 { "dr2", &do_dr2, CONF_TYPE_FLAG, 0, 0, 1, NULL}, |
52 { "nodr2", &do_dr2, CONF_TYPE_FLAG, 0, 1, 0, NULL}, | |
11967
4f4b81257d19
Adds support for the film grain effect and deblocking filters in xvid
attila
parents:
11437
diff
changeset
|
53 { "filmeffect", &filmeffect, CONF_TYPE_FLAG, 0, 0, 1, NULL}, |
4f4b81257d19
Adds support for the film grain effect and deblocking filters in xvid
attila
parents:
11437
diff
changeset
|
54 { "deblock-luma", &lumadeblock, CONF_TYPE_FLAG, 0, 0, 1, NULL}, |
4f4b81257d19
Adds support for the film grain effect and deblocking filters in xvid
attila
parents:
11437
diff
changeset
|
55 { "deblock-chroma", &chromadeblock, CONF_TYPE_FLAG, 0, 0, 1, NULL}, |
13652 | 56 { "dering-luma", &lumadering, CONF_TYPE_FLAG, 0, 0, 1, NULL}, |
57 { "dering-chroma", &chromadering, CONF_TYPE_FLAG, 0, 0, 1, NULL}, | |
11437 | 58 {NULL, NULL, 0, 0, 0, 0, NULL} |
59 }; | |
60 | |
61 /***************************************************************************** | |
62 * Module private data | |
63 ****************************************************************************/ | |
64 | |
65 typedef struct { | |
66 int cs; | |
67 unsigned char img_type; | |
68 void* hdl; | |
69 mp_image_t* mpi; | |
13652 | 70 int vo_initialized; |
11437 | 71 } priv_t; |
72 | |
73 /***************************************************************************** | |
13652 | 74 * Module function helpers |
75 ****************************************************************************/ | |
76 | |
77 static float stats2aspect(xvid_dec_stats_t *stats); | |
78 | |
79 /***************************************************************************** | |
11437 | 80 * Video decoder API function definitions |
81 ****************************************************************************/ | |
82 | |
83 /*============================================================================ | |
84 * control - to set/get/query special features/parameters | |
85 *==========================================================================*/ | |
86 | |
87 static int control(sh_video_t *sh,int cmd,void* arg,...) | |
88 { | |
89 return(CONTROL_UNKNOWN); | |
90 } | |
91 | |
92 /*============================================================================ | |
93 * init - initialize the codec | |
94 *==========================================================================*/ | |
95 | |
96 static int init(sh_video_t *sh) | |
97 { | |
13652 | 98 xvid_gbl_info_t xvid_gbl_info; |
11437 | 99 xvid_gbl_init_t xvid_ini; |
100 xvid_dec_create_t dec_p; | |
101 priv_t* p; | |
102 int cs; | |
103 | |
13652 | 104 memset(&xvid_gbl_info, 0, sizeof(xvid_gbl_info_t)); |
105 xvid_gbl_info.version = XVID_VERSION; | |
106 | |
11437 | 107 memset(&xvid_ini, 0, sizeof(xvid_gbl_init_t)); |
108 xvid_ini.version = XVID_VERSION; | |
13652 | 109 |
11437 | 110 memset(&dec_p, 0, sizeof(xvid_dec_create_t)); |
111 dec_p.version = XVID_VERSION; | |
112 | |
113 | |
114 switch(sh->codec->outfmt[sh->outfmtidx]){ | |
115 case IMGFMT_YV12: | |
116 /* We will use our own buffers, this speeds decoding avoiding | |
117 * frame memcpy's overhead */ | |
118 cs = (do_dr2)?XVID_CSP_INTERNAL:XVID_CSP_USER; | |
119 break; | |
120 case IMGFMT_YUY2: | |
121 cs = XVID_CSP_YUY2; | |
122 break; | |
123 case IMGFMT_UYVY: | |
124 cs = XVID_CSP_UYVY; | |
125 break; | |
126 case IMGFMT_I420: | |
127 case IMGFMT_IYUV: | |
128 /* We will use our own buffers, this speeds decoding avoiding | |
129 * frame memcpy's overhead */ | |
130 cs = (do_dr2)?XVID_CSP_INTERNAL:XVID_CSP_USER; | |
131 break; | |
132 case IMGFMT_BGR15: | |
133 cs = XVID_CSP_RGB555; | |
134 break; | |
135 case IMGFMT_BGR16: | |
136 cs = XVID_CSP_RGB565; | |
137 break; | |
138 case IMGFMT_BGR32: | |
139 cs = XVID_CSP_BGRA; | |
140 break; | |
141 case IMGFMT_YVYU: | |
142 cs = XVID_CSP_YVYU; | |
143 break; | |
144 default: | |
145 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Unsupported out_fmt: 0x%X\n", | |
146 sh->codec->outfmt[sh->outfmtidx]); | |
147 return(0); | |
148 } | |
149 | |
13652 | 150 /* Gather some information about the host library */ |
151 if(xvid_global(NULL, XVID_GBL_INFO, &xvid_gbl_info, NULL) < 0) { | |
152 mp_msg(MSGT_MENCODER,MSGL_INFO, "xvid: could not get information about the library\n"); | |
153 } else { | |
154 mp_msg(MSGT_MENCODER,MSGL_INFO, "xvid: using library version %d.%d.%d (build %s)\n", | |
155 XVID_VERSION_MAJOR(xvid_gbl_info.actual_version), | |
156 XVID_VERSION_MINOR(xvid_gbl_info.actual_version), | |
157 XVID_VERSION_PATCH(xvid_gbl_info.actual_version), | |
158 xvid_gbl_info.build); | |
159 } | |
160 | |
161 /* Initialize the xvidcore library */ | |
11437 | 162 if(xvid_global(NULL, XVID_GBL_INIT, &xvid_ini, NULL)) |
163 return(0); | |
164 | |
13652 | 165 /* We use 0 width and height so xvidcore will resize its buffers |
166 * if required. That allows this vd plugin to do resize on first | |
167 * VOL encountered (don't trust containers' width and height) */ | |
168 dec_p.width = 0; | |
169 dec_p.height = 0; | |
11437 | 170 |
13652 | 171 /* Get a decoder instance */ |
11437 | 172 if(xvid_decore(0, XVID_DEC_CREATE, &dec_p, NULL)<0) { |
173 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "XviD init failed\n"); | |
174 return(0); | |
175 } | |
176 | |
18879 | 177 p = malloc(sizeof(priv_t)); |
11437 | 178 p->cs = cs; |
179 p->hdl = dec_p.handle; | |
13652 | 180 p->vo_initialized = 0; |
11437 | 181 sh->context = p; |
182 | |
183 switch(cs) { | |
184 case XVID_CSP_INTERNAL: | |
185 p->img_type = MP_IMGTYPE_EXPORT; | |
186 break; | |
187 case XVID_CSP_USER: | |
188 p->img_type = MP_IMGTYPE_STATIC; | |
189 break; | |
190 default: | |
191 p->img_type = MP_IMGTYPE_TEMP; | |
192 break; | |
193 } | |
194 | |
195 return(1); | |
196 } | |
197 | |
198 /*============================================================================ | |
199 * uninit - close the codec | |
200 *==========================================================================*/ | |
201 | |
202 static void uninit(sh_video_t *sh){ | |
203 priv_t* p = sh->context; | |
204 if(!p) | |
205 return; | |
206 xvid_decore(p->hdl,XVID_DEC_DESTROY, NULL, NULL); | |
207 free(p); | |
208 } | |
209 | |
210 /*============================================================================ | |
211 * decode - decode a frame from stream | |
212 *==========================================================================*/ | |
213 | |
214 static mp_image_t* decode(sh_video_t *sh, void* data, int len, int flags) | |
215 { | |
216 xvid_dec_frame_t dec; | |
13652 | 217 xvid_dec_stats_t stats; |
218 mp_image_t* mpi = NULL; | |
219 | |
11437 | 220 priv_t* p = sh->context; |
221 | |
222 | |
13652 | 223 if(!data || len <= 0) |
11437 | 224 return(NULL); |
225 | |
226 memset(&dec,0,sizeof(xvid_dec_frame_t)); | |
13652 | 227 memset(&stats, 0, sizeof(xvid_dec_stats_t)); |
11437 | 228 dec.version = XVID_VERSION; |
13652 | 229 stats.version = XVID_VERSION; |
11437 | 230 |
231 dec.bitstream = data; | |
232 dec.length = len; | |
233 | |
13652 | 234 dec.general |= XVID_LOWDELAY |
235 /* XXX: if lowdelay is unset, and xvidcore internal buffers are | |
236 * used => crash. MUST FIX */ | |
11967
4f4b81257d19
Adds support for the film grain effect and deblocking filters in xvid
attila
parents:
11437
diff
changeset
|
237 | (filmeffect ? XVID_FILMEFFECT : 0 ) |
4f4b81257d19
Adds support for the film grain effect and deblocking filters in xvid
attila
parents:
11437
diff
changeset
|
238 | (lumadeblock ? XVID_DEBLOCKY : 0 ) |
4f4b81257d19
Adds support for the film grain effect and deblocking filters in xvid
attila
parents:
11437
diff
changeset
|
239 | (chromadeblock ? XVID_DEBLOCKUV : 0 ); |
13652 | 240 #if XVID_API >= XVID_MAKE_API(4,1) |
241 dec.general |= (lumadering ? XVID_DEBLOCKY|XVID_DERINGY : 0 ); | |
242 dec.general |= (chromadering ? XVID_DEBLOCKUV|XVID_DERINGUV : 0 ); | |
243 #endif | |
11437 | 244 dec.output.csp = p->cs; |
245 | |
13652 | 246 /* Decoding loop because xvidcore may return VOL information for |
247 * on the fly buffer resizing. In that case we must decode VOL, | |
248 * init VO, then decode the frame */ | |
249 do { | |
250 int consumed; | |
251 | |
252 /* If we don't know frame size yet, don't even try to request | |
253 * a buffer, we must loop until we find a VOL, so VO plugin | |
254 * is initialized and we can obviously output something */ | |
255 if (p->vo_initialized) { | |
256 mpi = mpcodecs_get_image(sh, p->img_type, | |
257 MP_IMGFLAG_ACCEPT_STRIDE, | |
258 sh->disp_w, sh->disp_h); | |
259 | |
260 if(p->cs != XVID_CSP_INTERNAL) { | |
261 dec.output.plane[0] = mpi->planes[0]; | |
262 dec.output.plane[1] = mpi->planes[1]; | |
263 dec.output.plane[2] = mpi->planes[2]; | |
11437 | 264 |
13652 | 265 dec.output.stride[0] = mpi->stride[0]; |
266 dec.output.stride[1] = mpi->stride[1]; | |
267 dec.output.stride[2] = mpi->stride[2]; | |
268 } | |
269 } | |
270 | |
271 /* Decode data */ | |
272 consumed = xvid_decore(p->hdl, XVID_DEC_DECODE, &dec, &stats); | |
273 if (consumed < 0) { | |
274 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Decoding error\n"); | |
275 return(NULL); | |
276 } | |
11437 | 277 |
13652 | 278 /* Found a VOL information stats, if VO plugin is not initialized |
279 * yet then do it now */ | |
280 if (stats.type == XVID_TYPE_VOL && !p->vo_initialized) { | |
281 sh->aspect = stats2aspect(&stats); | |
282 if(!mpcodecs_config_vo(sh, stats.data.vol.width, stats.data.vol.height, IMGFMT_YV12)) | |
283 return(NULL); | |
284 | |
285 /* Don't take this path twice */ | |
286 p->vo_initialized = !p->vo_initialized; | |
287 } | |
11437 | 288 |
13652 | 289 /* Don't forget to update buffer position and buffer length */ |
290 dec.bitstream += consumed; | |
291 dec.length -= consumed; | |
292 } while ((stats.type == XVID_TYPE_VOL || stats.type == XVID_TYPE_NOTHING) && dec.length > 0); | |
293 | |
294 /* There are two ways to get out of the decoding loop: | |
295 * - a frame has been returned | |
296 * - no more data in buffer and no frames returned */ | |
297 | |
298 /* If mpi is NULL, it proves nothing has been returned by the decoder | |
299 * so don't try to display internal buffers. */ | |
300 if (mpi != NULL && p->cs == XVID_CSP_INTERNAL) { | |
11437 | 301 mpi->planes[0] = dec.output.plane[0]; |
302 mpi->planes[1] = dec.output.plane[1]; | |
303 mpi->planes[2] = dec.output.plane[2]; | |
304 | |
305 mpi->stride[0] = dec.output.stride[0]; | |
306 mpi->stride[1] = dec.output.stride[1]; | |
307 mpi->stride[2] = dec.output.stride[2]; | |
308 } | |
309 | |
13652 | 310 /* If we got out the decoding loop because the buffer was empty and there was nothing |
311 * to output yet, then just return NULL */ | |
312 return((stats.type == XVID_TYPE_NOTHING)? NULL: mpi); | |
313 } | |
314 | |
315 /***************************************************************************** | |
316 * Helper functions | |
317 ****************************************************************************/ | |
318 | |
319 /* Returns DAR value according to VOL's informations contained in stats | |
320 * param */ | |
321 static float stats2aspect(xvid_dec_stats_t *stats) | |
322 { | |
323 if (stats->type == XVID_TYPE_VOL) { | |
324 float wpar; | |
325 float hpar; | |
326 float dar; | |
327 | |
328 /* MPEG4 strem stores PAR (Pixel Aspect Ratio), mplayer uses | |
329 * DAR (Display Aspect Ratio) | |
330 * | |
331 * Both are related thanks to the equation: | |
332 * width | |
333 * DAR = ----- x PAR | |
334 * height | |
335 * | |
336 * As MPEG4 is so well designed (*cough*), VOL header carries | |
337 * both informations together -- lucky eh ? */ | |
338 | |
339 switch (stats->data.vol.par) { | |
340 case XVID_PAR_11_VGA: /* 1:1 vga (square), default if supplied PAR is not a valid value */ | |
341 wpar = hpar = 1.0f; | |
342 break; | |
343 case XVID_PAR_43_PAL: /* 4:3 pal (12:11 625-line) */ | |
344 wpar = 12; | |
345 hpar = 11; | |
346 break; | |
347 case XVID_PAR_43_NTSC: /* 4:3 ntsc (10:11 525-line) */ | |
348 wpar = 10; | |
349 hpar = 11; | |
350 break; | |
351 case XVID_PAR_169_PAL: /* 16:9 pal (16:11 625-line) */ | |
352 wpar = 16; | |
353 hpar = 11; | |
354 break; | |
355 case XVID_PAR_169_NTSC: /* 16:9 ntsc (40:33 525-line) */ | |
356 wpar = 40; | |
357 hpar = 33; | |
358 break; | |
359 case XVID_PAR_EXT: /* extended par; use par_width, par_height */ | |
360 wpar = stats->data.vol.par_width; | |
361 hpar = stats->data.vol.par_height; | |
362 break; | |
363 default: | |
364 wpar = hpar = 1.0f; | |
365 break; | |
366 } | |
367 | |
368 dar = ((float)stats->data.vol.width*wpar); | |
369 dar /= ((float)stats->data.vol.height*hpar); | |
370 | |
371 return(dar); | |
372 } | |
373 | |
374 return(0.0f); | |
11437 | 375 } |
376 | |
377 /***************************************************************************** | |
378 * Module structure definition | |
379 ****************************************************************************/ | |
380 | |
381 static vd_info_t info = | |
382 { | |
383 "XviD 1.0 decoder", | |
384 "xvid", | |
385 "Marco Belli <elcabesa@inwind.it>, Edouard Gomez <ed.gomez@free.fr>", | |
386 "Marco Belli <elcabesa@inwind.it>, Edouard Gomez <ed.gomez@free.fr>", | |
387 "No Comment" | |
388 }; | |
389 | |
390 LIBVD_EXTERN(xvid) | |
391 | |
392 /* Please do not change that tag comment. | |
393 * arch-tag: b7d654a5-76ea-4768-9713-2c791567fe7d mplayer xvid decoder module */ |