]> git.sesse.net Git - vlc/blob - modules/codec/xvmc/xxmc.c
78531bf3601bdd3884bcda414157c2e81e96ced4
[vlc] / modules / codec / xvmc / xxmc.c
1 /*****************************************************************************
2  * xxmc.c : HW MPEG decoder thread
3  *****************************************************************************
4  * Copyright (C) 2000-2001 VideoLAN
5  * $Id$
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  *          Laurent Aimar <fenrir@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc/vlc.h>
33 #include <vlc_vout.h>
34 #include <vlc_codec.h>
35 #include <vlc_codec_synchro.h>
36
37 #include <unistd.h>
38 #ifdef __GLIBC__
39     #include <mcheck.h>
40 #endif
41
42 #include "mpeg2.h"
43 #include "attributes.h"
44 #include "mpeg2_internal.h"
45 #include "xvmc_vld.h"
46
47 /* Aspect ratio (ISO/IEC 13818-2 section 6.3.3, table 6-3) */
48 #define AR_SQUARE_PICTURE       1                           /* square pixels */
49 #define AR_3_4_PICTURE          2                        /* 3:4 picture (TV) */
50 #define AR_16_9_PICTURE         3              /* 16:9 picture (wide screen) */
51 #define AR_221_1_PICTURE        4                  /* 2.21:1 picture (movie) */
52
53 /*****************************************************************************
54  * decoder_sys_t : libmpeg2 decoder descriptor
55  *****************************************************************************/
56 struct decoder_sys_t
57 {
58     /*
59      * libmpeg2 properties
60      */
61     mpeg2dec_t          *p_mpeg2dec;
62     const mpeg2_info_t  *p_info;
63     bool                b_skip;
64
65     /*
66      * Input properties
67      */
68     mtime_t             i_pts;
69     mtime_t             i_previous_pts;
70     mtime_t             i_current_pts;
71     mtime_t             i_previous_dts;
72     mtime_t             i_current_dts;
73     int                 i_current_rate;
74     picture_t *         p_picture_to_destroy;
75     bool                b_garbage_pic;
76     bool                b_after_sequence_header; /* is it the next frame after
77                                                   * the sequence header ?    */
78     bool                b_slice_i;             /* intra-slice refresh stream */
79
80     /*
81      * Output properties
82      */
83     decoder_synchro_t   *p_synchro;
84     int                 i_aspect;
85     mtime_t             i_last_frame_pts;
86 };
87
88 /*****************************************************************************
89  * Local prototypes
90  *****************************************************************************/
91
92 static int  OpenDecoder( vlc_object_t * );
93 static void CloseDecoder( vlc_object_t * );
94
95 static picture_t *DecodeBlock( decoder_t *, block_t ** );
96
97 static picture_t *GetNewPicture( decoder_t *, uint8_t ** );
98
99 /*****************************************************************************
100  * Module descriptor
101  *****************************************************************************/
102 vlc_module_begin();
103     set_description( _("MPEG I/II hw video decoder (using libmpeg2)") );
104     set_capability( "decoder", 140 );
105     set_callbacks( OpenDecoder, CloseDecoder );
106     add_shortcut( "xxmc" );
107 vlc_module_end();
108
109 /*****************************************************************************
110  * OpenDecoder: probe the decoder and return score
111  *****************************************************************************/
112 static int OpenDecoder( vlc_object_t *p_this )
113 {
114
115     decoder_t *p_dec = (decoder_t*)p_this;
116     decoder_sys_t *p_sys = NULL;
117     uint32_t i_accel = 0;
118     FILE *f_wd_dec; 
119
120 #ifdef __GLIBC__
121     mtrace();
122 #endif
123     if( p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','v') &&
124         p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','1') &&
125         /* Pinnacle hardware-mpeg1 */
126         p_dec->fmt_in.i_codec != VLC_FOURCC('P','I','M','1') &&
127         /* VIA hardware-mpeg2 */
128         p_dec->fmt_in.i_codec != VLC_FOURCC('X','x','M','C') &&
129         /* ATI Video */
130         p_dec->fmt_in.i_codec != VLC_FOURCC('V','C','R','2') &&
131         p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','2') )
132     {
133         return VLC_EGENERIC;
134     }
135
136     msg_Dbg(p_dec, "OpenDecoder Entering");
137
138     /* Allocate the memory needed to store the decoder's structure */
139     p_dec->p_sys = p_sys = (decoder_sys_t *)malloc(sizeof(decoder_sys_t));
140     if( !p_sys )
141         return VLC_ENOMEM;
142
143     /* Initialize the thread properties */
144     memset( p_sys, 0, sizeof(decoder_sys_t) );
145     p_sys->p_mpeg2dec = NULL;
146     p_sys->p_synchro  = NULL;
147     p_sys->p_info     = NULL;
148     p_sys->i_pts      = mdate() + DEFAULT_PTS_DELAY;
149     p_sys->i_current_pts  = 0;
150     p_sys->i_previous_pts = 0;
151     p_sys->i_current_dts  = 0;
152     p_sys->i_previous_dts = 0;
153     p_sys->p_picture_to_destroy = NULL;
154     p_sys->b_garbage_pic = 0;
155     p_sys->b_slice_i  = 0;
156     p_sys->b_skip     = 0;
157
158 #if defined( __i386__ )
159     if( vlc_CPU() & CPU_CAPABILITY_MMX )
160     {
161         i_accel |= MPEG2_ACCEL_X86_MMX;
162     }
163
164     if( vlc_CPU() & CPU_CAPABILITY_3DNOW )
165     {
166         i_accel |= MPEG2_ACCEL_X86_3DNOW;
167     }
168
169     if( vlc_CPU() & CPU_CAPABILITY_MMXEXT )
170     {
171         i_accel |= MPEG2_ACCEL_X86_MMXEXT;
172     }
173
174 #elif defined( __powerpc__ ) || defined( SYS_DARWIN )
175     if( vlc_CPU() & CPU_CAPABILITY_ALTIVEC )
176     {
177         i_accel |= MPEG2_ACCEL_PPC_ALTIVEC;
178     }
179
180 #else
181     /* If we do not know this CPU, trust libmpeg2's feature detection */
182     i_accel = MPEG2_ACCEL_DETECT;
183
184 #endif
185
186     /* Set CPU acceleration features */
187     mpeg2_accel( i_accel );
188
189     /* Initialize decoder */
190     p_sys->p_mpeg2dec = mpeg2_init();
191     if( p_sys->p_mpeg2dec == NULL)
192     {
193         msg_Err( p_dec, "mpeg2_init() failed" );
194         free( p_sys );
195         return VLC_EGENERIC;
196     }
197
198     p_sys->p_info = mpeg2_info( p_sys->p_mpeg2dec );
199
200     p_dec->pf_decode_video = DecodeBlock;
201
202     f_wd_dec = fopen("/vlc/dec_pid", "w");
203     if (f_wd_dec != NULL)
204     {
205         fprintf(f_wd_dec, "%d\n", getpid());
206         fflush(f_wd_dec);
207         fclose(f_wd_dec);
208     }
209
210     msg_Dbg(p_dec, "OpenDecoder Leaving");
211     return VLC_SUCCESS;
212 }
213
214 static void WriteDecodeFile(int value)
215 {
216     FILE *f_wd_ok;
217
218     f_wd_ok = fopen("/vlc/dec_ok", "w");
219     if (f_wd_ok != NULL)
220     {
221         fprintf(f_wd_ok, "%d", value);
222         fflush(f_wd_ok);
223         fclose(f_wd_ok);
224     }
225 }
226
227 /*****************************************************************************
228  * RunDecoder: the libmpeg2 decoder
229  *****************************************************************************/
230 static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
231 {
232     decoder_sys_t   *p_sys = p_dec->p_sys;
233     mpeg2_state_t   state;
234     picture_t       *p_pic;
235
236     block_t *p_block;
237
238     if( !pp_block || !*pp_block )
239         return NULL;
240
241     p_block = *pp_block;
242     while( 1 )
243     {
244         state = mpeg2_parse( p_sys->p_mpeg2dec );
245         switch( state )
246         {
247             case STATE_BUFFER:
248                 if( !p_block->i_buffer )
249                 {
250                     block_Release( p_block );
251                     return NULL;
252                 }
253                 if( (p_block->i_flags&BLOCK_FLAG_DISCONTINUITY) &&
254                     p_sys->p_synchro &&
255                     p_sys->p_info->sequence &&
256                     p_sys->p_info->sequence->width != (unsigned int)-1 )
257                 {
258                     decoder_SynchroReset( p_sys->p_synchro );
259                     if( p_sys->p_info->current_fbuf != NULL
260                         && p_sys->p_info->current_fbuf->id != NULL )
261                     {
262                         p_sys->b_garbage_pic = 1;
263                         p_pic = p_sys->p_info->current_fbuf->id;
264                     }
265                     else
266                     {
267                         uint8_t *buf[3];
268                         buf[0] = buf[1] = buf[2] = NULL;
269                         if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
270                             break;
271                         mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
272                     }
273                     p_sys->p_picture_to_destroy = p_pic;
274
275                     if ( p_sys->b_slice_i )
276                     {
277                         decoder_SynchroNewPicture( p_sys->p_synchro,
278                             I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate,
279                             p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
280                         decoder_SynchroDecode( p_sys->p_synchro );
281                         decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
282                     }
283                 }
284
285 #ifdef PIC_FLAG_PTS
286                 if( p_block->i_pts )
287                 {
288                     mpeg2_pts( p_sys->p_mpeg2dec, (uint32_t)p_block->i_pts );
289
290 #else /* New interface */
291                 if( p_block->i_pts || p_block->i_dts )
292                 {
293                     mpeg2_tag_picture( p_sys->p_mpeg2dec,
294                                         (uint32_t)p_block->i_pts,
295                                         (uint32_t)p_block->i_dts );
296 #endif
297                     p_sys->i_previous_pts = p_sys->i_current_pts;
298                     p_sys->i_current_pts = p_block->i_pts;
299                     p_sys->i_previous_dts = p_sys->i_current_dts;
300                     p_sys->i_current_dts = p_block->i_dts;
301                 }
302                 p_sys->i_current_rate = p_block->i_rate;
303
304                 mpeg2_buffer( p_sys->p_mpeg2dec, p_block->p_buffer,
305                                 p_block->p_buffer + p_block->i_buffer );
306                 p_block->i_buffer = 0;
307                 break;
308
309             case STATE_SEQUENCE:
310             {
311                 /* Initialize video output */
312                 uint8_t *buf[3];
313                 buf[0] = buf[1] = buf[2] = NULL;
314
315                 /* Check whether the input gave a particular aspect ratio */
316                 if( p_dec->fmt_in.video.i_aspect )
317                 {
318                     p_sys->i_aspect = p_dec->fmt_in.video.i_aspect;
319                     if( p_sys->i_aspect <= AR_221_1_PICTURE )
320                     switch( p_sys->i_aspect )
321                     {
322                     case AR_3_4_PICTURE:
323                         p_sys->i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
324                         break;
325                     case AR_16_9_PICTURE:
326                         p_sys->i_aspect = VOUT_ASPECT_FACTOR * 16 / 9;
327                         break;
328                     case AR_221_1_PICTURE:
329                         p_sys->i_aspect = VOUT_ASPECT_FACTOR * 221 / 100;
330                         break;
331                     case AR_SQUARE_PICTURE:
332                         p_sys->i_aspect = VOUT_ASPECT_FACTOR *
333                                     p_sys->p_info->sequence->width /
334                                     p_sys->p_info->sequence->height;
335                         break;
336                     }
337                 }
338                 else
339                 {
340                     /* Use the value provided in the MPEG sequence header */
341                     if( p_sys->p_info->sequence->pixel_height > 0 )
342                     {
343                         p_sys->i_aspect =
344                             ((uint64_t)p_sys->p_info->sequence->display_width) *
345                             p_sys->p_info->sequence->pixel_width *
346                             VOUT_ASPECT_FACTOR /
347                             p_sys->p_info->sequence->display_height /
348                             p_sys->p_info->sequence->pixel_height;
349                     }
350                     else
351                     {
352                         /* Invalid aspect, assume 4:3.
353                         * This shouldn't happen and if it does it is a bug
354                         * in libmpeg2 (likely triggered by an invalid stream) */
355                         p_sys->i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
356                     }
357                 }
358
359                 msg_Dbg( p_dec, "%dx%d, aspect %d, %u.%03u fps",
360                         p_sys->p_info->sequence->width,
361                         p_sys->p_info->sequence->height, p_sys->i_aspect,
362                         (uint32_t)((uint64_t)1001000000 * 27 /
363                             p_sys->p_info->sequence->frame_period / 1001),
364                         (uint32_t)((uint64_t)1001000000 * 27 /
365                             p_sys->p_info->sequence->frame_period % 1001) );
366
367                 mpeg2_custom_fbuf( p_sys->p_mpeg2dec, 1 );
368
369                 /* Set the first 2 reference frames */
370                 mpeg2_set_buf( p_sys->p_mpeg2dec, buf, NULL );
371
372                 if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
373                 {
374                     block_Release( p_block );
375                     return NULL;
376                 }
377                 mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
378
379                 p_pic->date = 0;
380                 p_dec->pf_picture_link( p_dec, p_pic );
381
382                 if( p_sys->p_synchro )
383                 {
384                     decoder_SynchroRelease( p_sys->p_synchro );
385                 }
386                 p_sys->p_synchro = decoder_SynchroInit( p_dec,
387                     (uint32_t)((uint64_t)1001000000 * 27 /
388                     p_sys->p_info->sequence->frame_period) );
389                 p_sys->b_after_sequence_header = 1;
390             }
391             break;
392
393             case STATE_PICTURE_2ND:
394                 decoder_SynchroNewPicture( p_sys->p_synchro,
395                         p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
396                         p_sys->p_info->current_picture->nb_fields,
397                         0, 0, p_sys->i_current_rate,
398                         p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
399
400                 if( p_sys->b_skip )
401                 {
402                     decoder_SynchroTrash( p_sys->p_synchro );
403                 }
404                 else
405                 {
406                     decoder_SynchroDecode( p_sys->p_synchro );
407                 }
408                 break;
409
410             case STATE_PICTURE:
411             {
412                 uint8_t *buf[3];
413                 mtime_t i_pts;
414                 buf[0] = buf[1] = buf[2] = NULL;
415
416                 if ( p_sys->b_after_sequence_header &&
417                     ((p_sys->p_info->current_picture->flags &
418                         PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_P) )
419                 {
420                     /* Intra-slice refresh. Simulate a blank I picture. */
421                     msg_Dbg( p_dec, "intra-slice refresh stream" );
422                     decoder_SynchroNewPicture( p_sys->p_synchro,
423                         I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate,
424                         p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
425                     decoder_SynchroDecode( p_sys->p_synchro );
426                     decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
427                     p_sys->b_slice_i = 1;
428                 }
429                 p_sys->b_after_sequence_header = 0;
430
431 #ifdef PIC_FLAG_PTS
432                 i_pts = p_sys->p_info->current_picture->flags & PIC_FLAG_PTS ?
433                     ( ( p_sys->p_info->current_picture->pts ==
434                         (uint32_t)p_sys->i_current_pts ) ?
435                     p_sys->i_current_pts : p_sys->i_previous_pts ) : 0;
436 #else /* New interface */
437                 i_pts = p_sys->p_info->current_picture->flags & PIC_FLAG_TAGS ?
438                     ( ( p_sys->p_info->current_picture->tag ==
439                         (uint32_t)p_sys->i_current_pts ) ?
440                     p_sys->i_current_pts : p_sys->i_previous_pts ) : 0;
441 #endif
442                 /* Hack to handle demuxers which only have DTS timestamps */
443                 if( !i_pts && !p_block->i_pts && p_block->i_dts > 0 )
444                 {
445                     if( p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ||
446                         (p_sys->p_info->current_picture->flags &
447                         PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_B )
448                     {
449                         i_pts = p_block->i_dts;
450                     }
451                 }
452                 p_block->i_pts = p_block->i_dts = 0;
453                 /* End hack */
454
455                 decoder_SynchroNewPicture( p_sys->p_synchro,
456                     p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
457                     p_sys->p_info->current_picture->nb_fields, i_pts,
458                     0, p_sys->i_current_rate,
459                     p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
460
461                 if ( !(p_sys->b_slice_i
462                     && ((p_sys->p_info->current_picture->flags
463                             & PIC_MASK_CODING_TYPE) == P_CODING_TYPE))
464                     && !decoder_SynchroChoose( p_sys->p_synchro,
465                                 p_sys->p_info->current_picture->flags
466                                     & PIC_MASK_CODING_TYPE,
467                                 /*FindVout(p_dec)->render_time*/ 0 /*FIXME*/,
468                                 p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ) )
469                 {
470                     mpeg2_skip( p_sys->p_mpeg2dec, 1 );
471                     p_sys->b_skip = 1;
472                     decoder_SynchroTrash( p_sys->p_synchro );
473                     mpeg2_set_buf( p_sys->p_mpeg2dec, buf, NULL );
474                 }
475                 else
476                 {
477                     mpeg2_skip( p_sys->p_mpeg2dec, 0 );
478                     p_sys->b_skip = 0;
479                     decoder_SynchroDecode( p_sys->p_synchro );
480
481                     if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
482                     {
483                         block_Release( p_block );
484                         return NULL;
485                     }
486
487                     p_sys->p_mpeg2dec->ptr_forward_ref_picture = p_sys->p_mpeg2dec->fbuf[2]->id;
488                     p_sys->p_mpeg2dec->ptr_backward_ref_picture = p_sys->p_mpeg2dec->fbuf[1]->id;
489
490                     if ((p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE) != B_CODING_TYPE)
491                     {
492                         //if (p_sys->p_mpeg2dec->ptr_forward_ref_picture &&
493                         //    p_sys->p_mpeg2dec->ptr_forward_ref_picture != picture->backward_reference_frame)
494                         //    p_pic->forward_reference_frame->free (p_pic->forward_reference_frame);
495
496                         p_sys->p_mpeg2dec->ptr_forward_ref_picture =
497                                     p_sys->p_mpeg2dec->ptr_backward_ref_picture;
498                         p_sys->p_mpeg2dec->ptr_backward_ref_picture = (void *)p_pic;
499                     }
500                     mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
501                 }
502             }
503             break;
504
505             case STATE_END:
506             case STATE_SLICE:
507                 p_pic = NULL;
508                 if( p_sys->p_info->display_fbuf
509                     && p_sys->p_info->display_fbuf->id )
510                 {
511                     p_pic = (picture_t *)p_sys->p_info->display_fbuf->id;
512
513                     decoder_SynchroEnd( p_sys->p_synchro,
514                                 p_sys->p_info->display_picture->flags
515                                 & PIC_MASK_CODING_TYPE,
516                                 p_sys->b_garbage_pic );
517                     p_sys->b_garbage_pic = 0;
518
519                     if ( p_sys->p_picture_to_destroy != p_pic )
520                     {
521                         p_pic->date = decoder_SynchroDate( p_sys->p_synchro );
522                     }
523                     else
524                     {
525                         p_sys->p_picture_to_destroy = NULL;
526                         p_pic->date = 0;
527                     }
528                 }
529
530                 if( p_sys->p_info->discard_fbuf &&
531                     p_sys->p_info->discard_fbuf->id )
532                 {
533                     p_dec->pf_picture_unlink( p_dec, p_sys->p_info->discard_fbuf->id );
534                 }
535                 /* For still frames */
536                 //if( state == STATE_END && p_pic ) p_pic->b_force = true;
537
538                 if( p_pic )
539                 {
540 #if 0
541                     /* Avoid frames with identical timestamps.
542                      * Especially needed for still frames in DVD menus. */
543                      if( p_sys->i_last_frame_pts == p_pic->date ) p_pic->date++;
544                         p_sys->i_last_frame_pts = p_pic->date;
545 #endif
546                     return p_pic;
547                 }
548                 break;
549
550             case STATE_INVALID:
551             {
552                 uint8_t *buf[3];
553                 buf[0] = buf[1] = buf[2] = NULL;
554
555                 msg_Warn( p_dec, "invalid picture encountered" );
556                 if ( ( p_sys->p_info->current_picture == NULL ) ||
557                 ( ( p_sys->p_info->current_picture->flags &
558                     PIC_MASK_CODING_TYPE) != B_CODING_TYPE ) )
559                 {
560                     if( p_sys->p_synchro ) decoder_SynchroReset( p_sys->p_synchro );
561                 }
562                 mpeg2_skip( p_sys->p_mpeg2dec, 1 );
563                 p_sys->b_skip = 1;
564
565                 if( p_sys->p_info->current_fbuf &&
566                     p_sys->p_info->current_fbuf->id )
567                 {
568                     p_sys->b_garbage_pic = 1;
569                     p_pic = p_sys->p_info->current_fbuf->id;
570                 }
571                 else if( !p_sys->p_info->sequence )
572                 {
573                     break;
574                 }
575                 else
576                 {
577                     if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
578                         break;
579                     mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
580                 }
581                 p_sys->p_picture_to_destroy = p_pic;
582
583                 memset( p_pic->p[0].p_pixels, 0,
584                         p_sys->p_info->sequence->width
585                         * p_sys->p_info->sequence->height );
586                 memset( p_pic->p[1].p_pixels, 0x80,
587                         p_sys->p_info->sequence->width
588                         * p_sys->p_info->sequence->height / 4 );
589                 memset( p_pic->p[2].p_pixels, 0x80,
590                         p_sys->p_info->sequence->width
591                         * p_sys->p_info->sequence->height / 4 );
592
593                 if( p_sys->b_slice_i )
594                 {
595                     decoder_SynchroNewPicture( p_sys->p_synchro,
596                         I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate,
597                         p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
598                     decoder_SynchroDecode( p_sys->p_synchro );
599                     decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
600                 }
601                 break;
602             }
603
604             default:
605                 break;
606         }
607     }
608     return NULL;
609 }
610
611 /*****************************************************************************
612  * CloseDecoder: libmpeg2 decoder destruction
613  *****************************************************************************/
614 static void CloseDecoder( vlc_object_t *p_this )
615 {
616     decoder_t *p_dec = (decoder_t *)p_this;
617     decoder_sys_t *p_sys = p_dec->p_sys;
618     FILE *f_wd_dec;
619
620     if( p_sys->p_synchro ) decoder_SynchroRelease( p_sys->p_synchro );
621     if( p_sys->p_mpeg2dec ) mpeg2_close( p_sys->p_mpeg2dec );
622
623     f_wd_dec = fopen("/vlc/dec_pid", "w");
624     if (f_wd_dec != NULL)
625     {
626         fprintf(f_wd_dec, "0\n");
627         fflush(f_wd_dec);
628         fclose(f_wd_dec);
629     }
630     free( p_sys );
631 }
632
633 static double get_aspect_ratio( decoder_t *p_dec )
634 {
635     decoder_sys_t *p_sys = p_dec->p_sys;
636     double ratio;
637     double mpeg1_pel_ratio[16] = {1.0 /* forbidden */,
638         1.0, 0.6735, 0.7031, 0.7615, 0.8055, 0.8437, 0.8935, 0.9157,
639         0.9815, 1.0255, 1.0695, 1.0950, 1.1575, 1.2015, 1.0 /*reserved*/ };
640
641     if( !p_sys->p_mpeg2dec->decoder.mpeg1 )
642     {
643         /* these hardcoded values are defined on mpeg2 standard for
644         * aspect ratio. other values are reserved or forbidden.  */
645         switch( p_sys->p_mpeg2dec->decoder.aspect_ratio_information )
646         {
647             case 2:
648                 ratio = 4.0/3.0;
649                 break;
650             case 3:
651                 ratio = 16.0/9.0;
652                 break;
653             case 4:
654                 ratio = 2.11/1.0;
655                 break;
656             case 1:
657                 default:
658                 ratio = (double)p_sys->p_mpeg2dec->decoder.width/(double)p_sys->p_mpeg2dec->decoder.height;
659             break;
660         }
661     }
662     else
663     {
664         /* mpeg1 constants refer to pixel aspect ratio */
665         ratio = (double)p_sys->p_mpeg2dec->decoder.width/(double)p_sys->p_mpeg2dec->decoder.height;
666         ratio /= mpeg1_pel_ratio[p_sys->p_mpeg2dec->decoder.aspect_ratio_information];
667     }
668     return ratio;
669 }
670 /*****************************************************************************
671  * GetNewPicture: Get a new picture from the vout and set the buf struct
672  *****************************************************************************/
673 static picture_t *GetNewPicture( decoder_t *p_dec, uint8_t **pp_buf )
674 {
675     //msg_Dbg(p_dec, "GetNewPicture Entering");
676     decoder_sys_t *p_sys = p_dec->p_sys;
677     picture_t *p_pic;
678
679     p_dec->fmt_out.video.i_width = p_sys->p_info->sequence->width;
680     p_dec->fmt_out.video.i_height = p_sys->p_info->sequence->height;
681     p_dec->fmt_out.video.i_aspect = p_sys->i_aspect;
682
683     if( p_sys->p_info->sequence->frame_period > 0 )
684     {
685         p_dec->fmt_out.video.i_frame_rate =
686             (uint32_t)( (uint64_t)1001000000 * 27 /
687                         p_sys->p_info->sequence->frame_period );
688         p_dec->fmt_out.video.i_frame_rate_base = 1001;
689     }
690
691     p_dec->fmt_out.i_codec =
692         ( p_sys->p_info->sequence->chroma_height <
693           p_sys->p_info->sequence->height ) ?
694         VLC_FOURCC('I','4','2','0') : VLC_FOURCC('I','4','2','2');
695
696 #if 0
697     p_sys->f_wd_nb = fopen("/vlc/dec_nb", "w");
698     if (p_sys->f_wd_nb != NULL)
699     {
700 //      fprintf(p_sys->f_wd_nb, "%d\n", mdate());
701         fprintf(p_sys->f_wd_nb, "%s\n", mdate());
702         fflush(p_sys->f_wd_nb);
703     }
704 #endif
705     p_pic = p_dec->pf_vout_buffer_new( p_dec );
706
707     if( p_pic == NULL ) return NULL;
708
709     p_pic->b_progressive = p_sys->p_info->current_picture != NULL ?
710         p_sys->p_info->current_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME : 1;
711     p_pic->b_top_field_first = p_sys->p_info->current_picture != NULL ?
712         p_sys->p_info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST : 1;
713     p_pic->i_nb_fields = p_sys->p_info->current_picture != NULL ?
714         p_sys->p_info->current_picture->nb_fields : 2;
715     p_pic->format.i_frame_rate = p_dec->fmt_out.video.i_frame_rate;
716     p_pic->format.i_frame_rate_base = p_dec->fmt_out.video.i_frame_rate_base;
717
718     p_dec->pf_picture_link( p_dec, p_pic );
719
720     pp_buf[0] = p_pic->p[0].p_pixels;
721     pp_buf[1] = p_pic->p[1].p_pixels;
722     pp_buf[2] = p_pic->p[2].p_pixels;
723
724     /* let driver ensure this image has the right format */
725 #if 0
726     this->driver->update_frame_format( p_pic->p_sys->p_vout, p_pic,
727                                        p_dec->fmt_out.video.i_width,
728                                        p_dec->fmt_out.video.i_height,
729                                        p_dec->fmt_out.video.i_aspect,
730                                        format, flags);
731 #endif
732     mpeg2_xxmc_choose_coding( p_dec, &p_sys->p_mpeg2dec->decoder, p_pic,
733                               get_aspect_ratio(p_dec), 0 );
734     return p_pic;
735 }