video.c 43 KB
Newer Older
1
/*****************************************************************************
2
 * video.c: video decoder using the libavcodec library
3
 *****************************************************************************
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
4
 * Copyright (C) 1999-2001 VLC authors and VideoLAN
5
6
7
8
9
 * $Id$
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 *          Gildas Bazin <gbazin@videolan.org>
 *
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
10
11
12
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
13
14
15
16
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
17
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
19
 *
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
20
21
22
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23
24
25
26
27
 *****************************************************************************/

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

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

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

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

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

    /* Video decoder specific part */
    mtime_t i_pts;

    AVFrame          *p_ff_pic;

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

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

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

70
    bool b_has_b_frames;
71
72

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

75

76
    /* */
77
    bool palette_sent;
78
79
80

    /* */
    bool b_flush;
81
82
83

    /* VA API */
    vlc_va_t *p_va;
Laurent Aimar's avatar
Laurent Aimar committed
84
85

    vlc_sem_t sem_mt;
86
87
};

Laurent Aimar's avatar
Laurent Aimar committed
88
89
90
91
92
93
94
95
#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

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

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

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

/* Returns a new picture buffer */
static inline picture_t *ffmpeg_NewPictBuf( decoder_t *p_dec,
                                            AVCodecContext *p_context )
{
124
    decoder_sys_t *p_sys = p_dec->p_sys;
125
126
    int width = p_context->coded_width;
    int height = p_context->coded_height;
127

128
129
130
131
132
133
    if( p_sys->p_va == NULL )
    {
        int aligns[AV_NUM_DATA_POINTERS];

        avcodec_align_dimensions2(p_context, &width, &height, aligns);
    }
134
135


136
137
138
139
140
    if( width == 0 || height == 0 || width > 8192 || height > 8192 )
    {
        msg_Err( p_dec, "Invalid frame size %dx%d.", width, height );
        return NULL; /* invalid display size */
    }
141
142
143
144
    p_dec->fmt_out.video.i_width = width;
    p_dec->fmt_out.video.i_height = height;

    if( width != p_context->width || height != p_context->height )
145
146
147
148
    {
        p_dec->fmt_out.video.i_visible_width = p_context->width;
        p_dec->fmt_out.video.i_visible_height = p_context->height;
    }
149
150
151
152
153
    else
    {
        p_dec->fmt_out.video.i_visible_width = width;
        p_dec->fmt_out.video.i_visible_height = height;
    }
154

155
    if( !p_sys->p_va && GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) )
156
    {
157
158
159
160
        /* 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;
161
    }
162
    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;
163
164

    /* If an aspect-ratio was specified in the input format then force it */
Laurent Aimar's avatar
Laurent Aimar committed
165
    if( p_dec->fmt_in.video.i_sar_num > 0 && p_dec->fmt_in.video.i_sar_den > 0 )
166
    {
Laurent Aimar's avatar
Laurent Aimar committed
167
168
        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;
169
170
171
    }
    else
    {
172
173
        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;
174

Laurent Aimar's avatar
Laurent Aimar committed
175
        if( !p_dec->fmt_out.video.i_sar_num || !p_dec->fmt_out.video.i_sar_den )
176
        {
Laurent Aimar's avatar
Laurent Aimar committed
177
178
            p_dec->fmt_out.video.i_sar_num = 1;
            p_dec->fmt_out.video.i_sar_den = 1;
179
180
181
        }
    }

Laurent Aimar's avatar
Laurent Aimar committed
182
183
    if( p_dec->fmt_in.video.i_frame_rate > 0 &&
        p_dec->fmt_in.video.i_frame_rate_base > 0 )
184
185
186
187
    {
        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
188
            p_dec->fmt_in.video.i_frame_rate_base;
189
    }
190
    else if( p_context->time_base.num > 0 && p_context->time_base.den > 0 )
191
192
    {
        p_dec->fmt_out.video.i_frame_rate = p_context->time_base.den;
193
        p_dec->fmt_out.video.i_frame_rate_base = p_context->time_base.num * __MAX( p_context->ticks_per_frame, 1 );
194
    }
195

196
    return decoder_NewPicture( p_dec );
197
198
199
200
201
202
203
204
}

/*****************************************************************************
 * 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
205
int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
206
                      AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
207
208
{
    decoder_sys_t *p_sys;
209
    int i_val;
210
211

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

215
216
    p_codec->type = AVMEDIA_TYPE_VIDEO;
    p_context->codec_type = AVMEDIA_TYPE_VIDEO;
217
    p_context->codec_id = i_codec_id;
218
219
220
221
    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;
222
    p_sys->p_ff_pic = avcodec_alloc_frame();
223
    p_sys->b_delayed_open = true;
224
    p_sys->p_va = NULL;
Laurent Aimar's avatar
Laurent Aimar committed
225
    vlc_sem_init( &p_sys->sem_mt, 0 );
226
227

    /* ***** Fill p_context with init values ***** */
228
    p_sys->p_context->codec_tag = ffmpeg_CodecTag( p_dec->fmt_in.i_original_fourcc ?: p_dec->fmt_in.i_codec );
229
230
231

    /*  ***** Get configuration of ffmpeg plugin ***** */
    p_sys->p_context->workaround_bugs =
232
        var_InheritInteger( p_dec, "avcodec-workaround-bugs" );
233
    p_sys->p_context->err_recognition =
234
        var_InheritInteger( p_dec, "avcodec-error-resilience" );
235

236
237
    if( var_CreateGetBool( p_dec, "grayscale" ) )
        p_sys->p_context->flags |= CODEC_FLAG_GRAY;
238

Luca Barbato's avatar
Luca Barbato committed
239
240
241
242
243
    /* ***** Output always the frames ***** */
#if LIBAVCODEC_VERSION_CHECK(55, 23, 1, 40, 101)
    p_sys->p_context->flags |= CODEC_FLAG_OUTPUT_CORRUPT;
#endif

244
    i_val = var_CreateGetInteger( p_dec, "avcodec-vismv" );
245
    if( i_val ) p_sys->p_context->debug_mv = i_val;
246

247
    i_val = var_CreateGetInteger( p_dec, "avcodec-skiploopfilter" );
248
249
250
251
    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;
252

253
    if( var_CreateGetBool( p_dec, "avcodec-fast" ) )
254
        p_sys->p_context->flags2 |= CODEC_FLAG2_FAST;
255

256
    /* ***** libavcodec frame skipping ***** */
257
    p_sys->b_hurry_up = var_CreateGetBool( p_dec, "avcodec-hurry-up" );
258

259
260
261
262
263
264
265
    i_val = var_CreateGetInteger( p_dec, "avcodec-skip-frame" );
    if( i_val >= 4 ) p_sys->p_context->skip_frame = AVDISCARD_ALL;
    else if( i_val == 3 ) p_sys->p_context->skip_frame = AVDISCARD_NONKEY;
    else if( i_val == 2 ) p_sys->p_context->skip_frame = AVDISCARD_BIDIR;
    else if( i_val == 1 ) p_sys->p_context->skip_frame = AVDISCARD_NONREF;
    else if( i_val == -1 ) p_sys->p_context->skip_frame = AVDISCARD_NONE;
    else p_sys->p_context->skip_frame = AVDISCARD_DEFAULT;
266
    p_sys->i_skip_frame = p_sys->p_context->skip_frame;
267

268
269
270
271
272
273
274
    i_val = var_CreateGetInteger( p_dec, "avcodec-skip-idct" );
    if( i_val >= 4 ) p_sys->p_context->skip_idct = AVDISCARD_ALL;
    else if( i_val == 3 ) p_sys->p_context->skip_idct = AVDISCARD_NONKEY;
    else if( i_val == 2 ) p_sys->p_context->skip_idct = AVDISCARD_BIDIR;
    else if( i_val == 1 ) p_sys->p_context->skip_idct = AVDISCARD_NONREF;
    else if( i_val == -1 ) p_sys->p_context->skip_idct = AVDISCARD_NONE;
    else p_sys->p_context->skip_idct = AVDISCARD_DEFAULT;
275
    p_sys->i_skip_idct = p_sys->p_context->skip_idct;
276

277
    /* ***** libavcodec direct rendering ***** */
278
    p_sys->b_direct_rendering = false;
279
    p_sys->i_direct_rendering_used = -1;
280
    if( var_CreateGetBool( p_dec, "avcodec-dr" ) &&
281
       (p_sys->p_codec->capabilities & CODEC_CAP_DR1) &&
282
        /* No idea why ... but this fixes flickering on some TSCC streams */
283
284
        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 &&
285
286
287
288
        !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() */
289
        p_sys->b_direct_rendering = true;
290
291
    }

292
    /* libavcodec doesn't properly release old pictures when frames are skipped */
293
    //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = false;
294
295
    if( p_sys->b_direct_rendering )
    {
296
        msg_Dbg( p_dec, "trying to use direct rendering" );
297
298
        p_sys->p_context->flags |= CODEC_FLAG_EMU_EDGE;
    }
299
300
301
302
    else
    {
        msg_Dbg( p_dec, "direct rendering is disabled" );
    }
303

304
    p_sys->p_context->get_format = ffmpeg_GetFormat;
305
306
    /* Always use our get_buffer wrapper so we can calculate the
     * PTS correctly */
307
308
309
#if LIBAVCODEC_VERSION_MAJOR >= 55
    p_sys->p_context->get_buffer2 = lavc_GetFrame;
#else
310
    p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf;
311
    p_sys->p_context->reget_buffer = avcodec_default_reget_buffer;
312
    p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf;
313
#endif
314
315
    p_sys->p_context->opaque = p_dec;

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

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

332
    switch( i_codec_id )
Laurent Aimar's avatar
Laurent Aimar committed
333
    {
334
335
336
337
338
339
340
341
        case AV_CODEC_ID_MPEG4:
        case AV_CODEC_ID_H263:
            p_sys->p_context->thread_type = 0;
            break;
        case AV_CODEC_ID_MPEG1VIDEO:
        case AV_CODEC_ID_MPEG2VIDEO:
            p_sys->p_context->thread_type &= ~FF_THREAD_SLICE;
            /* fall through */
342
# if (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 1, 0))
343
344
345
        case AV_CODEC_ID_H264:
        case AV_CODEC_ID_VC1:
        case AV_CODEC_ID_WMV3:
346
            p_sys->p_context->thread_type &= ~FF_THREAD_FRAME;
347
# endif
348
    }
349

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
    /* Workaround: frame multithreading is not compatible with
     * DXVA2. When a frame is being copied to host memory, the frame
     * is locked and cannot be used as a reference frame
     * simultaneously and thus decoding fails for some frames. This
     * causes major image corruption. */
# if defined(_WIN32)
    char *avcodec_hw = var_InheritString( p_dec, "avcodec-hw" );
    if( avcodec_hw == NULL || strcasecmp( avcodec_hw, "none" ) )
    {
        msg_Warn( p_dec, "threaded frame decoding is not compatible with DXVA2, disabled" );
        p_sys->p_context->thread_type &= ~FF_THREAD_FRAME;
    }
    free( avcodec_hw );
# endif

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

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

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

385
386
    p_dec->fmt_out.video.orientation = p_dec->fmt_in.video.orientation;

387
388
389
390
391
392
393
    if( p_dec->fmt_in.video.p_palette ) {
        p_sys->palette_sent = false;
        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
        p_sys->palette_sent = true;
394

395
396
397
    /* ***** init this codec with special data ***** */
    ffmpeg_InitCodec( p_dec );

398
    /* ***** Open the codec ***** */
399
    if( ffmpeg_OpenCodec( p_dec ) < 0 )
400
401
    {
        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
402
        av_free( p_sys->p_ff_pic );
Laurent Aimar's avatar
Laurent Aimar committed
403
        vlc_sem_destroy( &p_sys->sem_mt );
404
405
406
407
408
409
410
411
412
413
        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
414
picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
415
416
{
    decoder_sys_t *p_sys = p_dec->p_sys;
417
    AVCodecContext *p_context = p_sys->p_context;
418
419
420
    int b_drawpicture;
    block_t *p_block;

421
    if( !pp_block )
422
        return NULL;
423

424
    if( !p_context->extradata_size && p_dec->fmt_in.i_extra )
425
    {
426
        ffmpeg_InitCodec( p_dec );
427
428
429
430
431
432
        if( p_sys->b_delayed_open )
        {
            if( ffmpeg_OpenCodec( p_dec ) )
                msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
        }
    }
433

434
    p_block = *pp_block;
435
436
437
    if(!p_block && !(p_sys->p_codec->capabilities & CODEC_CAP_DELAY) )
        return NULL;

438
439
    if( p_sys->b_delayed_open )
    {
440
441
        if( p_block )
            block_Release( p_block );
442
443
        return NULL;
    }
444

445
    if( p_block)
446
    {
447
448
449
        if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
        {
            p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover properly */
450

451
            p_sys->i_late_frames = 0;
452

453
454
455
456
            post_mt( p_sys );
            if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
                avcodec_flush_buffers( p_context );
            wait_mt( p_sys );
Laurent Aimar's avatar
Laurent Aimar committed
457

458
459
460
            block_Release( p_block );
            return NULL;
        }
461

462
463
464
465
466
467
468
        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;
        }
469
470
    }

471
    if( !p_dec->b_pace_control && (p_sys->i_late_frames > 0) &&
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
472
        (mdate() - p_sys->i_late_frames_start > INT64_C(5000000)) )
473
    {
474
        if( p_sys->i_pts > VLC_TS_INVALID )
475
        {
476
            p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover properly */
477
        }
478
479
        if( p_block )
            block_Release( p_block );
480
        p_sys->i_late_frames--;
481
482
        msg_Err( p_dec, "more than 5 seconds of late video -> "
                 "dropping frame (computer too slow ?)" );
483
484
485
486
487
        return NULL;
    }

    /* A good idea could be to decode all I pictures and see for the other */
    if( !p_dec->b_pace_control &&
488
489
        p_sys->b_hurry_up &&
        (p_sys->i_late_frames > 4) )
490
491
    {
        b_drawpicture = 0;
492
        if( p_sys->i_late_frames < 12 )
493
        {
494
            p_context->skip_frame =
495
496
                    (p_sys->i_skip_frame <= AVDISCARD_NONREF) ?
                    AVDISCARD_NONREF : p_sys->i_skip_frame;
497
498
499
500
501
502
        }
        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 */
503
504
            if( p_block )
                block_Release( p_block );
505
            msg_Warn( p_dec, "More than 4 late frames, dropping frame" );
506
507
508
509
510
            return NULL;
        }
    }
    else
    {
511
        if( p_sys->b_hurry_up )
512
            p_context->skip_frame = p_sys->i_skip_frame;
513
        if( !p_block || !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
514
515
516
517
518
            b_drawpicture = 1;
        else
            b_drawpicture = 0;
    }

519
    if( p_context->width <= 0 || p_context->height <= 0 )
520
    {
521
        if( p_sys->b_hurry_up )
522
            p_context->skip_frame = p_sys->i_skip_frame;
523
    }
Laurent Aimar's avatar
Laurent Aimar committed
524
525
    else if( !b_drawpicture )
    {
526
527
528
        /* It creates broken picture
         * FIXME either our parser or ffmpeg is broken */
#if 0
529
        if( p_sys->b_hurry_up )
530
            p_context->skip_frame = __MAX( p_context->skip_frame,
531
                                                  AVDISCARD_NONREF );
532
#endif
Laurent Aimar's avatar
Laurent Aimar committed
533
    }
534
535

    /*
536
     * Do the actual decoding now */
537

538
    /* Don't forget that libavcodec requires a little more bytes
539
     * that the real frame size */
540
    if( p_block && p_block->i_buffer > 0 )
541
    {
542
543
        p_sys->b_flush = ( p_block->i_flags & BLOCK_FLAG_END_OF_SEQUENCE ) != 0;

544
545
546
        p_block = block_Realloc( p_block, 0,
                            p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE );
        if( !p_block )
ivoire's avatar
ivoire committed
547
            return NULL;
548
        p_block->i_buffer -= FF_INPUT_BUFFER_PADDING_SIZE;
549
        *pp_block = p_block;
550
        memset( p_block->p_buffer + p_block->i_buffer, 0,
551
552
553
                FF_INPUT_BUFFER_PADDING_SIZE );
    }

554
    while( !p_block || p_block->i_buffer > 0 || p_sys->b_flush )
555
556
557
    {
        int i_used, b_gotpicture;
        picture_t *p_pic;
558
        AVPacket pkt;
559

Laurent Aimar's avatar
Laurent Aimar committed
560
        post_mt( p_sys );
561

562
        av_init_packet( &pkt );
563
564
565
566
567
568
569
570
571
572
573
574
575
        if( p_block )
        {
            pkt.data = p_block->p_buffer;
            pkt.size = p_block->i_buffer;
            pkt.pts = p_block->i_pts;
            pkt.dts = p_block->i_dts;
        }
        else
        {
            /* Return delayed frames if codec has CODEC_CAP_DELAY */
            pkt.data = NULL;
            pkt.size = 0;
        }
576

577
578
579
580
581
582
583
584
585
        if( !p_sys->palette_sent )
        {
            uint8_t *pal = av_packet_new_side_data(&pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
            if (pal) {
                memcpy(pal, p_dec->fmt_in.video.p_palette->palette, AVPALETTE_SIZE);
                p_sys->palette_sent = true;
            }
        }

586
        /* Make sure we don't reuse the same timestamps twice */
587
588
589
590
591
        if( p_block )
        {
            p_block->i_pts =
            p_block->i_dts = VLC_TS_INVALID;
        }
592

593
594
        i_used = avcodec_decode_video2( p_context, p_sys->p_ff_pic,
                                       &b_gotpicture, &pkt );
ssbssa's avatar
ssbssa committed
595
        av_free_packet( &pkt );
596

Laurent Aimar's avatar
Laurent Aimar committed
597
        wait_mt( p_sys );
598

599
600
601
        if( p_sys->b_flush )
            p_sys->b_first_frame = true;

602
        if( p_block )
603
        {
604
605
            if( p_block->i_buffer <= 0 )
                p_sys->b_flush = false;
606

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

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

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

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

639
        /* Compute the PTS */
640
641
642
643
644
        mtime_t i_pts =
                    p_sys->p_ff_pic->pkt_pts;
        if (i_pts <= VLC_TS_INVALID)
            i_pts = p_sys->p_ff_pic->pkt_dts;

645
646
647
648
649
650
651
652
653
654
655
656
        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 )
            {
657
                p_sys->i_pts += CLOCK_FREQ *
658
659
660
661
662
663
664
665
666
667
                    (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;

668
                p_sys->i_pts += CLOCK_FREQ *
669
670
671
672
673
                    (2 + p_sys->p_ff_pic->repeat_pict) *
                    i_tick * p_context->time_base.num /
                    (2 * p_context->time_base.den);
            }
        }
674

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

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

691
        if( !b_drawpicture || ( !p_sys->p_va && !p_sys->p_ff_pic->linesize[0] ) )
692
693
            continue;

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

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

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

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

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

            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
        {
750
            decoder_DeletePicture( p_dec, p_pic );
751
752
753
        }
    }

754
755
    if( p_block )
        block_Release( p_block );
756
757
758
759
760
761
    return NULL;
}

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

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

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

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

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

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

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

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

796
    if( p_sys->i_codec_id == AV_CODEC_ID_SVQ3 )
797
798
799
800
    {
        uint8_t *p;

        p_sys->p_context->extradata_size = i_size + 12;
801
802
803
        p = p_sys->p_context->extradata =
            av_malloc( p_sys->p_context->extradata_size +
                       FF_INPUT_BUFFER_PADDING_SIZE );
ivoire's avatar
ivoire committed
804
805
        if( !p )
            return;
806
807
808
809
810
811
812

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

        /* Now remove all atoms before the SMI one */
        if( p_sys->p_context->extradata_size > 0x5a &&
813
            strncmp( (char*)&p[0x56], "SMI ", 4 ) )
814
815
816
817
818
819
820
821
822
823
824
        {
            uint8_t *psz = &p[0x52];

            while( psz < &p[p_sys->p_context->extradata_size - 8] )
            {
                int i_size = GetDWBE( psz );
                if( i_size <= 1 )
                {
                    /* FIXME handle 1 as long size */
                    break;
                }
825
                if( !strncmp( (char*)&psz[4], "SMI ", 4 ) )
826
827
828
829
830
831
832
833
834
835
836
837
838
839
                {
                    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 =
840
            av_malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
ivoire's avatar
ivoire committed
841
842
843
844
        if( p_sys->p_context->extradata )
        {
            memcpy( p_sys->p_context->extradata,
                    p_dec->fmt_in.p_extra, i_size );
845
            memset( p_sys->p_context->extradata + i_size,
ivoire's avatar
ivoire committed
846
847
                    0, FF_INPUT_BUFFER_PADDING_SIZE );
        }
848
849
850
    }
}

851
852
853
854
855
856
857
858
859
/*****************************************************************************
 * ffmpeg_CopyPicture: copy a picture from ffmpeg internal buffers to a
 *                     picture_t structure (when not in direct rendering mode).
 *****************************************************************************/
static void ffmpeg_CopyPicture( decoder_t *p_dec,
                                picture_t *p_pic, AVFrame *p_ff_pic )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

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

871
872
873
874
        if( p_sys->p_context->pix_fmt == PIX_FMT_PAL8 )
        {
            if( !p_pic->format.p_palette )
                p_pic->format.p_palette = calloc( 1, sizeof(video_palette_t) );
875

876
877
            if( p_pic->format.p_palette )
            {
878
                p_pic->format.p_palette->i_entries = AVPALETTE_COUNT;
879
880
881
882
                memcpy( p_pic->format.p_palette->palette, p_ff_pic->data[1], AVPALETTE_SIZE );
            }
        }

883
        for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
884
        {
885
886
887
888
889
890
891
892
            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++ )
893
            {
Rafaël Carré's avatar
Rafaël Carré committed
894
                memcpy( p_dst, p_src, i_size );
895
896
                p_src += i_src_stride;
                p_dst += i_dst_stride;
897
898
899
900
901
            }
        }
    }
    else
    {
902
903
904
        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" );
905
        p_dec->b_error = 1;
906
907
908
    }
}

909
#if LIBAVCODEC_VERSION_MAJOR >= 55
910
911
static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame,
                            int flags)
912
913
914
915
916
917
918
919
920
921
922
{
    decoder_t *dec = ctx->opaque;
    decoder_sys_t *sys = dec->p_sys;
    vlc_va_t *va = sys->p_va;

    if (vlc_va_Setup(va, &ctx->hwaccel_context, &dec->fmt_out.video.i_chroma,
                     ctx->coded_width, ctx->coded_height))
    {
        msg_Err(dec, "hardware acceleration setup failed");
        return -1;
    }
923
    if (vlc_va_Get(va, &frame->opaque, &frame->data[0]))
924
925
926
927
    {
        msg_Err(dec, "hardware acceleration picture allocation failed");
        return -1;
    }
928
929
930
    /* data[0] must be non-NULL for libavcodec internal checks.
     * data[3] actually contains the format-specific surface handle. */
    frame->data[3] = frame->data[0];
931

932
933
    frame->buf[0] = av_buffer_create(frame->data[0], 0, va->release,
                                     frame->opaque, 0);
934
935
    if (unlikely(frame->buf[0] == NULL))
    {
936
        vlc_va_Release(va, frame->opaque, frame->data[0]);
937
938
        return -1;
    }
939
940
    assert(frame->data[0] != NULL);
    (void) flags;
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
    return 0;
}

typedef struct
{
    decoder_t *decoder;
    picture_t *picture;
} lavc_pic_ref_t;

static void lavc_dr_ReleaseFrame(void *opaque, uint8_t *data)
{
    lavc_pic_ref_t *ref = opaque;

    decoder_UnlinkPicture(ref->decoder, ref->picture);
    free(ref);
    (void) data;
}

static picture_t *lavc_dr_GetFrame(struct AVCodecContext *ctx,
960
                                   AVFrame *frame, int flags)
961
962
{
    decoder_t *dec = (decoder_t *)ctx->opaque;
963
    decoder_sys_t *sys = dec->p_sys;
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981

    if (GetVlcChroma(&dec->fmt_out.video, ctx->pix_fmt) != VLC_SUCCESS)
        return NULL;
    dec->fmt_out.i_codec = dec->fmt_out.video.i_chroma;
    if (ctx->pix_fmt == PIX_FMT_PAL8)
        return NULL;

    int width = frame->width;
    int height = frame->height;
    int aligns[AV_NUM_DATA_POINTERS];

    avcodec_align_dimensions2(ctx, &width, &height, aligns);

    picture_t *pic = ffmpeg_NewPictBuf(dec, ctx);
    if (pic == NULL)
        return NULL;

    /* Check that the picture is suitable for libavcodec */
982
983
    if (pic->p[0].i_pitch < width * pic->p[0].i_pixel_pitch)
    {
984
985
986
        if (sys->i_direct_rendering_used != 0)
            msg_Dbg(dec, "plane 0: pitch too small (%d/%d*%d)",
                    pic->p[0].i_pitch, width, pic->p[0].i_pixel_pitch);
987
988
989
990
991
        goto no_dr;
    }

    if (pic->p[0].i_lines < height)
    {
992
993
994
        if (sys->i_direct_rendering_used != 0)
            msg_Dbg(dec, "plane 0: lines too few (%d/%d)",
                    pic->p[0].i_lines, height);
995
        goto no_dr;
996
    }
997
998
999

    for (int i = 0; i < pic->i_planes; i++)
    {
1000
        if (pic->p[i].i_pitch % aligns[i])
1001
        {
1002
1003
1004
            if (sys->i_direct_rendering_used != 0)
                msg_Dbg(dec, "plane %d: pitch not aligned (%d%%%d)",
                        i, pic->p[i].i_pitch, aligns[i]);
1005
            goto no_dr;
1006
        }
1007
        if (((uintptr_t)pic->p[i].p_pixels) % aligns[i])
1008
        {
1009
1010
            if (sys->i_direct_rendering_used != 0)
                msg_Warn(dec, "plane %d not aligned", i);
1011
            goto no_dr;
1012
        }
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055