X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fmpeg%2Fts.c;h=df434a99fd6f250978d7d4c8465e3a89d5a31f18;hb=e7d665052834a3cb508893fe3060ba3ae929b88f;hp=2758c77f207e587739e30d7c95a2485f314ff612;hpb=d8e92b78f09a58d76f474f7f7d69821cc2ee856f;p=vlc diff --git a/modules/demux/mpeg/ts.c b/modules/demux/mpeg/ts.c index 2758c77f20..df434a99fd 100644 --- a/modules/demux/mpeg/ts.c +++ b/modules/demux/mpeg/ts.c @@ -2,7 +2,7 @@ * mpeg_ts.c : Transport Stream input module for vlc ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: ts.c,v 1.22 2003/05/05 22:48:22 gbazin Exp $ + * $Id: ts.c,v 1.38 2003/10/27 13:35:15 nitrox Exp $ * * Authors: Henri Fallon * Johan Bilien @@ -26,12 +26,6 @@ * Preamble *****************************************************************************/ #include -#include - -#ifdef HAVE_STDINT_H -# include /* uint8_t */ -#endif - #include #include @@ -94,13 +88,13 @@ static void TS_DVBPSI_HandlePMT ( input_thread_t *, dvbpsi_pmt_t * ); /***************************************************************************** * Module descriptor *****************************************************************************/ -#define VLS_BACKWARDS_COMPAT_TEXT N_("compatibility with pre-0.4 VLS") +#define VLS_BACKWARDS_COMPAT_TEXT N_("Compatibility with pre-0.4 VLS") #define VLS_BACKWARDS_COMPAT_LONGTEXT N_( \ "The protocol for transmitting A/52 audio streams changed between VLC " \ "0.3.x and 0.4. By default VLC assumes you have the latest VLS. In case " \ "you're using an old version, select this option.") -#define BUGGY_PSI_TEXT N_("buggy PSI") +#define BUGGY_PSI_TEXT N_("Buggy PSI") #define BUGGY_PSI_LONGTEXT N_( \ "If you have a stream whose PSI packets do not feature incremented " \ "continuity counters, select this option.") @@ -136,13 +130,19 @@ static int Activate( vlc_object_t * p_this ) /* Set the demux function */ p_input->pf_demux = Demux; + p_input->pf_demux_control = demux_vaControlDefault; +#if 0 + /* XXX Unused already done by src/input.c */ /* Initialize access plug-in structures. */ if( p_input->i_mtu == 0 ) { /* Improve speed. */ + msg_Dbg( p_input, "using default mtu (%d) with bufsize (%d)\n", + p_input->i_mtu, INPUT_DEFAULT_BUFSIZE ); p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE; } +#endif /* Have a peep at the show. */ if( input_Peek( p_input, &p_peek, 1 ) < 1 ) @@ -218,6 +218,7 @@ static int Activate( vlc_object_t * p_this ) * The PAT es is indepedent of any program. */ p_pat_es = input_AddES( p_input, NULL, 0x00, UNKNOWN_ES, NULL, sizeof( es_ts_data_t ) ); + p_pat_es->i_fourcc = VLC_FOURCC( 'p', 'a', 't', ' ' ); p_demux_data = (es_ts_data_t *)p_pat_es->p_demux_data; p_demux_data->b_psi = 1; p_demux_data->i_psi_type = PSI_IS_PAT; @@ -297,11 +298,11 @@ static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data, { /* unit_start set to 1 -> presence of a pointer field * (see ISO/IEC 13818 (2.4.4.2) which should be set to 0x00 */ - if( (u8)p[0] != 0x00 ) + if( (uint8_t)p[0] != 0x00 ) { msg_Warn( p_input, "non-zero pointer field found, trying to continue" ); - p+=(u8)p[0]; + p+=(uint8_t)p[0]; } else { @@ -310,7 +311,7 @@ static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data, /* This is the begining of a new section */ - if( ((u8)(p[1]) & 0xc0) != 0x80 ) + if( ((uint8_t)(p[1]) & 0xc0) != 0x80 ) { msg_Warn( p_input, "invalid PSI packet" ); p_psi->b_trash = 1; @@ -320,7 +321,7 @@ static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data, p_psi->i_section_length = ((p[1] & 0xF) << 8) | p[2]; p_psi->b_section_complete = 0; p_psi->i_read_in_section = 0; - p_psi->i_section_number = (u8)p[6]; + p_psi->i_section_number = (uint8_t)p[6]; if( p_psi->b_is_complete || p_psi->i_section_number == 0 ) { @@ -328,7 +329,7 @@ static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data, p_psi->b_is_complete = 0; p_psi->b_trash = 0; p_psi->i_version_number = ( p[5] >> 1 ) & 0x1f; - p_psi->i_last_section_number = (u8)p[7]; + p_psi->i_last_section_number = (uint8_t)p[7]; /* We'll write at the begining of the buffer */ p_psi->p_current = p_psi->buffer; @@ -346,7 +347,7 @@ static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data, "PSI version differs inside same PAT" ); p_psi->b_trash = 1; } - if( p_psi->i_section_number + 1 != (u8)p[6] ) + if( p_psi->i_section_number + 1 != (uint8_t)p[6] ) { msg_Warn( p_input, "PSI Section discontinuity, packet lost?" ); @@ -445,17 +446,17 @@ static void TSDecodePAT( input_thread_t * p_input, es_descriptor_t * p_es ) do { - i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) | + i_section_length = ((uint32_t)(p_current_data[1] & 0xF) << 8) | p_current_data[2]; - i_current_section = (u8)p_current_data[6]; + i_current_section = (uint8_t)p_current_data[6]; for( i_loop = 0; ( i_loop < (i_section_length - 9) / 4 ) && !b_changed; i_loop++ ) { - i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 ) + i_program_id = ( (uint32_t)*(p_current_data + i_loop * 4 + 8) << 8 ) | *(p_current_data + i_loop * 4 + 9); - i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F) + i_pmt_pid = ( ((uint32_t)*(p_current_data + i_loop * 4 + 10) & 0x1F) << 8 ) | *(p_current_data + i_loop * 4 + 11); @@ -507,15 +508,15 @@ static void TSDecodePAT( input_thread_t * p_input, es_descriptor_t * p_es ) do { - i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) | + i_section_length = ((uint32_t)(p_current_data[1] & 0xF) << 8) | p_current_data[2]; - i_current_section = (u8)p_current_data[6]; + i_current_section = (uint8_t)p_current_data[6]; for( i_loop = 0; i_loop < (i_section_length - 9) / 4 ; i_loop++ ) { - i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 ) + i_program_id = ( (uint32_t)*(p_current_data + i_loop * 4 + 8) << 8 ) | *(p_current_data + i_loop * 4 + 9); - i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F) + i_pmt_pid = ( ((uint32_t)*(p_current_data + i_loop * 4 + 10) & 0x1F) << 8 ) | *(p_current_data + i_loop * 4 + 11); @@ -531,8 +532,9 @@ static void TSDecodePAT( input_thread_t * p_input, es_descriptor_t * p_es ) p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED; /* Add the PMT ES to this program */ - p_current_es = input_AddES( p_input, p_pgrm,(u16)i_pmt_pid, + p_current_es = input_AddES( p_input, p_pgrm,(uint16_t)i_pmt_pid, UNKNOWN_ES, NULL, sizeof( es_ts_data_t) ); + p_current_es->i_fourcc = VLC_FOURCC( 'p', 'm', 't', ' ' ); p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data; p_es_demux->b_psi = 1; p_es_demux->i_psi_type = PSI_IS_PMT; @@ -587,7 +589,7 @@ static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es ) p_current_section = p_psi->buffer; p_current_data = p_psi->buffer; - p_pgrm_data->i_pcr_pid = ( ((u32)*(p_current_section + 8) & 0x1F) << 8 ) | + p_pgrm_data->i_pcr_pid = ( ((uint32_t)*(p_current_section + 8) & 0x1F) << 8 ) | *(p_current_section + 9); @@ -610,10 +612,10 @@ static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es ) /* Then add what we received in this PMT */ do { - i_section_length = ( ((u32)*(p_current_data + 1) & 0xF) << 8 ) | + i_section_length = ( ((uint32_t)*(p_current_data + 1) & 0xF) << 8 ) | *(p_current_data + 2); - i_current_section = (u8)p_current_data[6]; - i_prog_info_length = ( ((u32)*(p_current_data + 10) & 0xF) << 8 ) | + i_current_section = (uint8_t)p_current_data[6]; + i_prog_info_length = ( ((uint32_t)*(p_current_data + 10) & 0xF) << 8 ) | *(p_current_data + 11); /* For the moment we ignore program descriptors */ @@ -624,9 +626,9 @@ static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es ) while( p_current_data < p_current_section + i_section_length -1 ) { i_stream_type = (int)p_current_data[0]; - i_pid = ( ((u32)*(p_current_data + 1) & 0x1F) << 8 ) | + i_pid = ( ((uint32_t)*(p_current_data + 1) & 0x1F) << 8 ) | *(p_current_data + 2); - i_es_info_length = ( ((u32)*(p_current_data + 3) & 0xF) << 8 ) | + i_es_info_length = ( ((uint32_t)*(p_current_data + 3) & 0xF) << 8 ) | *(p_current_data + 4); /* Tell the interface what kind of stream it is and select @@ -654,7 +656,6 @@ static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es ) i_cat = AUDIO_ES; break; case A52_AUDIO_ES: - case A52DVB_AUDIO_ES: if ( !b_vls_compat ) i_fourcc = VLC_FOURCC('a','5','2',' '); else @@ -710,7 +711,7 @@ static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es ) } /* Add this ES to the program */ - p_new_es = input_AddES( p_input, p_es->p_pgrm, (u16)i_pid, + p_new_es = input_AddES( p_input, p_es->p_pgrm, (uint16_t)i_pid, i_cat, NULL, sizeof( es_ts_data_t ) ); ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter = 0xFF; @@ -736,7 +737,7 @@ static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es ) if( !p_input->stream.p_selected_program ) { pgrm_descriptor_t * p_pgrm_to_select; - u16 i_id = (u16)config_GetInt( p_input, "program" ); + uint16_t i_id = (uint16_t)config_GetInt( p_input, "program" ); if( i_id != 0 ) /* if user specified a program */ { @@ -1174,9 +1175,12 @@ static void TS_DVBPSI_HandlePAT( input_thread_t * p_input, p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data; - if ( ( p_new_pat->b_current_next && ( p_new_pat->i_version != p_stream_data->i_pat_version ) ) || - p_stream_data->i_pat_version == PAT_UNINITIALIZED ) + if( ( p_new_pat->b_current_next && + ( p_new_pat->i_version != p_stream_data->i_pat_version ) ) || + p_stream_data->i_pat_version == PAT_UNINITIALIZED ) { + msg_Dbg( p_input, "Processing PAT version %d", p_new_pat->i_version ); + /* Delete all programs */ while( p_input->stream.i_pgrm_number ) { @@ -1188,6 +1192,10 @@ static void TS_DVBPSI_HandlePAT( input_thread_t * p_input, MP4_IODClean( &p_pgrm_demux_old->iod ); } + /* Delete old PMT decoder */ + if( p_pgrm_demux_old->p_pmt_handle ) + dvbpsi_DetachPMT( p_pgrm_demux_old->p_pmt_handle ); + input_DelProgram( p_input, p_input->stream.pp_programs[0] ); } @@ -1196,6 +1204,8 @@ static void TS_DVBPSI_HandlePAT( input_thread_t * p_input, while( p_pgrm ) { + msg_Dbg( p_input, "New program: %d", p_pgrm->i_number ); + /* If program = 0, we're having info about NIT not PMT */ if( p_pgrm->i_number ) { @@ -1208,21 +1218,13 @@ static void TS_DVBPSI_HandlePAT( input_thread_t * p_input, /* Add the PMT ES to this program */ p_current_es = input_AddES( p_input, p_new_pgrm, - (u16)p_pgrm->i_pid, UNKNOWN_ES, + (uint16_t)p_pgrm->i_pid, UNKNOWN_ES, NULL, sizeof(es_ts_data_t) ); + p_current_es->i_fourcc = VLC_FOURCC( 'p', 'm', 't', ' ' ); p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data; p_es_demux->b_psi = 1; p_es_demux->i_psi_type = PSI_IS_PMT; - - p_es_demux->p_psi_section = malloc( sizeof( psi_section_t ) ); - if ( p_es_demux->p_psi_section == NULL ) - { - msg_Err( p_input, "out of memory" ); - p_input->b_error = 1; - return; - } - - p_es_demux->p_psi_section->b_is_complete = 0; + p_es_demux->p_psi_section = NULL; p_es_demux->i_continuity_counter = 0xFF; /* Create a PMT decoder */ @@ -1273,10 +1275,31 @@ static void TS_DVBPSI_HandlePMT( input_thread_t * p_input, p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data; p_pgrm_demux->i_pcr_pid = p_new_pmt->i_pcr_pid; - if( ( p_new_pmt->b_current_next && ( p_new_pmt->i_version != p_pgrm_demux->i_pmt_version ) ) || - p_pgrm_demux->i_pmt_version == PMT_UNINITIALIZED ) + if( ( p_new_pmt->b_current_next && + ( p_new_pmt->i_version != p_pgrm_demux->i_pmt_version ) ) || + p_pgrm_demux->i_pmt_version == PMT_UNINITIALIZED ) { dvbpsi_descriptor_t *p_dr = p_new_pmt->p_first_descriptor; + int i_loop; + + msg_Dbg( p_input, "Processing PMT for program %d version %d", + p_new_pmt->i_program_number, p_new_pmt->i_version ); + + /* Delete all ES in this program except the PSI. We start from the + * end because i_es_number gets decremented after each deletion. */ + for( i_loop = p_pgrm->i_es_number ; i_loop > 0 ; ) + { + es_ts_data_t * p_es_demux; + + i_loop--; + p_es_demux = (es_ts_data_t *) + p_pgrm->pp_es[i_loop]->p_demux_data; + if ( !p_es_demux->b_psi ) + { + input_DelES( p_input, p_pgrm->pp_es[i_loop] ); + } + } + /* IOD */ while( p_dr && ( p_dr->i_tag != 0x1d ) ) p_dr = p_dr->p_next; @@ -1289,7 +1312,15 @@ static void TS_DVBPSI_HandlePMT( input_thread_t * p_input, p_es = p_new_pmt->p_first_es; while( p_es ) { - int i_fourcc, i_cat, i_stream_id; + vlc_fourcc_t i_fourcc; + int i_size, i_cat, i_stream_id = 0; + es_ts_data_t demux_data; + BITMAPINFOHEADER *p_bih = NULL; + WAVEFORMATEX *p_wf = NULL; + char psz_desc[30]; + + memset( &demux_data, 0, sizeof(es_ts_data_t) ); + *psz_desc = 0; switch( p_es->i_type ) { @@ -1305,7 +1336,6 @@ static void TS_DVBPSI_HandlePMT( input_thread_t * p_input, i_cat = AUDIO_ES; break; case A52_AUDIO_ES: - case A52DVB_AUDIO_ES: if ( !b_vls_compat ) i_fourcc = VLC_FOURCC('a','5','2',' '); else @@ -1362,178 +1392,160 @@ static void TS_DVBPSI_HandlePMT( input_thread_t * p_input, i_stream_id = 0xfa; break; case MSCODEC_VIDEO_ES: - i_fourcc = VLC_FOURCC(0,0,0,0); // fixed later + i_fourcc = VLC_FOURCC(0,0,0,0); /* fixed later */ i_cat = VIDEO_ES; i_stream_id = 0xa0; break; + case PES_PRIVATE_ES: + /* We need to check a descriptor to find the real codec */ + i_fourcc = VLC_FOURCC(0,0,0,0); /* fixed later */ + i_cat = UNKNOWN_ES; + i_stream_id = 0xbd; + break; default: i_fourcc = 0; i_cat = UNKNOWN_ES; i_stream_id = 0; } - /* Add this ES */ - p_new_es = input_AddES( p_input, p_pgrm, (u16)p_es->i_pid, - i_cat, NULL, sizeof( es_ts_data_t ) ); - if( p_new_es == NULL ) - { - msg_Err( p_input, "could not add ES %d", p_es->i_pid ); - p_input->b_error = 1; - return; - } - p_new_es->i_fourcc = i_fourcc; - p_new_es->i_stream_id = i_stream_id; - - ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter = 0xFF; - - if( p_es->i_type == MPEG4_VIDEO_ES || p_es->i_type == MPEG4_AUDIO_ES ) + if( p_es->i_type == MPEG4_VIDEO_ES || + p_es->i_type == MPEG4_AUDIO_ES ) { /* mpeg4 stream, search sl_descriptor */ dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor; - es_ts_data_t *p_es_demux = - (es_ts_data_t*)p_new_es->p_demux_data; - while( p_dr && ( p_dr->i_tag != 0x1f ) ) - p_dr = p_dr->p_next; + while( p_dr && ( p_dr->i_tag != 0x1f ) ) p_dr = p_dr->p_next; + if( p_dr && p_dr->i_length == 2 ) { int i_es_descr_index; - p_es_demux->i_es_id = + demux_data.i_es_id = ( p_dr->p_data[0] << 8 ) | p_dr->p_data[1]; - p_es_demux->p_es_descr = NULL; + demux_data.p_es_descr = NULL; msg_Warn( p_input, "found SL_descriptor" ); - for( i_es_descr_index = 0; i_es_descr_index < 255; i_es_descr_index++ ) + for( i_es_descr_index = 0; i_es_descr_index < 255; + i_es_descr_index++ ) { if( p_pgrm_demux->iod.es_descr[i_es_descr_index].b_ok && - p_pgrm_demux->iod.es_descr[i_es_descr_index].i_es_id == p_es_demux->i_es_id ) + p_pgrm_demux->iod.es_descr[i_es_descr_index].i_es_id == demux_data.i_es_id ) { - p_es_demux->p_es_descr = &p_pgrm_demux->iod.es_descr[i_es_descr_index]; + demux_data.p_es_descr = + &p_pgrm_demux->iod.es_descr[i_es_descr_index]; break; } } } - if( p_es_demux->p_es_descr != NULL ) + + if( demux_data.p_es_descr != NULL ) { - vlc_fourcc_t i_fourcc; - int i_cat; - p_es_demux->b_mpeg4 = 1; +#define DESCR demux_data.p_es_descr->dec_descr + demux_data.b_mpeg4 = 1; /* fix fourcc */ - switch( p_es_demux->p_es_descr->dec_descr.i_streamType ) + switch( DESCR.i_streamType ) { - case 0x04: /* VisualStream */ - i_cat = VIDEO_ES; - switch( p_es_demux->p_es_descr->dec_descr.i_objectTypeIndication ) - { - case 0x20: - i_fourcc = VLC_FOURCC('m','p','4','v'); // mpeg4 - break; - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - i_fourcc = VLC_FOURCC( 'm','p','g','v' ); // mpeg2 - break; - case 0x6a: - i_fourcc = VLC_FOURCC( 'm','p','g','v' ); // mpeg1 - break; - case 0x6c: - i_fourcc = VLC_FOURCC( 'j','p','e','g' ); // mpeg1 - break; - default: - i_fourcc = 0; - break; - } + case 0x04: /* VisualStream */ + i_cat = VIDEO_ES; + switch( DESCR.i_objectTypeIndication ) + { + case 0x20: + i_fourcc = VLC_FOURCC('m','p','4','v'); // mpeg4 break; - case 0x05: /* AudioStream */ - i_cat = AUDIO_ES; - switch( p_es_demux->p_es_descr->dec_descr.i_objectTypeIndication ) - { - case 0x40: - i_fourcc = VLC_FOURCC('m','p','4','a'); // mpeg4 - break; - case 0x66: - case 0x67: - case 0x68: - i_fourcc = VLC_FOURCC('m','p','4','a'); // mpeg2 aac - break; - case 0x69: - i_fourcc = VLC_FOURCC('m','p','g','a'); // mpeg2 - break; - case 0x6b: - i_fourcc = VLC_FOURCC('m','p','g','a'); // mpeg1 - break; - default: - i_fourcc = 0; - break; - } + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + i_fourcc = VLC_FOURCC( 'm','p','g','v' ); // mpeg2 + break; + case 0x6a: + i_fourcc = VLC_FOURCC( 'm','p','g','v' ); // mpeg1 + break; + case 0x6c: + i_fourcc = VLC_FOURCC( 'j','p','e','g' ); // mpeg1 break; default: - i_cat = UNKNOWN_ES; i_fourcc = 0; break; - } - - p_new_es->i_fourcc = i_fourcc; - p_new_es->i_cat = i_cat; - switch( i_cat ) - { - case VIDEO_ES: - { - int i_size; - BITMAPINFOHEADER *p_bih; - - i_size = sizeof( BITMAPINFOHEADER ) + - p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len; - p_new_es->p_bitmapinfoheader = (void*)p_bih = malloc( i_size ); - p_bih->biSize = i_size; - p_bih->biWidth = 0; - p_bih->biHeight = 0; - p_bih->biPlanes = 1; - p_bih->biBitCount = 0; - p_bih->biCompression = 0; - p_bih->biSizeImage = 0; - p_bih->biXPelsPerMeter = 0; - p_bih->biYPelsPerMeter = 0; - p_bih->biClrUsed = 0; - p_bih->biClrImportant = 0; - memcpy( &p_bih[1], - p_es_demux->p_es_descr->dec_descr.p_decoder_specific_info, - p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len ); - } + } + break; + case 0x05: /* AudioStream */ + i_cat = AUDIO_ES; + switch( DESCR.i_objectTypeIndication ) + { + case 0x40: + i_fourcc = VLC_FOURCC('m','p','4','a'); // mpeg4 break; - case AUDIO_ES: - { - int i_size; - WAVEFORMATEX *p_wf; - - i_size = sizeof( WAVEFORMATEX ) + - p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len; - p_new_es->p_waveformatex = (void*)p_wf = malloc( i_size ); - p_wf->wFormatTag = 0xffff; - p_wf->nChannels = 0; - p_wf->nSamplesPerSec = 0; - p_wf->nAvgBytesPerSec = 0; - p_wf->nBlockAlign = 1; - p_wf->wBitsPerSample = 0; - p_wf->cbSize = p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len; - memcpy( &p_wf[1], - p_es_demux->p_es_descr->dec_descr.p_decoder_specific_info, - p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len ); - } + case 0x66: + case 0x67: + case 0x68: + i_fourcc = VLC_FOURCC('m','p','4','a');// mpeg2 aac + break; + case 0x69: + i_fourcc = VLC_FOURCC('m','p','g','a'); // mpeg2 + break; + case 0x6b: + i_fourcc = VLC_FOURCC('m','p','g','a'); // mpeg1 break; default: + i_fourcc = 0; break; + } + break; + default: + i_cat = UNKNOWN_ES; + i_fourcc = 0; + break; + } + + switch( i_cat ) + { + case VIDEO_ES: + i_size = sizeof( BITMAPINFOHEADER ) + + DESCR.i_decoder_specific_info_len; + p_bih = malloc( i_size ); + p_bih->biSize = i_size; + p_bih->biWidth = 0; + p_bih->biHeight = 0; + p_bih->biPlanes = 1; + p_bih->biBitCount = 0; + p_bih->biCompression = 0; + p_bih->biSizeImage = 0; + p_bih->biXPelsPerMeter = 0; + p_bih->biYPelsPerMeter = 0; + p_bih->biClrUsed = 0; + p_bih->biClrImportant = 0; + memcpy( &p_bih[1], + DESCR.p_decoder_specific_info, + DESCR.i_decoder_specific_info_len ); + break; + case AUDIO_ES: + i_size = sizeof( WAVEFORMATEX ) + + DESCR.i_decoder_specific_info_len; + p_wf = malloc( i_size ); + p_wf->wFormatTag = 0xffff; + p_wf->nChannels = 0; + p_wf->nSamplesPerSec = 0; + p_wf->nAvgBytesPerSec = 0; + p_wf->nBlockAlign = 1; + p_wf->wBitsPerSample = 0; + p_wf->cbSize = DESCR.i_decoder_specific_info_len; + memcpy( &p_wf[1], + DESCR.p_decoder_specific_info, + DESCR.i_decoder_specific_info_len ); + break; + default: + break; } } else { - msg_Warn( p_input, "mpeg4 stream without (valid) sl_descriptor" ); - p_es_demux->b_mpeg4 = 0; + msg_Warn( p_input, + "mpeg4 stream without (valid) sl_descriptor" ); + demux_data.b_mpeg4 = 0; } } @@ -1541,24 +1553,19 @@ static void TS_DVBPSI_HandlePMT( input_thread_t * p_input, { /* crapy ms codec stream, search private descriptor */ dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor; - es_ts_data_t *p_es_demux = - (es_ts_data_t*)p_new_es->p_demux_data; - while( p_dr && ( p_dr->i_tag != 0xa0 ) ) - p_dr = p_dr->p_next; + while( p_dr && ( p_dr->i_tag != 0xa0 ) ) p_dr = p_dr->p_next; + if( p_dr && p_dr->i_length >= 8 ) { - int i_size; int i_bih_size; - BITMAPINFOHEADER *p_bih; - - p_new_es->i_fourcc = ( p_dr->p_data[0] << 24 )| ( p_dr->p_data[1] << 16 )| - ( p_dr->p_data[2] << 8 )| ( p_dr->p_data[3] ); + i_fourcc = VLC_FOURCC( p_dr->p_data[0], p_dr->p_data[1], + p_dr->p_data[2], p_dr->p_data[3] ); - i_bih_size = ( ( p_dr->p_data[8] << 8)|( p_dr->p_data[9] ) ); + i_bih_size = (p_dr->p_data[8] << 8) | p_dr->p_data[9]; i_size = sizeof( BITMAPINFOHEADER ) + i_bih_size; - p_new_es->p_bitmapinfoheader = (void*)p_bih = malloc( i_size ); + p_bih = malloc( i_size ); p_bih->biSize = i_size; p_bih->biWidth = ( p_dr->p_data[4] << 8 )|p_dr->p_data[5]; p_bih->biHeight = ( p_dr->p_data[6] << 8 )|p_dr->p_data[7]; @@ -1570,24 +1577,48 @@ static void TS_DVBPSI_HandlePMT( input_thread_t * p_input, p_bih->biYPelsPerMeter = 0; p_bih->biClrUsed = 0; p_bih->biClrImportant = 0; - memcpy( &p_bih[1], - &p_dr->p_data[10], - i_bih_size ); + memcpy( &p_bih[1], &p_dr->p_data[10], i_bih_size ); } else { - msg_Warn( p_input, "private ms-codec stream without bih private sl_descriptor" ); - p_new_es->i_fourcc = 0; - p_new_es->i_cat = UNKNOWN_ES; + msg_Warn( p_input, "private ms-codec stream without bih " + "private sl_descriptor" ); + i_fourcc = 0; + i_cat = UNKNOWN_ES; } } + else if( p_es->i_type == PES_PRIVATE_ES ) + { + dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor; + /* We have to find a descriptor giving the right codec */ - if( ( p_new_es->i_cat == AUDIO_ES ) - || (p_new_es->i_cat == SPU_ES ) ) + for(p_dr = p_es->p_first_descriptor; p_dr; p_dr = p_dr->p_next) + { + if( p_dr->i_tag == 0x6a ) + { + /* A52 */ + i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' ); + i_cat = AUDIO_ES; + } + else if( p_dr->i_tag == 0x59 ) + { + /* DVB subtitle */ + i_fourcc = VLC_FOURCC( 'd', 'v', 'b', 's' ); + i_cat = SPU_ES; + } + } + if( i_fourcc == VLC_FOURCC(0,0,0,0) ) + { + msg_Warn( p_input, + "Unknown codec/type for Private PES stream" ); + } + } + + if( i_cat == AUDIO_ES || i_cat == SPU_ES ) { dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor; - while( p_dr && ( p_dr->i_tag != 0x0a ) ) - p_dr = p_dr->p_next; + while( p_dr && ( p_dr->i_tag != 0x0a ) ) p_dr = p_dr->p_next; + if( p_dr ) { dvbpsi_iso639_dr_t *p_decoded = @@ -1596,19 +1627,33 @@ static void TS_DVBPSI_HandlePMT( input_thread_t * p_input, { const iso639_lang_t * p_iso; p_iso = GetLang_2T((char*)p_decoded->i_iso_639_code); - if(p_iso) + + if( p_iso && strcmp(p_iso->psz_native_name,"Unknown")) { - if(p_iso->psz_native_name[0]) - strcpy( p_new_es->psz_desc, - p_iso->psz_native_name ); + if( p_iso->psz_native_name[0] ) + strncpy( psz_desc, + p_iso->psz_native_name, 20 ); else - strcpy( p_new_es->psz_desc, - p_iso->psz_eng_name ); + strncpy( psz_desc, + p_iso->psz_eng_name, 20 ); } else { - strncpy( p_new_es->psz_desc, - p_decoded->i_iso_639_code, 3 ); + p_iso = GetLang_2B( + (char*)p_decoded->i_iso_639_code); + if ( p_iso ) + { + if( p_iso->psz_native_name[0] ) + strncpy( psz_desc, + p_iso->psz_native_name, 20 ); + else + strncpy( psz_desc, + p_iso->psz_eng_name, 20 ); + } + else + { + strncpy( psz_desc, p_decoded->i_iso_639_code, 3 ); + } } } } @@ -1616,23 +1661,41 @@ static void TS_DVBPSI_HandlePMT( input_thread_t * p_input, { case MPEG1_AUDIO_ES: case MPEG2_AUDIO_ES: - strcat( p_new_es->psz_desc, " (mpeg)" ); + strcat( psz_desc, " (mpeg)" ); break; case LPCM_AUDIO_ES: case LPCMB_AUDIO_ES: - strcat( p_new_es->psz_desc, " (lpcm)" ); + strcat( psz_desc, " (lpcm)" ); break; case A52_AUDIO_ES: - case A52DVB_AUDIO_ES: case A52B_AUDIO_ES: - strcat( p_new_es->psz_desc, " (A52)" ); + strcat( psz_desc, " (A52)" ); break; case MPEG4_AUDIO_ES: - strcat( p_new_es->psz_desc, " (aac)" ); + strcat( psz_desc, " (aac)" ); break; } } + /* Add this ES */ + p_new_es = input_AddES( p_input, p_pgrm, (uint16_t)p_es->i_pid, + i_cat, psz_desc, sizeof( es_ts_data_t ) ); + if( p_new_es == NULL ) + { + msg_Err( p_input, "could not add ES %d", p_es->i_pid ); + p_input->b_error = 1; + return; + } + p_new_es->i_fourcc = i_fourcc; + p_new_es->i_stream_id = i_stream_id; + p_new_es->p_bitmapinfoheader = (void*)p_bih; + p_new_es->p_waveformatex = (void*)p_wf; + memcpy( p_new_es->p_demux_data, &demux_data, + sizeof(es_ts_data_t) ); + + ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter = + 0xFF; + p_es = p_es->p_next; } @@ -1640,7 +1703,7 @@ static void TS_DVBPSI_HandlePMT( input_thread_t * p_input, if( !p_input->stream.p_selected_program ) { pgrm_descriptor_t * p_pgrm_to_select; - u16 i_id = (u16)config_GetInt( p_input, "program" ); + uint16_t i_id = (uint16_t)config_GetInt( p_input, "program" ); if( i_id != 0 ) /* if user specified a program */ { @@ -1650,7 +1713,7 @@ static void TS_DVBPSI_HandlePMT( input_thread_t * p_input, p_input->pf_set_program( p_input, p_pgrm_to_select ); } else - p_input->pf_set_program( p_input, p_pgrm ); + p_input->pf_set_program( p_input, p_pgrm ); } /* if the pmt belongs to the currently selected program, we * reselect it to update its ES */