Commit 73c979f2 authored by Francois Cartegnie's avatar Francois Cartegnie

demux: ogg: delay ES creation for preparsing.

Prevents creating ES & decoders just for playlist preparsing.
parent b6dd43d5
...@@ -116,6 +116,7 @@ static void Ogg_UpdatePCR ( logical_stream_t *, ogg_packet * ); ...@@ -116,6 +116,7 @@ static void Ogg_UpdatePCR ( logical_stream_t *, ogg_packet * );
static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * ); static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
static int Ogg_OpusPacketDuration( logical_stream_t *, ogg_packet * ); static int Ogg_OpusPacketDuration( logical_stream_t *, ogg_packet * );
static void Ogg_CreateES( demux_t *p_demux );
static int Ogg_BeginningOfStream( demux_t *p_demux ); static int Ogg_BeginningOfStream( demux_t *p_demux );
static int Ogg_FindLogicalStreams( demux_t *p_demux ); static int Ogg_FindLogicalStreams( demux_t *p_demux );
static void Ogg_EndOfStream( demux_t *p_demux ); static void Ogg_EndOfStream( demux_t *p_demux );
...@@ -270,9 +271,6 @@ static int Demux( demux_t * p_demux ) ...@@ -270,9 +271,6 @@ static int Demux( demux_t * p_demux )
if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS ) if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS )
return 0; return 0;
if ( ! p_sys->skeleton.major )
p_sys->b_preparsing_done = true;
/* Find the real duration */ /* Find the real duration */
stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek ); stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
if ( b_canseek ) if ( b_canseek )
...@@ -282,6 +280,18 @@ static int Demux( demux_t * p_demux ) ...@@ -282,6 +280,18 @@ static int Demux( demux_t * p_demux )
es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 ); es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 );
} }
if ( p_sys->b_preparsing_done )
{
for ( int i=0; i < p_sys->i_streams; i++ )
{
if ( !p_sys->pp_stream[i]->p_es )
{
Ogg_CreateES( p_demux );
break;
}
}
}
/* /*
* The first data page of a physical stream is stored in the relevant logical stream * The first data page of a physical stream is stored in the relevant logical stream
* in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the * in Ogg_FindLogicalStreams. Therefore, we must not read a page and only update the
...@@ -317,7 +327,7 @@ static int Demux( demux_t * p_demux ) ...@@ -317,7 +327,7 @@ static int Demux( demux_t * p_demux )
for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ ) for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
{ {
logical_stream_t *p_stream = p_sys->pp_stream[i_stream]; logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
if ( p_stream->b_have_updated_format ) if ( p_stream->b_have_updated_format && p_stream->p_es )
{ {
p_stream->b_have_updated_format = false; p_stream->b_have_updated_format = false;
if ( p_stream->p_skel ) Ogg_ApplySkeleton( p_stream ); if ( p_stream->p_skel ) Ogg_ApplySkeleton( p_stream );
...@@ -329,7 +339,6 @@ static int Demux( demux_t * p_demux ) ...@@ -329,7 +339,6 @@ static int Demux( demux_t * p_demux )
} }
} }
for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ ) for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
{ {
if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) ) if ( p_sys->pp_stream[i_stream]->i_serial_no == ogg_page_serialno( &p_sys->current_page ) )
...@@ -530,6 +539,12 @@ static int Demux( demux_t * p_demux ) ...@@ -530,6 +539,12 @@ static int Demux( demux_t * p_demux )
{ {
logical_stream_t *p_stream = p_sys->pp_stream[i_stream]; logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
if ( p_stream->b_force_backup )
{
/* We have 1 or more streams needing more than 1 page for preparsing */
p_sys->b_preparsing_done = false;
}
if( p_stream->fmt.i_cat == SPU_ES ) if( p_stream->fmt.i_cat == SPU_ES )
continue; continue;
if( p_stream->i_interpolated_pcr < 0 ) if( p_stream->i_interpolated_pcr < 0 )
...@@ -937,6 +952,9 @@ static void Ogg_DecodePacket( demux_t *p_demux, ...@@ -937,6 +952,9 @@ static void Ogg_DecodePacket( demux_t *p_demux,
p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return; p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
/* Check the ES is selected */ /* Check the ES is selected */
if ( !p_stream->p_es )
b_selected = true;
else
es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
p_stream->p_es, &b_selected ); p_stream->p_es, &b_selected );
...@@ -1048,6 +1066,7 @@ static void Ogg_DecodePacket( demux_t *p_demux, ...@@ -1048,6 +1066,7 @@ static void Ogg_DecodePacket( demux_t *p_demux,
} }
else else
{ {
if ( p_stream->p_es )
/* Otherwise we set config from first headers */ /* Otherwise we set config from first headers */
es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT, es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
p_stream->p_es, &p_stream->fmt ); p_stream->p_es, &p_stream->fmt );
...@@ -1279,8 +1298,18 @@ static void Ogg_DecodePacket( demux_t *p_demux, ...@@ -1279,8 +1298,18 @@ static void Ogg_DecodePacket( demux_t *p_demux,
memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len, memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
p_oggpacket->bytes - i_header_len ); p_oggpacket->bytes - i_header_len );
assert( p_ogg->b_preparsing_done ); if ( p_stream->p_es )
{
/* Because ES creation is delayed for preparsing */
if ( p_stream->p_preparse_block )
{
es_out_Send( p_demux->out, p_stream->p_es, p_stream->p_preparse_block );
p_stream->p_preparse_block = NULL;
}
es_out_Send( p_demux->out, p_stream->p_es, p_block ); es_out_Send( p_demux->out, p_stream->p_es, p_block );
}
else
block_ChainAppend( & p_stream->p_preparse_block, p_block );
} }
/* Re-implemented to avoid linking against libopus from the demuxer. */ /* Re-implemented to avoid linking against libopus from the demuxer. */
...@@ -1798,33 +1827,24 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) ...@@ -1798,33 +1827,24 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
} }
/**************************************************************************** /****************************************************************************
* Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add * Ogg_CreateES: Creates all Elementary streams once headers are parsed
* Elementary streams.
****************************************************************************/ ****************************************************************************/
static int Ogg_BeginningOfStream( demux_t *p_demux ) static void Ogg_CreateES( demux_t *p_demux )
{ {
demux_sys_t *p_ogg = p_demux->p_sys ; demux_sys_t *p_ogg = p_demux->p_sys;
logical_stream_t *p_old_stream = p_ogg->p_old_stream; logical_stream_t *p_old_stream = p_ogg->p_old_stream;
int i_stream; int i_stream;
/* Find the logical streams embedded in the physical stream and
* initialize our p_ogg structure. */
if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
{
msg_Warn( p_demux, "couldn't find any ogg logical stream" );
return VLC_EGENERIC;
}
p_ogg->i_bitrate = 0;
for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ ) for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
{ {
logical_stream_t *p_stream = p_ogg->pp_stream[i_stream]; logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
p_stream->p_es = NULL; if ( p_stream->p_es == NULL )
{
/* initialise kframe index */ /* Better be safe than sorry when possible with ogm */
p_stream->idx=NULL; if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
p_stream->fmt.i_codec == VLC_CODEC_A52 )
p_stream->fmt.b_packetized = false;
/* Try first to reuse an old ES */ /* Try first to reuse an old ES */
if( p_old_stream && if( p_old_stream &&
...@@ -1838,15 +1858,11 @@ static int Ogg_BeginningOfStream( demux_t *p_demux ) ...@@ -1838,15 +1858,11 @@ static int Ogg_BeginningOfStream( demux_t *p_demux )
p_old_stream->p_es = NULL; p_old_stream->p_es = NULL;
p_old_stream = NULL; p_old_stream = NULL;
es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
p_stream->p_es, &p_stream->fmt );
} }
else
if( !p_stream->p_es )
{ {
/* Better be safe than sorry when possible with ogm */
if( p_stream->fmt.i_codec == VLC_CODEC_MPGA ||
p_stream->fmt.i_codec == VLC_CODEC_A52 )
p_stream->fmt.b_packetized = false;
p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt ); p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
} }
...@@ -1856,6 +1872,45 @@ static int Ogg_BeginningOfStream( demux_t *p_demux ) ...@@ -1856,6 +1872,45 @@ static int Ogg_BeginningOfStream( demux_t *p_demux )
/* Set the CMML stream active */ /* Set the CMML stream active */
es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es ); es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
} }
}
}
if( p_ogg->p_old_stream )
{
if( p_ogg->p_old_stream->p_es )
msg_Dbg( p_demux, "old stream not reused" );
Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
p_ogg->p_old_stream = NULL;
}
}
/****************************************************************************
* Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add
* Elementary streams.
****************************************************************************/
static int Ogg_BeginningOfStream( demux_t *p_demux )
{
demux_sys_t *p_ogg = p_demux->p_sys ;
int i_stream;
/* Find the logical streams embedded in the physical stream and
* initialize our p_ogg structure. */
if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
{
msg_Warn( p_demux, "couldn't find any ogg logical stream" );
return VLC_EGENERIC;
}
p_ogg->i_bitrate = 0;
for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
{
logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];
p_stream->p_es = NULL;
/* initialise kframe index */
p_stream->idx=NULL;
if ( p_stream->fmt.i_bitrate == 0 && if ( p_stream->fmt.i_bitrate == 0 &&
( p_stream->fmt.i_cat == VIDEO_ES || ( p_stream->fmt.i_cat == VIDEO_ES ||
...@@ -1869,15 +1924,6 @@ static int Ogg_BeginningOfStream( demux_t *p_demux ) ...@@ -1869,15 +1924,6 @@ static int Ogg_BeginningOfStream( demux_t *p_demux )
p_stream->b_reinit = false; p_stream->b_reinit = false;
} }
if( p_ogg->p_old_stream )
{
if( p_ogg->p_old_stream->p_es )
msg_Dbg( p_demux, "old stream not reused" );
Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );
p_ogg->p_old_stream = NULL;
}
/* get total frame count for video stream; we will need this for seeking */ /* get total frame count for video stream; we will need this for seeking */
p_ogg->i_total_frames = 0; p_ogg->i_total_frames = 0;
...@@ -1902,6 +1948,7 @@ static void Ogg_EndOfStream( demux_t *p_demux ) ...@@ -1902,6 +1948,7 @@ static void Ogg_EndOfStream( demux_t *p_demux )
p_ogg->pp_stream = NULL; p_ogg->pp_stream = NULL;
p_ogg->skeleton.major = 0; p_ogg->skeleton.major = 0;
p_ogg->skeleton.minor = 0; p_ogg->skeleton.minor = 0;
p_ogg->b_preparsing_done = false;
/* */ /* */
if( p_ogg->p_meta ) if( p_ogg->p_meta )
...@@ -1941,6 +1988,13 @@ static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_strea ...@@ -1941,6 +1988,13 @@ static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_strea
if ( p_demux->p_sys->p_skelstream == p_stream ) if ( p_demux->p_sys->p_skelstream == p_stream )
p_demux->p_sys->p_skelstream = NULL; p_demux->p_sys->p_skelstream = NULL;
/* Shouldn't happen */
if ( unlikely( p_stream->p_preparse_block ) )
{
block_ChainRelease( p_stream->p_preparse_block );
p_stream->p_preparse_block = NULL;
}
free( p_stream ); free( p_stream );
} }
/** /**
......
...@@ -104,6 +104,7 @@ typedef struct logical_stream_s ...@@ -104,6 +104,7 @@ typedef struct logical_stream_s
/* for Annodex logical bitstreams */ /* for Annodex logical bitstreams */
int i_secondary_header_packets; int i_secondary_header_packets;
block_t *p_preparse_block;
} logical_stream_t; } logical_stream_t;
struct ogg_skeleton_t struct ogg_skeleton_t
......
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