]> git.sesse.net Git - vlc/blob - modules/demux/avformat/demux.c
Merge branch 'master' into lpcm_encoder
[vlc] / modules / demux / avformat / demux.c
1 /*****************************************************************************
2  * demux.c: demuxer using ffmpeg (libavformat).
3  *****************************************************************************
4  * Copyright (C) 2004-2009 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Gildas Bazin <gbazin@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vlc_common.h>
34 #include <vlc_demux.h>
35 #include <vlc_stream.h>
36 #include <vlc_meta.h>
37 #include <vlc_input.h>
38 #include <vlc_charset.h>
39 #include <vlc_avcodec.h>
40
41 /* ffmpeg header */
42 #if defined(HAVE_LIBAVFORMAT_AVFORMAT_H)
43 #   include <libavformat/avformat.h>
44 #elif defined(HAVE_FFMPEG_AVFORMAT_H)
45 #   include <ffmpeg/avformat.h>
46 #endif
47
48 #include "../../codec/avcodec/avcodec.h"
49 #include "../../codec/avcodec/chroma.h"
50 #include "avformat.h"
51 #include "../xiph.h"
52 #include "../vobsub.h"
53
54 //#define AVFORMAT_DEBUG 1
55
56 /* Version checking */
57 #if defined(HAVE_FFMPEG_AVFORMAT_H) || defined(HAVE_LIBAVFORMAT_AVFORMAT_H)
58
59 #if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(50<<8)+0) )
60 #   define HAVE_FFMPEG_CODEC_ATTACHMENT 1
61 #endif
62
63 /*****************************************************************************
64  * demux_sys_t: demux descriptor
65  *****************************************************************************/
66 struct demux_sys_t
67 {
68     ByteIOContext   io;
69     int             io_buffer_size;
70     uint8_t        *io_buffer;
71
72     AVInputFormat  *fmt;
73     AVFormatContext *ic;
74     URLContext     url;
75     URLProtocol    prot;
76
77     int             i_tk;
78     es_out_id_t     **tk;
79
80     int64_t     i_pcr;
81     int64_t     i_pcr_inc;
82     int         i_pcr_tk;
83
84     unsigned    i_ssa_order;
85
86     int                i_attachments;
87     input_attachment_t **attachments;
88
89     /* Only one title with seekpoints possible atm. */
90     input_title_t *p_title;
91 };
92
93 /*****************************************************************************
94  * Local prototypes
95  *****************************************************************************/
96 static int Demux  ( demux_t *p_demux );
97 static int Control( demux_t *p_demux, int i_query, va_list args );
98
99 static int IORead( void *opaque, uint8_t *buf, int buf_size );
100 static int64_t IOSeek( void *opaque, int64_t offset, int whence );
101
102 static block_t *BuildSsaFrame( const AVPacket *p_pkt, unsigned i_order );
103 static void UpdateSeekPoint( demux_t *p_demux, int64_t i_time );
104
105 /*****************************************************************************
106  * Open
107  *****************************************************************************/
108 int OpenDemux( vlc_object_t *p_this )
109 {
110     demux_t       *p_demux = (demux_t*)p_this;
111     demux_sys_t   *p_sys;
112     AVProbeData   pd;
113     AVInputFormat *fmt;
114     unsigned int  i;
115     int64_t       i_start_time = -1;
116     bool          b_can_seek;
117     char         *psz_url;
118
119     if( p_demux->psz_file )
120         psz_url = strdup( p_demux->psz_file );
121     else
122     {
123         if( asprintf( &psz_url, "%s://%s", p_demux->psz_access, p_demux->psz_location ) == -1)
124             return VLC_ENOMEM;
125     }
126     msg_Dbg( p_demux, "trying url: %s", psz_url );
127     /* Init Probe data */
128     pd.filename = psz_url;
129     if( ( pd.buf_size = stream_Peek( p_demux->s, &pd.buf, 2048 + 213 ) ) <= 0 )
130     {
131         free( psz_url );
132         msg_Warn( p_demux, "cannot peek" );
133         return VLC_EGENERIC;
134     }
135
136     vlc_avcodec_lock();
137     av_register_all(); /* Can be called several times */
138     vlc_avcodec_unlock();
139
140     /* Guess format */
141     if( !( fmt = av_probe_input_format( &pd, 1 ) ) )
142     {
143         msg_Dbg( p_demux, "couldn't guess format" );
144         free( psz_url );
145         return VLC_EGENERIC;
146     }
147
148     /* Don't try to handle MPEG unless forced */
149     if( !p_demux->b_force &&
150         ( !strcmp( fmt->name, "mpeg" ) ||
151           !strcmp( fmt->name, "vcd" ) ||
152           !strcmp( fmt->name, "vob" ) ||
153           !strcmp( fmt->name, "mpegts" ) ||
154           /* libavformat's redirector won't work */
155           !strcmp( fmt->name, "redir" ) ||
156           !strcmp( fmt->name, "sdp" ) ) )
157     {
158         free( psz_url );
159         return VLC_EGENERIC;
160     }
161
162     /* Don't trigger false alarms on bin files */
163     if( !p_demux->b_force && !strcmp( fmt->name, "psxstr" ) )
164     {
165         int i_len;
166
167         if( !p_demux->psz_file )
168         {
169             free( psz_url );
170             return VLC_EGENERIC;
171         }
172
173         i_len = strlen( p_demux->psz_file );
174         if( i_len < 4 )
175         {
176             free( psz_url );
177             return VLC_EGENERIC;
178         }
179
180         if( strcasecmp( &p_demux->psz_file[i_len - 4], ".str" ) &&
181             strcasecmp( &p_demux->psz_file[i_len - 4], ".xai" ) &&
182             strcasecmp( &p_demux->psz_file[i_len - 3], ".xa" ) )
183         {
184             free( psz_url );
185             return VLC_EGENERIC;
186         }
187     }
188
189     msg_Dbg( p_demux, "detected format: %s", fmt->name );
190
191     /* Fill p_demux fields */
192     p_demux->pf_demux = Demux;
193     p_demux->pf_control = Control;
194     p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
195     p_sys->ic = 0;
196     p_sys->fmt = fmt;
197     p_sys->i_tk = 0;
198     p_sys->tk = NULL;
199     p_sys->i_pcr_tk = -1;
200     p_sys->i_pcr = -1;
201     p_sys->i_ssa_order = 0;
202     TAB_INIT( p_sys->i_attachments, p_sys->attachments);
203     p_sys->p_title = NULL;
204
205     /* Create I/O wrapper */
206     p_sys->io_buffer_size = 32768;  /* FIXME */
207     p_sys->io_buffer = malloc( p_sys->io_buffer_size );
208     p_sys->url.priv_data = p_demux;
209     p_sys->url.prot = &p_sys->prot;
210     p_sys->url.prot->name = "VLC I/O wrapper";
211     p_sys->url.prot->url_open = 0;
212     p_sys->url.prot->url_read =
213                     (int (*) (URLContext *, unsigned char *, int))IORead;
214     p_sys->url.prot->url_write = 0;
215     p_sys->url.prot->url_seek =
216                     (int64_t (*) (URLContext *, int64_t, int))IOSeek;
217     p_sys->url.prot->url_close = 0;
218     p_sys->url.prot->next = 0;
219     init_put_byte( &p_sys->io, p_sys->io_buffer, p_sys->io_buffer_size,
220                    0, &p_sys->url, IORead, NULL, IOSeek );
221
222     stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_can_seek );
223     if( !b_can_seek )
224     {
225        /* Tell avformat that input is stream, so it doesn't get stuck
226        when trying av_find_stream_info() trying to seek all the wrong places
227        init_put_byte defaults io.is_streamed=0, so thats why we set them after it
228        */
229        p_sys->url.is_streamed = 1;
230        p_sys->io.is_streamed = 1;
231     }
232
233
234     /* Open it */
235     if( av_open_input_stream( &p_sys->ic, &p_sys->io, psz_url,
236                               p_sys->fmt, NULL ) )
237     {
238         msg_Err( p_demux, "av_open_input_stream failed" );
239         free( psz_url );
240         CloseDemux( p_this );
241         return VLC_EGENERIC;
242     }
243     free( psz_url );
244     psz_url = NULL;
245
246     vlc_avcodec_lock(); /* avformat calls avcodec behind our back!!! */
247     if( av_find_stream_info( p_sys->ic ) < 0 )
248     {
249         msg_Warn( p_demux, "av_find_stream_info failed" );
250     }
251     vlc_avcodec_unlock();
252
253     for( i = 0; i < p_sys->ic->nb_streams; i++ )
254     {
255         AVStream *s = p_sys->ic->streams[i];
256         AVCodecContext *cc = s->codec;
257
258         es_out_id_t  *es;
259         es_format_t  fmt;
260         vlc_fourcc_t fcc;
261         const char *psz_type = "unknown";
262
263         if( !GetVlcFourcc( cc->codec_id, NULL, &fcc, NULL ) )
264             fcc = VLC_FOURCC( 'u', 'n', 'd', 'f' );
265
266         switch( cc->codec_type )
267         {
268         case CODEC_TYPE_AUDIO:
269             es_format_Init( &fmt, AUDIO_ES, fcc );
270             fmt.i_bitrate = cc->bit_rate;
271             fmt.audio.i_channels = cc->channels;
272             fmt.audio.i_rate = cc->sample_rate;
273             fmt.audio.i_bitspersample = cc->bits_per_coded_sample;
274             fmt.audio.i_blockalign = cc->block_align;
275             psz_type = "audio";
276             break;
277
278         case CODEC_TYPE_VIDEO:
279             es_format_Init( &fmt, VIDEO_ES, fcc );
280
281             /* Special case for raw video data */
282             if( cc->codec_id == CODEC_ID_RAWVIDEO )
283             {
284                 msg_Dbg( p_demux, "raw video, pixel format: %i", cc->pix_fmt );
285                 if( GetVlcChroma( &fmt.video, cc->pix_fmt ) != VLC_SUCCESS)
286                 {
287                     msg_Err( p_demux, "was unable to find a FourCC match for raw video" );
288                 }
289                 else
290                     fmt.i_codec = fmt.video.i_chroma;
291             }
292             /* We need this for the h264 packetizer */
293             else if( cc->codec_id == CODEC_ID_H264 && ( !strcmp( p_sys->fmt->name, "flv" ) ||
294                 !strcmp( p_sys->fmt->name, "matroska" ) || !strcmp( p_sys->fmt->name, "mp4" ) ) )
295                 fmt.i_original_fourcc = VLC_FOURCC( 'a', 'v', 'c', '1' );
296
297             fmt.video.i_width = cc->width;
298             fmt.video.i_height = cc->height;
299             if( cc->palctrl )
300             {
301                 fmt.video.p_palette = malloc( sizeof(video_palette_t) );
302                 *fmt.video.p_palette = *(video_palette_t *)cc->palctrl;
303             }
304             psz_type = "video";
305             fmt.video.i_frame_rate = cc->time_base.den;
306             fmt.video.i_frame_rate_base = cc->time_base.num * __MAX( cc->ticks_per_frame, 1 );
307             break;
308
309         case CODEC_TYPE_SUBTITLE:
310             es_format_Init( &fmt, SPU_ES, fcc );
311             if( strncmp( p_sys->ic->iformat->name, "matroska", 8 ) == 0 &&
312                 cc->codec_id == CODEC_ID_DVD_SUBTITLE &&
313                 cc->extradata != NULL &&
314                 cc->extradata_size > 0 )
315             {
316                 char *psz_start;
317                 char *psz_buf = malloc( cc->extradata_size + 1);
318                 if( psz_buf != NULL )
319                 {
320                     memcpy( psz_buf, cc->extradata , cc->extradata_size );
321                     psz_buf[cc->extradata_size] = '\0';
322
323                     psz_start = strstr( psz_buf, "size:" );
324                     if( psz_start &&
325                         vobsub_size_parse( psz_start,
326                                            &fmt.subs.spu.i_original_frame_width,
327                                            &fmt.subs.spu.i_original_frame_height ) == VLC_SUCCESS )
328                     {
329                         msg_Dbg( p_demux, "original frame size: %dx%d",
330                                  fmt.subs.spu.i_original_frame_width,
331                                  fmt.subs.spu.i_original_frame_height );
332                     }
333                     else
334                     {
335                         msg_Warn( p_demux, "reading original frame size failed" );
336                     }
337
338                     psz_start = strstr( psz_buf, "palette:" );
339                     if( psz_start &&
340                         vobsub_palette_parse( psz_start, &fmt.subs.spu.palette[1] ) == VLC_SUCCESS )
341                     {
342                         fmt.subs.spu.palette[0] =  0xBeef;
343                         msg_Dbg( p_demux, "vobsub palette read" );
344                     }
345                     else
346                     {
347                         msg_Warn( p_demux, "reading original palette failed" );
348                     }
349                     free( psz_buf );
350                 }
351             }
352
353             psz_type = "subtitle";
354             break;
355
356         default:
357             es_format_Init( &fmt, UNKNOWN_ES, 0 );
358 #ifdef HAVE_FFMPEG_CODEC_ATTACHMENT
359             if( cc->codec_type == CODEC_TYPE_ATTACHMENT )
360             {
361                 input_attachment_t *p_attachment;
362                 psz_type = "attachment";
363                 if( cc->codec_id == CODEC_ID_TTF )
364                 {
365                     p_attachment = vlc_input_attachment_New( s->filename, "application/x-truetype-font", NULL,
366                                              cc->extradata, (int)cc->extradata_size );
367                     TAB_APPEND( p_sys->i_attachments, p_sys->attachments, p_attachment );
368                 }
369                 else msg_Warn( p_demux, "unsupported attachment type in ffmpeg demux" );
370             }
371             break;
372 #endif
373
374             if( cc->codec_type == CODEC_TYPE_DATA )
375                 psz_type = "data";
376
377             msg_Warn( p_demux, "unsupported track type in ffmpeg demux" );
378             break;
379         }
380         fmt.psz_language = strdup( s->language );
381         if( s->disposition & AV_DISPOSITION_DEFAULT )
382             fmt.i_priority = 1000;
383
384 #ifdef HAVE_FFMPEG_CODEC_ATTACHMENT
385         if( cc->codec_type != CODEC_TYPE_ATTACHMENT )
386 #endif
387         {
388             const bool    b_ogg = !strcmp( p_sys->fmt->name, "ogg" );
389             const uint8_t *p_extra = cc->extradata;
390             unsigned      i_extra  = cc->extradata_size;
391
392             if( cc->codec_id == CODEC_ID_THEORA && b_ogg )
393             {
394                 unsigned pi_size[3];
395                 void     *pp_data[3];
396                 unsigned i_count;
397                 for( i_count = 0; i_count < 3; i_count++ )
398                 {
399                     if( i_extra < 2 )
400                         break;
401                     pi_size[i_count] = GetWBE( p_extra );
402                     pp_data[i_count] = (uint8_t*)&p_extra[2];
403                     if( i_extra < pi_size[i_count] + 2 )
404                         break;
405
406                     p_extra += 2 + pi_size[i_count];
407                     i_extra -= 2 + pi_size[i_count];
408                 }
409                 if( i_count > 0 && xiph_PackHeaders( &fmt.i_extra, &fmt.p_extra,
410                                                      pi_size, pp_data, i_count ) )
411                 {
412                     fmt.i_extra = 0;
413                     fmt.p_extra = NULL;
414                 }
415             }
416             else if( cc->codec_id == CODEC_ID_SPEEX && b_ogg )
417             {
418                 uint8_t p_dummy_comment[] = {
419                     0, 0, 0, 0,
420                     0, 0, 0, 0,
421                 };
422                 unsigned pi_size[2];
423                 void     *pp_data[2];
424
425                 pi_size[0] = i_extra;
426                 pp_data[0] = (uint8_t*)p_extra;
427
428                 pi_size[1] = sizeof(p_dummy_comment);
429                 pp_data[1] = p_dummy_comment;
430
431                 if( pi_size[0] > 0 && xiph_PackHeaders( &fmt.i_extra, &fmt.p_extra,
432                                                         pi_size, pp_data, 2 ) )
433                 {
434                     fmt.i_extra = 0;
435                     fmt.p_extra = NULL;
436                 }
437             }
438             else if( cc->extradata_size > 0 )
439             {
440                 fmt.p_extra = malloc( i_extra );
441                 if( fmt.p_extra )
442                 {
443                     fmt.i_extra = i_extra;
444                     memcpy( fmt.p_extra, p_extra, i_extra );
445                 }
446             }
447         }
448         es = es_out_Add( p_demux->out, &fmt );
449         if( s->disposition & AV_DISPOSITION_DEFAULT )
450             es_out_Control( p_demux->out, ES_OUT_SET_ES_DEFAULT, es );
451         es_format_Clean( &fmt );
452
453         msg_Dbg( p_demux, "adding es: %s codec = %4.4s",
454                  psz_type, (char*)&fcc );
455         TAB_APPEND( p_sys->i_tk, p_sys->tk, es );
456     }
457     if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
458         i_start_time = p_sys->ic->start_time * 1000000 / AV_TIME_BASE;
459
460     msg_Dbg( p_demux, "AVFormat supported stream" );
461     msg_Dbg( p_demux, "    - format = %s (%s)",
462              p_sys->fmt->name, p_sys->fmt->long_name );
463     msg_Dbg( p_demux, "    - start time = %"PRId64, i_start_time );
464     msg_Dbg( p_demux, "    - duration = %"PRId64,
465              ( p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE ) ?
466              p_sys->ic->duration * 1000000 / AV_TIME_BASE : -1 );
467
468     if( p_sys->ic->nb_chapters > 0 )
469         p_sys->p_title = vlc_input_title_New();
470     for( i = 0; i < p_sys->ic->nb_chapters; i++ )
471     {
472         seekpoint_t *s = vlc_seekpoint_New();
473
474         if( p_sys->ic->chapters[i]->title )
475         {
476             s->psz_name = strdup( p_sys->ic->chapters[i]->title );
477             EnsureUTF8( s->psz_name );
478             msg_Dbg( p_demux, "    - chapter %d: %s", i, s->psz_name );
479         }
480         s->i_time_offset = p_sys->ic->chapters[i]->start * 1000000 *
481             p_sys->ic->chapters[i]->time_base.num /
482             p_sys->ic->chapters[i]->time_base.den -
483             (i_start_time != -1 ? i_start_time : 0 );
484         TAB_APPEND( p_sys->p_title->i_seekpoint, p_sys->p_title->seekpoint, s );
485     }
486
487     return VLC_SUCCESS;
488 }
489
490 /*****************************************************************************
491  * Close
492  *****************************************************************************/
493 void CloseDemux( vlc_object_t *p_this )
494 {
495     demux_t     *p_demux = (demux_t*)p_this;
496     demux_sys_t *p_sys = p_demux->p_sys;
497
498     FREENULL( p_sys->tk );
499
500     if( p_sys->ic ) av_close_input_stream( p_sys->ic );
501
502     for( int i = 0; i < p_sys->i_attachments; i++ )
503         free( p_sys->attachments[i] );
504     TAB_CLEAN( p_sys->i_attachments, p_sys->attachments);
505
506     if( p_sys->p_title )
507         vlc_input_title_Delete( p_sys->p_title );
508
509     free( p_sys->io_buffer );
510     free( p_sys );
511 }
512
513 /*****************************************************************************
514  * Demux:
515  *****************************************************************************/
516 static int Demux( demux_t *p_demux )
517 {
518     demux_sys_t *p_sys = p_demux->p_sys;
519     AVPacket    pkt;
520     block_t     *p_frame;
521     int64_t     i_start_time;
522
523     /* Read a frame */
524     if( av_read_frame( p_sys->ic, &pkt ) )
525     {
526         return 0;
527     }
528     if( pkt.stream_index < 0 || pkt.stream_index >= p_sys->i_tk )
529     {
530         av_free_packet( &pkt );
531         return 1;
532     }
533     const AVStream *p_stream = p_sys->ic->streams[pkt.stream_index];
534     if( p_stream->time_base.den <= 0 )
535     {
536         msg_Warn( p_demux, "Invalid time base for the stream %d", pkt.stream_index );
537         av_free_packet( &pkt );
538         return 1;
539     }
540     if( p_stream->codec->codec_id == CODEC_ID_SSA )
541     {
542         p_frame = BuildSsaFrame( &pkt, p_sys->i_ssa_order++ );
543         if( !p_frame )
544         {
545             av_free_packet( &pkt );
546             return 1;
547         }
548     }
549     else
550     {
551         if( ( p_frame = block_New( p_demux, pkt.size ) ) == NULL )
552         {
553             av_free_packet( &pkt );
554             return 0;
555         }
556         memcpy( p_frame->p_buffer, pkt.data, pkt.size );
557     }
558
559     if( pkt.flags & PKT_FLAG_KEY )
560         p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
561
562     i_start_time = ( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE ) ?
563         ( p_sys->ic->start_time * 1000000 / AV_TIME_BASE )  : 0;
564
565     p_frame->i_dts = ( pkt.dts == (int64_t)AV_NOPTS_VALUE ) ?
566         VLC_TS_INVALID : (pkt.dts) * 1000000 *
567         p_stream->time_base.num /
568         p_stream->time_base.den - i_start_time + VLC_TS_0;
569     p_frame->i_pts = ( pkt.pts == (int64_t)AV_NOPTS_VALUE ) ?
570         VLC_TS_INVALID : (pkt.pts) * 1000000 *
571         p_stream->time_base.num /
572         p_stream->time_base.den - i_start_time + VLC_TS_0;
573     if( pkt.duration > 0 && p_frame->i_length <= 0 )
574         p_frame->i_length = pkt.duration * 1000000 *
575             p_stream->time_base.num /
576             p_stream->time_base.den;
577
578     if( pkt.dts != AV_NOPTS_VALUE && pkt.dts == pkt.pts &&
579         p_stream->codec->codec_type == CODEC_TYPE_VIDEO )
580     {
581         /* Add here notoriously bugged file formats/samples regarding PTS */
582         if( !strcmp( p_sys->fmt->name, "flv" ) )
583             p_frame->i_pts = VLC_TS_INVALID;
584     }
585 #ifdef AVFORMAT_DEBUG
586     msg_Dbg( p_demux, "tk[%d] dts=%"PRId64" pts=%"PRId64,
587              pkt.stream_index, p_frame->i_dts, p_frame->i_pts );
588 #endif
589
590     if( p_frame->i_dts > VLC_TS_INVALID  &&
591         ( pkt.stream_index == p_sys->i_pcr_tk || p_sys->i_pcr_tk < 0 ) )
592     {
593         p_sys->i_pcr_tk = pkt.stream_index;
594         p_sys->i_pcr = p_frame->i_dts;
595
596         es_out_Control( p_demux->out, ES_OUT_SET_PCR, (int64_t)p_sys->i_pcr );
597     }
598
599     es_out_Send( p_demux->out, p_sys->tk[pkt.stream_index], p_frame );
600
601     UpdateSeekPoint( p_demux, p_sys->i_pcr);
602     av_free_packet( &pkt );
603     return 1;
604 }
605
606 static void UpdateSeekPoint( demux_t *p_demux, int64_t i_time )
607 {
608     demux_sys_t *p_sys = p_demux->p_sys;
609     int i;
610
611     if( !p_sys->p_title )
612         return;
613
614     for( i = 0; i < p_sys->p_title->i_seekpoint; i++ )
615     {
616         if( i_time < p_sys->p_title->seekpoint[i]->i_time_offset )
617             break;
618     }
619     i--;
620
621     if( i != p_demux->info.i_seekpoint && i >= 0 )
622     {
623         p_demux->info.i_seekpoint = i;
624         p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
625     }
626 }
627
628 static block_t *BuildSsaFrame( const AVPacket *p_pkt, unsigned i_order )
629 {
630     if( p_pkt->size <= 0 )
631         return NULL;
632
633     char buffer[256];
634     const size_t i_buffer_size = __MIN( sizeof(buffer) - 1, p_pkt->size );
635     memcpy( buffer, p_pkt->data, i_buffer_size );
636     buffer[i_buffer_size] = '\0';
637
638     /* */
639     int i_layer;
640     int h0, m0, s0, c0;
641     int h1, m1, s1, c1;
642     int i_position = 0;
643     if( sscanf( buffer, "Dialogue: %d,%d:%d:%d.%d,%d:%d:%d.%d,%n", &i_layer,
644                 &h0, &m0, &s0, &c0, &h1, &m1, &s1, &c1, &i_position ) < 9 )
645         return NULL;
646     if( i_position <= 0 || i_position >= i_buffer_size )
647         return NULL;
648
649     char *p;
650     if( asprintf( &p, "%u,%d,%.*s", i_order, i_layer, p_pkt->size - i_position, p_pkt->data + i_position ) < 0 )
651         return NULL;
652
653     block_t *p_frame = block_heap_Alloc( p, p, strlen(p) + 1 );
654     if( p_frame )
655         p_frame->i_length = CLOCK_FREQ * ((h1 - h1) * 3600 +
656                                           (m1-m0) * 60 +
657                                           (s1-s0) * 1) +
658                             CLOCK_FREQ * (c1-c0) / 100;
659     return p_frame;
660 }
661
662 /*****************************************************************************
663  * Control:
664  *****************************************************************************/
665 static int Control( demux_t *p_demux, int i_query, va_list args )
666 {
667     demux_sys_t *p_sys = p_demux->p_sys;
668     double f, *pf;
669     int64_t i64, *pi64;
670
671     switch( i_query )
672     {
673         case DEMUX_GET_POSITION:
674             pf = (double*) va_arg( args, double* ); *pf = 0.0;
675             i64 = stream_Size( p_demux->s );
676             if( i64 > 0 )
677             {
678                 double current = stream_Tell( p_demux->s );
679                 *pf = current / (double)i64;
680             }
681
682             if( (p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE) && (p_sys->i_pcr > 0) )
683             {
684                 *pf = (double)p_sys->i_pcr / (double)p_sys->ic->duration;
685             }
686
687             return VLC_SUCCESS;
688
689         case DEMUX_SET_POSITION:
690             f = (double) va_arg( args, double );
691             if( p_sys->i_pcr > 0 )
692             {
693                 i64 = p_sys->ic->duration * f;
694                 if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
695                     i64 += p_sys->ic->start_time;
696
697                 msg_Warn( p_demux, "DEMUX_SET_POSITION: %"PRId64, i64 );
698
699                 /* If we have a duration, we prefer to seek by time
700                    but if we don't, or if the seek fails, try BYTE seeking */
701                 if( p_sys->ic->duration == (int64_t)AV_NOPTS_VALUE ||
702                     (av_seek_frame( p_sys->ic, -1, i64, 0 ) < 0) )
703                 {
704                     int64_t i_size = stream_Size( p_demux->s );
705                     i64 = (i_size * f);
706
707                     msg_Warn( p_demux, "DEMUX_SET_BYTE_POSITION: %"PRId64, i64 );
708                     if( av_seek_frame( p_sys->ic, -1, i64, AVSEEK_FLAG_BYTE ) < 0 )
709                         return VLC_EGENERIC;
710                 }
711                 else
712                 {
713                     UpdateSeekPoint( p_demux, i64 );
714                 }
715                 p_sys->i_pcr = -1; /* Invalidate time display */
716             }
717             return VLC_SUCCESS;
718
719         case DEMUX_GET_LENGTH:
720             pi64 = (int64_t*)va_arg( args, int64_t * );
721             if( p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE )
722                 *pi64 = p_sys->ic->duration * 1000000 / AV_TIME_BASE;
723             else
724                 *pi64 = 0;
725             return VLC_SUCCESS;
726
727         case DEMUX_GET_TIME:
728             pi64 = (int64_t*)va_arg( args, int64_t * );
729             *pi64 = p_sys->i_pcr;
730             return VLC_SUCCESS;
731
732         case DEMUX_SET_TIME:
733             i64 = (int64_t)va_arg( args, int64_t );
734             i64 = i64 *AV_TIME_BASE / 1000000;
735             if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
736                 i64 += p_sys->ic->start_time;
737
738             msg_Warn( p_demux, "DEMUX_SET_TIME: %"PRId64, i64 );
739
740             if( av_seek_frame( p_sys->ic, -1, i64, 0 ) < 0 )
741             {
742                 return VLC_EGENERIC;
743             }
744             p_sys->i_pcr = -1; /* Invalidate time display */
745             UpdateSeekPoint( p_demux, i64 );
746             return VLC_SUCCESS;
747
748         case DEMUX_HAS_UNSUPPORTED_META:
749         {
750             bool *pb_bool = (bool*)va_arg( args, bool* );
751             *pb_bool = true;
752             return VLC_SUCCESS;
753         }
754
755
756         case DEMUX_GET_META:
757         {
758             vlc_meta_t *p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
759
760             if( p_sys->ic->title[0] )
761                 vlc_meta_SetTitle( p_meta, p_sys->ic->title );
762             if( p_sys->ic->author[0] )
763                 vlc_meta_SetArtist( p_meta, p_sys->ic->author );
764             if( p_sys->ic->copyright[0] )
765                 vlc_meta_SetCopyright( p_meta, p_sys->ic->copyright );
766             if( p_sys->ic->comment[0] )
767                 vlc_meta_SetDescription( p_meta, p_sys->ic->comment );
768             if( p_sys->ic->genre[0] )
769                 vlc_meta_SetGenre( p_meta, p_sys->ic->genre );
770             return VLC_SUCCESS;
771         }
772
773         case DEMUX_GET_ATTACHMENTS:
774         {
775             input_attachment_t ***ppp_attach =
776                 (input_attachment_t***)va_arg( args, input_attachment_t*** );
777             int *pi_int = (int*)va_arg( args, int * );
778             int i;
779
780             if( p_sys->i_attachments <= 0 )
781                 return VLC_EGENERIC;
782
783             *pi_int = p_sys->i_attachments;;
784             *ppp_attach = malloc( sizeof(input_attachment_t**) * p_sys->i_attachments );
785             for( i = 0; i < p_sys->i_attachments; i++ )
786                 (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
787             return VLC_SUCCESS;
788         }
789
790         case DEMUX_GET_TITLE_INFO:
791         {
792             input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
793             int *pi_int    = (int*)va_arg( args, int* );
794             int *pi_title_offset = (int*)va_arg( args, int* );
795             int *pi_seekpoint_offset = (int*)va_arg( args, int* );
796
797             if( !p_sys->p_title )
798                 return VLC_EGENERIC;
799
800             *pi_int = 1;
801             *ppp_title = malloc( sizeof( input_title_t**) );
802             (*ppp_title)[0] = vlc_input_title_Duplicate( p_sys->p_title );
803             *pi_title_offset = 0;
804             *pi_seekpoint_offset = 0;
805             return VLC_SUCCESS;
806         }
807         case DEMUX_SET_TITLE:
808         {
809             const int i_title = (int)va_arg( args, int );
810             if( !p_sys->p_title || i_title != 0 )
811                 return VLC_EGENERIC;
812             return VLC_SUCCESS;
813         }
814         case DEMUX_SET_SEEKPOINT:
815         {
816             const int i_seekpoint = (int)va_arg( args, int );
817             if( !p_sys->p_title )
818                 return VLC_EGENERIC;
819
820             i64 = p_sys->p_title->seekpoint[i_seekpoint]->i_time_offset *AV_TIME_BASE / 1000000;
821             if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
822                 i64 += p_sys->ic->start_time;
823
824             msg_Warn( p_demux, "DEMUX_SET_TIME: %"PRId64, i64 );
825
826             if( av_seek_frame( p_sys->ic, -1, i64, 0 ) < 0 )
827             {
828                 return VLC_EGENERIC;
829             }
830             p_sys->i_pcr = -1; /* Invalidate time display */
831             UpdateSeekPoint( p_demux, i64 );
832             return VLC_SUCCESS;
833         }
834
835
836         default:
837             return VLC_EGENERIC;
838     }
839 }
840
841 /*****************************************************************************
842  * I/O wrappers for libavformat
843  *****************************************************************************/
844 static int IORead( void *opaque, uint8_t *buf, int buf_size )
845 {
846     URLContext *p_url = opaque;
847     demux_t *p_demux = p_url->priv_data;
848     if( buf_size < 0 ) return -1;
849     int i_ret = stream_Read( p_demux->s, buf, buf_size );
850     return i_ret ? i_ret : -1;
851 }
852
853 static int64_t IOSeek( void *opaque, int64_t offset, int whence )
854 {
855     URLContext *p_url = opaque;
856     demux_t *p_demux = p_url->priv_data;
857     int64_t i_absolute;
858     int64_t i_size = stream_Size( p_demux->s );
859
860 #ifdef AVFORMAT_DEBUG
861     msg_Warn( p_demux, "IOSeek offset: %"PRId64", whence: %i", offset, whence );
862 #endif
863
864     switch( whence )
865     {
866 #ifdef AVSEEK_SIZE
867         case AVSEEK_SIZE:
868             return i_size;
869 #endif
870         case SEEK_SET:
871             i_absolute = (int64_t)offset;
872             break;
873         case SEEK_CUR:
874             i_absolute = stream_Tell( p_demux->s ) + (int64_t)offset;
875             break;
876         case SEEK_END:
877             i_absolute = i_size + (int64_t)offset;
878             break;
879         default:
880             return -1;
881
882     }
883
884     if( i_absolute < 0 )
885     {
886         msg_Dbg( p_demux, "Trying to seek before the beginning" );
887         return -1;
888     }
889
890     if( i_size > 0 && i_absolute >= i_size )
891     {
892         msg_Dbg( p_demux, "Trying to seek too far : EOF?" );
893         return -1;
894     }
895
896     if( stream_Seek( p_demux->s, i_absolute ) )
897     {
898         msg_Warn( p_demux, "we were not allowed to seek, or EOF " );
899         return -1;
900     }
901
902     return stream_Tell( p_demux->s );
903 }
904
905 #endif /* HAVE_LIBAVFORMAT_AVFORMAT_H */