/*****************************************************************************
* mpeg_system.c: TS, PS and PES management
*****************************************************************************
- * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: mpeg_system.c,v 1.58 2001/09/24 11:17:49 massiot Exp $
+ * Copyright (C) 1998-2001 VideoLAN
+ * $Id: mpeg_system.c,v 1.77 2001/12/30 07:09:56 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
/*****************************************************************************
* Preamble
*****************************************************************************/
-#include "defs.h"
-
#include <stdlib.h>
#include <string.h> /* memcpy(), memset() */
#include <sys/types.h> /* off_t */
-#include "config.h"
-#include "common.h"
-#include "threads.h"
-#include "mtime.h"
-
-#include "intf_msg.h"
+#include <videolan/vlc.h>
#include "stream_control.h"
#include "input_ext-intf.h"
#include "input_ext-dec.h"
#include "input_ext-plugins.h"
-#include "main.h" /* AC3/MPEG channel, SPU channel */
-
/*****************************************************************************
* Local prototypes
*****************************************************************************/
if( MoveChunk( p_header, &p_data, &p_byte, PES_HEADER_SIZE )
!= PES_HEADER_SIZE )
{
- intf_WarnMsg( 1, "PES packet too short to have a header" );
+ intf_WarnMsg( 1, "input: PES packet too short to have a header" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
if( (p_header[0] || p_header[1] || (p_header[2] != 1)) )
{
/* packet_start_code_prefix != 0x000001 */
- intf_ErrMsg( "PES packet doesn't start with 0x000001 : data loss" );
+ intf_ErrMsg( "input error: data loss, "
+ "PES packet doesn't start with 0x000001" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
}
{
/* PES_packet_length is set and != total received payload */
/* Warn the decoder that the data may be corrupt. */
- intf_WarnMsg( 1, "PES sizes do not match : packet corrupted" );
+ intf_WarnMsg( 1, "input: packet corrupted, "
+ "PES sizes do not match" );
}
switch( p_es->i_stream_id )
}
if( i_pes_header_size == 23 )
{
- intf_ErrMsg( "Too much MPEG-1 stuffing" );
+ intf_ErrMsg( "input error: too much MPEG-1 stuffing" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
i_pes_header_size += 2;
if( MoveChunk( NULL, &p_data, &p_byte, 2 ) != 2 )
{
- intf_WarnMsg( 1,
- "PES packet too short to have a MPEG-1 header" );
+ intf_WarnMsg( 1, "input: PES packet too short "
+ "to have a MPEG-1 header" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
i_pes_header_size += 4;
if( MoveChunk( p_ts, &p_data, &p_byte, 5 ) != 5 )
{
- intf_WarnMsg( 1,
- "PES packet too short to have a MPEG-1 header" );
+ intf_WarnMsg( 1, "input: PES packet too short "
+ "to have a MPEG-1 header" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
i_pes_header_size += 5;
if( MoveChunk( p_ts, &p_data, &p_byte, 5 ) != 5 )
{
- intf_WarnMsg( 1,
- "PES packet too short to have a MPEG-1 header" );
+ intf_WarnMsg( 1, "input: PES packet too short "
+ "to have a MPEG-1 header" );
p_input->pf_delete_pes( p_input->p_method_data,
p_pes );
p_pes = NULL;
/* Go to the next data packet. */
if( (p_data = p_data->p_next) == NULL )
{
- intf_ErrMsg( "PES header bigger than payload" );
+ intf_ErrMsg( "input error: PES header bigger than payload" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
/* This last packet is partly header, partly payload. */
if( i_payload_size < i_pes_header_size )
{
- intf_ErrMsg( "PES header bigger than payload" );
+ intf_ErrMsg( "input error: PES header bigger than payload" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
else
{
- intf_ErrMsg("No fifo to receive PES %p (who wrote this damn code ?)",
- p_pes);
+ intf_ErrMsg( "input error: no fifo to receive PES %p "
+ "(who wrote this damn code ?)", p_pes );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
}
p_pes = NULL;
* started. */
if( (p_pes = p_input->pf_new_pes( p_input->p_method_data ) ) == NULL )
{
- intf_ErrMsg("Out of memory");
+ intf_ErrMsg( "input error: out of memory" );
p_input->b_error = 1;
return;
}
else
{
/* Update the relations between the data packets */
- p_es->p_last->p_next = p_data;
+ p_pes->p_last->p_next = p_data;
}
- p_es->p_last = p_data;
+ p_pes->p_last = p_data;
+ p_pes->i_nb_data++;
/* Size of the payload carried in the data packet */
p_pes->i_pes_size += (p_data->p_payload_end
{
u16 i_id;
- i_id = p_data->p_payload_start[3]; /* stream_id */
+ i_id = p_data->p_demux_start[3]; /* stream_id */
if( i_id == 0xBD )
{
/* FIXME : this is not valid if the header is split in multiple
* packets */
/* stream_private_id */
- i_id |= p_data->p_payload_start[ 9 + p_data->p_payload_start[8] ] << 8;
+ i_id |= p_data->p_demux_start[ 9 + p_data->p_demux_start[8] ] << 8;
}
return( i_id );
}
int i;
int i_new_es_number = 0;
- if( p_data->p_payload_start + 10 > p_data->p_payload_end )
+ if( p_data->p_demux_start + 10 > p_data->p_payload_end )
{
- intf_ErrMsg( "PSM too short : packet corrupt" );
+ intf_ErrMsg( "input error: PSM too short : packet corrupt" );
return;
}
if( p_demux->b_has_PSM
- && p_demux->i_PSM_version == (p_data->p_payload_start[6] & 0x1F) )
+ && p_demux->i_PSM_version == (p_data->p_demux_start[6] & 0x1F) )
{
/* Already got that one. */
return;
}
- intf_DbgMsg( "Building PSM" );
+ intf_DbgMsg( "input: building PSM" );
p_demux->b_has_PSM = 1;
- p_demux->i_PSM_version = p_data->p_payload_start[6] & 0x1F;
+ p_demux->i_PSM_version = p_data->p_demux_start[6] & 0x1F;
/* Go to elementary_stream_map_length, jumping over
* program_stream_info. */
- p_byte = p_data->p_payload_start + 10
- + U16_AT(&p_data->p_payload_start[8]);
+ p_byte = p_data->p_demux_start + 10
+ + U16_AT(&p_data->p_demux_start[8]);
if( p_byte > p_data->p_payload_end )
{
- intf_ErrMsg( "PSM too short : packet corrupt" );
+ intf_ErrMsg( "input error: PSM too short, packet corrupt" );
return;
}
/* This is the full size of the elementary_stream_map.
p_byte += 2;
if( p_end > p_data->p_payload_end )
{
- intf_ErrMsg( "PSM too short : packet corrupt" );
+ intf_ErrMsg( "input error: PSM too short, packet corrupt" );
return;
}
}
/* Un-select the streams that are no longer parts of the program. */
- for( i = i_new_es_number;
- i < p_input->stream.pp_programs[0]->i_es_number;
- i++ )
+ while( i_new_es_number < p_input->stream.pp_programs[0]->i_es_number )
{
/* We remove pp_es[i_new_es_member] and not pp_es[i] because the
* list will be emptied starting from the end */
p_input->stream.pp_programs[0]->pp_es[i_new_es_number] );
}
-#ifdef STATS
- intf_Msg( "input info: The stream map after the PSM is now :" );
- input_DumpStream( p_input );
-#endif
+ if( p_main->b_stats )
+ {
+ intf_StatMsg( "input info: The stream map after the PSM is now :" );
+ input_DumpStream( p_input );
+ }
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
u32 i_code;
es_descriptor_t * p_es = NULL;
- i_code = p_data->p_payload_start[3];
+ i_code = p_data->p_demux_start[3];
if( i_code > 0xBC ) /* ES start code */
{
i_id, 0 );
if( p_es != NULL )
{
- p_es->i_stream_id = p_data->p_payload_start[3];
+ p_es->i_stream_id = p_data->p_demux_start[3];
/* Set stream type and auto-spawn. */
if( (i_id & 0xF0) == 0xE0 )
p_es->i_type = UNKNOWN_ES;
}
}
+
+ /* Tell the interface the stream has changed */
+ p_input->stream.b_changed = 1;
}
} /* stream.b_is_ok */
vlc_mutex_unlock( &p_input->stream.stream_lock );
boolean_t b_trash = 0;
es_descriptor_t * p_es = NULL;
- i_code = U32_AT( p_data->p_payload_start );
+ i_code = ((u32)p_data->p_demux_start[0] << 24)
+ | ((u32)p_data->p_demux_start[1] << 16)
+ | ((u32)p_data->p_demux_start[2] << 8)
+ | p_data->p_demux_start[3];
if( i_code <= 0x1BC )
{
switch( i_code )
mtime_t scr_time;
u32 i_mux_rate;
- if( (p_data->p_payload_start[4] & 0xC0) == 0x40 )
+ if( (p_data->p_demux_start[4] & 0xC0) == 0x40 )
{
/* MPEG-2 */
byte_t p_header[14];
byte_t * p_byte;
- p_byte = p_data->p_payload_start;
+ p_byte = p_data->p_demux_start;
if( MoveChunk( p_header, &p_data, &p_byte, 14 ) != 14 )
{
- intf_WarnMsg( 1, "Packet too short to have a header" );
+ intf_WarnMsg( 1, "input: packet too short "
+ "to have a header" );
b_trash = 1;
break;
}
/* MPEG-1 SCR is like PTS. */
byte_t p_header[12];
byte_t * p_byte;
- p_byte = p_data->p_payload_start;
+ p_byte = p_data->p_demux_start;
if( MoveChunk( p_header, &p_data, &p_byte, 12 ) != 12 )
{
- intf_WarnMsg( 1, "Packet too short to have a header" );
+ intf_WarnMsg( 1, "input: packet too short "
+ "to have a header" );
b_trash = 1;
break;
}
if( i_mux_rate != p_input->stream.i_mux_rate
&& p_input->stream.i_mux_rate )
{
- intf_WarnMsg(2,
- "Mux_rate changed - expect cosmetic errors");
+ intf_WarnMsg( 2, "input: mux_rate changed, "
+ "expect cosmetic errors" );
}
p_input->stream.i_mux_rate = i_mux_rate;
default:
/* This should not happen */
b_trash = 1;
- intf_WarnMsg( 3, "Unwanted packet received with start code 0x%.8x",
- i_code );
+ intf_WarnMsg( 3, "input: unwanted packet received "
+ "with start code 0x%.8x", i_code );
}
}
else
&& (!p_es->b_audio || !p_input->stream.control.b_mute) )
{
vlc_mutex_unlock( &p_input->stream.control.control_lock );
-#ifdef STATS
p_es->c_packets++;
-#endif
input_GatherPES( p_input, p_data, p_es, 1, 0 );
}
else
if( b_trash )
{
p_input->pf_delete_packet( p_input->p_method_data, p_data );
-#ifdef STATS
- p_input->c_packets_trashed++;
-#endif
+ p_input->stream.c_packets_trashed++;
}
}
es_ts_data_t * p_es_demux = NULL;
pgrm_ts_data_t * p_pgrm_demux = NULL;
-#define p (p_data->p_buffer)
+#define p (p_data->p_demux_start)
/* Extract flags values from TS common header. */
i_pid = ((p[1] & 0x1F) << 8) | p[2];
b_unit_start = (p[1] & 0x40);
((p_es->p_decoder_fifo != NULL) || b_psi
|| (p_pgrm_demux->i_pcr_pid == i_pid) ) )
{
-#ifdef STATS
p_es->c_packets++;
-#endif
/* Extract adaptation field information if any */
if( b_payload ? (p[4] > 182) : (p[4] != 183) )
{
intf_WarnMsg( 2,
- "Invalid TS adaptation field (%p)",
+ "input: invalid TS adaptation field (%p)",
p_data );
p_data->b_discard_payload = 1;
-#ifdef STATS
p_es->c_invalid_packets++;
-#endif
}
/* Now we are sure that the byte containing flags is present:
if( p[5] & 0x80 )
{
intf_WarnMsg( 2,
- "discontinuity_indicator"
+ "input: discontinuity_indicator"
" encountered by TS demux (position read: %d,"
" saved: %d)",
p[5] & 0x80, p_es_demux->i_continuity_counter );
* draft. As there is nothing interesting in this packet
* (except PCR that have already been handled), we can trash
* the packet. */
- intf_WarnMsg( 3,
- "Packet without payload received by TS demux" );
+ intf_WarnMsg( 3, "input: packet without payload received "
+ "by TS demux" );
b_trash = 1;
}
else if( i_dummy <= 0 )
{
/* Duplicate packet: mark it as being to be trashed. */
- intf_WarnMsg( 3, "Duplicate packet received by TS demux" );
+ intf_WarnMsg( 3, "input: duplicate packet received "
+ "by TS demux" );
b_trash = 1;
}
else if( p_es_demux->i_continuity_counter == 0xFF )
* this ES since the continuity counter ranges between 0 and
* 0x0F excepts when it has been initialized by the input:
* init the counter to the correct value. */
- intf_WarnMsg( 3, "First packet for PID %d received by TS demux",
- p_es->i_id );
+ intf_WarnMsg( 3, "input: first packet for PID %d received "
+ "by TS demux", p_es->i_id );
p_es_demux->i_continuity_counter = (p[3] & 0x0f);
}
else
* continuity_counter wrapped and we received a dup packet:
* as we don't know, do as if we missed a packet to be sure
* to recover from this situation */
- intf_WarnMsg( 2,
- "Packet lost by TS demux: current %d, packet %d",
- p_es_demux->i_continuity_counter & 0x0f,
- p[3] & 0x0f );
+ intf_WarnMsg( 2, "input: packet lost by TS demux: "
+ "current %d, packet %d",
+ p_es_demux->i_continuity_counter & 0x0f,
+ p[3] & 0x0f );
b_lost = 1;
p_es_demux->i_continuity_counter = p[3] & 0x0f;
} /* not continuous */
if( b_trash )
{
p_input->pf_delete_packet( p_input->p_method_data, p_data );
-#ifdef STATS
- p_input->c_packets_trashed++;
-#endif
+ p_input->stream.c_packets_trashed++;
}
else
{
* (see ISO/IEC 13818 (2.4.4.2) which should be set to 0x00 */
if( (u8)p[0] != 0x00 )
{
- intf_WarnMsg( 2,
- "Non zero pointer field found. Trying to continue" );
+ intf_WarnMsg( 2, "input: non zero pointer field found, "
+ "trying to continue" );
p+=(u8)p[0];
}
else
if( ((u8)(p[1]) & 0xc0) != 0x80 )
{
- intf_WarnMsg( 2, "Invalid PSI packet" );
+ intf_WarnMsg( 2, "input: invalid PSI packet" );
p_psi->b_trash = 1;
}
else
if( p_psi->i_version_number != (( p[5] >> 1 ) & 0x1f) )
{
- intf_WarnMsg( 2,
- "PSI version differs inside same PAT" );
+ intf_WarnMsg( 2, "input: PSI version differs "
+ "inside same PAT" );
p_psi->b_trash = 1;
}
if( p_psi->i_section_number + 1 != (u8)p[6] )
{
- intf_WarnMsg( 2,
- "PSI Section discontinuity. Packet lost ?");
+ intf_WarnMsg( 2, "input: PSI Section discontinuity, "
+ "packet lost ?" );
p_psi->b_trash = 1;
}
else
}
else
{
- intf_WarnMsg( 2, "Received unexpected new PSI section" );
+ intf_WarnMsg( 2, "input: got unexpected new PSI section" );
p_psi->b_trash = 1;
}
}
else
{
memcpy( p_psi->buffer, p, p_data->p_payload_end - p );
- p_psi->i_read_in_section+= p_data->p_payload_end - p;
+ p_psi->i_read_in_section += p_data->p_payload_end - p;
p_psi->p_current += p_data->p_payload_end - p;
}
*****************************************************************************/
static void input_DecodePAT( input_thread_t * p_input, es_descriptor_t * p_es )
{
-
stream_ts_data_t * p_stream_data;
es_ts_data_t * p_demux_data;
+ pgrm_descriptor_t * p_pgrm;
+ es_descriptor_t * p_current_es;
+ byte_t * p_current_data;
+
+ int i_section_length, i_program_id, i_pmt_pid;
+ int i_loop, i_current_section;
+
+ boolean_t b_changed = 0;
+
p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
#define p_psi (p_demux_data->p_psi_section)
+ /* Not so fast, Mike ! If the PAT version has changed, we first check
+ * that its content has really changed before doing anything */
if( p_stream_data->i_pat_version != p_psi->i_version_number )
{
- /* PAT has changed. We are going to delete all programms and
+ int i_programs = p_input->stream.i_pgrm_number;
+
+ p_current_data = p_psi->buffer;
+
+ do
+ {
+ i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
+ p_current_data[2];
+ i_current_section = (u8)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 )
+ | *(p_current_data + i_loop * 4 + 9);
+ i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
+ << 8 )
+ | *(p_current_data + i_loop * 4 + 11);
+
+ if( i_program_id )
+ {
+ if( (p_pgrm = input_FindProgram( p_input, i_program_id ))
+ && (p_current_es = input_FindES( p_input, i_pmt_pid ))
+ && p_current_es->p_pgrm == p_pgrm
+ && p_current_es->i_id == i_pmt_pid
+ && ((es_ts_data_t *)p_current_es->p_demux_data)->b_psi
+ && ((es_ts_data_t *)p_current_es->p_demux_data)
+ ->i_psi_type == PSI_IS_PMT )
+ {
+ i_programs--;
+ }
+ else
+ {
+ b_changed = 1;
+ }
+ }
+ }
+
+ p_current_data += 3 + i_section_length;
+
+ } while( ( i_current_section < p_psi->i_last_section_number )
+ && !b_changed );
+
+ /* If we didn't find the expected amount of programs, the PAT has
+ * changed. Otherwise, it only changed if b_changed is already != 0 */
+ b_changed = b_changed || i_programs;
+ }
+
+ if( b_changed )
+ {
+ /* PAT has changed. We are going to delete all programs and
* create new ones. We chose not to only change what was needed
* as a PAT change may mean the stream is radically changing and
- * this is a secure method to avoid krashes */
- pgrm_descriptor_t * p_pgrm;
- es_descriptor_t * p_current_es;
+ * this is a secure method to avoid crashes */
es_ts_data_t * p_es_demux;
pgrm_ts_data_t * p_pgrm_demux;
- byte_t * p_current_data;
-
- int i_section_length,i_program_id,i_pmt_pid;
- int i_loop, i_current_section;
p_current_data = p_psi->buffer;
-
- for( i_loop = 0; i_loop < p_input->stream.i_pgrm_number; i_loop++ )
+ /* Delete all programs */
+ while( p_input->stream.i_pgrm_number )
{
- input_DelProgram( p_input, p_input->stream.pp_programs[i_loop] );
+ input_DelProgram( p_input, p_input->stream.pp_programs[0] );
}
do
{
- i_section_length = ((p_current_data[1] & 0xF) << 8) |
+ i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
p_current_data[2];
i_current_section = (u8)p_current_data[6];
- for( i_loop = 0; i_loop < (i_section_length-9)/4 ; i_loop++ )
+ for( i_loop = 0; i_loop < (i_section_length - 9) / 4 ; i_loop++ )
{
- i_program_id = ( *(p_current_data + i_loop * 4 + 8) << 8 ) |
- *(p_current_data + i_loop * 4 + 9);
- i_pmt_pid = ( (*( p_current_data + i_loop * 4 + 10) & 0x1F)
- << 8 ) |
- *( p_current_data + i_loop * 4 + 11);
+ i_program_id = ( (u32)*(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)
+ << 8 )
+ | *(p_current_data + i_loop * 4 + 11);
/* If program = 0, we're having info about NIT not PMT */
if( i_program_id )
}
}
- p_current_data+=3+i_section_length;
-
+ p_current_data += 3 + i_section_length;
+
} while( i_current_section < p_psi->i_last_section_number );
-
- /* Go to the beginning of the next section*/
+
+ /* Go to the beginning of the next section */
p_stream_data->i_pat_version = p_psi->i_version_number;
}
#undef p_psi
+ /* FIXME This has nothing to do here */
+ p_input->stream.p_selected_program = p_input->stream.pp_programs[0] ;
}
/*****************************************************************************
p_current_section = p_psi->buffer;
p_current_data = p_psi->buffer;
- p_pgrm_data->i_pcr_pid = ( (*(p_current_section + 8) & 0x1F) << 8 ) |
+ p_pgrm_data->i_pcr_pid = ( ((u32)*(p_current_section + 8) & 0x1F) << 8 ) |
*(p_current_section + 9);
i_audio_es = 0;
i_required_spu_es = 0;
}
- /* Delete all ES in this program except the PSI */
- for( i_loop=0; i_loop < p_es->p_pgrm->i_es_number; i_loop++ )
+ /* 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_es->p_pgrm->i_es_number ; i_loop ; )
{
+ i_loop--;
p_es_demux = (es_ts_data_t *)
p_es->p_pgrm->pp_es[i_loop]->p_demux_data;
if ( ! p_es_demux->b_psi )
- input_DelES( p_input, p_es->p_pgrm->pp_es[i_loop] );
+ {
+ input_DelES( p_input, p_es->p_pgrm->pp_es[i_loop] );
+ }
}
/* Then add what we received in this PMT */
do
{
- i_section_length = ( (*(p_current_data + 1) & 0xF) << 8 ) |
+ i_section_length = ( ((u32)*(p_current_data + 1) & 0xF) << 8 ) |
*(p_current_data + 2);
i_current_section = (u8)p_current_data[6];
- i_prog_info_length = ( (*(p_current_data + 10) & 0xF) << 8 ) |
+ i_prog_info_length = ( ((u32)*(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 = ( (*(p_current_data + 1) & 0x1F) << 8 ) |
+ i_pid = ( ((u32)*(p_current_data + 1) & 0x1F) << 8 ) |
*(p_current_data + 2);
- i_es_info_length = ( (*(p_current_data + 3) & 0xF) << 8 ) |
+ i_es_info_length = ( ((u32)*(p_current_data + 3) & 0xF) << 8 ) |
*(p_current_data + 4);
/* Add this ES to the program */
break;
case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES:
- case LPCM_AUDIO_ES :
p_new_es->i_cat = AUDIO_ES;
i_audio_es += 1;
if( i_audio_es == i_required_audio_es )
input_SelectES( p_input, p_new_es );
break;
+ case LPCM_AUDIO_ES :
case AC3_AUDIO_ES :
p_new_es->i_stream_id = 0xBD;
p_new_es->i_cat = AUDIO_ES;
break;
/* Not sure this one is fully specification-compliant */
case DVD_SPU_ES :
+ p_new_es->i_stream_id = 0xBD;
p_new_es->i_cat = SPU_ES;
i_spu_es += 1;
if( i_spu_es == i_required_spu_es )
if( i_required_audio_es > i_audio_es )
{
- intf_WarnMsg( 2, "TS input: Non-existing audio ES required." );
+ intf_WarnMsg( 2, "input: non-existing audio ES required" );
}
if( i_required_spu_es > i_spu_es )
{
- intf_WarnMsg( 2, "TS input: Non-existing subtitles ES required." );
+ intf_WarnMsg( 2, "input: non-existing subtitles ES required" );
}
p_pgrm_data->i_pmt_version = p_psi->i_version_number;
/* inform interface that stream has changed */
p_input->stream.b_changed = 1;
+ /* Remove lock */
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
}
#undef p_psi
-
- /* Remove lock */
- vlc_mutex_unlock( &p_input->stream.stream_lock );
}
+