demux.c 39.2 KB
Newer Older
Gildas Bazin's avatar
 
Gildas Bazin committed
1
/*****************************************************************************
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
2
 * demux.c: demuxer using libavformat
Gildas Bazin's avatar
 
Gildas Bazin committed
3
 *****************************************************************************
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
4
 * Copyright (C) 2004-2009 VLC authors and VideoLAN
5
 * $Id$
Gildas Bazin's avatar
 
Gildas Bazin committed
6 7
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8
 *          Gildas Bazin <gbazin@videolan.org>
Gildas Bazin's avatar
 
Gildas Bazin committed
9
 *
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
Gildas Bazin's avatar
 
Gildas Bazin committed
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.
Gildas Bazin's avatar
 
Gildas Bazin committed
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.
Gildas Bazin's avatar
 
Gildas Bazin committed
23 24 25 26 27 28
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/

29 30 31 32
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

33
#include <vlc_common.h>
Clément Stenac's avatar
Clément Stenac committed
34 35
#include <vlc_demux.h>
#include <vlc_stream.h>
36
#include <vlc_meta.h>
37
#include <vlc_input.h>
38
#include <vlc_charset.h>
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
39
#include <vlc_avcodec.h>
Gildas Bazin's avatar
 
Gildas Bazin committed
40

41
#include "../../codec/avcodec/avcodec.h"
42
#include "../../codec/avcodec/chroma.h"
43
#include "../../codec/avcodec/avcommon_compat.h"
44
#include "avformat.h"
45
#include "../xiph.h"
46
#include "../vobsub.h"
47

48
#include <libavformat/avformat.h>
49

50 51 52 53 54 55 56 57
#if ( (LIBAVUTIL_VERSION_MICRO <  100 && LIBAVUTIL_VERSION_INT >= AV_VERSION_INT( 53, 15, 0) ) || \
      (LIBAVUTIL_VERSION_MICRO >= 100 && LIBAVUTIL_VERSION_INT >= AV_VERSION_INT( 52, 85, 100 ) )  )
# if LIBAVFORMAT_VERSION_CHECK( 55, 18, 0, 40, 100)
#  include <libavutil/display.h>
#  define HAVE_AV_STREAM_GET_SIDE_DATA
# endif
#endif

58 59
//#define AVFORMAT_DEBUG 1

60
# define HAVE_AVUTIL_CODEC_ATTACHMENT 1
61

Gildas Bazin's avatar
 
Gildas Bazin committed
62 63 64 65 66 67 68 69 70 71
/*****************************************************************************
 * demux_sys_t: demux descriptor
 *****************************************************************************/
struct demux_sys_t
{
    AVInputFormat  *fmt;
    AVFormatContext *ic;

    int             i_tk;
    es_out_id_t     **tk;
72 73
    int64_t         *tk_pcr;
    int64_t         i_pcr;
74

75 76
    unsigned    i_ssa_order;

77 78
    int                i_attachments;
    input_attachment_t **attachments;
79 80 81

    /* Only one title with seekpoints possible atm. */
    input_title_t *p_title;
Gildas Bazin's avatar
 
Gildas Bazin committed
82 83
};

84 85
#define AVFORMAT_IOBUFFER_SIZE 32768  /* FIXME */

Gildas Bazin's avatar
 
Gildas Bazin committed
86 87 88 89 90 91 92
/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
static int Demux  ( demux_t *p_demux );
static int Control( demux_t *p_demux, int i_query, va_list args );

static int IORead( void *opaque, uint8_t *buf, int buf_size );
93
static int64_t IOSeek( void *opaque, int64_t offset, int whence );
Gildas Bazin's avatar
 
Gildas Bazin committed
94

95
static block_t *BuildSsaFrame( const AVPacket *p_pkt, unsigned i_order );
96
static void UpdateSeekPoint( demux_t *p_demux, int64_t i_time );
97
static void ResetTime( demux_t *p_demux, int64_t i_time );
98

99 100 101 102 103 104 105 106 107 108
static vlc_fourcc_t CodecTagToFourcc( uint32_t codec_tag )
{
    // convert from little-endian avcodec codec_tag to VLC native-endian fourcc
#ifdef WORDS_BIGENDIAN
    return bswap32(codec_tag);
#else
    return codec_tag;
#endif
}

Gildas Bazin's avatar
 
Gildas Bazin committed
109 110 111
/*****************************************************************************
 * Open
 *****************************************************************************/
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154

static void get_rotation(es_format_t *fmt, AVStream *s)
{
    char const *kRotateKey = "rotate";
    AVDictionaryEntry *rotation = av_dict_get(s->metadata, kRotateKey, NULL, 0);
    long angle = 0;

    if( rotation )
    {
        angle = strtol(rotation->value, NULL, 10);

        if (angle > 45 && angle < 135)
            fmt->video.orientation = ORIENT_ROTATED_90;

        else if (angle > 135 && angle < 225)
            fmt->video.orientation = ORIENT_ROTATED_180;

        else if (angle > 225 && angle < 315)
            fmt->video.orientation = ORIENT_ROTATED_270;

        else
            fmt->video.orientation = ORIENT_NORMAL;
    }
#ifdef HAVE_AV_STREAM_GET_SIDE_DATA
    int32_t *matrix = (int32_t *)av_stream_get_side_data(s, AV_PKT_DATA_DISPLAYMATRIX, NULL);
    if( matrix ) {
        angle = lround(av_display_rotation_get(matrix));

        if (angle > 45 && angle < 135)
            fmt->video.orientation = ORIENT_ROTATED_270;

        else if (angle > 135 || angle < -135)
            fmt->video.orientation = ORIENT_ROTATED_180;

        else if (angle < -45 && angle > -135)
            fmt->video.orientation = ORIENT_ROTATED_90;

        else
            fmt->video.orientation = ORIENT_NORMAL;
    }
#endif
}

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
155
int OpenDemux( vlc_object_t *p_this )
Gildas Bazin's avatar
 
Gildas Bazin committed
156 157 158
{
    demux_t       *p_demux = (demux_t*)p_this;
    demux_sys_t   *p_sys;
159
    AVProbeData   pd = { };
160
    AVInputFormat *fmt = NULL;
161
    int64_t       i_start_time = -1;
162
    bool          b_can_seek;
163
    char         *psz_url;
164
    const uint8_t *peek;
165
    int           error;
Gildas Bazin's avatar
 
Gildas Bazin committed
166

167
    /* Init Probe data */
168
    pd.buf_size = vlc_stream_Peek( p_demux->s, &peek, 2048 + 213 );
169 170 171 172 173 174 175 176 177 178 179 180 181
    if( pd.buf_size <= 0 )
    {
        msg_Warn( p_demux, "cannot peek" );
        return VLC_EGENERIC;
    }

    pd.buf = malloc( pd.buf_size + AVPROBE_PADDING_SIZE );
    if( unlikely(pd.buf == NULL) )
        return VLC_ENOMEM;

    memcpy( pd.buf, peek, pd.buf_size );
    memset( pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE );

182 183 184 185
    if( p_demux->psz_file )
        psz_url = strdup( p_demux->psz_file );
    else
    {
186 187 188
        if( asprintf( &psz_url, "%s://%s", p_demux->psz_access,
                      p_demux->psz_location ) == -1)
            psz_url = NULL;
189
    }
190 191 192 193

    if( psz_url != NULL )
        msg_Dbg( p_demux, "trying url: %s", psz_url );

194
    pd.filename = psz_url;
195

196
    vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_can_seek );
Gildas Bazin's avatar
 
Gildas Bazin committed
197

198
    vlc_init_avformat(p_this);
Gildas Bazin's avatar
 
Gildas Bazin committed
199

200
    /* Guess format */
201
    char *psz_format = var_InheritString( p_this, "avformat-format" );
202 203
    if( psz_format )
    {
204
        if( (fmt = av_find_input_format(psz_format)) )
205 206 207 208
            msg_Dbg( p_demux, "forcing format: %s", fmt->name );
        free( psz_format );
    }

209 210 211 212 213 214
    if( fmt == NULL )
        fmt = av_probe_input_format( &pd, 1 );

    free( pd.buf );

    if( fmt == NULL )
Gildas Bazin's avatar
 
Gildas Bazin committed
215 216
    {
        msg_Dbg( p_demux, "couldn't guess format" );
217
        free( psz_url );
Gildas Bazin's avatar
 
Gildas Bazin committed
218 219 220
        return VLC_EGENERIC;
    }

221
    if( !p_demux->obj.force )
Gildas Bazin's avatar
 
Gildas Bazin committed
222
    {
223 224 225 226 227
        static const char ppsz_blacklist[][16] = {
            /* Don't handle MPEG unless forced */
            "mpeg", "vcd", "vob", "mpegts",
            /* libavformat's redirector won't work */
            "redir", "sdp",
228 229
            /* Don't handle subtitles format */
            "ass", "srt", "microdvd",
230
            /* No timestamps at all */
231
            "hevc", "h264",
232 233 234 235 236 237 238 239 240 241 242
            ""
        };

        for( int i = 0; *ppsz_blacklist[i]; i++ )
        {
            if( !strcmp( fmt->name, ppsz_blacklist[i] ) )
            {
                free( psz_url );
                return VLC_EGENERIC;
            }
        }
Gildas Bazin's avatar
 
Gildas Bazin committed
243 244
    }

245
    /* Don't trigger false alarms on bin files */
246
    if( !p_demux->obj.force && !strcmp( fmt->name, "psxstr" ) )
247 248 249
    {
        int i_len;

250 251 252 253 254
        if( !p_demux->psz_file )
        {
            free( psz_url );
            return VLC_EGENERIC;
        }
255

256
        i_len = strlen( p_demux->psz_file );
257 258 259 260 261
        if( i_len < 4 )
        {
            free( psz_url );
            return VLC_EGENERIC;
        }
262

263 264 265
        if( strcasecmp( &p_demux->psz_file[i_len - 4], ".str" ) &&
            strcasecmp( &p_demux->psz_file[i_len - 4], ".xai" ) &&
            strcasecmp( &p_demux->psz_file[i_len - 3], ".xa" ) )
266
        {
267
            free( psz_url );
268 269 270 271
            return VLC_EGENERIC;
        }
    }

272 273
    msg_Dbg( p_demux, "detected format: %s", fmt->name );

Gildas Bazin's avatar
 
Gildas Bazin committed
274 275 276
    /* Fill p_demux fields */
    p_demux->pf_demux = Demux;
    p_demux->pf_control = Control;
277
    p_demux->p_sys = p_sys = xmalloc( sizeof( demux_sys_t ) );
278
    p_sys->ic = 0;
Gildas Bazin's avatar
 
Gildas Bazin committed
279 280 281
    p_sys->fmt = fmt;
    p_sys->i_tk = 0;
    p_sys->tk = NULL;
282
    p_sys->tk_pcr = NULL;
283
    p_sys->i_ssa_order = 0;
284
    TAB_INIT( p_sys->i_attachments, p_sys->attachments);
285
    p_sys->p_title = NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
286 287

    /* Create I/O wrapper */
288
    unsigned char * p_io_buffer = av_malloc( AVFORMAT_IOBUFFER_SIZE );
289 290 291 292 293 294
    if( !p_io_buffer )
    {
        free( psz_url );
        CloseDemux( p_this );
        return VLC_ENOMEM;
    }
295

296
    p_sys->ic = avformat_alloc_context();
297 298
    if( !p_sys->ic )
    {
299
        av_free( p_io_buffer );
300 301 302 303 304 305 306 307 308
        free( psz_url );
        CloseDemux( p_this );
        return VLC_ENOMEM;
    }

    AVIOContext *pb = p_sys->ic->pb = avio_alloc_context( p_io_buffer,
        AVFORMAT_IOBUFFER_SIZE, 0, p_demux, IORead, NULL, IOSeek );
    if( !pb )
    {
309
        av_free( p_io_buffer );
310 311 312 313 314
        free( psz_url );
        CloseDemux( p_this );
        return VLC_ENOMEM;
    }

315
    p_sys->ic->pb->seekable = b_can_seek ? AVIO_SEEKABLE_NORMAL : 0;
316
    error = avformat_open_input(&p_sys->ic, psz_url, p_sys->fmt, NULL);
317

318
    if( error < 0 )
Gildas Bazin's avatar
 
Gildas Bazin committed
319
    {
320 321
        msg_Err( p_demux, "Could not open %s: %s", psz_url,
                 vlc_strerror_c(AVUNERROR(error)) );
Hannes Domani's avatar
Hannes Domani committed
322
        av_free( p_io_buffer );
Hannes Domani's avatar
Hannes Domani committed
323
        av_free( pb );
324
        p_sys->ic = NULL;
325
        free( psz_url );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
326
        CloseDemux( p_this );
Gildas Bazin's avatar
 
Gildas Bazin committed
327 328
        return VLC_EGENERIC;
    }
329
    free( psz_url );
Gildas Bazin's avatar
 
Gildas Bazin committed
330

331
#if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(26<<8)+0)
332
    char *psz_opts = var_InheritString( p_demux, "avformat-options" );
333 334
    AVDictionary *options[p_sys->ic->nb_streams ? p_sys->ic->nb_streams : 1];
    options[0] = NULL;
335 336
    unsigned int nb_streams = p_sys->ic->nb_streams;
    for (unsigned i = 1; i < nb_streams; i++)
337
        options[i] = NULL;
338
    if (psz_opts) {
339
        vlc_av_get_options(psz_opts, &options[0]);
340
        for (unsigned i = 1; i < nb_streams; i++) {
341 342
            av_dict_copy(&options[i], options[0], 0);
        }
343
        free(psz_opts);
344 345 346
    }
    vlc_avcodec_lock(); /* avformat calls avcodec behind our back!!! */
    error = avformat_find_stream_info( p_sys->ic, options );
347
    /* FIXME: what if nb_streams change after that call? */
348 349
    vlc_avcodec_unlock();
    AVDictionaryEntry *t = NULL;
Rafaël Carré's avatar
Rafaël Carré committed
350
    while ((t = av_dict_get(options[0], "", t, AV_DICT_IGNORE_SUFFIX))) {
351 352
        msg_Err( p_demux, "Unknown option \"%s\"", t->key );
    }
353
    av_dict_free(&options[0]);
354
    for (unsigned i = 1; i < nb_streams; i++) {
Rafaël Carré's avatar
Rafaël Carré committed
355 356
        av_dict_free(&options[i]);
    }
357
#else
358
    vlc_avcodec_lock(); /* avformat calls avcodec behind our back!!! */
359
    error = av_find_stream_info( p_sys->ic );
360
    vlc_avcodec_unlock();
361 362
#endif

363
    if( error < 0 )
Gildas Bazin's avatar
 
Gildas Bazin committed
364
    {
365 366
        msg_Warn( p_demux, "Could not find stream info: %s",
                  vlc_strerror_c(AVUNERROR(error)) );
Gildas Bazin's avatar
 
Gildas Bazin committed
367 368
    }

369
    for( unsigned i = 0; i < p_sys->ic->nb_streams; i++ )
Gildas Bazin's avatar
 
Gildas Bazin committed
370
    {
Laurent Aimar's avatar
Laurent Aimar committed
371
        AVStream *s = p_sys->ic->streams[i];
372
        const AVCodecParameters *cp = s->codecpar;
373
        es_out_id_t  *es = NULL;
374
        es_format_t es_fmt;
375
        const char *psz_type = "unknown";
376 377
        vlc_fourcc_t fcc = GetVlcFourcc( cp->codec_id );
        if( !fcc )
Gildas Bazin's avatar
 
Gildas Bazin committed
378 379
            fcc = VLC_FOURCC( 'u', 'n', 'd', 'f' );

380 381 382
#if LIBAVFORMAT_VERSION_INT >= ((54<<16)+(2<<8)+0)
        /* Do not use the cover art as a stream */
        if( s->disposition == AV_DISPOSITION_ATTACHED_PIC )
383
            fcc = 0;
384
#endif
385 386 387 388 389
        if( fcc == 0 )
        {
            TAB_APPEND( p_sys->i_tk, p_sys->tk, NULL );
            continue;
        }
390

391
        switch( cp->codec_type )
Gildas Bazin's avatar
 
Gildas Bazin committed
392
        {
393
        case AVMEDIA_TYPE_AUDIO:
394 395 396 397 398 399 400
            es_format_Init( &es_fmt, AUDIO_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
            es_fmt.i_bitrate = cp->bit_rate;
            es_fmt.audio.i_channels = cp->channels;
            es_fmt.audio.i_rate = cp->sample_rate;
            es_fmt.audio.i_bitspersample = cp->bits_per_coded_sample;
            es_fmt.audio.i_blockalign = cp->block_align;
401
            psz_type = "audio";
402 403 404

            if(cp->codec_id == AV_CODEC_ID_AAC_LATM)
            {
405 406
                es_fmt.i_original_fourcc = VLC_FOURCC('L','A','T','M');
                es_fmt.b_packetized = false;
407 408 409 410
            }
            else if(cp->codec_id == AV_CODEC_ID_AAC &&
                    strstr(p_sys->fmt->long_name, "raw ADTS AAC"))
            {
411 412
                es_fmt.i_original_fourcc = VLC_FOURCC('A','D','T','S');
                es_fmt.b_packetized = false;
413
            }
Gildas Bazin's avatar
 
Gildas Bazin committed
414
            break;
415

416
        case AVMEDIA_TYPE_VIDEO:
417 418
            es_format_Init( &es_fmt, VIDEO_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
419

420
            es_fmt.video.i_bits_per_pixel = cp->bits_per_coded_sample;
421
            /* Special case for raw video data */
422
            if( cp->codec_id == AV_CODEC_ID_RAWVIDEO )
423
            {
424
                msg_Dbg( p_demux, "raw video, pixel format: %i", cp->format );
425
                if( GetVlcChroma( &es_fmt.video, cp->format ) != VLC_SUCCESS)
426 427 428 429
                {
                    msg_Err( p_demux, "was unable to find a FourCC match for raw video" );
                }
                else
430
                    es_fmt.i_codec = es_fmt.video.i_chroma;
431
            }
432
            /* We need this for the h264 packetizer */
433
            else if( cp->codec_id == AV_CODEC_ID_H264 && ( p_sys->fmt == av_find_input_format("flv") ||
434
                p_sys->fmt == av_find_input_format("matroska") || p_sys->fmt == av_find_input_format("mp4") ) )
435
                es_fmt.i_original_fourcc = VLC_FOURCC( 'a', 'v', 'c', '1' );
436

437 438 439 440
            es_fmt.video.i_width = cp->width;
            es_fmt.video.i_height = cp->height;
            es_fmt.video.i_visible_width = es_fmt.video.i_width;
            es_fmt.video.i_visible_height = es_fmt.video.i_height;
441

442
            get_rotation(&es_fmt, s);
443

444
# warning FIXME: implement palette transmission
445
            psz_type = "video";
446 447 448
            es_fmt.video.i_frame_rate = s->codec->time_base.num;
            es_fmt.video.i_frame_rate_base = s->codec->time_base.den * __MAX( s->codec->ticks_per_frame, 1 );
            es_fmt.video.i_sar_num = s->sample_aspect_ratio.num;
449
            if (s->sample_aspect_ratio.num > 0)
450
                es_fmt.video.i_sar_den = s->sample_aspect_ratio.den;
451
            else
452
                es_fmt.video.i_sar_den = 0;
Gildas Bazin's avatar
 
Gildas Bazin committed
453
            break;
454

455
        case AVMEDIA_TYPE_SUBTITLE:
456 457
            es_format_Init( &es_fmt, SPU_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
458
            if( strncmp( p_sys->ic->iformat->name, "matroska", 8 ) == 0 &&
459 460 461
                cp->codec_id == AV_CODEC_ID_DVD_SUBTITLE &&
                cp->extradata != NULL &&
                cp->extradata_size > 0 )
462 463
            {
                char *psz_start;
464
                char *psz_buf = malloc( cp->extradata_size + 1);
465 466
                if( psz_buf != NULL )
                {
467 468
                    memcpy( psz_buf, cp->extradata , cp->extradata_size );
                    psz_buf[cp->extradata_size] = '\0';
469 470 471 472

                    psz_start = strstr( psz_buf, "size:" );
                    if( psz_start &&
                        vobsub_size_parse( psz_start,
473 474
                                           &es_fmt.subs.spu.i_original_frame_width,
                                           &es_fmt.subs.spu.i_original_frame_height ) == VLC_SUCCESS )
475 476
                    {
                        msg_Dbg( p_demux, "original frame size: %dx%d",
477 478
                                 es_fmt.subs.spu.i_original_frame_width,
                                 es_fmt.subs.spu.i_original_frame_height );
479 480 481 482 483 484 485 486
                    }
                    else
                    {
                        msg_Warn( p_demux, "reading original frame size failed" );
                    }

                    psz_start = strstr( psz_buf, "palette:" );
                    if( psz_start &&
487
                        vobsub_palette_parse( psz_start, &es_fmt.subs.spu.palette[1] ) == VLC_SUCCESS )
488
                    {
489
                        es_fmt.subs.spu.palette[0] =  0xBeef;
490 491 492 493 494 495 496 497 498 499
                        msg_Dbg( p_demux, "vobsub palette read" );
                    }
                    else
                    {
                        msg_Warn( p_demux, "reading original palette failed" );
                    }
                    free( psz_buf );
                }
            }

500
            psz_type = "subtitle";
501
            break;
502

Gildas Bazin's avatar
 
Gildas Bazin committed
503
        default:
504 505
            es_format_Init( &es_fmt, UNKNOWN_ES, 0 );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
506
#ifdef HAVE_AVUTIL_CODEC_ATTACHMENT
507
            if( cp->codec_type == AVMEDIA_TYPE_ATTACHMENT )
508 509
            {
                input_attachment_t *p_attachment;
510

511
                psz_type = "attachment";
512
                if( cp->codec_id == AV_CODEC_ID_TTF )
513
                {
514
                    AVDictionaryEntry *filename = av_dict_get( s->metadata, "filename", NULL, 0 );
515 516 517 518
                    if( filename && filename->value )
                    {
                        p_attachment = vlc_input_attachment_New(
                                filename->value, "application/x-truetype-font",
519
                                NULL, cp->extradata, (int)cp->extradata_size );
520 521 522
                        if( p_attachment )
                            TAB_APPEND( p_sys->i_attachments, p_sys->attachments,
                                        p_attachment );
523
                    }
524
                }
525
                else msg_Warn( p_demux, "unsupported attachment type (%u) in avformat demux", cp->codec_id );
526
            }
527
            else
528
#endif
529
            {
530
                if( cp->codec_type == AVMEDIA_TYPE_DATA )
531
                    psz_type = "data";
532

533
                msg_Warn( p_demux, "unsupported track type (%u:%u) in avformat demux", cp->codec_type, cp->codec_id );
534
            }
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
535
            break;
Gildas Bazin's avatar
 
Gildas Bazin committed
536
        }
537

538
        AVDictionaryEntry *language = av_dict_get( s->metadata, "language", NULL, 0 );
539
        if ( language && language->value )
540
            es_fmt.psz_language = strdup( language->value );
541

542
        if( s->disposition & AV_DISPOSITION_DEFAULT )
543
            es_fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN + 1000;
544

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
545
#ifdef HAVE_AVUTIL_CODEC_ATTACHMENT
546
        if( cp->codec_type != AVMEDIA_TYPE_ATTACHMENT )
547
#endif
548
        if( cp->codec_type != AVMEDIA_TYPE_DATA )
549
        {
550
            const bool    b_ogg = !strcmp( p_sys->fmt->name, "ogg" );
551 552
            const uint8_t *p_extra = cp->extradata;
            unsigned      i_extra  = cp->extradata_size;
553

554
            if( cp->codec_id == AV_CODEC_ID_THEORA && b_ogg )
555 556
            {
                unsigned pi_size[3];
Pierre Ynard's avatar
Pierre Ynard committed
557
                const void *pp_data[3];
558 559 560 561 562 563
                unsigned i_count;
                for( i_count = 0; i_count < 3; i_count++ )
                {
                    if( i_extra < 2 )
                        break;
                    pi_size[i_count] = GetWBE( p_extra );
Pierre Ynard's avatar
Pierre Ynard committed
564
                    pp_data[i_count] = &p_extra[2];
565 566 567 568 569 570
                    if( i_extra < pi_size[i_count] + 2 )
                        break;

                    p_extra += 2 + pi_size[i_count];
                    i_extra -= 2 + pi_size[i_count];
                }
571
                if( i_count > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
572 573
                                                     pi_size, pp_data, i_count ) )
                {
574 575
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
576 577
                }
            }
578
            else if( cp->codec_id == AV_CODEC_ID_SPEEX && b_ogg )
579
            {
Pierre Ynard's avatar
Pierre Ynard committed
580
                const uint8_t p_dummy_comment[] = {
581 582 583 584
                    0, 0, 0, 0,
                    0, 0, 0, 0,
                };
                unsigned pi_size[2];
Pierre Ynard's avatar
Pierre Ynard committed
585
                const void *pp_data[2];
586 587

                pi_size[0] = i_extra;
Pierre Ynard's avatar
Pierre Ynard committed
588
                pp_data[0] = p_extra;
589 590 591 592

                pi_size[1] = sizeof(p_dummy_comment);
                pp_data[1] = p_dummy_comment;

593
                if( pi_size[0] > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
594 595
                                                        pi_size, pp_data, 2 ) )
                {
596 597
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
598 599
                }
            }
600
            else if( cp->codec_id == AV_CODEC_ID_OPUS )
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618
            {
                const uint8_t p_dummy_comment[] = {
                    'O', 'p', 'u', 's',
                    'T', 'a', 'g', 's',
                    0, 0, 0, 0, /* Vendor String length */
                                /* Vendor String */
                    0, 0, 0, 0, /* User Comment List Length */

                };
                unsigned pi_size[2];
                const void *pp_data[2];

                pi_size[0] = i_extra;
                pp_data[0] = p_extra;

                pi_size[1] = sizeof(p_dummy_comment);
                pp_data[1] = p_dummy_comment;

619
                if( pi_size[0] > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
620 621
                                                        pi_size, pp_data, 2 ) )
                {
622 623
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
624 625
                }
            }
626
            else if( cp->extradata_size > 0 )
627
            {
628 629
                es_fmt.p_extra = malloc( i_extra );
                if( es_fmt.p_extra )
630
                {
631 632
                    es_fmt.i_extra = i_extra;
                    memcpy( es_fmt.p_extra, p_extra, i_extra );
633 634
                }
            }
635
            es = es_out_Add( p_demux->out, &es_fmt );
636 637
            if( s->disposition & AV_DISPOSITION_DEFAULT )
                es_out_Control( p_demux->out, ES_OUT_SET_ES_DEFAULT, es );
638
            es_format_Clean( &es_fmt );
639

640
            msg_Dbg( p_demux, "adding es: %s codec = %4.4s (%d)",
641
                     psz_type, (char*)&fcc, cp->codec_id  );
642
        }
643
        TAB_APPEND( p_sys->i_tk, p_sys->tk, es );
Gildas Bazin's avatar
 
Gildas Bazin committed
644
    }
645
    p_sys->tk_pcr = xcalloc( p_sys->i_tk, sizeof(*p_sys->tk_pcr) );
646

647 648
    if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
        i_start_time = p_sys->ic->start_time * 1000000 / AV_TIME_BASE;
Gildas Bazin's avatar
 
Gildas Bazin committed
649

650
    msg_Dbg( p_demux, "AVFormat(%s %s) supported stream", AVPROVIDER(LIBAVFORMAT), LIBAVFORMAT_IDENT );
Gildas Bazin's avatar
 
Gildas Bazin committed
651 652
    msg_Dbg( p_demux, "    - format = %s (%s)",
             p_sys->fmt->name, p_sys->fmt->long_name );
653
    msg_Dbg( p_demux, "    - start time = %"PRId64, i_start_time );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
654
    msg_Dbg( p_demux, "    - duration = %"PRId64,
655
             ( p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE ) ?
Gildas Bazin's avatar
 
Gildas Bazin committed
656
             p_sys->ic->duration * 1000000 / AV_TIME_BASE : -1 );
Gildas Bazin's avatar
 
Gildas Bazin committed
657

658
    if( p_sys->ic->nb_chapters > 0 )
659
    {
660
        p_sys->p_title = vlc_input_title_New();
661 662 663
        p_sys->p_title->i_length = p_sys->ic->duration * 1000000 / AV_TIME_BASE;
    }

664
    for( unsigned i = 0; i < p_sys->ic->nb_chapters; i++ )
665 666 667
    {
        seekpoint_t *s = vlc_seekpoint_New();

668
        AVDictionaryEntry *title = av_dict_get( p_sys->ic->metadata, "title", NULL, 0);
669
        if( title && title->value )
670
        {
671
            s->psz_name = strdup( title->value );
672 673 674 675 676 677 678 679 680 681
            EnsureUTF8( s->psz_name );
            msg_Dbg( p_demux, "    - chapter %d: %s", i, s->psz_name );
        }
        s->i_time_offset = p_sys->ic->chapters[i]->start * 1000000 *
            p_sys->ic->chapters[i]->time_base.num /
            p_sys->ic->chapters[i]->time_base.den -
            (i_start_time != -1 ? i_start_time : 0 );
        TAB_APPEND( p_sys->p_title->i_seekpoint, p_sys->p_title->seekpoint, s );
    }

682
    ResetTime( p_demux, 0 );
Gildas Bazin's avatar
 
Gildas Bazin committed
683 684 685 686 687 688
    return VLC_SUCCESS;
}

/*****************************************************************************
 * Close
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
689
void CloseDemux( vlc_object_t *p_this )
Gildas Bazin's avatar
 
Gildas Bazin committed
690 691 692 693
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys = p_demux->p_sys;

694
    free( p_sys->tk );
695
    free( p_sys->tk_pcr );
696

697
    if( p_sys->ic )
698
    {
699 700 701 702 703
        if( p_sys->ic->pb )
        {
            av_free( p_sys->ic->pb->buffer );
            av_free( p_sys->ic->pb );
        }
704
#if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(26<<8)+0)
705 706 707 708
        avformat_close_input( &p_sys->ic );
#else
        av_close_input_stream( p_sys->ic );
#endif
709
    }
710

711
    for( int i = 0; i < p_sys->i_attachments; i++ )
712
        vlc_input_attachment_Delete( p_sys->attachments[i] );
713 714
    TAB_CLEAN( p_sys->i_attachments, p_sys->attachments);

715 716 717
    if( p_sys->p_title )
        vlc_input_title_Delete( p_sys->p_title );

Gildas Bazin's avatar
 
Gildas Bazin committed
718 719 720 721 722 723 724 725 726 727 728
    free( p_sys );
}

/*****************************************************************************
 * Demux:
 *****************************************************************************/
static int Demux( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    AVPacket    pkt;
    block_t     *p_frame;
Gildas Bazin's avatar
 
Gildas Bazin committed
729
    int64_t     i_start_time;
Gildas Bazin's avatar
 
Gildas Bazin committed
730 731

    /* Read a frame */
732 733
    int i_av_ret = av_read_frame( p_sys->ic, &pkt );
    if( i_av_ret )
Gildas Bazin's avatar
 
Gildas Bazin committed
734
    {
735 736 737 738
        /* Avoid EOF if av_read_frame returns AVERROR(EAGAIN) */
        if( i_av_ret == AVERROR(EAGAIN) )
            return 1;

Gildas Bazin's avatar
 
Gildas Bazin committed
739 740 741 742
        return 0;
    }
    if( pkt.stream_index < 0 || pkt.stream_index >= p_sys->i_tk )
    {
743
        av_packet_unref( &pkt );
Gildas Bazin's avatar
 
Gildas Bazin committed
744 745
        return 1;
    }
746
    const AVStream *p_stream = p_sys->ic->streams[pkt.stream_index];
747 748 749
    if( p_stream->time_base.den <= 0 )
    {
        msg_Warn( p_demux, "Invalid time base for the stream %d", pkt.stream_index );
750
        av_packet_unref( &pkt );
751 752
        return 1;
    }
753
    if( p_stream->codecpar->codec_id == AV_CODEC_ID_SSA )
Gildas Bazin's avatar
 
Gildas Bazin committed
754
    {
755 756
        p_frame = BuildSsaFrame( &pkt, p_sys->i_ssa_order++ );
        if( !p_frame )
757
        {
758
            av_packet_unref( &pkt );
759
            return 1;
760
        }
761 762 763
    }
    else
    {
764
        if( ( p_frame = block_Alloc( pkt.size ) ) == NULL )
765
        {
766
            av_packet_unref( &pkt );
767
            return 0;
768
        }
769
        memcpy( p_frame->p_buffer, pkt.data, pkt.size );
Gildas Bazin's avatar
 
Gildas Bazin committed
770
    }
Gildas Bazin's avatar
 
Gildas Bazin committed
771

772
    if( pkt.flags & AV_PKT_FLAG_KEY )
773 774
        p_frame->i_flags |= BLOCK_FLAG_TYPE_I;

775 776 777 778 779
    /* Used to avoid timestamps overlow */
    lldiv_t q;
    if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
    {
        q = lldiv( p_sys->ic->start_time, AV_TIME_BASE);
Ilkka Ollakka's avatar
Ilkka Ollakka committed
780
        i_start_time = q.quot * CLOCK_FREQ + q.rem * CLOCK_FREQ / AV_TIME_BASE;
781 782 783 784 785 786 787 788 789
    }
    else
        i_start_time = 0;

    if( pkt.dts == (int64_t)AV_NOPTS_VALUE )
        p_frame->i_dts = VLC_TS_INVALID;
    else
    {
        q = lldiv( pkt.dts, p_stream->time_base.den );
Ilkka Ollakka's avatar
Ilkka Ollakka committed
790 791
        p_frame->i_dts = q.quot * CLOCK_FREQ *
            p_stream->time_base.num + q.rem * CLOCK_FREQ *
792 793 794 795 796 797 798 799 800
            p_stream->time_base.num /
            p_stream->time_base.den - i_start_time + VLC_TS_0;
    }

    if( pkt.pts == (int64_t)AV_NOPTS_VALUE )
        p_frame->i_pts = VLC_TS_INVALID;
    else
    {
        q = lldiv( pkt.pts, p_stream->time_base.den );
Ilkka Ollakka's avatar
Ilkka Ollakka committed
801 802
        p_frame->i_pts = q.quot * CLOCK_FREQ *
            p_stream->time_base.num + q.rem * CLOCK_FREQ *
803 804 805
            p_stream->time_base.num /
            p_stream->time_base.den - i_start_time + VLC_TS_0;
    }
806
    if( pkt.duration > 0 && p_frame->i_length <= 0 )
Ilkka Ollakka's avatar
Ilkka Ollakka committed
807
        p_frame->i_length = pkt.duration * CLOCK_FREQ *
808
            p_stream->time_base.num /
809
            p_stream->time_base.den;
Gildas Bazin's avatar
 
Gildas Bazin committed
810

811 812
    /* Add here notoriously bugged file formats/samples */
    if( !strcmp( p_sys->fmt->name, "flv" ) )
813
    {
814 815 816 817
        /* FLV and video PTS */
        if( p_stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
            pkt.dts != (int64_t)AV_NOPTS_VALUE && pkt.dts == pkt.pts )
                p_frame->i_pts = VLC_TS_INVALID;
818 819 820 821 822 823 824 825 826 827 828 829

        /* Handle broken dts/pts increase with AAC. Duration is correct.
         * sky_the80s_aacplus.flv #8195 */
        if( p_stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
            p_stream->codecpar->codec_id == AV_CODEC_ID_AAC )
        {
            if( p_sys->tk_pcr[pkt.stream_index] != VLC_TS_INVALID &&
                p_sys->tk_pcr[pkt.stream_index] + p_frame->i_length > p_frame->i_dts )
            {
                p_frame->i_dts = p_frame->i_pts = p_sys->tk_pcr[pkt.stream_index] + p_frame->i_length;
            }
        }
830
    }
831
#ifdef AVFORMAT_DEBUG
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
832
    msg_Dbg( p_demux, "tk[%d] dts=%"PRId64" pts=%"PRId64,
Gildas Bazin's avatar
 
Gildas Bazin committed
833
             pkt.stream_index, p_frame->i_dts, p_frame->i_pts );
834
#endif
835 836
    if( p_frame->i_dts > VLC_TS_INVALID )
        p_sys->tk_pcr[pkt.stream_index] = p_frame->i_dts;
Gildas Bazin's avatar
 
Gildas Bazin committed
837

838 839 840
    int64_t i_ts_max = INT64_MIN;
    for( int i = 0; i < p_sys->i_tk; i++ )
        i_ts_max = __MAX( i_ts_max, p_sys->tk_pcr[i] );
Gildas Bazin's avatar
 
Gildas Bazin committed
841

842 843 844 845 846 847 848 849 850 851 852
    int64_t i_ts_min = INT64_MAX;
    for( int i = 0; i < p_sys->i_tk; i++ )
    {
        if( p_sys->tk_pcr[i] > VLC_TS_INVALID && p_sys->tk_pcr[i] + 10 * CLOCK_FREQ >= i_ts_max )
            i_ts_min = __MIN( i_ts_min, p_sys->tk_pcr[i] );
    }
    if( i_ts_min >= p_sys->i_pcr )
    {
        p_sys->i_pcr = i_ts_min;
        es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
        UpdateSeekPoint( p_demux, p_sys->i_pcr );
Gildas Bazin's avatar
 
Gildas Bazin committed
853 854
    }

855 856 857 858
    if( p_sys->tk[pkt.stream_index] != NULL )
        es_out_Send( p_demux->out, p_sys->tk[pkt.stream_index], p_frame );
    else
        block_Release( p_frame );
859

860
    av_packet_unref( &pkt );
Gildas Bazin's avatar
 
Gildas Bazin committed
861 862 863
    return 1;
}

Derk-Jan Hartman's avatar