video.c 41.9 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 <assert.h>
37

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

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

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

    /* Video decoder specific part */
    mtime_t i_pts;

    AVFrame          *p_ff_pic;

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

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

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

70
    bool b_has_b_frames;
71 72

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

75

76
    /* */
77 78 79 80 81
#if LIBAVCODEC_VERSION_MAJOR < 54
    AVPaletteControl palette;
#else
# warning FIXME
#endif
82 83 84

    /* */
    bool b_flush;
85 86 87

    /* VA API */
    vlc_va_t *p_va;
Laurent Aimar's avatar
Laurent Aimar committed
88 89

    vlc_sem_t sem_mt;
90 91
};

Laurent Aimar's avatar
Laurent Aimar committed
92 93 94 95 96 97 98 99
#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

100 101 102
/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
103
static void ffmpeg_InitCodec      ( decoder_t * );
104
static void ffmpeg_CopyPicture    ( decoder_t *, picture_t *, AVFrame * );
105 106 107
#if LIBAVCODEC_VERSION_MAJOR >= 55
static int lavc_GetFrame(struct AVCodecContext *, AVFrame *, int);
#else
108 109
static int  ffmpeg_GetFrameBuf    ( struct AVCodecContext *, AVFrame * );
static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *, AVFrame * );
110
#endif
111 112 113
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *,
                                          const enum PixelFormat * );

114 115 116 117 118 119 120 121 122 123 124 125 126 127
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 )
{
128
    decoder_sys_t *p_sys = p_dec->p_sys;
129

130 131 132 133 134 135 136 137
    if( p_context->coded_width != p_context->width ||
        p_context->coded_height != p_context->height )
    {
        p_dec->fmt_out.video.i_visible_width = p_context->width;
        p_dec->fmt_out.video.i_visible_height = p_context->height;
    }
    p_dec->fmt_out.video.i_width = p_context->coded_width;
    p_dec->fmt_out.video.i_height = p_context->coded_height;
138 139 140 141 142 143

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

144
    if( !p_sys->p_va && GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) )
145
    {
146 147 148 149
        /* 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;
150
    }
151
    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;
152 153

    /* If an aspect-ratio was specified in the input format then force it */
Laurent Aimar's avatar
Laurent Aimar committed
154
    if( p_dec->fmt_in.video.i_sar_num > 0 && p_dec->fmt_in.video.i_sar_den > 0 )
155
    {
Laurent Aimar's avatar
Laurent Aimar committed
156 157
        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;
158 159 160
    }
    else
    {
161 162
        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;
163

Laurent Aimar's avatar
Laurent Aimar committed
164
        if( !p_dec->fmt_out.video.i_sar_num || !p_dec->fmt_out.video.i_sar_den )
165
        {
Laurent Aimar's avatar
Laurent Aimar committed
166 167
            p_dec->fmt_out.video.i_sar_num = 1;
            p_dec->fmt_out.video.i_sar_den = 1;
168 169 170
        }
    }

Laurent Aimar's avatar
Laurent Aimar committed
171 172
    if( p_dec->fmt_in.video.i_frame_rate > 0 &&
        p_dec->fmt_in.video.i_frame_rate_base > 0 )
173 174 175 176
    {
        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
177
            p_dec->fmt_in.video.i_frame_rate_base;
178
    }
179
    else if( p_context->time_base.num > 0 && p_context->time_base.den > 0 )
180 181
    {
        p_dec->fmt_out.video.i_frame_rate = p_context->time_base.den;
182
        p_dec->fmt_out.video.i_frame_rate_base = p_context->time_base.num * __MAX( p_context->ticks_per_frame, 1 );
183
    }
184

185
    return decoder_NewPicture( p_dec );
186 187 188 189 190 191 192 193
}

/*****************************************************************************
 * 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
194
int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
195
                      AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
196 197
{
    decoder_sys_t *p_sys;
198
    int i_val;
199 200

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

204 205
    p_codec->type = AVMEDIA_TYPE_VIDEO;
    p_context->codec_type = AVMEDIA_TYPE_VIDEO;
206
    p_context->codec_id = i_codec_id;
207 208 209 210
    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;
211
    p_sys->p_ff_pic = avcodec_alloc_frame();
212
    p_sys->b_delayed_open = true;
213
    p_sys->p_va = NULL;
Laurent Aimar's avatar
Laurent Aimar committed
214
    vlc_sem_init( &p_sys->sem_mt, 0 );
215 216

    /* ***** Fill p_context with init values ***** */
217
    p_sys->p_context->codec_tag = ffmpeg_CodecTag( p_dec->fmt_in.i_original_fourcc ?: p_dec->fmt_in.i_codec );
218 219 220

    /*  ***** Get configuration of ffmpeg plugin ***** */
    p_sys->p_context->workaround_bugs =
221
        var_InheritInteger( p_dec, "avcodec-workaround-bugs" );
222
    p_sys->p_context->err_recognition =
223
        var_InheritInteger( p_dec, "avcodec-error-resilience" );
224

225 226
    if( var_CreateGetBool( p_dec, "grayscale" ) )
        p_sys->p_context->flags |= CODEC_FLAG_GRAY;
227

228
    i_val = var_CreateGetInteger( p_dec, "avcodec-vismv" );
229
    if( i_val ) p_sys->p_context->debug_mv = i_val;
230

231
    i_val = var_CreateGetInteger( p_dec, "avcodec-skiploopfilter" );
232 233 234 235
    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;
236

237
    if( var_CreateGetBool( p_dec, "avcodec-fast" ) )
238
        p_sys->p_context->flags2 |= CODEC_FLAG2_FAST;
239

240
#if LIBAVCODEC_VERSION_CHECK( 54, 41, 0, 91, 100 )
241 242 243 244
    if( var_InheritBool( p_dec, "avcodec-ignorecrop" ) )
        p_sys->p_context->flags2 |= CODEC_FLAG2_IGNORE_CROP;
#endif

245
    /* ***** libavcodec frame skipping ***** */
246
    p_sys->b_hurry_up = var_CreateGetBool( p_dec, "avcodec-hurry-up" );
247

248
    switch( var_CreateGetInteger( p_dec, "avcodec-skip-frame" ) )
249 250 251 252 253 254 255 256
    {
        case -1:
            p_sys->p_context->skip_frame = AVDISCARD_NONE;
            break;
        case 0:
            p_sys->p_context->skip_frame = AVDISCARD_DEFAULT;
            break;
        case 1:
257
            p_sys->p_context->skip_frame = AVDISCARD_NONREF;
258 259 260 261 262 263 264 265 266 267 268
            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;
    }
269
    p_sys->i_skip_frame = p_sys->p_context->skip_frame;
270

271
    switch( var_CreateGetInteger( p_dec, "avcodec-skip-idct" ) )
272 273 274 275 276 277 278 279
    {
        case -1:
            p_sys->p_context->skip_idct = AVDISCARD_NONE;
            break;
        case 0:
            p_sys->p_context->skip_idct = AVDISCARD_DEFAULT;
            break;
        case 1:
280
            p_sys->p_context->skip_idct = AVDISCARD_NONREF;
281 282 283 284 285 286 287 288 289 290 291
            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;
    }
292
    p_sys->i_skip_idct = p_sys->p_context->skip_idct;
293

294
    /* ***** libavcodec direct rendering ***** */
295
    p_sys->b_direct_rendering = false;
296
    p_sys->i_direct_rendering_used = -1;
297
    if( var_CreateGetBool( p_dec, "avcodec-dr" ) &&
298
       (p_sys->p_codec->capabilities & CODEC_CAP_DR1) &&
299
        /* No idea why ... but this fixes flickering on some TSCC streams */
300 301
        p_sys->i_codec_id != AV_CODEC_ID_TSCC && p_sys->i_codec_id != AV_CODEC_ID_CSCD &&
        p_sys->i_codec_id != AV_CODEC_ID_CINEPAK &&
302 303 304 305
        !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() */
306
        p_sys->b_direct_rendering = true;
307 308
    }

309
    /* libavcodec doesn't properly release old pictures when frames are skipped */
310
    //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = false;
311 312
    if( p_sys->b_direct_rendering )
    {
313
        msg_Dbg( p_dec, "trying to use direct rendering" );
314 315
        p_sys->p_context->flags |= CODEC_FLAG_EMU_EDGE;
    }
316 317 318 319
    else
    {
        msg_Dbg( p_dec, "direct rendering is disabled" );
    }
320

321
    p_sys->p_context->get_format = ffmpeg_GetFormat;
322 323
    /* Always use our get_buffer wrapper so we can calculate the
     * PTS correctly */
324 325 326
#if LIBAVCODEC_VERSION_MAJOR >= 55
    p_sys->p_context->get_buffer2 = lavc_GetFrame;
#else
327
    p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf;
328
    p_sys->p_context->reget_buffer = avcodec_default_reget_buffer;
329
    p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf;
330
#endif
331 332
    p_sys->p_context->opaque = p_dec;

Laurent Aimar's avatar
Laurent Aimar committed
333
#ifdef HAVE_AVCODEC_MT
334
    int i_thread_count = var_InheritInteger( p_dec, "avcodec-threads" );
Laurent Aimar's avatar
Laurent Aimar committed
335
    if( i_thread_count <= 0 )
336
    {
Laurent Aimar's avatar
Laurent Aimar committed
337
        i_thread_count = vlc_GetCPUCount();
338 339
        if( i_thread_count > 1 )
            i_thread_count++;
340 341 342

        //FIXME: take in count the decoding time
        i_thread_count = __MIN( i_thread_count, 4 );
343
    }
344
    i_thread_count = __MIN( i_thread_count, 16 );
345 346
    msg_Dbg( p_dec, "allowing %d thread(s) for decoding", i_thread_count );
    p_sys->p_context->thread_count = i_thread_count;
347
    p_sys->p_context->thread_safe_callbacks = true;
348

349
    switch( i_codec_id )
Laurent Aimar's avatar
Laurent Aimar committed
350
    {
351 352 353 354 355 356 357 358
        case AV_CODEC_ID_MPEG4:
        case AV_CODEC_ID_H263:
            p_sys->p_context->thread_type = 0;
            break;
        case AV_CODEC_ID_MPEG1VIDEO:
        case AV_CODEC_ID_MPEG2VIDEO:
            p_sys->p_context->thread_type &= ~FF_THREAD_SLICE;
            /* fall through */
359
# if (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 1, 0))
360 361 362
        case AV_CODEC_ID_H264:
        case AV_CODEC_ID_VC1:
        case AV_CODEC_ID_WMV3:
363
            p_sys->p_context->thread_type &= ~FF_THREAD_FRAME;
364
# endif
365
    }
366

367 368 369 370
    if( p_sys->p_context->thread_type & FF_THREAD_FRAME )
        p_dec->i_extra_picture_buffers = 2 * p_sys->p_context->thread_count;
#endif

371
    /* ***** misc init ***** */
372
    p_sys->i_pts = VLC_TS_INVALID;
373 374
    p_sys->b_has_b_frames = false;
    p_sys->b_first_frame = true;
375
    p_sys->b_flush = false;
376 377 378 379
    p_sys->i_late_frames = 0;

    /* Set output properties */
    p_dec->fmt_out.i_cat = VIDEO_ES;
380 381
    if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS )
    {
382
        /* we are doomed. but not really, because most codecs set their pix_fmt later on */
383
        p_dec->fmt_out.i_codec = VLC_CODEC_I420;
384 385
    }
    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;
386

387
#if LIBAVCODEC_VERSION_MAJOR < 54
388
    /* Setup palette */
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
    memset( &p_sys->palette, 0, sizeof(p_sys->palette) );
    if( p_dec->fmt_in.video.p_palette )
    {
        p_sys->palette.palette_changed = 1;

        for( int i = 0; i < __MIN( AVPALETTE_COUNT, p_dec->fmt_in.video.p_palette->i_entries ); i++ )
        {
            union {
                uint32_t u;
                uint8_t a[4];
            } c;
            c.a[0] = p_dec->fmt_in.video.p_palette->palette[i][0];
            c.a[1] = p_dec->fmt_in.video.p_palette->palette[i][1];
            c.a[2] = p_dec->fmt_in.video.p_palette->palette[i][2];
            c.a[3] = p_dec->fmt_in.video.p_palette->palette[i][3];

            p_sys->palette.palette[i] = c.u;
        }
        p_sys->p_context->palctrl = &p_sys->palette;

        p_dec->fmt_out.video.p_palette = malloc( sizeof(video_palette_t) );
        if( p_dec->fmt_out.video.p_palette )
            *p_dec->fmt_out.video.p_palette = *p_dec->fmt_in.video.p_palette;
    }
    else if( p_sys->i_codec_id != CODEC_ID_MSVIDEO1 && p_sys->i_codec_id != CODEC_ID_CINEPAK )
    {
        p_sys->p_context->palctrl = &p_sys->palette;
    }
#else
# warning FIXME
#endif
420

421 422 423
    /* ***** init this codec with special data ***** */
    ffmpeg_InitCodec( p_dec );

424
    /* ***** Open the codec ***** */
425
    if( ffmpeg_OpenCodec( p_dec ) < 0 )
426 427
    {
        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
428
        av_free( p_sys->p_ff_pic );
Laurent Aimar's avatar
Laurent Aimar committed
429
        vlc_sem_destroy( &p_sys->sem_mt );
430 431 432 433 434 435 436 437 438 439
        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
440
picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
441 442
{
    decoder_sys_t *p_sys = p_dec->p_sys;
443
    AVCodecContext *p_context = p_sys->p_context;
444
    int b_drawpicture;
445
    int b_null_size = false;
446 447
    block_t *p_block;

448 449
    if( !pp_block || !*pp_block )
        return NULL;
450

451
    if( !p_context->extradata_size && p_dec->fmt_in.i_extra )
452
    {
453
        ffmpeg_InitCodec( p_dec );
454 455 456 457 458 459
        if( p_sys->b_delayed_open )
        {
            if( ffmpeg_OpenCodec( p_dec ) )
                msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
        }
    }
460

461
    p_block = *pp_block;
462 463 464 465 466
    if( p_sys->b_delayed_open )
    {
        block_Release( p_block );
        return NULL;
    }
467 468 469

    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
    {
470
        p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover properly */
471 472 473

        p_sys->i_late_frames = 0;

474
        post_mt( p_sys );
475 476
        if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
            avcodec_flush_buffers( p_context );
477
        wait_mt( p_sys );
Laurent Aimar's avatar
Laurent Aimar committed
478

479
        block_Release( p_block );
480 481 482 483 484 485 486 487 488 489 490
        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;
    }

491
    if( !p_dec->b_pace_control && (p_sys->i_late_frames > 0) &&
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
492
        (mdate() - p_sys->i_late_frames_start > INT64_C(5000000)) )
493
    {
494
        if( p_sys->i_pts > VLC_TS_INVALID )
495 496 497
        {
            msg_Err( p_dec, "more than 5 seconds of late video -> "
                     "dropping frame (computer too slow ?)" );
498
            p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover properly */
499 500 501 502 503 504 505 506
        }
        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 &&
507 508
        p_sys->b_hurry_up &&
        (p_sys->i_late_frames > 4) )
509 510
    {
        b_drawpicture = 0;
511
        if( p_sys->i_late_frames < 12 )
512
        {
513
            p_context->skip_frame =
514 515
                    (p_sys->i_skip_frame <= AVDISCARD_NONREF) ?
                    AVDISCARD_NONREF : p_sys->i_skip_frame;
516 517 518 519 520 521 522 523 524 525 526 527
        }
        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
    {
528
        if( p_sys->b_hurry_up )
529
            p_context->skip_frame = p_sys->i_skip_frame;
Laurent Aimar's avatar
Laurent Aimar committed
530
        if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
531 532 533 534 535
            b_drawpicture = 1;
        else
            b_drawpicture = 0;
    }

536
    if( p_context->width <= 0 || p_context->height <= 0 )
537
    {
538
        if( p_sys->b_hurry_up )
539
            p_context->skip_frame = p_sys->i_skip_frame;
540
        b_null_size = true;
541
    }
Laurent Aimar's avatar
Laurent Aimar committed
542 543
    else if( !b_drawpicture )
    {
544 545 546
        /* It creates broken picture
         * FIXME either our parser or ffmpeg is broken */
#if 0
547
        if( p_sys->b_hurry_up )
548
            p_context->skip_frame = __MAX( p_context->skip_frame,
549
                                                  AVDISCARD_NONREF );
550
#endif
Laurent Aimar's avatar
Laurent Aimar committed
551
    }
552 553

    /*
554
     * Do the actual decoding now */
555

556
    /* Don't forget that libavcodec requires a little more bytes
557 558 559
     * that the real frame size */
    if( p_block->i_buffer > 0 )
    {
560 561
        p_sys->b_flush = ( p_block->i_flags & BLOCK_FLAG_END_OF_SEQUENCE ) != 0;

562 563 564
        p_block = block_Realloc( p_block, 0,
                            p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE );
        if( !p_block )
ivoire's avatar
ivoire committed
565
            return NULL;
566
        p_block->i_buffer -= FF_INPUT_BUFFER_PADDING_SIZE;
567
        *pp_block = p_block;
568
        memset( p_block->p_buffer + p_block->i_buffer, 0,
569 570 571
                FF_INPUT_BUFFER_PADDING_SIZE );
    }

572
    while( p_block->i_buffer > 0 || p_sys->b_flush )
573 574 575
    {
        int i_used, b_gotpicture;
        picture_t *p_pic;
576
        AVPacket pkt;
577

Laurent Aimar's avatar
Laurent Aimar committed
578
        post_mt( p_sys );
579

580 581 582
        av_init_packet( &pkt );
        pkt.data = p_block->p_buffer;
        pkt.size = p_block->i_buffer;
583 584 585 586 587 588 589
        pkt.pts = p_block->i_pts;
        pkt.dts = p_block->i_dts;

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

590 591
        i_used = avcodec_decode_video2( p_context, p_sys->p_ff_pic,
                                       &b_gotpicture, &pkt );
592

593 594
        if( b_null_size && !p_sys->b_flush &&
            p_context->width > 0 && p_context->height > 0 )
595 596
        {
            /* Reparse it to not drop the I frame */
597
            b_null_size = false;
598
            if( p_sys->b_hurry_up )
599
                p_context->skip_frame = p_sys->i_skip_frame;
600 601
            i_used = avcodec_decode_video2( p_context, p_sys->p_ff_pic,
                                           &b_gotpicture, &pkt );
602
        }
Laurent Aimar's avatar
Laurent Aimar committed
603
        wait_mt( p_sys );
604

605 606 607
        if( p_sys->b_flush )
            p_sys->b_first_frame = true;

608
        if( p_block->i_buffer <= 0 )
609 610
            p_sys->b_flush = false;

611 612
        if( i_used < 0 )
        {
Laurent Aimar's avatar
Laurent Aimar committed
613
            if( b_drawpicture )
614 615
                msg_Warn( p_dec, "cannot decode one frame (%zu bytes)",
                          p_block->i_buffer );
616 617 618
            block_Release( p_block );
            return NULL;
        }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
619
        else if( (unsigned)i_used > p_block->i_buffer ||
Laurent Aimar's avatar
Laurent Aimar committed
620
                 p_context->thread_count > 1 )
621
        {
622
            i_used = p_block->i_buffer;
623 624 625
        }

        /* Consumed bytes */
626 627
        p_block->i_buffer -= i_used;
        p_block->p_buffer += i_used;
628 629 630 631 632 633 634 635

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

636
        /* Sanity check (seems to be needed for some streams) */
637
        if( p_sys->p_ff_pic->pict_type == AV_PICTURE_TYPE_B)
638 639 640 641
        {
            p_sys->b_has_b_frames = true;
        }

642
        /* Compute the PTS */
643 644 645 646 647
        mtime_t i_pts =
                    p_sys->p_ff_pic->pkt_pts;
        if (i_pts <= VLC_TS_INVALID)
            i_pts = p_sys->p_ff_pic->pkt_dts;

648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
        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);
            }
        }
677

678
        /* Update frame late count (except when doing preroll) */
679 680
        mtime_t i_display_date = 0;
        if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
681
            i_display_date = decoder_GetDisplayDate( p_dec, i_pts );
682

683
        if( i_display_date > 0 && i_display_date <= mdate() )
684 685 686 687 688 689 690 691 692 693
        {
            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;
        }

694
        if( !b_drawpicture || ( !p_sys->p_va && !p_sys->p_ff_pic->linesize[0] ) )
695 696
            continue;

697
        if( p_sys->p_va != NULL || p_sys->p_ff_pic->opaque == NULL )
698 699
        {
            /* Get a new picture */
700
            p_pic = ffmpeg_NewPictBuf( p_dec, p_context );
701 702 703 704 705 706 707 708 709 710 711 712 713
            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;
714
            decoder_LinkPicture( p_dec, p_pic );
715 716
        }

Laurent Aimar's avatar
Laurent Aimar committed
717
        if( !p_dec->fmt_in.video.i_sar_num || !p_dec->fmt_in.video.i_sar_den )
718 719
        {
            /* Fetch again the aspect ratio in case it changed */
720
            p_dec->fmt_out.video.i_sar_num
721
                = p_context->sample_aspect_ratio.num;
722
            p_dec->fmt_out.video.i_sar_den
723
                = p_context->sample_aspect_ratio.den;
724

Laurent Aimar's avatar
Laurent Aimar committed
725
            if( !p_dec->fmt_out.video.i_sar_num || !p_dec->fmt_out.video.i_sar_den )
726
            {
Laurent Aimar's avatar
Laurent Aimar committed
727 728
                p_dec->fmt_out.video.i_sar_num = 1;
                p_dec->fmt_out.video.i_sar_den = 1;
729 730 731
            }
        }

732
        /* Send decoded frame to vout */
733
        if( i_pts > VLC_TS_INVALID)
734
        {
735
            p_pic->date = i_pts;
736 737 738 739

            if( p_sys->b_first_frame )
            {
                /* Hack to force display of still pictures */
740 741
                p_sys->b_first_frame = false;
                p_pic->b_force = true;
742 743 744 745 746 747 748 749 750 751
            }

            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;

            return p_pic;
        }
        else
        {
752
            decoder_DeletePicture( p_dec, p_pic );
753 754 755 756 757 758 759 760 761 762
        }
    }

    block_Release( p_block );
    return NULL;
}

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

Laurent Aimar's avatar
Laurent Aimar committed
770 771
    post_mt( p_sys );

772 773 774
    /* 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 );
775

Laurent Aimar's avatar
Laurent Aimar committed
776 777
    wait_mt( p_sys );

778 779
    if( p_sys->p_ff_pic )
        av_free( p_sys->p_ff_pic );
780 781

    if( p_sys->p_va )
782
        vlc_va_Delete( p_sys->p_va );
783

Laurent Aimar's avatar
Laurent Aimar committed
784
    vlc_sem_destroy( &p_sys->sem_mt );
785 786
}

787 788 789 790 791 792 793 794 795 796
/*****************************************************************************
 * 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;

797
    if( p_sys->i_codec_id == AV_CODEC_ID_SVQ3 )
798 799 800 801 802 803
    {
        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
804 805
        if( !p )
            return;
806 807 808 809 810 811 812

        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 &&
813
            strncmp( (char*)&p[0x56], "SMI ", 4 ) )
814 815 816 817 818 819 820 821 822 823 824
        {
            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;
                }
825
                if( !strncmp( (char*)&psz[4], "SMI ", 4 ) )
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840
                {
                    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
841 842 843 844 845 846 847
        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 );
        }
848 849 850
    }
}

851 852 853 854 855 856 857 858 859
/*****************************************************************************
 * 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;

860 861
    if( p_sys->p_va )
    {
862
        vlc_va_Extract( p_sys->p_va, p_pic, p_ff_pic );
863
    }
864
    else if( FindVlcChroma( p_sys->p_context->pix_fmt ) )
865 866 867 868 869
    {
        int i_plane, i_size, i_line;
        uint8_t *p_dst, *p_src;
        int i_src_stride, i_dst_stride;

870
        for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
871
        {
872 873 874 875 876 877 878 879
            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++ )
880
            {
Rafaël Carré's avatar
Rafaël Carré committed
881
                memcpy( p_dst, p_src, i_size );
882 883
                p_src += i_src_stride;
                p_dst += i_dst_stride;
884 885 886 887 888
            }
        }
    }
    else
    {