99aac651eec54652579250c0095d84548a5d708e
[vlc.git] / modules / demux / mpeg / ps.c
1 /*****************************************************************************
2  * ps.c: Program Stream demux module for VLC.
3  *****************************************************************************
4  * Copyright (C) 2004-2009 VLC authors and VideoLAN
5  *
6  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_demux.h>
34
35 #include "pes.h"
36 #include "ps.h"
37
38 /* TODO:
39  *  - re-add pre-scanning.
40  *  - ...
41  */
42
43 #define TIME_TEXT N_("Trust MPEG timestamps")
44 #define TIME_LONGTEXT N_("Normally we use the timestamps of the MPEG files " \
45     "to calculate position and duration. However sometimes this might not " \
46     "be usable. Disable this option to calculate from the bitrate instead." )
47
48 #define PS_PACKET_PROBE 3
49 #define CDXA_HEADER_SIZE 44
50 #define CDXA_SECTOR_SIZE 2352
51 #define CDXA_SECTOR_HEADER_SIZE 24
52
53 /*****************************************************************************
54  * Module descriptor
55  *****************************************************************************/
56 static int  OpenForce( vlc_object_t * );
57 static int  Open   ( vlc_object_t * );
58 static void Close  ( vlc_object_t * );
59
60 vlc_module_begin ()
61     set_description( N_("MPEG-PS demuxer") )
62     set_shortname( N_("PS") )
63     set_category( CAT_INPUT )
64     set_subcategory( SUBCAT_INPUT_DEMUX )
65     set_capability( "demux", 1 )
66     set_callbacks( OpenForce, Close )
67     add_shortcut( "ps" )
68
69     add_bool( "ps-trust-timestamps", true, TIME_TEXT,
70                  TIME_LONGTEXT, true )
71         change_safe ()
72
73     add_submodule ()
74     set_description( N_("MPEG-PS demuxer") )
75     set_capability( "demux", 8 )
76     set_callbacks( Open, Close )
77     add_shortcut( "ps" )
78 vlc_module_end ()
79
80 /*****************************************************************************
81  * Local prototypes
82  *****************************************************************************/
83
84 typedef struct
85 {
86     ps_psm_t    psm;
87     ps_track_t  tk[PS_TK_COUNT];
88
89     vlc_tick_t  i_pack_scr; /* current read pack scr value, temp */
90     vlc_tick_t  i_first_scr; /* media offset */
91     vlc_tick_t  i_scr; /* committed, current position */
92     int64_t     i_scr_track_id;
93     int         i_mux_rate;
94     vlc_tick_t  i_length;
95     int         i_time_track_index;
96     vlc_tick_t  i_current_pts;
97     uint64_t    i_start_byte;
98     uint64_t    i_lastpack_byte;
99
100     int         i_aob_mlp_count;
101
102     bool  b_lost_sync;
103     bool  b_have_pack;
104     bool  b_bad_scr;
105     bool  b_seekable;
106     enum
107     {
108         MPEG_PS = 0,
109         CDXA_PS,
110         PSMF_PS,
111     } format;
112
113     int         current_title;
114     int         current_seekpoint;
115     unsigned    updates;
116 } demux_sys_t;
117
118 static int Demux  ( demux_t *p_demux );
119 static int Control( demux_t *p_demux, int i_query, va_list args );
120
121 static int      ps_pkt_resynch( stream_t *, int, bool );
122 static block_t *ps_pkt_read   ( stream_t * );
123
124 /*****************************************************************************
125  * Open
126  *****************************************************************************/
127 static int OpenCommon( vlc_object_t *p_this, bool b_force )
128 {
129     demux_t     *p_demux = (demux_t*)p_this;
130     demux_sys_t *p_sys;
131
132     const uint8_t *p_peek;
133     ssize_t i_peek = 0;
134     ssize_t i_offset = 0;
135     ssize_t i_skip = 0;
136     unsigned i_max_packets = PS_PACKET_PROBE;
137     int format = MPEG_PS;
138     int i_mux_rate = 0;
139     vlc_tick_t i_length = VLC_TICK_INVALID;
140
141     i_peek = vlc_stream_Peek( p_demux->s, &p_peek, 16 );
142     if( i_peek < 16 )
143         return VLC_EGENERIC;
144
145     if( !memcmp( p_peek, "PSMF", 4 ) &&
146         (GetDWBE( &p_peek[4] ) & 0x30303030) == 0x30303030 )
147     {
148         i_peek = vlc_stream_Peek( p_demux->s, &p_peek, 100 );
149         if( i_peek < 100 )
150             return VLC_EGENERIC;
151         i_skip = i_offset = GetWBE( &p_peek[10] );
152         format = PSMF_PS;
153         msg_Info( p_demux, "Detected PSMF-PS header");
154         i_mux_rate = GetDWBE( &p_peek[96] );
155         if( GetDWBE( &p_peek[86] ) > 0 )
156             i_length = vlc_tick_from_samples( GetDWBE( &p_peek[92] ), GetDWBE( &p_peek[86] ));
157     }
158     else if( !memcmp( p_peek, "RIFF", 4 ) && !memcmp( &p_peek[8], "CDXA", 4 ) )
159     {
160         format = CDXA_PS;
161         i_max_packets = 0; /* We can't probe here */
162         i_skip = CDXA_HEADER_SIZE;
163         msg_Info( p_demux, "Detected CDXA-PS" );
164         /* FIXME: have a proper way to decap CD sectors or make an access stream filter */
165     }
166     else if( b_force )
167     {
168         msg_Warn( p_demux, "this does not look like an MPEG PS stream, "
169                   "continuing anyway" );
170         i_max_packets = 0;
171     }
172
173     for( unsigned i=0; i<i_max_packets; i++ )
174     {
175         if( i_peek < i_offset + 16 )
176         {
177             i_peek = vlc_stream_Peek( p_demux->s, &p_peek, i_offset + 16 );
178             if( i_peek < i_offset + 16 )
179                 return VLC_EGENERIC;
180         }
181
182         const uint8_t startcode[3] = { 0x00, 0x00, 0x01 };
183         const uint8_t *p_header = &p_peek[i_offset];
184         if( memcmp( p_header, startcode, 3 ) ||
185            ( (p_header[3] & 0xB0) != 0xB0 &&
186             !(p_header[3] >= 0xC0 && p_header[3] <= 0xEF) &&
187               p_header[3] != PS_STREAM_ID_EXTENDED &&
188               p_header[3] != PS_STREAM_ID_DIRECTORY ) )
189             return VLC_EGENERIC;
190
191         ssize_t i_pessize = ps_pkt_size( p_header, 16 );
192         if( i_pessize < 5 )
193             return VLC_EGENERIC;
194         i_offset += i_pessize;
195     }
196
197     if( i_skip > 0 && !p_demux->b_preparsing &&
198         vlc_stream_Read( p_demux->s, NULL, i_skip ) != i_skip )
199         return VLC_EGENERIC;
200
201     /* Fill p_demux field */
202     p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
203     if( !p_sys ) return VLC_ENOMEM;
204
205     p_demux->pf_demux = Demux;
206     p_demux->pf_control = Control;
207
208     /* Init p_sys */
209     p_sys->i_mux_rate = i_mux_rate;
210     p_sys->i_pack_scr  = VLC_TICK_INVALID;
211     p_sys->i_first_scr = VLC_TICK_INVALID;
212     p_sys->i_scr = VLC_TICK_INVALID;
213     p_sys->i_scr_track_id = 0;
214     p_sys->i_length   = i_length;
215     p_sys->i_current_pts = VLC_TICK_INVALID;
216     p_sys->i_time_track_index = -1;
217     p_sys->i_aob_mlp_count = 0;
218     p_sys->i_start_byte = i_skip;
219     p_sys->i_lastpack_byte = i_skip;
220
221     p_sys->b_lost_sync = false;
222     p_sys->b_have_pack = false;
223     p_sys->b_bad_scr   = false;
224     p_sys->b_seekable  = false;
225     p_sys->format      = format;
226     p_sys->current_title = 0;
227     p_sys->current_seekpoint = 0;
228     p_sys->updates = 0;
229
230     vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &p_sys->b_seekable );
231
232     ps_psm_init( &p_sys->psm );
233     ps_track_init( p_sys->tk );
234
235     /* TODO prescanning of ES */
236
237     return VLC_SUCCESS;
238 }
239
240 static int OpenForce( vlc_object_t *p_this )
241 {
242     return OpenCommon( p_this, true );
243 }
244
245 static int Open( vlc_object_t *p_this )
246 {
247     return OpenCommon( p_this, p_this->force );
248 }
249
250 /*****************************************************************************
251  * Close
252  *****************************************************************************/
253 static void Close( vlc_object_t *p_this )
254 {
255     demux_t     *p_demux = (demux_t*)p_this;
256     demux_sys_t *p_sys = p_demux->p_sys;
257     int i;
258
259     for( i = 0; i < PS_TK_COUNT; i++ )
260     {
261         ps_track_t *tk = &p_sys->tk[i];
262         if( tk->b_configured )
263         {
264             es_format_Clean( &tk->fmt );
265             if( tk->es ) es_out_Del( p_demux->out, tk->es );
266         }
267     }
268
269     ps_psm_destroy( &p_sys->psm );
270
271     free( p_sys );
272 }
273
274 static int Probe( demux_t *p_demux, bool b_end )
275 {
276     demux_sys_t *p_sys = p_demux->p_sys;
277     int i_ret, i_id;
278     block_t *p_pkt;
279
280     i_ret = ps_pkt_resynch( p_demux->s, p_sys->format, p_sys->b_have_pack );
281     if( i_ret < 0 )
282     {
283         return VLC_DEMUXER_EOF;
284     }
285     else if( i_ret == 0 )
286     {
287         if( !p_sys->b_lost_sync )
288             msg_Warn( p_demux, "garbage at input, trying to resync..." );
289
290         p_sys->b_lost_sync = true;
291         return VLC_DEMUXER_SUCCESS;
292     }
293
294     if( p_sys->b_lost_sync ) msg_Warn( p_demux, "found sync code" );
295     p_sys->b_lost_sync = false;
296
297     if( ( p_pkt = ps_pkt_read( p_demux->s ) ) == NULL )
298     {
299         return VLC_DEMUXER_EOF;
300     }
301
302     i_id = ps_pkt_id( p_pkt->p_buffer, p_pkt->i_buffer );
303     if( i_id >= 0xc0 )
304     {
305         ps_track_t *tk = &p_sys->tk[ps_id_to_tk(i_id)];
306         if( !ps_pkt_parse_pes( VLC_OBJECT(p_demux), p_pkt, tk->i_skip ) &&
307              p_pkt->i_pts != VLC_TICK_INVALID )
308         {
309             if( b_end && (tk->i_last_pts == VLC_TICK_INVALID || p_pkt->i_pts > tk->i_last_pts) )
310             {
311                 tk->i_last_pts = p_pkt->i_pts;
312             }
313             else if ( tk->i_first_pts == VLC_TICK_INVALID )
314             {
315                 tk->i_first_pts = p_pkt->i_pts;
316             }
317         }
318     }
319     else if( i_id == PS_STREAM_ID_PACK_HEADER )
320     {
321         vlc_tick_t i_scr; int dummy;
322         if( !b_end && !ps_pkt_parse_pack( p_pkt->p_buffer, p_pkt->i_buffer,
323                                           &i_scr, &dummy ) )
324         {
325             if( p_sys->i_first_scr == VLC_TICK_INVALID )
326                 p_sys->i_first_scr = i_scr;
327         }
328         p_sys->b_have_pack = true;
329     }
330
331     block_Release( p_pkt );
332     return VLC_DEMUXER_SUCCESS;
333 }
334
335 static bool FindLength( demux_t *p_demux )
336 {
337     demux_sys_t *p_sys = p_demux->p_sys;
338     int64_t i_current_pos = -1, i_size = 0, i_end = 0;
339
340     if( !var_CreateGetBool( p_demux, "ps-trust-timestamps" ) )
341         return true;
342
343     if( p_sys->i_length == VLC_TICK_INVALID ) /* First time */
344     {
345         p_sys->i_length = VLC_TICK_0;
346         /* Check beginning */
347         int i = 0;
348         i_current_pos = vlc_stream_Tell( p_demux->s );
349         while( i < 40 && Probe( p_demux, false ) > 0 ) i++;
350
351         /* Check end */
352         i_size = stream_Size( p_demux->s );
353         i_end = VLC_CLIP( i_size, 0, 200000 );
354         if( vlc_stream_Seek( p_demux->s, i_size - i_end ) == VLC_SUCCESS )
355         {
356             i = 0;
357             while( i < 400 && Probe( p_demux, true ) > 0 ) i++;
358             if( i_current_pos >= 0 &&
359                 vlc_stream_Seek( p_demux->s, i_current_pos ) != VLC_SUCCESS )
360                     return false;
361         }
362         else return false;
363     }
364
365     /* Find the longest track */
366     for( int i = 0; i < PS_TK_COUNT; i++ )
367     {
368         ps_track_t *tk = &p_sys->tk[i];
369         if( tk->i_first_pts != VLC_TICK_INVALID &&
370             tk->i_last_pts > tk->i_first_pts )
371         {
372             vlc_tick_t i_length = tk->i_last_pts - tk->i_first_pts;
373             if( i_length > p_sys->i_length )
374             {
375                 p_sys->i_length = i_length;
376                 p_sys->i_time_track_index = i;
377                 msg_Dbg( p_demux, "we found a length of: %"PRId64 "s", SEC_FROM_VLC_TICK(p_sys->i_length) );
378             }
379         }
380     }
381     return true;
382 }
383
384 static void NotifyDiscontinuity( ps_track_t *p_tk, es_out_t *out )
385 {
386     bool b_selected;
387     for( size_t i = 0; i < PS_TK_COUNT; i++ )
388     {
389         ps_track_t *tk = &p_tk[i];
390         if( tk->es &&
391                 es_out_Control( out, ES_OUT_GET_ES_STATE, tk->es, &b_selected ) == VLC_SUCCESS
392                 && b_selected )
393         {
394             tk->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
395         }
396     }
397 }
398
399 static void CheckPCR( demux_sys_t *p_sys, es_out_t *out, vlc_tick_t i_scr )
400 {
401     if( p_sys->i_scr != VLC_TICK_INVALID &&
402         llabs( p_sys->i_scr - i_scr ) > VLC_TICK_FROM_SEC(1) )
403         NotifyDiscontinuity( p_sys->tk, out );
404 }
405
406 /*****************************************************************************
407  * Demux:
408  *****************************************************************************/
409 static int Demux( demux_t *p_demux )
410 {
411     demux_sys_t *p_sys = p_demux->p_sys;
412     int i_ret, i_mux_rate;
413     block_t *p_pkt;
414
415     i_ret = ps_pkt_resynch( p_demux->s, p_sys->format, p_sys->b_have_pack );
416     if( i_ret < 0 )
417     {
418         return VLC_DEMUXER_EOF;
419     }
420     else if( i_ret == 0 )
421     {
422         if( !p_sys->b_lost_sync )
423         {
424             msg_Warn( p_demux, "garbage at input from %"PRIu64", trying to resync...",
425                                 vlc_stream_Tell(p_demux->s) );
426             NotifyDiscontinuity( p_sys->tk, p_demux->out );
427         }
428
429         p_sys->b_lost_sync = true;
430         return VLC_DEMUXER_SUCCESS;
431     }
432
433     if( p_sys->b_lost_sync ) msg_Warn( p_demux, "found sync code" );
434     p_sys->b_lost_sync = false;
435
436     if( p_sys->i_length == VLC_TICK_INVALID && p_sys->b_seekable )
437     {
438         if( !FindLength( p_demux ) )
439             return VLC_DEMUXER_EGENERIC;
440     }
441
442     if( ( p_pkt = ps_pkt_read( p_demux->s ) ) == NULL )
443     {
444         return VLC_DEMUXER_EOF;
445     }
446
447     if( p_pkt->i_buffer < 4 )
448     {
449         block_Release( p_pkt );
450         return VLC_DEMUXER_EGENERIC;
451     }
452
453     const uint8_t i_stream_id = p_pkt->p_buffer[3];
454     switch( i_stream_id )
455     {
456     case PS_STREAM_ID_END_STREAM:
457     case PS_STREAM_ID_PADDING:
458         block_Release( p_pkt );
459         break;
460
461     case PS_STREAM_ID_PACK_HEADER:
462         if( !ps_pkt_parse_pack( p_pkt->p_buffer, p_pkt->i_buffer,
463                                 &p_sys->i_pack_scr, &i_mux_rate ) )
464         {
465             if( p_sys->i_first_scr == VLC_TICK_INVALID )
466                 p_sys->i_first_scr = p_sys->i_pack_scr;
467             CheckPCR( p_sys, p_demux->out, p_sys->i_pack_scr );
468             p_sys->i_scr = p_sys->i_pack_scr;
469             p_sys->i_lastpack_byte = vlc_stream_Tell( p_demux->s );
470             if( !p_sys->b_have_pack ) p_sys->b_have_pack = true;
471             /* done later on to work around bad vcd/svcd streams */
472             /* es_out_SetPCR( p_demux->out, p_sys->i_scr ); */
473             if( i_mux_rate > 0 ) p_sys->i_mux_rate = i_mux_rate;
474         }
475         block_Release( p_pkt );
476         break;
477
478     case PS_STREAM_ID_SYSTEM_HEADER:
479         if( !ps_pkt_parse_system( p_pkt->p_buffer, p_pkt->i_buffer,
480                                   &p_sys->psm, p_sys->tk ) )
481         {
482             int i;
483             for( i = 0; i < PS_TK_COUNT; i++ )
484             {
485                 ps_track_t *tk = &p_sys->tk[i];
486
487                 if( !tk->b_configured && tk->fmt.i_cat != UNKNOWN_ES )
488                 {
489                     if( tk->b_seen )
490                         tk->es = es_out_Add( p_demux->out, &tk->fmt );
491                      /* else create when seeing packet */
492                     tk->b_configured = true;
493                 }
494             }
495         }
496         block_Release( p_pkt );
497         break;
498
499     case PS_STREAM_ID_MAP:
500         if( p_sys->psm.i_version == 0xFF )
501             msg_Dbg( p_demux, "contains a PSM");
502
503         ps_psm_fill( &p_sys->psm,
504                      p_pkt->p_buffer, p_pkt->i_buffer,
505                      p_sys->tk, p_demux->out );
506         block_Release( p_pkt );
507         break;
508
509     default:
510         /* Reject non video/audio nor PES */
511         if( i_stream_id < 0xC0 || i_stream_id > 0xEF )
512         {
513             block_Release( p_pkt );
514             break;
515         }
516         /* fallthrough */
517     case PS_STREAM_ID_PRIVATE_STREAM1:
518     case PS_STREAM_ID_EXTENDED:
519         {
520             int i_id = ps_pkt_id( p_pkt->p_buffer, p_pkt->i_buffer );
521             /* Small heuristic to improve MLP detection from AOB */
522             if( i_id == 0xa001 &&
523                 p_sys->i_aob_mlp_count < 500 )
524             {
525                 p_sys->i_aob_mlp_count++;
526             }
527             else if( i_id == 0xbda1 &&
528                      p_sys->i_aob_mlp_count > 0 )
529             {
530                 p_sys->i_aob_mlp_count--;
531                 i_id = 0xa001;
532             }
533
534             bool b_new = false;
535             ps_track_t *tk = &p_sys->tk[ps_id_to_tk(i_id)];
536
537             if( !tk->b_configured )
538             {
539                 if( !ps_track_fill( tk, &p_sys->psm, i_id,
540                                     p_pkt->p_buffer, p_pkt->i_buffer, false ) )
541                 {
542                     /* No PSM and no probing yet */
543                     if( p_sys->format == PSMF_PS )
544                     {
545                         if( tk->fmt.i_cat == VIDEO_ES )
546                             tk->fmt.i_codec = VLC_CODEC_H264;
547 #if 0
548                         if( i_stream_id == PS_STREAM_ID_PRIVATE_STREAM1 )
549                         {
550                             es_format_Change( &tk->fmt, AUDIO_ES, VLC_CODEC_ATRAC3P );
551                             tk->fmt.audio.i_blockalign = 376;
552                             tk->fmt.audio.i_channels = 2;
553                             tk->fmt.audio.i_rate = 44100;
554                         }
555 #endif
556                     }
557
558                     tk->es = es_out_Add( p_demux->out, &tk->fmt );
559                     b_new = true;
560                     tk->b_configured = true;
561                 }
562                 else
563                 {
564                     msg_Dbg( p_demux, "es id=0x%x format unknown", i_id );
565                 }
566             }
567
568             /* Late creation from system header */
569             if( !tk->b_seen && tk->b_configured && !tk->es && tk->fmt.i_cat != UNKNOWN_ES )
570                 tk->es = es_out_Add( p_demux->out, &tk->fmt );
571
572             tk->b_seen = true;
573
574             /* The popular VCD/SVCD subtitling WinSubMux does not
575              * renumber the SCRs when merging subtitles into the PES */
576             if( tk->b_seen && !p_sys->b_bad_scr &&
577                 ( tk->fmt.i_codec == VLC_CODEC_OGT ||
578                   tk->fmt.i_codec == VLC_CODEC_CVD ) )
579             {
580                 p_sys->b_bad_scr = true;
581                 p_sys->i_first_scr = VLC_TICK_INVALID;
582             }
583
584             if( p_sys->i_pack_scr != VLC_TICK_INVALID && !p_sys->b_bad_scr )
585             {
586                 if( (tk->fmt.i_cat == AUDIO_ES || tk->fmt.i_cat == VIDEO_ES) &&
587                     tk->i_first_pts != VLC_TICK_INVALID && tk->i_first_pts - p_sys->i_pack_scr > VLC_TICK_FROM_SEC(2))
588                 {
589                     msg_Warn( p_demux, "Incorrect SCR timing offset by of %"PRId64 "ms, disabling",
590                                        MS_FROM_VLC_TICK(tk->i_first_pts - p_sys->i_pack_scr) );
591                     p_sys->b_bad_scr = true; /* Disable Offset SCR */
592                     p_sys->i_first_scr = VLC_TICK_INVALID;
593                 }
594                 else
595                     es_out_SetPCR( p_demux->out, p_sys->i_pack_scr );
596             }
597
598             if( tk->b_configured && tk->es &&
599                 !ps_pkt_parse_pes( VLC_OBJECT(p_demux), p_pkt, tk->i_skip ) )
600             {
601                 if( tk->fmt.i_cat == AUDIO_ES || tk->fmt.i_cat == VIDEO_ES )
602                 {
603                     if( !p_sys->b_bad_scr && p_sys->i_pack_scr != VLC_TICK_INVALID && p_pkt->i_pts != VLC_TICK_INVALID &&
604                         p_sys->i_pack_scr > p_pkt->i_pts + VLC_TICK_FROM_MS(250) )
605                     {
606                         msg_Warn( p_demux, "Incorrect SCR timing in advance of %" PRId64 "ms, disabling",
607                                            MS_FROM_VLC_TICK(p_sys->i_pack_scr - p_pkt->i_pts) );
608                         p_sys->b_bad_scr = true;
609                         p_sys->i_first_scr = VLC_TICK_INVALID;
610                     }
611
612                     if( (p_sys->b_bad_scr || !p_sys->b_have_pack) && !p_sys->i_scr_track_id )
613                     {
614                         p_sys->i_scr_track_id = tk->i_id;
615                     }
616                 }
617
618                 if( ((!b_new && !p_sys->b_have_pack) || p_sys->b_bad_scr) &&
619                     p_sys->i_scr_track_id == tk->i_id &&
620                     p_pkt->i_pts != VLC_TICK_INVALID )
621                 {
622                     /* A hack to sync the A/V on PES files. */
623                     msg_Dbg( p_demux, "force SCR: %"PRId64, p_pkt->i_pts );
624                     CheckPCR( p_sys, p_demux->out, p_pkt->i_pts );
625                     p_sys->i_scr = p_pkt->i_pts;
626                     if( p_sys->i_first_scr == VLC_TICK_INVALID )
627                         p_sys->i_first_scr = p_sys->i_scr;
628                     es_out_SetPCR( p_demux->out, p_pkt->i_pts );
629                 }
630
631                 if( tk->fmt.i_codec == VLC_CODEC_TELETEXT &&
632                     p_pkt->i_pts == VLC_TICK_INVALID && p_sys->i_scr != VLC_TICK_INVALID )
633                 {
634                     /* Teletext may have missing PTS (ETSI EN 300 472 Annexe A)
635                      * In this case use the last SCR + 40ms */
636                     p_pkt->i_pts = p_sys->i_scr + VLC_TICK_FROM_MS(40);
637                 }
638
639                 if( p_pkt->i_pts > p_sys->i_current_pts )
640                 {
641                     p_sys->i_current_pts = p_pkt->i_pts;
642                 }
643
644                 if( tk->i_next_block_flags )
645                 {
646                     p_pkt->i_flags = tk->i_next_block_flags;
647                     tk->i_next_block_flags = 0;
648                 }
649 #if 0
650                 if( tk->fmt.i_codec == VLC_CODEC_ATRAC3P )
651                 {
652                     p_pkt->p_buffer += 14;
653                     p_pkt->i_buffer -= 14;
654                 }
655 #endif
656                 es_out_Send( p_demux->out, tk->es, p_pkt );
657             }
658             else
659             {
660                 block_Release( p_pkt );
661             }
662
663             p_sys->i_pack_scr = VLC_TICK_INVALID;
664         }
665         break;
666     }
667
668     demux_UpdateTitleFromStream( p_demux );
669     return VLC_DEMUXER_SUCCESS;
670 }
671
672 /*****************************************************************************
673  * Control:
674  *****************************************************************************/
675 static int Control( demux_t *p_demux, int i_query, va_list args )
676 {
677     demux_sys_t *p_sys = p_demux->p_sys;
678     double f, *pf;
679     int64_t i64;
680     int i_ret;
681
682     switch( i_query )
683     {
684         case DEMUX_CAN_SEEK:
685             *va_arg( args, bool * ) = p_sys->b_seekable;
686             return VLC_SUCCESS;
687
688         case DEMUX_GET_TITLE:
689             *va_arg( args, int * ) = p_sys->current_title;
690             return VLC_SUCCESS;
691
692         case DEMUX_GET_SEEKPOINT:
693             *va_arg( args, int * ) = p_sys->current_seekpoint;
694             return VLC_SUCCESS;
695
696         case DEMUX_GET_POSITION:
697             pf = va_arg( args, double * );
698             i64 = stream_Size( p_demux->s ) - p_sys->i_start_byte;
699             if( i64 > 0 )
700             {
701                 double current = vlc_stream_Tell( p_demux->s ) - p_sys->i_start_byte;
702                 *pf = current / (double)i64;
703             }
704             else
705             {
706                 *pf = 0.0;
707             }
708             return VLC_SUCCESS;
709
710         case DEMUX_SET_POSITION:
711             f = va_arg( args, double );
712             i64 = stream_Size( p_demux->s ) - p_sys->i_start_byte;
713             p_sys->i_current_pts = VLC_TICK_INVALID;
714             p_sys->i_scr = VLC_TICK_INVALID;
715
716             if( p_sys->format == CDXA_PS )
717             {
718                 i64 = (int64_t)(i64  * f); /* Align to sector payload */
719                 i64 = p_sys->i_start_byte + i64 - (i64 % CDXA_SECTOR_SIZE) + CDXA_SECTOR_HEADER_SIZE;
720             }
721             else
722             {
723                 i64 = p_sys->i_start_byte + (int64_t)(i64 * f);
724             }
725
726             i_ret = vlc_stream_Seek( p_demux->s, i64 );
727             if( i_ret == VLC_SUCCESS )
728             {
729                 NotifyDiscontinuity( p_sys->tk, p_demux->out );
730                 return i_ret;
731             }
732             break;
733
734         case DEMUX_GET_TIME:
735             if( p_sys->i_time_track_index >= 0 && p_sys->i_current_pts != VLC_TICK_INVALID )
736             {
737                 *va_arg( args, vlc_tick_t * ) = p_sys->i_current_pts - p_sys->tk[p_sys->i_time_track_index].i_first_pts;
738                 return VLC_SUCCESS;
739             }
740             if( p_sys->i_first_scr != VLC_TICK_INVALID && p_sys->i_scr != VLC_TICK_INVALID )
741             {
742                 vlc_tick_t i_time = p_sys->i_scr - p_sys->i_first_scr;
743                 /* H.222 2.5.2.2 */
744                 if( p_sys->i_mux_rate > 0 && p_sys->b_have_pack )
745                 {
746                     uint64_t i_offset = vlc_stream_Tell( p_demux->s ) - p_sys->i_lastpack_byte;
747                     i_time += vlc_tick_from_samples(i_offset, p_sys->i_mux_rate * 50);
748                 }
749                 *va_arg( args, vlc_tick_t * ) = i_time;
750                 return VLC_SUCCESS;
751             }
752             *va_arg( args, vlc_tick_t * ) = 0;
753             break;
754
755         case DEMUX_GET_LENGTH:
756             if( p_sys->i_length > VLC_TICK_0 )
757             {
758                 *va_arg( args, vlc_tick_t * ) = p_sys->i_length;
759                 return VLC_SUCCESS;
760             }
761             else if( p_sys->i_mux_rate > 0 )
762             {
763                 *va_arg( args, vlc_tick_t * ) = vlc_tick_from_samples( stream_Size( p_demux->s ) - p_sys->i_start_byte / 50,
764                     p_sys->i_mux_rate );
765                 return VLC_SUCCESS;
766             }
767             *va_arg( args, vlc_tick_t * ) = 0;
768             break;
769
770         case DEMUX_SET_TIME:
771         {
772             if( p_sys->i_time_track_index >= 0 && p_sys->i_current_pts != VLC_TICK_INVALID &&
773                 p_sys->i_length > VLC_TICK_0)
774             {
775                 vlc_tick_t i_time = va_arg( args, vlc_tick_t );
776                 i_time -= p_sys->tk[p_sys->i_time_track_index].i_first_pts;
777                 return demux_Control( p_demux, DEMUX_SET_POSITION, (double) i_time / p_sys->i_length );
778             }
779             break;
780         }
781
782         case DEMUX_GET_TITLE_INFO:
783         {
784             struct input_title_t ***v = va_arg( args, struct input_title_t*** );
785             int *c = va_arg( args, int * );
786
787             *va_arg( args, int* ) = 0; /* Title offset */
788             *va_arg( args, int* ) = 0; /* Chapter offset */
789             return vlc_stream_Control( p_demux->s, STREAM_GET_TITLE_INFO, v,
790                                        c );
791         }
792
793         case DEMUX_SET_TITLE:
794             return vlc_stream_vaControl( p_demux->s, STREAM_SET_TITLE, args );
795
796         case DEMUX_SET_SEEKPOINT:
797             return vlc_stream_vaControl( p_demux->s, STREAM_SET_SEEKPOINT,
798                                          args );
799
800         case DEMUX_TEST_AND_CLEAR_FLAGS:
801         {
802             unsigned *restrict flags = va_arg(args, unsigned *);
803             *flags &= p_sys->updates;
804             p_sys->updates &= ~*flags;
805             return VLC_SUCCESS;
806         }
807
808         case DEMUX_GET_META:
809             return vlc_stream_vaControl( p_demux->s, STREAM_GET_META, args );
810
811         case DEMUX_GET_FPS:
812             break;
813
814         case DEMUX_CAN_PAUSE:
815         case DEMUX_SET_PAUSE_STATE:
816         case DEMUX_CAN_CONTROL_PACE:
817         case DEMUX_GET_PTS_DELAY:
818             return demux_vaControlHelper( p_demux->s, 0, -1, 0, 1, i_query, args );
819
820         default:
821             break;
822
823     }
824     return VLC_EGENERIC;
825 }
826
827 /*****************************************************************************
828  * Divers:
829  *****************************************************************************/
830
831 /* PSResynch: resynch on a system startcode
832  *  It doesn't skip more than 512 bytes
833  *  -1 -> error, 0 -> not synch, 1 -> ok
834  */
835 static int ps_pkt_resynch( stream_t *s, int format, bool b_pack )
836 {
837     const uint8_t *p_peek;
838     int     i_peek;
839     int     i_skip;
840
841     if( vlc_stream_Peek( s, &p_peek, 4 ) < 4 )
842     {
843         return -1;
844     }
845     if( p_peek[0] == 0 && p_peek[1] == 0 && p_peek[2] == 1 &&
846         p_peek[3] >= PS_STREAM_ID_END_STREAM )
847     {
848         return 1;
849     }
850
851     if( ( i_peek = vlc_stream_Peek( s, &p_peek, 512 ) ) < 4 )
852     {
853         return -1;
854     }
855     i_skip = 0;
856
857     for( ;; )
858     {
859         if( i_peek < 4 )
860         {
861             break;
862         }
863         /* Handle mid stream 24 bytes padding+CRC creating emulated sync codes with incorrect
864            PES sizes and frelling up to UINT16_MAX bytes followed by 24 bytes CDXA Header */
865         if( format == CDXA_PS && i_skip == 0 && i_peek >= 48 )
866         {
867             const uint8_t cdxasynccode[12] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
868                                                0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
869             if( !memcmp( &p_peek[24], cdxasynccode, 12 ) )
870             {
871                 i_peek -= 48;
872                 p_peek += 48;
873                 i_skip += 48;
874                 continue;
875             }
876         }
877
878         if( p_peek[0] == 0 && p_peek[1] == 0 && p_peek[2] == 1 &&
879             p_peek[3] >= PS_STREAM_ID_END_STREAM &&
880             ( !b_pack || p_peek[3] == PS_STREAM_ID_PACK_HEADER ) )
881         {
882             return vlc_stream_Read( s, NULL, i_skip ) == i_skip ? 1 : -1;
883         }
884
885         p_peek++;
886         i_peek--;
887         i_skip++;
888     }
889     return vlc_stream_Read( s, NULL, i_skip ) == i_skip ? 0 : -1;
890 }
891
892 static block_t *ps_pkt_read( stream_t *s )
893 {
894     const uint8_t *p_peek;
895     int i_peek = vlc_stream_Peek( s, &p_peek, 14 );
896     if( i_peek < 4 )
897         return NULL;
898
899     int i_size = ps_pkt_size( p_peek, i_peek );
900     if( i_size <= 6 && p_peek[3] > PS_STREAM_ID_PACK_HEADER )
901     {
902         /* Special case, search the next start code */
903         i_size = 6;
904         for( ;; )
905         {
906             i_peek = vlc_stream_Peek( s, &p_peek, i_size + 1024 );
907             if( i_peek <= i_size + 4 )
908             {
909                 return NULL;
910             }
911             while( i_size <= i_peek - 4 )
912             {
913                 if( p_peek[i_size] == 0x00 && p_peek[i_size+1] == 0x00 &&
914                     p_peek[i_size+2] == 0x01 && p_peek[i_size+3] >= PS_STREAM_ID_END_STREAM )
915                 {
916                     return vlc_stream_Block( s, i_size );
917                 }
918                 i_size++;
919             }
920         }
921     }
922     else
923     {
924         /* Normal case */
925         return vlc_stream_Block( s, i_size );
926     }
927
928     return NULL;
929 }