/*****************************************************************************
* Module descriptor
*****************************************************************************/
-static int Open ( vlc_object_t * );
-static void Close( vlc_object_t * );
+static int Open ( vlc_object_t * );
+static int OpenAlt( vlc_object_t * );
+static void Close ( vlc_object_t * );
vlc_module_begin();
set_description( _("PS demuxer") );
set_capability( "demux2", 1 );
set_callbacks( Open, Close );
add_shortcut( "ps" );
+
+ set_description( _("PS demuxer") );
+ set_capability( "demux2", 9 );
+ set_callbacks( OpenAlt, Close );
vlc_module_end();
/*****************************************************************************
return VLC_EGENERIC;
}
- if( p_peek[0] != 0 || p_peek[1] != 0 || p_peek[2] != 1 ||
- p_peek[3] < 0xb9 )
+ if( p_peek[0] != 0 || p_peek[1] != 0 ||
+ p_peek[2] != 1 || p_peek[3] < 0xb9 )
{
msg_Warn( p_demux, "this does not look like an MPEG PS stream, "
"continuing anyway" );
return VLC_SUCCESS;
}
+static int OpenAlt( vlc_object_t *p_this )
+{
+ demux_t *p_demux = (demux_t*)p_this;
+ uint8_t *p_peek;
+
+ if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 )
+ {
+ msg_Err( p_demux, "cannot peek" );
+ return VLC_EGENERIC;
+ }
+
+ if( p_peek[0] != 0 || p_peek[1] != 0 ||
+ p_peek[2] != 1 || p_peek[3] < 0xb9 )
+ {
+ if( !p_demux->b_force ) return VLC_EGENERIC;
+ }
+
+ return Open( p_this );
+}
+
/*****************************************************************************
* Close
*****************************************************************************/
break;
case 0x1bc:
- msg_Dbg( p_demux, "received PSM");
- ps_psm_fill( &p_sys->psm, p_pkt );
+ /* msg_Dbg( p_demux, "received PSM"); */
+ ps_psm_fill( &p_sys->psm, p_pkt, p_sys->tk, p_demux->out );
block_Release( p_pkt );
break;
{
vlc_bool_t b_seen;
int i_skip;
+ int i_id;
es_out_id_t *es;
es_format_t fmt;
{
tk[i].b_seen = VLC_FALSE;
tk[i].i_skip = 0;
+ tk[i].i_id = 0;
tk[i].es = NULL;
es_format_Init( &tk[i].fmt, UNKNOWN_ES, 0 );
}
static inline int ps_track_fill( ps_track_t *tk, ps_psm_t *p_psm, int i_id )
{
tk->i_skip = 0;
+ tk->i_id = i_id;
if( ( i_id&0xff00 ) == 0xbd00 )
{
if( ( i_id&0xf8 ) == 0x88 )
{
es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('m','p','g','a') );
}
- else return VLC_EGENERIC;
+ else if( tk->fmt.i_cat == UNKNOWN_ES ) return VLC_EGENERIC;
}
/* PES packets usually contain truncated frames */
int i_descriptor;
uint8_t *p_descriptor;
- struct ps_es_t *p_next;
-
} ps_es_t;
struct ps_psm_t
p_psm->i_es = 0;
}
-static inline int ps_psm_fill( ps_psm_t *p_psm, block_t *p_pkt )
+static inline int ps_psm_fill( ps_psm_t *p_psm, block_t *p_pkt,
+ ps_track_t tk[PS_TK_COUNT], es_out_t *out )
{
int i_buffer = p_pkt->i_buffer;
uint8_t *p_buffer = p_pkt->p_buffer;
- int i_length, i_version, i_info_length, i_esm_length, i_es_base;
+ int i_length, i_version, i_info_length, i_esm_length, i_es_base, i;
if( !p_psm || p_buffer[3] != 0xbc ) return VLC_EGENERIC;
memcpy( es.p_descriptor, p_buffer + i_es_base + 4, i_info_length);
}
- p_psm->es = realloc( &p_psm->es, sizeof(ps_es_t) * (p_psm->i_es+1) );
+ p_psm->es = realloc( p_psm->es, sizeof(ps_es_t *) * (p_psm->i_es+1) );
+ p_psm->es[p_psm->i_es] = malloc( sizeof(ps_es_t) );
*p_psm->es[p_psm->i_es++] = es;
i_es_base += 4 + i_info_length;
}
p_psm->i_version = i_version;
+ /* Check/Modify our existing tracks */
+ for( i = 0; i < PS_TK_COUNT; i++ )
+ {
+ ps_track_t tk_tmp;
+
+ if( !tk[i].b_seen || !tk[i].es ) continue;
+
+ if( ps_track_fill( &tk_tmp, p_psm, tk[i].i_id ) != VLC_SUCCESS )
+ continue;
+
+ if( tk_tmp.fmt.i_codec == tk[i].fmt.i_codec ) continue;
+
+ es_out_Del( out, tk[i].es );
+ tk[i] = tk_tmp;
+ tk[i].b_seen = VLC_TRUE;
+ tk[i].es = es_out_Add( out, &tk[i].fmt );
+ }
+
return VLC_SUCCESS;
}