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