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

Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
25 26 27 28 29 30 31 32
/*****************************************************************************
 * NOTA BENE: this module requires the linking against a library which is
 * known to require licensing under the GNU General Public License version 2
 * (or later). Therefore, the result of compiling this module will normally
 * be subject to the terms of that later license.
 *****************************************************************************/


gbazin's avatar
 
gbazin committed
33 34 35
/*****************************************************************************
 * Preamble
 *****************************************************************************/
36 37 38
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
39
#include <assert.h>
40

41
#include <vlc_common.h>
42
#include <vlc_plugin.h>
zorglub's avatar
zorglub committed
43
#include <vlc_codec.h>
44
#include <vlc_block_helper.h>
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
45
#include <vlc_cpu.h>
46
#include "../codec/cc.h"
gbazin's avatar
 
gbazin committed
47

48
#include <mpeg2.h>
gbazin's avatar
 
gbazin committed
49

50
#include <vlc_codec_synchro.h>
51

gbazin's avatar
 
gbazin committed
52
/*****************************************************************************
gbazin's avatar
 
gbazin committed
53
 * decoder_sys_t : libmpeg2 decoder descriptor
gbazin's avatar
 
gbazin committed
54
 *****************************************************************************/
55 56 57 58 59 60 61 62
#define DPB_COUNT (3+1)
typedef struct
{
    picture_t *p_picture;
    bool      b_linked;
    bool      b_displayed;
} picture_dpb_t;

gbazin's avatar
 
gbazin committed
63
struct decoder_sys_t
gbazin's avatar
 
gbazin committed
64 65 66 67 68 69
{
    /*
     * libmpeg2 properties
     */
    mpeg2dec_t          *p_mpeg2dec;
    const mpeg2_info_t  *p_info;
70
    bool                b_skip;
gbazin's avatar
 
gbazin committed
71 72 73 74 75 76

    /*
     * Input properties
     */
    mtime_t          i_previous_pts;
    mtime_t          i_current_pts;
77 78
    mtime_t          i_previous_dts;
    mtime_t          i_current_dts;
79 80
    bool             b_garbage_pic;
    bool             b_after_sequence_header; /* is it the next frame after
81
                                               * the sequence header ?    */
82 83
    bool             b_slice_i;             /* intra-slice refresh stream */
    bool             b_second_field;
gbazin's avatar
 
gbazin committed
84

85
    bool             b_preroll;
Laurent Aimar's avatar
Laurent Aimar committed
86

87 88 89
    /* */
    picture_dpb_t        p_dpb[DPB_COUNT];

gbazin's avatar
 
gbazin committed
90 91 92
    /*
     * Output properties
     */
93
    decoder_synchro_t *p_synchro;
94 95 96 97 98 99 100 101 102
    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;
103 104
    uint8_t        *p_gop_user_data;
    uint32_t        i_gop_user_data;
gbazin's avatar
 
gbazin committed
105
};
gbazin's avatar
 
gbazin committed
106 107 108 109

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
gbazin's avatar
 
gbazin committed
110 111 112 113
static int  OpenDecoder( vlc_object_t * );
static void CloseDecoder( vlc_object_t * );

static picture_t *DecodeBlock( decoder_t *, block_t ** );
114
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
115
static block_t   *GetCc( decoder_t *p_dec, bool pb_present[4] );
116
#endif
gbazin's avatar
 
gbazin committed
117

118 119 120
static picture_t *GetNewPicture( decoder_t * );
static void PutPicture( decoder_t *, picture_t * );

121
static void GetAR( decoder_t *p_dec );
gbazin's avatar
 
gbazin committed
122

123 124
static void Reset( decoder_t *p_dec );

125 126 127 128 129
/* */
static void DpbInit( decoder_t * );
static void DpbClean( decoder_t * );
static picture_t *DpbNewPicture( decoder_t * );
static void DpbUnlinkPicture( decoder_t *, picture_t * );
130
static int DpbDisplayPicture( decoder_t *, picture_t * );
131

gbazin's avatar
 
gbazin committed
132 133 134
/*****************************************************************************
 * Module descriptor
 *****************************************************************************/
135 136
vlc_module_begin ()
    set_description( N_("MPEG I/II video decoder (using libmpeg2)") )
137
    set_capability( "decoder", 50 )
138 139 140 141 142
    set_category( CAT_INPUT )
    set_subcategory( SUBCAT_INPUT_VCODEC )
    set_callbacks( OpenDecoder, CloseDecoder )
    add_shortcut( "libmpeg2" )
vlc_module_end ()
gbazin's avatar
 
gbazin committed
143 144 145 146 147 148

/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
gbazin's avatar
 
gbazin committed
149
    decoder_t *p_dec = (decoder_t*)p_this;
gbazin's avatar
 
gbazin committed
150
    decoder_sys_t *p_sys;
Sam Hocevar's avatar
Sam Hocevar committed
151
    uint32_t i_accel = 0;
gbazin's avatar
 
gbazin committed
152

Laurent Aimar's avatar
Laurent Aimar committed
153
    if( p_dec->fmt_in.i_codec != VLC_CODEC_MPGV )
gbazin's avatar
 
gbazin committed
154
        return VLC_EGENERIC;
155

156 157 158 159 160 161 162 163 164 165 166 167 168
    /* 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;
gbazin's avatar
 
gbazin committed
169 170
    }

gbazin's avatar
 
gbazin committed
171
    /* Allocate the memory needed to store the decoder's structure */
172
    if( ( p_dec->p_sys = p_sys = calloc( 1, sizeof(*p_sys)) ) == NULL )
173
        return VLC_ENOMEM;
gbazin's avatar
 
gbazin committed
174 175

    /* Initialize the thread properties */
gbazin's avatar
 
gbazin committed
176 177 178 179 180
    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;
181 182
    p_sys->i_current_dts  = 0;
    p_sys->i_previous_dts = 0;
Laurent Aimar's avatar
Laurent Aimar committed
183 184
    p_sys->i_sar_num = 0;
    p_sys->i_sar_den = 0;
185 186 187 188
    p_sys->b_garbage_pic = false;
    p_sys->b_slice_i  = false;
    p_sys->b_second_field = false;
    p_sys->b_skip     = false;
189
    p_sys->b_preroll = false;
190
    DpbInit( p_dec );
gbazin's avatar
 
gbazin committed
191

192 193 194 195 196 197 198
    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
199 200
    p_sys->p_gop_user_data = NULL;
    p_sys->i_gop_user_data = 0;
201

Christophe Massiot's avatar
Christophe Massiot committed
202
#if defined( __i386__ ) || defined( __x86_64__ )
203
    if( vlc_CPU_MMX() )
Sam Hocevar's avatar
Sam Hocevar committed
204
        i_accel |= MPEG2_ACCEL_X86_MMX;
205
    if( vlc_CPU_3dNOW() )
Sam Hocevar's avatar
Sam Hocevar committed
206
        i_accel |= MPEG2_ACCEL_X86_3DNOW;
207
    if( vlc_CPU_MMXEXT() )
Sam Hocevar's avatar
Sam Hocevar committed
208
        i_accel |= MPEG2_ACCEL_X86_MMXEXT;
hartman's avatar
hartman committed
209
#elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )
210
    if( vlc_CPU_ALTIVEC() )
Sam Hocevar's avatar
Sam Hocevar committed
211 212
        i_accel |= MPEG2_ACCEL_PPC_ALTIVEC;

213 214
#elif defined(__arm__)
# ifdef MPEG2_ACCEL_ARM
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
215
    i_accel |= MPEG2_ACCEL_ARM;
216
# endif
217
# ifdef MPEG2_ACCEL_ARM_NEON
218
    if( vlc_CPU_ARM_NEON() )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
219
        i_accel |= MPEG2_ACCEL_ARM_NEON;
220 221
# endif

222
    /* TODO: sparc */
Sam Hocevar's avatar
Sam Hocevar committed
223 224 225 226 227 228 229 230 231
#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 );

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

gbazin's avatar
 
gbazin committed
241 242 243
    p_sys->p_info = mpeg2_info( p_sys->p_mpeg2dec );

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

    return VLC_SUCCESS;
}
gbazin's avatar
 
gbazin committed
249

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

gbazin's avatar
 
gbazin committed
258 259
    block_t *p_block;

260 261
    if( !pp_block || !*pp_block )
        return NULL;
gbazin's avatar
 
gbazin committed
262 263

    p_block = *pp_block;
264
    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
265
        Reset( p_dec );
gbazin's avatar
 
gbazin committed
266 267

    while( 1 )
gbazin's avatar
 
gbazin committed
268
    {
gbazin's avatar
 
gbazin committed
269
        state = mpeg2_parse( p_sys->p_mpeg2dec );
gbazin's avatar
 
gbazin committed
270 271 272 273

        switch( state )
        {
        case STATE_SEQUENCE:
gbazin's avatar
 
gbazin committed
274
        {
275 276
            /* */
            DpbClean( p_dec );
gbazin's avatar
 
gbazin committed
277

278
            /* */
gbazin's avatar
 
gbazin committed
279
            mpeg2_custom_fbuf( p_sys->p_mpeg2dec, 1 );
gbazin's avatar
 
gbazin committed
280 281

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

            if( p_sys->p_synchro )
298
                decoder_SynchroRelease( p_sys->p_synchro );
299

300 301 302 303 304 305
            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) );
306 307
            p_sys->b_after_sequence_header = true;
            break;
gbazin's avatar
 
gbazin committed
308
        }
gbazin's avatar
 
gbazin committed
309

310 311 312 313 314 315 316 317 318 319 320 321
        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 );
                }
            }
322 323
            break;

gbazin's avatar
 
gbazin committed
324 325
        case STATE_PICTURE:
        {
326 327 328
            const mpeg2_info_t *p_info = p_sys->p_info;
            const mpeg2_picture_t *p_current = p_info->current_picture;

329
            mtime_t i_pts, i_dts;
330

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

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

gbazin's avatar
 
gbazin committed
353 354 355
            /* Hack to handle demuxers which only have DTS timestamps */
            if( !i_pts && !p_block->i_pts && p_block->i_dts > 0 )
            {
356 357
                if( p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ||
                    (p_current->flags &
gbazin's avatar
 
gbazin committed
358 359 360 361 362 363 364 365
                      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 */

366 367
#else /* New interface */

368 369 370 371 372 373
            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;
374 375
#endif

376 377
            /* If nb_fields == 1, it is a field picture, and it will be
             * followed by another field picture for which we won't call
378
             * decoder_SynchroNewPicture() because this would have other
379 380 381
             * problems, so we take it into account here.
             * This kind of sucks, but I didn't think better. --Meuuh
             */
382
            decoder_SynchroNewPicture( p_sys->p_synchro,
383 384 385 386
                                       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 );
gbazin's avatar
 
gbazin committed
387

388

389 390
            picture_t *p_pic;

391
            if( p_dec->b_frame_drop_allowed && !p_sys->b_preroll &&
392
                !(p_sys->b_slice_i
393
                   && ((p_current->flags
394
                         & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_P))
395
                   && !decoder_SynchroChoose( p_sys->p_synchro,
396
                              p_current->flags
gbazin's avatar
 
gbazin committed
397
                                & PIC_MASK_CODING_TYPE,
398
                              /*p_sys->p_vout->render_time*/ 0 /*FIXME*/,
399
                              p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ) )
400 401
                p_pic = NULL;
            else
402
            {
403
                p_pic = DpbNewPicture( p_dec );
404 405 406
                if( !p_pic )
                {
                    Reset( p_dec );
407 408 409 410 411 412 413 414

                    p_pic = DpbNewPicture( p_dec );
                    if( !p_pic )
                    {
                        mpeg2_reset( p_sys->p_mpeg2dec, 1 );
                        block_Release( p_block );
                        return NULL;
                    }
415 416
                }
            }
417

418 419 420 421 422
            mpeg2_skip( p_sys->p_mpeg2dec, p_pic == NULL );
            p_sys->b_skip = p_pic == NULL;
            if( p_pic != NULL )
                decoder_SynchroDecode( p_sys->p_synchro );
            else
423
                decoder_SynchroTrash( p_sys->p_synchro );
424

425
            PutPicture( p_dec, p_pic );
gbazin's avatar
 
gbazin committed
426

427
            if( p_info->user_data_len > 2 || p_sys->i_gop_user_data > 2 )
428 429 430
            {
                p_sys->i_cc_pts = i_pts;
                p_sys->i_cc_dts = i_dts;
431
                if( (p_current->flags
432 433
                             & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_P )
                    p_sys->i_cc_flags = BLOCK_FLAG_TYPE_P;
434
                else if( (p_current->flags
435 436 437
                             & 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;
438 439
                bool b_top_field_first = p_sys->p_info->current_picture->flags
                                           & PIC_FLAG_TOP_FIELD_FIRST;
440

441 442 443
                if( p_sys->i_gop_user_data > 2 )
                {
                    /* We now have picture info for any cached user_data out of the gop */
444 445
                    cc_Extract( &p_sys->cc, b_top_field_first,
                                &p_sys->p_gop_user_data[0], p_sys->i_gop_user_data );
446 447 448 449
                    p_sys->i_gop_user_data = 0;
                }

                /* Extract the CC from the user_data of the picture */
450
                if( p_info->user_data_len > 2 )
451 452
                    cc_Extract( &p_sys->cc, b_top_field_first,
                                &p_info->user_data[0], p_info->user_data_len );
gbazin's avatar
 
gbazin committed
453 454
            }
        }
455
        break;
gbazin's avatar
 
gbazin committed
456

457 458 459

        case STATE_BUFFER:
            if( !p_block->i_buffer )
460
            {
461 462 463 464 465 466 467 468 469 470 471 472 473
                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 )
474
                {
475 476 477 478 479 480 481 482 483 484
                    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 );
485 486
                }
            }
487 488 489 490 491 492 493 494 495 496 497 498 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

            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;
531 532
            break;

533 534

        case STATE_INVALID_END:
gbazin's avatar
 
gbazin committed
535
        case STATE_END:
536
        case STATE_SLICE:
537 538 539
        {
            picture_t *p_pic = NULL;

540 541
            if( p_sys->p_info->display_fbuf &&
                p_sys->p_info->display_fbuf->id )
gbazin's avatar
 
gbazin committed
542
            {
543
                p_pic = p_sys->p_info->display_fbuf->id;
544 545
                if( DpbDisplayPicture( p_dec, p_pic ) )
                    p_pic = NULL;
gbazin's avatar
 
gbazin committed
546

547
                decoder_SynchroEnd( p_sys->p_synchro,
548 549
                                    p_sys->p_info->display_picture->flags & PIC_MASK_CODING_TYPE,
                                    p_sys->b_garbage_pic );
550

551 552 553 554 555 556 557
                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;
                }
558 559
            }

gbazin's avatar
 
gbazin committed
560 561
            if( p_sys->p_info->discard_fbuf &&
                p_sys->p_info->discard_fbuf->id )
562
            {
563
                DpbUnlinkPicture( p_dec, p_sys->p_info->discard_fbuf->id );
gbazin's avatar
 
gbazin committed
564
            }
gbazin's avatar
 
gbazin committed
565

566 567
            if( p_pic )
            {
568 569 570
                if( state == STATE_END )
                    p_pic->b_force = true; /* For still frames */

571 572
                /* Avoid frames with identical timestamps.
                 * Especially needed for still frames in DVD menus. */
573 574
                if( p_sys->i_last_frame_pts == p_pic->date )
                    p_pic->date++;
575 576 577
                p_sys->i_last_frame_pts = p_pic->date;
                return p_pic;
            }
gbazin's avatar
 
gbazin committed
578
            break;
579
        }
gbazin's avatar
 
gbazin committed
580

581
        case STATE_INVALID:
582
        {
583 584 585
            msg_Err( p_dec, "invalid picture encountered" );
            /* I don't think we have anything to do, but well without
             * docs ... */
586
            break;
587
        }
588

gbazin's avatar
 
gbazin committed
589 590 591 592 593
        default:
            break;
        }
    }

gbazin's avatar
 
gbazin committed
594 595
    /* Never reached */
    return NULL;
gbazin's avatar
 
gbazin committed
596 597 598
}

/*****************************************************************************
gbazin's avatar
 
gbazin committed
599
 * CloseDecoder: libmpeg2 decoder destruction
gbazin's avatar
 
gbazin committed
600
 *****************************************************************************/
gbazin's avatar
 
gbazin committed
601
static void CloseDecoder( vlc_object_t *p_this )
gbazin's avatar
 
gbazin committed
602
{
gbazin's avatar
 
gbazin committed
603
    decoder_t *p_dec = (decoder_t *)p_this;
gbazin's avatar
 
gbazin committed
604 605
    decoder_sys_t *p_sys = p_dec->p_sys;

606 607
    DpbClean( p_dec );

608 609
    free( p_sys->p_gop_user_data );

610
    if( p_sys->p_synchro ) decoder_SynchroRelease( p_sys->p_synchro );
gbazin's avatar
 
gbazin committed
611

gbazin's avatar
 
gbazin committed
612
    if( p_sys->p_mpeg2dec ) mpeg2_close( p_sys->p_mpeg2dec );
gbazin's avatar
 
gbazin committed
613

gbazin's avatar
 
gbazin committed
614
    free( p_sys );
gbazin's avatar
 
gbazin committed
615
}
gbazin's avatar
 
gbazin committed
616

617 618 619 620 621 622 623 624
/*****************************************************************************
 * 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 );
625
    mpeg2_reset( p_sys->p_mpeg2dec, 0 );
626 627 628
    DpbClean( p_dec );
}

gbazin's avatar
 
gbazin committed
629 630 631
/*****************************************************************************
 * GetNewPicture: Get a new picture from the vout and set the buf struct
 *****************************************************************************/
632
static picture_t *GetNewPicture( decoder_t *p_dec )
gbazin's avatar
 
gbazin committed
633
{
gbazin's avatar
 
gbazin committed
634
    decoder_sys_t *p_sys = p_dec->p_sys;
gbazin's avatar
 
gbazin committed
635
    picture_t *p_pic;
gbazin's avatar
 
gbazin committed
636

gbazin's avatar
 
gbazin committed
637
    p_dec->fmt_out.video.i_width = p_sys->p_info->sequence->width;
638 639
    p_dec->fmt_out.video.i_visible_width =
        p_sys->p_info->sequence->picture_width;
gbazin's avatar
 
gbazin committed
640
    p_dec->fmt_out.video.i_height = p_sys->p_info->sequence->height;
641 642
    p_dec->fmt_out.video.i_visible_height =
        p_sys->p_info->sequence->picture_height;
643 644
    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;
gbazin's avatar
 
gbazin committed
645

646 647 648 649 650 651 652 653
    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;
    }

gbazin's avatar
 
gbazin committed
654 655 656
    p_dec->fmt_out.i_codec =
        ( p_sys->p_info->sequence->chroma_height <
          p_sys->p_info->sequence->height ) ?
657
        VLC_CODEC_I420 : VLC_CODEC_I422;
gbazin's avatar
 
gbazin committed
658

gbazin's avatar
 
gbazin committed
659
    /* Get a new picture */
660
    p_pic = decoder_NewPicture( p_dec );
gbazin's avatar
 
gbazin committed
661

662 663
    if( p_pic == NULL )
        return NULL;
gbazin's avatar
 
gbazin committed
664

gbazin's avatar
 
gbazin committed
665 666 667 668 669 670 671
    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;

gbazin's avatar
 
gbazin committed
672 673
    return p_pic;
}
674

675
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690
/*****************************************************************************
 * 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;

691
    p_cc = block_Alloc( p_sys->cc.i_data);
692 693 694 695 696 697 698 699 700 701
    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;
}
702
#endif
703

704 705 706 707 708
/*****************************************************************************
 * GetAR: Get aspect ratio
 *****************************************************************************/
static void GetAR( decoder_t *p_dec )
{
709
    decoder_sys_t *p_sys = p_dec->p_sys;
Laurent Aimar's avatar
Laurent Aimar committed
710 711
    int i_old_sar_num = p_sys->i_sar_num;
    int i_old_sar_den = p_sys->i_sar_den;
712 713

    /* Check whether the input gave a particular aspect ratio */
Laurent Aimar's avatar
Laurent Aimar committed
714 715
    if( p_dec->fmt_in.video.i_sar_num > 0 &&
        p_dec->fmt_in.video.i_sar_den > 0 )
716
    {
Laurent Aimar's avatar
Laurent Aimar committed
717 718
        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;
719 720 721 722 723 724
    }
    else
    {
        /* Use the value provided in the MPEG sequence header */
        if( p_sys->p_info->sequence->pixel_height > 0 )
        {
725 726
            p_sys->i_sar_num = p_sys->p_info->sequence->pixel_width;
            p_sys->i_sar_den = p_sys->p_info->sequence->pixel_height;
727 728 729 730 731 732
        }
        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) */
733 734
            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;
735 736 737
        }
    }

Laurent Aimar's avatar
Laurent Aimar committed
738 739
    if( p_sys->i_sar_num == i_old_sar_num &&
        p_sys->i_sar_den == i_old_sar_den )
740 741
        return;

742 743
    if( p_sys->p_info->sequence->frame_period > 0 )
        msg_Dbg( p_dec,
Laurent Aimar's avatar
Laurent Aimar committed
744
                 "%dx%d (display %d,%d), sar %i:%i, %u.%03u fps",
745 746 747 748
                 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
749
                 p_sys->i_sar_num, p_sys->i_sar_den,
750 751 752 753 754 755
                 (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" );
756
}
757 758 759 760 761 762 763 764 765 766 767 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

/*****************************************************************************
 * 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 )
802
            picture_Release( p->p_picture );
803
        if( !p->b_displayed )
804
            picture_Release( p->p_picture );
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

        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 )
    {
834
        picture_Hold( p->p_picture );
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
        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 );
861 862 863 864 865 866 867 868

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

869 870
    assert( p && p->b_linked );

871
    picture_Release( p->p_picture );
872 873 874
    p->b_linked = false;

    if( !p->b_displayed )
875
        picture_Release( p->p_picture );
876 877 878 879 880
    p->p_picture = NULL;
}
/**
 * Mark the provided picture as displayed.
 */
881
static int DpbDisplayPicture( decoder_t *p_dec, picture_t *p_picture )
882 883
{
    picture_dpb_t *p = DpbFindPicture( p_dec, p_picture );
884 885 886 887 888 889 890 891

    /* 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;
    }

892 893 894
    assert( p && !p->b_displayed && p->b_linked );

    p->b_displayed = true;
895
    return VLC_SUCCESS;
896 897 898
}