X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fts.c;h=1902dcad539ba7ff97933290c8f49d4a8b33255f;hb=514e325d50ea0f061dbcd7779a722bf50f95f50d;hp=ed39a879380ff92c27a0abeed1031ea7fdb505c2;hpb=4ab6e7c7c561140be4c4d995adae277e82240f4a;p=vlc diff --git a/modules/demux/ts.c b/modules/demux/ts.c index ed39a87938..1902dcad53 100644 --- a/modules/demux/ts.c +++ b/modules/demux/ts.c @@ -1,7 +1,7 @@ /***************************************************************************** * ts.c: Transport Stream input module for VLC. ***************************************************************************** - * Copyright (C) 2004-2005 VideoLAN (Centrale Réseaux) and its contributors + * Copyright (C) 2004-2005 the VideoLAN team * $Id$ * * Authors: Laurent Aimar @@ -19,20 +19,26 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ + +#include + +#include #include /* malloc(), free() */ #include -#include -#include +#include /* DVB-specific things */ +#include +#include #include "iso_lang.h" -#include "network.h" +#include +#include #include "../mux/mpeg/csa.h" @@ -67,12 +73,15 @@ # endif #endif +#undef TS_DEBUG + /* TODO: * - XXX: do not mark options message to be translated, they are too osbcure for now ... * - test it * - ... */ +#define vlc_meta_Add(a,b,c) fprintf(stderr, "FIXME: TS demuxer meta is broken\n" ) /***************************************************************************** * Module descriptor *****************************************************************************/ @@ -81,26 +90,29 @@ static void Close ( vlc_object_t * ); #define PMT_TEXT N_("Extra PMT") #define PMT_LONGTEXT N_( \ - "Allows a user to specify an extra pmt (pmt_pid=pid:stream_type[,...])" ) + "Allows a user to specify an extra pmt (pmt_pid=pid:stream_type[,...])." ) #define PID_TEXT N_("Set id of ES to PID") -#define PID_LONGTEXT N_("set id of es to pid") +#define PID_LONGTEXT N_("Set the internal ID of each elementary stream" \ + " handled by VLC to the same value as the PID in" \ + " the TS stream, instead of 1, 2, 3, etc. Useful to" \ + " do \'#duplicate{..., select=\"es=\"}\'.") #define TSOUT_TEXT N_("Fast udp streaming") #define TSOUT_LONGTEXT N_( \ - "Sends TS to specific ip:port by udp (you must know what you are doing)") + "Sends TS to specific ip:port by udp (you must know what you are doing).") #define MTUOUT_TEXT N_("MTU for out mode") -#define MTUOUT_LONGTEXT N_("MTU for out mode") +#define MTUOUT_LONGTEXT N_("MTU for out mode.") #define CSA_TEXT N_("CSA ck") -#define CSA_LONGTEXT N_("CSA ck") +#define CSA_LONGTEXT N_("Control word for the CSA encryption algorithm") #define SILENT_TEXT N_("Silent mode") -#define SILENT_LONGTEXT N_("do not complain on encrypted PES") +#define SILENT_LONGTEXT N_("Do not complain on encrypted PES.") #define CAPMT_SYSID_TEXT N_("CAPMT System ID") -#define CAPMT_SYSID_LONGTEXT N_("only forward descriptors from this SysID to the CAM") +#define CAPMT_SYSID_LONGTEXT N_("Only forward descriptors from this SysID to the CAM.") #define CPKT_TEXT N_("Packet size in bytes to decrypt") #define CPKT_LONGTEXT N_("Specify the size of the TS packet to decrypt. " \ @@ -108,7 +120,7 @@ static void Close ( vlc_object_t * ); "decrypting. " ) #define TSDUMP_TEXT N_("Filename of dump") -#define TSDUMP_LONGTEXT N_("Specify a filename where to dump the TS in") +#define TSDUMP_LONGTEXT N_("Specify a filename where to dump the TS in.") #define APPEND_TEXT N_("Append") #define APPEND_LONGTEXT N_( \ @@ -127,12 +139,12 @@ vlc_module_begin(); set_subcategory( SUBCAT_INPUT_DEMUX ); add_string( "ts-extra-pmt", NULL, NULL, PMT_TEXT, PMT_LONGTEXT, VLC_TRUE ); - add_bool( "ts-es-id-pid", 0, NULL, PID_TEXT, PID_LONGTEXT, VLC_TRUE ); + add_bool( "ts-es-id-pid", 1, NULL, PID_TEXT, PID_LONGTEXT, VLC_TRUE ); add_string( "ts-out", NULL, NULL, TSOUT_TEXT, TSOUT_LONGTEXT, VLC_TRUE ); add_integer( "ts-out-mtu", 1500, NULL, MTUOUT_TEXT, MTUOUT_LONGTEXT, VLC_TRUE ); add_string( "ts-csa-ck", NULL, NULL, CSA_TEXT, CSA_LONGTEXT, VLC_TRUE ); - add_integer( "ts-csa-pkt", 188, NULL, CPKT_TEXT, CPKT_LONGTEXT, VLC_TRUE ); + add_integer( "ts-csa-pkt", 188, NULL, CPKT_TEXT, CPKT_LONGTEXT, VLC_TRUE ); add_bool( "ts-silent", 0, NULL, SILENT_TEXT, SILENT_LONGTEXT, VLC_TRUE ); add_file( "ts-dump-file", NULL, NULL, TSDUMP_TEXT, TSDUMP_LONGTEXT, VLC_FALSE ); @@ -325,7 +337,7 @@ struct demux_sys_t FILE *p_file; /* filehandle */ uint64_t i_write; /* bytes written */ vlc_bool_t b_file_out; /* dump mode enabled */ - + /* */ vlc_bool_t b_meta; }; @@ -361,6 +373,7 @@ static void IODFree( iod_descriptor_t * ); #define TS_PACKET_SIZE_192 192 #define TS_PACKET_SIZE_204 204 #define TS_PACKET_SIZE_MAX 204 +#define TS_TOPFIELD_HEADER 1320 /***************************************************************************** * Open @@ -377,25 +390,42 @@ static int Open( vlc_object_t *p_this ) ts_pid_t *pat; char *psz_mode; vlc_bool_t b_append; + vlc_bool_t b_topfield = VLC_FALSE; vlc_value_t val; if( stream_Peek( p_demux->s, &p_peek, TS_PACKET_SIZE_MAX ) < TS_PACKET_SIZE_MAX ) return VLC_EGENERIC; + if( p_peek[0] == 'T' && p_peek[1] == 'F' && + p_peek[2] == 'r' && p_peek[3] == 'c' ) + { + b_topfield = VLC_TRUE; + msg_Dbg( p_demux, "this is a topfield file" ); + } + /* Search first sync byte */ for( i_sync = 0; i_sync < TS_PACKET_SIZE_MAX; i_sync++ ) { if( p_peek[i_sync] == 0x47 ) break; } - if( i_sync >= TS_PACKET_SIZE_MAX ) + if( i_sync >= TS_PACKET_SIZE_MAX && !b_topfield ) { if( strcmp( p_demux->psz_demux, "ts" ) ) return VLC_EGENERIC; msg_Warn( p_demux, "this does not look like a TS stream, continuing" ); } - /* Check next 3 sync bytes */ - i_peek = TS_PACKET_SIZE_MAX * 3 + i_sync + 1; + if( b_topfield ) + { + /* Read the entire Topfield header */ + i_peek = TS_TOPFIELD_HEADER; + } + else + { + /* Check next 3 sync bytes */ + i_peek = TS_PACKET_SIZE_MAX * 3 + i_sync + 1; + } + if( ( stream_Peek( p_demux->s, &p_peek, i_peek ) ) < i_peek ) { msg_Err( p_demux, "cannot peek" ); @@ -423,6 +453,73 @@ static int Open( vlc_object_t *p_this ) { i_packet_size = TS_PACKET_SIZE_188; } + else if( b_topfield ) + { + i_packet_size = TS_PACKET_SIZE_188; +#if 0 + /* I used the TF5000PVR 2004 Firmware .doc header documentation, + * http://www.i-topfield.com/data/product/firmware/Structure%20of%20Recorded%20File%20in%20TF5000PVR%20(Feb%2021%202004).doc + * but after the filename the offsets seem to be incorrect. - DJ */ + int i_duration, i_name; + char *psz_name = malloc(25); + char *psz_event_name; + char *psz_event_text = malloc(130); + char *psz_ext_text = malloc(1025); + + // 2 bytes version Uimsbf (4,5) + // 2 bytes reserved (6,7) + // 2 bytes duration in minutes Uimsbf (8,9( + i_duration = (int) (p_peek[8] << 8) | p_peek[9]; + msg_Dbg( p_demux, "Topfield recording length: +/- %d minutes", i_duration); + // 2 bytes service number in channel list (10, 11) + // 2 bytes service type Bslbf 0=TV 1=Radio Bslb (12, 13) + // 4 bytes of reserved + tuner info (14,15,16,17) + // 2 bytes of Service ID Bslbf (18,19) + // 2 bytes of PMT PID Uimsbf (20,21) + // 2 bytes of PCR PID Uimsbf (22,23) + // 2 bytes of Video PID Uimsbf (24,25) + // 2 bytes of Audio PID Uimsbf (26,27) + // 24 bytes filename Bslbf + memcpy( psz_name, &p_peek[28], 24 ); + psz_name[24] = '\0'; + msg_Dbg( p_demux, "recordingname=%s", psz_name ); + // 1 byte of sat index Uimsbf (52) + // 3 bytes (1 bit of polarity Bslbf +23 bits reserved) + // 4 bytes of freq. Uimsbf (56,57,58,59) + // 2 bytes of symbol rate Uimsbf (60,61) + // 2 bytes of TS stream ID Uimsbf (62,63) + // 4 bytes reserved + // 2 bytes reserved + // 2 bytes duration Uimsbf (70,71) + //i_duration = (int) (p_peek[70] << 8) | p_peek[71]; + //msg_Dbg( p_demux, "Topfield 2nd duration field: +/- %d minutes", i_duration); + // 4 bytes EventID Uimsbf (72-75) + // 8 bytes of Start and End time info (76-83) + // 1 byte reserved (84) + // 1 byte event name length Uimsbf (89) + i_name = (int)(p_peek[89]&~0x81); + msg_Dbg( p_demux, "event name length = %d", i_name); + psz_event_name = malloc( i_name+1 ); + // 1 byte parental rating (90) + // 129 bytes of event text + memcpy( psz_event_name, &p_peek[91], i_name ); + psz_event_name[i_name] = '\0'; + memcpy( psz_event_text, &p_peek[91+i_name], 129-i_name ); + psz_event_text[129-i_name] = '\0'; + msg_Dbg( p_demux, "event name=%s", psz_event_name ); + msg_Dbg( p_demux, "event text=%s", psz_event_text ); + // 12 bytes reserved (220) + // 6 bytes reserved + // 2 bytes Event Text Length Uimsbf + // 4 bytes EventID Uimsbf + // FIXME We just have 613 bytes. not enough for this entire text + // 1024 bytes Extended Event Text Bslbf + memcpy( psz_ext_text, p_peek+372, 1024 ); + psz_ext_text[1024] = '\0'; + msg_Dbg( p_demux, "extended event text=%s", psz_ext_text ); + // 52 bytes reserved Bslbf +#endif + } else { msg_Warn( p_demux, "TS module discarded (lost sync)" ); @@ -455,7 +552,7 @@ static int Open( vlc_object_t *p_this ) msg_Info( p_demux, "dumping raw stream to standard output" ); p_sys->p_file = stdout; } - else if( ( p_sys->p_file = fopen( p_sys->psz_file, psz_mode ) ) == NULL ) + else if( ( p_sys->p_file = utf8_fopen( p_sys->psz_file, psz_mode ) ) == NULL ) { msg_Err( p_demux, "cannot create `%s' for writing", p_sys->psz_file ); p_sys->b_file_out = VLC_FALSE; @@ -500,6 +597,8 @@ static int Open( vlc_object_t *p_this ) pid->b_seen = VLC_FALSE; pid->b_valid = VLC_FALSE; } + /* PID 8191 is padding */ + p_sys->pid[8191].b_seen = VLC_TRUE; p_sys->i_packet_size = i_packet_size; p_sys->b_udp_out = VLC_FALSE; p_sys->i_ts_read = 50; @@ -561,7 +660,7 @@ static int Open( vlc_object_t *p_this ) if( i_port <= 0 ) i_port = 1234; msg_Dbg( p_demux, "resend ts to '%s:%d'", val.psz_string, i_port ); - p_sys->fd = net_OpenUDP( p_demux, "", 0, val.psz_string, i_port ); + p_sys->fd = net_ConnectUDP( p_demux, val.psz_string, i_port, 0 ); if( p_sys->fd < 0 ) { msg_Err( p_demux, "failed to open udp socket, send disabled" ); @@ -804,12 +903,13 @@ static void Close( vlc_object_t *p_this ) fclose( p_sys->p_file ); p_sys->p_file = NULL; } - free( p_sys->psz_file ); - p_sys->psz_file = NULL; free( p_sys->buffer ); } + free( p_sys->psz_file ); + p_sys->psz_file = NULL; + free( p_sys ); } @@ -828,7 +928,7 @@ static int DemuxFile( demux_t *p_demux ) i_data = stream_Read( p_demux->s, p_sys->buffer, i_bufsize ); if( (i_data <= 0) && (i_data < p_sys->i_packet_size) ) { - msg_Dbg( p_demux, "Error reading malformed packets" ); + msg_Dbg( p_demux, "error reading malformed packets" ); return i_data; } @@ -878,7 +978,7 @@ static int DemuxFile( demux_t *p_demux ) i_diff = ( i_cc - p_pid->i_cc )&0x0f; if( b_payload && i_diff == 1 ) { - p_pid->i_cc++; + p_pid->i_cc = ( p_pid->i_cc + 1 ) & 0xf; } else { @@ -1063,6 +1163,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) demux_sys_t *p_sys = p_demux->p_sys; double f, *pf; int64_t i64; + int64_t *pi64; int i_int; if( p_sys->b_file_out ) @@ -1114,6 +1215,12 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) } *pi64 = 0; return VLC_EGENERIC; +#else + case DEMUX_GET_TIME: + case DEMUX_GET_LENGTH: + pi64 = (int64_t*)va_arg( args, int64_t * ); + *pi64 = 0; + return VLC_SUCCESS; #endif case DEMUX_SET_GROUP: { @@ -1680,7 +1787,7 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk ) i_diff = ( i_cc - pid->i_cc )&0x0f; if( b_payload && i_diff == 1 ) { - pid->i_cc++; + pid->i_cc = ( pid->i_cc + 1 ) & 0xf; } else { @@ -1814,9 +1921,7 @@ static int PIDFillFormat( ts_pid_t *pid, int i_stream_type ) case 0x92: /* DVD_SPU vls (sub) */ es_format_Init( fmt, SPU_ES, VLC_FOURCC( 's', 'p', 'u', 'b' ) ); break; - case 0x93: /* LPCM vls (audio) */ - es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'l', 'p', 'c', 'b' ) ); - break; + case 0x94: /* SDDS (audio) */ es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 's', 'd', 'd', 'b' ) ); break; @@ -1917,7 +2022,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) p_iod = malloc( sizeof( iod_descriptor_t ) ); memset( p_iod, 0, sizeof( iod_descriptor_t ) ); -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n************ IOD ************" ); #endif for( i = 0; i < 255; i++ ) @@ -1934,33 +2039,33 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) byte1 = IODGetByte( &i_data, &p_data ); byte2 = IODGetByte( &i_data, &p_data ); byte3 = IODGetByte( &i_data, &p_data ); - if( byte2 == 0x02 ) //old vlc's buggy implementation of the IOD_descriptor + if( byte2 == 0x02 ) //old vlc's buggy implementation of the IOD_descriptor { p_iod->i_iod_label_scope = 0x11; p_iod->i_iod_label = byte1; i_iod_tag = byte2; } - else //correct implementation of the IOD_descriptor + else //correct implementation of the IOD_descriptor { p_iod->i_iod_label_scope = byte1; p_iod->i_iod_label = byte2; i_iod_tag = byte3; } -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* iod_label:%d", p_iod->i_iod_label ); fprintf( stderr, "\n* ===========" ); fprintf( stderr, "\n* tag:0x%x", i_iod_tag ); #endif if( i_iod_tag != 0x02 ) { -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n ERR: tag %02x != 0x02", i_iod_tag ); #endif return p_iod; } i_iod_length = IODDescriptorLength( &i_data, &p_data ); -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* length:%d", i_iod_length ); #endif if( i_iod_length > i_data ) @@ -1972,7 +2077,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) i_flags = IODGetByte( &i_data, &p_data ); p_iod->i_od_id |= i_flags >> 6; b_url = ( i_flags >> 5 )&0x01; -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* od_id:%d", p_iod->i_od_id ); fprintf( stderr, "\n* url flag:%d", b_url ); fprintf( stderr, "\n* includeInlineProfileLevel flag:%d", ( i_flags >> 4 )&0x01 ); @@ -1980,7 +2085,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) if( b_url ) { p_iod->psz_url = IODGetURL( &i_data, &p_data ); -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* url string:%s", p_iod->psz_url ); fprintf( stderr, "\n*****************************\n" ); #endif @@ -1996,7 +2101,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) p_iod->i_audioProfileLevelIndication = IODGetByte( &i_data, &p_data ); p_iod->i_visualProfileLevelIndication = IODGetByte( &i_data, &p_data ); p_iod->i_graphicsProfileLevelIndication = IODGetByte( &i_data, &p_data ); -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* ODProfileLevelIndication:%d", p_iod->i_ODProfileLevelIndication ); fprintf( stderr, "\n* sceneProfileLevelIndication:%d", p_iod->i_sceneProfileLevelIndication ); fprintf( stderr, "\n* audioProfileLevelIndication:%d", p_iod->i_audioProfileLevelIndication ); @@ -2024,7 +2129,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) { #define es_descr p_iod->es_descr[i_es_index] int i_decoderConfigDescr_length; -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* - ES_Descriptor length:%d", i_length ); #endif es_descr.b_ok = 1; @@ -2035,7 +2140,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) b_url = ( i_flags >> 6 )&0x01; es_descr.b_OCRStreamFlag = ( i_flags >> 5 )&0x01; es_descr.i_streamPriority = i_flags & 0x1f; -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* * streamDependenceFlag:%d", es_descr.b_streamDependenceFlag ); fprintf( stderr, "\n* * OCRStreamFlag:%d", es_descr.b_OCRStreamFlag ); fprintf( stderr, "\n* * streamPriority:%d", es_descr.i_streamPriority ); @@ -2043,7 +2148,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) if( es_descr.b_streamDependenceFlag ) { es_descr.i_dependOn_es_id = IODGetWord( &i_data, &p_data ); -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* * dependOn_es_id:%d", es_descr.i_dependOn_es_id ); #endif } @@ -2051,7 +2156,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) if( b_url ) { es_descr.psz_url = IODGetURL( &i_data, &p_data ); -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* url string:%s", es_descr.psz_url ); #endif } @@ -2063,21 +2168,21 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) if( es_descr.b_OCRStreamFlag ) { es_descr.i_OCR_es_id = IODGetWord( &i_data, &p_data ); -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* * OCR_es_id:%d", es_descr.i_OCR_es_id ); #endif } if( IODGetByte( &i_data, &p_data ) != 0x04 ) { -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* ERR missing DecoderConfigDescr" ); #endif es_descr.b_ok = 0; break; } i_decoderConfigDescr_length = IODDescriptorLength( &i_data, &p_data ); -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* - DecoderConfigDesc length:%d", i_decoderConfigDescr_length ); #endif #define dec_descr es_descr.dec_descr @@ -2088,7 +2193,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) dec_descr.i_bufferSizeDB = IODGet3Bytes( &i_data, &p_data ); dec_descr.i_maxBitrate = IODGetDWord( &i_data, &p_data ); dec_descr.i_avgBitrate = IODGetDWord( &i_data, &p_data ); -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* * objectTypeIndication:0x%x", dec_descr.i_objectTypeIndication ); fprintf( stderr, "\n* * streamType:0x%x", dec_descr.i_streamType ); fprintf( stderr, "\n* * upStream:%d", dec_descr.b_upStream ); @@ -2125,18 +2230,18 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) if( IODGetByte( &i_data, &p_data ) != 0x06 ) { -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* ERR missing SLConfigDescr" ); #endif es_descr.b_ok = 0; break; } i_SLConfigDescr_length = IODDescriptorLength( &i_data, &p_data ); -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* - SLConfigDescr length:%d", i_SLConfigDescr_length ); #endif i_predefined = IODGetByte( &i_data, &p_data ); -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* * i_predefined:0x%x", i_predefined ); #endif switch( i_predefined ) @@ -2174,7 +2279,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) } break; default: -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* ERR unsupported SLConfigDescr predefined" ); #endif es_descr.b_ok = 0; @@ -2185,7 +2290,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) #undef sl_descr #undef es_descr default: -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n* - OD tag:0x%x length:%d (Unsupported)", i_tag, i_length ); #endif break; @@ -2195,7 +2300,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) i_data = i_data_sav - i_length; i_es_index++; } -#ifdef DEBUG +#ifdef TS_DEBUG fprintf( stderr, "\n*****************************\n" ); #endif return p_iod; @@ -2303,6 +2408,7 @@ static void SDTCallBack( demux_t *p_demux, dvbpsi_sdt_t *p_sdt ) { if( p_dr->i_tag == 0x48 ) { +#if 0 static const char *psz_type[0x11] = { "Reserved", "Digital television service", @@ -2322,6 +2428,7 @@ static void SDTCallBack( demux_t *p_demux, dvbpsi_sdt_t *p_sdt ) "RCS FLS (see EN 301 790 [35])", "DVB MHP service" }; +#endif dvbpsi_service_dr_t *pD = dvbpsi_DecodeServiceDr( p_dr ); char str1[257]; char str2[257]; @@ -2335,8 +2442,8 @@ static void SDTCallBack( demux_t *p_demux, dvbpsi_sdt_t *p_sdt ) msg_Dbg( p_demux, " - type=%d provider=%s name=%s", pD->i_service_type, str1, str2 ); - vlc_meta_Add( p_meta, "Name", str2 ); - vlc_meta_Add( p_meta, "Provider", str1 ); + vlc_meta_SetTitle( p_meta, str2 ); + vlc_meta_SetPublisher( p_meta, str1 ); if( pD->i_service_type >= 0x01 && pD->i_service_type <= 0x10 ) vlc_meta_Add( p_meta, "Type", psz_type[pD->i_service_type] ); } @@ -2353,7 +2460,6 @@ static void SDTCallBack( demux_t *p_demux, dvbpsi_sdt_t *p_sdt ) else vlc_meta_Add( p_meta, "Status", "Unknown" ); - es_out_Control( p_demux->out, ES_OUT_SET_GROUP_META, p_srv->i_service_id, p_meta ); vlc_meta_Delete( p_meta ); @@ -2389,7 +2495,7 @@ static void EITEventFixString( unsigned char *psz ) * caracters encoding, for now lets skip it */ if( psz[0] >= 0x20 ) return; - if( ( i_len = strlen( psz ) ) > 0 ) + if( ( i_len = strlen( (char *) psz ) ) > 0 ) memmove( &psz[0], &psz[1], i_len ); /* Copy the \0 too */ } static void EITCallBack( demux_t *p_demux, dvbpsi_eit_t *p_eit ) @@ -2458,8 +2564,8 @@ static void EITCallBack( demux_t *p_demux, dvbpsi_eit_t *p_eit ) memcpy( psz_text, pE->i_text, pE->i_text_length ); psz_text[pE->i_text_length] = '\0'; - EITEventFixString(psz_name); - EITEventFixString(psz_text); + EITEventFixString((unsigned char *)&psz_name); + EITEventFixString((unsigned char *)&psz_text); msg_Dbg( p_demux, " - short event lang=%3.3s '%s' : '%s'", pE->i_iso_639_code, psz_name, psz_text ); } @@ -2480,12 +2586,12 @@ static void EITCallBack( demux_t *p_demux, dvbpsi_eit_t *p_eit ) memcpy( str1, pE->i_item_description[i], pE->i_item_description_length[i] ); str1[pE->i_item_description_length[i]] = '\0'; - EITEventFixString(str1); + EITEventFixString((unsigned char *)&str1); memcpy( str2, pE->i_item[i], pE->i_item_length[i] ); str2[pE->i_item_length[i]] = '\0'; - EITEventFixString(str2); + EITEventFixString((unsigned char *)&str2); msg_Dbg( p_demux, " - desc='%s' item='%s'", str1, str2 ); psz_extra = realloc( psz_extra, @@ -2499,7 +2605,7 @@ static void EITCallBack( demux_t *p_demux, dvbpsi_eit_t *p_eit ) memcpy( str1, pE->i_text, pE->i_text_length ); str1[pE->i_text_length] = '\0'; - EITEventFixString(str1); + EITEventFixString((unsigned char *)&str1); msg_Dbg( p_demux, " - text='%s'", str1 ); psz_extra = realloc( psz_extra, @@ -2524,7 +2630,7 @@ static void EITCallBack( demux_t *p_demux, dvbpsi_eit_t *p_eit ) if( p_evt->i_running_status == 0x04 ) { - vlc_meta_Add( p_meta, VLC_META_NOW_PLAYING, psz_name ); + vlc_meta_SetNowPlaying( p_meta, psz_name ); b_event_active = VLC_TRUE; } @@ -2533,7 +2639,7 @@ static void EITCallBack( demux_t *p_demux, dvbpsi_eit_t *p_eit ) } if( !b_event_active ) - vlc_meta_Add( p_meta, VLC_META_NOW_PLAYING, "" ); + vlc_meta_SetNowPlaying( p_meta, "" ); es_out_Control( p_demux->out, ES_OUT_SET_GROUP_META, p_eit->i_service_id, p_meta ); vlc_meta_Delete( p_meta ); @@ -2548,6 +2654,8 @@ static void PSINewTableCallBack( demux_t *p_demux, dvbpsi_handle h, msg_Dbg( p_demux, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)", i_table_id, i_table_id, i_extension, i_extension ); #endif + if( p_demux->p_sys->pid[0].psi->i_pat_version == -1 ) + return; if( i_table_id == 0x42 ) { @@ -2880,23 +2988,32 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) else if( p_dr->i_tag == 0x73 ) { /* DTS audio descriptor (ETSI TS 101 154 Annex F) */ - msg_Dbg( p_demux, " * DTS audio descriptor not decoded" ); + msg_Dbg( p_demux, " * DTS audio descriptor not decoded" ); pid->es->fmt.i_cat = AUDIO_ES; pid->es->fmt.i_codec = VLC_FOURCC( 'd', 't', 's', ' ' ); } else if( p_dr->i_tag == 0x45 ) { - msg_Dbg( p_demux, " * VBI Data descriptor" ); + msg_Dbg( p_demux, " * VBI Data descriptor" ); /* FIXME : store the information somewhere */ } else if( p_dr->i_tag == 0x46 ) { - msg_Dbg( p_demux, " * VBI Teletext descriptor" ); + msg_Dbg( p_demux, " * VBI Teletext descriptor" ); /* FIXME : store the information somewhere */ } +#ifdef _DVBPSI_DR_52_H_ + else if( p_dr->i_tag == 0x52 ) + { + dvbpsi_stream_identifier_dr_t *si; + si = dvbpsi_DecodeStreamIdentifierDr( p_dr ); + + msg_Dbg( p_demux, " * Stream Component Identifier: %d", si->i_component_tag ); + } +#endif else if( p_dr->i_tag == 0x56 ) { - msg_Dbg( p_demux, " * EBU Teletext descriptor" ); + msg_Dbg( p_demux, " * EBU Teletext descriptor" ); pid->es->fmt.i_cat = SPU_ES; pid->es->fmt.i_codec = VLC_FOURCC( 't', 'e', 'l', 'x' ); pid->es->fmt.psz_description = strdup( "Teletext" ); @@ -3016,10 +3133,76 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) if( p_decoded ) { +#if DR_0A_API_VER >= 2 + pid->es->fmt.psz_language = malloc( 4 ); + memcpy( pid->es->fmt.psz_language, + p_decoded->code[0].iso_639_code, 3 ); + pid->es->fmt.psz_language[3] = 0; + msg_Dbg( p_demux, "found language: %s", pid->es->fmt.psz_language); + switch( p_decoded->code[0].i_audio_type ) { + case 0: + pid->es->fmt.psz_description = NULL; + break; + case 1: + pid->es->fmt.psz_description = + strdup(_("clean effects")); + break; + case 2: + pid->es->fmt.psz_description = + strdup(_("hearing impaired")); + break; + case 3: + pid->es->fmt.psz_description = + strdup(_("visual impaired commentary")); + break; + default: + msg_Dbg( p_demux, "unknown audio type: %d", + p_decoded->code[0].i_audio_type); + pid->es->fmt.psz_description = NULL; + break; + } + pid->es->fmt.i_extra_languages = p_decoded->i_code_count-1; + pid->es->fmt.p_extra_languages = + malloc( sizeof(*pid->es->fmt.p_extra_languages) * + pid->es->fmt.i_extra_languages ); + for( i = 0; i < pid->es->fmt.i_extra_languages; i++ ) { + msg_Dbg( p_demux, "bang" ); + pid->es->fmt.p_extra_languages[i].psz_language = + malloc(4); + memcpy(pid->es->fmt.p_extra_languages[i].psz_language, + p_decoded->code[i+1].iso_639_code, 3 ); + pid->es->fmt.p_extra_languages[i].psz_language[3] = '\0'; + switch( p_decoded->code[i].i_audio_type ) { + case 0: + pid->es->fmt.p_extra_languages[i].psz_description = + NULL; + break; + case 1: + pid->es->fmt.p_extra_languages[i].psz_description = + strdup(_("clean effects")); + break; + case 2: + pid->es->fmt.p_extra_languages[i].psz_description = + strdup(_("hearing impaired")); + break; + case 3: + pid->es->fmt.p_extra_languages[i].psz_description = + strdup(_("visual impaired commentary")); + break; + default: + msg_Dbg( p_demux, "unknown audio type: %d", + p_decoded->code[i].i_audio_type); + pid->es->fmt.psz_description = NULL; + break; + } + + } +#else pid->es->fmt.psz_language = malloc( 4 ); memcpy( pid->es->fmt.psz_language, p_decoded->i_iso_639_code, 3 ); pid->es->fmt.psz_language[3] = 0; +#endif } } } @@ -3096,7 +3279,8 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) } } - if( DVBProgramIsSelected( p_demux, prg->i_number ) ) + if( DVBProgramIsSelected( p_demux, prg->i_number ) + && (pid->es->id != NULL || p_sys->b_udp_out) ) { /* Set demux filter */ stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, @@ -3293,7 +3477,9 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat ) if( p_sys->i_dvb_program == 0 ) p_sys->i_dvb_program = p_program->i_number; - if( stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, ACCESS_SET_PRIVATE_ID_STATE, p_program->i_pid, VLC_TRUE ) ) + if( stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, + ACCESS_SET_PRIVATE_ID_STATE, + p_program->i_pid, VLC_TRUE ) ) p_sys->b_dvb_control = VLC_FALSE; } }