]> git.sesse.net Git - vlc/blob - modules/codec/xvmc/xxmc.c
Merge branch 1.0-bugfix
[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_common.h>
33 #include <vlc_plugin.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( N_("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_CODEC_MPGV )
124         return VLC_EGENERIC;
125     /* Select onl recognized original format (standard mpeg video) */
126     switch( p_dec->fmt_in.i_original_fourcc )
127     {
128     case VLC_FOURCC('m','p','g','1'):
129     case VLC_FOURCC('m','p','g','2'):
130     case VLC_FOURCC('m','p','g','v'):
131     /* Pinnacle hardware-mpeg1 */
132     case VLC_FOURCC('P','I','M','1'):
133     /* VIA hardware-mpeg2 */
134     case VLC_FOURCC('X','x','M','C'):
135     /* ATI Video */
136     case VLC_FOURCC('V','C','R','2'):
137         break;
138     default:
139         if( p_dec->fmt_in.i_original_fourcc )
140             return VLC_EGENERIC;
141         break;
142     }
143
144     msg_Dbg(p_dec, "OpenDecoder Entering");
145
146     /* Allocate the memory needed to store the decoder's structure */
147     p_dec->p_sys = p_sys = calloc( 1, sizeof(*p_sys) );
148     if( !p_sys )
149         return VLC_ENOMEM;
150
151     /* Initialize the thread properties */
152     p_sys->p_mpeg2dec = NULL;
153     p_sys->p_synchro  = NULL;
154     p_sys->p_info     = NULL;
155     p_sys->i_pts      = mdate() + DEFAULT_PTS_DELAY;
156     p_sys->i_current_pts  = 0;
157     p_sys->i_previous_pts = 0;
158     p_sys->i_current_dts  = 0;
159     p_sys->i_previous_dts = 0;
160     p_sys->p_picture_to_destroy = NULL;
161     p_sys->b_garbage_pic = 0;
162     p_sys->b_slice_i  = 0;
163     p_sys->b_skip     = 0;
164
165 #if defined( __i386__ )
166     if( vlc_CPU() & CPU_CAPABILITY_MMX )
167     {
168         i_accel |= MPEG2_ACCEL_X86_MMX;
169     }
170
171     if( vlc_CPU() & CPU_CAPABILITY_3DNOW )
172     {
173         i_accel |= MPEG2_ACCEL_X86_3DNOW;
174     }
175
176     if( vlc_CPU() & CPU_CAPABILITY_MMXEXT )
177     {
178         i_accel |= MPEG2_ACCEL_X86_MMXEXT;
179     }
180
181 #elif defined( __powerpc__ ) || defined( SYS_DARWIN )
182     if( vlc_CPU() & CPU_CAPABILITY_ALTIVEC )
183     {
184         i_accel |= MPEG2_ACCEL_PPC_ALTIVEC;
185     }
186
187 #else
188     /* If we do not know this CPU, trust libmpeg2's feature detection */
189     i_accel = MPEG2_ACCEL_DETECT;
190
191 #endif
192
193     /* Set CPU acceleration features */
194     mpeg2_accel( i_accel );
195
196     /* Initialize decoder */
197     p_sys->p_mpeg2dec = mpeg2_init();
198     if( p_sys->p_mpeg2dec == NULL)
199     {
200         msg_Err( p_dec, "mpeg2_init() failed" );
201         free( p_sys );
202         return VLC_EGENERIC;
203     }
204
205     p_sys->p_info = mpeg2_info( p_sys->p_mpeg2dec );
206
207     p_dec->pf_decode_video = DecodeBlock;
208     p_dec->fmt_out.i_cat = VIDEO_ES;
209     p_dec->fmt_out.i_codec = 0;
210
211     f_wd_dec = fopen("/vlc/dec_pid", "w");
212     if (f_wd_dec != NULL)
213     {
214         fprintf(f_wd_dec, "%d\n", getpid());
215         fflush(f_wd_dec);
216         fclose(f_wd_dec);
217     }
218
219     msg_Dbg(p_dec, "OpenDecoder Leaving");
220     return VLC_SUCCESS;
221 }
222
223 static void WriteDecodeFile(int value)
224 {
225     FILE *f_wd_ok;
226
227     f_wd_ok = fopen("/vlc/dec_ok", "w");
228     if (f_wd_ok != NULL)
229     {
230         fprintf(f_wd_ok, "%d", value);
231         fflush(f_wd_ok);
232         fclose(f_wd_ok);
233     }
234 }
235
236 /*****************************************************************************
237  * RunDecoder: the libmpeg2 decoder
238  *****************************************************************************/
239 static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
240 {
241     decoder_sys_t   *p_sys = p_dec->p_sys;
242     mpeg2_state_t   state;
243     picture_t       *p_pic;
244
245     block_t *p_block;
246
247     if( !pp_block || !*pp_block )
248         return NULL;
249
250     p_block = *pp_block;
251     while( 1 )
252     {
253         state = mpeg2_parse( p_sys->p_mpeg2dec );
254         switch( state )
255         {
256             case STATE_BUFFER:
257                 if( !p_block->i_buffer )
258                 {
259                     block_Release( p_block );
260                     return NULL;
261                 }
262                 if( (p_block->i_flags&BLOCK_FLAG_DISCONTINUITY) &&
263                     p_sys->p_synchro &&
264                     p_sys->p_info->sequence &&
265                     p_sys->p_info->sequence->width != (unsigned int)-1 )
266                 {
267                     decoder_SynchroReset( p_sys->p_synchro );
268                     if( p_sys->p_info->current_fbuf != NULL
269                         && p_sys->p_info->current_fbuf->id != NULL )
270                     {
271                         p_sys->b_garbage_pic = 1;
272                         p_pic = p_sys->p_info->current_fbuf->id;
273                     }
274                     else
275                     {
276                         uint8_t *buf[3];
277                         buf[0] = buf[1] = buf[2] = NULL;
278                         if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
279                             break;
280                         mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
281                     }
282                     p_sys->p_picture_to_destroy = p_pic;
283
284                     if ( p_sys->b_slice_i )
285                     {
286                         decoder_SynchroNewPicture( p_sys->p_synchro,
287                             I_CODING_TYPE, 2, 0, 0,
288                             p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
289                         decoder_SynchroDecode( p_sys->p_synchro );
290                         decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
291                     }
292                 }
293
294 #ifdef PIC_FLAG_PTS
295                 if( p_block->i_pts )
296                 {
297                     mpeg2_pts( p_sys->p_mpeg2dec, (uint32_t)p_block->i_pts );
298
299 #else /* New interface */
300                 if( p_block->i_pts || p_block->i_dts )
301                 {
302                     mpeg2_tag_picture( p_sys->p_mpeg2dec,
303                                         (uint32_t)p_block->i_pts,
304                                         (uint32_t)p_block->i_dts );
305 #endif
306                     p_sys->i_previous_pts = p_sys->i_current_pts;
307                     p_sys->i_current_pts = p_block->i_pts;
308                     p_sys->i_previous_dts = p_sys->i_current_dts;
309                     p_sys->i_current_dts = p_block->i_dts;
310                 }
311                 p_sys->i_current_rate = p_block->i_rate;
312
313                 mpeg2_buffer( p_sys->p_mpeg2dec, p_block->p_buffer,
314                                 p_block->p_buffer + p_block->i_buffer );
315                 p_block->i_buffer = 0;
316                 break;
317
318             case STATE_SEQUENCE:
319             {
320                 /* Initialize video output */
321                 uint8_t *buf[3];
322                 buf[0] = buf[1] = buf[2] = NULL;
323
324                 /* Check whether the input gave a particular aspect ratio */
325                 if( p_dec->fmt_in.video.i_aspect )
326                 {
327                     p_sys->i_aspect = p_dec->fmt_in.video.i_aspect;
328                     if( p_sys->i_aspect <= AR_221_1_PICTURE )
329                     switch( p_sys->i_aspect )
330                     {
331                     case AR_3_4_PICTURE:
332                         p_sys->i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
333                         break;
334                     case AR_16_9_PICTURE:
335                         p_sys->i_aspect = VOUT_ASPECT_FACTOR * 16 / 9;
336                         break;
337                     case AR_221_1_PICTURE:
338                         p_sys->i_aspect = VOUT_ASPECT_FACTOR * 221 / 100;
339                         break;
340                     case AR_SQUARE_PICTURE:
341                         p_sys->i_aspect = VOUT_ASPECT_FACTOR *
342                                     p_sys->p_info->sequence->width /
343                                     p_sys->p_info->sequence->height;
344                         break;
345                     }
346                 }
347                 else
348                 {
349                     /* Use the value provided in the MPEG sequence header */
350                     if( p_sys->p_info->sequence->pixel_height > 0 )
351                     {
352                         p_sys->i_aspect =
353                             ((uint64_t)p_sys->p_info->sequence->display_width) *
354                             p_sys->p_info->sequence->pixel_width *
355                             VOUT_ASPECT_FACTOR /
356                             p_sys->p_info->sequence->display_height /
357                             p_sys->p_info->sequence->pixel_height;
358                     }
359                     else
360                     {
361                         /* Invalid aspect, assume 4:3.
362                         * This shouldn't happen and if it does it is a bug
363                         * in libmpeg2 (likely triggered by an invalid stream) */
364                         p_sys->i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
365                     }
366                 }
367
368                 msg_Dbg( p_dec, "%dx%d, aspect %d, %u.%03u fps",
369                         p_sys->p_info->sequence->width,
370                         p_sys->p_info->sequence->height, p_sys->i_aspect,
371                         (uint32_t)((uint64_t)1001000000 * 27 /
372                             p_sys->p_info->sequence->frame_period / 1001),
373                         (uint32_t)((uint64_t)1001000000 * 27 /
374                             p_sys->p_info->sequence->frame_period % 1001) );
375
376                 mpeg2_custom_fbuf( p_sys->p_mpeg2dec, 1 );
377
378                 /* Set the first 2 reference frames */
379                 mpeg2_set_buf( p_sys->p_mpeg2dec, buf, NULL );
380
381                 if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
382                 {
383                     block_Release( p_block );
384                     return NULL;
385                 }
386                 mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
387
388                 p_pic->date = 0;
389                 decoder_LinkPicture( p_dec, p_pic );
390
391                 if( p_sys->p_synchro )
392                 {
393                     decoder_SynchroRelease( p_sys->p_synchro );
394                 }
395                 p_sys->p_synchro = decoder_SynchroInit( p_dec,
396                     (uint32_t)((uint64_t)1001000000 * 27 /
397                     p_sys->p_info->sequence->frame_period) );
398                 p_sys->b_after_sequence_header = 1;
399             }
400             break;
401
402             case STATE_PICTURE_2ND:
403                 decoder_SynchroNewPicture( p_sys->p_synchro,
404                         p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
405                         p_sys->p_info->current_picture->nb_fields,
406                         0, 0,
407                         p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
408
409                 if( p_sys->b_skip )
410                 {
411                     decoder_SynchroTrash( p_sys->p_synchro );
412                 }
413                 else
414                 {
415                     decoder_SynchroDecode( p_sys->p_synchro );
416                 }
417                 break;
418
419             case STATE_PICTURE:
420             {
421                 uint8_t *buf[3];
422                 mtime_t i_pts;
423                 buf[0] = buf[1] = buf[2] = NULL;
424
425                 if ( p_sys->b_after_sequence_header &&
426                     ((p_sys->p_info->current_picture->flags &
427                         PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_P) )
428                 {
429                     /* Intra-slice refresh. Simulate a blank I picture. */
430                     msg_Dbg( p_dec, "intra-slice refresh stream" );
431                     decoder_SynchroNewPicture( p_sys->p_synchro,
432                         I_CODING_TYPE, 2, 0, 0,
433                         p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
434                     decoder_SynchroDecode( p_sys->p_synchro );
435                     decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
436                     p_sys->b_slice_i = 1;
437                 }
438                 p_sys->b_after_sequence_header = 0;
439
440 #ifdef PIC_FLAG_PTS
441                 i_pts = p_sys->p_info->current_picture->flags & PIC_FLAG_PTS ?
442                     ( ( p_sys->p_info->current_picture->pts ==
443                         (uint32_t)p_sys->i_current_pts ) ?
444                     p_sys->i_current_pts : p_sys->i_previous_pts ) : 0;
445 #else /* New interface */
446                 i_pts = p_sys->p_info->current_picture->flags & PIC_FLAG_TAGS ?
447                     ( ( p_sys->p_info->current_picture->tag ==
448                         (uint32_t)p_sys->i_current_pts ) ?
449                     p_sys->i_current_pts : p_sys->i_previous_pts ) : 0;
450 #endif
451                 /* Hack to handle demuxers which only have DTS timestamps */
452                 if( !i_pts && !p_block->i_pts && p_block->i_dts > 0 )
453                 {
454                     if( p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ||
455                         (p_sys->p_info->current_picture->flags &
456                         PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_B )
457                     {
458                         i_pts = p_block->i_dts;
459                     }
460                 }
461                 p_block->i_pts = p_block->i_dts = 0;
462                 /* End hack */
463
464                 decoder_SynchroNewPicture( p_sys->p_synchro,
465                     p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
466                     p_sys->p_info->current_picture->nb_fields, i_pts,
467                     0,
468                     p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
469
470                 if ( !(p_sys->b_slice_i
471                     && ((p_sys->p_info->current_picture->flags
472                             & PIC_MASK_CODING_TYPE) == P_CODING_TYPE))
473                     && !decoder_SynchroChoose( p_sys->p_synchro,
474                                 p_sys->p_info->current_picture->flags
475                                     & PIC_MASK_CODING_TYPE,
476                                 /*FindVout(p_dec)->render_time*/ 0 /*FIXME*/,
477                                 p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ) )
478                 {
479                     mpeg2_skip( p_sys->p_mpeg2dec, 1 );
480                     p_sys->b_skip = 1;
481                     decoder_SynchroTrash( p_sys->p_synchro );
482                     mpeg2_set_buf( p_sys->p_mpeg2dec, buf, NULL );
483                 }
484                 else
485                 {
486                     mpeg2_skip( p_sys->p_mpeg2dec, 0 );
487                     p_sys->b_skip = 0;
488                     decoder_SynchroDecode( p_sys->p_synchro );
489
490                     if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
491                     {
492                         block_Release( p_block );
493                         return NULL;
494                     }
495
496                     //p_sys->p_mpeg2dec->ptr_forward_ref_picture = p_sys->p_mpeg2dec->fbuf[2]->id;
497                     //p_sys->p_mpeg2dec->ptr_backward_ref_picture = p_sys->p_mpeg2dec->fbuf[1]->id;
498
499                     if ((p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE) != B_CODING_TYPE)
500                     {
501                         //if (p_sys->p_mpeg2dec->ptr_forward_ref_picture &&
502                         //    p_sys->p_mpeg2dec->ptr_forward_ref_picture != picture->backward_reference_frame)
503                         //    p_pic->forward_reference_frame->free (p_pic->forward_reference_frame);
504
505                         //p_sys->p_mpeg2dec->ptr_forward_ref_picture =
506                         //            p_sys->p_mpeg2dec->ptr_backward_ref_picture;
507                         //p_sys->p_mpeg2dec->ptr_backward_ref_picture = (void *)p_pic;
508                     }
509                     mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
510                 }
511             }
512             break;
513
514             case STATE_END:
515             case STATE_SLICE:
516                 p_pic = NULL;
517                 if( p_sys->p_info->display_fbuf
518                     && p_sys->p_info->display_fbuf->id )
519                 {
520                     p_pic = (picture_t *)p_sys->p_info->display_fbuf->id;
521
522                     decoder_SynchroEnd( p_sys->p_synchro,
523                                 p_sys->p_info->display_picture->flags
524                                 & PIC_MASK_CODING_TYPE,
525                                 p_sys->b_garbage_pic );
526                     p_sys->b_garbage_pic = 0;
527
528                     if ( p_sys->p_picture_to_destroy != p_pic )
529                     {
530                         p_pic->date = decoder_SynchroDate( p_sys->p_synchro );
531                     }
532                     else
533                     {
534                         p_sys->p_picture_to_destroy = NULL;
535                         p_pic->date = 0;
536                     }
537                 }
538
539                 if( p_sys->p_info->discard_fbuf &&
540                     p_sys->p_info->discard_fbuf->id )
541                 {
542                     decoder_UnlinkPicture( p_dec, p_sys->p_info->discard_fbuf->id );
543                 }
544                 /* For still frames */
545                 //if( state == STATE_END && p_pic ) p_pic->b_force = true;
546
547                 if( p_pic )
548                 {
549 #if 0
550                     /* Avoid frames with identical timestamps.
551                      * Especially needed for still frames in DVD menus. */
552                      if( p_sys->i_last_frame_pts == p_pic->date ) p_pic->date++;
553                         p_sys->i_last_frame_pts = p_pic->date;
554 #endif
555                     return p_pic;
556                 }
557                 break;
558
559             case STATE_INVALID:
560             {
561                 uint8_t *buf[3];
562                 buf[0] = buf[1] = buf[2] = NULL;
563
564                 msg_Warn( p_dec, "invalid picture encountered" );
565                 if ( ( p_sys->p_info->current_picture == NULL ) ||
566                 ( ( p_sys->p_info->current_picture->flags &
567                     PIC_MASK_CODING_TYPE) != B_CODING_TYPE ) )
568                 {
569                     if( p_sys->p_synchro ) decoder_SynchroReset( p_sys->p_synchro );
570                 }
571                 mpeg2_skip( p_sys->p_mpeg2dec, 1 );
572                 p_sys->b_skip = 1;
573
574                 if( p_sys->p_info->current_fbuf &&
575                     p_sys->p_info->current_fbuf->id )
576                 {
577                     p_sys->b_garbage_pic = 1;
578                     p_pic = p_sys->p_info->current_fbuf->id;
579                 }
580                 else if( !p_sys->p_info->sequence )
581                 {
582                     break;
583                 }
584                 else
585                 {
586                     if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
587                         break;
588                     mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
589                 }
590                 p_sys->p_picture_to_destroy = p_pic;
591
592                 memset( p_pic->p[0].p_pixels, 0,
593                         p_sys->p_info->sequence->width
594                         * p_sys->p_info->sequence->height );
595                 memset( p_pic->p[1].p_pixels, 0x80,
596                         p_sys->p_info->sequence->width
597                         * p_sys->p_info->sequence->height / 4 );
598                 memset( p_pic->p[2].p_pixels, 0x80,
599                         p_sys->p_info->sequence->width
600                         * p_sys->p_info->sequence->height / 4 );
601
602                 if( p_sys->b_slice_i )
603                 {
604                     decoder_SynchroNewPicture( p_sys->p_synchro,
605                         I_CODING_TYPE, 2, 0, 0,
606                         p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
607                     decoder_SynchroDecode( p_sys->p_synchro );
608                     decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
609                 }
610                 break;
611             }
612
613             default:
614                 break;
615         }
616     }
617     return NULL;
618 }
619
620 /*****************************************************************************
621  * CloseDecoder: libmpeg2 decoder destruction
622  *****************************************************************************/
623 static void CloseDecoder( vlc_object_t *p_this )
624 {
625     decoder_t *p_dec = (decoder_t *)p_this;
626     decoder_sys_t *p_sys = p_dec->p_sys;
627     FILE *f_wd_dec;
628
629     if( p_sys->p_synchro ) decoder_SynchroRelease( p_sys->p_synchro );
630     if( p_sys->p_mpeg2dec ) mpeg2_close( p_sys->p_mpeg2dec );
631
632     f_wd_dec = fopen("/vlc/dec_pid", "w");
633     if (f_wd_dec != NULL)
634     {
635         fprintf(f_wd_dec, "0\n");
636         fflush(f_wd_dec);
637         fclose(f_wd_dec);
638     }
639     free( p_sys );
640 }
641
642 static double get_aspect_ratio( decoder_t *p_dec )
643 {
644     decoder_sys_t *p_sys = p_dec->p_sys;
645     double ratio;
646     double mpeg1_pel_ratio[16] = {1.0 /* forbidden */,
647         1.0, 0.6735, 0.7031, 0.7615, 0.8055, 0.8437, 0.8935, 0.9157,
648         0.9815, 1.0255, 1.0695, 1.0950, 1.1575, 1.2015, 1.0 /*reserved*/ };
649
650     if( !p_sys->p_mpeg2dec->decoder.mpeg1 )
651     {
652         /* these hardcoded values are defined on mpeg2 standard for
653         * aspect ratio. other values are reserved or forbidden.  */
654         /*switch( p_sys->p_mpeg2dec->decoder.aspect_ratio_information )
655         {
656             case 2:
657                 ratio = 4.0/3.0;
658                 break;
659             case 3:
660                 ratio = 16.0/9.0;
661                 break;
662             case 4:
663                 ratio = 2.11/1.0;
664                 break;
665             case 1:
666                 default:*/
667                 ratio = (double)p_sys->p_mpeg2dec->decoder.width/(double)p_sys->p_mpeg2dec->decoder.height;
668         /*    break;
669         }*/
670     }
671     else
672     {
673         /* mpeg1 constants refer to pixel aspect ratio */
674         ratio = (double)p_sys->p_mpeg2dec->decoder.width/(double)p_sys->p_mpeg2dec->decoder.height;
675         /* ratio /= mpeg1_pel_ratio[p_sys->p_mpeg2dec->decoder.aspect_ratio_information]; */
676     }
677     return ratio;
678 }
679 /*****************************************************************************
680  * GetNewPicture: Get a new picture from the vout and set the buf struct
681  *****************************************************************************/
682 static picture_t *GetNewPicture( decoder_t *p_dec, uint8_t **pp_buf )
683 {
684     //msg_Dbg(p_dec, "GetNewPicture Entering");
685     decoder_sys_t *p_sys = p_dec->p_sys;
686     picture_t *p_pic;
687
688     p_dec->fmt_out.video.i_width = p_sys->p_info->sequence->width;
689     p_dec->fmt_out.video.i_height = p_sys->p_info->sequence->height;
690     p_dec->fmt_out.video.i_aspect = p_sys->i_aspect;
691
692     if( p_sys->p_info->sequence->frame_period > 0 )
693     {
694         p_dec->fmt_out.video.i_frame_rate =
695             (uint32_t)( (uint64_t)1001000000 * 27 /
696                         p_sys->p_info->sequence->frame_period );
697         p_dec->fmt_out.video.i_frame_rate_base = 1001;
698     }
699
700     p_dec->fmt_out.i_codec =
701         ( p_sys->p_info->sequence->chroma_height <
702           p_sys->p_info->sequence->height ) ?
703         VLC_CODEC_I420 : VLC_CODEC_I422;
704
705 #if 0
706     p_sys->f_wd_nb = fopen("/vlc/dec_nb", "w");
707     if (p_sys->f_wd_nb != NULL)
708     {
709 //      fprintf(p_sys->f_wd_nb, "%d\n", mdate());
710         fprintf(p_sys->f_wd_nb, "%s\n", mdate());
711         fflush(p_sys->f_wd_nb);
712     }
713 #endif
714     p_pic = decoder_NewPicture( p_dec );
715
716     if( p_pic == NULL ) return NULL;
717
718     p_pic->b_progressive = p_sys->p_info->current_picture != NULL ?
719         p_sys->p_info->current_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME : 1;
720     p_pic->b_top_field_first = p_sys->p_info->current_picture != NULL ?
721         p_sys->p_info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST : 1;
722     p_pic->i_nb_fields = p_sys->p_info->current_picture != NULL ?
723         p_sys->p_info->current_picture->nb_fields : 2;
724     p_pic->format.i_frame_rate = p_dec->fmt_out.video.i_frame_rate;
725     p_pic->format.i_frame_rate_base = p_dec->fmt_out.video.i_frame_rate_base;
726
727     decoder_LinkPicture( p_dec, p_pic );
728
729     pp_buf[0] = p_pic->p[0].p_pixels;
730     pp_buf[1] = p_pic->p[1].p_pixels;
731     pp_buf[2] = p_pic->p[2].p_pixels;
732
733     /* let driver ensure this image has the right format */
734 #if 0
735     this->driver->update_frame_format( p_pic->p_sys->p_vout, p_pic,
736                                        p_dec->fmt_out.video.i_width,
737                                        p_dec->fmt_out.video.i_height,
738                                        p_dec->fmt_out.video.i_aspect,
739                                        format, flags);
740     mpeg2_xxmc_choose_coding( p_dec, &p_sys->p_mpeg2dec->decoder, p_pic,
741                               get_aspect_ratio(p_dec), 0 );
742 #endif
743     return p_pic;
744 }