demux.c 36.1 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
//#define AVFORMAT_DEBUG 1

52
# define HAVE_AVUTIL_CODEC_ATTACHMENT 1
53

Gildas Bazin's avatar
 
Gildas Bazin committed
54 55 56 57 58 59 60 61 62 63 64 65 66
/*****************************************************************************
 * demux_sys_t: demux descriptor
 *****************************************************************************/
struct demux_sys_t
{
    int             io_buffer_size;
    uint8_t        *io_buffer;

    AVInputFormat  *fmt;
    AVFormatContext *ic;

    int             i_tk;
    es_out_id_t     **tk;
67 68
    int64_t         *tk_pcr;
    int64_t         i_pcr;
69

70 71
    unsigned    i_ssa_order;

72 73
    int                i_attachments;
    input_attachment_t **attachments;
74 75 76

    /* Only one title with seekpoints possible atm. */
    input_title_t *p_title;
Gildas Bazin's avatar
 
Gildas Bazin committed
77 78 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
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
105
int OpenDemux( vlc_object_t *p_this )
Gildas Bazin's avatar
 
Gildas Bazin committed
106 107 108 109
{
    demux_t       *p_demux = (demux_t*)p_this;
    demux_sys_t   *p_sys;
    AVProbeData   pd;
110
    AVInputFormat *fmt = NULL;
111 112
    unsigned int  i;
    int64_t       i_start_time = -1;
113
    bool          b_can_seek;
114
    char         *psz_url;
115
    int           error;
Gildas Bazin's avatar
 
Gildas Bazin committed
116

117 118 119 120 121 122 123 124
    if( p_demux->psz_file )
        psz_url = strdup( p_demux->psz_file );
    else
    {
        if( asprintf( &psz_url, "%s://%s", p_demux->psz_access, p_demux->psz_location ) == -1)
            return VLC_ENOMEM;
    }
    msg_Dbg( p_demux, "trying url: %s", psz_url );
Gildas Bazin's avatar
 
Gildas Bazin committed
125
    /* Init Probe data */
126
    pd.filename = psz_url;
127
    if( ( pd.buf_size = stream_Peek( p_demux->s, (const uint8_t**)&pd.buf, 2048 + 213 ) ) <= 0 )
Gildas Bazin's avatar
 
Gildas Bazin committed
128
    {
129
        free( psz_url );
Gildas Bazin's avatar
 
Gildas Bazin committed
130 131 132
        msg_Warn( p_demux, "cannot peek" );
        return VLC_EGENERIC;
    }
133
    stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_can_seek );
Gildas Bazin's avatar
 
Gildas Bazin committed
134

135
    vlc_init_avformat(p_this);
Gildas Bazin's avatar
 
Gildas Bazin committed
136

137
    char *psz_format = var_InheritString( p_this, "avformat-format" );
138 139
    if( psz_format )
    {
140
        if( (fmt = av_find_input_format(psz_format)) )
141 142 143 144
            msg_Dbg( p_demux, "forcing format: %s", fmt->name );
        free( psz_format );
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
145
    /* Guess format */
146
    if( !fmt && !( fmt = av_probe_input_format( &pd, 1 ) ) )
Gildas Bazin's avatar
 
Gildas Bazin committed
147 148
    {
        msg_Dbg( p_demux, "couldn't guess format" );
149
        free( psz_url );
Gildas Bazin's avatar
 
Gildas Bazin committed
150 151 152
        return VLC_EGENERIC;
    }

153
    if( !p_demux->b_force )
Gildas Bazin's avatar
 
Gildas Bazin committed
154
    {
155 156 157 158 159
        static const char ppsz_blacklist[][16] = {
            /* Don't handle MPEG unless forced */
            "mpeg", "vcd", "vob", "mpegts",
            /* libavformat's redirector won't work */
            "redir", "sdp",
160 161
            /* Don't handle subtitles format */
            "ass", "srt", "microdvd",
162 163 164 165 166 167 168 169 170 171 172
            ""
        };

        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
173 174
    }

175 176 177 178 179
    /* Don't trigger false alarms on bin files */
    if( !p_demux->b_force && !strcmp( fmt->name, "psxstr" ) )
    {
        int i_len;

180 181 182 183 184
        if( !p_demux->psz_file )
        {
            free( psz_url );
            return VLC_EGENERIC;
        }
185

186
        i_len = strlen( p_demux->psz_file );
187 188 189 190 191
        if( i_len < 4 )
        {
            free( psz_url );
            return VLC_EGENERIC;
        }
192

193 194 195
        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" ) )
196
        {
197
            free( psz_url );
198 199 200 201
            return VLC_EGENERIC;
        }
    }

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

Gildas Bazin's avatar
 
Gildas Bazin committed
204 205 206 207
    /* Fill p_demux fields */
    p_demux->pf_demux = Demux;
    p_demux->pf_control = Control;
    p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
208
    p_sys->ic = 0;
Gildas Bazin's avatar
 
Gildas Bazin committed
209 210 211
    p_sys->fmt = fmt;
    p_sys->i_tk = 0;
    p_sys->tk = NULL;
212
    p_sys->tk_pcr = NULL;
213
    p_sys->i_ssa_order = 0;
214
    TAB_INIT( p_sys->i_attachments, p_sys->attachments);
215
    p_sys->p_title = NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
216 217 218 219

    /* Create I/O wrapper */
    p_sys->io_buffer_size = 32768;  /* FIXME */
    p_sys->io_buffer = malloc( p_sys->io_buffer_size );
220

221 222
    p_sys->ic = avformat_alloc_context();
    p_sys->ic->pb = avio_alloc_context( p_sys->io_buffer,
223
        p_sys->io_buffer_size, 0, p_demux, IORead, NULL, IOSeek );
224
    p_sys->ic->pb->seekable = b_can_seek ? AVIO_SEEKABLE_NORMAL : 0;
225
    error = avformat_open_input(&p_sys->ic, psz_url, p_sys->fmt, NULL);
226

227
    if( error < 0 )
Gildas Bazin's avatar
 
Gildas Bazin committed
228
    {
229 230
        msg_Err( p_demux, "Could not open %s: %s", psz_url,
                 vlc_strerror_c(AVUNERROR(error)) );
231
        p_sys->ic = NULL;
232
        free( psz_url );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
233
        CloseDemux( p_this );
Gildas Bazin's avatar
 
Gildas Bazin committed
234 235
        return VLC_EGENERIC;
    }
236
    free( psz_url );
Gildas Bazin's avatar
 
Gildas Bazin committed
237

238
#if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(26<<8)+0)
239
    char *psz_opts = var_InheritString( p_demux, "avformat-options" );
240 241
    AVDictionary *options[p_sys->ic->nb_streams ? p_sys->ic->nb_streams : 1];
    options[0] = NULL;
242 243
    unsigned int nb_streams = p_sys->ic->nb_streams;
    for (unsigned i = 1; i < nb_streams; i++)
244
        options[i] = NULL;
245 246
    if (psz_opts && *psz_opts) {
        options[0] = vlc_av_get_options(psz_opts);
247
        for (unsigned i = 1; i < nb_streams; i++) {
248 249 250 251 252 253
            av_dict_copy(&options[i], options[0], 0);
        }
    }
    free(psz_opts);
    vlc_avcodec_lock(); /* avformat calls avcodec behind our back!!! */
    error = avformat_find_stream_info( p_sys->ic, options );
254
    /* FIXME: what if nb_streams change after that call? */
255 256
    vlc_avcodec_unlock();
    AVDictionaryEntry *t = NULL;
Rafaël Carré's avatar
Rafaël Carré committed
257
    while ((t = av_dict_get(options[0], "", t, AV_DICT_IGNORE_SUFFIX))) {
258 259
        msg_Err( p_demux, "Unknown option \"%s\"", t->key );
    }
260
    av_dict_free(&options[0]);
261
    for (unsigned i = 1; i < nb_streams; i++) {
Rafaël Carré's avatar
Rafaël Carré committed
262 263
        av_dict_free(&options[i]);
    }
264
#else
265
    vlc_avcodec_lock(); /* avformat calls avcodec behind our back!!! */
266
    error = av_find_stream_info( p_sys->ic );
267
    vlc_avcodec_unlock();
268 269
#endif

270
    if( error < 0 )
Gildas Bazin's avatar
 
Gildas Bazin committed
271
    {
272 273
        msg_Warn( p_demux, "Could not find stream info: %s",
                  vlc_strerror_c(AVUNERROR(error)) );
Gildas Bazin's avatar
 
Gildas Bazin committed
274 275 276 277
    }

    for( i = 0; i < p_sys->ic->nb_streams; i++ )
    {
Laurent Aimar's avatar
Laurent Aimar committed
278 279 280
        AVStream *s = p_sys->ic->streams[i];
        AVCodecContext *cc = s->codec;

Gildas Bazin's avatar
 
Gildas Bazin committed
281 282 283
        es_out_id_t  *es;
        es_format_t  fmt;
        vlc_fourcc_t fcc;
284
        const char *psz_type = "unknown";
Gildas Bazin's avatar
 
Gildas Bazin committed
285

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
286
        if( !GetVlcFourcc( cc->codec_id, NULL, &fcc, NULL ) )
Gildas Bazin's avatar
 
Gildas Bazin committed
287 288
            fcc = VLC_FOURCC( 'u', 'n', 'd', 'f' );

289 290 291 292 293 294
#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 )
            continue;
#endif

Gildas Bazin's avatar
 
Gildas Bazin committed
295 296
        switch( cc->codec_type )
        {
297
        case AVMEDIA_TYPE_AUDIO:
Gildas Bazin's avatar
 
Gildas Bazin committed
298
            es_format_Init( &fmt, AUDIO_ES, fcc );
299
            fmt.i_original_fourcc = CodecTagToFourcc( cc->codec_tag );
300
            fmt.i_bitrate = cc->bit_rate;
Gildas Bazin's avatar
 
Gildas Bazin committed
301 302
            fmt.audio.i_channels = cc->channels;
            fmt.audio.i_rate = cc->sample_rate;
Alexis Ballier's avatar
Alexis Ballier committed
303
            fmt.audio.i_bitspersample = cc->bits_per_coded_sample;
Gildas Bazin's avatar
 
Gildas Bazin committed
304
            fmt.audio.i_blockalign = cc->block_align;
305
            psz_type = "audio";
Gildas Bazin's avatar
 
Gildas Bazin committed
306
            break;
307

308
        case AVMEDIA_TYPE_VIDEO:
Gildas Bazin's avatar
 
Gildas Bazin committed
309
            es_format_Init( &fmt, VIDEO_ES, fcc );
310
            fmt.i_original_fourcc = CodecTagToFourcc( cc->codec_tag );
311

312
            fmt.video.i_bits_per_pixel = cc->bits_per_coded_sample;
313
            /* Special case for raw video data */
314
            if( cc->codec_id == AV_CODEC_ID_RAWVIDEO )
315 316 317 318 319 320 321 322 323
            {
                msg_Dbg( p_demux, "raw video, pixel format: %i", cc->pix_fmt );
                if( GetVlcChroma( &fmt.video, cc->pix_fmt ) != VLC_SUCCESS)
                {
                    msg_Err( p_demux, "was unable to find a FourCC match for raw video" );
                }
                else
                    fmt.i_codec = fmt.video.i_chroma;
            }
324
            /* We need this for the h264 packetizer */
325
            else if( cc->codec_id == AV_CODEC_ID_H264 && ( p_sys->fmt == av_find_input_format("flv") ||
326
                p_sys->fmt == av_find_input_format("matroska") || p_sys->fmt == av_find_input_format("mp4") ) )
327
                fmt.i_original_fourcc = VLC_FOURCC( 'a', 'v', 'c', '1' );
328

Gildas Bazin's avatar
 
Gildas Bazin committed
329 330
            fmt.video.i_width = cc->width;
            fmt.video.i_height = cc->height;
331 332 333 334 335 336 337 338 339 340

            char const *kRotateKey = "rotate";
            AVDictionaryEntry *rotation = av_dict_get(s->metadata, kRotateKey, NULL, 0);

            if( rotation )
            {

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

                if (angle > 45 && angle < 135)
341
                    fmt.video.orientation = ORIENT_ROTATED_90;
342 343 344 345 346

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

                else if (angle > 225 && angle < 315)
347
                    fmt.video.orientation = ORIENT_ROTATED_270;
348 349 350 351 352

                else
                    fmt.video.orientation = ORIENT_NORMAL;
            }

353 354 355 356 357 358 359
#if LIBAVCODEC_VERSION_MAJOR < 54
            if( cc->palctrl )
            {
                fmt.video.p_palette = malloc( sizeof(video_palette_t) );
                *fmt.video.p_palette = *(video_palette_t *)cc->palctrl;
            }
#else
360
# warning FIXME: implement palette transmission
361
#endif
362
            psz_type = "video";
363
            fmt.video.i_frame_rate = cc->time_base.den;
364
            fmt.video.i_frame_rate_base = cc->time_base.num * __MAX( cc->ticks_per_frame, 1 );
Wills Wang's avatar
Wills Wang committed
365
            fmt.video.i_sar_num = s->sample_aspect_ratio.num;
366 367 368 369
            if (s->sample_aspect_ratio.num > 0)
                fmt.video.i_sar_den = s->sample_aspect_ratio.den;
            else
                fmt.video.i_sar_den = 0;
Gildas Bazin's avatar
 
Gildas Bazin committed
370
            break;
371

372
        case AVMEDIA_TYPE_SUBTITLE:
373
            es_format_Init( &fmt, SPU_ES, fcc );
374
            fmt.i_original_fourcc = CodecTagToFourcc( cc->codec_tag );
375
            if( strncmp( p_sys->ic->iformat->name, "matroska", 8 ) == 0 &&
376
                cc->codec_id == AV_CODEC_ID_DVD_SUBTITLE &&
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
                cc->extradata != NULL &&
                cc->extradata_size > 0 )
            {
                char *psz_start;
                char *psz_buf = malloc( cc->extradata_size + 1);
                if( psz_buf != NULL )
                {
                    memcpy( psz_buf, cc->extradata , cc->extradata_size );
                    psz_buf[cc->extradata_size] = '\0';

                    psz_start = strstr( psz_buf, "size:" );
                    if( psz_start &&
                        vobsub_size_parse( psz_start,
                                           &fmt.subs.spu.i_original_frame_width,
                                           &fmt.subs.spu.i_original_frame_height ) == VLC_SUCCESS )
                    {
                        msg_Dbg( p_demux, "original frame size: %dx%d",
                                 fmt.subs.spu.i_original_frame_width,
                                 fmt.subs.spu.i_original_frame_height );
                    }
                    else
                    {
                        msg_Warn( p_demux, "reading original frame size failed" );
                    }

                    psz_start = strstr( psz_buf, "palette:" );
                    if( psz_start &&
                        vobsub_palette_parse( psz_start, &fmt.subs.spu.palette[1] ) == VLC_SUCCESS )
                    {
                        fmt.subs.spu.palette[0] =  0xBeef;
                        msg_Dbg( p_demux, "vobsub palette read" );
                    }
                    else
                    {
                        msg_Warn( p_demux, "reading original palette failed" );
                    }
                    free( psz_buf );
                }
            }

417
            psz_type = "subtitle";
418
            break;
419

Gildas Bazin's avatar
 
Gildas Bazin committed
420
        default:
421
            es_format_Init( &fmt, UNKNOWN_ES, 0 );
422
            fmt.i_original_fourcc = CodecTagToFourcc( cc->codec_tag );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
423
#ifdef HAVE_AVUTIL_CODEC_ATTACHMENT
424
            if( cc->codec_type == AVMEDIA_TYPE_ATTACHMENT )
425 426
            {
                input_attachment_t *p_attachment;
427

428
                psz_type = "attachment";
429
                if( cc->codec_id == AV_CODEC_ID_TTF )
430
                {
431
                    AVDictionaryEntry *filename = av_dict_get( s->metadata, "filename", NULL, 0 );
432 433 434 435 436 437 438 439
                    if( filename && filename->value )
                    {
                        p_attachment = vlc_input_attachment_New(
                                filename->value, "application/x-truetype-font",
                                NULL, cc->extradata, (int)cc->extradata_size );
                        TAB_APPEND( p_sys->i_attachments, p_sys->attachments,
                                p_attachment );
                    }
440
                }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
441
                else msg_Warn( p_demux, "unsupported attachment type (%u) in avformat demux", cc->codec_id );
442
            }
443
            else
444
#endif
445 446 447
            {
                if( cc->codec_type == AVMEDIA_TYPE_DATA )
                    psz_type = "data";
448

449
                msg_Warn( p_demux, "unsupported track type (%u:%u) in avformat demux", cc->codec_type, cc->codec_id );
450
            }
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
451
            break;
Gildas Bazin's avatar
 
Gildas Bazin committed
452
        }
453

454
        AVDictionaryEntry *language = av_dict_get( s->metadata, "language", NULL, 0 );
455 456 457
        if ( language && language->value )
            fmt.psz_language = strdup( language->value );

458
        if( s->disposition & AV_DISPOSITION_DEFAULT )
459
            fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN + 1000;
460

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
461
#ifdef HAVE_AVUTIL_CODEC_ATTACHMENT
462
        if( cc->codec_type != AVMEDIA_TYPE_ATTACHMENT )
463
#endif
464
        if( cc->codec_type != AVMEDIA_TYPE_DATA )
465
        {
466
            const bool    b_ogg = !strcmp( p_sys->fmt->name, "ogg" );
467 468 469
            const uint8_t *p_extra = cc->extradata;
            unsigned      i_extra  = cc->extradata_size;

470
            if( cc->codec_id == AV_CODEC_ID_THEORA && b_ogg )
471 472
            {
                unsigned pi_size[3];
Pierre Ynard's avatar
Pierre Ynard committed
473
                const void *pp_data[3];
474 475 476 477 478 479
                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
480
                    pp_data[i_count] = &p_extra[2];
481 482 483 484 485 486 487 488 489 490 491 492 493
                    if( i_extra < pi_size[i_count] + 2 )
                        break;

                    p_extra += 2 + pi_size[i_count];
                    i_extra -= 2 + pi_size[i_count];
                }
                if( i_count > 0 && xiph_PackHeaders( &fmt.i_extra, &fmt.p_extra,
                                                     pi_size, pp_data, i_count ) )
                {
                    fmt.i_extra = 0;
                    fmt.p_extra = NULL;
                }
            }
494
            else if( cc->codec_id == AV_CODEC_ID_SPEEX && b_ogg )
495
            {
Pierre Ynard's avatar
Pierre Ynard committed
496
                const uint8_t p_dummy_comment[] = {
497 498 499 500
                    0, 0, 0, 0,
                    0, 0, 0, 0,
                };
                unsigned pi_size[2];
Pierre Ynard's avatar
Pierre Ynard committed
501
                const void *pp_data[2];
502 503

                pi_size[0] = i_extra;
Pierre Ynard's avatar
Pierre Ynard committed
504
                pp_data[0] = p_extra;
505 506 507 508 509 510 511 512 513 514 515

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

                if( pi_size[0] > 0 && xiph_PackHeaders( &fmt.i_extra, &fmt.p_extra,
                                                        pi_size, pp_data, 2 ) )
                {
                    fmt.i_extra = 0;
                    fmt.p_extra = NULL;
                }
            }
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
#if LIBAVCODEC_VERSION_CHECK( 54, 29, 0, 17, 101 )
            else if( cc->codec_id == AV_CODEC_ID_OPUS )
            {
                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;

                if( pi_size[0] > 0 && xiph_PackHeaders( &fmt.i_extra, &fmt.p_extra,
                                                        pi_size, pp_data, 2 ) )
                {
                    fmt.i_extra = 0;
                    fmt.p_extra = NULL;
                }
            }
#endif
544 545 546 547 548 549 550 551 552
            else if( cc->extradata_size > 0 )
            {
                fmt.p_extra = malloc( i_extra );
                if( fmt.p_extra )
                {
                    fmt.i_extra = i_extra;
                    memcpy( fmt.p_extra, p_extra, i_extra );
                }
            }
553 554 555 556 557
            es = es_out_Add( p_demux->out, &fmt );
            if( s->disposition & AV_DISPOSITION_DEFAULT )
                es_out_Control( p_demux->out, ES_OUT_SET_ES_DEFAULT, es );
            es_format_Clean( &fmt );

558 559
            msg_Dbg( p_demux, "adding es: %s codec = %4.4s (%d)",
                     psz_type, (char*)&fcc, cc->codec_id  );
560
            TAB_APPEND( p_sys->i_tk, p_sys->tk, es );
561
        }
Gildas Bazin's avatar
 
Gildas Bazin committed
562
    }
563 564
    p_sys->tk_pcr = calloc( p_sys->i_tk, sizeof(*p_sys->tk_pcr) );

565 566
    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
567 568 569 570

    msg_Dbg( p_demux, "AVFormat supported stream" );
    msg_Dbg( p_demux, "    - format = %s (%s)",
             p_sys->fmt->name, p_sys->fmt->long_name );
571
    msg_Dbg( p_demux, "    - start time = %"PRId64, i_start_time );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
572
    msg_Dbg( p_demux, "    - duration = %"PRId64,
573
             ( p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE ) ?
Gildas Bazin's avatar
 
Gildas Bazin committed
574
             p_sys->ic->duration * 1000000 / AV_TIME_BASE : -1 );
Gildas Bazin's avatar
 
Gildas Bazin committed
575

576
    if( p_sys->ic->nb_chapters > 0 )
577
    {
578
        p_sys->p_title = vlc_input_title_New();
579 580 581
        p_sys->p_title->i_length = p_sys->ic->duration * 1000000 / AV_TIME_BASE;
    }

582 583 584 585
    for( i = 0; i < p_sys->ic->nb_chapters; i++ )
    {
        seekpoint_t *s = vlc_seekpoint_New();

586
        AVDictionaryEntry *title = av_dict_get( p_sys->ic->metadata, "title", NULL, 0);
587
        if( title && title->value )
588
        {
589
            s->psz_name = strdup( title->value );
590 591 592 593 594 595 596 597 598 599
            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 );
    }

600
    ResetTime( p_demux, 0 );
Gildas Bazin's avatar
 
Gildas Bazin committed
601 602 603 604 605 606
    return VLC_SUCCESS;
}

/*****************************************************************************
 * Close
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
607
void CloseDemux( vlc_object_t *p_this )
Gildas Bazin's avatar
 
Gildas Bazin committed
608 609 610 611
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys = p_demux->p_sys;

612
    FREENULL( p_sys->tk );
613
    free( p_sys->tk_pcr );
614

615
    if( p_sys->ic )
616 617
    {
        av_free( p_sys->ic->pb );
618
#if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(26<<8)+0)
619 620 621 622
        avformat_close_input( &p_sys->ic );
#else
        av_close_input_stream( p_sys->ic );
#endif
623
    }
624

625 626 627 628
    for( int i = 0; i < p_sys->i_attachments; i++ )
        free( p_sys->attachments[i] );
    TAB_CLEAN( p_sys->i_attachments, p_sys->attachments);

629 630 631
    if( p_sys->p_title )
        vlc_input_title_Delete( p_sys->p_title );

632
    free( p_sys->io_buffer );
Gildas Bazin's avatar
 
Gildas Bazin committed
633 634 635 636 637 638 639 640 641 642 643
    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
644
    int64_t     i_start_time;
Gildas Bazin's avatar
 
Gildas Bazin committed
645 646

    /* Read a frame */
647 648
    int i_av_ret = av_read_frame( p_sys->ic, &pkt );
    if( i_av_ret )
Gildas Bazin's avatar
 
Gildas Bazin committed
649
    {
650 651 652 653
        /* Avoid EOF if av_read_frame returns AVERROR(EAGAIN) */
        if( i_av_ret == AVERROR(EAGAIN) )
            return 1;

Gildas Bazin's avatar
 
Gildas Bazin committed
654 655 656 657 658 659 660
        return 0;
    }
    if( pkt.stream_index < 0 || pkt.stream_index >= p_sys->i_tk )
    {
        av_free_packet( &pkt );
        return 1;
    }
661
    const AVStream *p_stream = p_sys->ic->streams[pkt.stream_index];
662 663 664 665 666 667
    if( p_stream->time_base.den <= 0 )
    {
        msg_Warn( p_demux, "Invalid time base for the stream %d", pkt.stream_index );
        av_free_packet( &pkt );
        return 1;
    }
668
    if( p_stream->codec->codec_id == AV_CODEC_ID_SSA )
Gildas Bazin's avatar
 
Gildas Bazin committed
669
    {
670 671
        p_frame = BuildSsaFrame( &pkt, p_sys->i_ssa_order++ );
        if( !p_frame )
672 673
        {
            av_free_packet( &pkt );
674
            return 1;
675
        }
676 677 678
    }
    else
    {
679
        if( ( p_frame = block_Alloc( pkt.size ) ) == NULL )
680 681
        {
            av_free_packet( &pkt );
682
            return 0;
683
        }
684
        memcpy( p_frame->p_buffer, pkt.data, pkt.size );
Gildas Bazin's avatar
 
Gildas Bazin committed
685
    }
Gildas Bazin's avatar
 
Gildas Bazin committed
686

687
    if( pkt.flags & AV_PKT_FLAG_KEY )
688 689
        p_frame->i_flags |= BLOCK_FLAG_TYPE_I;

690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
    /* 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);
        i_start_time = q.quot * (int64_t)1000000 + q.rem * (int64_t)1000000 / AV_TIME_BASE;
    }
    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 );
        p_frame->i_dts = q.quot * (int64_t)1000000 *
            p_stream->time_base.num + q.rem * (int64_t)1000000 *
            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 );
        p_frame->i_pts = q.quot * (int64_t)1000000 *
            p_stream->time_base.num + q.rem * (int64_t)1000000 *
            p_stream->time_base.num /
            p_stream->time_base.den - i_start_time + VLC_TS_0;
    }
721
    if( pkt.duration > 0 && p_frame->i_length <= 0 )
722
        p_frame->i_length = pkt.duration * 1000000 *
723
            p_stream->time_base.num /
724
            p_stream->time_base.den;
Gildas Bazin's avatar
 
Gildas Bazin committed
725

726
    if( pkt.dts != (int64_t)AV_NOPTS_VALUE && pkt.dts == pkt.pts &&
727
        p_stream->codec->codec_type == AVMEDIA_TYPE_VIDEO )
728 729 730
    {
        /* Add here notoriously bugged file formats/samples regarding PTS */
        if( !strcmp( p_sys->fmt->name, "flv" ) )
731
            p_frame->i_pts = VLC_TS_INVALID;
732
    }
733
#ifdef AVFORMAT_DEBUG
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
734
    msg_Dbg( p_demux, "tk[%d] dts=%"PRId64" pts=%"PRId64,
Gildas Bazin's avatar
 
Gildas Bazin committed
735
             pkt.stream_index, p_frame->i_dts, p_frame->i_pts );
736
#endif
737 738
    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
739

740 741 742
    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
743

744 745 746 747 748 749 750 751 752 753 754
    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
755 756 757
    }

    es_out_Send( p_demux->out, p_sys->tk[pkt.stream_index], p_frame );
758

Gildas Bazin's avatar
 
Gildas Bazin committed
759 760 761 762
    av_free_packet( &pkt );
    return 1;
}

763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
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;
    }
}

785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
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 )
        i_time = 1;

    p_sys->i_pcr = i_time;
    for( int i = 0; i < p_sys->i_tk; i++ )
        p_sys->tk_pcr[i] = i_time;

    if( i_time > VLC_TS_INVALID )
    {
        es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_time );
        UpdateSeekPoint( p_demux, i_time );
    }
}

805 806 807 808 809 810
static block_t *BuildSsaFrame( const AVPacket *p_pkt, unsigned i_order )
{
    if( p_pkt->size <= 0 )
        return NULL;

    char buffer[256];
811
    const size_t i_buffer_size = __MIN( (int)sizeof(buffer) - 1, p_pkt->size );
812 813 814 815 816 817 818 819 820 821 822
    memcpy( buffer, p_pkt->data, i_buffer_size );
    buffer[i_buffer_size] = '\0';

    /* */
    int i_layer;
    int h0, m0, s0, c0;
    int h1, m1, s1, c1;
    int i_position = 0;
    if( sscanf( buffer, "Dialogue: %d,%d:%d:%d.%d,%d:%d:%d.%d,%n", &i_layer,
                &h0, &m0, &s0, &c0, &h1, &m1, &s1, &c1, &i_position ) < 9 )
        return NULL;
823
    if( i_position <= 0 || (unsigned)i_position >= i_buffer_size )
824 825 826 827 828 829
        return NULL;

    char *p;
    if( asprintf( &p, "%u,%d,%.*s", i_order, i_layer, p_pkt->size - i_position, p_pkt->data + i_position ) < 0 )
        return NULL;

830
    block_t *p_frame = block_heap_Alloc( p, strlen(p) + 1 );
831
    if( p_frame )
Rémi Duraffort's avatar
Rémi Duraffort committed
832
        p_frame->i_length = CLOCK_FREQ * ((h1-h0) * 3600 +
833 834 835 836 837 838
                                          (m1-m0) * 60 +
                                          (s1-s0) * 1) +
                            CLOCK_FREQ * (c1-c0) / 100;
    return p_frame;
}

Gildas Bazin's avatar
 
Gildas Bazin committed
839 840 841 842 843 844
/*****************************************************************************
 * Control:
 *****************************************************************************/
static int Control( demux_t *p_demux, int i_query, va_list args )
{
    demux_sys_t *p_sys = p_demux->p_sys;
845
    const int64_t i_start_time = p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE ? p_sys->ic->start_time : 0;
Gildas Bazin's avatar
 
Gildas Bazin committed
846 847 848 849 850 851
    double f, *pf;
    int64_t i64, *pi64;

    switch( i_query )
    {
        case DEMUX_GET_POSITION:
852
            pf = (double*) va_arg( args, double* ); *pf = 0.0;
Gildas Bazin's avatar
 
Gildas Bazin committed
853 854 855
            i64 = stream_Size( p_demux->s );
            if( i64 > 0 )
            {
856 857
                double current = stream_Tell( p_demux->s );
                *pf = current / (double)i64;
Gildas Bazin's avatar
 
Gildas Bazin committed
858
            }
859

860
            if( (p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE) && (p_sys->i_pcr > 0) )
Gildas Bazin's avatar
 
Gildas Bazin committed
861
            {
862
                *pf = (double)p_sys->i_pcr / (double)p_sys->ic->duration;
Gildas Bazin's avatar
 
Gildas Bazin committed
863
            }
864

Gildas Bazin's avatar
 
Gildas Bazin committed
865 866 867 868
            return VLC_SUCCESS;

        case DEMUX_SET_POSITION:
            f = (double) va_arg( args, double );
869
            i64 = p_sys->ic->duration * f + i_start_time;
Gildas Bazin's avatar
 
Gildas Bazin committed
870

871
            msg_Warn( p_demux, "DEMUX_SET_POSITION: %"PRId64, i64 );
Gildas Bazin's avatar
 
Gildas Bazin committed
872

873 874 875 876 877 878 879
            /* If we have a duration, we prefer to seek by time
               but if we don't, or if the seek fails, try BYTE seeking */
            if( p_sys->ic->duration == (int64_t)AV_NOPTS_VALUE ||
                (av_seek_frame( p_sys->ic, -1, i64, AVSEEK_FLAG_BACKWARD ) < 0) )
            {
                int64_t i_size = stream_Size( p_demux->s );
                i64 = (i_size * f);
880

881 882 883 884 885 886 887 888 889
                msg_Warn( p_demux, "DEMUX_SET_BYTE_POSITION: %"PRId64, i64 );
                if( av_seek_frame( p_sys->ic, -1, i64, AVSEEK_FLAG_BYTE ) < 0 )
                    return VLC_EGENERIC;

                ResetTime( p_demux, -1 );
            }
            else
            {
                ResetTime( p_demux, i64 - i_start_time );
Gildas Bazin's avatar
 
Gildas Bazin committed
890 891 892
            }
            return VLC_SUCCESS;

893 894
        case DEMUX_GET_LENGTH:
            pi64 = (int64_t*)va_arg( args, int64_t * );
895
            if( p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE )
896 897 898
                *pi64 = p_sys->ic->duration * 1000000 / AV_TIME_BASE;
            else
                *pi64 = 0;
899 900
            return VLC_SUCCESS;

Gildas Bazin's avatar
 
Gildas Bazin committed
901 902 903 904 905 906
        case DEMUX_GET_TIME:
            pi64 = (int64_t*)va_arg( args, int64_t * );
            *pi64 = p_sys->i_pcr;
            return VLC_SUCCESS;

        case DEMUX_SET_TIME:
907
        {
Gildas Bazin's avatar
 
Gildas Bazin committed
908
            i64 = (int64_t)va_arg( args, int64_t );
909
            i64 = i64 *AV_TIME_BASE / 1000000 + i_start_time;
Gildas Bazin's avatar
 
Gildas Bazin committed
910

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
911
            msg_Warn( p_demux, "DEMUX_SET_TIME: %"PRId64, i64 );
Gildas Bazin's avatar
 
Gildas Bazin committed
912

913
            if( av_seek_frame( p_sys->ic, -1, i64, AVSEEK_FLAG_BACKWARD ) < 0 )
Gildas Bazin's avatar
 
Gildas Bazin committed
914 915 916
            {
                return VLC_EGENERIC;
            }
917
            ResetTime( p_demux, i64 - i_start_time );
Gildas Bazin's avatar
 
Gildas Bazin committed
918
            return VLC_SUCCESS;
919
        }
Gildas Bazin's avatar
 
Gildas Bazin committed
920

921 922 923 924 925 926 927 928
        case DEMUX_HAS_UNSUPPORTED_META:
        {
            bool *pb_bool = (bool*)va_arg( args, bool* );
            *pb_bool = true;
            return VLC_SUCCESS;
        }


929 930
        case DEMUX_GET_META:
        {
931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959
            static const char names[][10] = {
                [vlc_meta_Title] = "title",
                [vlc_meta_Artist] = "artist",
                [vlc_meta_Genre] = "genre",
                [vlc_meta_Copyright] = "copyright",
                [vlc_meta_Album] = "album",
                //[vlc_meta_TrackNumber] -- TODO: parse number/total value
                [vlc_meta_Description] = "comment",
                //[vlc_meta_Rating]
                [vlc_meta_Date] = "date",
                [vlc_meta_Setting] = "encoder",
                //[vlc_meta_URL]
                [vlc_meta_Language] = "language",
                //[vlc_meta_NowPlaying]
                [vlc_meta_Publisher] = "publisher",
                [vlc_meta_EncodedBy] = "encoded_by",
                //[vlc_meta_ArtworkURL]
                //[vlc_meta_TrackID]
                //[vlc_meta_TrackTotal]
            };
            vlc_meta_t *p_meta = va_arg( args, vlc_meta_t * );
            AVDictionary *dict = p_sys->ic->metadata;

            for( unsigned i = 0; i < sizeof(names) / sizeof(*names); i++)
            {
                if( !names[i][0] )
                    continue;

                AVDictionaryEntry *e = av_dict_get( dict, names[i], NULL, 0 );
960
                if( e != NULL && e->value != NULL && IsUTF8(e->value) )
961 962
                    vlc_meta_Set( p_meta, i, e->value );
            }
963 964 965
            return VLC_SUCCESS;
        }

966 967 968 969 970 971 972 973 974 975 976
        case DEMUX_GET_ATTACHMENTS:
        {
            input_attachment_t ***ppp_attach =
                (input_attachment_t***)va_arg( args, input_attachment_t*** );
            int *pi_int = (int*)va_arg( args, int * );
            int i;

            if( p_sys->i_attachments <= 0 )
                return VLC_EGENERIC;

            *pi_int = p_sys->i_attachments;;
Rémi Duraffort's avatar
Rémi Duraffort committed
977
            *ppp_attach = malloc( sizeof(input_attachment_t*) * p_sys->i_attachments );