video.c 39.5 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
111
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *,
                                          const enum PixelFormat * );

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

227
    i_val = var_CreateGetInteger( p_dec, "avcodec-lowres" );
228
    if( i_val > 0 && i_val <= 2 ) p_sys->p_context->lowres = i_val;
229

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        p_sys->i_late_frames = 0;

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

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

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

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

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

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

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

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

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

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

587
588
589
590
591
        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 );
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;
        }
Laurent Aimar's avatar
Laurent Aimar committed
619
620
        else if( i_used > p_block->i_buffer ||
                 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
643
644
645
646
647
648
649
650
651
652
653
654
        /* 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;
655
656
657
658
659
660
661
662
663

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

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

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

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

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

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

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

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

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

            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;

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

788
789
790
791
            return p_pic;
        }
        else
        {
792
            decoder_DeletePicture( p_dec, p_pic );
793
794
795
796
797
798
799
800
801
802
        }
    }

    block_Release( p_block );
    return NULL;
}

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

Laurent Aimar's avatar
Laurent Aimar committed
810
811
    post_mt( p_sys );

812
813
814
    /* 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 );
815

Laurent Aimar's avatar
Laurent Aimar committed
816
817
    wait_mt( p_sys );

818
    if( p_sys->p_ff_pic ) av_free( p_sys->p_ff_pic );
819
820

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

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

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

892
893
894
895
896
897
898
899
900
/*****************************************************************************
 * 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;

901
902
    if( p_sys->p_va )
    {
903
        vlc_va_Extract( p_sys->p_va, p_pic, p_ff_pic );
904
    }
905
    else if( FindVlcChroma( p_sys->p_context->pix_fmt ) )
906
907
908
909
910
    {
        int i_plane, i_size, i_line;
        uint8_t *p_dst, *p_src;
        int i_src_stride, i_dst_stride;

911
        for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
912
        {
913
914
915
916
917
918
919
920
            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++ )
921
            {
Rafaël Carré's avatar
Rafaël Carré committed
922
                memcpy( p_dst, p_src, i_size );
923
924
                p_src += i_src_stride;
                p_dst += i_dst_stride;
925
926
927
928
929
            }
        }
    }
    else
    {
930
931
932
        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" );
933
        p_dec->b_error = 1;
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
    }
}

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

950
    /* */
951
    p_ff_pic->reordered_opaque = p_context->reordered_opaque;
952
953
954
955
    p_ff_pic->opaque = NULL;

    if( p_sys->p_va )
    {
956
        /* hwaccel_context is not present in old ffmpeg version */
957
        if( vlc_va_Setup( p_sys->p_va,
958
959
                          &p_context->hwaccel_context, &p_dec->fmt_out.video.i_chroma,
                          p_context->width, p_context->height ) )
960
        {
961
            msg_Err( p_dec, "vlc_va_Setup failed" );
962
963
964
965
966
            return -1;
        }

        /* */
        p_ff_pic->type = FF_BUFFER_TYPE_USER;
967
968
969
970

#if LIBAVCODEC_VERSION_MAJOR < 54
        p_ff_pic->age = 256*256*256*64;
#endif
971

972
        if( vlc_va_Get( p_sys->p_va, p_ff_pic ) )
973
974
975
976
977
978
        {
            msg_Err( p_dec, "VaGrabSurface failed" );
            return -1;
        }
        return 0;
    }
979
    else if( !p_sys->b_direct_rendering )
980
    {
981
        /* Not much to do in indirect rendering mode. */
982
983
984
        return avcodec_default_get_buffer( p_context, p_ff_pic );
    }

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

989
990
991
    int i_width = p_context->width;
    int i_height = p_context->height;
    avcodec_align_dimensions( p_context, &i_width, &i_height );
992

993
    if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS ||
994
        p_context->pix_fmt == PIX_FMT_PAL8 )
995
        goto no_dr;
996

997
    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;
998
999

    /* Get a new picture */
1000
    p_pic = ffmpeg_NewPictBuf( p_dec, p_context );
For faster browsing, not all history is shown. View entire blame