video.c 38.2 KB
Newer Older
1
/*****************************************************************************
2
 * video.c: video decoder using the libavcodec library
3
 *****************************************************************************
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
4
 * Copyright (C) 1999-2001 VLC authors and VideoLAN
5 6 7 8 9
 * $Id$
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 *          Gildas Bazin <gbazin@videolan.org>
 *
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
13 14 15 16
 * (at your option) any later version.
 *
 * 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.
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.
23 24 25 26 27
 *****************************************************************************/

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

32
#include <vlc_common.h>
zorglub's avatar
zorglub committed
33
#include <vlc_codec.h>
34
#include <vlc_avcodec.h>
Laurent Aimar's avatar
Laurent Aimar committed
35
#include <vlc_cpu.h>
36
#include <vlc_modules.h>
37
#include <assert.h>
38

39
#include <libavcodec/avcodec.h>
40
#include <libavutil/mem.h>
41
#include <libavutil/pixdesc.h>
42

43
#include "avcodec.h"
44
#include "va.h"
45 46 47 48 49 50

/*****************************************************************************
 * decoder_sys_t : decoder descriptor
 *****************************************************************************/
struct decoder_sys_t
{
51
    AVCODEC_COMMON_MEMBERS
52 53 54 55 56 57 58

    /* Video decoder specific part */
    mtime_t i_pts;

    AVFrame          *p_ff_pic;

    /* for frame skipping algo */
59
    bool b_hurry_up;
60 61
    enum AVDiscard i_skip_frame;
    enum AVDiscard i_skip_idct;
62 63 64 65 66 67

    /* how many decoded frames are late */
    int     i_late_frames;
    mtime_t i_late_frames_start;

    /* for direct rendering */
68
    bool b_direct_rendering;
69
    int  i_direct_rendering_used;
70

71
    bool b_has_b_frames;
72 73

    /* Hack to force display of still pictures */
74
    bool b_first_frame;
75

76

77
    /* */
78 79
    //AVPaletteControl palette;
#warning FIXME
80 81 82

    /* */
    bool b_flush;
83 84 85

    /* VA API */
    vlc_va_t *p_va;
Laurent Aimar's avatar
Laurent Aimar committed
86 87

    vlc_sem_t sem_mt;
88 89
};

Laurent Aimar's avatar
Laurent Aimar committed
90 91 92 93 94 95 96 97
#ifdef HAVE_AVCODEC_MT
#   define wait_mt(s) vlc_sem_wait( &s->sem_mt )
#   define post_mt(s) vlc_sem_post( &s->sem_mt )
#else
#   define wait_mt(s)
#   define post_mt(s)
#endif

98 99 100
/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
101
static void ffmpeg_InitCodec      ( decoder_t * );
102 103
static void ffmpeg_CopyPicture    ( decoder_t *, picture_t *, AVFrame * );
static int  ffmpeg_GetFrameBuf    ( struct AVCodecContext *, AVFrame * );
104
static int  ffmpeg_ReGetFrameBuf( struct AVCodecContext *, AVFrame * );
105
static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *, AVFrame * );
106 107
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *,
                                          const enum PixelFormat * );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
108
static void vlc_va_Delete( vlc_va_t * );
109

110 111 112 113 114 115 116 117 118 119 120 121 122 123
static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc )
{
    uint8_t *p = (uint8_t*)&fcc;
    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
}

/*****************************************************************************
 * Local Functions
 *****************************************************************************/

/* Returns a new picture buffer */
static inline picture_t *ffmpeg_NewPictBuf( decoder_t *p_dec,
                                            AVCodecContext *p_context )
{
124
    decoder_sys_t *p_sys = p_dec->p_sys;
125

126 127
    p_dec->fmt_out.video.i_width = p_context->width;
    p_dec->fmt_out.video.i_height = p_context->height;
128 129 130 131 132 133

    if( !p_context->width || !p_context->height )
    {
        return NULL; /* invalid display size */
    }

134
    if( !p_sys->p_va && GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) )
135
    {
136 137 138 139
        /* we are doomed, but not really, because most codecs set their pix_fmt
         * much later
         * FIXME does it make sense here ? */
        p_dec->fmt_out.video.i_chroma = VLC_CODEC_I420;
140
    }
141
    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;
142 143

    /* If an aspect-ratio was specified in the input format then force it */
Laurent Aimar's avatar
Laurent Aimar committed
144
    if( p_dec->fmt_in.video.i_sar_num > 0 && p_dec->fmt_in.video.i_sar_den > 0 )
145
    {
Laurent Aimar's avatar
Laurent Aimar committed
146 147
        p_dec->fmt_out.video.i_sar_num = p_dec->fmt_in.video.i_sar_num;
        p_dec->fmt_out.video.i_sar_den = p_dec->fmt_in.video.i_sar_den;
148 149 150
    }
    else
    {
151 152
        p_dec->fmt_out.video.i_sar_num = p_context->sample_aspect_ratio.num;
        p_dec->fmt_out.video.i_sar_den = p_context->sample_aspect_ratio.den;
153

Laurent Aimar's avatar
Laurent Aimar committed
154
        if( !p_dec->fmt_out.video.i_sar_num || !p_dec->fmt_out.video.i_sar_den )
155
        {
Laurent Aimar's avatar
Laurent Aimar committed
156 157
            p_dec->fmt_out.video.i_sar_num = 1;
            p_dec->fmt_out.video.i_sar_den = 1;
158 159 160
        }
    }

Laurent Aimar's avatar
Laurent Aimar committed
161 162
    if( p_dec->fmt_in.video.i_frame_rate > 0 &&
        p_dec->fmt_in.video.i_frame_rate_base > 0 )
163 164 165 166
    {
        p_dec->fmt_out.video.i_frame_rate =
            p_dec->fmt_in.video.i_frame_rate;
        p_dec->fmt_out.video.i_frame_rate_base =
damienf's avatar
damienf committed
167
            p_dec->fmt_in.video.i_frame_rate_base;
168
    }
169
    else if( p_context->time_base.num > 0 && p_context->time_base.den > 0 )
170 171 172 173
    {
        p_dec->fmt_out.video.i_frame_rate = p_context->time_base.den;
        p_dec->fmt_out.video.i_frame_rate_base = p_context->time_base.num;
    }
174

175
    return decoder_NewPicture( p_dec );
176 177 178 179 180 181 182 183
}

/*****************************************************************************
 * InitVideo: initialize the video decoder
 *****************************************************************************
 * the ffmpeg codec will be opened, some memory allocated. The vout is not yet
 * opened (done after the first decoded frame).
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
184
int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
185
                      AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
186 187
{
    decoder_sys_t *p_sys;
188
    int i_val;
189 190

    /* Allocate the memory needed to store the decoder's structure */
ivoire's avatar
ivoire committed
191
    if( ( p_dec->p_sys = p_sys = calloc( 1, sizeof(decoder_sys_t) ) ) == NULL )
192
        return VLC_ENOMEM;
193

194 195
    p_codec->type = AVMEDIA_TYPE_VIDEO;
    p_context->codec_type = AVMEDIA_TYPE_VIDEO;
196
    p_context->codec_id = i_codec_id;
197 198 199 200
    p_sys->p_context = p_context;
    p_sys->p_codec = p_codec;
    p_sys->i_codec_id = i_codec_id;
    p_sys->psz_namecodec = psz_namecodec;
201
    p_sys->p_ff_pic = avcodec_alloc_frame();
202
    p_sys->b_delayed_open = true;
203
    p_sys->p_va = NULL;
Laurent Aimar's avatar
Laurent Aimar committed
204
    vlc_sem_init( &p_sys->sem_mt, 0 );
205 206

    /* ***** Fill p_context with init values ***** */
207
    p_sys->p_context->codec_tag = ffmpeg_CodecTag( p_dec->fmt_in.i_original_fourcc ?: p_dec->fmt_in.i_codec );
208 209 210

    /*  ***** Get configuration of ffmpeg plugin ***** */
    p_sys->p_context->workaround_bugs =
211
        var_InheritInteger( p_dec, "avcodec-workaround-bugs" );
212
    p_sys->p_context->err_recognition =
213
        var_InheritInteger( p_dec, "avcodec-error-resilience" );
214

215 216
    if( var_CreateGetBool( p_dec, "grayscale" ) )
        p_sys->p_context->flags |= CODEC_FLAG_GRAY;
217

218
    i_val = var_CreateGetInteger( p_dec, "avcodec-vismv" );
219
    if( i_val ) p_sys->p_context->debug_mv = i_val;
220

221
    i_val = var_CreateGetInteger( p_dec, "avcodec-skiploopfilter" );
222 223 224 225
    if( i_val >= 4 ) p_sys->p_context->skip_loop_filter = AVDISCARD_ALL;
    else if( i_val == 3 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONKEY;
    else if( i_val == 2 ) p_sys->p_context->skip_loop_filter = AVDISCARD_BIDIR;
    else if( i_val == 1 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONREF;
226

227
    if( var_CreateGetBool( p_dec, "avcodec-fast" ) )
228
        p_sys->p_context->flags2 |= CODEC_FLAG2_FAST;
229

230 231 232 233 234
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 54, 41, 0 )
    if( var_InheritBool( p_dec, "avcodec-ignorecrop" ) )
        p_sys->p_context->flags2 |= CODEC_FLAG2_IGNORE_CROP;
#endif

235
    /* ***** libavcodec frame skipping ***** */
236
    p_sys->b_hurry_up = var_CreateGetBool( p_dec, "avcodec-hurry-up" );
237

238
    switch( var_CreateGetInteger( p_dec, "avcodec-skip-frame" ) )
239 240 241 242 243 244 245 246
    {
        case -1:
            p_sys->p_context->skip_frame = AVDISCARD_NONE;
            break;
        case 0:
            p_sys->p_context->skip_frame = AVDISCARD_DEFAULT;
            break;
        case 1:
247
            p_sys->p_context->skip_frame = AVDISCARD_NONREF;
248 249 250 251 252 253 254 255 256 257 258
            break;
        case 2:
            p_sys->p_context->skip_frame = AVDISCARD_NONKEY;
            break;
        case 3:
            p_sys->p_context->skip_frame = AVDISCARD_ALL;
            break;
        default:
            p_sys->p_context->skip_frame = AVDISCARD_NONE;
            break;
    }
259
    p_sys->i_skip_frame = p_sys->p_context->skip_frame;
260

261
    switch( var_CreateGetInteger( p_dec, "avcodec-skip-idct" ) )
262 263 264 265 266 267 268 269
    {
        case -1:
            p_sys->p_context->skip_idct = AVDISCARD_NONE;
            break;
        case 0:
            p_sys->p_context->skip_idct = AVDISCARD_DEFAULT;
            break;
        case 1:
270
            p_sys->p_context->skip_idct = AVDISCARD_NONREF;
271 272 273 274 275 276 277 278 279 280 281
            break;
        case 2:
            p_sys->p_context->skip_idct = AVDISCARD_NONKEY;
            break;
        case 3:
            p_sys->p_context->skip_idct = AVDISCARD_ALL;
            break;
        default:
            p_sys->p_context->skip_idct = AVDISCARD_NONE;
            break;
    }
282
    p_sys->i_skip_idct = p_sys->p_context->skip_idct;
283

284
    /* ***** libavcodec direct rendering ***** */
285
    p_sys->b_direct_rendering = false;
286
    p_sys->i_direct_rendering_used = -1;
287
    if( var_CreateGetBool( p_dec, "avcodec-dr" ) &&
288
       (p_sys->p_codec->capabilities & CODEC_CAP_DR1) &&
289
        /* No idea why ... but this fixes flickering on some TSCC streams */
290
        p_sys->i_codec_id != CODEC_ID_TSCC && p_sys->i_codec_id != CODEC_ID_CSCD &&
291
        p_sys->i_codec_id != CODEC_ID_CINEPAK &&
292 293 294 295
        !p_sys->p_context->debug_mv )
    {
        /* Some codecs set pix_fmt only after the 1st frame has been decoded,
         * so we need to do another check in ffmpeg_GetFrameBuf() */
296
        p_sys->b_direct_rendering = true;
297 298
    }

299
    /* libavcodec doesn't properly release old pictures when frames are skipped */
300
    //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = false;
301 302
    if( p_sys->b_direct_rendering )
    {
303
        msg_Dbg( p_dec, "trying to use direct rendering" );
304 305
        p_sys->p_context->flags |= CODEC_FLAG_EMU_EDGE;
    }
306 307 308 309
    else
    {
        msg_Dbg( p_dec, "direct rendering is disabled" );
    }
310 311 312 313

    /* Always use our get_buffer wrapper so we can calculate the
     * PTS correctly */
    p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf;
314
    p_sys->p_context->reget_buffer = ffmpeg_ReGetFrameBuf;
315 316 317
    p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf;
    p_sys->p_context->opaque = p_dec;

Laurent Aimar's avatar
Laurent Aimar committed
318
#ifdef HAVE_AVCODEC_MT
319
    int i_thread_count = var_InheritInteger( p_dec, "avcodec-threads" );
Laurent Aimar's avatar
Laurent Aimar committed
320
    if( i_thread_count <= 0 )
321
    {
Laurent Aimar's avatar
Laurent Aimar committed
322
        i_thread_count = vlc_GetCPUCount();
323 324
        if( i_thread_count > 1 )
            i_thread_count++;
325 326 327

        //FIXME: take in count the decoding time
        i_thread_count = __MIN( i_thread_count, 4 );
328
    }
329
    i_thread_count = __MIN( i_thread_count, 16 );
330 331 332 333
    msg_Dbg( p_dec, "allowing %d thread(s) for decoding", i_thread_count );
    p_sys->p_context->thread_count = i_thread_count;
#endif

334 335
    char *hw = var_CreateGetString( p_dec, "avcodec-hw" ); /* FIXME */
    if( (hw == NULL || strcasecmp( hw, "none" )) &&
336 337 338 339
        (i_codec_id == CODEC_ID_MPEG1VIDEO || i_codec_id == CODEC_ID_MPEG2VIDEO ||
         i_codec_id == CODEC_ID_MPEG4 ||
         i_codec_id == CODEC_ID_H264 ||
         i_codec_id == CODEC_ID_VC1 || i_codec_id == CODEC_ID_WMV3) )
Laurent Aimar's avatar
Laurent Aimar committed
340
    {
341
#ifdef HAVE_AVCODEC_MT
342
        if( p_sys->p_context->thread_type & FF_THREAD_FRAME )
343
        {
344
            msg_Warn( p_dec, "threaded frame decoding is not compatible with libavcodec-hw, disabled" );
345 346
            p_sys->p_context->thread_type &= ~FF_THREAD_FRAME;
        }
347 348 349
        if( ( p_sys->p_context->thread_type & FF_THREAD_SLICE ) &&
            ( i_codec_id == CODEC_ID_MPEG1VIDEO || i_codec_id == CODEC_ID_MPEG2VIDEO ) )
        {
350
            msg_Warn( p_dec, "threaded slice decoding is not compatible with libavcodec-hw, disabled" );
351 352
            p_sys->p_context->thread_type &= ~FF_THREAD_SLICE;
        }
353
#endif
354 355
        p_sys->p_context->get_format = ffmpeg_GetFormat;
    }
356
    free( hw );
357 358 359 360 361
#ifdef HAVE_AVCODEC_MT
    if( p_sys->p_context->thread_type & FF_THREAD_FRAME )
        p_dec->i_extra_picture_buffers = 2 * p_sys->p_context->thread_count;
#endif

Laurent Aimar's avatar
Laurent Aimar committed
362

363
    /* ***** misc init ***** */
364
    p_sys->i_pts = VLC_TS_INVALID;
365 366
    p_sys->b_has_b_frames = false;
    p_sys->b_first_frame = true;
367
    p_sys->b_flush = false;
368 369 370 371
    p_sys->i_late_frames = 0;

    /* Set output properties */
    p_dec->fmt_out.i_cat = VIDEO_ES;
372 373
    if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS )
    {
374
        /* we are doomed. but not really, because most codecs set their pix_fmt later on */
375
        p_dec->fmt_out.i_codec = VLC_CODEC_I420;
376 377
    }
    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;
378 379

    /* Setup palette */
380
# warning FIXME
381

382 383 384
    /* ***** init this codec with special data ***** */
    ffmpeg_InitCodec( p_dec );

385
    /* ***** Open the codec ***** */
386
    if( ffmpeg_OpenCodec( p_dec ) < 0 )
387 388
    {
        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
389
        av_free( p_sys->p_ff_pic );
Laurent Aimar's avatar
Laurent Aimar committed
390
        vlc_sem_destroy( &p_sys->sem_mt );
391 392 393 394 395 396 397 398 399 400
        free( p_sys );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}

/*****************************************************************************
 * DecodeVideo: Called to decode one or more frames
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
401
picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
402 403
{
    decoder_sys_t *p_sys = p_dec->p_sys;
404
    AVCodecContext *p_context = p_sys->p_context;
405
    int b_drawpicture;
406
    int b_null_size = false;
407 408
    block_t *p_block;

409 410
    if( !pp_block || !*pp_block )
        return NULL;
411

412
    if( !p_context->extradata_size && p_dec->fmt_in.i_extra )
413
    {
414
        ffmpeg_InitCodec( p_dec );
415 416 417 418 419 420
        if( p_sys->b_delayed_open )
        {
            if( ffmpeg_OpenCodec( p_dec ) )
                msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
        }
    }
421

422
    p_block = *pp_block;
423 424 425 426 427
    if( p_sys->b_delayed_open )
    {
        block_Release( p_block );
        return NULL;
    }
428 429 430

    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
    {
431
        p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover properly */
432 433 434

        p_sys->i_late_frames = 0;

435 436
        if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
            avcodec_flush_buffers( p_context );
Laurent Aimar's avatar
Laurent Aimar committed
437

438
        block_Release( p_block );
439 440 441 442 443 444 445 446 447 448 449
        return NULL;
    }

    if( p_block->i_flags & BLOCK_FLAG_PREROLL )
    {
        /* Do not care about late frames when prerolling
         * TODO avoid decoding of non reference frame
         * (ie all B except for H264 where it depends only on nal_ref_idc) */
        p_sys->i_late_frames = 0;
    }

450
    if( !p_dec->b_pace_control && (p_sys->i_late_frames > 0) &&
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
451
        (mdate() - p_sys->i_late_frames_start > INT64_C(5000000)) )
452
    {
453
        if( p_sys->i_pts > VLC_TS_INVALID )
454 455 456
        {
            msg_Err( p_dec, "more than 5 seconds of late video -> "
                     "dropping frame (computer too slow ?)" );
457
            p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover properly */
458 459 460 461 462 463 464 465
        }
        block_Release( p_block );
        p_sys->i_late_frames--;
        return NULL;
    }

    /* A good idea could be to decode all I pictures and see for the other */
    if( !p_dec->b_pace_control &&
466 467
        p_sys->b_hurry_up &&
        (p_sys->i_late_frames > 4) )
468 469
    {
        b_drawpicture = 0;
470
        if( p_sys->i_late_frames < 12 )
471
        {
472
            p_context->skip_frame =
473 474
                    (p_sys->i_skip_frame <= AVDISCARD_NONREF) ?
                    AVDISCARD_NONREF : p_sys->i_skip_frame;
475 476 477 478 479 480 481 482 483 484 485 486
        }
        else
        {
            /* picture too late, won't decode
             * but break picture until a new I, and for mpeg4 ...*/
            p_sys->i_late_frames--; /* needed else it will never be decrease */
            block_Release( p_block );
            return NULL;
        }
    }
    else
    {
487
        if( p_sys->b_hurry_up )
488
            p_context->skip_frame = p_sys->i_skip_frame;
Laurent Aimar's avatar
Laurent Aimar committed
489
        if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
490 491 492 493 494
            b_drawpicture = 1;
        else
            b_drawpicture = 0;
    }

495
    if( p_context->width <= 0 || p_context->height <= 0 )
496
    {
497
        if( p_sys->b_hurry_up )
498
            p_context->skip_frame = p_sys->i_skip_frame;
499
        b_null_size = true;
500
    }
Laurent Aimar's avatar
Laurent Aimar committed
501 502
    else if( !b_drawpicture )
    {
503 504 505
        /* It creates broken picture
         * FIXME either our parser or ffmpeg is broken */
#if 0
506
        if( p_sys->b_hurry_up )
507
            p_context->skip_frame = __MAX( p_context->skip_frame,
508
                                                  AVDISCARD_NONREF );
509
#endif
Laurent Aimar's avatar
Laurent Aimar committed
510
    }
511 512

    /*
513
     * Do the actual decoding now */
514

515
    /* Don't forget that libavcodec requires a little more bytes
516 517 518
     * that the real frame size */
    if( p_block->i_buffer > 0 )
    {
519 520
        p_sys->b_flush = ( p_block->i_flags & BLOCK_FLAG_END_OF_SEQUENCE ) != 0;

521 522 523
        p_block = block_Realloc( p_block, 0,
                            p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE );
        if( !p_block )
ivoire's avatar
ivoire committed
524
            return NULL;
525
        p_block->i_buffer -= FF_INPUT_BUFFER_PADDING_SIZE;
526
        *pp_block = p_block;
527
        memset( p_block->p_buffer + p_block->i_buffer, 0,
528 529 530
                FF_INPUT_BUFFER_PADDING_SIZE );
    }

531
    while( p_block->i_buffer > 0 || p_sys->b_flush )
532 533 534
    {
        int i_used, b_gotpicture;
        picture_t *p_pic;
535
        AVPacket pkt;
536

537 538 539 540 541 542 543
        /* Set the PTS/DTS in the context reordered_opaque field */
        if( p_block->i_pts > VLC_TS_INVALID  )
            p_context->reordered_opaque = (p_block->i_pts << 1) | 0;
        else if( p_block->i_dts > VLC_TS_INVALID )
            p_context->reordered_opaque = (p_block->i_dts << 1) | 1;
        else
            p_context->reordered_opaque = INT64_MIN;
544
        p_sys->p_ff_pic->reordered_opaque = p_context->reordered_opaque;
545 546 547 548 549

        /* Make sure we don't reuse the same timestamps twice */
        p_block->i_pts =
        p_block->i_dts = VLC_TS_INVALID;

Laurent Aimar's avatar
Laurent Aimar committed
550
        post_mt( p_sys );
551

552 553 554 555 556
        av_init_packet( &pkt );
        pkt.data = p_block->p_buffer;
        pkt.size = p_block->i_buffer;
        i_used = avcodec_decode_video2( p_context, p_sys->p_ff_pic,
                                       &b_gotpicture, &pkt );
557

558 559
        if( b_null_size && !p_sys->b_flush &&
            p_context->width > 0 && p_context->height > 0 )
560 561
        {
            /* Reparse it to not drop the I frame */
562
            b_null_size = false;
563
            if( p_sys->b_hurry_up )
564
                p_context->skip_frame = p_sys->i_skip_frame;
565 566
            i_used = avcodec_decode_video2( p_context, p_sys->p_ff_pic,
                                           &b_gotpicture, &pkt );
567
        }
Laurent Aimar's avatar
Laurent Aimar committed
568
        wait_mt( p_sys );
569

570 571 572
        if( p_sys->b_flush )
            p_sys->b_first_frame = true;

573
        if( p_block->i_buffer <= 0 )
574 575
            p_sys->b_flush = false;

576 577
        if( i_used < 0 )
        {
Laurent Aimar's avatar
Laurent Aimar committed
578
            if( b_drawpicture )
579 580
                msg_Warn( p_dec, "cannot decode one frame (%zu bytes)",
                          p_block->i_buffer );
581 582 583
            block_Release( p_block );
            return NULL;
        }
Laurent Aimar's avatar
Laurent Aimar committed
584 585
        else if( i_used > p_block->i_buffer ||
                 p_context->thread_count > 1 )
586
        {
587
            i_used = p_block->i_buffer;
588 589 590
        }

        /* Consumed bytes */
591 592
        p_block->i_buffer -= i_used;
        p_block->p_buffer += i_used;
593 594 595 596 597 598 599 600

        /* Nothing to display */
        if( !b_gotpicture )
        {
            if( i_used == 0 ) break;
            continue;
        }

601
        /* Sanity check (seems to be needed for some streams) */
602
        if( p_sys->p_ff_pic->pict_type == AV_PICTURE_TYPE_B)
603 604 605 606
        {
            p_sys->b_has_b_frames = true;
        }

607 608 609 610 611 612 613 614 615 616 617 618 619
        /* Compute the PTS */
        mtime_t i_pts = VLC_TS_INVALID;
        if( p_sys->p_ff_pic->reordered_opaque != INT64_MIN )
        {
            mtime_t i_ts = p_sys->p_ff_pic->reordered_opaque >> 1;
            bool    b_dts = p_sys->p_ff_pic->reordered_opaque & 1;
            if( b_dts )
            {
                if( !p_context->has_b_frames ||
                    !p_sys->b_has_b_frames ||
                    !p_sys->p_ff_pic->reference ||
                    p_sys->i_pts <= VLC_TS_INVALID )
                    i_pts = i_ts;
620 621 622 623 624 625 626 627 628

                /* Guess what ? The rules are different for Real Video :( */
                if( (p_dec->fmt_in.i_codec == VLC_CODEC_RV30 ||
                     p_dec->fmt_in.i_codec == VLC_CODEC_RV40) &&
                    p_sys->b_has_b_frames )
                {
                    i_pts = VLC_TS_INVALID;
                    if(p_sys->p_ff_pic->reference) i_pts = i_ts;
                }
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
            }
            else
            {
                i_pts = i_ts;
            }
        }
        if( i_pts <= VLC_TS_INVALID )
            i_pts = p_sys->i_pts;

        /* Interpolate the next PTS */
        if( i_pts > VLC_TS_INVALID )
            p_sys->i_pts = i_pts;
        if( p_sys->i_pts > VLC_TS_INVALID )
        {
            /* interpolate the next PTS */
            if( p_dec->fmt_in.video.i_frame_rate > 0 &&
                p_dec->fmt_in.video.i_frame_rate_base > 0 )
            {
                p_sys->i_pts += INT64_C(1000000) *
                    (2 + p_sys->p_ff_pic->repeat_pict) *
                    p_dec->fmt_in.video.i_frame_rate_base /
                    (2 * p_dec->fmt_in.video.i_frame_rate);
            }
            else if( p_context->time_base.den > 0 )
            {
                int i_tick = p_context->ticks_per_frame;
                if( i_tick <= 0 )
                    i_tick = 1;

                p_sys->i_pts += INT64_C(1000000) *
                    (2 + p_sys->p_ff_pic->repeat_pict) *
                    i_tick * p_context->time_base.num /
                    (2 * p_context->time_base.den);
            }
        }
664

665
        /* Update frame late count (except when doing preroll) */
666 667
        mtime_t i_display_date = 0;
        if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
668
            i_display_date = decoder_GetDisplayDate( p_dec, i_pts );
669

670
        if( i_display_date > 0 && i_display_date <= mdate() )
671 672 673 674 675 676 677 678 679 680
        {
            p_sys->i_late_frames++;
            if( p_sys->i_late_frames == 1 )
                p_sys->i_late_frames_start = mdate();
        }
        else
        {
            p_sys->i_late_frames = 0;
        }

681
        if( !b_drawpicture || ( !p_sys->p_va && !p_sys->p_ff_pic->linesize[0] ) )
682 683
            continue;

684
        if( p_sys->p_va != NULL || p_sys->p_ff_pic->opaque == NULL )
685 686
        {
            /* Get a new picture */
687
            p_pic = ffmpeg_NewPictBuf( p_dec, p_context );
688 689 690 691 692 693 694 695 696 697 698 699 700
            if( !p_pic )
            {
                block_Release( p_block );
                return NULL;
            }

            /* Fill p_picture_t from AVVideoFrame and do chroma conversion
             * if needed */
            ffmpeg_CopyPicture( p_dec, p_pic, p_sys->p_ff_pic );
        }
        else
        {
            p_pic = (picture_t *)p_sys->p_ff_pic->opaque;
701
            decoder_LinkPicture( p_dec, p_pic );
702 703
        }

Laurent Aimar's avatar
Laurent Aimar committed
704
        if( !p_dec->fmt_in.video.i_sar_num || !p_dec->fmt_in.video.i_sar_den )
705 706
        {
            /* Fetch again the aspect ratio in case it changed */
707
            p_dec->fmt_out.video.i_sar_num
708
                = p_context->sample_aspect_ratio.num;
709
            p_dec->fmt_out.video.i_sar_den
710
                = p_context->sample_aspect_ratio.den;
711

Laurent Aimar's avatar
Laurent Aimar committed
712
            if( !p_dec->fmt_out.video.i_sar_num || !p_dec->fmt_out.video.i_sar_den )
713
            {
Laurent Aimar's avatar
Laurent Aimar committed
714 715
                p_dec->fmt_out.video.i_sar_num = 1;
                p_dec->fmt_out.video.i_sar_den = 1;
716 717 718
            }
        }

719
        /* Send decoded frame to vout */
720
        if( i_pts > VLC_TS_INVALID)
721
        {
722
            p_pic->date = i_pts;
723 724 725 726

            if( p_sys->b_first_frame )
            {
                /* Hack to force display of still pictures */
727 728
                p_sys->b_first_frame = false;
                p_pic->b_force = true;
729 730 731 732 733 734
            }

            p_pic->i_nb_fields = 2 + p_sys->p_ff_pic->repeat_pict;
            p_pic->b_progressive = !p_sys->p_ff_pic->interlaced_frame;
            p_pic->b_top_field_first = p_sys->p_ff_pic->top_field_first;

735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752
            p_pic->i_qstride = p_sys->p_ff_pic->qstride;
            int i_mb_h = ( p_pic->format.i_height + 15 ) / 16;
            p_pic->p_q = malloc( p_pic->i_qstride * i_mb_h );
            memcpy( p_pic->p_q, p_sys->p_ff_pic->qscale_table,
                    p_pic->i_qstride * i_mb_h );
            switch( p_sys->p_ff_pic->qscale_type )
            {
                case FF_QSCALE_TYPE_MPEG1:
                    p_pic->i_qtype = QTYPE_MPEG1;
                    break;
                case FF_QSCALE_TYPE_MPEG2:
                    p_pic->i_qtype = QTYPE_MPEG2;
                    break;
                case FF_QSCALE_TYPE_H264:
                    p_pic->i_qtype = QTYPE_H264;
                    break;
            }

753 754 755 756
            return p_pic;
        }
        else
        {
757
            decoder_DeletePicture( p_dec, p_pic );
758 759 760 761 762 763 764 765 766 767
        }
    }

    block_Release( p_block );
    return NULL;
}

/*****************************************************************************
 * EndVideo: decoder destruction
 *****************************************************************************
768
 * This function is called when the thread ends after a successful
769 770
 * initialization.
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
771
void EndVideoDec( decoder_t *p_dec )
772 773 774
{
    decoder_sys_t *p_sys = p_dec->p_sys;

Laurent Aimar's avatar
Laurent Aimar committed
775 776
    post_mt( p_sys );

777 778 779
    /* do not flush buffers if codec hasn't been opened (theora/vorbis/VC1) */
    if( p_sys->p_context->codec )
        avcodec_flush_buffers( p_sys->p_context );
780

Laurent Aimar's avatar
Laurent Aimar committed
781 782
    wait_mt( p_sys );

783
    if( p_sys->p_ff_pic ) av_free( p_sys->p_ff_pic );
784 785

    if( p_sys->p_va )
786
    {
787
        vlc_va_Delete( p_sys->p_va );
788 789
        p_sys->p_va = NULL;
    }
Laurent Aimar's avatar
Laurent Aimar committed
790
    vlc_sem_destroy( &p_sys->sem_mt );
791 792
}

793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809
/*****************************************************************************
 * ffmpeg_InitCodec: setup codec extra initialization data for ffmpeg
 *****************************************************************************/
static void ffmpeg_InitCodec( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    int i_size = p_dec->fmt_in.i_extra;

    if( !i_size ) return;

    if( p_sys->i_codec_id == CODEC_ID_SVQ3 )
    {
        uint8_t *p;

        p_sys->p_context->extradata_size = i_size + 12;
        p = p_sys->p_context->extradata  =
            malloc( p_sys->p_context->extradata_size );
ivoire's avatar
ivoire committed
810 811
        if( !p )
            return;
812 813 814 815 816 817 818

        memcpy( &p[0],  "SVQ3", 4 );
        memset( &p[4], 0, 8 );
        memcpy( &p[12], p_dec->fmt_in.p_extra, i_size );

        /* Now remove all atoms before the SMI one */
        if( p_sys->p_context->extradata_size > 0x5a &&
819
            strncmp( (char*)&p[0x56], "SMI ", 4 ) )
820 821 822 823 824 825 826 827 828 829 830
        {
            uint8_t *psz = &p[0x52];

            while( psz < &p[p_sys->p_context->extradata_size - 8] )
            {
                int i_size = GetDWBE( psz );
                if( i_size <= 1 )
                {
                    /* FIXME handle 1 as long size */
                    break;
                }
831
                if( !strncmp( (char*)&psz[4], "SMI ", 4 ) )
832 833 834 835 836 837 838 839 840 841 842 843 844 845 846
                {
                    memmove( &p[0x52], psz,
                             &p[p_sys->p_context->extradata_size] - psz );
                    break;
                }

                psz += i_size;
            }
        }
    }
    else
    {
        p_sys->p_context->extradata_size = i_size;
        p_sys->p_context->extradata =
            malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
ivoire's avatar
ivoire committed
847 848 849 850 851 852 853
        if( p_sys->p_context->extradata )
        {
            memcpy( p_sys->p_context->extradata,
                    p_dec->fmt_in.p_extra, i_size );
            memset( &((uint8_t*)p_sys->p_context->extradata)[i_size],
                    0, FF_INPUT_BUFFER_PADDING_SIZE );
        }
854 855 856
    }
}

857 858 859 860 861 862 863 864 865
/*****************************************************************************
 * ffmpeg_CopyPicture: copy a picture from ffmpeg internal buffers to a
 *                     picture_t structure (when not in direct rendering mode).
 *****************************************************************************/
static void ffmpeg_CopyPicture( decoder_t *p_dec,
                                picture_t *p_pic, AVFrame *p_ff_pic )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

866 867
    if( p_sys->p_va )
    {
868
        vlc_va_Extract( p_sys->p_va, p_pic, p_ff_pic );
869
    }
870
    else if( FindVlcChroma( p_sys->p_context->pix_fmt ) )
871 872 873 874 875
    {
        int i_plane, i_size, i_line;
        uint8_t *p_dst, *p_src;
        int i_src_stride, i_dst_stride;

876
        for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
877
        {
878 879 880 881 882 883 884 885
            p_src  = p_ff_pic->data[i_plane];
            p_dst = p_pic->p[i_plane].p_pixels;
            i_src_stride = p_ff_pic->linesize[i_plane];
            i_dst_stride = p_pic->p[i_plane].i_pitch;

            i_size = __MIN( i_src_stride, i_dst_stride );
            for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines;
                 i_line++ )
886
            {
Rafaël Carré's avatar
Rafaël Carré committed
887
                memcpy( p_dst, p_src, i_size );
888 889
                p_src += i_src_stride;
                p_dst += i_dst_stride;
890 891 892 893 894
            }
        }
    }
    else
    {
895 896 897
        const char *name = av_get_pix_fmt_name( p_sys->p_context->pix_fmt );
        msg_Err( p_dec, "Unsupported decoded output format %d (%s)",
                 p_sys->p_context->pix_fmt, name ? name : "unknown" );
898
        p_dec->b_error = 1;