video.c 38.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 <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
80
81
82
#if LIBAVCODEC_VERSION_MAJOR < 54
    AVPaletteControl palette;
#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
    p_sys->p_context->err_recognition =
216
        var_InheritInteger( p_dec, "avcodec-error-resilience" );
217

218
219
    if( var_CreateGetBool( p_dec, "grayscale" ) )
        p_sys->p_context->flags |= CODEC_FLAG_GRAY;
220

221
    i_val = var_CreateGetInteger( p_dec, "avcodec-vismv" );
222
    if( i_val ) p_sys->p_context->debug_mv = i_val;
223

224
    i_val = var_CreateGetInteger( p_dec, "avcodec-skiploopfilter" );
225
226
227
228
    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;
229

230
    if( var_CreateGetBool( p_dec, "avcodec-fast" ) )
231
        p_sys->p_context->flags2 |= CODEC_FLAG2_FAST;
232

233
#if LIBAVCODEC_VERSION_CHECK( 54, 41, 0, 91, 100 )
234
235
236
237
    if( var_InheritBool( p_dec, "avcodec-ignorecrop" ) )
        p_sys->p_context->flags2 |= CODEC_FLAG2_IGNORE_CROP;
#endif

238
    /* ***** libavcodec frame skipping ***** */
239
    p_sys->b_hurry_up = var_CreateGetBool( p_dec, "avcodec-hurry-up" );
240

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

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

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

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

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

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

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

337
338
    char *hw = var_CreateGetString( p_dec, "avcodec-hw" ); /* FIXME */
    if( (hw == NULL || strcasecmp( hw, "none" )) &&
339
340
341
342
        (i_codec_id == AV_CODEC_ID_MPEG1VIDEO || i_codec_id == AV_CODEC_ID_MPEG2VIDEO ||
         i_codec_id == AV_CODEC_ID_MPEG4 ||
         i_codec_id == AV_CODEC_ID_H264 ||
         i_codec_id == AV_CODEC_ID_VC1 || i_codec_id == AV_CODEC_ID_WMV3) )
Laurent Aimar's avatar
Laurent Aimar committed
343
    {
344
#ifdef HAVE_AVCODEC_MT
345
        if( p_sys->p_context->thread_type & FF_THREAD_FRAME )
346
        {
347
            msg_Warn( p_dec, "threaded frame decoding is not compatible with libavcodec-hw, disabled" );
348
349
            p_sys->p_context->thread_type &= ~FF_THREAD_FRAME;
        }
350
        if( ( p_sys->p_context->thread_type & FF_THREAD_SLICE ) &&
351
            ( i_codec_id == AV_CODEC_ID_MPEG1VIDEO || i_codec_id == AV_CODEC_ID_MPEG2VIDEO ) )
352
        {
353
            msg_Warn( p_dec, "threaded slice decoding is not compatible with libavcodec-hw, disabled" );
354
355
            p_sys->p_context->thread_type &= ~FF_THREAD_SLICE;
        }
356
#endif
357
358
        p_sys->p_context->get_format = ffmpeg_GetFormat;
    }
359
    free( hw );
360
361
362
363
364
#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
365

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

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

382
#if LIBAVCODEC_VERSION_MAJOR < 54
383
    /* Setup palette */
384
385
386
387
388
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
    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
415

416
417
418
    /* ***** init this codec with special data ***** */
    ffmpeg_InitCodec( p_dec );

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

443
444
    if( !pp_block || !*pp_block )
        return NULL;
445

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

456
    p_block = *pp_block;
457
458
459
460
461
    if( p_sys->b_delayed_open )
    {
        block_Release( p_block );
        return NULL;
    }
462
463
464

    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
    {
465
        p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover properly */
466
467
468

        p_sys->i_late_frames = 0;

469
470
        if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
            avcodec_flush_buffers( p_context );
Laurent Aimar's avatar
Laurent Aimar committed
471

472
        block_Release( p_block );
473
474
475
476
477
478
479
480
481
482
483
        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;
    }

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

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

    /*
547
     * Do the actual decoding now */
548

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

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

565
    while( p_block->i_buffer > 0 || p_sys->b_flush )
566
567
568
    {
        int i_used, b_gotpicture;
        picture_t *p_pic;
569
        AVPacket pkt;
570

571
572
573
574
575
576
577
        /* 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;
578
        p_sys->p_ff_pic->reordered_opaque = p_context->reordered_opaque;
579
580
581
582
583

        /* 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
584
        post_mt( p_sys );
585

586
587
588
589
590
        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 );
591

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

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

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

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

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

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

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

641
642
643
644
645
646
647
648
649
650
651
652
653
        /* 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;
654
655
656
657
658
659
660
661
662

                /* 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;
                }
663
664
665
666
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
            }
            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);
            }
        }
698

699
        /* Update frame late count (except when doing preroll) */
700
701
        mtime_t i_display_date = 0;
        if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
702
            i_display_date = decoder_GetDisplayDate( p_dec, i_pts );
703

704
        if( i_display_date > 0 && i_display_date <= mdate() )
705
706
707
708
709
710
711
712
713
714
        {
            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;
        }

715
        if( !b_drawpicture || ( !p_sys->p_va && !p_sys->p_ff_pic->linesize[0] ) )
716
717
            continue;

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

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

Laurent Aimar's avatar
Laurent Aimar committed
746
            if( !p_dec->fmt_out.video.i_sar_num || !p_dec->fmt_out.video.i_sar_den )
747
            {
Laurent Aimar's avatar
Laurent Aimar committed
748
749
                p_dec->fmt_out.video.i_sar_num = 1;
                p_dec->fmt_out.video.i_sar_den = 1;
750
751
752
            }
        }

753
        /* Send decoded frame to vout */
754
        if( i_pts > VLC_TS_INVALID)
755
        {
756
            p_pic->date = i_pts;
757
758
759
760

            if( p_sys->b_first_frame )
            {
                /* Hack to force display of still pictures */
761
762
                p_sys->b_first_frame = false;
                p_pic->b_force = true;
763
764
765
766
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;

            return p_pic;
        }
        else
        {
773
            decoder_DeletePicture( p_dec, p_pic );
774
775
776
777
778
779
780
781
782
783
        }
    }

    block_Release( p_block );
    return NULL;
}

/*****************************************************************************
 * EndVideo: decoder destruction
 *****************************************************************************
784
 * This function is called when the thread ends after a successful
785
786
 * initialization.
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
787
void EndVideoDec( decoder_t *p_dec )
788
789
790
{
    decoder_sys_t *p_sys = p_dec->p_sys;

Laurent Aimar's avatar
Laurent Aimar committed
791
792
    post_mt( p_sys );

793
794
795
    /* 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 );
796

Laurent Aimar's avatar
Laurent Aimar committed
797
798
    wait_mt( p_sys );

799
    if( p_sys->p_ff_pic ) av_free( p_sys->p_ff_pic );
800
801

    if( p_sys->p_va )
802
    {
803
        vlc_va_Delete( p_sys->p_va );
804
805
        p_sys->p_va = NULL;
    }
Laurent Aimar's avatar
Laurent Aimar committed
806
    vlc_sem_destroy( &p_sys->sem_mt );
807
808
}

809
810
811
812
813
814
815
816
817
818
/*****************************************************************************
 * 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;

819
    if( p_sys->i_codec_id == AV_CODEC_ID_SVQ3 )
820
821
822
823
824
825
    {
        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
826
827
        if( !p )
            return;
828
829
830
831
832
833
834

        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 &&
835
            strncmp( (char*)&p[0x56], "SMI ", 4 ) )
836
837
838
839
840
841
842
843
844
845
846
        {
            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;
                }
847
                if( !strncmp( (char*)&psz[4], "SMI ", 4 ) )
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
                {
                    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
863
864
865
866
867
868
869
        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 );
        }
870
871
872
    }
}

873
874
875
876
877
878
879
880
881
/*****************************************************************************
 * 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;

882
883
    if( p_sys->p_va )
    {
884
        vlc_va_Extract( p_sys->p_va, p_pic, p_ff_pic );
885
    }
886
    else if( FindVlcChroma( p_sys->p_context->pix_fmt ) )
887
888
889
890
891
    {
        int i_plane, i_size, i_line;
        uint8_t *p_dst, *p_src;
        int i_src_stride, i_dst_stride;

892
        for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
893
        {
894
895
896
897
898
899
900
901
            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++ )
902
            {
Rafaël Carré's avatar
Rafaël Carré committed
903
                memcpy( p_dst, p_src, i_size );
904
905
                p_src += i_src_stride;
                p_dst += i_dst_stride;
906
907
908
909
910
            }
        }
    }
    else
    {
911
912
913
        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" );
914
        p_dec->b_error = 1;
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
    }
}

/*****************************************************************************
 * ffmpeg_GetFrameBuf: callback used by ffmpeg to get a frame buffer.
 *****************************************************************************
 * It is used for direct rendering as well as to get the right PTS for each
 * decoded picture (even in indirect rendering mode).
 *****************************************************************************/
static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
                               AVFrame *p_ff_pic )
{
    decoder_t *p_dec = (decoder_t *)p_context->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;
    picture_t *p_pic;

931
    /* */
932
    p_ff_pic->reordered_opaque = p_context->reordered_opaque;
933
934
935
936
    p_ff_pic->opaque = NULL;

    if( p_sys->p_va )
    {
937
        /* hwaccel_context is not present in old ffmpeg version */
938
        if( vlc_va_Setup( p_sys->p_va,
939
940
                          &p_context->hwaccel_context, &p_dec->fmt_out.video.i_chroma,
                          p_context->width, p_context->height ) )
941
        {
942
            msg_Err( p_dec, "vlc_va_Setup failed" );
943
944
945
946
947
            return -1;
        }

        /* */
        p_ff_pic->type = FF_BUFFER_TYPE_USER;
948

949
950
951
952
#if LIBAVCODEC_VERSION_MAJOR < 54
        p_ff_pic->age = 256*256*256*64;
#endif

953
        if( vlc_va_Get( p_sys->p_va, p_ff_pic ) )
954
955
956
957
958
959
        {
            msg_Err( p_dec, "VaGrabSurface failed" );
            return -1;
        }
        return 0;
    }
960
    else if( !p_sys->b_direct_rendering )
961
    {
962
        /* Not much to do in indirect rendering mode. */
963
964
965
        return avcodec_default_get_buffer( p_context, p_ff_pic );
    }

Laurent Aimar's avatar
Laurent Aimar committed
966
    wait_mt( p_sys );
967
    /* Some codecs set pix_fmt only after the 1st frame has been decoded,
968
969
     * so we need to check for direct rendering again. */

970
971
972
    int i_width = p_context->width;
    int i_height = p_context->height;
    avcodec_align_dimensions( p_context, &i_width, &i_height );
973

974
    if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS ||
975
        p_context->pix_fmt == PIX_FMT_PAL8 )
976
        goto no_dr;
977

978
    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;
979
980

    /* Get a new picture */
981
    p_pic = ffmpeg_NewPictBuf( p_dec, p_context );
982
    if( !p_pic )
983
        goto no_dr;
984
985
986
987
988
989
    bool b_compatible = true;
    if( p_pic->p[0].i_pitch / p_pic->p[0].i_pixel_pitch < i_width ||
        p_pic->p[0].i_lines < i_height )
        b_compatible = false;
    for( int i = 0; i < p_pic->i_planes && b_compatible; i++ )
    {
990
991
992
        unsigned i_align;
        switch( p_sys->i_codec_id )
        {
993
994
995
996
997
        case AV_CODEC_ID_SVQ1:
        case AV_CODEC_ID_VP5:
        case AV_CODEC_ID_VP6:
        case AV_CODEC_ID_VP6F:
        case AV_CODEC_ID_VP6A:
998
999
1000
            i_align = 16;
            break;
        default:
For faster browsing, not all history is shown. View entire blame