demux.c 38.4 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
#include <libavutil/display.h>
50

51 52
//#define AVFORMAT_DEBUG 1

53
# define HAVE_AVUTIL_CODEC_ATTACHMENT 1
54

Gildas Bazin's avatar
 
Gildas Bazin committed
55 56 57 58 59 60 61 62 63 64
/*****************************************************************************
 * demux_sys_t: demux descriptor
 *****************************************************************************/
struct demux_sys_t
{
    AVInputFormat  *fmt;
    AVFormatContext *ic;

    int             i_tk;
    es_out_id_t     **tk;
65 66
    int64_t         *tk_pcr;
    int64_t         i_pcr;
67

68 69
    unsigned    i_ssa_order;

70 71
    int                i_attachments;
    input_attachment_t **attachments;
72 73 74

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

77 78
#define AVFORMAT_IOBUFFER_SIZE 32768  /* FIXME */

Gildas Bazin's avatar
 
Gildas Bazin committed
79 80 81 82 83 84 85
/*****************************************************************************
 * 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 );
86
static int64_t IOSeek( void *opaque, int64_t offset, int whence );
Gildas Bazin's avatar
 
Gildas Bazin committed
87

88
static block_t *BuildSsaFrame( const AVPacket *p_pkt, unsigned i_order );
89
static void UpdateSeekPoint( demux_t *p_demux, int64_t i_time );
90
static void ResetTime( demux_t *p_demux, int64_t i_time );
91

92 93 94 95 96 97 98 99 100 101
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
102 103 104
/*****************************************************************************
 * Open
 *****************************************************************************/
105 106 107 108 109 110 111 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

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;
    }
    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;
    }
}

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
146
int OpenDemux( vlc_object_t *p_this )
Gildas Bazin's avatar
 
Gildas Bazin committed
147 148 149
{
    demux_t       *p_demux = (demux_t*)p_this;
    demux_sys_t   *p_sys;
150
    AVProbeData   pd = { };
151
    AVInputFormat *fmt = NULL;
152
    int64_t       i_start_time = -1;
153
    bool          b_can_seek;
154
    char         *psz_url;
155
    const uint8_t *peek;
156
    int           error;
Gildas Bazin's avatar
 
Gildas Bazin committed
157

158
    /* Init Probe data */
159
    pd.buf_size = vlc_stream_Peek( p_demux->s, &peek, 2048 + 213 );
160 161 162 163 164 165 166 167 168 169 170 171 172
    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 );

173 174 175 176
    if( p_demux->psz_file )
        psz_url = strdup( p_demux->psz_file );
    else
    {
177 178 179
        if( asprintf( &psz_url, "%s://%s", p_demux->psz_access,
                      p_demux->psz_location ) == -1)
            psz_url = NULL;
180
    }
181 182 183 184

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

185
    pd.filename = psz_url;
186

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

189
    vlc_init_avformat(p_this);
Gildas Bazin's avatar
 
Gildas Bazin committed
190

191
    /* Guess format */
192
    char *psz_format = var_InheritString( p_this, "avformat-format" );
193 194
    if( psz_format )
    {
195
        if( (fmt = av_find_input_format(psz_format)) )
196 197 198 199
            msg_Dbg( p_demux, "forcing format: %s", fmt->name );
        free( psz_format );
    }

200 201 202 203 204 205
    if( fmt == NULL )
        fmt = av_probe_input_format( &pd, 1 );

    free( pd.buf );

    if( fmt == NULL )
Gildas Bazin's avatar
 
Gildas Bazin committed
206 207
    {
        msg_Dbg( p_demux, "couldn't guess format" );
208
        free( psz_url );
Gildas Bazin's avatar
 
Gildas Bazin committed
209 210 211
        return VLC_EGENERIC;
    }

212
    if( !p_demux->obj.force )
Gildas Bazin's avatar
 
Gildas Bazin committed
213
    {
214 215 216 217 218
        static const char ppsz_blacklist[][16] = {
            /* Don't handle MPEG unless forced */
            "mpeg", "vcd", "vob", "mpegts",
            /* libavformat's redirector won't work */
            "redir", "sdp",
219 220
            /* Don't handle subtitles format */
            "ass", "srt", "microdvd",
221
            /* No timestamps at all */
222
            "hevc", "h264",
223 224 225 226 227 228 229 230 231 232 233
            ""
        };

        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
234 235
    }

236
    /* Don't trigger false alarms on bin files */
237
    if( !p_demux->obj.force && !strcmp( fmt->name, "psxstr" ) )
238 239 240
    {
        int i_len;

241 242 243 244 245
        if( !p_demux->psz_file )
        {
            free( psz_url );
            return VLC_EGENERIC;
        }
246

247
        i_len = strlen( p_demux->psz_file );
248 249 250 251 252
        if( i_len < 4 )
        {
            free( psz_url );
            return VLC_EGENERIC;
        }
253

254 255 256
        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" ) )
257
        {
258
            free( psz_url );
259 260 261 262
            return VLC_EGENERIC;
        }
    }

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

Gildas Bazin's avatar
 
Gildas Bazin committed
265 266 267
    /* Fill p_demux fields */
    p_demux->pf_demux = Demux;
    p_demux->pf_control = Control;
268
    p_demux->p_sys = p_sys = xmalloc( sizeof( demux_sys_t ) );
269
    p_sys->ic = 0;
Gildas Bazin's avatar
 
Gildas Bazin committed
270 271 272
    p_sys->fmt = fmt;
    p_sys->i_tk = 0;
    p_sys->tk = NULL;
273
    p_sys->tk_pcr = NULL;
274
    p_sys->i_ssa_order = 0;
275
    TAB_INIT( p_sys->i_attachments, p_sys->attachments);
276
    p_sys->p_title = NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
277 278

    /* Create I/O wrapper */
279
    unsigned char * p_io_buffer = av_malloc( AVFORMAT_IOBUFFER_SIZE );
280 281 282 283 284 285
    if( !p_io_buffer )
    {
        free( psz_url );
        CloseDemux( p_this );
        return VLC_ENOMEM;
    }
286

287
    p_sys->ic = avformat_alloc_context();
288 289
    if( !p_sys->ic )
    {
290
        av_free( p_io_buffer );
291 292 293 294 295 296 297 298 299
        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 )
    {
300
        av_free( p_io_buffer );
301 302 303 304 305
        free( psz_url );
        CloseDemux( p_this );
        return VLC_ENOMEM;
    }

306
    p_sys->ic->pb->seekable = b_can_seek ? AVIO_SEEKABLE_NORMAL : 0;
307
    error = avformat_open_input(&p_sys->ic, psz_url, p_sys->fmt, NULL);
308

309
    if( error < 0 )
Gildas Bazin's avatar
 
Gildas Bazin committed
310
    {
311 312
        msg_Err( p_demux, "Could not open %s: %s", psz_url,
                 vlc_strerror_c(AVUNERROR(error)) );
Hannes Domani's avatar
Hannes Domani committed
313
        av_free( p_io_buffer );
Hannes Domani's avatar
Hannes Domani committed
314
        av_free( pb );
315
        p_sys->ic = NULL;
316
        free( psz_url );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
317
        CloseDemux( p_this );
Gildas Bazin's avatar
 
Gildas Bazin committed
318 319
        return VLC_EGENERIC;
    }
320
    free( psz_url );
Gildas Bazin's avatar
 
Gildas Bazin committed
321

322
    char *psz_opts = var_InheritString( p_demux, "avformat-options" );
323 324
    AVDictionary *options[p_sys->ic->nb_streams ? p_sys->ic->nb_streams : 1];
    options[0] = NULL;
325 326
    unsigned int nb_streams = p_sys->ic->nb_streams;
    for (unsigned i = 1; i < nb_streams; i++)
327
        options[i] = NULL;
328
    if (psz_opts) {
329
        vlc_av_get_options(psz_opts, &options[0]);
330
        for (unsigned i = 1; i < nb_streams; i++) {
331 332
            av_dict_copy(&options[i], options[0], 0);
        }
333
        free(psz_opts);
334 335 336
    }
    vlc_avcodec_lock(); /* avformat calls avcodec behind our back!!! */
    error = avformat_find_stream_info( p_sys->ic, options );
337
    /* FIXME: what if nb_streams change after that call? */
338 339
    vlc_avcodec_unlock();
    AVDictionaryEntry *t = NULL;
Rafaël Carré's avatar
Rafaël Carré committed
340
    while ((t = av_dict_get(options[0], "", t, AV_DICT_IGNORE_SUFFIX))) {
341 342
        msg_Err( p_demux, "Unknown option \"%s\"", t->key );
    }
343
    av_dict_free(&options[0]);
344
    for (unsigned i = 1; i < nb_streams; i++) {
Rafaël Carré's avatar
Rafaël Carré committed
345 346
        av_dict_free(&options[i]);
    }
347

348
    if( error < 0 )
Gildas Bazin's avatar
 
Gildas Bazin committed
349
    {
350 351
        msg_Warn( p_demux, "Could not find stream info: %s",
                  vlc_strerror_c(AVUNERROR(error)) );
Gildas Bazin's avatar
 
Gildas Bazin committed
352 353
    }

354
    for( unsigned i = 0; i < p_sys->ic->nb_streams; i++ )
Gildas Bazin's avatar
 
Gildas Bazin committed
355
    {
Laurent Aimar's avatar
Laurent Aimar committed
356
        AVStream *s = p_sys->ic->streams[i];
357
        const AVCodecParameters *cp = s->codecpar;
358
        es_out_id_t  *es = NULL;
359
        es_format_t es_fmt;
360
        const char *psz_type = "unknown";
Gildas Bazin's avatar
 
Gildas Bazin committed
361

362 363
        /* Do not use the cover art as a stream */
        if( s->disposition == AV_DISPOSITION_ATTACHED_PIC )
364 365 366 367
        {
            TAB_APPEND( p_sys->i_tk, p_sys->tk, NULL );
            continue;
        }
368

369
        vlc_fourcc_t fcc = GetVlcFourcc( cp->codec_id );
370
        switch( cp->codec_type )
Gildas Bazin's avatar
 
Gildas Bazin committed
371
        {
372
        case AVMEDIA_TYPE_AUDIO:
373 374 375 376 377 378 379
            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;
380
            psz_type = "audio";
381 382 383

            if(cp->codec_id == AV_CODEC_ID_AAC_LATM)
            {
384 385
                es_fmt.i_original_fourcc = VLC_FOURCC('L','A','T','M');
                es_fmt.b_packetized = false;
386 387 388 389
            }
            else if(cp->codec_id == AV_CODEC_ID_AAC &&
                    strstr(p_sys->fmt->long_name, "raw ADTS AAC"))
            {
390 391
                es_fmt.i_original_fourcc = VLC_FOURCC('A','D','T','S');
                es_fmt.b_packetized = false;
392
            }
Gildas Bazin's avatar
 
Gildas Bazin committed
393
            break;
394

395
        case AVMEDIA_TYPE_VIDEO:
396 397
            es_format_Init( &es_fmt, VIDEO_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
398

399
            es_fmt.video.i_bits_per_pixel = cp->bits_per_coded_sample;
400
            /* Special case for raw video data */
401
            if( cp->codec_id == AV_CODEC_ID_RAWVIDEO )
402
            {
403
                msg_Dbg( p_demux, "raw video, pixel format: %i", cp->format );
404
                if( GetVlcChroma( &es_fmt.video, cp->format ) != VLC_SUCCESS)
405 406 407 408
                {
                    msg_Err( p_demux, "was unable to find a FourCC match for raw video" );
                }
                else
409
                    es_fmt.i_codec = es_fmt.video.i_chroma;
410
            }
411
            /* We need this for the h264 packetizer */
412
            else if( cp->codec_id == AV_CODEC_ID_H264 && ( p_sys->fmt == av_find_input_format("flv") ||
413
                p_sys->fmt == av_find_input_format("matroska") || p_sys->fmt == av_find_input_format("mp4") ) )
414
                es_fmt.i_original_fourcc = VLC_FOURCC( 'a', 'v', 'c', '1' );
415

416 417 418 419
            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;
420

421
            get_rotation(&es_fmt, s);
422

423
# warning FIXME: implement palette transmission
424
            psz_type = "video";
425 426 427
            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;
428
            if (s->sample_aspect_ratio.num > 0)
429
                es_fmt.video.i_sar_den = s->sample_aspect_ratio.den;
430
            else
431
                es_fmt.video.i_sar_den = 0;
Gildas Bazin's avatar
 
Gildas Bazin committed
432
            break;
433

434
        case AVMEDIA_TYPE_SUBTITLE:
435 436
            es_format_Init( &es_fmt, SPU_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
437
            if( strncmp( p_sys->ic->iformat->name, "matroska", 8 ) == 0 &&
438 439 440
                cp->codec_id == AV_CODEC_ID_DVD_SUBTITLE &&
                cp->extradata != NULL &&
                cp->extradata_size > 0 )
441 442
            {
                char *psz_start;
443
                char *psz_buf = malloc( cp->extradata_size + 1);
444 445
                if( psz_buf != NULL )
                {
446 447
                    memcpy( psz_buf, cp->extradata , cp->extradata_size );
                    psz_buf[cp->extradata_size] = '\0';
448 449 450 451

                    psz_start = strstr( psz_buf, "size:" );
                    if( psz_start &&
                        vobsub_size_parse( psz_start,
452 453
                                           &es_fmt.subs.spu.i_original_frame_width,
                                           &es_fmt.subs.spu.i_original_frame_height ) == VLC_SUCCESS )
454 455
                    {
                        msg_Dbg( p_demux, "original frame size: %dx%d",
456 457
                                 es_fmt.subs.spu.i_original_frame_width,
                                 es_fmt.subs.spu.i_original_frame_height );
458 459 460 461 462 463 464 465
                    }
                    else
                    {
                        msg_Warn( p_demux, "reading original frame size failed" );
                    }

                    psz_start = strstr( psz_buf, "palette:" );
                    if( psz_start &&
466
                        vobsub_palette_parse( psz_start, &es_fmt.subs.spu.palette[1] ) == VLC_SUCCESS )
467
                    {
468
                        es_fmt.subs.spu.palette[0] = SPU_PALETTE_DEFINED;
469 470 471 472 473 474 475 476 477 478
                        msg_Dbg( p_demux, "vobsub palette read" );
                    }
                    else
                    {
                        msg_Warn( p_demux, "reading original palette failed" );
                    }
                    free( psz_buf );
                }
            }

479
            psz_type = "subtitle";
480
            break;
481

Gildas Bazin's avatar
 
Gildas Bazin committed
482
        default:
483 484
            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
485
#ifdef HAVE_AVUTIL_CODEC_ATTACHMENT
486
            if( cp->codec_type == AVMEDIA_TYPE_ATTACHMENT )
487 488
            {
                input_attachment_t *p_attachment;
489

490
                psz_type = "attachment";
491
                if( cp->codec_id == AV_CODEC_ID_TTF )
492
                {
493
                    AVDictionaryEntry *filename = av_dict_get( s->metadata, "filename", NULL, 0 );
494 495 496 497
                    if( filename && filename->value )
                    {
                        p_attachment = vlc_input_attachment_New(
                                filename->value, "application/x-truetype-font",
498
                                NULL, cp->extradata, (int)cp->extradata_size );
499 500 501
                        if( p_attachment )
                            TAB_APPEND( p_sys->i_attachments, p_sys->attachments,
                                        p_attachment );
502
                    }
503
                }
504
                else msg_Warn( p_demux, "unsupported attachment type (%u) in avformat demux", cp->codec_id );
505
            }
506
            else
507
#endif
508
            {
509
                if( cp->codec_type == AVMEDIA_TYPE_DATA )
510
                    psz_type = "data";
511

512
                msg_Warn( p_demux, "unsupported track type (%u:%u) in avformat demux", cp->codec_type, cp->codec_id );
513
            }
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
514
            break;
Gildas Bazin's avatar
 
Gildas Bazin committed
515
        }
516

517
        AVDictionaryEntry *language = av_dict_get( s->metadata, "language", NULL, 0 );
518
        if ( language && language->value )
519
            es_fmt.psz_language = strdup( language->value );
520

521
        if( s->disposition & AV_DISPOSITION_DEFAULT )
522
            es_fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN + 1000;
523

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
524
#ifdef HAVE_AVUTIL_CODEC_ATTACHMENT
525
        if( cp->codec_type != AVMEDIA_TYPE_ATTACHMENT )
526
#endif
527
        if( cp->codec_type != AVMEDIA_TYPE_DATA )
528
        {
529
            const bool    b_ogg = !strcmp( p_sys->fmt->name, "ogg" );
530 531
            const uint8_t *p_extra = cp->extradata;
            unsigned      i_extra  = cp->extradata_size;
532

533
            if( cp->codec_id == AV_CODEC_ID_THEORA && b_ogg )
534 535
            {
                unsigned pi_size[3];
Pierre Ynard's avatar
Pierre Ynard committed
536
                const void *pp_data[3];
537 538 539 540 541 542
                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
543
                    pp_data[i_count] = &p_extra[2];
544 545 546 547 548 549
                    if( i_extra < pi_size[i_count] + 2 )
                        break;

                    p_extra += 2 + pi_size[i_count];
                    i_extra -= 2 + pi_size[i_count];
                }
550
                if( i_count > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
551 552
                                                     pi_size, pp_data, i_count ) )
                {
553 554
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
555 556
                }
            }
557
            else if( cp->codec_id == AV_CODEC_ID_SPEEX && b_ogg )
558
            {
Pierre Ynard's avatar
Pierre Ynard committed
559
                const uint8_t p_dummy_comment[] = {
560 561 562 563
                    0, 0, 0, 0,
                    0, 0, 0, 0,
                };
                unsigned pi_size[2];
Pierre Ynard's avatar
Pierre Ynard committed
564
                const void *pp_data[2];
565 566

                pi_size[0] = i_extra;
Pierre Ynard's avatar
Pierre Ynard committed
567
                pp_data[0] = p_extra;
568 569 570 571

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

572
                if( pi_size[0] > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
573 574
                                                        pi_size, pp_data, 2 ) )
                {
575 576
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
577 578
                }
            }
579
            else if( cp->codec_id == AV_CODEC_ID_OPUS )
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
            {
                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;

598
                if( pi_size[0] > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
599 600
                                                        pi_size, pp_data, 2 ) )
                {
601 602
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
603 604
                }
            }
605
            else if( cp->extradata_size > 0 )
606
            {
607 608
                es_fmt.p_extra = malloc( i_extra );
                if( es_fmt.p_extra )
609
                {
610 611
                    es_fmt.i_extra = i_extra;
                    memcpy( es_fmt.p_extra, p_extra, i_extra );
612 613
                }
            }
614
            es = es_out_Add( p_demux->out, &es_fmt );
615 616
            if( s->disposition & AV_DISPOSITION_DEFAULT )
                es_out_Control( p_demux->out, ES_OUT_SET_ES_DEFAULT, es );
617
            es_format_Clean( &es_fmt );
618

619
            msg_Dbg( p_demux, "adding es: %s codec = %4.4s (%d)",
620
                     psz_type, (char*)&fcc, cp->codec_id  );
621
        }
622
        TAB_APPEND( p_sys->i_tk, p_sys->tk, es );
Gildas Bazin's avatar
 
Gildas Bazin committed
623
    }
624
    p_sys->tk_pcr = xcalloc( p_sys->i_tk, sizeof(*p_sys->tk_pcr) );
625

626 627
    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
628

629
    msg_Dbg( p_demux, "AVFormat(%s %s) supported stream", AVPROVIDER(LIBAVFORMAT), LIBAVFORMAT_IDENT );
Gildas Bazin's avatar
 
Gildas Bazin committed
630 631
    msg_Dbg( p_demux, "    - format = %s (%s)",
             p_sys->fmt->name, p_sys->fmt->long_name );
632
    msg_Dbg( p_demux, "    - start time = %"PRId64, i_start_time );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
633
    msg_Dbg( p_demux, "    - duration = %"PRId64,
634
             ( p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE ) ?
Gildas Bazin's avatar
 
Gildas Bazin committed
635
             p_sys->ic->duration * 1000000 / AV_TIME_BASE : -1 );
Gildas Bazin's avatar
 
Gildas Bazin committed
636

637
    if( p_sys->ic->nb_chapters > 0 )
638
    {
639
        p_sys->p_title = vlc_input_title_New();
640 641 642
        p_sys->p_title->i_length = p_sys->ic->duration * 1000000 / AV_TIME_BASE;
    }

643
    for( unsigned i = 0; i < p_sys->ic->nb_chapters; i++ )
644 645 646
    {
        seekpoint_t *s = vlc_seekpoint_New();

647
        AVDictionaryEntry *title = av_dict_get( p_sys->ic->metadata, "title", NULL, 0);
648
        if( title && title->value )
649
        {
650
            s->psz_name = strdup( title->value );
651 652 653 654 655 656 657 658 659 660
            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 );
    }

661
    ResetTime( p_demux, 0 );
Gildas Bazin's avatar
 
Gildas Bazin committed
662 663 664 665 666 667
    return VLC_SUCCESS;
}

/*****************************************************************************
 * Close
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
668
void CloseDemux( vlc_object_t *p_this )
Gildas Bazin's avatar
 
Gildas Bazin committed
669 670 671 672
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys = p_demux->p_sys;

673
    free( p_sys->tk );
674
    free( p_sys->tk_pcr );
675

676
    if( p_sys->ic )
677
    {
678 679 680 681 682
        if( p_sys->ic->pb )
        {
            av_free( p_sys->ic->pb->buffer );
            av_free( p_sys->ic->pb );
        }
683
        avformat_close_input( &p_sys->ic );
684
    }
685

686
    for( int i = 0; i < p_sys->i_attachments; i++ )
687
        vlc_input_attachment_Delete( p_sys->attachments[i] );
688 689
    TAB_CLEAN( p_sys->i_attachments, p_sys->attachments);

690 691 692
    if( p_sys->p_title )
        vlc_input_title_Delete( p_sys->p_title );

Gildas Bazin's avatar
 
Gildas Bazin committed
693 694 695 696 697 698 699 700 701 702 703
    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
704
    int64_t     i_start_time;
Gildas Bazin's avatar
 
Gildas Bazin committed
705 706

    /* Read a frame */
707 708
    int i_av_ret = av_read_frame( p_sys->ic, &pkt );
    if( i_av_ret )
Gildas Bazin's avatar
 
Gildas Bazin committed
709
    {
710 711 712 713
        /* Avoid EOF if av_read_frame returns AVERROR(EAGAIN) */
        if( i_av_ret == AVERROR(EAGAIN) )
            return 1;

Gildas Bazin's avatar
 
Gildas Bazin committed
714 715 716 717
        return 0;
    }
    if( pkt.stream_index < 0 || pkt.stream_index >= p_sys->i_tk )
    {
718
        av_packet_unref( &pkt );
Gildas Bazin's avatar
 
Gildas Bazin committed
719 720
        return 1;
    }
721
    const AVStream *p_stream = p_sys->ic->streams[pkt.stream_index];
722 723 724
    if( p_stream->time_base.den <= 0 )
    {
        msg_Warn( p_demux, "Invalid time base for the stream %d", pkt.stream_index );
725
        av_packet_unref( &pkt );
726 727
        return 1;
    }
728
    if( p_stream->codecpar->codec_id == AV_CODEC_ID_SSA )
Gildas Bazin's avatar
 
Gildas Bazin committed
729
    {
730 731
        p_frame = BuildSsaFrame( &pkt, p_sys->i_ssa_order++ );
        if( !p_frame )
732
        {
733
            av_packet_unref( &pkt );
734
            return 1;
735
        }
736 737 738
    }
    else
    {
739
        if( ( p_frame = block_Alloc( pkt.size ) ) == NULL )
740
        {
741
            av_packet_unref( &pkt );
742
            return 0;
743
        }
744
        memcpy( p_frame->p_buffer, pkt.data, pkt.size );
Gildas Bazin's avatar
 
Gildas Bazin committed
745
    }
Gildas Bazin's avatar
 
Gildas Bazin committed
746

747
    if( pkt.flags & AV_PKT_FLAG_KEY )
748 749
        p_frame->i_flags |= BLOCK_FLAG_TYPE_I;

750 751 752 753 754
    /* 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
755
        i_start_time = q.quot * CLOCK_FREQ + q.rem * CLOCK_FREQ / AV_TIME_BASE;
756 757 758 759 760 761 762 763 764
    }
    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
765 766
        p_frame->i_dts = q.quot * CLOCK_FREQ *
            p_stream->time_base.num + q.rem * CLOCK_FREQ *
767 768 769 770 771 772 773 774 775
            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
776 777
        p_frame->i_pts = q.quot * CLOCK_FREQ *
            p_stream->time_base.num + q.rem * CLOCK_FREQ *
778 779 780
            p_stream->time_base.num /
            p_stream->time_base.den - i_start_time + VLC_TS_0;
    }
781
    if( pkt.duration > 0 && p_frame->i_length <= 0 )
Ilkka Ollakka's avatar
Ilkka Ollakka committed
782
        p_frame->i_length = pkt.duration * CLOCK_FREQ *
783
            p_stream->time_base.num /
784
            p_stream->time_base.den;
Gildas Bazin's avatar
 
Gildas Bazin committed
785

786 787
    /* Add here notoriously bugged file formats/samples */
    if( !strcmp( p_sys->fmt->name, "flv" ) )
788
    {
789 790 791 792
        /* 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;
793 794 795 796 797 798 799 800 801 802 803 804

        /* 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;
            }
        }
805
    }
806
#ifdef AVFORMAT_DEBUG
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
807
    msg_Dbg( p_demux, "tk[%d] dts=%"PRId64" pts=%"PRId64,
Gildas Bazin's avatar
 
Gildas Bazin committed
808
             pkt.stream_index, p_frame->i_dts, p_frame->i_pts );
809
#endif
810 811
    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
812

813 814 815
    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
816

817 818 819 820 821 822 823 824 825
    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;
826
        es_out_SetPCR( p_demux->out, p_sys->i_pcr );
827
        UpdateSeekPoint( p_demux, p_sys->i_pcr );
Gildas Bazin's avatar
 
Gildas Bazin committed
828 829
    }

830 831 832 833
    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 );
834

835
    av_packet_unref( &pkt );
Gildas Bazin's avatar
 
Gildas Bazin committed
836 837 838
    return 1;
}

839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
static void UpdateSeekPoint( demux_t *p_demux, int64_t i_time )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    int i;

    if( !p_sys->p_title )
        return;

    for( i = 0; i < p_sys->p_title->i_seekpoint; i++ )
    {
        if( i_time < p_sys->p_title->seekpoint[i]->i_time_offset )
            break;
    }
    i--;

    if( i != p_demux->info.i_seekpoint && i >= 0 )
    {
        p_demux->info.i_seekpoint = i;
        p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
    }
}

861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880
static void ResetTime( demux_t *p_demux, int64_t i_time )
{
    demux_sys_t *p_sys = p_demux->p_sys;

    if( p_sys->ic->start_time == (int64_t)AV_NOPTS_VALUE || i_time < 0 )
        i_time = VLC_TS_INVALID;
    else if( i_time == 0 )