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