Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

ts.c

00001 /*****************************************************************************
00002  * ts.c: Transport Stream input module for VLC.
00003  *****************************************************************************
00004  * Copyright (C) 2004-2005 VideoLAN (Centrale Réseaux) and its contributors
00005  * $Id: ts.c 12692 2005-09-27 01:10:56Z hartman $
00006  *
00007  * Authors: Laurent Aimar <[email protected]>
00008  *          Jean-Paul Saman <jpsaman #_at_# m2x.nl>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 /*****************************************************************************
00026  * Preamble
00027  *****************************************************************************/
00028 #include <stdlib.h>                                      /* malloc(), free() */
00029 #include <ctype.h>
00030 
00031 #include <vlc/vlc.h>
00032 #include <vlc/input.h>
00033 
00034 #include "iso_lang.h"
00035 #include "network.h"
00036 
00037 #include "../mux/mpeg/csa.h"
00038 
00039 /* Include dvbpsi headers */
00040 #ifdef HAVE_DVBPSI_DR_H
00041 #   include <dvbpsi/dvbpsi.h>
00042 #   include <dvbpsi/demux.h>
00043 #   include <dvbpsi/descriptor.h>
00044 #   include <dvbpsi/pat.h>
00045 #   include <dvbpsi/pmt.h>
00046 #   include <dvbpsi/sdt.h>
00047 #   include <dvbpsi/dr.h>
00048 #   include <dvbpsi/psi.h>
00049 #else
00050 #   include "dvbpsi.h"
00051 #   include "demux.h"
00052 #   include "descriptor.h"
00053 #   include "tables/pat.h"
00054 #   include "tables/pmt.h"
00055 #   include "tables/sdt.h"
00056 #   include "descriptors/dr.h"
00057 #   include "psi.h"
00058 #endif
00059 
00060 /* EIT support */
00061 #ifdef _DVBPSI_DR_4D_H_
00062 #   define TS_USE_DVB_SI 1
00063 #   ifdef HAVE_DVBPSI_DR_H
00064 #       include <dvbpsi/eit.h>
00065 #   else
00066 #       include "tables/eit.h"
00067 #   endif
00068 #endif
00069 
00070 /* TODO:
00071  *  - XXX: do not mark options message to be translated, they are too osbcure for now ...
00072  *  - test it
00073  *  - ...
00074  */
00075 
00076 /*****************************************************************************
00077  * Module descriptor
00078  *****************************************************************************/
00079 static int  Open  ( vlc_object_t * );
00080 static void Close ( vlc_object_t * );
00081 
00082 #define PMT_TEXT N_("Extra PMT")
00083 #define PMT_LONGTEXT N_( \
00084   "Allows a user to specify an extra pmt (pmt_pid=pid:stream_type[,...])" )
00085 
00086 #define PID_TEXT N_("Set id of ES to PID")
00087 #define PID_LONGTEXT N_("set id of es to pid")
00088 
00089 #define TSOUT_TEXT N_("Fast udp streaming")
00090 #define TSOUT_LONGTEXT N_( \
00091   "Sends TS to specific ip:port by udp (you must know what you are doing)")
00092 
00093 #define MTUOUT_TEXT N_("MTU for out mode")
00094 #define MTUOUT_LONGTEXT N_("MTU for out mode")
00095 
00096 #define CSA_TEXT N_("CSA ck")
00097 #define CSA_LONGTEXT N_("CSA ck")
00098 
00099 #define SILENT_TEXT N_("Silent mode")
00100 #define SILENT_LONGTEXT N_("do not complain on encrypted PES")
00101 
00102 #define CAPMT_SYSID_TEXT N_("CAPMT System ID")
00103 #define CAPMT_SYSID_LONGTEXT N_("only forward descriptors from this SysID to the CAM")
00104 
00105 #define CPKT_TEXT N_("Packet size in bytes to decrypt")
00106 #define CPKT_LONGTEXT N_("Specify the size of the TS packet to decrypt. " \
00107     "The decryption routines subtract the TS-header from the value before " \
00108     "decrypting. " )
00109 
00110 #define TSDUMP_TEXT N_("Filename of dump")
00111 #define TSDUMP_LONGTEXT N_("Specify a filename where to dump the TS in")
00112 
00113 #define APPEND_TEXT N_("Append")
00114 #define APPEND_LONGTEXT N_( \
00115     "If the file exists and this option is selected, the existing file " \
00116     "will not be overwritten." )
00117 
00118 #define DUMPSIZE_TEXT N_("Dump buffer size")
00119 #define DUMPSIZE_LONGTEXT N_( \
00120     "Tweak the buffer size for reading and writing an integer number of packets." \
00121     "Specify the size of the buffer here and not the number of packets." )
00122 
00123 vlc_module_begin();
00124     set_description( _("MPEG Transport Stream demuxer") );
00125     set_shortname ( "MPEG-TS" );
00126     set_category( CAT_INPUT );
00127     set_subcategory( SUBCAT_INPUT_DEMUX );
00128 
00129     add_string( "ts-extra-pmt", NULL, NULL, PMT_TEXT, PMT_LONGTEXT, VLC_TRUE );
00130     add_bool( "ts-es-id-pid", 0, NULL, PID_TEXT, PID_LONGTEXT, VLC_TRUE );
00131     add_string( "ts-out", NULL, NULL, TSOUT_TEXT, TSOUT_LONGTEXT, VLC_TRUE );
00132     add_integer( "ts-out-mtu", 1500, NULL, MTUOUT_TEXT,
00133                  MTUOUT_LONGTEXT, VLC_TRUE );
00134     add_string( "ts-csa-ck", NULL, NULL, CSA_TEXT, CSA_LONGTEXT, VLC_TRUE );
00135     add_integer( "ts-csa-pkt", 188, NULL, CPKT_TEXT, CPKT_LONGTEXT, VLC_TRUE );    
00136     add_bool( "ts-silent", 0, NULL, SILENT_TEXT, SILENT_LONGTEXT, VLC_TRUE );
00137 
00138     add_file( "ts-dump-file", NULL, NULL, TSDUMP_TEXT, TSDUMP_LONGTEXT, VLC_FALSE );
00139     add_bool( "ts-dump-append", 0, NULL, APPEND_TEXT, APPEND_LONGTEXT, VLC_FALSE );
00140     add_integer( "ts-dump-size", 16384, NULL, DUMPSIZE_TEXT,
00141                  DUMPSIZE_LONGTEXT, VLC_TRUE );
00142 
00143     set_capability( "demux2", 10 );
00144     set_callbacks( Open, Close );
00145     add_shortcut( "ts" );
00146 vlc_module_end();
00147 
00148 /*****************************************************************************
00149  * Local prototypes
00150  *****************************************************************************/
00151 
00152 typedef struct
00153 {
00154     uint8_t                 i_objectTypeIndication;
00155     uint8_t                 i_streamType;
00156     vlc_bool_t              b_upStream;
00157     uint32_t                i_bufferSizeDB;
00158     uint32_t                i_maxBitrate;
00159     uint32_t                i_avgBitrate;
00160 
00161     int                     i_decoder_specific_info_len;
00162     uint8_t                 *p_decoder_specific_info;
00163 
00164 } decoder_config_descriptor_t;
00165 
00166 typedef struct
00167 {
00168     vlc_bool_t              b_useAccessUnitStartFlag;
00169     vlc_bool_t              b_useAccessUnitEndFlag;
00170     vlc_bool_t              b_useRandomAccessPointFlag;
00171     vlc_bool_t              b_useRandomAccessUnitsOnlyFlag;
00172     vlc_bool_t              b_usePaddingFlag;
00173     vlc_bool_t              b_useTimeStampsFlags;
00174     vlc_bool_t              b_useIdleFlag;
00175     vlc_bool_t              b_durationFlag;
00176     uint32_t                i_timeStampResolution;
00177     uint32_t                i_OCRResolution;
00178     uint8_t                 i_timeStampLength;
00179     uint8_t                 i_OCRLength;
00180     uint8_t                 i_AU_Length;
00181     uint8_t                 i_instantBitrateLength;
00182     uint8_t                 i_degradationPriorityLength;
00183     uint8_t                 i_AU_seqNumLength;
00184     uint8_t                 i_packetSeqNumLength;
00185 
00186     uint32_t                i_timeScale;
00187     uint16_t                i_accessUnitDuration;
00188     uint16_t                i_compositionUnitDuration;
00189 
00190     uint64_t                i_startDecodingTimeStamp;
00191     uint64_t                i_startCompositionTimeStamp;
00192 
00193 } sl_config_descriptor_t;
00194 
00195 typedef struct
00196 {
00197     vlc_bool_t              b_ok;
00198     uint16_t                i_es_id;
00199 
00200     vlc_bool_t              b_streamDependenceFlag;
00201     vlc_bool_t              b_OCRStreamFlag;
00202     uint8_t                 i_streamPriority;
00203 
00204     char                    *psz_url;
00205 
00206     uint16_t                i_dependOn_es_id;
00207     uint16_t                i_OCR_es_id;
00208 
00209     decoder_config_descriptor_t    dec_descr;
00210     sl_config_descriptor_t         sl_descr;
00211 
00212 } es_mpeg4_descriptor_t;
00213 
00214 typedef struct
00215 {
00216     uint8_t                i_iod_label, i_iod_label_scope;
00217 
00218     /* IOD */
00219     uint16_t                i_od_id;
00220     char                    *psz_url;
00221 
00222     uint8_t                 i_ODProfileLevelIndication;
00223     uint8_t                 i_sceneProfileLevelIndication;
00224     uint8_t                 i_audioProfileLevelIndication;
00225     uint8_t                 i_visualProfileLevelIndication;
00226     uint8_t                 i_graphicsProfileLevelIndication;
00227 
00228     es_mpeg4_descriptor_t   es_descr[255];
00229 
00230 } iod_descriptor_t;
00231 
00232 typedef struct
00233 {
00234     dvbpsi_handle   handle;
00235 
00236     int             i_version;
00237     int             i_number;
00238     int             i_pid_pcr;
00239     int             i_pid_pmt;
00240     /* IOD stuff (mpeg4) */
00241     iod_descriptor_t *iod;
00242 
00243 } ts_prg_psi_t;
00244 
00245 typedef struct
00246 {
00247     /* for special PAT/SDT case */
00248     dvbpsi_handle   handle; /* PAT/SDT/EIT */
00249     int             i_pat_version;
00250     int             i_sdt_version;
00251 
00252     /* For PMT */
00253     int             i_prg;
00254     ts_prg_psi_t    **prg;
00255 
00256 } ts_psi_t;
00257 
00258 typedef struct
00259 {
00260     es_format_t  fmt;
00261     es_out_id_t *id;
00262     int         i_pes_size;
00263     int         i_pes_gathered;
00264     block_t     *p_pes;
00265     block_t     **pp_last;
00266 
00267     es_mpeg4_descriptor_t *p_mpeg4desc;
00268     int         b_gather;
00269 
00270 } ts_es_t;
00271 
00272 typedef struct
00273 {
00274     int         i_pid;
00275 
00276     vlc_bool_t  b_seen;
00277     vlc_bool_t  b_valid;
00278     int         i_cc;   /* countinuity counter */
00279 
00280     /* PSI owner (ie PMT -> PAT, ES -> PMT */
00281     ts_psi_t   *p_owner;
00282     int         i_owner_number;
00283 
00284     /* */
00285     ts_psi_t    *psi;
00286     ts_es_t     *es;
00287 
00288     /* Some private streams encapsulate several ES (eg. DVB subtitles)*/
00289     ts_es_t     **extra_es;
00290     int         i_extra_es;
00291 
00292 } ts_pid_t;
00293 
00294 struct demux_sys_t
00295 {
00296     /* TS packet size (188, 192, 204) */
00297     int         i_packet_size;
00298 
00299     /* how many TS packet we read at once */
00300     int         i_ts_read;
00301 
00302     /* All pid */
00303     ts_pid_t    pid[8192];
00304 
00305     /* All PMT */
00306     int         i_pmt;
00307     ts_pid_t    **pmt;
00308 
00309     /* */
00310     vlc_bool_t  b_es_id_pid;
00311     csa_t       *csa;
00312     int         i_csa_pkt_size;
00313     vlc_bool_t  b_silent;
00314 
00315     vlc_bool_t  b_udp_out;
00316     int         fd; /* udp socket */
00317     uint8_t     *buffer;
00318 
00319     vlc_bool_t  b_dvb_control;
00320     int         i_dvb_program;
00321     vlc_list_t  *p_programs_list;
00322 
00323     /* TS dump */
00324     char        *psz_file;  /* file to dump data in */
00325     FILE        *p_file;    /* filehandle */
00326     uint64_t    i_write;    /* bytes written */
00327     vlc_bool_t  b_file_out; /* dump mode enabled */
00328     
00329     /* */
00330     vlc_bool_t  b_meta;
00331 };
00332 
00333 static int Demux    ( demux_t *p_demux );
00334 static int DemuxFile( demux_t *p_demux );
00335 static int Control( demux_t *p_demux, int i_query, va_list args );
00336 
00337 static void PIDInit ( ts_pid_t *pid, vlc_bool_t b_psi, ts_psi_t *p_owner );
00338 static void PIDClean( es_out_t *out, ts_pid_t *pid );
00339 static int  PIDFillFormat( ts_pid_t *pid, int i_stream_type );
00340 
00341 static void PATCallBack( demux_t *, dvbpsi_pat_t * );
00342 static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt );
00343 #ifdef TS_USE_DVB_SI
00344 static void PSINewTableCallBack( demux_t *, dvbpsi_handle,
00345                                  uint8_t  i_table_id, uint16_t i_extension );
00346 #endif
00347 
00348 static inline int PIDGet( block_t *p )
00349 {
00350     return ( (p->p_buffer[1]&0x1f)<<8 )|p->p_buffer[2];
00351 }
00352 
00353 static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk );
00354 
00355 static void PCRHandle( demux_t *p_demux, ts_pid_t *, block_t * );
00356 
00357 static iod_descriptor_t *IODNew( int , uint8_t * );
00358 static void              IODFree( iod_descriptor_t * );
00359 
00360 #define TS_PACKET_SIZE_188 188
00361 #define TS_PACKET_SIZE_192 192
00362 #define TS_PACKET_SIZE_204 204
00363 #define TS_PACKET_SIZE_MAX 204
00364 
00365 /*****************************************************************************
00366  * Open
00367  *****************************************************************************/
00368 static int Open( vlc_object_t *p_this )
00369 {
00370     demux_t     *p_demux = (demux_t*)p_this;
00371     demux_sys_t *p_sys;
00372 
00373     uint8_t     *p_peek;
00374     int          i_sync, i_peek, i;
00375     int          i_packet_size;
00376 
00377     ts_pid_t    *pat;
00378     char        *psz_mode;
00379     vlc_bool_t   b_append;
00380 
00381     vlc_value_t  val;
00382 
00383     if( stream_Peek( p_demux->s, &p_peek, TS_PACKET_SIZE_MAX ) <
00384         TS_PACKET_SIZE_MAX ) return VLC_EGENERIC;
00385 
00386     /* Search first sync byte */
00387     for( i_sync = 0; i_sync < TS_PACKET_SIZE_MAX; i_sync++ )
00388     {
00389         if( p_peek[i_sync] == 0x47 ) break;
00390     }
00391     if( i_sync >= TS_PACKET_SIZE_MAX )
00392     {
00393         if( strcmp( p_demux->psz_demux, "ts" ) ) return VLC_EGENERIC;
00394         msg_Warn( p_demux, "this does not look like a TS stream, continuing" );
00395     }
00396 
00397     /* Check next 3 sync bytes */
00398     i_peek = TS_PACKET_SIZE_MAX * 3 + i_sync + 1;
00399     if( ( stream_Peek( p_demux->s, &p_peek, i_peek ) ) < i_peek )
00400     {
00401         msg_Err( p_demux, "cannot peek" );
00402         return VLC_EGENERIC;
00403     }
00404     if( p_peek[i_sync + TS_PACKET_SIZE_188] == 0x47 &&
00405         p_peek[i_sync + 2 * TS_PACKET_SIZE_188] == 0x47 &&
00406         p_peek[i_sync + 3 * TS_PACKET_SIZE_188] == 0x47 )
00407     {
00408         i_packet_size = TS_PACKET_SIZE_188;
00409     }
00410     else if( p_peek[i_sync + TS_PACKET_SIZE_192] == 0x47 &&
00411              p_peek[i_sync + 2 * TS_PACKET_SIZE_192] == 0x47 &&
00412              p_peek[i_sync + 3 * TS_PACKET_SIZE_192] == 0x47 )
00413     {
00414         i_packet_size = TS_PACKET_SIZE_192;
00415     }
00416     else if( p_peek[i_sync + TS_PACKET_SIZE_204] == 0x47 &&
00417              p_peek[i_sync + 2 * TS_PACKET_SIZE_204] == 0x47 &&
00418              p_peek[i_sync + 3 * TS_PACKET_SIZE_204] == 0x47 )
00419     {
00420         i_packet_size = TS_PACKET_SIZE_204;
00421     }
00422     else if( !strcmp( p_demux->psz_demux, "ts" ) )
00423     {
00424         i_packet_size = TS_PACKET_SIZE_188;
00425     }
00426     else
00427     {
00428         msg_Warn( p_demux, "TS module discarded (lost sync)" );
00429         return VLC_EGENERIC;
00430     }
00431 
00432     p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
00433     memset( p_sys, 0, sizeof( demux_sys_t ) );
00434     p_sys->i_packet_size = i_packet_size;
00435 
00436     /* Fill dump mode fields */
00437     p_sys->i_write = 0;
00438     p_sys->p_file = NULL;
00439     p_sys->b_file_out = VLC_FALSE;
00440     p_sys->psz_file = var_CreateGetString( p_demux, "ts-dump-file" );
00441     if( *p_sys->psz_file != '\0' )
00442     {
00443         p_sys->b_file_out = VLC_TRUE;
00444 
00445         var_Create( p_demux, "ts-dump-append", VLC_VAR_BOOL|VLC_VAR_DOINHERIT );
00446         var_Get( p_demux, "ts-dump-append", &val );
00447         b_append = val.b_bool;
00448         if ( b_append )
00449             psz_mode = "ab";
00450         else
00451             psz_mode = "wb";
00452 
00453         if( !strcmp( p_sys->psz_file, "-" ) )
00454         {
00455             msg_Info( p_demux, "dumping raw stream to standard output" );
00456             p_sys->p_file = stdout;
00457         }
00458         else if( ( p_sys->p_file = fopen( p_sys->psz_file, psz_mode ) ) == NULL )
00459         {
00460             msg_Err( p_demux, "cannot create `%s' for writing", p_sys->psz_file );
00461             p_sys->b_file_out = VLC_FALSE;
00462         }
00463 
00464         if( p_sys->b_file_out )
00465         {
00466             vlc_value_t bufsize;
00467 
00468             /* Determine how many packets to read. */
00469             var_Create( p_demux, "ts-dump-size",
00470                         VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
00471             var_Get( p_demux, "ts-dump-size", &bufsize );
00472             p_sys->i_ts_read = (int) (bufsize.i_int / p_sys->i_packet_size);
00473             if( p_sys->i_ts_read <= 0 )
00474             {
00475                 p_sys->i_ts_read = 1500 / p_sys->i_packet_size;
00476             }
00477             p_sys->buffer = malloc( p_sys->i_packet_size * p_sys->i_ts_read );
00478             msg_Info( p_demux, "%s raw stream to file `%s' reading packets %d",
00479                       b_append ? "appending" : "dumping", p_sys->psz_file,
00480                       p_sys->i_ts_read );
00481         }
00482     }
00483 
00484     /* Fill p_demux field */
00485     if( p_sys->b_file_out )
00486         p_demux->pf_demux = DemuxFile;
00487     else
00488         p_demux->pf_demux = Demux;
00489     p_demux->pf_control = Control;
00490 
00491     /* Init p_sys field */
00492     p_sys->b_meta = VLC_TRUE;
00493     p_sys->b_dvb_control = VLC_TRUE;
00494     p_sys->i_dvb_program = 0;
00495     for( i = 0; i < 8192; i++ )
00496     {
00497         ts_pid_t *pid = &p_sys->pid[i];
00498 
00499         pid->i_pid      = i;
00500         pid->b_seen     = VLC_FALSE;
00501         pid->b_valid    = VLC_FALSE;
00502     }
00503     /* PID 8191 is padding */
00504     p_sys->pid[8191].b_seen = VLC_TRUE;
00505     p_sys->i_packet_size = i_packet_size;
00506     p_sys->b_udp_out = VLC_FALSE;
00507     p_sys->i_ts_read = 50;
00508     p_sys->csa = NULL;
00509 
00510     /* Init PAT handler */
00511     pat = &p_sys->pid[0];
00512     PIDInit( pat, VLC_TRUE, NULL );
00513     pat->psi->handle = dvbpsi_AttachPAT( (dvbpsi_pat_callback)PATCallBack,
00514                                          p_demux );
00515 #ifdef TS_USE_DVB_SI
00516     if( p_sys->b_meta )
00517     {
00518         ts_pid_t *sdt = &p_sys->pid[0x11];
00519         ts_pid_t *eit = &p_sys->pid[0x12];
00520 
00521         PIDInit( sdt, VLC_TRUE, NULL );
00522         sdt->psi->handle =
00523             dvbpsi_AttachDemux( (dvbpsi_demux_new_cb_t)PSINewTableCallBack,
00524                                 p_demux );
00525         PIDInit( eit, VLC_TRUE, NULL );
00526         eit->psi->handle =
00527             dvbpsi_AttachDemux( (dvbpsi_demux_new_cb_t)PSINewTableCallBack,
00528                                 p_demux );
00529         if( p_sys->b_dvb_control )
00530         {
00531             stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
00532                             ACCESS_SET_PRIVATE_ID_STATE, 0x11, VLC_TRUE );
00533             stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
00534                             ACCESS_SET_PRIVATE_ID_STATE, 0x12, VLC_TRUE );
00535         }
00536     }
00537 #endif
00538 
00539     /* Init PMT array */
00540     p_sys->i_pmt = 0;
00541     p_sys->pmt   = NULL;
00542 
00543     /* Read config */
00544     var_Create( p_demux, "ts-es-id-pid", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
00545     var_Get( p_demux, "ts-es-id-pid", &val );
00546     p_sys->b_es_id_pid = val.b_bool;
00547 
00548     var_Create( p_demux, "ts-out", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
00549     var_Get( p_demux, "ts-out", &val );
00550     if( val.psz_string && *val.psz_string && !p_sys->b_file_out )
00551     {
00552         vlc_value_t mtu;
00553         char *psz = strchr( val.psz_string, ':' );
00554         int   i_port = 0;
00555 
00556         p_sys->b_udp_out = VLC_TRUE;
00557 
00558         if( psz )
00559         {
00560             *psz++ = '\0';
00561             i_port = atoi( psz );
00562         }
00563         if( i_port <= 0 ) i_port  = 1234;
00564         msg_Dbg( p_demux, "resend ts to '%s:%d'", val.psz_string, i_port );
00565 
00566         p_sys->fd = net_OpenUDP( p_demux, "", 0, val.psz_string, i_port );
00567         if( p_sys->fd < 0 )
00568         {
00569             msg_Err( p_demux, "failed to open udp socket, send disabled" );
00570             p_sys->b_udp_out = VLC_FALSE;
00571         }
00572         else
00573         {
00574             var_Create( p_demux, "ts-out-mtu",
00575                         VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
00576             var_Get( p_demux, "ts-out-mtu", &mtu );
00577             p_sys->i_ts_read = mtu.i_int / p_sys->i_packet_size;
00578             if( p_sys->i_ts_read <= 0 )
00579             {
00580                 p_sys->i_ts_read = 1500 / p_sys->i_packet_size;
00581             }
00582             p_sys->buffer = malloc( p_sys->i_packet_size * p_sys->i_ts_read );
00583         }
00584     }
00585     if( val.psz_string )
00586     {
00587         free( val.psz_string );
00588     }
00589 
00590     /* We handle description of an extra PMT */
00591     var_Create( p_demux, "ts-extra-pmt", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
00592     var_Get( p_demux, "ts-extra-pmt", &val );
00593     if( val.psz_string && strchr( val.psz_string, '=' ) != NULL )
00594     {
00595         char *psz = val.psz_string;
00596         int  i_pid = strtol( psz, &psz, 0 );
00597 
00598         if( i_pid >= 2 && i_pid < 8192 )
00599         {
00600             ts_pid_t *pmt = &p_sys->pid[i_pid];
00601 
00602             msg_Dbg( p_demux, "extra pmt specified (pid=%d)", i_pid );
00603             PIDInit( pmt, VLC_TRUE, NULL );
00604             pmt->psi->i_prg = 1;
00605             pmt->psi->prg = malloc( sizeof(ts_prg_psi_t) );
00606             /* FIXME we should also ask for a number */
00607             pmt->psi->prg[0]->handle =
00608                 dvbpsi_AttachPMT( 1, (dvbpsi_pmt_callback)PMTCallBack,
00609                                   p_demux );
00610             pmt->psi->prg[0]->i_number = 0; /* special one */
00611 
00612             psz = strchr( psz, '=' ) + 1;   /* can't failed */
00613             while( psz && *psz )
00614             {
00615                 char *psz_next = strchr( psz, ',' );
00616                 int i_pid, i_stream_type;
00617 
00618                 if( psz_next )
00619                 {
00620                     *psz_next++ = '\0';
00621                 }
00622 
00623                 i_pid = strtol( psz, &psz, 0 );
00624                 if( *psz == ':' )
00625                 {
00626                     i_stream_type = strtol( psz + 1, &psz, 0 );
00627                     if( i_pid >= 2 && i_pid < 8192 &&
00628                         !p_sys->pid[i_pid].b_valid )
00629                     {
00630                         ts_pid_t *pid = &p_sys->pid[i_pid];
00631 
00632                         PIDInit( pid, VLC_FALSE, pmt->psi);
00633                         if( pmt->psi->prg[0]->i_pid_pcr <= 0 )
00634                         {
00635                             pmt->psi->prg[0]->i_pid_pcr = i_pid;
00636                         }
00637                         PIDFillFormat( pid, i_stream_type);
00638                         if( pid->es->fmt.i_cat != UNKNOWN_ES )
00639                         {
00640                             if( p_sys->b_es_id_pid )
00641                             {
00642                                 pid->es->fmt.i_id = i_pid;
00643                             }
00644                             msg_Dbg( p_demux, "  * es pid=%d type=%d "
00645                                      "fcc=%4.4s", i_pid, i_stream_type,
00646                                      (char*)&pid->es->fmt.i_codec );
00647                             pid->es->id = es_out_Add( p_demux->out,
00648                                                       &pid->es->fmt );
00649                         }
00650                     }
00651                 }
00652                 psz = psz_next;
00653             }
00654         }
00655     }
00656     if( val.psz_string )
00657     {
00658         free( val.psz_string );
00659     }
00660 
00661     var_Create( p_demux, "ts-csa-ck", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
00662     var_Get( p_demux, "ts-csa-ck", &val );
00663     if( val.psz_string && *val.psz_string )
00664     {
00665         char *psz = val.psz_string;
00666         if( psz[0] == '0' && ( psz[1] == 'x' || psz[1] == 'X' ) )
00667         {
00668             psz += 2;
00669         }
00670         if( strlen( psz ) != 16 )
00671         {
00672             msg_Warn( p_demux, "invalid csa ck (it must be 16 chars long)" );
00673         }
00674         else
00675         {
00676 #ifndef UNDER_CE
00677             uint64_t i_ck = strtoull( psz, NULL, 16 );
00678 #else
00679             uint64_t i_ck = strtoll( psz, NULL, 16 );
00680 #endif
00681             uint8_t ck[8];
00682             int     i;
00683             for( i = 0; i < 8; i++ )
00684             {
00685                 ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
00686             }
00687 #ifndef TS_NO_CSA_CK_MSG
00688             msg_Dbg( p_demux, "using CSA scrambling with "
00689                      "ck=%x:%x:%x:%x:%x:%x:%x:%x",
00690                      ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
00691 #endif
00692             p_sys->csa = csa_New();
00693 
00694             if( p_sys->csa )
00695             {
00696                 vlc_value_t pkt_val;
00697 
00698                 csa_SetCW( p_sys->csa, ck, ck );
00699 
00700                 var_Create( p_demux, "ts-csa-pkt", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
00701                 var_Get( p_demux, "ts-csa-pkt", &pkt_val );
00702                 if( pkt_val.i_int < 4 || pkt_val.i_int > 188 )
00703                 {
00704                     msg_Err( p_demux, "wrong packet size %d specified.", pkt_val.i_int );
00705                     msg_Warn( p_demux, "using default packet size of 188 bytes" );
00706                     p_sys->i_csa_pkt_size = 188;
00707                 }
00708                 else p_sys->i_csa_pkt_size = pkt_val.i_int;
00709                 msg_Dbg( p_demux, "decrypting %d bytes of packet", p_sys->i_csa_pkt_size );
00710             }
00711         }
00712     }
00713     if( val.psz_string )
00714     {
00715         free( val.psz_string );
00716     }
00717 
00718     var_Create( p_demux, "ts-silent", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
00719     var_Get( p_demux, "ts-silent", &val );
00720     p_sys->b_silent = val.b_bool;
00721 
00722     return VLC_SUCCESS;
00723 }
00724 
00725 /*****************************************************************************
00726  * Close
00727  *****************************************************************************/
00728 static void Close( vlc_object_t *p_this )
00729 {
00730     demux_t     *p_demux = (demux_t*)p_this;
00731     demux_sys_t *p_sys = p_demux->p_sys;
00732 
00733     int          i;
00734 
00735     msg_Dbg( p_demux, "pid list:" );
00736     for( i = 0; i < 8192; i++ )
00737     {
00738         ts_pid_t *pid = &p_sys->pid[i];
00739 
00740         if( pid->b_valid && pid->psi )
00741         {
00742             switch( pid->i_pid )
00743             {
00744                 case 0: /* PAT */
00745                     dvbpsi_DetachPAT( pid->psi->handle );
00746                     free( pid->psi );
00747                     break;
00748                 case 1: /* CAT */
00749                     free( pid->psi );
00750                     break;
00751                 case 0x11: /* SDT */
00752                 case 0x12: /* EIT */
00753                     dvbpsi_DetachDemux( pid->psi->handle );
00754                     free( pid->psi );
00755                     break;
00756                 default:
00757                     PIDClean( p_demux->out, pid );
00758                     break;
00759             }
00760         }
00761         else if( pid->b_valid && pid->es )
00762         {
00763             PIDClean( p_demux->out, pid );
00764         }
00765 
00766         if( pid->b_seen )
00767         {
00768             msg_Dbg( p_demux, "  - pid[%d] seen", pid->i_pid );
00769         }
00770 
00771         if( p_sys->b_dvb_control && pid->i_pid > 0 )
00772         {
00773             /* too much */
00774             stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, ACCESS_SET_PRIVATE_ID_STATE, pid->i_pid, VLC_FALSE );
00775         }
00776 
00777     }
00778 
00779     if( p_sys->b_udp_out )
00780     {
00781         net_Close( p_sys->fd );
00782         free( p_sys->buffer );
00783     }
00784     if( p_sys->csa )
00785     {
00786         csa_Delete( p_sys->csa );
00787     }
00788 
00789     if( p_sys->i_pmt ) free( p_sys->pmt );
00790 
00791     if ( p_sys->p_programs_list )
00792     {
00793         vlc_value_t val;
00794         val.p_list = p_sys->p_programs_list;
00795         var_Change( p_demux, "programs", VLC_VAR_FREELIST, &val, NULL );
00796     }
00797 
00798     /* If in dump mode, then close the file */
00799     if( p_sys->b_file_out )
00800     {
00801         msg_Info( p_demux ,"closing %s ("I64Fd" Kbytes dumped)", p_sys->psz_file,
00802                   p_sys->i_write / 1024 );
00803 
00804         if( p_sys->p_file != stdout )
00805         {
00806             fclose( p_sys->p_file );
00807             p_sys->p_file = NULL;
00808         }
00809         free( p_sys->psz_file );
00810         p_sys->psz_file = NULL;
00811 
00812         free( p_sys->buffer );
00813     }
00814 
00815     free( p_sys );
00816 }
00817 
00818 /*****************************************************************************
00819  * DemuxFile:
00820  *****************************************************************************/
00821 static int DemuxFile( demux_t *p_demux )
00822 {
00823     demux_sys_t *p_sys = p_demux->p_sys;
00824     uint8_t     *p_buffer = p_sys->buffer; /* Put first on sync byte */
00825     int i_diff= 0;
00826     int i_data= 0;
00827     int i_pos = 0;
00828     int i_bufsize = p_sys->i_packet_size * p_sys->i_ts_read;
00829 
00830     i_data = stream_Read( p_demux->s, p_sys->buffer, i_bufsize );
00831     if( (i_data <= 0) && (i_data < p_sys->i_packet_size) )
00832     {
00833         msg_Dbg( p_demux, "Error reading malformed packets" );
00834         return i_data;
00835     }
00836 
00837     /* Test continuity counter */
00838     while( i_pos < i_data )
00839     {
00840         ts_pid_t    *p_pid;   /* point to a PID structure */
00841         vlc_bool_t b_payload; /* indicates a packet with payload */
00842         vlc_bool_t b_adaptation; /* adaptation field */
00843         int i_cc  = 0;        /* continuity counter */
00844 
00845         if( p_sys->buffer[i_pos] != 0x47 )
00846         {
00847             msg_Warn( p_demux, "lost sync" );
00848             while( !p_demux->b_die && (i_pos < i_data) )
00849             {
00850                 i_pos++;
00851                 if( p_sys->buffer[i_pos] == 0x47 )
00852                     break;
00853             }
00854             if( !p_demux->b_die )
00855                 msg_Warn( p_demux, "sync found" );
00856         }
00857 
00858         /* continuous when (one of this):
00859          * diff == 1
00860          * diff == 0 and payload == 0
00861          * diff == 0 and duplicate packet (playload != 0) <- should we
00862          *   test the content ?
00863          */
00864         i_cc  = p_buffer[i_pos+3]&0x0f;
00865         b_payload = p_buffer[i_pos+3]&0x10;
00866         b_adaptation = p_buffer[i_pos+3]&0x20;
00867 
00868         /* Get the PID */
00869         p_pid = &p_sys->pid[ ((p_buffer[i_pos+1]&0x1f)<<8)|p_buffer[i_pos+2] ];
00870 
00871         /* Detect discontinuity indicator in adaptation field */
00872         if( b_adaptation )
00873         {
00874             if( p_buffer[i_pos+5]&0x80 )
00875                 msg_Warn( p_demux, "discontinuity indicator (pid=%d) ", p_pid->i_pid );
00876             if( p_buffer[i_pos+5]&0x40 )
00877                 msg_Warn( p_demux, "random access indicator (pid=%d) ", p_pid->i_pid );
00878         }
00879 
00880         i_diff = ( i_cc - p_pid->i_cc )&0x0f;
00881         if( b_payload && i_diff == 1 )
00882         {
00883             p_pid->i_cc++;
00884         }
00885         else
00886         {
00887             if( p_pid->i_cc == 0xff )
00888             {
00889                 msg_Warn( p_demux, "first packet for pid=%d cc=0x%x",
00890                         p_pid->i_pid, i_cc );
00891                 p_pid->i_cc = i_cc;
00892             }
00893             else if( i_diff != 0 )
00894             {
00895                 /* FIXME what to do when discontinuity_indicator is set ? */
00896                 msg_Warn( p_demux, "transport error detected 0x%x instead of 0x%x",
00897                           i_cc, ( p_pid->i_cc + 1 )&0x0f );
00898 
00899                 p_pid->i_cc = i_cc;
00900                 /* Mark transport error in the TS packet. */
00901                 p_buffer[i_pos+1] |= 0x80;
00902             }
00903         }
00904 
00905         /* Test if user wants to decrypt it first */
00906         if( p_sys->csa )
00907             csa_Decrypt( p_demux->p_sys->csa, &p_buffer[i_pos], p_demux->p_sys->i_csa_pkt_size );
00908 
00909         i_pos += p_sys->i_packet_size;
00910     }
00911 
00912     /* Then write */
00913     i_data = fwrite( p_sys->buffer, 1, i_data, p_sys->p_file );
00914     if( i_data < 0 )
00915     {
00916         msg_Err( p_demux, "failed to write data" );
00917         return -1;
00918     }
00919 #if 0
00920     msg_Dbg( p_demux, "dumped %d bytes", i_data );
00921 #endif
00922 
00923     p_sys->i_write += i_data;
00924     return 1;
00925 }
00926 
00927 /*****************************************************************************
00928  * Demux:
00929  *****************************************************************************/
00930 static int Demux( demux_t *p_demux )
00931 {
00932     demux_sys_t *p_sys = p_demux->p_sys;
00933     int          i_pkt;
00934 
00935     /* We read at most 100 TS packet or until a frame is completed */
00936     for( i_pkt = 0; i_pkt < p_sys->i_ts_read; i_pkt++ )
00937     {
00938         vlc_bool_t  b_frame = VLC_FALSE;
00939         block_t     *p_pkt;
00940         ts_pid_t    *p_pid;
00941 
00942         /* Get a new TS packet */
00943         if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) )
00944         {
00945             msg_Dbg( p_demux, "eof ?" );
00946             return 0;
00947         }
00948 
00949         /* Check sync byte and re-sync if needed */
00950         if( p_pkt->p_buffer[0] != 0x47 )
00951         {
00952             msg_Warn( p_demux, "lost synchro" );
00953             block_Release( p_pkt );
00954 
00955             while( !p_demux->b_die )
00956             {
00957                 uint8_t *p_peek;
00958                 int i_peek, i_skip = 0;
00959 
00960                 i_peek = stream_Peek( p_demux->s, &p_peek,
00961                                       p_sys->i_packet_size * 10 );
00962                 if( i_peek < p_sys->i_packet_size + 1 )
00963                 {
00964                     msg_Dbg( p_demux, "eof ?" );
00965                     return 0;
00966                 }
00967 
00968                 while( i_skip < i_peek - p_sys->i_packet_size )
00969                 {
00970                     if( p_peek[i_skip] == 0x47 &&
00971                         p_peek[i_skip + p_sys->i_packet_size] == 0x47 )
00972                     {
00973                         break;
00974                     }
00975                     i_skip++;
00976                 }
00977 
00978                 msg_Dbg( p_demux, "skipping %d bytes of garbage", i_skip );
00979                 stream_Read( p_demux->s, NULL, i_skip );
00980 
00981                 if( i_skip < i_peek - p_sys->i_packet_size )
00982                 {
00983                     break;
00984                 }
00985             }
00986 
00987             if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) )
00988             {
00989                 msg_Dbg( p_demux, "eof ?" );
00990                 return 0;
00991             }
00992         }
00993 
00994         if( p_sys->b_udp_out )
00995         {
00996             memcpy( &p_sys->buffer[i_pkt * p_sys->i_packet_size],
00997                     p_pkt->p_buffer, p_sys->i_packet_size );
00998         }
00999 
01000         /* Parse the TS packet */
01001         p_pid = &p_sys->pid[PIDGet( p_pkt )];
01002 
01003         if( p_pid->b_valid )
01004         {
01005             if( p_pid->psi )
01006             {
01007                 if( p_pid->i_pid == 0 || p_pid->i_pid == 0x11 || p_pid->i_pid == 0x12 )
01008                 {
01009                     dvbpsi_PushPacket( p_pid->psi->handle, p_pkt->p_buffer );
01010                 }
01011                 else
01012                 {
01013                     int i_prg;
01014                     for( i_prg = 0; i_prg < p_pid->psi->i_prg; i_prg++ )
01015                     {
01016                         dvbpsi_PushPacket( p_pid->psi->prg[i_prg]->handle,
01017                                            p_pkt->p_buffer );
01018                     }
01019                 }
01020                 block_Release( p_pkt );
01021             }
01022             else if( !p_sys->b_udp_out )
01023             {
01024                 b_frame = GatherPES( p_demux, p_pid, p_pkt );
01025             }
01026             else
01027             {
01028                 PCRHandle( p_demux, p_pid, p_pkt );
01029                 block_Release( p_pkt );
01030             }
01031         }
01032         else
01033         {
01034             if( !p_pid->b_seen )
01035             {
01036                 msg_Dbg( p_demux, "pid[%d] unknown", p_pid->i_pid );
01037             }
01038             /* We have to handle PCR if present */
01039             PCRHandle( p_demux, p_pid, p_pkt );
01040             block_Release( p_pkt );
01041         }
01042         p_pid->b_seen = VLC_TRUE;
01043 
01044         if( b_frame )
01045         {
01046             break;
01047         }
01048     }
01049 
01050     if( p_sys->b_udp_out )
01051     {
01052         /* Send the complete block */
01053         net_Write( p_demux, p_sys->fd, NULL, p_sys->buffer,
01054                    p_sys->i_ts_read * p_sys->i_packet_size );
01055     }
01056 
01057     return 1;
01058 }
01059 
01060 /*****************************************************************************
01061  * Control:
01062  *****************************************************************************/
01063 static int Control( demux_t *p_demux, int i_query, va_list args )
01064 {
01065     demux_sys_t *p_sys = p_demux->p_sys;
01066     double f, *pf;
01067     int64_t i64;
01068     int64_t *pi64;
01069     int i_int;
01070 
01071     if( p_sys->b_file_out )
01072         return demux2_vaControlHelper( p_demux->s, 0, -1, 0, 1, i_query, args );
01073 
01074     switch( i_query )
01075     {
01076         case DEMUX_GET_POSITION:
01077             pf = (double*) va_arg( args, double* );
01078             i64 = stream_Size( p_demux->s );
01079             if( i64 > 0 )
01080             {
01081                 *pf = (double)stream_Tell( p_demux->s ) / (double)i64;
01082             }
01083             else
01084             {
01085                 *pf = 0.0;
01086             }
01087             return VLC_SUCCESS;
01088         case DEMUX_SET_POSITION:
01089             f = (double) va_arg( args, double );
01090             i64 = stream_Size( p_demux->s );
01091 
01092             es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
01093             if( stream_Seek( p_demux->s, (int64_t)(i64 * f) ) )
01094             {
01095                 return VLC_EGENERIC;
01096             }
01097             return VLC_SUCCESS;
01098 #if 0
01099 
01100         case DEMUX_GET_TIME:
01101             pi64 = (int64_t*)va_arg( args, int64_t * );
01102             if( p_sys->i_time < 0 )
01103             {
01104                 *pi64 = 0;
01105                 return VLC_EGENERIC;
01106             }
01107             *pi64 = p_sys->i_time;
01108             return VLC_SUCCESS;
01109 
01110         case DEMUX_GET_LENGTH:
01111             pi64 = (int64_t*)va_arg( args, int64_t * );
01112             if( p_sys->i_mux_rate > 0 )
01113             {
01114                 *pi64 = I64C(1000000) * ( stream_Size( p_demux->s ) / 50 ) /
01115                         p_sys->i_mux_rate;
01116                 return VLC_SUCCESS;
01117             }
01118             *pi64 = 0;
01119             return VLC_EGENERIC;
01120 #else
01121         case DEMUX_GET_TIME:
01122         case DEMUX_GET_LENGTH:
01123             pi64 = (int64_t*)va_arg( args, int64_t * );
01124             *pi64 = 0;
01125             return VLC_SUCCESS;
01126 #endif
01127         case DEMUX_SET_GROUP:
01128         {
01129             uint16_t i_vpid = 0, i_apid1 = 0, i_apid2 = 0, i_apid3 = 0;
01130             ts_prg_psi_t *p_prg = NULL;
01131             vlc_list_t *p_list;
01132 
01133             i_int = (int)va_arg( args, int );
01134             p_list = (vlc_list_t *)va_arg( args, vlc_list_t * );
01135             msg_Dbg( p_demux, "DEMUX_SET_GROUP %d %p", i_int, p_list );
01136 
01137             if( p_sys->b_dvb_control && i_int > 0 && i_int != p_sys->i_dvb_program )
01138             {
01139                 int i_pmt_pid = -1;
01140                 int i;
01141 
01142                 /* Search pmt to be unselected */
01143                 for( i = 0; i < p_sys->i_pmt; i++ )
01144                 {
01145                     ts_pid_t *pmt = p_sys->pmt[i];
01146                     int i_prg;
01147 
01148                     for( i_prg = 0; i_prg < pmt->psi->i_prg; i_prg++ )
01149                     {
01150                         if( pmt->psi->prg[i_prg]->i_number == p_sys->i_dvb_program )
01151                         {
01152                             i_pmt_pid = p_sys->pmt[i]->i_pid;
01153                             break;
01154                         }
01155                     }
01156                     if( i_pmt_pid > 0 ) break;
01157                 }
01158 
01159                 if( i_pmt_pid > 0 )
01160                 {
01161                     stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
01162                                     ACCESS_SET_PRIVATE_ID_STATE, i_pmt_pid,
01163                                     VLC_FALSE );
01164                     /* All ES */
01165                     for( i = 2; i < 8192; i++ )
01166                     {
01167                         ts_pid_t *pid = &p_sys->pid[i];
01168                         int i_prg;
01169 
01170                         if( !pid->b_valid || pid->psi ) continue;
01171 
01172                         for( i_prg = 0; i_prg < pid->p_owner->i_prg; i_prg++ )
01173                         {
01174                             if( pid->p_owner->prg[i_prg]->i_pid_pmt == i_pmt_pid && pid->es->id )
01175                             {
01176                                 /* We only remove es that aren't defined by extra pmt */
01177                                 stream_Control( p_demux->s,
01178                                                 STREAM_CONTROL_ACCESS,
01179                                                 ACCESS_SET_PRIVATE_ID_STATE,
01180                                                 i, VLC_FALSE );
01181                                 break;
01182                             }
01183                         }
01184                     }
01185                 }
01186 
01187                 /* select new program */
01188                 p_sys->i_dvb_program = i_int;
01189                 i_pmt_pid = -1;
01190                 for( i = 0; i < p_sys->i_pmt; i++ )
01191                 {
01192                     ts_pid_t *pmt = p_sys->pmt[i];
01193                     int i_prg;
01194 
01195                     for( i_prg = 0; i_prg < pmt->psi->i_prg; i_prg++ )
01196                     {
01197                         if( pmt->psi->prg[i_prg]->i_number == i_int )
01198                         {
01199                             i_pmt_pid = p_sys->pmt[i]->i_pid;
01200                             p_prg = p_sys->pmt[i]->psi->prg[i_prg];
01201                             break;
01202                         }
01203                     }
01204                     if( i_pmt_pid > 0 ) break;
01205                 }
01206                 if( i_pmt_pid > 0 )
01207                 {
01208                     stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
01209                                     ACCESS_SET_PRIVATE_ID_STATE, i_pmt_pid,
01210                                     VLC_TRUE );
01211                     stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
01212                                     ACCESS_SET_PRIVATE_ID_STATE, p_prg->i_pid_pcr,
01213                                     VLC_TRUE );
01214 
01215                     for( i = 2; i < 8192; i++ )
01216                     {
01217                         ts_pid_t *pid = &p_sys->pid[i];
01218                         int i_prg;
01219 
01220                         if( !pid->b_valid || pid->psi ) continue;
01221 
01222                         for( i_prg = 0; i_prg < pid->p_owner->i_prg; i_prg++ )
01223                         {
01224                             if( pid->p_owner->prg[i_prg]->i_pid_pmt == i_pmt_pid && pid->es->id )
01225                             {
01226                                 if ( pid->es->fmt.i_cat == VIDEO_ES && !i_vpid )
01227                                     i_vpid = i;
01228                                 if ( pid->es->fmt.i_cat == AUDIO_ES && !i_apid1 )
01229                                     i_apid1 = i;
01230                                 else if ( pid->es->fmt.i_cat == AUDIO_ES && !i_apid2 )
01231                                     i_apid2 = i;
01232                                 else if ( pid->es->fmt.i_cat == AUDIO_ES && !i_apid3 )
01233                                     i_apid3 = i;
01234 
01235                                 stream_Control( p_demux->s,
01236                                                 STREAM_CONTROL_ACCESS,
01237                                                 ACCESS_SET_PRIVATE_ID_STATE,
01238                                                 i, VLC_TRUE );
01239                                 break;
01240                             }
01241                         }
01242                     }
01243                 }
01244             }
01245             else
01246             {
01247                 p_sys->i_dvb_program = -1;
01248                 p_sys->p_programs_list = p_list;
01249             }
01250             return VLC_SUCCESS;
01251         }
01252 
01253         case DEMUX_GET_FPS:
01254         case DEMUX_SET_TIME:
01255         default:
01256             return VLC_EGENERIC;
01257     }
01258 }
01259 
01260 static void PIDInit( ts_pid_t *pid, vlc_bool_t b_psi, ts_psi_t *p_owner )
01261 {
01262     vlc_bool_t b_old_valid = pid->b_valid;
01263 
01264     pid->b_valid    = VLC_TRUE;
01265     pid->i_cc       = 0xff;
01266     pid->p_owner    = p_owner;
01267     pid->i_owner_number = 0;
01268 
01269     pid->extra_es   = NULL;
01270     pid->i_extra_es = 0;
01271 
01272     if( b_psi )
01273     {
01274         pid->es  = NULL;
01275 
01276         if( !b_old_valid )
01277         {
01278             pid->psi = malloc( sizeof( ts_psi_t ) );
01279             pid->psi->handle= NULL;
01280             pid->psi->i_prg = 0;
01281             pid->psi->prg   = NULL;
01282         }
01283         pid->psi->i_pat_version  = -1;
01284         pid->psi->i_sdt_version  = -1;
01285         if( p_owner )
01286         {
01287             ts_prg_psi_t *prg = malloc( sizeof( ts_prg_psi_t ) );
01288             /* PMT */
01289             prg->i_version  = -1;
01290             prg->i_number   = -1;
01291             prg->i_pid_pcr  = -1;
01292             prg->i_pid_pmt  = -1;
01293             prg->iod        = NULL;
01294             prg->handle     = NULL;
01295 
01296             TAB_APPEND( pid->psi->i_prg, pid->psi->prg, prg );
01297         }
01298     }
01299     else
01300     {
01301         pid->psi = NULL;
01302         pid->es  = malloc( sizeof( ts_es_t ) );
01303 
01304         es_format_Init( &pid->es->fmt, UNKNOWN_ES, 0 );
01305         pid->es->id      = NULL;
01306         pid->es->p_pes   = NULL;
01307         pid->es->i_pes_size= 0;
01308         pid->es->i_pes_gathered= 0;
01309         pid->es->pp_last = &pid->es->p_pes;
01310         pid->es->p_mpeg4desc = NULL;
01311         pid->es->b_gather = VLC_FALSE;
01312     }
01313 }
01314 
01315 static void PIDClean( es_out_t *out, ts_pid_t *pid )
01316 {
01317     if( pid->psi )
01318     {
01319         int i;
01320 
01321         if( pid->psi->handle ) dvbpsi_DetachPMT( pid->psi->handle );
01322         for( i = 0; i < pid->psi->i_prg; i++ )
01323         {
01324             if( pid->psi->prg[i]->iod )
01325                 IODFree( pid->psi->prg[i]->iod );
01326             if( pid->psi->prg[i]->handle )
01327                 dvbpsi_DetachPMT( pid->psi->prg[i]->handle );
01328             free( pid->psi->prg[i] );
01329         }
01330         if( pid->psi->prg ) free( pid->psi->prg );
01331         free( pid->psi );
01332     }
01333     else
01334     {
01335         int i;
01336 
01337         if( pid->es->id )
01338             es_out_Del( out, pid->es->id );
01339 
01340         if( pid->es->p_pes )
01341             block_ChainRelease( pid->es->p_pes );
01342 
01343         es_format_Clean( &pid->es->fmt );
01344 
01345         free( pid->es );
01346 
01347         for( i = 0; i < pid->i_extra_es; i++ )
01348         {
01349             if( pid->extra_es[i]->id )
01350                 es_out_Del( out, pid->extra_es[i]->id );
01351 
01352             if( pid->extra_es[i]->p_pes )
01353                 block_ChainRelease( pid->extra_es[i]->p_pes );
01354 
01355             es_format_Clean( &pid->extra_es[i]->fmt );
01356 
01357             free( pid->extra_es[i] );
01358         }
01359         if( pid->i_extra_es ) free( pid->extra_es );
01360     }
01361 
01362     pid->b_valid = VLC_FALSE;
01363 }
01364 
01365 /****************************************************************************
01366  * gathering stuff
01367  ****************************************************************************/
01368 static void ParsePES( demux_t *p_demux, ts_pid_t *pid )
01369 {
01370     block_t *p_pes = pid->es->p_pes;
01371     uint8_t header[30];
01372     int     i_pes_size = 0;
01373     int     i_skip = 0;
01374     mtime_t i_dts = -1;
01375     mtime_t i_pts = -1;
01376     mtime_t i_length = 0;
01377     int i_max;
01378 
01379     /* remove the pes from pid */
01380     pid->es->p_pes = NULL;
01381     pid->es->i_pes_size= 0;
01382     pid->es->i_pes_gathered= 0;
01383     pid->es->pp_last = &pid->es->p_pes;
01384 
01385     /* FIXME find real max size */
01386     i_max = block_ChainExtract( p_pes, header, 30 );
01387 
01388 
01389     if( header[0] != 0 || header[1] != 0 || header[2] != 1 )
01390     {
01391         if( !p_demux->p_sys->b_silent )
01392             msg_Warn( p_demux, "invalid header [0x%x:%x:%x:%x] (pid: %d)",
01393                       header[0], header[1],header[2],header[3], pid->i_pid );
01394         block_ChainRelease( p_pes );
01395         return;
01396     }
01397 
01398     /* TODO check size */
01399     switch( header[3] )
01400     {
01401         case 0xBC:  /* Program stream map */
01402         case 0xBE:  /* Padding */
01403         case 0xBF:  /* Private stream 2 */
01404         case 0xB0:  /* ECM */
01405         case 0xB1:  /* EMM */
01406         case 0xFF:  /* Program stream directory */
01407         case 0xF2:  /* DSMCC stream */
01408         case 0xF8:  /* ITU-T H.222.1 type E stream */
01409             i_skip = 6;
01410             break;
01411         default:
01412             if( ( header[6]&0xC0 ) == 0x80 )
01413             {
01414                 /* mpeg2 PES */
01415                 i_skip = header[8] + 9;
01416 
01417                 if( header[7]&0x80 )    /* has pts */
01418                 {
01419                     i_pts = ((mtime_t)(header[ 9]&0x0e ) << 29)|
01420                              (mtime_t)(header[10] << 22)|
01421                             ((mtime_t)(header[11]&0xfe) << 14)|
01422                              (mtime_t)(header[12] << 7)|
01423                              (mtime_t)(header[13] >> 1);
01424 
01425                     if( header[7]&0x40 )    /* has dts */
01426                     {
01427                          i_dts = ((mtime_t)(header[14]&0x0e ) << 29)|
01428                                  (mtime_t)(header[15] << 22)|
01429                                 ((mtime_t)(header[16]&0xfe) << 14)|
01430                                  (mtime_t)(header[17] << 7)|
01431                                  (mtime_t)(header[18] >> 1);
01432                     }
01433                 }
01434             }
01435             else
01436             {
01437                 i_skip = 6;
01438                 while( i_skip < 23 && header[i_skip] == 0xff )
01439                 {
01440                     i_skip++;
01441                 }
01442                 if( i_skip == 23 )
01443                 {
01444                     msg_Err( p_demux, "too much MPEG-1 stuffing" );
01445                     block_ChainRelease( p_pes );
01446                     return;
01447                 }
01448                 if( ( header[i_skip] & 0xC0 ) == 0x40 )
01449                 {
01450                     i_skip += 2;
01451                 }
01452 
01453                 if(  header[i_skip]&0x20 )
01454                 {
01455                      i_pts = ((mtime_t)(header[i_skip]&0x0e ) << 29)|
01456                               (mtime_t)(header[i_skip+1] << 22)|
01457                              ((mtime_t)(header[i_skip+2]&0xfe) << 14)|
01458                               (mtime_t)(header[i_skip+3] << 7)|
01459                               (mtime_t)(header[i_skip+4] >> 1);
01460 
01461                     if( header[i_skip]&0x10 )    /* has dts */
01462                     {
01463                          i_dts = ((mtime_t)(header[i_skip+5]&0x0e ) << 29)|
01464                                   (mtime_t)(header[i_skip+6] << 22)|
01465                                  ((mtime_t)(header[i_skip+7]&0xfe) << 14)|
01466                                   (mtime_t)(header[i_skip+8] << 7)|
01467                                   (mtime_t)(header[i_skip+9] >> 1);
01468                          i_skip += 10;
01469                     }
01470                     else
01471                     {
01472                         i_skip += 5;
01473                     }
01474                 }
01475                 else
01476                 {
01477                     i_skip += 1;
01478                 }
01479             }
01480             break;
01481     }
01482 
01483     if( pid->es->fmt.i_codec == VLC_FOURCC( 'a', '5', '2', 'b' ) ||
01484         pid->es->fmt.i_codec == VLC_FOURCC( 'd', 't', 's', 'b' ) )
01485     {
01486         i_skip += 4;
01487     }
01488     else if( pid->es->fmt.i_codec == VLC_FOURCC( 'l', 'p', 'c', 'b' ) ||
01489              pid->es->fmt.i_codec == VLC_FOURCC( 's', 'p', 'u', 'b' ) ||
01490              pid->es->fmt.i_codec == VLC_FOURCC( 's', 'd', 'd', 'b' ) )
01491     {
01492         i_skip += 1;
01493     }
01494     else if( pid->es->fmt.i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) &&
01495              pid->es->p_mpeg4desc )
01496     {
01497         decoder_config_descriptor_t *dcd = &pid->es->p_mpeg4desc->dec_descr;
01498 
01499         if( dcd->i_decoder_specific_info_len > 2 &&
01500             dcd->p_decoder_specific_info[0] == 0x10 &&
01501             ( dcd->p_decoder_specific_info[1]&0x10 ) )
01502         {
01503             /* display length */
01504             if( p_pes->i_buffer + 2 <= i_skip )
01505             {
01506                 i_length = GetWBE( &p_pes->p_buffer[i_skip] );
01507             }
01508 
01509             i_skip += 2;
01510         }
01511         if( p_pes->i_buffer + 2 <= i_skip )
01512         {
01513             i_pes_size = GetWBE( &p_pes->p_buffer[i_skip] );
01514         }
01515         /* */
01516         i_skip += 2;
01517     }
01518 
01519     /* skip header */
01520     while( p_pes && i_skip > 0 )
01521     {
01522         if( p_pes->i_buffer <= i_skip )
01523         {
01524             block_t *p_next = p_pes->p_next;
01525 
01526             i_skip -= p_pes->i_buffer;
01527             block_Release( p_pes );
01528             p_pes = p_next;
01529         }
01530         else
01531         {
01532             p_pes->i_buffer -= i_skip;
01533             p_pes->p_buffer += i_skip;
01534             break;
01535         }
01536     }
01537 
01538     /* ISO/IEC 13818-1 2.7.5: if no pts and no dts, then dts == pts */
01539     if( i_pts >= 0 && i_dts < 0 )
01540         i_dts = i_pts;
01541 
01542     if( p_pes )
01543     {
01544         block_t *p_block;
01545         int i;
01546 
01547         if( i_dts >= 0 )
01548         {
01549             p_pes->i_dts = i_dts * 100 / 9;
01550         }
01551         if( i_pts >= 0 )
01552         {
01553             p_pes->i_pts = i_pts * 100 / 9;
01554         }
01555         p_pes->i_length = i_length * 100 / 9;
01556 
01557         p_block = block_ChainGather( p_pes );
01558         if( pid->es->fmt.i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) )
01559         {
01560             if( i_pes_size > 0 && p_block->i_buffer > i_pes_size )
01561             {
01562                 p_block->i_buffer = i_pes_size;
01563             }
01564             /* Append a \0 */
01565             p_block = block_Realloc( p_block, 0, p_block->i_buffer + 1 );
01566             p_block->p_buffer[p_block->i_buffer -1] = '\0';
01567         }
01568 
01569         for( i = 0; i < pid->i_extra_es; i++ )
01570         {
01571             es_out_Send( p_demux->out, pid->extra_es[i]->id,
01572                          block_Duplicate( p_block ) );
01573         }
01574 
01575         es_out_Send( p_demux->out, pid->es->id, p_block );
01576     }
01577     else
01578     {
01579         msg_Warn( p_demux, "empty pes" );
01580     }
01581 }
01582 
01583 static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
01584 {
01585     demux_sys_t   *p_sys = p_demux->p_sys;
01586     const uint8_t *p = p_bk->p_buffer;
01587 
01588     if( ( p[3]&0x20 ) && /* adaptation */
01589         ( p[5]&0x10 ) &&
01590         ( p[4] >= 7 ) )
01591     {
01592         int i;
01593         mtime_t i_pcr;  /* 33 bits */
01594 
01595         i_pcr = ( (mtime_t)p[6] << 25 ) |
01596                 ( (mtime_t)p[7] << 17 ) |
01597                 ( (mtime_t)p[8] << 9 ) |
01598                 ( (mtime_t)p[9] << 1 ) |
01599                 ( (mtime_t)p[10] >> 7 );
01600 
01601         /* Search program and set the PCR */
01602         for( i = 0; i < p_sys->i_pmt; i++ )
01603         {
01604             int i_prg;
01605             for( i_prg = 0; i_prg < p_sys->pmt[i]->psi->i_prg; i_prg++ )
01606             {
01607                 if( pid->i_pid == p_sys->pmt[i]->psi->prg[i_prg]->i_pid_pcr )
01608                 {
01609                     es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR,
01610                                     (int)p_sys->pmt[i]->psi->prg[i_prg]->i_number,
01611                                     (int64_t)(i_pcr * 100 / 9) );
01612                 }
01613             }
01614         }
01615     }
01616 }
01617 
01618 static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
01619 {
01620     const uint8_t    *p = p_bk->p_buffer;
01621     const vlc_bool_t b_unit_start = p[1]&0x40;
01622     const vlc_bool_t b_adaptation = p[3]&0x20;
01623     const vlc_bool_t b_payload    = p[3]&0x10;
01624     const int        i_cc         = p[3]&0x0f;   /* continuity counter */
01625     vlc_bool_t       b_discontinuity = VLC_FALSE;/* discontinuity */    
01626 
01627     /* transport_scrambling_control is ignored */
01628     int         i_skip = 0;
01629     vlc_bool_t  i_ret  = VLC_FALSE;
01630     int         i_diff;
01631 
01632 #if 0
01633     msg_Dbg( p_demux, "pid=%d unit_start=%d adaptation=%d payload=%d "
01634              "cc=0x%x", pid->i_pid, b_unit_start, b_adaptation,
01635              b_payload, i_cc );
01636 #endif
01637 
01638     /* For now, ignore additional error correction
01639      * TODO: handle Reed-Solomon 204,188 error correction */
01640     p_bk->i_buffer = TS_PACKET_SIZE_188;
01641 
01642     if( p[1]&0x80 )
01643     {
01644         msg_Dbg( p_demux, "transport_error_indicator set (pid=%d)",
01645                  pid->i_pid );
01646         if( pid->es->p_pes ) //&& pid->es->fmt.i_cat == VIDEO_ES )
01647             pid->es->p_pes->i_flags |= BLOCK_FLAG_CORRUPTED;
01648     }
01649 
01650     if( p_demux->p_sys->csa )
01651     {
01652         csa_Decrypt( p_demux->p_sys->csa, p_bk->p_buffer, p_demux->p_sys->i_csa_pkt_size );
01653     }
01654 
01655     if( !b_adaptation )
01656     {
01657         /* We don't have any adaptation_field, so payload starts
01658          * immediately after the 4 byte TS header */
01659         i_skip = 4;
01660     }
01661     else
01662     {
01663         /* p[4] is adaptation_field_length minus one */
01664         i_skip = 5 + p[4];
01665         if( p[4] > 0 )
01666         {
01667             /* discontinuity indicator found in stream */
01668             b_discontinuity = (p[5]&0x80) ? VLC_TRUE : VLC_FALSE;
01669             if( b_discontinuity && pid->es->p_pes )
01670             {
01671                 msg_Warn( p_demux, "discontinuity indicator (pid=%d) ",
01672                             pid->i_pid );
01673                 /* pid->es->p_pes->i_flags |= BLOCK_FLAG_DISCONTINUITY; */
01674             }
01675 #if 0
01676             if( p[5]&0x40 )
01677                 msg_Dbg( p_demux, "random access indicator (pid=%d) ", pid->i_pid );
01678 #endif
01679         }
01680     }
01681 
01682     /* Test continuity counter */
01683     /* continuous when (one of this):
01684         * diff == 1
01685         * diff == 0 and payload == 0
01686         * diff == 0 and duplicate packet (playload != 0) <- should we
01687         *   test the content ?
01688      */
01689     i_diff = ( i_cc - pid->i_cc )&0x0f;
01690     if( b_payload && i_diff == 1 )
01691     {
01692         pid->i_cc++;
01693     }
01694     else
01695     {
01696         if( pid->i_cc == 0xff )
01697         {
01698             msg_Warn( p_demux, "first packet for pid=%d cc=0x%x",
01699                       pid->i_pid, i_cc );
01700             pid->i_cc = i_cc;
01701         }
01702         else if( i_diff != 0 && !b_discontinuity )
01703         {
01704             msg_Warn( p_demux, "discontinuity received 0x%x instead of 0x%x (pid=%d)",
01705                       i_cc, ( pid->i_cc + 1 )&0x0f, pid->i_pid );
01706 
01707             pid->i_cc = i_cc;
01708             if( pid->es->p_pes && pid->es->fmt.i_cat != VIDEO_ES )
01709             {
01710                 /* Small video artifacts are usually better then
01711                  * dropping full frames */
01712                 pid->es->p_pes->i_flags |= BLOCK_FLAG_CORRUPTED;
01713             }
01714         }
01715     }
01716 
01717     PCRHandle( p_demux, pid, p_bk );
01718 
01719     if( i_skip >= 188 || pid->es->id == NULL || p_demux->p_sys->b_udp_out )
01720     {
01721         block_Release( p_bk );
01722         return i_ret;
01723     }
01724 
01725     /* We have to gather it */
01726     p_bk->p_buffer += i_skip;
01727     p_bk->i_buffer -= i_skip;
01728 
01729     if( b_unit_start )
01730     {
01731         if( pid->es->p_pes )
01732         {
01733             ParsePES( p_demux, pid );
01734             i_ret = VLC_TRUE;
01735         }
01736 
01737         block_ChainLastAppend( &pid->es->pp_last, p_bk );
01738         if( p_bk->i_buffer > 6 )
01739         {
01740             pid->es->i_pes_size = GetWBE( &p_bk->p_buffer[4] );
01741             if( pid->es->i_pes_size > 0 )
01742             {
01743                 pid->es->i_pes_size += 6;
01744             }
01745         }
01746         pid->es->i_pes_gathered += p_bk->i_buffer;
01747         if( pid->es->i_pes_size > 0 &&
01748             pid->es->i_pes_gathered >= pid->es->i_pes_size )
01749         {
01750             ParsePES( p_demux, pid );
01751             i_ret = VLC_TRUE;
01752         }
01753     }
01754     else
01755     {
01756         if( pid->es->p_pes == NULL )
01757         {
01758             /* msg_Dbg( p_demux, "broken packet" ); */
01759             block_Release( p_bk );
01760         }
01761         else
01762         {
01763             block_ChainLastAppend( &pid->es->pp_last, p_bk );
01764             pid->es->i_pes_gathered += p_bk->i_buffer;
01765             if( pid->es->i_pes_size > 0 &&
01766                 pid->es->i_pes_gathered >= pid->es->i_pes_size )
01767             {
01768                 ParsePES( p_demux, pid );
01769                 i_ret = VLC_TRUE;
01770             }
01771         }
01772     }
01773 
01774     return i_ret;
01775 }
01776 
01777 static int PIDFillFormat( ts_pid_t *pid, int i_stream_type )
01778 {
01779     es_format_t *fmt = &pid->es->fmt;
01780 
01781     switch( i_stream_type )
01782     {
01783         case 0x01:  /* MPEG-1 video */
01784         case 0x02:  /* MPEG-2 video */
01785         case 0x80:  /* MPEG-2 MOTO video */
01786             es_format_Init( fmt, VIDEO_ES, VLC_FOURCC( 'm', 'p', 'g', 'v' ) );
01787             break;
01788         case 0x03:  /* MPEG-1 audio */
01789         case 0x04:  /* MPEG-2 audio */
01790             es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'm', 'p', 'g', 'a' ) );
01791             break;
01792         case 0x11:  /* MPEG4 (audio) */
01793         case 0x0f:  /* ISO/IEC 13818-7 Audio with ADTS transport syntax */
01794             es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'm', 'p', '4', 'a' ) );
01795             break;
01796         case 0x10:  /* MPEG4 (video) */
01797             es_format_Init( fmt, VIDEO_ES, VLC_FOURCC( 'm', 'p', '4', 'v' ) );
01798             pid->es->b_gather = VLC_TRUE;
01799             break;
01800         case 0x1B:  /* H264 <- check transport syntax/needed descriptor */
01801             es_format_Init( fmt, VIDEO_ES, VLC_FOURCC( 'h', '2', '6', '4' ) );
01802             break;
01803 
01804         case 0x81:  /* A52 (audio) */
01805             es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'a', '5', '2', ' ' ) );
01806             break;
01807         case 0x82:  /* DVD_SPU (sub) */
01808             es_format_Init( fmt, SPU_ES, VLC_FOURCC( 's', 'p', 'u', ' ' ) );
01809             break;
01810         case 0x83:  /* LPCM (audio) */
01811             es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'l', 'p', 'c', 'm' ) );
01812             break;
01813         case 0x84:  /* SDDS (audio) */
01814             es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 's', 'd', 'd', 's' ) );
01815             break;
01816         case 0x85:  /* DTS (audio) */
01817             es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'd', 't', 's', ' ' ) );
01818             break;
01819 
01820         case 0x91:  /* A52 vls (audio) */
01821             es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'a', '5', '2', 'b' ) );
01822             break;
01823         case 0x92:  /* DVD_SPU vls (sub) */
01824             es_format_Init( fmt, SPU_ES, VLC_FOURCC( 's', 'p', 'u', 'b' ) );
01825             break;
01826         case 0x93:  /* LPCM vls (audio) */
01827             es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'l', 'p', 'c', 'b' ) );
01828             break;
01829         case 0x94:  /* SDDS (audio) */
01830             es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 's', 'd', 'd', 'b' ) );
01831             break;
01832 
01833         case 0xa0:  /* MSCODEC vlc (video) (fixed later) */
01834             es_format_Init( fmt, UNKNOWN_ES, 0 );
01835             pid->es->b_gather = VLC_TRUE;
01836             break;
01837 
01838         case 0x06:  /* PES_PRIVATE  (fixed later) */
01839         case 0x12:  /* MPEG-4 generic (sub/scene/...) (fixed later) */
01840         default:
01841             es_format_Init( fmt, UNKNOWN_ES, 0 );
01842             break;
01843     }
01844 
01845     /* PES packets usually contain truncated frames */
01846     fmt->b_packetized = VLC_FALSE;
01847 
01848     return fmt->i_cat == UNKNOWN_ES ? VLC_EGENERIC : VLC_SUCCESS ;
01849 }
01850 
01851 /*****************************************************************************
01852  * MP4 specific functions (IOD parser)
01853  *****************************************************************************/
01854 static int  IODDescriptorLength( int *pi_data, uint8_t **pp_data )
01855 {
01856     unsigned int i_b;
01857     unsigned int i_len = 0;
01858     do
01859     {
01860         i_b = **pp_data;
01861         (*pp_data)++;
01862         (*pi_data)--;
01863         i_len = ( i_len << 7 ) + ( i_b&0x7f );
01864 
01865     } while( i_b&0x80 );
01866 
01867     return( i_len );
01868 }
01869 static int IODGetByte( int *pi_data, uint8_t **pp_data )
01870 {
01871     if( *pi_data > 0 )
01872     {
01873         const int i_b = **pp_data;
01874         (*pp_data)++;
01875         (*pi_data)--;
01876         return( i_b );
01877     }
01878     return( 0 );
01879 }
01880 static int IODGetWord( int *pi_data, uint8_t **pp_data )
01881 {
01882     const int i1 = IODGetByte( pi_data, pp_data );
01883     const int i2 = IODGetByte( pi_data, pp_data );
01884     return( ( i1 << 8 ) | i2 );
01885 }
01886 static int IODGet3Bytes( int *pi_data, uint8_t **pp_data )
01887 {
01888     const int i1 = IODGetByte( pi_data, pp_data );
01889     const int i2 = IODGetByte( pi_data, pp_data );
01890     const int i3 = IODGetByte( pi_data, pp_data );
01891 
01892     return( ( i1 << 16 ) | ( i2 << 8) | i3 );
01893 }
01894 
01895 static uint32_t IODGetDWord( int *pi_data, uint8_t **pp_data )
01896 {
01897     const uint32_t i1 = IODGetWord( pi_data, pp_data );
01898     const uint32_t i2 = IODGetWord( pi_data, pp_data );
01899     return( ( i1 << 16 ) | i2 );
01900 }
01901 
01902 static char* IODGetURL( int *pi_data, uint8_t **pp_data )
01903 {
01904     char *url;
01905     int i_url_len, i;
01906 
01907     i_url_len = IODGetByte( pi_data, pp_data );
01908     url = malloc( i_url_len + 1 );
01909     for( i = 0; i < i_url_len; i++ )
01910     {
01911         url[i] = IODGetByte( pi_data, pp_data );
01912     }
01913     url[i_url_len] = '\0';
01914     return( url );
01915 }
01916 
01917 static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
01918 {
01919     iod_descriptor_t *p_iod;
01920     int i;
01921     int i_es_index;
01922     uint8_t     i_flags, i_iod_tag, byte1, byte2, byte3;
01923     vlc_bool_t  b_url;
01924     int         i_iod_length;
01925 
01926     p_iod = malloc( sizeof( iod_descriptor_t ) );
01927     memset( p_iod, 0, sizeof( iod_descriptor_t ) );
01928 
01929 #ifdef DEBUG
01930     fprintf( stderr, "\n************ IOD ************" );
01931 #endif
01932     for( i = 0; i < 255; i++ )
01933     {
01934         p_iod->es_descr[i].b_ok = 0;
01935     }
01936     i_es_index = 0;
01937 
01938     if( i_data < 3 )
01939     {
01940         return p_iod;
01941     }
01942 
01943     byte1 = IODGetByte( &i_data, &p_data );
01944     byte2 = IODGetByte( &i_data, &p_data );
01945     byte3 = IODGetByte( &i_data, &p_data );
01946     if( byte2 == 0x02 ) //old vlc's buggy implementation of the IOD_descriptor
01947     {
01948         p_iod->i_iod_label_scope = 0x11;
01949         p_iod->i_iod_label = byte1;
01950         i_iod_tag = byte2;
01951     }
01952     else                //correct implementation of the IOD_descriptor
01953     {
01954         p_iod->i_iod_label_scope = byte1;
01955         p_iod->i_iod_label = byte2;
01956         i_iod_tag = byte3;
01957     }
01958 #ifdef DEBUG
01959     fprintf( stderr, "\n* iod_label:%d", p_iod->i_iod_label );
01960     fprintf( stderr, "\n* ===========" );
01961     fprintf( stderr, "\n* tag:0x%x", i_iod_tag );
01962 #endif
01963     if( i_iod_tag != 0x02 )
01964     {
01965 #ifdef DEBUG
01966         fprintf( stderr, "\n ERR: tag %02x != 0x02", i_iod_tag );
01967 #endif
01968         return p_iod;
01969     }
01970 
01971     i_iod_length = IODDescriptorLength( &i_data, &p_data );
01972 #ifdef DEBUG
01973     fprintf( stderr, "\n* length:%d", i_iod_length );
01974 #endif
01975     if( i_iod_length > i_data )
01976     {
01977         i_iod_length = i_data;
01978     }
01979 
01980     p_iod->i_od_id = ( IODGetByte( &i_data, &p_data ) << 2 );
01981     i_flags = IODGetByte( &i_data, &p_data );
01982     p_iod->i_od_id |= i_flags >> 6;
01983     b_url = ( i_flags >> 5  )&0x01;
01984 #ifdef DEBUG
01985     fprintf( stderr, "\n* od_id:%d", p_iod->i_od_id );
01986     fprintf( stderr, "\n* url flag:%d", b_url );
01987     fprintf( stderr, "\n* includeInlineProfileLevel flag:%d", ( i_flags >> 4 )&0x01 );
01988 #endif
01989     if( b_url )
01990     {
01991         p_iod->psz_url = IODGetURL( &i_data, &p_data );
01992 #ifdef DEBUG
01993         fprintf( stderr, "\n* url string:%s", p_iod->psz_url );
01994         fprintf( stderr, "\n*****************************\n" );
01995 #endif
01996         return p_iod;
01997     }
01998     else
01999     {
02000         p_iod->psz_url = NULL;
02001     }
02002 
02003     p_iod->i_ODProfileLevelIndication = IODGetByte( &i_data, &p_data );
02004     p_iod->i_sceneProfileLevelIndication = IODGetByte( &i_data, &p_data );
02005     p_iod->i_audioProfileLevelIndication = IODGetByte( &i_data, &p_data );
02006     p_iod->i_visualProfileLevelIndication = IODGetByte( &i_data, &p_data );
02007     p_iod->i_graphicsProfileLevelIndication = IODGetByte( &i_data, &p_data );
02008 #ifdef DEBUG
02009     fprintf( stderr, "\n* ODProfileLevelIndication:%d", p_iod->i_ODProfileLevelIndication );
02010     fprintf( stderr, "\n* sceneProfileLevelIndication:%d", p_iod->i_sceneProfileLevelIndication );
02011     fprintf( stderr, "\n* audioProfileLevelIndication:%d", p_iod->i_audioProfileLevelIndication );
02012     fprintf( stderr, "\n* visualProfileLevelIndication:%d", p_iod->i_visualProfileLevelIndication );
02013     fprintf( stderr, "\n* graphicsProfileLevelIndication:%d", p_iod->i_graphicsProfileLevelIndication );
02014 #endif
02015 
02016     while( i_data > 0 && i_es_index < 255)
02017     {
02018         int i_tag, i_length;
02019         int     i_data_sav;
02020         uint8_t *p_data_sav;
02021 
02022         i_tag = IODGetByte( &i_data, &p_data );
02023         i_length = IODDescriptorLength( &i_data, &p_data );
02024 
02025         i_data_sav = i_data;
02026         p_data_sav = p_data;
02027 
02028         i_data = i_length;
02029 
02030         switch( i_tag )
02031         {
02032             case 0x03:
02033                 {
02034 #define es_descr    p_iod->es_descr[i_es_index]
02035                     int i_decoderConfigDescr_length;
02036 #ifdef DEBUG
02037                     fprintf( stderr, "\n* - ES_Descriptor length:%d", i_length );
02038 #endif
02039                     es_descr.b_ok = 1;
02040 
02041                     es_descr.i_es_id = IODGetWord( &i_data, &p_data );
02042                     i_flags = IODGetByte( &i_data, &p_data );
02043                     es_descr.b_streamDependenceFlag = ( i_flags >> 7 )&0x01;
02044                     b_url = ( i_flags >> 6 )&0x01;
02045                     es_descr.b_OCRStreamFlag = ( i_flags >> 5 )&0x01;
02046                     es_descr.i_streamPriority = i_flags & 0x1f;
02047 #ifdef DEBUG
02048                     fprintf( stderr, "\n*   * streamDependenceFlag:%d", es_descr.b_streamDependenceFlag );
02049                     fprintf( stderr, "\n*   * OCRStreamFlag:%d", es_descr.b_OCRStreamFlag );
02050                     fprintf( stderr, "\n*   * streamPriority:%d", es_descr.i_streamPriority );
02051 #endif
02052                     if( es_descr.b_streamDependenceFlag )
02053                     {
02054                         es_descr.i_dependOn_es_id = IODGetWord( &i_data, &p_data );
02055 #ifdef DEBUG
02056                         fprintf( stderr, "\n*   * dependOn_es_id:%d", es_descr.i_dependOn_es_id );
02057 #endif
02058                     }
02059 
02060                     if( b_url )
02061                     {
02062                         es_descr.psz_url = IODGetURL( &i_data, &p_data );
02063 #ifdef DEBUG
02064                         fprintf( stderr, "\n* url string:%s", es_descr.psz_url );
02065 #endif
02066                     }
02067                     else
02068                     {
02069                         es_descr.psz_url = NULL;
02070                     }
02071 
02072                     if( es_descr.b_OCRStreamFlag )
02073                     {
02074                         es_descr.i_OCR_es_id = IODGetWord( &i_data, &p_data );
02075 #ifdef DEBUG
02076                         fprintf( stderr, "\n*   * OCR_es_id:%d", es_descr.i_OCR_es_id );
02077 #endif
02078                     }
02079 
02080                     if( IODGetByte( &i_data, &p_data ) != 0x04 )
02081                     {
02082 #ifdef DEBUG
02083                         fprintf( stderr, "\n* ERR missing DecoderConfigDescr" );
02084 #endif
02085                         es_descr.b_ok = 0;
02086                         break;
02087                     }
02088                     i_decoderConfigDescr_length = IODDescriptorLength( &i_data, &p_data );
02089 #ifdef DEBUG
02090                     fprintf( stderr, "\n*   - DecoderConfigDesc length:%d", i_decoderConfigDescr_length );
02091 #endif
02092 #define dec_descr   es_descr.dec_descr
02093                     dec_descr.i_objectTypeIndication = IODGetByte( &i_data, &p_data );
02094                     i_flags = IODGetByte( &i_data, &p_data );
02095                     dec_descr.i_streamType = i_flags >> 2;
02096                     dec_descr.b_upStream = ( i_flags >> 1 )&0x01;
02097                     dec_descr.i_bufferSizeDB = IODGet3Bytes( &i_data, &p_data );
02098                     dec_descr.i_maxBitrate = IODGetDWord( &i_data, &p_data );
02099                     dec_descr.i_avgBitrate = IODGetDWord( &i_data, &p_data );
02100 #ifdef DEBUG
02101                     fprintf( stderr, "\n*     * objectTypeIndication:0x%x", dec_descr.i_objectTypeIndication  );
02102                     fprintf( stderr, "\n*     * streamType:0x%x", dec_descr.i_streamType );
02103                     fprintf( stderr, "\n*     * upStream:%d", dec_descr.b_upStream );
02104                     fprintf( stderr, "\n*     * bufferSizeDB:%d", dec_descr.i_bufferSizeDB );
02105                     fprintf( stderr, "\n*     * maxBitrate:%d", dec_descr.i_maxBitrate );
02106                     fprintf( stderr, "\n*     * avgBitrate:%d", dec_descr.i_avgBitrate );
02107 #endif
02108                     if( i_decoderConfigDescr_length > 13 && IODGetByte( &i_data, &p_data ) == 0x05 )
02109                     {
02110                         int i;
02111                         dec_descr.i_decoder_specific_info_len =
02112                             IODDescriptorLength( &i_data, &p_data );
02113                         if( dec_descr.i_decoder_specific_info_len > 0 )
02114                         {
02115                             dec_descr.p_decoder_specific_info =
02116                                 malloc( dec_descr.i_decoder_specific_info_len );
02117                         }
02118                         for( i = 0; i < dec_descr.i_decoder_specific_info_len; i++ )
02119                         {
02120                             dec_descr.p_decoder_specific_info[i] = IODGetByte( &i_data, &p_data );
02121                         }
02122                     }
02123                     else
02124                     {
02125                         dec_descr.i_decoder_specific_info_len = 0;
02126                         dec_descr.p_decoder_specific_info = NULL;
02127                     }
02128                 }
02129 #undef  dec_descr
02130 #define sl_descr    es_descr.sl_descr
02131                 {
02132                     int i_SLConfigDescr_length;
02133                     int i_predefined;
02134 
02135                     if( IODGetByte( &i_data, &p_data ) != 0x06 )
02136                     {
02137 #ifdef DEBUG
02138                         fprintf( stderr, "\n* ERR missing SLConfigDescr" );
02139 #endif
02140                         es_descr.b_ok = 0;
02141                         break;
02142                     }
02143                     i_SLConfigDescr_length = IODDescriptorLength( &i_data, &p_data );
02144 #ifdef DEBUG
02145                     fprintf( stderr, "\n*   - SLConfigDescr length:%d", i_SLConfigDescr_length );
02146 #endif
02147                     i_predefined = IODGetByte( &i_data, &p_data );
02148 #ifdef DEBUG
02149                     fprintf( stderr, "\n*     * i_predefined:0x%x", i_predefined  );
02150 #endif
02151                     switch( i_predefined )
02152                     {
02153                         case 0x01:
02154                             {
02155                                 sl_descr.b_useAccessUnitStartFlag   = 0;
02156                                 sl_descr.b_useAccessUnitEndFlag     = 0;
02157                                 sl_descr.b_useRandomAccessPointFlag = 0;
02158                                 //sl_descr.b_useRandomAccessUnitsOnlyFlag = 0;
02159                                 sl_descr.b_usePaddingFlag           = 0;
02160                                 sl_descr.b_useTimeStampsFlags       = 0;
02161                                 sl_descr.b_useIdleFlag              = 0;
02162                                 sl_descr.b_durationFlag     = 0;    // FIXME FIXME
02163                                 sl_descr.i_timeStampResolution      = 1000;
02164                                 sl_descr.i_OCRResolution    = 0;    // FIXME FIXME
02165                                 sl_descr.i_timeStampLength          = 32;
02166                                 sl_descr.i_OCRLength        = 0;    // FIXME FIXME
02167                                 sl_descr.i_AU_Length                = 0;
02168                                 sl_descr.i_instantBitrateLength= 0; // FIXME FIXME
02169                                 sl_descr.i_degradationPriorityLength= 0;
02170                                 sl_descr.i_AU_seqNumLength          = 0;
02171                                 sl_descr.i_packetSeqNumLength       = 0;
02172                                 if( sl_descr.b_durationFlag )
02173                                 {
02174                                     sl_descr.i_timeScale            = 0;    // FIXME FIXME
02175                                     sl_descr.i_accessUnitDuration   = 0;    // FIXME FIXME
02176                                     sl_descr.i_compositionUnitDuration= 0;    // FIXME FIXME
02177                                 }
02178                                 if( !sl_descr.b_useTimeStampsFlags )
02179                                 {
02180                                     sl_descr.i_startDecodingTimeStamp   = 0;    // FIXME FIXME
02181                                     sl_descr.i_startCompositionTimeStamp= 0;    // FIXME FIXME
02182                                 }
02183                             }
02184                             break;
02185                         default:
02186 #ifdef DEBUG
02187                             fprintf( stderr, "\n* ERR unsupported SLConfigDescr predefined" );
02188 #endif
02189                             es_descr.b_ok = 0;
02190                             break;
02191                     }
02192                 }
02193                 break;
02194 #undef  sl_descr
02195 #undef  es_descr
02196             default:
02197 #ifdef DEBUG
02198                 fprintf( stderr, "\n* - OD tag:0x%x length:%d (Unsupported)", i_tag, i_length );
02199 #endif
02200                 break;
02201         }
02202 
02203         p_data = p_data_sav + i_length;
02204         i_data = i_data_sav - i_length;
02205         i_es_index++;
02206     }
02207 #ifdef DEBUG
02208     fprintf( stderr, "\n*****************************\n" );
02209 #endif
02210     return p_iod;
02211 }
02212 
02213 static void IODFree( iod_descriptor_t *p_iod )
02214 {
02215     int i;
02216 
02217     if( p_iod->psz_url )
02218     {
02219         free( p_iod->psz_url );
02220         p_iod->psz_url = NULL;
02221         free( p_iod );
02222         return;
02223     }
02224 
02225     for( i = 0; i < 255; i++ )
02226     {
02227 #define es_descr p_iod->es_descr[i]
02228         if( es_descr.b_ok )
02229         {
02230             if( es_descr.psz_url )
02231             {
02232                 free( es_descr.psz_url );
02233                 es_descr.psz_url = NULL;
02234             }
02235             else
02236             {
02237                 if( es_descr.dec_descr.p_decoder_specific_info != NULL )
02238                 {
02239                     free( es_descr.dec_descr.p_decoder_specific_info );
02240                     es_descr.dec_descr.p_decoder_specific_info = NULL;
02241                     es_descr.dec_descr.i_decoder_specific_info_len = 0;
02242                 }
02243             }
02244         }
02245         es_descr.b_ok = 0;
02246 #undef  es_descr
02247     }
02248     free( p_iod );
02249 }
02250 
02251 /****************************************************************************
02252  ****************************************************************************
02253  ** libdvbpsi callbacks
02254  ****************************************************************************
02255  ****************************************************************************/
02256 static vlc_bool_t DVBProgramIsSelected( demux_t *p_demux, uint16_t i_pgrm )
02257 {
02258     demux_sys_t          *p_sys = p_demux->p_sys;
02259 
02260     if ( !p_sys->b_dvb_control ) return VLC_FALSE;
02261     if ( (p_sys->i_dvb_program == -1 && p_sys->p_programs_list == NULL)
02262            || p_sys->i_dvb_program == 0 )
02263         return VLC_TRUE;
02264     if ( p_sys->i_dvb_program == i_pgrm ) return VLC_TRUE;
02265 
02266     if ( p_sys->p_programs_list != NULL )
02267     {
02268         int i;
02269         for ( i = 0; i < p_sys->p_programs_list->i_count; i++ )
02270         {
02271             if ( i_pgrm == p_sys->p_programs_list->p_values[i].i_int )
02272                 return VLC_TRUE;
02273         }
02274     }
02275     return VLC_FALSE;
02276 }
02277 
02278 #ifdef TS_USE_DVB_SI
02279 static void SDTCallBack( demux_t *p_demux, dvbpsi_sdt_t *p_sdt )
02280 {
02281     demux_sys_t          *p_sys = p_demux->p_sys;
02282     ts_pid_t             *sdt = &p_sys->pid[0x11];
02283     dvbpsi_sdt_service_t *p_srv;
02284 
02285     msg_Dbg( p_demux, "SDTCallBack called" );
02286 
02287     if( sdt->psi->i_sdt_version != -1 &&
02288         ( !p_sdt->b_current_next ||
02289           p_sdt->i_version == sdt->psi->i_sdt_version ) )
02290     {
02291         dvbpsi_DeleteSDT( p_sdt );
02292         return;
02293     }
02294 
02295     msg_Dbg( p_demux, "new SDT ts_id=%d version=%d current_next=%d "
02296              "network_id=%d",
02297              p_sdt->i_ts_id, p_sdt->i_version, p_sdt->b_current_next,
02298              p_sdt->i_network_id );
02299 
02300     for( p_srv = p_sdt->p_first_service; p_srv; p_srv = p_srv->p_next )
02301     {
02302         vlc_meta_t          *p_meta = vlc_meta_New();
02303         dvbpsi_descriptor_t *p_dr;
02304 
02305         msg_Dbg( p_demux, "  * service id=%d eit schedule=%d present=%d "
02306                  "running=%d free_ca=%d",
02307                  p_srv->i_service_id, p_srv->b_eit_schedule,
02308                  p_srv->b_eit_present, p_srv->i_running_status,
02309                  p_srv->b_free_ca );
02310 
02311         for( p_dr = p_srv->p_first_descriptor; p_dr; p_dr = p_dr->p_next )
02312         {
02313             if( p_dr->i_tag == 0x48 )
02314             {
02315                 static const char *psz_type[0x11] = {
02316                     "Reserved",
02317                     "Digital television service",
02318                     "Digital radio sound service",
02319                     "Teletext service",
02320                     "NVOD reference service",
02321                     "NVOD time-shifted service",
02322                     "Mosaic service",
02323                     "PAL coded signal",
02324                     "SECAM coded signal",
02325                     "D/D2-MAC",
02326                     "FM Radio",
02327                     "NTSC coded signal",
02328                     "Data broadcast service",
02329                     "Reserved for Common Interface Usage",
02330                     "RCS Map (see EN 301 790 [35])",
02331                     "RCS FLS (see EN 301 790 [35])",
02332                     "DVB MHP service"
02333                 };
02334                 dvbpsi_service_dr_t *pD = dvbpsi_DecodeServiceDr( p_dr );
02335                 char str1[257];
02336                 char str2[257];
02337 
02338                 memcpy( str1, pD->i_service_provider_name,
02339                         pD->i_service_provider_name_length );
02340                 str1[pD->i_service_provider_name_length] = '\0';
02341                 memcpy( str2, pD->i_service_name, pD->i_service_name_length );
02342                 str2[pD->i_service_name_length] = '\0';
02343 
02344                 msg_Dbg( p_demux, "    - type=%d provider=%s name=%s",
02345                         pD->i_service_type, str1, str2 );
02346 
02347                 vlc_meta_Add( p_meta, "Name", str2 );
02348                 vlc_meta_Add( p_meta, "Provider", str1 );
02349                 if( pD->i_service_type >= 0x01 && pD->i_service_type <= 0x10 )
02350                     vlc_meta_Add( p_meta, "Type", psz_type[pD->i_service_type] );
02351             }
02352         }
02353 
02354         if( p_srv->i_running_status == 0x01 )
02355             vlc_meta_Add( p_meta, "Status", "Not running" );
02356         else if( p_srv->i_running_status == 0x02 )
02357             vlc_meta_Add( p_meta, "Status", "Starts in a few seconds" );
02358         else if( p_srv->i_running_status == 0x03 )
02359             vlc_meta_Add( p_meta, "Status", "Pausing" );
02360         else if( p_srv->i_running_status == 0x04 )
02361             vlc_meta_Add( p_meta, "Status", "Running" );
02362         else
02363             vlc_meta_Add( p_meta, "Status", "Unknown" );
02364 
02365 
02366         es_out_Control( p_demux->out, ES_OUT_SET_GROUP_META,
02367                         p_srv->i_service_id, p_meta );
02368         vlc_meta_Delete( p_meta );
02369     }
02370 
02371     sdt->psi->i_sdt_version = p_sdt->i_version;
02372     dvbpsi_DeleteSDT( p_sdt );
02373 }
02374 #if 0
02375 static void DecodeMjd( int i_mjd, int *p_y, int *p_m, int *p_d )
02376 {
02377     int yp = (int)( ( (double)i_mjd - 15078.2)/365.25 );
02378     int mp = (int)( ((double)i_mjd - 14956.1 - (int)(yp * 365.25)) / 30.6001 );
02379 
02380     *p_d = i_mjd - 14956 - (int)(yp*365.25) - (int)(mp*30.6001);
02381 
02382     if( mp == 14 || mp == 15 )
02383     {
02384         *p_y = yp + 1;
02385         *p_m = mp - 1 + 12;
02386     }
02387     else
02388     {
02389         *p_y = yp;
02390         *p_m = mp - 1;
02391     }
02392 }
02393 #endif
02394 static void EITEventFixString( unsigned char *psz )
02395 {
02396     int i_len;
02397     /* Sometimes the first char isn't a normal char but designed
02398      * caracters encoding, for now lets skip it */
02399     if( psz[0] >= 0x20 )
02400             return;
02401     if( ( i_len = strlen( psz ) ) > 0 )
02402         memmove( &psz[0], &psz[1], i_len ); /* Copy the \0 too */
02403 }
02404 static void EITCallBack( demux_t *p_demux, dvbpsi_eit_t *p_eit )
02405 {
02406     dvbpsi_eit_event_t *p_evt;
02407     vlc_meta_t         *p_meta;
02408     vlc_bool_t b_event_active = VLC_FALSE;
02409 
02410     msg_Dbg( p_demux, "EITCallBack called" );
02411     if( !p_eit->b_current_next )
02412     {
02413         dvbpsi_DeleteEIT( p_eit );
02414         return;
02415     }
02416 
02417     msg_Dbg( p_demux, "new EIT service_id=%d version=%d current_next=%d "
02418              "ts_id=%d network_id=%d segment_last_section_number=%d "
02419              "last_table_id=%d",
02420              p_eit->i_service_id, p_eit->i_version, p_eit->b_current_next,
02421              p_eit->i_ts_id, p_eit->i_network_id,
02422              p_eit->i_segment_last_section_number, p_eit->i_last_table_id );
02423 
02424     p_meta = vlc_meta_New();
02425     for( p_evt = p_eit->p_first_event; p_evt; p_evt = p_evt->p_next )
02426     {
02427         dvbpsi_descriptor_t *p_dr;
02428         char                *psz_cat = malloc( strlen("Event")+10 );
02429         char                psz_start[15];
02430         char                psz_duration[15];
02431         char                psz_name[256];
02432         char                psz_text[256];
02433         char                *psz_extra = strdup("");
02434         char                *psz_value;
02435 
02436         sprintf( psz_cat, "Event %d", p_evt->i_event_id );
02437         sprintf( psz_start, "%d%d:%d%d:%d%d",
02438                  (int)(p_evt->i_start_time >> 20)&0xf,
02439                  (int)(p_evt->i_start_time >> 16)&0xf,
02440                  (int)(p_evt->i_start_time >> 12)&0xf,
02441                  (int)(p_evt->i_start_time >>  8)&0xf,
02442                  (int)(p_evt->i_start_time >>  4)&0xf,
02443                  (int)(p_evt->i_start_time      )&0xf );
02444         sprintf( psz_duration, "%d%d:%d%d:%d%d",
02445                  (p_evt->i_duration >> 20)&0xf, (p_evt->i_duration >> 16)&0xf,
02446                  (p_evt->i_duration >> 12)&0xf, (p_evt->i_duration >>  8)&0xf,
02447                  (p_evt->i_duration >>  4)&0xf, (p_evt->i_duration      )&0xf );
02448         psz_name[0] = psz_text[0] = '\0';
02449 
02450         msg_Dbg( p_demux, "  * event id=%d start_time:mjd=%d %s duration=%s "
02451                           "running=%d free_ca=%d",
02452                  p_evt->i_event_id,
02453                  (int)(p_evt->i_start_time >> 24),
02454                  psz_start, psz_duration,
02455                  p_evt->i_running_status, p_evt->b_free_ca );
02456 
02457         for( p_dr = p_evt->p_first_descriptor; p_dr; p_dr = p_dr->p_next )
02458         {
02459             if( p_dr->i_tag == 0x4d )
02460             {
02461                 dvbpsi_short_event_dr_t *pE = dvbpsi_DecodeShortEventDr( p_dr );
02462 
02463                 if( pE )
02464                 {
02465                     memcpy( psz_name, pE->i_event_name, pE->i_event_name_length);
02466                     psz_name[pE->i_event_name_length] = '\0';
02467                     memcpy( psz_text, pE->i_text, pE->i_text_length );
02468                     psz_text[pE->i_text_length] = '\0';
02469 
02470                     EITEventFixString(psz_name);
02471                     EITEventFixString(psz_text);
02472                     msg_Dbg( p_demux, "    - short event lang=%3.3s '%s' : '%s'",
02473                              pE->i_iso_639_code, psz_name, psz_text );
02474                 }
02475             }
02476             else if( p_dr->i_tag == 0x4e )
02477             {
02478                 dvbpsi_extended_event_dr_t *pE = dvbpsi_DecodeExtendedEventDr( p_dr );
02479                 char str1[257];
02480                 char str2[257];
02481 
02482                 if( pE )
02483                 {
02484                     int i;
02485                     msg_Dbg( p_demux, "    - extended event lang=%3.3s",
02486                              pE->i_iso_639_code );
02487                     for( i = 0; i < pE->i_entry_count; i++ )
02488                     {
02489                         memcpy( str1, pE->i_item_description[i],
02490                                 pE->i_item_description_length[i] );
02491                         str1[pE->i_item_description_length[i]] = '\0';
02492                         EITEventFixString(str1);
02493 
02494                         memcpy( str2, pE->i_item[i],
02495                                 pE->i_item_length[i] );
02496                         str2[pE->i_item_length[i]] = '\0';
02497                         EITEventFixString(str2);
02498 
02499                         msg_Dbg( p_demux, "       - desc='%s' item='%s'", str1, str2 );
02500                         psz_extra = realloc( psz_extra,
02501                                     strlen(psz_extra) +
02502                                     strlen(str1) +strlen(str2) + 1 + 3 );
02503                         strcat( psz_extra, str1 );
02504                         strcat( psz_extra, "(" );
02505                         strcat( psz_extra, str2 );
02506                         strcat( psz_extra, ") " );
02507                     }
02508 
02509                     memcpy( str1, pE->i_text, pE->i_text_length );
02510                     str1[pE->i_text_length] = '\0';
02511                     EITEventFixString(str1);
02512 
02513                     msg_Dbg( p_demux, "       - text='%s'", str1 );
02514                     psz_extra = realloc( psz_extra,
02515                                          strlen(psz_extra) + strlen(str1) + 2 );
02516                     strcat( psz_extra, str1 );
02517                     strcat( psz_extra, " " );
02518                 }
02519             }
02520             else
02521             {
02522                 msg_Dbg( p_demux, "    - tag=0x%x(%d)", p_dr->i_tag, p_dr->i_tag );
02523             }
02524         }
02525 
02526         asprintf( &psz_value, "%s: %s (+%s) %s (%s)",
02527                   psz_start,
02528                   psz_name,
02529                   psz_duration,
02530                   psz_text, psz_extra );
02531         vlc_meta_Add( p_meta, psz_cat, psz_value );
02532         free( psz_value );
02533 
02534         if( p_evt->i_running_status == 0x04 )
02535         {
02536             vlc_meta_Add( p_meta, VLC_META_NOW_PLAYING, psz_name );
02537             b_event_active = VLC_TRUE;
02538         }
02539 
02540         free( psz_cat );
02541         free( psz_extra );
02542     }
02543 
02544     if( !b_event_active )
02545         vlc_meta_Add( p_meta, VLC_META_NOW_PLAYING, "" );
02546     es_out_Control( p_demux->out, ES_OUT_SET_GROUP_META,
02547                     p_eit->i_service_id, p_meta );
02548     vlc_meta_Delete( p_meta );
02549 
02550     dvbpsi_DeleteEIT( p_eit );
02551 }
02552 
02553 static void PSINewTableCallBack( demux_t *p_demux, dvbpsi_handle h,
02554                                  uint8_t  i_table_id, uint16_t i_extension )
02555 {
02556 #if 0
02557     msg_Dbg( p_demux, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
02558              i_table_id, i_table_id, i_extension, i_extension );
02559 #endif
02560 
02561     if( i_table_id == 0x42 )
02562     {
02563         msg_Dbg( p_demux, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
02564                  i_table_id, i_table_id, i_extension, i_extension );
02565 
02566         dvbpsi_AttachSDT( h, i_table_id, i_extension,
02567                           (dvbpsi_sdt_callback)SDTCallBack, p_demux );
02568     }
02569     else if( i_table_id == 0x4e || /* Current/Following */
02570              ( i_table_id >= 0x50 && i_table_id <= 0x5f ) ) /* Schedule */
02571     {
02572         msg_Dbg( p_demux, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
02573                  i_table_id, i_table_id, i_extension, i_extension );
02574 
02575         dvbpsi_AttachEIT( h, i_table_id, i_extension,
02576                           (dvbpsi_eit_callback)EITCallBack, p_demux );
02577     }
02578 }
02579 #endif
02580 
02581 static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
02582 {
02583     demux_sys_t          *p_sys = p_demux->p_sys;
02584     dvbpsi_descriptor_t  *p_dr;
02585     dvbpsi_pmt_es_t      *p_es;
02586 
02587     ts_pid_t             *pmt = NULL;
02588     ts_prg_psi_t         *prg = NULL;
02589 
02590     ts_pid_t             **pp_clean = NULL;
02591     int                  i_clean = 0, i;
02592 
02593     msg_Dbg( p_demux, "PMTCallBack called" );
02594 
02595     /* First find this PMT declared in PAT */
02596     for( i = 0; i < p_sys->i_pmt; i++ )
02597     {
02598         int i_prg;
02599         for( i_prg = 0; i_prg < p_sys->pmt[i]->psi->i_prg; i_prg++ )
02600         {
02601             if( p_sys->pmt[i]->psi->prg[i_prg]->i_number ==
02602                 p_pmt->i_program_number )
02603             {
02604                 pmt = p_sys->pmt[i];
02605                 prg = p_sys->pmt[i]->psi->prg[i_prg];
02606                 break;
02607             }
02608         }
02609         if( pmt ) break;
02610     }
02611 
02612     if( pmt == NULL )
02613     {
02614         msg_Warn( p_demux, "unreferenced program (broken stream)" );
02615         dvbpsi_DeletePMT(p_pmt);
02616         return;
02617     }
02618 
02619     if( prg->i_version != -1 &&
02620         ( !p_pmt->b_current_next || prg->i_version == p_pmt->i_version ) )
02621     {
02622         dvbpsi_DeletePMT( p_pmt );
02623         return;
02624     }
02625 
02626     /* Clean this program (remove all es) */
02627     for( i = 0; i < 8192; i++ )
02628     {
02629         ts_pid_t *pid = &p_sys->pid[i];
02630 
02631         if( pid->b_valid && pid->p_owner == pmt->psi &&
02632             pid->i_owner_number == prg->i_number && pid->psi == NULL )
02633         {
02634             TAB_APPEND( i_clean, pp_clean, pid );
02635         }
02636     }
02637     if( prg->iod )
02638     {
02639         IODFree( prg->iod );
02640         prg->iod = NULL;
02641     }
02642 
02643     msg_Dbg( p_demux, "new PMT program number=%d version=%d pid_pcr=%d",
02644              p_pmt->i_program_number, p_pmt->i_version, p_pmt->i_pcr_pid );
02645     prg->i_pid_pcr = p_pmt->i_pcr_pid;
02646     prg->i_version = p_pmt->i_version;
02647 
02648     if( DVBProgramIsSelected( p_demux, prg->i_number ) )
02649     {
02650         /* Set demux filter */
02651         stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
02652                         ACCESS_SET_PRIVATE_ID_STATE, prg->i_pid_pcr,
02653                         VLC_TRUE );
02654     }
02655     else if ( p_sys->b_dvb_control )
02656     {
02657         msg_Warn( p_demux, "skipping program (not selected)" );
02658         dvbpsi_DeletePMT(p_pmt);
02659         return;
02660     }
02661 
02662     /* Parse descriptor */
02663     for( p_dr = p_pmt->p_first_descriptor; p_dr != NULL; p_dr = p_dr->p_next )
02664     {
02665         if( p_dr->i_tag == 0x1d )
02666         {
02667             /* We have found an IOD descriptor */
02668             msg_Dbg( p_demux, " * descriptor : IOD (0x1d)" );
02669 
02670             prg->iod = IODNew( p_dr->i_length, p_dr->p_data );
02671         }
02672         else if( p_dr->i_tag == 0x9 )
02673         {
02674             uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
02675                                 | p_dr->p_data[1];
02676             msg_Dbg( p_demux, " * descriptor : CA (0x9) SysID 0x%x", i_sysid );
02677         }
02678         else
02679         {
02680             msg_Dbg( p_demux, " * descriptor : unknown (0x%x)", p_dr->i_tag );
02681         }
02682     }
02683 
02684     for( p_es = p_pmt->p_first_es; p_es != NULL; p_es = p_es->p_next )
02685     {
02686         ts_pid_t tmp_pid, *old_pid = 0, *pid = &tmp_pid;
02687 
02688         /* Find out if the PID was already declared */
02689         for( i = 0; i < i_clean; i++ )
02690         {
02691             if( pp_clean[i] == &p_sys->pid[p_es->i_pid] )
02692             {
02693                 old_pid = pp_clean[i];
02694                 break;
02695             }
02696         }
02697 
02698         if( !old_pid && p_sys->pid[p_es->i_pid].b_valid )
02699         {
02700             ts_pid_t *pid = &p_sys->pid[p_es->i_pid];
02701             if( ( pid->i_pid == 0x11 /* SDT */ ||
02702                   pid->i_pid == 0x12 /* EDT */ ) && pid->psi )
02703             {
02704                 /* This doesn't look like a DVB stream so don't try
02705                  * parsing the SDT/EDT */
02706                 dvbpsi_DetachDemux( pid->psi->handle );
02707                 free( pid->psi );
02708                 pid->psi = 0;
02709             }
02710             else
02711             {
02712                 msg_Warn( p_demux, "pmt error: pid=%d already defined",
02713                           p_es->i_pid );
02714                 continue;
02715             }
02716         }
02717 
02718         PIDInit( pid, VLC_FALSE, pmt->psi );
02719         PIDFillFormat( pid, p_es->i_type );
02720         pid->i_owner_number = prg->i_number;
02721         pid->i_pid          = p_es->i_pid;
02722         pid->b_seen         = p_sys->pid[p_es->i_pid].b_seen;
02723 
02724         if( p_es->i_type == 0x10 || p_es->i_type == 0x11 ||
02725             p_es->i_type == 0x12 )
02726         {
02727             /* MPEG-4 stream: search SL_DESCRIPTOR */
02728             dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;;
02729 
02730             while( p_dr && ( p_dr->i_tag != 0x1f ) ) p_dr = p_dr->p_next;
02731 
02732             if( p_dr && p_dr->i_length == 2 )
02733             {
02734                 int i_es_id = ( p_dr->p_data[0] << 8 ) | p_dr->p_data[1];
02735 
02736                 msg_Warn( p_demux, "found SL_descriptor es_id=%d", i_es_id );
02737 
02738                 pid->es->p_mpeg4desc = NULL;
02739 
02740                 for( i = 0; i < 255; i++ )
02741                 {
02742                     iod_descriptor_t *iod = prg->iod;
02743 
02744                     if( iod->es_descr[i].b_ok &&
02745                         iod->es_descr[i].i_es_id == i_es_id )
02746                     {
02747                         pid->es->p_mpeg4desc = &iod->es_descr[i];
02748                         break;
02749                     }
02750                 }
02751             }
02752 
02753             if( pid->es->p_mpeg4desc != NULL )
02754             {
02755                 decoder_config_descriptor_t *dcd =
02756                     &pid->es->p_mpeg4desc->dec_descr;
02757 
02758                 if( dcd->i_streamType == 0x04 )    /* VisualStream */
02759                 {
02760                     pid->es->fmt.i_cat = VIDEO_ES;
02761                     switch( dcd->i_objectTypeIndication )
02762                     {
02763                     case 0x0B: /* mpeg4 sub */
02764                         pid->es->fmt.i_cat = SPU_ES;
02765                         pid->es->fmt.i_codec = VLC_FOURCC('s','u','b','t');
02766                         break;
02767 
02768                     case 0x20: /* mpeg4 */
02769                         pid->es->fmt.i_codec = VLC_FOURCC('m','p','4','v');
02770                         break;
02771                     case 0x21: /* h264 */
02772                         pid->es->fmt.i_codec = VLC_FOURCC('h','2','6','4');
02773                         break;
02774                     case 0x60:
02775                     case 0x61:
02776                     case 0x62:
02777                     case 0x63:
02778                     case 0x64:
02779                     case 0x65: /* mpeg2 */
02780                         pid->es->fmt.i_codec = VLC_FOURCC( 'm','p','g','v' );
02781                         break;
02782                     case 0x6a: /* mpeg1 */
02783                         pid->es->fmt.i_codec = VLC_FOURCC( 'm','p','g','v' );
02784                         break;
02785                     case 0x6c: /* mpeg1 */
02786                         pid->es->fmt.i_codec = VLC_FOURCC( 'j','p','e','g' );
02787                         break;
02788                     default:
02789                         pid->es->fmt.i_cat = UNKNOWN_ES;
02790                         break;
02791                     }
02792                 }
02793                 else if( dcd->i_streamType == 0x05 )    /* AudioStream */
02794                 {
02795                     pid->es->fmt.i_cat = AUDIO_ES;
02796                     switch( dcd->i_objectTypeIndication )
02797                     {
02798                     case 0x40: /* mpeg4 */
02799                         pid->es->fmt.i_codec = VLC_FOURCC('m','p','4','a');
02800                         break;
02801                     case 0x66:
02802                     case 0x67:
02803                     case 0x68: /* mpeg2 aac */
02804                         pid->es->fmt.i_codec = VLC_FOURCC('m','p','4','a');
02805                         break;
02806                     case 0x69: /* mpeg2 */
02807                         pid->es->fmt.i_codec = VLC_FOURCC('m','p','g','a');
02808                         break;
02809                     case 0x6b: /* mpeg1 */
02810                         pid->es->fmt.i_codec = VLC_FOURCC('m','p','g','a');
02811                         break;
02812                     default:
02813                         pid->es->fmt.i_cat = UNKNOWN_ES;
02814                         break;
02815                     }
02816                 }
02817                 else
02818                 {
02819                     pid->es->fmt.i_cat = UNKNOWN_ES;
02820                 }
02821 
02822                 if( pid->es->fmt.i_cat != UNKNOWN_ES )
02823                 {
02824                     pid->es->fmt.i_extra = dcd->i_decoder_specific_info_len;
02825                     if( pid->es->fmt.i_extra > 0 )
02826                     {
02827                         pid->es->fmt.p_extra = malloc( pid->es->fmt.i_extra );
02828                         memcpy( pid->es->fmt.p_extra,
02829                                 dcd->p_decoder_specific_info,
02830                                 pid->es->fmt.i_extra );
02831                     }
02832                 }
02833             }
02834         }
02835         else if( p_es->i_type == 0x06 )
02836         {
02837             dvbpsi_descriptor_t *p_dr;
02838 
02839             for( p_dr = p_es->p_first_descriptor; p_dr != NULL;
02840                  p_dr = p_dr->p_next )
02841             {
02842                 msg_Dbg( p_demux, "  * es pid=%d type=%d dr->i_tag=0x%x",
02843                          p_es->i_pid, p_es->i_type, p_dr->i_tag );
02844 
02845                 if( p_dr->i_tag == 0x05 )
02846                 {
02847                     /* Registration Descriptor */
02848                     if( p_dr->i_length != 4 )
02849                     {
02850                         msg_Warn( p_demux, "invalid Registration Descriptor" );
02851                     }
02852                     else
02853                     {
02854                         if( !memcmp( p_dr->p_data, "AC-3", 4 ) )
02855                         {
02856                             /* ATSC with stream_type 0x81 (but this descriptor
02857                              * is then not mandatory */
02858                             pid->es->fmt.i_cat = AUDIO_ES;
02859                             pid->es->fmt.i_codec = VLC_FOURCC('a','5','2',' ');
02860                         }
02861                         else if( !memcmp( p_dr->p_data, "DTS1", 4 ) ||
02862                                  !memcmp( p_dr->p_data, "DTS2", 4 ) ||
02863                                  !memcmp( p_dr->p_data, "DTS3", 4 ) )
02864                         {
02865                            /*registration descriptor(ETSI TS 101 154 Annex F)*/
02866                             pid->es->fmt.i_cat = AUDIO_ES;
02867                             pid->es->fmt.i_codec = VLC_FOURCC('d','t','s',' ');
02868                         }
02869                         else if( !memcmp( p_dr->p_data, "BSSD", 4 ) )
02870                         {
02871                             pid->es->fmt.i_cat = AUDIO_ES;
02872                             pid->es->fmt.i_codec = VLC_FOURCC('l','p','c','m');
02873                         }
02874                         else
02875                         {
02876                             msg_Warn( p_demux,
02877                                       "unknown Registration Descriptor (%4.4s)",
02878                                       p_dr->p_data );
02879                         }
02880                     }
02881 
02882                 }
02883                 else if( p_dr->i_tag == 0x6a )
02884                 {
02885                     /* DVB with stream_type 0x06 */
02886                     pid->es->fmt.i_cat = AUDIO_ES;
02887                     pid->es->fmt.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' );
02888                 }
02889                 else if( p_dr->i_tag == 0x73 )
02890                 {
02891                     /* DTS audio descriptor (ETSI TS 101 154 Annex F) */
02892                     msg_Dbg( p_demux, "    * DTS audio descriptor not decoded" );
02893                     pid->es->fmt.i_cat = AUDIO_ES;
02894                     pid->es->fmt.i_codec = VLC_FOURCC( 'd', 't', 's', ' ' );
02895                 }
02896                 else if( p_dr->i_tag == 0x45 )
02897                 {
02898                     msg_Dbg( p_demux, "    * VBI Data descriptor" );
02899                     /* FIXME : store the information somewhere */
02900                 }
02901                 else if( p_dr->i_tag == 0x46 )
02902                 {
02903                     msg_Dbg( p_demux, "    * VBI Teletext descriptor" );
02904                     /* FIXME : store the information somewhere */
02905                 }
02906 #ifdef _DVBPSI_DR_52_H_
02907                 else if( p_dr->i_tag == 0x52 )
02908                 {
02909                     dvbpsi_stream_identifier_dr_t *si;
02910                     si = dvbpsi_DecodeStreamIdentifierDr( p_dr );
02911                     
02912                     msg_Dbg( p_demux, "    * Stream Component Identifier: %d", si->i_component_tag );
02913                 }
02914 #endif
02915                 else if( p_dr->i_tag == 0x56 )
02916                 {
02917                     msg_Dbg( p_demux, "    * EBU Teletext descriptor" );
02918                     pid->es->fmt.i_cat = SPU_ES;
02919                     pid->es->fmt.i_codec = VLC_FOURCC( 't', 'e', 'l', 'x' );
02920                     pid->es->fmt.psz_description = strdup( "Teletext" );
02921                     pid->es->fmt.i_extra = p_dr->i_length;
02922                     pid->es->fmt.p_extra = malloc( p_dr->i_length );
02923                     memcpy( pid->es->fmt.p_extra, p_dr->p_data,
02924                             p_dr->i_length );
02925                 }
02926 #ifdef _DVBPSI_DR_59_H_
02927                 else if( p_dr->i_tag == 0x59 )
02928                 {
02929                     uint16_t n;
02930                     dvbpsi_subtitling_dr_t *sub;
02931 
02932                     /* DVB subtitles */
02933                     pid->es->fmt.i_cat = SPU_ES;
02934                     pid->es->fmt.i_codec = VLC_FOURCC( 'd', 'v', 'b', 's' );
02935                     pid->es->fmt.i_group = p_pmt->i_program_number;
02936 
02937                     sub = dvbpsi_DecodeSubtitlingDr( p_dr );
02938                     if( !sub ) continue;
02939 
02940                     /* Each subtitle ES contains n languages,
02941                      * We are going to create n ES for the n tracks */
02942                     if( sub->i_subtitles_number > 0 )
02943                     {
02944                         pid->es->fmt.psz_language = malloc( 4 );
02945                         memcpy( pid->es->fmt.psz_language,
02946                                 sub->p_subtitle[0].i_iso6392_language_code, 3);
02947                         pid->es->fmt.psz_language[3] = 0;
02948 
02949                         pid->es->fmt.subs.dvb.i_id =
02950                             sub->p_subtitle[0].i_composition_page_id;
02951                         /* Hack, FIXME */
02952                         pid->es->fmt.subs.dvb.i_id |=
02953                           ((int)sub->p_subtitle[0].i_ancillary_page_id << 16);
02954                     }
02955                     else pid->es->fmt.i_cat = UNKNOWN_ES;
02956 
02957                     for( n = 1; n < sub->i_subtitles_number; n++ )
02958                     {
02959                         ts_es_t *p_es = malloc( sizeof( ts_es_t ) );
02960                         p_es->fmt = pid->es->fmt;
02961                         p_es->id = NULL;
02962                         p_es->p_pes = NULL;
02963                         p_es->i_pes_size = 0;
02964                         p_es->i_pes_gathered = 0;
02965                         p_es->pp_last = &p_es->p_pes;
02966                         p_es->p_mpeg4desc = NULL;
02967 
02968                         p_es->fmt.psz_language = malloc( 4 );
02969                         memcpy( p_es->fmt.psz_language,
02970                                 sub->p_subtitle[n].i_iso6392_language_code, 3);
02971                         p_es->fmt.psz_language[3] = 0;
02972 
02973                         p_es->fmt.subs.dvb.i_id =
02974                             sub->p_subtitle[n].i_composition_page_id;
02975                         /* Hack, FIXME */
02976                         p_es->fmt.subs.dvb.i_id |=
02977                           ((int)sub->p_subtitle[n].i_ancillary_page_id << 16);
02978 
02979                         TAB_APPEND( pid->i_extra_es, pid->extra_es, p_es );
02980                     }
02981                 }
02982 #endif /* _DVBPSI_DR_59_H_ */
02983             }
02984         }
02985         else if( p_es->i_type == 0xa0 )
02986         {
02987             /* MSCODEC sent by vlc */
02988             dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
02989 
02990             while( p_dr && ( p_dr->i_tag != 0xa0 ) ) p_dr = p_dr->p_next;
02991 
02992             if( p_dr && p_dr->i_length >= 8 )
02993             {
02994                 pid->es->fmt.i_cat = VIDEO_ES;
02995                 pid->es->fmt.i_codec =
02996                     VLC_FOURCC( p_dr->p_data[0], p_dr->p_data[1],
02997                                 p_dr->p_data[2], p_dr->p_data[3] );
02998                 pid->es->fmt.video.i_width =
02999                     ( p_dr->p_data[4] << 8 ) | p_dr->p_data[5];
03000                 pid->es->fmt.video.i_height =
03001                     ( p_dr->p_data[6] << 8 ) | p_dr->p_data[7];
03002                 pid->es->fmt.i_extra = 
03003                     (p_dr->p_data[8] << 8) | p_dr->p_data[9];
03004 
03005                 if( pid->es->fmt.i_extra > 0 )
03006                 {
03007                     pid->es->fmt.p_extra = malloc( pid->es->fmt.i_extra );
03008                     memcpy( pid->es->fmt.p_extra, &p_dr->p_data[10],
03009                             pid->es->fmt.i_extra );
03010                 }
03011             }
03012             else
03013             {
03014                 msg_Warn( p_demux, "private MSCODEC (vlc) without bih private "
03015                           "descriptor" );
03016             }
03017             /* For such stream we will gather them ourself and don't launch a
03018              * packetizer.
03019              * Yes it's ugly but it's the only way to have DIV3 working */
03020             pid->es->fmt.b_packetized = VLC_TRUE;
03021         }
03022 
03023         if( pid->es->fmt.i_cat == AUDIO_ES ||
03024             ( pid->es->fmt.i_cat == SPU_ES &&
03025               pid->es->fmt.i_codec != VLC_FOURCC('d','v','b','s') ) )
03026         {
03027             /* get language descriptor */
03028             dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
03029             while( p_dr && ( p_dr->i_tag != 0x0a ) ) p_dr = p_dr->p_next;
03030 
03031             if( p_dr )
03032             {
03033                 dvbpsi_iso639_dr_t *p_decoded = dvbpsi_DecodeISO639Dr( p_dr );
03034 
03035                 if( p_decoded )
03036                 {
03037                     pid->es->fmt.psz_language = malloc( 4 );
03038                     memcpy( pid->es->fmt.psz_language,
03039                             p_decoded->i_iso_639_code, 3 );
03040                     pid->es->fmt.psz_language[3] = 0;
03041                 }
03042             }
03043         }
03044 
03045         pid->es->fmt.i_group = p_pmt->i_program_number;
03046         if( pid->es->fmt.i_cat == UNKNOWN_ES )
03047         {
03048             msg_Dbg( p_demux, "  * es pid=%d type=%d *unknown*",
03049                      p_es->i_pid, p_es->i_type );
03050         }
03051         else if( !p_sys->b_udp_out )
03052         {
03053             msg_Dbg( p_demux, "  * es pid=%d type=%d fcc=%4.4s",
03054                      p_es->i_pid, p_es->i_type, (char*)&pid->es->fmt.i_codec );
03055 
03056             if( p_sys->b_es_id_pid ) pid->es->fmt.i_id = p_es->i_pid;
03057 
03058             /* Check if we can avoid restarting the ES */
03059             if( old_pid &&
03060                 pid->es->fmt.i_codec == old_pid->es->fmt.i_codec &&
03061                 pid->es->fmt.i_extra == old_pid->es->fmt.i_extra &&
03062                 pid->es->fmt.i_extra == 0 &&
03063                 pid->i_extra_es == old_pid->i_extra_es &&
03064                 ( ( !pid->es->fmt.psz_language &&
03065                     !old_pid->es->fmt.psz_language ) ||
03066                   ( pid->es->fmt.psz_language &&
03067                     old_pid->es->fmt.psz_language &&
03068                     !strcmp( pid->es->fmt.psz_language,
03069                              old_pid->es->fmt.psz_language ) ) ) )
03070             {
03071                 pid->es->id = old_pid->es->id;
03072                 old_pid->es->id = NULL;
03073                 for( i = 0; i < pid->i_extra_es; i++ )
03074                 {
03075                     pid->extra_es[i]->id = old_pid->extra_es[i]->id;
03076                     old_pid->extra_es[i]->id = NULL;
03077                 }
03078             }
03079             else
03080             {
03081                 if( old_pid )
03082                 {
03083                     PIDClean( p_demux->out, old_pid );
03084                     TAB_REMOVE( i_clean, pp_clean, old_pid );
03085                     old_pid = 0;
03086                 }
03087 
03088                 pid->es->id = es_out_Add( p_demux->out, &pid->es->fmt );
03089                 for( i = 0; i < pid->i_extra_es; i++ )
03090                 {
03091                     pid->extra_es[i]->id =
03092                         es_out_Add( p_demux->out, &pid->extra_es[i]->fmt );
03093                 }
03094             }
03095         }
03096 
03097         /* Add ES to the list */
03098         if( old_pid )
03099         {
03100             PIDClean( p_demux->out, old_pid );
03101             TAB_REMOVE( i_clean, pp_clean, old_pid );
03102         }
03103         p_sys->pid[p_es->i_pid] = *pid;
03104 
03105         for( p_dr = p_es->p_first_descriptor; p_dr != NULL;
03106              p_dr = p_dr->p_next )
03107         {
03108             if( p_dr->i_tag == 0x9 )
03109             {
03110                 uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
03111                                     | p_dr->p_data[1];
03112                 msg_Dbg( p_demux, "   * descriptor : CA (0x9) SysID 0x%x",
03113                          i_sysid );
03114             }
03115         }
03116 
03117         if( DVBProgramIsSelected( p_demux, prg->i_number ) )
03118         {
03119             /* Set demux filter */
03120             stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
03121                             ACCESS_SET_PRIVATE_ID_STATE, p_es->i_pid,
03122                             VLC_TRUE );
03123         }
03124     }
03125 
03126     if( DVBProgramIsSelected( p_demux, prg->i_number ) )
03127     {
03128         /* Set CAM descrambling */
03129         stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
03130                         ACCESS_SET_PRIVATE_ID_CA, p_pmt );
03131     }
03132     else
03133     {
03134         dvbpsi_DeletePMT( p_pmt );
03135     }
03136 
03137     for ( i = 0; i < i_clean; i++ )
03138     {
03139         if( DVBProgramIsSelected( p_demux, prg->i_number ) )
03140         {
03141             stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
03142                             ACCESS_SET_PRIVATE_ID_STATE, pp_clean[i]->i_pid,
03143                             VLC_FALSE );
03144         }
03145 
03146         PIDClean( p_demux->out, pp_clean[i] );
03147     }
03148     if( i_clean ) free( pp_clean );
03149 }
03150 
03151 static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat )
03152 {
03153     demux_sys_t          *p_sys = p_demux->p_sys;
03154     dvbpsi_pat_program_t *p_program;
03155     ts_pid_t             *pat = &p_sys->pid[0];
03156     int                  i, j;
03157 
03158     msg_Dbg( p_demux, "PATCallBack called" );
03159 
03160     if( pat->psi->i_pat_version != -1 &&
03161         ( !p_pat->b_current_next ||
03162           p_pat->i_version == pat->psi->i_pat_version ) )
03163     {
03164         dvbpsi_DeletePAT( p_pat );
03165         return;
03166     }
03167 
03168     msg_Dbg( p_demux, "new PAT ts_id=%d version=%d current_next=%d",
03169              p_pat->i_ts_id, p_pat->i_version, p_pat->b_current_next );
03170 
03171     /* Clean old */
03172     if( p_sys->i_pmt > 0 )
03173     {
03174         int      i_pmt_rm = 0;
03175         ts_pid_t **pmt_rm = NULL;
03176 
03177         /* Search pmt to be deleted */
03178         for( i = 0; i < p_sys->i_pmt; i++ )
03179         {
03180             ts_pid_t *pmt = p_sys->pmt[i];
03181             vlc_bool_t b_keep = VLC_FALSE;
03182 
03183             for( p_program = p_pat->p_first_program; p_program != NULL;
03184                  p_program = p_program->p_next )
03185             {
03186                 if( p_program->i_pid == pmt->i_pid )
03187                 {
03188                     int i_prg;
03189                     for( i_prg = 0; i_prg < pmt->psi->i_prg; i_prg++ )
03190                     {
03191                         if( p_program->i_number ==
03192                             pmt->psi->prg[i_prg]->i_number )
03193                         {
03194                             b_keep = VLC_TRUE;
03195                             break;
03196                         }
03197                     }
03198                     if( b_keep ) break;
03199                 }
03200             }
03201 
03202             if( !b_keep )
03203             {
03204                 TAB_APPEND( i_pmt_rm, pmt_rm, pmt );
03205             }
03206         }
03207 
03208         /* Delete all ES attached to thoses PMT */
03209         for( i = 2; i < 8192; i++ )
03210         {
03211             ts_pid_t *pid = &p_sys->pid[i];
03212 
03213             if( !pid->b_valid || pid->psi ) continue;
03214 
03215             for( j = 0; j < i_pmt_rm; j++ )
03216             {
03217                 int i_prg;
03218                 for( i_prg = 0; i_prg < pid->p_owner->i_prg; i_prg++ )
03219                 {
03220                     /* We only remove es that aren't defined by extra pmt */
03221                     if( pid->p_owner->prg[i_prg]->i_pid_pmt !=
03222                         pmt_rm[j]->i_pid ) continue;
03223 
03224                     if( p_sys->b_dvb_control && pid->es->id )
03225                     {
03226                         if( stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
03227                                             ACCESS_SET_PRIVATE_ID_STATE, i,
03228                                             VLC_FALSE ) )
03229                             p_sys->b_dvb_control = VLC_FALSE;
03230                     }
03231 
03232                     PIDClean( p_demux->out, pid );
03233                     break;
03234                 }
03235 
03236                 if( !pid->b_valid ) break;
03237             }
03238         }
03239 
03240         /* Delete PMT pid */
03241         for( i = 0; i < i_pmt_rm; i++ )
03242         {
03243             int i_prg;
03244             if( p_sys->b_dvb_control )
03245             {
03246                 if( stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
03247                                     ACCESS_SET_PRIVATE_ID_STATE,
03248                                     pmt_rm[i]->i_pid, VLC_FALSE ) )
03249                     p_sys->b_dvb_control = VLC_FALSE;
03250             }
03251 
03252             for( i_prg = 0; i_prg < pmt_rm[i]->psi->i_prg; i_prg++ )
03253             {
03254                 const int i_number = pmt_rm[i]->psi->prg[i_prg]->i_number;
03255                 if( i_number != 0 )
03256                     es_out_Control( p_demux->out, ES_OUT_DEL_GROUP, i_number );
03257             }
03258 
03259             PIDClean( p_demux->out, &p_sys->pid[pmt_rm[i]->i_pid] );
03260             TAB_REMOVE( p_sys->i_pmt, p_sys->pmt, pmt_rm[i] );
03261         }
03262 
03263         if( pmt_rm ) free( pmt_rm );
03264     }
03265 
03266     /* now create programs */
03267     for( p_program = p_pat->p_first_program; p_program != NULL;
03268          p_program = p_program->p_next )
03269     {
03270         msg_Dbg( p_demux, "  * number=%d pid=%d", p_program->i_number,
03271                  p_program->i_pid );
03272         if( p_program->i_number != 0 )
03273         {
03274             ts_pid_t *pmt = &p_sys->pid[p_program->i_pid];
03275             vlc_bool_t b_add = VLC_TRUE;
03276 
03277             if( pmt->b_valid )
03278             {
03279                 int i_prg;
03280                 for( i_prg = 0; i_prg < pmt->psi->i_prg; i_prg++ )
03281                 {
03282                     if( pmt->psi->prg[i_prg]->i_number == p_program->i_number )
03283                     {
03284                         b_add = VLC_FALSE;
03285                         break;
03286                     }
03287                 }
03288             }
03289             else
03290             {
03291                 TAB_APPEND( p_sys->i_pmt, p_sys->pmt, pmt );
03292             }
03293 
03294             if( b_add )
03295             {
03296                 PIDInit( pmt, VLC_TRUE, pat->psi );
03297                 pmt->psi->prg[pmt->psi->i_prg-1]->handle =
03298                     dvbpsi_AttachPMT( p_program->i_number,
03299                                       (dvbpsi_pmt_callback)PMTCallBack,
03300                                       p_demux );
03301                 pmt->psi->prg[pmt->psi->i_prg-1]->i_number =
03302                     p_program->i_number;
03303                 pmt->psi->prg[pmt->psi->i_prg-1]->i_pid_pmt =
03304                     p_program->i_pid;
03305 
03306                 /* Now select PID at access level */
03307                 if( p_sys->b_dvb_control )
03308                 {
03309                     if( DVBProgramIsSelected( p_demux, p_program->i_number ) )
03310                     {
03311                         if( p_sys->i_dvb_program == 0 )
03312                             p_sys->i_dvb_program = p_program->i_number;
03313 
03314                         if( stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, ACCESS_SET_PRIVATE_ID_STATE, p_program->i_pid, VLC_TRUE ) )
03315                             p_sys->b_dvb_control = VLC_FALSE;
03316                     }
03317                 }
03318             }
03319         }
03320     }
03321     pat->psi->i_pat_version = p_pat->i_version;
03322 
03323     dvbpsi_DeletePAT( p_pat );
03324 }
03325 

Generated on Tue Dec 20 10:14:36 2005 for vlc-0.8.4a by  doxygen 1.4.2