libmpeg2.c 29.2 KB
Newer Older
Gildas Bazin's avatar
 
Gildas Bazin committed
1 2 3
/*****************************************************************************
 * libmpeg2.c: mpeg2 video decoder module making use of libmpeg2.
 *****************************************************************************
4
 * Copyright (C) 1999-2001 the VideoLAN team
5
 * $Id$
Gildas Bazin's avatar
 
Gildas Bazin committed
6
 *
7
 * Authors: Gildas Bazin <gbazin@videolan.org>
Gildas Bazin's avatar
 
Gildas Bazin committed
8
 *          Christophe Massiot <massiot@via.ecp.fr>
Gildas Bazin's avatar
 
Gildas Bazin committed
9 10 11 12 13
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
Sam Hocevar's avatar
Sam Hocevar committed
14
 *
Gildas Bazin's avatar
 
Gildas Bazin committed
15 16 17 18 19 20 21
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
Antoine Cellerier's avatar
Antoine Cellerier committed
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
Gildas Bazin's avatar
 
Gildas Bazin committed
23 24 25 26 27
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
28 29 30
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
31
#include <assert.h>
32

33
#include <vlc_common.h>
34
#include <vlc_plugin.h>
Clément Stenac's avatar
Clément Stenac committed
35
#include <vlc_codec.h>
36
#include <vlc_block_helper.h>
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
37
#include <vlc_cpu.h>
38
#include "../codec/cc.h"
Gildas Bazin's avatar
 
Gildas Bazin committed
39

40
#include <mpeg2.h>
Gildas Bazin's avatar
 
Gildas Bazin committed
41

42
#include <vlc_codec_synchro.h>
43

Gildas Bazin's avatar
 
Gildas Bazin committed
44
/*****************************************************************************
Gildas Bazin's avatar
 
Gildas Bazin committed
45
 * decoder_sys_t : libmpeg2 decoder descriptor
Gildas Bazin's avatar
 
Gildas Bazin committed
46
 *****************************************************************************/
47 48 49 50 51 52 53 54
#define DPB_COUNT (3+1)
typedef struct
{
    picture_t *p_picture;
    bool      b_linked;
    bool      b_displayed;
} picture_dpb_t;

Gildas Bazin's avatar
 
Gildas Bazin committed
55
struct decoder_sys_t
Gildas Bazin's avatar
 
Gildas Bazin committed
56 57 58 59 60 61
{
    /*
     * libmpeg2 properties
     */
    mpeg2dec_t          *p_mpeg2dec;
    const mpeg2_info_t  *p_info;
62
    bool                b_skip;
Gildas Bazin's avatar
 
Gildas Bazin committed
63 64 65 66 67 68

    /*
     * Input properties
     */
    mtime_t          i_previous_pts;
    mtime_t          i_current_pts;
69 70
    mtime_t          i_previous_dts;
    mtime_t          i_current_dts;
71 72
    bool             b_garbage_pic;
    bool             b_after_sequence_header; /* is it the next frame after
73
                                               * the sequence header ?    */
74 75
    bool             b_slice_i;             /* intra-slice refresh stream */
    bool             b_second_field;
Gildas Bazin's avatar
 
Gildas Bazin committed
76

77
    bool             b_preroll;
Laurent Aimar's avatar
Laurent Aimar committed
78

79 80 81
    /* */
    picture_dpb_t        p_dpb[DPB_COUNT];

Gildas Bazin's avatar
 
Gildas Bazin committed
82 83 84
    /*
     * Output properties
     */
85
    decoder_synchro_t *p_synchro;
86 87 88 89 90 91 92 93 94
    int             i_sar_num;
    int             i_sar_den;
    mtime_t         i_last_frame_pts;

    /* Closed captioning support */
    uint32_t        i_cc_flags;
    mtime_t         i_cc_pts;
    mtime_t         i_cc_dts;
    cc_data_t       cc;
95 96
    uint8_t        *p_gop_user_data;
    uint32_t        i_gop_user_data;
Gildas Bazin's avatar
 
Gildas Bazin committed
97
};
Gildas Bazin's avatar
 
Gildas Bazin committed
98 99 100 101

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
Gildas Bazin's avatar
 
Gildas Bazin committed
102 103 104 105
static int  OpenDecoder( vlc_object_t * );
static void CloseDecoder( vlc_object_t * );

static picture_t *DecodeBlock( decoder_t *, block_t ** );
106
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
107
static block_t   *GetCc( decoder_t *p_dec, bool pb_present[4] );
108
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
109

110 111 112
static picture_t *GetNewPicture( decoder_t * );
static void PutPicture( decoder_t *, picture_t * );

113
static void GetAR( decoder_t *p_dec );
Gildas Bazin's avatar
 
Gildas Bazin committed
114

115 116
static void Reset( decoder_t *p_dec );

117 118 119 120 121
/* */
static void DpbInit( decoder_t * );
static void DpbClean( decoder_t * );
static picture_t *DpbNewPicture( decoder_t * );
static void DpbUnlinkPicture( decoder_t *, picture_t * );
122
static int DpbDisplayPicture( decoder_t *, picture_t * );
123

Gildas Bazin's avatar
 
Gildas Bazin committed
124 125 126
/*****************************************************************************
 * Module descriptor
 *****************************************************************************/
127 128 129 130 131 132 133 134
vlc_module_begin ()
    set_description( N_("MPEG I/II video decoder (using libmpeg2)") )
    set_capability( "decoder", 150 )
    set_category( CAT_INPUT )
    set_subcategory( SUBCAT_INPUT_VCODEC )
    set_callbacks( OpenDecoder, CloseDecoder )
    add_shortcut( "libmpeg2" )
vlc_module_end ()
Gildas Bazin's avatar
 
Gildas Bazin committed
135 136 137 138 139 140

/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
Gildas Bazin's avatar
 
Gildas Bazin committed
141
    decoder_t *p_dec = (decoder_t*)p_this;
Gildas Bazin's avatar
 
Gildas Bazin committed
142
    decoder_sys_t *p_sys;
Sam Hocevar's avatar
Sam Hocevar committed
143
    uint32_t i_accel = 0;
Gildas Bazin's avatar
 
Gildas Bazin committed
144

Laurent Aimar's avatar
Laurent Aimar committed
145
    if( p_dec->fmt_in.i_codec != VLC_CODEC_MPGV )
Gildas Bazin's avatar
 
Gildas Bazin committed
146
        return VLC_EGENERIC;
147

148 149 150 151 152 153 154 155 156 157 158 159 160
    /* Select onl recognized original format (standard mpeg video) */
    switch( p_dec->fmt_in.i_original_fourcc )
    {
    case VLC_FOURCC('m','p','g','1'):
    case VLC_FOURCC('m','p','g','2'):
    case VLC_FOURCC('m','p','g','v'):
    case VLC_FOURCC('P','I','M','1'):
    case VLC_FOURCC('h','d','v','2'):
        break;
    default:
        if( p_dec->fmt_in.i_original_fourcc )
            return VLC_EGENERIC;
        break;
Gildas Bazin's avatar
 
Gildas Bazin committed
161 162
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
163
    /* Allocate the memory needed to store the decoder's structure */
164
    if( ( p_dec->p_sys = p_sys = calloc( 1, sizeof(*p_sys)) ) == NULL )
165
        return VLC_ENOMEM;
Gildas Bazin's avatar
 
Gildas Bazin committed
166 167

    /* Initialize the thread properties */
Gildas Bazin's avatar
 
Gildas Bazin committed
168 169 170 171 172
    p_sys->p_mpeg2dec = NULL;
    p_sys->p_synchro  = NULL;
    p_sys->p_info     = NULL;
    p_sys->i_current_pts  = 0;
    p_sys->i_previous_pts = 0;
173 174
    p_sys->i_current_dts  = 0;
    p_sys->i_previous_dts = 0;
Laurent Aimar's avatar
Laurent Aimar committed
175 176
    p_sys->i_sar_num = 0;
    p_sys->i_sar_den = 0;
177 178 179 180
    p_sys->b_garbage_pic = false;
    p_sys->b_slice_i  = false;
    p_sys->b_second_field = false;
    p_sys->b_skip     = false;
181
    p_sys->b_preroll = false;
182
    DpbInit( p_dec );
Gildas Bazin's avatar
 
Gildas Bazin committed
183

184 185 186 187 188 189 190
    p_sys->i_cc_pts = 0;
    p_sys->i_cc_dts = 0;
    p_sys->i_cc_flags = 0;
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
    p_dec->pf_get_cc = GetCc;
    cc_Init( &p_sys->cc );
#endif
191 192
    p_sys->p_gop_user_data = NULL;
    p_sys->i_gop_user_data = 0;
193

Christophe Massiot's avatar
Christophe Massiot committed
194
#if defined( __i386__ ) || defined( __x86_64__ )
195
    if( vlc_CPU() & CPU_CAPABILITY_MMX )
Sam Hocevar's avatar
Sam Hocevar committed
196 197 198 199
    {
        i_accel |= MPEG2_ACCEL_X86_MMX;
    }

200
    if( vlc_CPU() & CPU_CAPABILITY_3DNOW )
Sam Hocevar's avatar
Sam Hocevar committed
201 202 203 204
    {
        i_accel |= MPEG2_ACCEL_X86_3DNOW;
    }

205
    if( vlc_CPU() & CPU_CAPABILITY_MMXEXT )
Sam Hocevar's avatar
Sam Hocevar committed
206 207 208 209
    {
        i_accel |= MPEG2_ACCEL_X86_MMXEXT;
    }

210
#elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )
211
    if( vlc_CPU() & CPU_CAPABILITY_ALTIVEC )
Sam Hocevar's avatar
Sam Hocevar committed
212 213 214 215
    {
        i_accel |= MPEG2_ACCEL_PPC_ALTIVEC;
    }

216
#elif defined(__arm__)
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
217
    i_accel |= MPEG2_ACCEL_ARM;
218

219 220 221 222 223
# ifdef MPEG2_ACCEL_ARM_NEON
    if( vlc_CPU() & CPU_CAPABILITY_NEON )
	i_accel |= MPEG2_ACCEL_ARM_NEON;
# endif

Sam Hocevar's avatar
Sam Hocevar committed
224 225 226 227 228 229 230 231 232
#else
    /* If we do not know this CPU, trust libmpeg2's feature detection */
    i_accel = MPEG2_ACCEL_DETECT;

#endif

    /* Set CPU acceleration features */
    mpeg2_accel( i_accel );

Gildas Bazin's avatar
 
Gildas Bazin committed
233
    /* Initialize decoder */
Gildas Bazin's avatar
 
Gildas Bazin committed
234 235
    p_sys->p_mpeg2dec = mpeg2_init();
    if( p_sys->p_mpeg2dec == NULL)
Gildas Bazin's avatar
 
Gildas Bazin committed
236 237
    {
        msg_Err( p_dec, "mpeg2_init() failed" );
Gildas Bazin's avatar
 
Gildas Bazin committed
238
        free( p_sys );
Gildas Bazin's avatar
 
Gildas Bazin committed
239 240
        return VLC_EGENERIC;
    }
Gildas Bazin's avatar
 
Gildas Bazin committed
241

Gildas Bazin's avatar
 
Gildas Bazin committed
242 243 244
    p_sys->p_info = mpeg2_info( p_sys->p_mpeg2dec );

    p_dec->pf_decode_video = DecodeBlock;
245 246
    p_dec->fmt_out.i_cat = VIDEO_ES;
    p_dec->fmt_out.i_codec = 0;
Gildas Bazin's avatar
 
Gildas Bazin committed
247 248 249

    return VLC_SUCCESS;
}
Gildas Bazin's avatar
 
Gildas Bazin committed
250

Gildas Bazin's avatar
 
Gildas Bazin committed
251 252 253
/*****************************************************************************
 * RunDecoder: the libmpeg2 decoder
 *****************************************************************************/
Gildas Bazin's avatar
 
Gildas Bazin committed
254
static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
Gildas Bazin's avatar
 
Gildas Bazin committed
255 256 257 258 259
{
    decoder_sys_t   *p_sys = p_dec->p_sys;
    mpeg2_state_t   state;
    picture_t       *p_pic;

Gildas Bazin's avatar
 
Gildas Bazin committed
260 261
    block_t *p_block;

262 263
    if( !pp_block || !*pp_block )
        return NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
264 265

    p_block = *pp_block;
266
    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
267
        Reset( p_dec );
Gildas Bazin's avatar
 
Gildas Bazin committed
268 269

    while( 1 )
Gildas Bazin's avatar
 
Gildas Bazin committed
270
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
271
        state = mpeg2_parse( p_sys->p_mpeg2dec );
Gildas Bazin's avatar
 
Gildas Bazin committed
272 273 274 275

        switch( state )
        {
        case STATE_SEQUENCE:
Gildas Bazin's avatar
 
Gildas Bazin committed
276
        {
277 278
            /* */
            DpbClean( p_dec );
Gildas Bazin's avatar
 
Gildas Bazin committed
279

280
            /* */
Gildas Bazin's avatar
 
Gildas Bazin committed
281
            mpeg2_custom_fbuf( p_sys->p_mpeg2dec, 1 );
Gildas Bazin's avatar
 
Gildas Bazin committed
282 283

            /* Set the first 2 reference frames */
Laurent Aimar's avatar
Laurent Aimar committed
284 285
            p_sys->i_sar_num = 0;
            p_sys->i_sar_den = 0;
286 287
            GetAR( p_dec );
            for( int i = 0; i < 2; i++ )
288
            {
289 290 291
                picture_t *p_picture = DpbNewPicture( p_dec );
                if( !p_picture )
                {
292
                    Reset( p_dec );
293 294 295 296
                    block_Release( p_block );
                    return NULL;
                }
                PutPicture( p_dec, p_picture );
297
            }
Gildas Bazin's avatar
 
Gildas Bazin committed
298 299

            if( p_sys->p_synchro )
300
                decoder_SynchroRelease( p_sys->p_synchro );
301

302 303 304 305 306 307
            if( p_sys->p_info->sequence->frame_period <= 0 )
                p_sys->p_synchro = NULL;
            else
                p_sys->p_synchro =
                decoder_SynchroInit( p_dec, (uint32_t)(UINT64_C(1001000000) *
                                27 / p_sys->p_info->sequence->frame_period) );
308 309
            p_sys->b_after_sequence_header = true;
            break;
Gildas Bazin's avatar
 
Gildas Bazin committed
310
        }
Gildas Bazin's avatar
 
Gildas Bazin committed
311

312 313 314 315 316 317 318 319 320 321 322 323
        case STATE_GOP:
            /* There can be userdata in a GOP. It needs to be remembered for the next picture. */
            if( p_sys->p_info->user_data_len > 2 )
            {
                free( p_sys->p_gop_user_data );
                p_sys->p_gop_user_data = calloc( p_sys->p_info->user_data_len, sizeof(uint8_t) );
                if( p_sys->p_gop_user_data )
                {
                    p_sys->i_gop_user_data = p_sys->p_info->user_data_len;
                    memcpy( p_sys->p_gop_user_data, p_sys->p_info->user_data, p_sys->p_info->user_data_len );
                }
            }
324 325
            break;

Gildas Bazin's avatar
 
Gildas Bazin committed
326 327
        case STATE_PICTURE:
        {
328 329 330
            const mpeg2_info_t *p_info = p_sys->p_info;
            const mpeg2_picture_t *p_current = p_info->current_picture;

331
            mtime_t i_pts, i_dts;
332

333 334 335
            if( p_sys->b_after_sequence_header &&
                (p_current->flags &
                    PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_P )
336 337
            {
                /* Intra-slice refresh. Simulate a blank I picture. */
Gildas Bazin's avatar
 
Gildas Bazin committed
338
                msg_Dbg( p_dec, "intra-slice refresh stream" );
339
                decoder_SynchroNewPicture( p_sys->p_synchro,
340 341
                                           I_CODING_TYPE, 2, 0, 0,
                                           p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
342 343
                decoder_SynchroDecode( p_sys->p_synchro );
                decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
344
                p_sys->b_slice_i = true;
345
            }
346
            p_sys->b_after_sequence_header = false;
Gildas Bazin's avatar
 
Gildas Bazin committed
347

Gildas Bazin's avatar
 
Gildas Bazin committed
348
#ifdef PIC_FLAG_PTS
349 350
            i_pts = p_current->flags & PIC_FLAG_PTS ?
                ( ( p_current->pts ==
Gildas Bazin's avatar
 
Gildas Bazin committed
351 352
                    (uint32_t)p_sys->i_current_pts ) ?
                  p_sys->i_current_pts : p_sys->i_previous_pts ) : 0;
353
            i_dts = 0;
Gildas Bazin's avatar
 
Gildas Bazin committed
354

Gildas Bazin's avatar
 
Gildas Bazin committed
355 356 357
            /* Hack to handle demuxers which only have DTS timestamps */
            if( !i_pts && !p_block->i_pts && p_block->i_dts > 0 )
            {
358 359
                if( p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ||
                    (p_current->flags &
Gildas Bazin's avatar
 
Gildas Bazin committed
360 361 362 363 364 365 366 367
                      PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_B )
                {
                    i_pts = p_block->i_dts;
                }
            }
            p_block->i_pts = p_block->i_dts = 0;
            /* End hack */

368 369
#else /* New interface */

370 371 372 373 374 375
            i_pts = p_current->flags & PIC_FLAG_TAGS ?
                ( ( p_current->tag == (uint32_t)p_sys->i_current_pts ) ?
                            p_sys->i_current_pts : p_sys->i_previous_pts ) : 0;
            i_dts = p_current->flags & PIC_FLAG_TAGS ?
                ( ( p_current->tag2 == (uint32_t)p_sys->i_current_dts ) ?
                            p_sys->i_current_dts : p_sys->i_previous_dts ) : 0;
376 377
#endif

378 379
            /* If nb_fields == 1, it is a field picture, and it will be
             * followed by another field picture for which we won't call
380
             * decoder_SynchroNewPicture() because this would have other
381 382 383
             * problems, so we take it into account here.
             * This kind of sucks, but I didn't think better. --Meuuh
             */
384
            decoder_SynchroNewPicture( p_sys->p_synchro,
385 386 387 388
                                       p_current->flags & PIC_MASK_CODING_TYPE,
                                       p_current->nb_fields == 1 ? 2 :
                                       p_current->nb_fields, i_pts, i_dts,
                                       p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
Gildas Bazin's avatar
 
Gildas Bazin committed
389

390 391

            bool b_skip = false;
Laurent Aimar's avatar
Laurent Aimar committed
392
            if( !p_dec->b_pace_control && !p_sys->b_preroll &&
393
                !(p_sys->b_slice_i
394
                   && ((p_current->flags
395
                         & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_P))
396
                   && !decoder_SynchroChoose( p_sys->p_synchro,
397
                              p_current->flags
Gildas Bazin's avatar
 
Gildas Bazin committed
398
                                & PIC_MASK_CODING_TYPE,
399
                              /*p_sys->p_vout->render_time*/ 0 /*FIXME*/,
400
                              p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ) )
401 402 403 404 405 406
            {
                b_skip = true;
            }

            p_pic = NULL;
            if( !b_skip )
407
            {
408
                p_pic = DpbNewPicture( p_dec );
409 410 411
                if( !p_pic )
                {
                    Reset( p_dec );
412 413 414 415 416 417 418 419

                    p_pic = DpbNewPicture( p_dec );
                    if( !p_pic )
                    {
                        mpeg2_reset( p_sys->p_mpeg2dec, 1 );
                        block_Release( p_block );
                        return NULL;
                    }
420 421
                }
            }
422 423

            if( b_skip || !p_pic )
424
            {
Gildas Bazin's avatar
 
Gildas Bazin committed
425
                mpeg2_skip( p_sys->p_mpeg2dec, 1 );
426
                p_sys->b_skip = true;
427
                decoder_SynchroTrash( p_sys->p_synchro );
428 429

                PutPicture( p_dec, NULL );
430 431 432 433 434 435

                if( !b_skip )
                {
                    block_Release( p_block );
                    return NULL;
                }
436 437
            }
            else
Gildas Bazin's avatar
 
Gildas Bazin committed
438
            {
Gildas Bazin's avatar
 
Gildas Bazin committed
439
                mpeg2_skip( p_sys->p_mpeg2dec, 0 );
440
                p_sys->b_skip = false;
441
                decoder_SynchroDecode( p_sys->p_synchro );
Gildas Bazin's avatar
 
Gildas Bazin committed
442

443
                PutPicture( p_dec, p_pic );
444
            }
445
            if( p_info->user_data_len > 2 || p_sys->i_gop_user_data > 2 )
446 447 448
            {
                p_sys->i_cc_pts = i_pts;
                p_sys->i_cc_dts = i_dts;
449
                if( (p_current->flags
450 451
                             & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_P )
                    p_sys->i_cc_flags = BLOCK_FLAG_TYPE_P;
452
                else if( (p_current->flags
453 454 455 456
                             & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_B )
                    p_sys->i_cc_flags = BLOCK_FLAG_TYPE_B;
                else p_sys->i_cc_flags = BLOCK_FLAG_TYPE_I;

457 458 459 460 461 462 463 464
                if( p_sys->i_gop_user_data > 2 )
                {
                    /* We now have picture info for any cached user_data out of the gop */
                    cc_Extract( &p_sys->cc, &p_sys->p_gop_user_data[0], p_sys->i_gop_user_data );
                    p_sys->i_gop_user_data = 0;
                }

                /* Extract the CC from the user_data of the picture */
465 466
                if( p_info->user_data_len > 2 )
                    cc_Extract( &p_sys->cc, &p_info->user_data[0], p_info->user_data_len );
Gildas Bazin's avatar
 
Gildas Bazin committed
467 468
            }
        }
469
        break;
Gildas Bazin's avatar
 
Gildas Bazin committed
470

471 472 473

        case STATE_BUFFER:
            if( !p_block->i_buffer )
474
            {
475 476 477 478 479 480 481 482 483 484 485 486 487
                block_Release( p_block );
                return NULL;
            }

            if( (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY
                                      | BLOCK_FLAG_CORRUPTED)) &&
                p_sys->p_synchro &&
                p_sys->p_info->sequence &&
                p_sys->p_info->sequence->width != (unsigned)-1 )
            {
                decoder_SynchroReset( p_sys->p_synchro );
                if( p_sys->p_info->current_fbuf != NULL &&
                    p_sys->p_info->current_fbuf->id != NULL )
488
                {
489 490 491 492 493 494 495 496 497 498
                    p_sys->b_garbage_pic = true;
                }
                if( p_sys->b_slice_i )
                {
                    decoder_SynchroNewPicture( p_sys->p_synchro,
                                               I_CODING_TYPE, 2, 0, 0,
                                               p_sys->p_info->sequence->flags &
                                                            SEQ_FLAG_LOW_DELAY );
                    decoder_SynchroDecode( p_sys->p_synchro );
                    decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
499 500
                }
            }
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544

            if( p_block->i_flags & BLOCK_FLAG_PREROLL )
            {
                p_sys->b_preroll = true;
            }
            else if( p_sys->b_preroll )
            {
                p_sys->b_preroll = false;
                if( p_sys->p_synchro )
                    decoder_SynchroReset( p_sys->p_synchro );
            }

#ifdef PIC_FLAG_PTS
            if( p_block->i_pts )
            {
                mpeg2_pts( p_sys->p_mpeg2dec, (uint32_t)p_block->i_pts );

#else /* New interface */
            if( p_block->i_pts || p_block->i_dts )
            {
                mpeg2_tag_picture( p_sys->p_mpeg2dec,
                                   (uint32_t)p_block->i_pts,
                                   (uint32_t)p_block->i_dts );
#endif
                p_sys->i_previous_pts = p_sys->i_current_pts;
                p_sys->i_current_pts = p_block->i_pts;
                p_sys->i_previous_dts = p_sys->i_current_dts;
                p_sys->i_current_dts = p_block->i_dts;
            }

            mpeg2_buffer( p_sys->p_mpeg2dec, p_block->p_buffer,
                          p_block->p_buffer + p_block->i_buffer );

            p_block->i_buffer = 0;
            break;

#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)

        case STATE_SEQUENCE_MODIFIED:
            GetAR( p_dec );
            break;
#endif
        case STATE_PICTURE_2ND:
            p_sys->b_second_field = true;
545 546
            break;

547 548

        case STATE_INVALID_END:
Gildas Bazin's avatar
 
Gildas Bazin committed
549
        case STATE_END:
550
        case STATE_SLICE:
Gildas Bazin's avatar
 
Gildas Bazin committed
551
            p_pic = NULL;
552 553
            if( p_sys->p_info->display_fbuf &&
                p_sys->p_info->display_fbuf->id )
Gildas Bazin's avatar
 
Gildas Bazin committed
554
            {
555
                p_pic = p_sys->p_info->display_fbuf->id;
556 557
                if( DpbDisplayPicture( p_dec, p_pic ) )
                    p_pic = NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
558

559
                decoder_SynchroEnd( p_sys->p_synchro,
560 561
                                    p_sys->p_info->display_picture->flags & PIC_MASK_CODING_TYPE,
                                    p_sys->b_garbage_pic );
562

563 564 565 566 567 568 569
                if( p_pic )
                {
                    p_pic->date = decoder_SynchroDate( p_sys->p_synchro );
                    if( p_sys->b_garbage_pic )
                        p_pic->date = 0; /* ??? */
                    p_sys->b_garbage_pic = false;
                }
570 571
            }

Gildas Bazin's avatar
 
Gildas Bazin committed
572 573
            if( p_sys->p_info->discard_fbuf &&
                p_sys->p_info->discard_fbuf->id )
574
            {
575
                DpbUnlinkPicture( p_dec, p_sys->p_info->discard_fbuf->id );
Gildas Bazin's avatar
 
Gildas Bazin committed
576
            }
Gildas Bazin's avatar
 
Gildas Bazin committed
577

578
            /* For still frames */
579 580
            if( state == STATE_END && p_pic )
                p_pic->b_force = true;
581 582 583 584 585

            if( p_pic )
            {
                /* Avoid frames with identical timestamps.
                 * Especially needed for still frames in DVD menus. */
586 587
                if( p_sys->i_last_frame_pts == p_pic->date )
                    p_pic->date++;
588 589 590
                p_sys->i_last_frame_pts = p_pic->date;
                return p_pic;
            }
Gildas Bazin's avatar
 
Gildas Bazin committed
591 592
            break;

593
        case STATE_INVALID:
594
        {
595 596 597
            msg_Err( p_dec, "invalid picture encountered" );
            /* I don't think we have anything to do, but well without
             * docs ... */
598
            break;
599
        }
600

Gildas Bazin's avatar
 
Gildas Bazin committed
601 602 603 604 605
        default:
            break;
        }
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
606 607
    /* Never reached */
    return NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
608 609 610
}

/*****************************************************************************
Gildas Bazin's avatar
 
Gildas Bazin committed
611
 * CloseDecoder: libmpeg2 decoder destruction
Gildas Bazin's avatar
 
Gildas Bazin committed
612
 *****************************************************************************/
Gildas Bazin's avatar
 
Gildas Bazin committed
613
static void CloseDecoder( vlc_object_t *p_this )
Gildas Bazin's avatar
 
Gildas Bazin committed
614
{
Gildas Bazin's avatar
 
Gildas Bazin committed
615
    decoder_t *p_dec = (decoder_t *)p_this;
Gildas Bazin's avatar
 
Gildas Bazin committed
616 617
    decoder_sys_t *p_sys = p_dec->p_sys;

618 619
    DpbClean( p_dec );

620 621
    free( p_sys->p_gop_user_data );

622
    if( p_sys->p_synchro ) decoder_SynchroRelease( p_sys->p_synchro );
Gildas Bazin's avatar
 
Gildas Bazin committed
623

Gildas Bazin's avatar
 
Gildas Bazin committed
624
    if( p_sys->p_mpeg2dec ) mpeg2_close( p_sys->p_mpeg2dec );
Gildas Bazin's avatar
 
Gildas Bazin committed
625

Gildas Bazin's avatar
 
Gildas Bazin committed
626
    free( p_sys );
Gildas Bazin's avatar
 
Gildas Bazin committed
627
}
Gildas Bazin's avatar
 
Gildas Bazin committed
628

629 630 631 632 633 634 635 636
/*****************************************************************************
 * Reset: reset the decoder state
 *****************************************************************************/
static void Reset( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    cc_Flush( &p_sys->cc );
637
    mpeg2_reset( p_sys->p_mpeg2dec, 0 );
638 639 640
    DpbClean( p_dec );
}

Gildas Bazin's avatar
 
Gildas Bazin committed
641 642 643
/*****************************************************************************
 * GetNewPicture: Get a new picture from the vout and set the buf struct
 *****************************************************************************/
644
static picture_t *GetNewPicture( decoder_t *p_dec )
Gildas Bazin's avatar
 
Gildas Bazin committed
645
{
Gildas Bazin's avatar
 
Gildas Bazin committed
646
    decoder_sys_t *p_sys = p_dec->p_sys;
Gildas Bazin's avatar
 
Gildas Bazin committed
647
    picture_t *p_pic;
Gildas Bazin's avatar
 
Gildas Bazin committed
648

Gildas Bazin's avatar
 
Gildas Bazin committed
649
    p_dec->fmt_out.video.i_width = p_sys->p_info->sequence->width;
650 651
    p_dec->fmt_out.video.i_visible_width =
        p_sys->p_info->sequence->picture_width;
Gildas Bazin's avatar
 
Gildas Bazin committed
652
    p_dec->fmt_out.video.i_height = p_sys->p_info->sequence->height;
653 654
    p_dec->fmt_out.video.i_visible_height =
        p_sys->p_info->sequence->picture_height;
655 656
    p_dec->fmt_out.video.i_sar_num = p_sys->i_sar_num;
    p_dec->fmt_out.video.i_sar_den = p_sys->i_sar_den;
Gildas Bazin's avatar
 
Gildas Bazin committed
657

658 659 660 661 662 663 664 665
    if( p_sys->p_info->sequence->frame_period > 0 )
    {
        p_dec->fmt_out.video.i_frame_rate =
            (uint32_t)( (uint64_t)1001000000 * 27 /
                        p_sys->p_info->sequence->frame_period );
        p_dec->fmt_out.video.i_frame_rate_base = 1001;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
666 667 668
    p_dec->fmt_out.i_codec =
        ( p_sys->p_info->sequence->chroma_height <
          p_sys->p_info->sequence->height ) ?
669
        VLC_CODEC_I420 : VLC_CODEC_I422;
Gildas Bazin's avatar
 
Gildas Bazin committed
670

Gildas Bazin's avatar
 
Gildas Bazin committed
671
    /* Get a new picture */
672
    p_pic = decoder_NewPicture( p_dec );
Gildas Bazin's avatar
 
Gildas Bazin committed
673

674 675
    if( p_pic == NULL )
        return NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
676

Gildas Bazin's avatar
 
Gildas Bazin committed
677 678 679 680 681 682 683
    p_pic->b_progressive = p_sys->p_info->current_picture != NULL ?
        p_sys->p_info->current_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME : 1;
    p_pic->b_top_field_first = p_sys->p_info->current_picture != NULL ?
        p_sys->p_info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST : 1;
    p_pic->i_nb_fields = p_sys->p_info->current_picture != NULL ?
        p_sys->p_info->current_picture->nb_fields : 2;

Gildas Bazin's avatar
 
Gildas Bazin committed
684 685
    return p_pic;
}
686

687
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713
/*****************************************************************************
 * GetCc: Retrieves the Closed Captions for the CC decoder.
 *****************************************************************************/
static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] )
{
    decoder_sys_t   *p_sys = p_dec->p_sys;
    block_t         *p_cc = NULL;
    int i;

    for( i = 0; i < 4; i++ )
        pb_present[i] = p_sys->cc.pb_present[i];

    if( p_sys->cc.i_data <= 0 )
        return NULL;

    p_cc = block_New( p_dec, p_sys->cc.i_data);
    if( p_cc )
    {
        memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data );
        p_cc->i_dts =
        p_cc->i_pts = p_sys->cc.b_reorder ? p_sys->i_cc_pts : p_sys->i_cc_dts;
        p_cc->i_flags = ( p_sys->cc.b_reorder  ? p_sys->i_cc_flags : BLOCK_FLAG_TYPE_P ) & ( BLOCK_FLAG_TYPE_I|BLOCK_FLAG_TYPE_P|BLOCK_FLAG_TYPE_B);
    }
    cc_Flush( &p_sys->cc );
    return p_cc;
}
714
#endif
715

716 717 718 719 720
/*****************************************************************************
 * GetAR: Get aspect ratio
 *****************************************************************************/
static void GetAR( decoder_t *p_dec )
{
721
    decoder_sys_t *p_sys = p_dec->p_sys;
Laurent Aimar's avatar
Laurent Aimar committed
722 723
    int i_old_sar_num = p_sys->i_sar_num;
    int i_old_sar_den = p_sys->i_sar_den;
724 725

    /* Check whether the input gave a particular aspect ratio */
Laurent Aimar's avatar
Laurent Aimar committed
726 727
    if( p_dec->fmt_in.video.i_sar_num > 0 &&
        p_dec->fmt_in.video.i_sar_den > 0 )
728
    {
Laurent Aimar's avatar
Laurent Aimar committed
729 730
        p_sys->i_sar_num = p_dec->fmt_in.video.i_sar_num;
        p_sys->i_sar_den = p_dec->fmt_in.video.i_sar_den;
731 732 733 734 735 736
    }
    else
    {
        /* Use the value provided in the MPEG sequence header */
        if( p_sys->p_info->sequence->pixel_height > 0 )
        {
737 738
            p_sys->i_sar_num = p_sys->p_info->sequence->pixel_width;
            p_sys->i_sar_den = p_sys->p_info->sequence->pixel_height;
739 740 741 742 743 744
        }
        else
        {
            /* Invalid aspect, assume 4:3.
             * This shouldn't happen and if it does it is a bug
             * in libmpeg2 (likely triggered by an invalid stream) */
745 746
            p_sys->i_sar_num = p_sys->p_info->sequence->picture_height * 4;
            p_sys->i_sar_den = p_sys->p_info->sequence->picture_width * 3;
747 748 749
        }
    }

Laurent Aimar's avatar
Laurent Aimar committed
750 751
    if( p_sys->i_sar_num == i_old_sar_num &&
        p_sys->i_sar_den == i_old_sar_den )
752 753
        return;

754 755
    if( p_sys->p_info->sequence->frame_period > 0 )
        msg_Dbg( p_dec,
Laurent Aimar's avatar
Laurent Aimar committed
756
                 "%dx%d (display %d,%d), sar %i:%i, %u.%03u fps",
757 758 759 760
                 p_sys->p_info->sequence->picture_width,
                 p_sys->p_info->sequence->picture_height,
                 p_sys->p_info->sequence->display_width,
                 p_sys->p_info->sequence->display_height,
Laurent Aimar's avatar
Laurent Aimar committed
761
                 p_sys->i_sar_num, p_sys->i_sar_den,
762 763 764 765 766 767
                 (uint32_t)((uint64_t)1001000000 * 27 /
                     p_sys->p_info->sequence->frame_period / 1001),
                 (uint32_t)((uint64_t)1001000000 * 27 /
                     p_sys->p_info->sequence->frame_period % 1001) );
    else
        msg_Dbg( p_dec, "bad frame period" );
768
}
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872

/*****************************************************************************
 * PutPicture: Put a picture_t in mpeg2 context
 *****************************************************************************/
static void PutPicture( decoder_t *p_dec, picture_t *p_picture )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    /* */
    uint8_t *pp_buf[3];
    for( int j = 0; j < 3; j++ )
        pp_buf[j] = p_picture ? p_picture->p[j].p_pixels : NULL;
    mpeg2_set_buf( p_sys->p_mpeg2dec, pp_buf, p_picture );

    /* Completly broken API, why the hell does it suppose
     * the stride of the chroma planes ! */
    if( p_picture )
        mpeg2_stride( p_sys->p_mpeg2dec, p_picture->p[Y_PLANE].i_pitch );
}


/**
 * Initialize a virtual Decoded Picture Buffer to workaround
 * libmpeg2 deficient API
 */
static void DpbInit( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    for( int i = 0; i < DPB_COUNT; i++ )
        p_sys->p_dpb[i].p_picture = NULL;
}
/**
 * Empty and reset the current DPB
 */
static void DpbClean( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    for( int i = 0; i < DPB_COUNT; i++ )
    {
        picture_dpb_t *p = &p_sys->p_dpb[i];
        if( !p->p_picture )
            continue;
        if( p->b_linked )
            decoder_UnlinkPicture( p_dec, p->p_picture );
        if( !p->b_displayed )
            decoder_DeletePicture( p_dec, p->p_picture );

        p->p_picture = NULL;
    }
}
/**
 * Retreive a picture and reserve a place in the DPB
 */
static picture_t *DpbNewPicture( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    picture_dpb_t *p;
    int i;

    for( i = 0; i < DPB_COUNT; i++ )
    {
        p = &p_sys->p_dpb[i];
        if( !p->p_picture )
            break;
    }
    if( i >= DPB_COUNT )
    {
        msg_Err( p_dec, "Leaking picture" );
        return NULL;
    }

    p->p_picture = GetNewPicture( p_dec );
    if( p->p_picture )
    {
        decoder_LinkPicture( p_dec, p->p_picture );
        p->b_linked = true;
        p->b_displayed = false;

        p->p_picture->date = 0;
    }
    return p->p_picture;
}
static picture_dpb_t *DpbFindPicture( decoder_t *p_dec, picture_t *p_picture )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    for( int i = 0; i < DPB_COUNT; i++ )
    {
        picture_dpb_t *p = &p_sys->p_dpb[i];
        if( p->p_picture == p_picture )
            return p;
    }
    return NULL;
}
/**
 * Unlink the provided picture and ensure that the decoder
 * does not own it anymore.
 */
static void DpbUnlinkPicture( decoder_t *p_dec, picture_t *p_picture )
{
    picture_dpb_t *p = DpbFindPicture( p_dec, p_picture );
873 874 875 876 877 878 879 880

    /* XXX it is needed to workaround libmpeg2 bugs */
    if( !p || !p->b_linked )
    {
        msg_Err( p_dec, "DpbUnlinkPicture called on an invalid picture" );
        return;
    }

881 882 883 884 885 886 887 888 889 890 891 892
    assert( p && p->b_linked );

    decoder_UnlinkPicture( p_dec, p->p_picture );
    p->b_linked = false;

    if( !p->b_displayed )
        decoder_DeletePicture( p_dec, p->p_picture );
    p->p_picture = NULL;
}
/**
 * Mark the provided picture as displayed.
 */
893
static int DpbDisplayPicture( decoder_t *p_dec, picture_t *p_picture )
894 895
{
    picture_dpb_t *p = DpbFindPicture( p_dec, p_picture );
896 897 898 899 900 901 902 903

    /* XXX it is needed to workaround libmpeg2 bugs */
    if( !p || p->b_displayed || !p->b_linked )
    {
        msg_Err( p_dec, "DpbDisplayPicture called on an invalid picture" );
        return VLC_EGENERIC;
    }

904 905 906
    assert( p && !p->b_displayed && p->b_linked );

    p->b_displayed = true;
907
    return VLC_SUCCESS;
908 909 910
}