]> git.sesse.net Git - vlc/blob - modules/codec/xvmc/xxmc.c
set i_start_time with AV_TIME_BASE, fixes streaming flv from file (for me)
[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 #include <mcheck.h>
39
40 #include "mpeg2.h"
41 #include "attributes.h"
42 #include "mpeg2_internal.h"
43 #include "xvmc_vld.h"
44
45 /* Aspect ratio (ISO/IEC 13818-2 section 6.3.3, table 6-3) */
46 #define AR_SQUARE_PICTURE       1                           /* square pixels */
47 #define AR_3_4_PICTURE          2                        /* 3:4 picture (TV) */
48 #define AR_16_9_PICTURE         3              /* 16:9 picture (wide screen) */
49 #define AR_221_1_PICTURE        4                  /* 2.21:1 picture (movie) */
50
51 /*****************************************************************************
52  * decoder_sys_t : libmpeg2 decoder descriptor
53  *****************************************************************************/
54 struct decoder_sys_t
55 {
56     /*
57      * libmpeg2 properties
58      */
59     mpeg2dec_t          *p_mpeg2dec;
60     const mpeg2_info_t  *p_info;
61     vlc_bool_t          b_skip;
62
63     /*
64      * Input properties
65      */
66     mtime_t          i_pts;
67     mtime_t          i_previous_pts;
68     mtime_t          i_current_pts;
69     mtime_t          i_previous_dts;
70     mtime_t          i_current_dts;
71     int              i_current_rate;
72     picture_t *      p_picture_to_destroy;
73     vlc_bool_t       b_garbage_pic;
74     vlc_bool_t       b_after_sequence_header; /* is it the next frame after
75                                                * the sequence header ?    */
76     vlc_bool_t       b_slice_i;             /* intra-slice refresh stream */
77
78     /*
79      * Output properties
80      */
81     decoder_synchro_t *p_synchro;
82     int            i_aspect;
83     mtime_t        i_last_frame_pts;
84
85 };
86
87 /*****************************************************************************
88  * Local prototypes
89  *****************************************************************************/
90
91 static int  OpenDecoder( vlc_object_t * );
92 static void CloseDecoder( vlc_object_t * );
93
94 static picture_t *DecodeBlock( decoder_t *, block_t ** );
95
96 static picture_t *GetNewPicture( decoder_t *, uint8_t ** );
97
98 /*****************************************************************************
99  * Module descriptor
100  *****************************************************************************/
101 vlc_module_begin();
102     set_description( _("MPEG I/II hw video decoder (using libmpeg2)") );
103     set_capability( "decoder", 160 );
104     set_callbacks( OpenDecoder, CloseDecoder );
105     add_shortcut( "xxmc" );
106 vlc_module_end();
107
108 /*****************************************************************************
109  * OpenDecoder: probe the decoder and return score
110  *****************************************************************************/
111 static int OpenDecoder( vlc_object_t *p_this )
112 {
113
114     decoder_t *p_dec = (decoder_t*)p_this;
115     decoder_sys_t *p_sys = NULL;
116     uint32_t i_accel = 0;
117     FILE *f_wd_dec; 
118
119     msg_Dbg(p_dec, "OpenDecoder Entering");
120     mtrace();
121     if( p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','v') &&
122         p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','1') &&
123         /* Pinnacle hardware-mpeg1 */
124         p_dec->fmt_in.i_codec != VLC_FOURCC('P','I','M','1') &&
125         /* VIA hardware-mpeg2 */
126         p_dec->fmt_in.i_codec != VLC_FOURCC('X','x','M','C') &&
127         /* ATI Video */
128         p_dec->fmt_in.i_codec != VLC_FOURCC('V','C','R','2') &&
129         p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','2') )
130     {
131         return VLC_EGENERIC;
132     }
133
134     /* Allocate the memory needed to store the decoder's structure */
135     p_dec->p_sys = p_sys = (decoder_sys_t *)malloc(sizeof(decoder_sys_t));
136     if( !p_sys )
137     {
138         msg_Err( p_dec, "out of memory" );
139         return VLC_EGENERIC;
140     }
141
142     /* Initialize the thread properties */
143     memset( p_sys, 0, sizeof(decoder_sys_t) );
144     p_sys->p_mpeg2dec = NULL;
145     p_sys->p_synchro  = NULL;
146     p_sys->p_info     = NULL;
147     p_sys->i_pts      = mdate() + DEFAULT_PTS_DELAY;
148     p_sys->i_current_pts  = 0;
149     p_sys->i_previous_pts = 0;
150     p_sys->i_current_dts  = 0;
151     p_sys->i_previous_dts = 0;
152     p_sys->p_picture_to_destroy = NULL;
153     p_sys->b_garbage_pic = 0;
154     p_sys->b_slice_i  = 0;
155     p_sys->b_skip     = 0;
156
157 #if defined( __i386__ )
158     if( vlc_CPU() & CPU_CAPABILITY_MMX )
159     {
160         i_accel |= MPEG2_ACCEL_X86_MMX;
161     }
162
163     if( vlc_CPU() & CPU_CAPABILITY_3DNOW )
164     {
165         i_accel |= MPEG2_ACCEL_X86_3DNOW;
166     }
167
168     if( vlc_CPU() & CPU_CAPABILITY_MMXEXT )
169     {
170         i_accel |= MPEG2_ACCEL_X86_MMXEXT;
171     }
172
173 #elif defined( __powerpc__ ) || defined( SYS_DARWIN )
174     if( vlc_CPU() & CPU_CAPABILITY_ALTIVEC )
175     {
176         i_accel |= MPEG2_ACCEL_PPC_ALTIVEC;
177     }
178
179 #else
180     /* If we do not know this CPU, trust libmpeg2's feature detection */
181     i_accel = MPEG2_ACCEL_DETECT;
182
183 #endif
184
185     /* Set CPU acceleration features */
186     mpeg2_accel( i_accel );
187
188     /* Initialize decoder */
189     p_sys->p_mpeg2dec = mpeg2_init();
190     if( p_sys->p_mpeg2dec == NULL)
191     {
192         msg_Err( p_dec, "mpeg2_init() failed" );
193         free( p_sys );
194         return VLC_EGENERIC;
195     }
196
197     p_sys->p_info = mpeg2_info( p_sys->p_mpeg2dec );
198
199     p_dec->pf_decode_video = DecodeBlock;
200
201     f_wd_dec = fopen("/vlc/dec_pid", "w");
202
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 = VLC_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 }