* mpeg_ts.c : Transport Stream input module for vlc
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
- * $Id: ts.c,v 1.20 2003/03/18 23:59:07 massiot Exp $
+ * $Id: ts.c,v 1.38 2003/10/27 13:35:15 nitrox Exp $
*
* Authors: Henri Fallon <henri@via.ecp.fr>
* Johan Bilien <jobi@via.ecp.fr>
* Preamble
*****************************************************************************/
#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_STDINT_H
-# include <stdint.h> /* uint8_t */
-#endif
-
#include <vlc/vlc.h>
#include <vlc/input.h>
/*****************************************************************************
* 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.")
/* 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 )
/* We'll have to catch the PAT in order to continue
* Then the input will catch the PMT and then the others ES
* The PAT es is indepedent of any program. */
- p_pat_es = input_AddES( p_input, NULL,
- 0x00, sizeof( es_ts_data_t ) );
+ 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;
{
/* 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
{
/* 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;
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 )
{
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;
"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?" );
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);
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);
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,
- sizeof( es_ts_data_t) );
+ 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;
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);
/* 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 */
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);
- /* Add this ES to the program */
- p_new_es = input_AddES( p_input, p_es->p_pgrm,
- (u16)i_pid, sizeof( es_ts_data_t ) );
- ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter = 0xFF;
-
/* Tell the interface what kind of stream it is and select
* the required ones */
{
+ int i_fourcc, i_cat, i_stream_id;
+
switch( i_stream_type )
{
case MPEG1_VIDEO_ES:
case MPEG2_MOTO_VIDEO_ES:
/* This isn't real, but we don't actually use
* it. */
- p_new_es->i_stream_id = 0xE0;
- p_new_es->i_fourcc = VLC_FOURCC('m','p','g','v');
- p_new_es->i_cat = VIDEO_ES;
+ i_stream_id = 0xE0;
+ i_fourcc = VLC_FOURCC('m','p','g','v');
+ i_cat = VIDEO_ES;
break;
case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES:
/* This isn't real, but we don't actually use
* it. */
- p_new_es->i_stream_id = 0xC0;
- p_new_es->i_fourcc = VLC_FOURCC('m','p','g','a');
- p_new_es->i_cat = AUDIO_ES;
+ i_stream_id = 0xC0;
+ i_fourcc = VLC_FOURCC('m','p','g','a');
+ i_cat = AUDIO_ES;
break;
case A52_AUDIO_ES:
- case A52DVB_AUDIO_ES:
if ( !b_vls_compat )
- p_new_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
+ i_fourcc = VLC_FOURCC('a','5','2',' ');
else
- p_new_es->i_fourcc = VLC_FOURCC('a','5','2','b');
- p_new_es->i_stream_id = 0xBD;
- p_new_es->i_cat = AUDIO_ES;
+ i_fourcc = VLC_FOURCC('a','5','2','b');
+ i_stream_id = 0xBD;
+ i_cat = AUDIO_ES;
break;
case LPCM_AUDIO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('l','p','c','m');
- p_new_es->i_stream_id = 0xBD;
- p_new_es->i_cat = AUDIO_ES;
+ i_fourcc = VLC_FOURCC('l','p','c','m');
+ i_stream_id = 0xBD;
+ i_cat = AUDIO_ES;
break;
case DVD_SPU_ES:
if ( !b_vls_compat )
- p_new_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
+ i_fourcc = VLC_FOURCC('s','p','u',' ');
else
- p_new_es->i_fourcc = VLC_FOURCC('s','p','u','b');
- p_new_es->i_stream_id = 0xBD;
- p_new_es->i_cat = SPU_ES;
+ i_fourcc = VLC_FOURCC('s','p','u','b');
+ i_stream_id = 0xBD;
+ i_cat = SPU_ES;
break;
case SDDS_AUDIO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('s','d','d','s');
- p_new_es->i_stream_id = 0xBD;
- p_new_es->i_cat = AUDIO_ES;
+ i_fourcc = VLC_FOURCC('s','d','d','s');
+ i_stream_id = 0xBD;
+ i_cat = AUDIO_ES;
break;
case DTS_AUDIO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('d','t','s',' ');
- p_new_es->i_stream_id = 0xBD;
- p_new_es->i_cat = AUDIO_ES;
+ i_fourcc = VLC_FOURCC('d','t','s',' ');
+ i_stream_id = 0xBD;
+ i_cat = AUDIO_ES;
break;
/* 'b' stands for 'buggy' */
case A52B_AUDIO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('a','5','2','b');
- p_new_es->i_stream_id = 0xBD;
- p_new_es->i_cat = AUDIO_ES;
+ i_fourcc = VLC_FOURCC('a','5','2','b');
+ i_stream_id = 0xBD;
+ i_cat = AUDIO_ES;
break;
case LPCMB_AUDIO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('l','p','c','b');
- p_new_es->i_stream_id = 0xBD;
- p_new_es->i_cat = AUDIO_ES;
+ i_fourcc = VLC_FOURCC('l','p','c','b');
+ i_stream_id = 0xBD;
+ i_cat = AUDIO_ES;
break;
case DVDB_SPU_ES:
- p_new_es->i_fourcc = VLC_FOURCC('s','p','u','b');
- p_new_es->i_stream_id = 0xBD;
- p_new_es->i_cat = SPU_ES;
+ i_fourcc = VLC_FOURCC('s','p','u','b');
+ i_stream_id = 0xBD;
+ i_cat = SPU_ES;
break;
default :
- p_new_es->i_fourcc = 0;
- p_new_es->i_cat = UNKNOWN_ES;
+ i_stream_id = 0;
+ i_fourcc = 0;
+ i_cat = UNKNOWN_ES;
break;
}
+
+ /* Add this ES to the program */
+ 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;
+
+ p_new_es->i_stream_id = i_stream_id;
+ p_new_es->i_fourcc = i_fourcc;
+
}
p_current_data += 5 + i_es_info_length;
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 */
{
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 )
{
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] );
}
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 )
{
/* Add the PMT ES to this program */
p_current_es = input_AddES( p_input, p_new_pgrm,
- (u16) p_pgrm->i_pid,
- sizeof( es_ts_data_t) );
+ (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 */
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;
p_es = p_new_pmt->p_first_es;
while( p_es )
{
- /* Add this ES */
- p_new_es = input_AddES( p_input, p_pgrm,
- (u16)p_es->i_pid, 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;
- }
- ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter = 0xFF;
+ 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 )
{
case MPEG1_VIDEO_ES:
case MPEG2_VIDEO_ES:
case MPEG2_MOTO_VIDEO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('m','p','g','v');
- p_new_es->i_cat = VIDEO_ES;
+ i_fourcc = VLC_FOURCC('m','p','g','v');
+ i_cat = VIDEO_ES;
break;
case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('m','p','g','a');
- p_new_es->i_cat = AUDIO_ES;
+ i_fourcc = VLC_FOURCC('m','p','g','a');
+ i_cat = AUDIO_ES;
break;
case A52_AUDIO_ES:
- case A52DVB_AUDIO_ES:
if ( !b_vls_compat )
- p_new_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
+ i_fourcc = VLC_FOURCC('a','5','2',' ');
else
- p_new_es->i_fourcc = VLC_FOURCC('a','5','2','b');
- p_new_es->i_cat = AUDIO_ES;
- p_new_es->i_stream_id = 0xBD;
+ i_fourcc = VLC_FOURCC('a','5','2','b');
+ i_cat = AUDIO_ES;
+ i_stream_id = 0xBD;
break;
case DVD_SPU_ES:
if ( !b_vls_compat )
- p_new_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
+ i_fourcc = VLC_FOURCC('s','p','u',' ');
else
- p_new_es->i_fourcc = VLC_FOURCC('s','p','u','b');
- p_new_es->i_cat = SPU_ES;
- p_new_es->i_stream_id = 0xBD;
+ i_fourcc = VLC_FOURCC('s','p','u','b');
+ i_cat = SPU_ES;
+ i_stream_id = 0xBD;
break;
case LPCM_AUDIO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('l','p','c','m');
- p_new_es->i_cat = AUDIO_ES;
- p_new_es->i_stream_id = 0xBD;
+ i_fourcc = VLC_FOURCC('l','p','c','m');
+ i_cat = AUDIO_ES;
+ i_stream_id = 0xBD;
break;
case SDDS_AUDIO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('s','d','d','s');
- p_new_es->i_stream_id = 0xBD;
- p_new_es->i_cat = AUDIO_ES;
+ i_fourcc = VLC_FOURCC('s','d','d','s');
+ i_stream_id = 0xBD;
+ i_cat = AUDIO_ES;
break;
case DTS_AUDIO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('d','t','s',' ');
- p_new_es->i_stream_id = 0xBD;
- p_new_es->i_cat = AUDIO_ES;
+ i_fourcc = VLC_FOURCC('d','t','s',' ');
+ i_stream_id = 0xBD;
+ i_cat = AUDIO_ES;
break;
case A52B_AUDIO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('a','5','2','b');
- p_new_es->i_cat = AUDIO_ES;
- p_new_es->i_stream_id = 0xBD;
+ i_fourcc = VLC_FOURCC('a','5','2','b');
+ i_cat = AUDIO_ES;
+ i_stream_id = 0xBD;
break;
case DVDB_SPU_ES:
- p_new_es->i_fourcc = VLC_FOURCC('s','p','u','b');
- p_new_es->i_cat = SPU_ES;
- p_new_es->i_stream_id = 0xBD;
+ i_fourcc = VLC_FOURCC('s','p','u','b');
+ i_cat = SPU_ES;
+ i_stream_id = 0xBD;
break;
case LPCMB_AUDIO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('l','p','c','b');
- p_new_es->i_cat = AUDIO_ES;
- p_new_es->i_stream_id = 0xBD;
+ i_fourcc = VLC_FOURCC('l','p','c','b');
+ i_cat = AUDIO_ES;
+ i_stream_id = 0xBD;
break;
case MPEG4_VIDEO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('m','p','4','v');
- p_new_es->i_cat = VIDEO_ES;
- p_new_es->i_stream_id = 0xfa;
+ i_fourcc = VLC_FOURCC('m','p','4','v');
+ i_cat = VIDEO_ES;
+ i_stream_id = 0xfa;
break;
case MPEG4_AUDIO_ES:
- p_new_es->i_fourcc = VLC_FOURCC('m','p','4','a');
- p_new_es->i_cat = AUDIO_ES;
- p_new_es->i_stream_id = 0xfa;
+ i_fourcc = VLC_FOURCC('m','p','4','a');
+ i_cat = AUDIO_ES;
+ i_stream_id = 0xfa;
break;
case MSCODEC_VIDEO_ES:
- p_new_es->i_fourcc = VLC_FOURCC(0,0,0,0); // fixed later
- p_new_es->i_cat = VIDEO_ES;
- p_new_es->i_stream_id = 0xa0;
+ 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:
- p_new_es->i_fourcc = 0;
- p_new_es->i_cat = UNKNOWN_ES;
+ i_fourcc = 0;
+ i_cat = UNKNOWN_ES;
+ i_stream_id = 0;
}
- 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;
}
}
{
/* 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;
+ i_fourcc = VLC_FOURCC( p_dr->p_data[0], p_dr->p_data[1],
+ p_dr->p_data[2], p_dr->p_data[3] );
- 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_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];
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 =
{
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 );
+ }
}
}
}
{
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;
}
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 */
{
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 */