Commit b994d951 authored by Gildas Bazin's avatar Gildas Bazin

* modules/demux/ps.h: fixed PSM parsing.

* modules/demux/ps.c: improved MPEG PS autodetection a bit.
parent 299501b7
...@@ -40,13 +40,18 @@ ...@@ -40,13 +40,18 @@
* Module descriptor * Module descriptor
*****************************************************************************/ *****************************************************************************/
static int Open ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void Close( vlc_object_t * ); static int OpenAlt( vlc_object_t * );
static void Close ( vlc_object_t * );
vlc_module_begin(); vlc_module_begin();
set_description( _("PS demuxer") ); set_description( _("PS demuxer") );
set_capability( "demux2", 1 ); set_capability( "demux2", 1 );
set_callbacks( Open, Close ); set_callbacks( Open, Close );
add_shortcut( "ps" ); add_shortcut( "ps" );
set_description( _("PS demuxer") );
set_capability( "demux2", 9 );
set_callbacks( OpenAlt, Close );
vlc_module_end(); vlc_module_end();
/***************************************************************************** /*****************************************************************************
...@@ -84,8 +89,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -84,8 +89,8 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if( p_peek[0] != 0 || p_peek[1] != 0 || p_peek[2] != 1 || if( p_peek[0] != 0 || p_peek[1] != 0 ||
p_peek[3] < 0xb9 ) p_peek[2] != 1 || p_peek[3] < 0xb9 )
{ {
msg_Warn( p_demux, "this does not look like an MPEG PS stream, " msg_Warn( p_demux, "this does not look like an MPEG PS stream, "
"continuing anyway" ); "continuing anyway" );
...@@ -108,6 +113,26 @@ static int Open( vlc_object_t *p_this ) ...@@ -108,6 +113,26 @@ static int Open( vlc_object_t *p_this )
return VLC_SUCCESS; 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 * Close
*****************************************************************************/ *****************************************************************************/
...@@ -191,8 +216,8 @@ static int Demux( demux_t *p_demux ) ...@@ -191,8 +216,8 @@ static int Demux( demux_t *p_demux )
break; break;
case 0x1bc: case 0x1bc:
msg_Dbg( p_demux, "received PSM"); /* msg_Dbg( p_demux, "received PSM"); */
ps_psm_fill( &p_sys->psm, p_pkt ); ps_psm_fill( &p_sys->psm, p_pkt, p_sys->tk, p_demux->out );
block_Release( p_pkt ); block_Release( p_pkt );
break; break;
......
...@@ -32,6 +32,7 @@ typedef struct ...@@ -32,6 +32,7 @@ typedef struct
{ {
vlc_bool_t b_seen; vlc_bool_t b_seen;
int i_skip; int i_skip;
int i_id;
es_out_id_t *es; es_out_id_t *es;
es_format_t fmt; es_format_t fmt;
...@@ -45,6 +46,7 @@ static inline void ps_track_init( ps_track_t tk[PS_TK_COUNT] ) ...@@ -45,6 +46,7 @@ static inline void ps_track_init( ps_track_t tk[PS_TK_COUNT] )
{ {
tk[i].b_seen = VLC_FALSE; tk[i].b_seen = VLC_FALSE;
tk[i].i_skip = 0; tk[i].i_skip = 0;
tk[i].i_id = 0;
tk[i].es = NULL; tk[i].es = NULL;
es_format_Init( &tk[i].fmt, UNKNOWN_ES, 0 ); es_format_Init( &tk[i].fmt, UNKNOWN_ES, 0 );
} }
...@@ -54,6 +56,7 @@ static inline void ps_track_init( ps_track_t tk[PS_TK_COUNT] ) ...@@ -54,6 +56,7 @@ static inline void ps_track_init( ps_track_t tk[PS_TK_COUNT] )
static inline int ps_track_fill( ps_track_t *tk, ps_psm_t *p_psm, int i_id ) static inline int ps_track_fill( ps_track_t *tk, ps_psm_t *p_psm, int i_id )
{ {
tk->i_skip = 0; tk->i_skip = 0;
tk->i_id = i_id;
if( ( i_id&0xff00 ) == 0xbd00 ) if( ( i_id&0xff00 ) == 0xbd00 )
{ {
if( ( i_id&0xf8 ) == 0x88 ) if( ( i_id&0xf8 ) == 0x88 )
...@@ -117,7 +120,7 @@ static inline int ps_track_fill( ps_track_t *tk, ps_psm_t *p_psm, int i_id ) ...@@ -117,7 +120,7 @@ static inline int ps_track_fill( ps_track_t *tk, ps_psm_t *p_psm, int i_id )
{ {
es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('m','p','g','a') ); 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 */ /* PES packets usually contain truncated frames */
...@@ -348,8 +351,6 @@ typedef struct p_es_t ...@@ -348,8 +351,6 @@ typedef struct p_es_t
int i_descriptor; int i_descriptor;
uint8_t *p_descriptor; uint8_t *p_descriptor;
struct ps_es_t *p_next;
} ps_es_t; } ps_es_t;
struct ps_psm_t struct ps_psm_t
...@@ -391,11 +392,12 @@ static inline void ps_psm_destroy( ps_psm_t *p_psm ) ...@@ -391,11 +392,12 @@ static inline void ps_psm_destroy( ps_psm_t *p_psm )
p_psm->i_es = 0; 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; int i_buffer = p_pkt->i_buffer;
uint8_t *p_buffer = p_pkt->p_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; if( !p_psm || p_buffer[3] != 0xbc ) return VLC_EGENERIC;
...@@ -436,7 +438,8 @@ static inline int ps_psm_fill( ps_psm_t *p_psm, block_t *p_pkt ) ...@@ -436,7 +438,8 @@ static inline int ps_psm_fill( ps_psm_t *p_psm, block_t *p_pkt )
memcpy( es.p_descriptor, p_buffer + i_es_base + 4, i_info_length); 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; *p_psm->es[p_psm->i_es++] = es;
i_es_base += 4 + i_info_length; i_es_base += 4 + i_info_length;
} }
...@@ -445,5 +448,23 @@ static inline int ps_psm_fill( ps_psm_t *p_psm, block_t *p_pkt ) ...@@ -445,5 +448,23 @@ static inline int ps_psm_fill( ps_psm_t *p_psm, block_t *p_pkt )
p_psm->i_version = i_version; 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; return VLC_SUCCESS;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment