Mercurial > mplayer.hg
annotate libmpcodecs/vd_xvid4.c @ 22616:09dc129234a0
Matroska seeking fixes
If a relative seek forward went past the last index position the
Matroska demuxer did not seek to any index position. It did however set
the mkv_d->skip_to_timecode variable which meant that the next
fill_buffer() call would read from the current position until the target
position (probably the end of the file). Fix this by changing the code
to seek to the last index position if that is between the current and
target positions.
Also change backwards relative seek to accept an exactly matching index
position (<= vs <) and reorganize the seeking conditionals to allow
making the above change without turning the code into a complete mess.
author | uau |
---|---|
date | Fri, 16 Mar 2007 14:55:41 +0000 |
parents | 36589811e5d0 |
children | bb7c65f2a289 |
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 |
50 m_option_t xvid_dec_opts[] = { | |
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 */ |