Commit 032b7f88 authored by Laurent Aimar's avatar Laurent Aimar

* ts.c: - send PES as soon as possible to decoder (and not waiting the

           next one).
         - added partial 14496-17 support, in other words mpeg4 text
           subtitles.
parent 0833e088
...@@ -185,6 +185,8 @@ typedef struct ...@@ -185,6 +185,8 @@ typedef struct
{ {
es_format_t fmt; es_format_t fmt;
es_out_id_t *id; es_out_id_t *id;
int i_pes_size;
int i_pes_gathered;
block_t *p_pes; block_t *p_pes;
block_t **pp_last; block_t **pp_last;
...@@ -792,6 +794,8 @@ static void PIDInit( ts_pid_t *pid, vlc_bool_t b_psi, ts_psi_t *p_owner ) ...@@ -792,6 +794,8 @@ static void PIDInit( ts_pid_t *pid, vlc_bool_t b_psi, ts_psi_t *p_owner )
es_format_Init( &pid->es->fmt, UNKNOWN_ES, 0 ); es_format_Init( &pid->es->fmt, UNKNOWN_ES, 0 );
pid->es->id = NULL; pid->es->id = NULL;
pid->es->p_pes = NULL; pid->es->p_pes = NULL;
pid->es->i_pes_size= 0;
pid->es->i_pes_gathered= 0;
pid->es->pp_last = &pid->es->p_pes; pid->es->pp_last = &pid->es->p_pes;
pid->es->p_mpeg4desc = NULL; pid->es->p_mpeg4desc = NULL;
pid->es->b_gather = VLC_FALSE; pid->es->b_gather = VLC_FALSE;
...@@ -853,14 +857,17 @@ static void ParsePES ( demux_t *p_demux, ts_pid_t *pid ) ...@@ -853,14 +857,17 @@ static void ParsePES ( demux_t *p_demux, ts_pid_t *pid )
{ {
block_t *p_pes = pid->es->p_pes; block_t *p_pes = pid->es->p_pes;
uint8_t header[30]; uint8_t header[30];
int i_pes_size; int i_pes_size = 0;
int i_skip = 0; int i_skip = 0;
mtime_t i_dts = -1; mtime_t i_dts = -1;
mtime_t i_pts = -1; mtime_t i_pts = -1;
mtime_t i_length = 0;
int i_max; int i_max;
/* remove the pes from pid */ /* remove the pes from pid */
pid->es->p_pes = NULL; pid->es->p_pes = NULL;
pid->es->i_pes_size= 0;
pid->es->i_pes_gathered= 0;
pid->es->pp_last = &pid->es->p_pes; pid->es->pp_last = &pid->es->p_pes;
/* FIXME find real max size */ /* FIXME find real max size */
...@@ -875,10 +882,7 @@ static void ParsePES ( demux_t *p_demux, ts_pid_t *pid ) ...@@ -875,10 +882,7 @@ static void ParsePES ( demux_t *p_demux, ts_pid_t *pid )
return; return;
} }
i_pes_size = (header[4] << 8)|header[5];
/* TODO check size */ /* TODO check size */
switch( header[3] ) switch( header[3] )
{ {
case 0xBC: /* Program stream map */ case 0xBC: /* Program stream map */
...@@ -974,6 +978,30 @@ static void ParsePES ( demux_t *p_demux, ts_pid_t *pid ) ...@@ -974,6 +978,30 @@ static void ParsePES ( demux_t *p_demux, ts_pid_t *pid )
{ {
i_skip += 1; i_skip += 1;
} }
else if( pid->es->fmt.i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) && pid->es->p_mpeg4desc )
{
decoder_config_descriptor_t *dcd = &pid->es->p_mpeg4desc->dec_descr;
if( dcd->i_decoder_specific_info_len > 2 &&
dcd->p_decoder_specific_info[0] == 0x10 &&
( dcd->p_decoder_specific_info[1]&0x10 ) )
{
/* display length */
if( p_pes->i_buffer + 2 <= i_skip )
{
msg_Warn( p_demux, "length: %lld", i_length );
i_length = GetWBE( &p_pes->p_buffer[i_skip] );
}
i_skip += 2;
}
if( p_pes->i_buffer + 2 <= i_skip )
{
i_pes_size = GetWBE( &p_pes->p_buffer[i_skip] );
}
/* */
i_skip += 2;
}
/* skip header */ /* skip header */
while( p_pes && i_skip > 0 ) while( p_pes && i_skip > 0 )
...@@ -1007,16 +1035,21 @@ static void ParsePES ( demux_t *p_demux, ts_pid_t *pid ) ...@@ -1007,16 +1035,21 @@ static void ParsePES ( demux_t *p_demux, ts_pid_t *pid )
{ {
p_pes->i_pts = i_pts * 100 / 9; p_pes->i_pts = i_pts * 100 / 9;
} }
p_pes->i_length = i_length * 100 / 9;
if( 1 ) //pid->es->b_gather )
{
/* For mpeg4/mscodec we first gather the packet.
* This will make ffmpeg a lot happier */
p_block = block_ChainGather( p_pes ); p_block = block_ChainGather( p_pes );
} if( pid->es->fmt.i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) )
else {
if( i_pes_size > 0 && p_block->i_buffer > i_pes_size )
{ {
p_block = p_pes; p_block->i_buffer = i_pes_size;
}
/* Append a \0 */
p_block = block_Realloc( p_block, 0, p_block->i_buffer + 1 );
p_block->p_buffer[p_block->i_buffer -1] = '\0';
msg_Warn( p_demux, "subs: pts=%lld str='%s'",
p_block->i_pts, p_block->p_buffer );
} }
for( i = 0; i < pid->i_extra_es; i++ ) for( i = 0; i < pid->i_extra_es; i++ )
...@@ -1167,6 +1200,21 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk ) ...@@ -1167,6 +1200,21 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
} }
block_ChainLastAppend( &pid->es->pp_last, p_bk ); block_ChainLastAppend( &pid->es->pp_last, p_bk );
if( p_bk->i_buffer > 6 )
{
pid->es->i_pes_size = GetWBE( &p_bk->p_buffer[4] );
if( pid->es->i_pes_size > 0 )
{
pid->es->i_pes_size += 6;
}
}
pid->es->i_pes_gathered += p_bk->i_buffer;
if( pid->es->i_pes_size > 0 &&
pid->es->i_pes_gathered >= pid->es->i_pes_size )
{
ParsePES( p_demux, pid );
i_ret = VLC_TRUE;
}
} }
else else
{ {
...@@ -1177,9 +1225,14 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk ) ...@@ -1177,9 +1225,14 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
} }
else else
{ {
/* TODO check if when have gathered enough packets to form a
* PES (ie read PES size)*/
block_ChainLastAppend( &pid->es->pp_last, p_bk ); block_ChainLastAppend( &pid->es->pp_last, p_bk );
pid->es->i_pes_gathered += p_bk->i_buffer;
if( pid->es->i_pes_size > 0 &&
pid->es->i_pes_gathered >= pid->es->i_pes_size )
{
ParsePES( p_demux, pid );
i_ret = VLC_TRUE;
}
} }
} }
} }
...@@ -1249,6 +1302,7 @@ static int PIDFillFormat( ts_pid_t *pid, int i_stream_type ) ...@@ -1249,6 +1302,7 @@ static int PIDFillFormat( ts_pid_t *pid, int i_stream_type )
break; break;
case 0x06: /* PES_PRIVATE (fixed later) */ case 0x06: /* PES_PRIVATE (fixed later) */
case 0x12: /* MPEG-4 generic (sub/scene/...) (fixed later) */
default: default:
es_format_Init( fmt, UNKNOWN_ES, 0 ); es_format_Init( fmt, UNKNOWN_ES, 0 );
break; break;
...@@ -1714,7 +1768,7 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) ...@@ -1714,7 +1768,7 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
PIDFillFormat( pid, p_es->i_type ); PIDFillFormat( pid, p_es->i_type );
pid->i_owner_number = prg->i_number; pid->i_owner_number = prg->i_number;
if( p_es->i_type == 0x10 || p_es->i_type == 0x11 ) if( p_es->i_type == 0x10 || p_es->i_type == 0x11 || p_es->i_type == 0x12 )
{ {
/* MPEG-4 stream: search SL_DESCRIPTOR */ /* MPEG-4 stream: search SL_DESCRIPTOR */
dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;; dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;;
...@@ -1753,6 +1807,11 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) ...@@ -1753,6 +1807,11 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
pid->es->fmt.i_cat = VIDEO_ES; pid->es->fmt.i_cat = VIDEO_ES;
switch( dcd->i_objectTypeIndication ) switch( dcd->i_objectTypeIndication )
{ {
case 0x0B: /* mpeg4 sub */
pid->es->fmt.i_cat = SPU_ES;
pid->es->fmt.i_codec = VLC_FOURCC('s','u','b','t');
break;
case 0x20: /* mpeg4 */ case 0x20: /* mpeg4 */
pid->es->fmt.i_codec = VLC_FOURCC('m','p','4','v'); pid->es->fmt.i_codec = VLC_FOURCC('m','p','4','v');
break; break;
...@@ -1866,6 +1925,8 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) ...@@ -1866,6 +1925,8 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
p_es->fmt = pid->es->fmt; p_es->fmt = pid->es->fmt;
p_es->id = NULL; p_es->id = NULL;
p_es->p_pes = NULL; p_es->p_pes = NULL;
p_es->i_pes_size = 0;
p_es->i_pes_gathered = 0;
p_es->pp_last = &p_es->p_pes; p_es->pp_last = &p_es->p_pes;
p_es->p_mpeg4desc = NULL; p_es->p_mpeg4desc = NULL;
......
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