video.c 39.6 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
#if LIBAVCODEC_VERSION_MAJOR < 54
79
    AVPaletteControl palette;
80 81 82
#else
# warning FIXME
#endif
83 84 85

    /* */
    bool b_flush;
86 87 88

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

    vlc_sem_t sem_mt;
91 92
};

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

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

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

129 130
    p_dec->fmt_out.video.i_width = p_context->width;
    p_dec->fmt_out.video.i_height = p_context->height;
131 132 133 134 135 136

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

137
    if( !p_sys->p_va && GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) )
138
    {
139 140 141 142
        /* 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;
143
    }
144
    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;
145 146

    /* If an aspect-ratio was specified in the input format then force it */
Laurent Aimar's avatar
Laurent Aimar committed
147
    if( p_dec->fmt_in.video.i_sar_num > 0 && p_dec->fmt_in.video.i_sar_den > 0 )
148
    {
Laurent Aimar's avatar
Laurent Aimar committed
149 150
        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;
151 152 153
    }
    else
    {
154 155
        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;
156

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

Laurent Aimar's avatar
Laurent Aimar committed
164 165
    if( p_dec->fmt_in.video.i_frame_rate > 0 &&
        p_dec->fmt_in.video.i_frame_rate_base > 0 )
166 167 168 169
    {
        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
170
            p_dec->fmt_in.video.i_frame_rate_base;
171
    }
172
    else if( p_context->time_base.num > 0 && p_context->time_base.den > 0 )
173 174 175 176
    {
        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;
    }
177

178
    return decoder_NewPicture( p_dec );
179 180 181 182 183 184 185 186
}

/*****************************************************************************
 * 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
187
int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
188
                      AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
189 190
{
    decoder_sys_t *p_sys;
191
    int i_val;
192 193

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

197 198
    p_codec->type = AVMEDIA_TYPE_VIDEO;
    p_context->codec_type = AVMEDIA_TYPE_VIDEO;
199
    p_context->codec_id = i_codec_id;
200 201 202 203
    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;
204
    p_sys->p_ff_pic = avcodec_alloc_frame();
205
    p_sys->b_delayed_open = true;
206
    p_sys->p_va = NULL;
Laurent Aimar's avatar
Laurent Aimar committed
207
    vlc_sem_init( &p_sys->sem_mt, 0 );
208 209

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

    /*  ***** Get configuration of ffmpeg plugin ***** */
    p_sys->p_context->workaround_bugs =
214
        var_InheritInteger( p_dec, "avcodec-workaround-bugs" );
215
#if LIBAVCODEC_VERSION_MAJOR < 54
aballier's avatar
aballier committed
216
    p_sys->p_context->error_recognition =
217
#else
218
    p_sys->p_context->err_recognition =
219
#endif
220
        var_InheritInteger( p_dec, "avcodec-error-resilience" );
221

222 223
    if( var_CreateGetBool( p_dec, "grayscale" ) )
        p_sys->p_context->flags |= CODEC_FLAG_GRAY;
224

225
    i_val = var_CreateGetInteger( p_dec, "avcodec-vismv" );
226
    if( i_val ) p_sys->p_context->debug_mv = i_val;
227

228
    i_val = var_CreateGetInteger( p_dec, "avcodec-skiploopfilter" );
229 230 231 232
    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;
233

234
    if( var_CreateGetBool( p_dec, "avcodec-fast" ) )
235
        p_sys->p_context->flags2 |= CODEC_FLAG2_FAST;
236

237 238 239 240 241
#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

242
    /* ***** libavcodec frame skipping ***** */
243
    p_sys->b_hurry_up = var_CreateGetBool( p_dec, "avcodec-hurry-up" );
244

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

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

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

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

    /* Always use our get_buffer wrapper so we can calculate the
     * PTS correctly */
    p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf;
321
    p_sys->p_context->reget_buffer = ffmpeg_ReGetFrameBuf;
322 323 324
    p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf;
    p_sys->p_context->opaque = p_dec;

Laurent Aimar's avatar
Laurent Aimar committed
325
#ifdef HAVE_AVCODEC_MT
326
    int i_thread_count = var_InheritInteger( p_dec, "avcodec-threads" );
Laurent Aimar's avatar
Laurent Aimar committed
327
    if( i_thread_count <= 0 )
328
    {
Laurent Aimar's avatar
Laurent Aimar committed
329
        i_thread_count = vlc_GetCPUCount();
330 331
        if( i_thread_count > 1 )
            i_thread_count++;
332 333 334

        //FIXME: take in count the decoding time
        i_thread_count = __MIN( i_thread_count, 4 );
335
    }
336
    i_thread_count = __MIN( i_thread_count, 16 );
337 338 339 340
    msg_Dbg( p_dec, "allowing %d thread(s) for decoding", i_thread_count );
    p_sys->p_context->thread_count = i_thread_count;
#endif

341 342
    char *hw = var_CreateGetString( p_dec, "avcodec-hw" ); /* FIXME */
    if( (hw == NULL || strcasecmp( hw, "none" )) &&
343 344 345 346
        (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
347
    {
348
#ifdef HAVE_AVCODEC_MT
349
        if( p_sys->p_context->thread_type & FF_THREAD_FRAME )
350
        {
351
            msg_Warn( p_dec, "threaded frame decoding is not compatible with libavcodec-hw, disabled" );
352 353
            p_sys->p_context->thread_type &= ~FF_THREAD_FRAME;
        }
354 355 356
        if( ( p_sys->p_context->thread_type & FF_THREAD_SLICE ) &&
            ( i_codec_id == CODEC_ID_MPEG1VIDEO || i_codec_id == CODEC_ID_MPEG2VIDEO ) )
        {
357
            msg_Warn( p_dec, "threaded slice decoding is not compatible with libavcodec-hw, disabled" );
358 359
            p_sys->p_context->thread_type &= ~FF_THREAD_SLICE;
        }
360
#endif
361 362
        p_sys->p_context->get_format = ffmpeg_GetFormat;
    }
363
    free( hw );
364 365 366 367 368
#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
369

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

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

386
#if LIBAVCODEC_VERSION_MAJOR < 54
387
    /* Setup palette */
388
    memset( &p_sys->palette, 0, sizeof(p_sys->palette) );
389
    if( p_dec->fmt_in.video.p_palette )
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
    {
        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;
    }
412
    else if( p_sys->i_codec_id != CODEC_ID_MSVIDEO1 && p_sys->i_codec_id != CODEC_ID_CINEPAK )
413 414 415
    {
        p_sys->p_context->palctrl = &p_sys->palette;
    }
416 417 418
#else
# warning FIXME
#endif
419

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

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

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

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

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

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

        p_sys->i_late_frames = 0;

473 474
        if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
            avcodec_flush_buffers( p_context );
Laurent Aimar's avatar
Laurent Aimar committed
475

476
        block_Release( p_block );
477 478 479 480 481 482 483 484 485 486 487
        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;
    }

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

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

    /*
551
     * Do the actual decoding now */
552

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

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

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

575 576 577 578 579 580 581
        /* 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;
582
        p_sys->p_ff_pic->reordered_opaque = p_context->reordered_opaque;
583 584 585 586 587

        /* 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
588
        post_mt( p_sys );
589

590 591 592 593 594
        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 );
595

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

608 609 610
        if( p_sys->b_flush )
            p_sys->b_first_frame = true;

611
        if( p_block->i_buffer <= 0 )
612 613
            p_sys->b_flush = false;

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

        /* Consumed bytes */
629 630
        p_block->i_buffer -= i_used;
        p_block->p_buffer += i_used;
631 632 633 634 635 636 637 638

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

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

645 646 647 648 649 650 651 652 653 654 655 656 657
        /* 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;
658 659 660 661 662 663 664 665 666

                /* 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;
                }
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701
            }
            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);
            }
        }
702

703
        /* Update frame late count (except when doing preroll) */
704 705
        mtime_t i_display_date = 0;
        if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
706
            i_display_date = decoder_GetDisplayDate( p_dec, i_pts );
707

708
        if( i_display_date > 0 && i_display_date <= mdate() )
709 710 711 712 713 714 715 716 717 718
        {
            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;
        }

719
        if( !b_drawpicture || ( !p_sys->p_va && !p_sys->p_ff_pic->linesize[0] ) )
720 721
            continue;

722
        if( p_sys->p_va != NULL || p_sys->p_ff_pic->opaque == NULL )
723 724
        {
            /* Get a new picture */
725
            p_pic = ffmpeg_NewPictBuf( p_dec, p_context );
726 727 728 729 730 731 732 733 734 735 736 737 738
            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;
739
            decoder_LinkPicture( p_dec, p_pic );
740 741
        }

Laurent Aimar's avatar
Laurent Aimar committed
742
        if( !p_dec->fmt_in.video.i_sar_num || !p_dec->fmt_in.video.i_sar_den )
743 744
        {
            /* Fetch again the aspect ratio in case it changed */
745
            p_dec->fmt_out.video.i_sar_num
746
                = p_context->sample_aspect_ratio.num;
747
            p_dec->fmt_out.video.i_sar_den
748
                = p_context->sample_aspect_ratio.den;
749

Laurent Aimar's avatar
Laurent Aimar committed
750
            if( !p_dec->fmt_out.video.i_sar_num || !p_dec->fmt_out.video.i_sar_den )
751
            {
Laurent Aimar's avatar
Laurent Aimar committed
752 753
                p_dec->fmt_out.video.i_sar_num = 1;
                p_dec->fmt_out.video.i_sar_den = 1;
754 755 756
            }
        }

757
        /* Send decoded frame to vout */
758
        if( i_pts > VLC_TS_INVALID)
759
        {
760
            p_pic->date = i_pts;
761 762 763 764

            if( p_sys->b_first_frame )
            {
                /* Hack to force display of still pictures */
765 766
                p_sys->b_first_frame = false;
                p_pic->b_force = true;
767 768 769 770 771 772
            }

            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;

773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
            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;
            }

791 792 793 794
            return p_pic;
        }
        else
        {
795
            decoder_DeletePicture( p_dec, p_pic );
796 797 798 799 800 801 802 803 804 805
        }
    }

    block_Release( p_block );
    return NULL;
}

/*****************************************************************************
 * EndVideo: decoder destruction
 *****************************************************************************
806
 * This function is called when the thread ends after a successful
807 808
 * initialization.
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
809
void EndVideoDec( decoder_t *p_dec )
810 811 812
{
    decoder_sys_t *p_sys = p_dec->p_sys;

Laurent Aimar's avatar
Laurent Aimar committed
813 814
    post_mt( p_sys );

815 816 817
    /* 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 );
818

Laurent Aimar's avatar
Laurent Aimar committed
819 820
    wait_mt( p_sys );

821
    if( p_sys->p_ff_pic ) av_free( p_sys->p_ff_pic );
822 823

    if( p_sys->p_va )
824
    {
825
        vlc_va_Delete( p_sys->p_va );
826 827
        p_sys->p_va = NULL;
    }
Laurent Aimar's avatar
Laurent Aimar committed
828
    vlc_sem_destroy( &p_sys->sem_mt );
829 830
}

831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847
/*****************************************************************************
 * 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
848 849
        if( !p )
            return;
850 851 852 853 854 855 856

        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 &&
857
            strncmp( (char*)&p[0x56], "SMI ", 4 ) )
858 859 860 861 862 863 864 865 866 867 868
        {
            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;
                }
869
                if( !strncmp( (char*)&psz[4], "SMI ", 4 ) )
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
                {
                    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
885 886 887 888 889 890 891
        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 );
        }
892 893 894
    }
}

895 896 897 898 899 900 901 902 903
/*****************************************************************************
 * 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,