Commit 02650b60 authored by Jean-Paul Saman's avatar Jean-Paul Saman

packetizer/h264.c: improve SPS/PPS detection for frames

parent b8b84564
...@@ -92,10 +92,12 @@ struct decoder_sys_t ...@@ -92,10 +92,12 @@ struct decoder_sys_t
/* */ /* */
bool b_slice; bool b_slice;
block_t *p_frame; block_t *p_frame;
bool b_frame_sps;
bool b_frame_pps;
bool b_header; bool b_header;
bool b_sps; bool b_sps;
bool b_pps; bool b_pps;
block_t *pp_sps[SPS_MAX]; block_t *pp_sps[SPS_MAX];
block_t *pp_pps[PPS_MAX]; block_t *pp_pps[PPS_MAX];
...@@ -151,6 +153,8 @@ enum nal_priority_e ...@@ -151,6 +153,8 @@ enum nal_priority_e
NAL_PRIORITY_HIGHEST = 3, NAL_PRIORITY_HIGHEST = 3,
}; };
#define BLOCK_FLAG_PRIVATE_AUD (1 << BLOCK_FLAG_PRIVATE_SHIFT)
static block_t *Packetize( decoder_t *, block_t ** ); static block_t *Packetize( decoder_t *, block_t ** );
static block_t *PacketizeAVC1( decoder_t *, block_t ** ); static block_t *PacketizeAVC1( decoder_t *, block_t ** );
static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] ); static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] );
...@@ -209,6 +213,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -209,6 +213,8 @@ static int Open( vlc_object_t *p_this )
p_sys->b_slice = false; p_sys->b_slice = false;
p_sys->p_frame = NULL; p_sys->p_frame = NULL;
p_sys->b_frame_sps = false;
p_sys->b_frame_pps = false;
p_sys->b_header= false; p_sys->b_header= false;
p_sys->b_sps = false; p_sys->b_sps = false;
p_sys->b_pps = false; p_sys->b_pps = false;
...@@ -506,6 +512,8 @@ static void PacketizeReset( void *p_private, bool b_broken ) ...@@ -506,6 +512,8 @@ static void PacketizeReset( void *p_private, bool b_broken )
if( p_sys->p_frame ) if( p_sys->p_frame )
block_ChainRelease( p_sys->p_frame ); block_ChainRelease( p_sys->p_frame );
p_sys->p_frame = NULL; p_sys->p_frame = NULL;
p_sys->b_frame_sps = false;
p_sys->b_frame_pps = false;
p_sys->slice.i_frame_type = 0; p_sys->slice.i_frame_type = 0;
p_sys->b_slice = false; p_sys->b_slice = false;
} }
...@@ -645,6 +653,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_used_ts, block_t *p_fr ...@@ -645,6 +653,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_used_ts, block_t *p_fr
{ {
if( p_sys->b_slice ) if( p_sys->b_slice )
p_pic = OutputPicture( p_dec ); p_pic = OutputPicture( p_dec );
p_sys->b_frame_sps = true;
PutSPS( p_dec, p_frag ); PutSPS( p_dec, p_frag );
...@@ -655,6 +664,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_used_ts, block_t *p_fr ...@@ -655,6 +664,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_used_ts, block_t *p_fr
{ {
if( p_sys->b_slice ) if( p_sys->b_slice )
p_pic = OutputPicture( p_dec ); p_pic = OutputPicture( p_dec );
p_sys->b_frame_pps = true;
PutPPS( p_dec, p_frag ); PutPPS( p_dec, p_frag );
...@@ -670,7 +680,21 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_used_ts, block_t *p_fr ...@@ -670,7 +680,21 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_used_ts, block_t *p_fr
/* Parse SEI for CC support */ /* Parse SEI for CC support */
if( i_nal_type == NAL_SEI ) if( i_nal_type == NAL_SEI )
{
ParseSei( p_dec, p_frag ); ParseSei( p_dec, p_frag );
}
else if( i_nal_type == NAL_AU_DELIMITER )
{
if( p_sys->p_frame && (p_sys->p_frame->i_flags & BLOCK_FLAG_PRIVATE_AUD) )
{
block_Release( p_frag );
p_frag = NULL;
}
else
{
p_frag->i_flags |= BLOCK_FLAG_PRIVATE_AUD;
}
}
} }
/* Append the block */ /* Append the block */
...@@ -695,26 +719,40 @@ static block_t *OutputPicture( decoder_t *p_dec ) ...@@ -695,26 +719,40 @@ static block_t *OutputPicture( decoder_t *p_dec )
if( !p_sys->b_header && p_sys->slice.i_frame_type != BLOCK_FLAG_TYPE_I) if( !p_sys->b_header && p_sys->slice.i_frame_type != BLOCK_FLAG_TYPE_I)
return NULL; return NULL;
if( p_sys->slice.i_frame_type == BLOCK_FLAG_TYPE_I && p_sys->b_sps && p_sys->b_pps ) const bool b_sps_pps_i = p_sys->slice.i_frame_type == BLOCK_FLAG_TYPE_I &&
p_sys->b_sps &&
p_sys->b_pps;
if( b_sps_pps_i || p_sys->b_frame_sps || p_sys->b_frame_pps )
{ {
block_t *p_list = NULL; block_t *p_head = NULL;
int i; if( p_sys->p_frame->i_flags & BLOCK_FLAG_PRIVATE_AUD )
{
p_head = p_sys->p_frame;
p_sys->p_frame = p_sys->p_frame->p_next;
}
for( i = 0; i < SPS_MAX; i++ ) block_t *p_list = NULL;
for( int i = 0; i < SPS_MAX && (b_sps_pps_i || p_sys->b_frame_sps); i++ )
{ {
if( p_sys->pp_sps[i] ) if( p_sys->pp_sps[i] )
block_ChainAppend( &p_list, block_Duplicate( p_sys->pp_sps[i] ) ); block_ChainAppend( &p_list, block_Duplicate( p_sys->pp_sps[i] ) );
} }
for( i = 0; i < PPS_MAX; i++ )
for( int i = 0; i < PPS_MAX && (b_sps_pps_i || p_sys->b_frame_pps); i++ )
{ {
if( p_sys->pp_pps[i] ) if( p_sys->pp_pps[i] )
block_ChainAppend( &p_list, block_Duplicate( p_sys->pp_pps[i] ) ); block_ChainAppend( &p_list, block_Duplicate( p_sys->pp_pps[i] ) );
} }
if( p_list )
if( b_sps_pps_i && p_list )
p_sys->b_header = true; p_sys->b_header = true;
block_ChainAppend( &p_list, p_sys->p_frame ); if( p_head )
p_pic = block_ChainGather( p_list ); p_head->p_next = p_list;
else
p_head = p_list;
block_ChainAppend( &p_head, p_sys->p_frame );
p_pic = block_ChainGather( p_head );
} }
else else
{ {
...@@ -724,9 +762,12 @@ static block_t *OutputPicture( decoder_t *p_dec ) ...@@ -724,9 +762,12 @@ static block_t *OutputPicture( decoder_t *p_dec )
p_pic->i_pts = p_sys->i_frame_pts; p_pic->i_pts = p_sys->i_frame_pts;
p_pic->i_length = 0; /* FIXME */ p_pic->i_length = 0; /* FIXME */
p_pic->i_flags |= p_sys->slice.i_frame_type; p_pic->i_flags |= p_sys->slice.i_frame_type;
p_pic->i_flags &= ~BLOCK_FLAG_PRIVATE_AUD;
p_sys->slice.i_frame_type = 0; p_sys->slice.i_frame_type = 0;
p_sys->p_frame = NULL; p_sys->p_frame = NULL;
p_sys->b_frame_sps = false;
p_sys->b_frame_pps = false;
p_sys->i_frame_dts = -1; p_sys->i_frame_dts = -1;
p_sys->i_frame_pts = -1; p_sys->i_frame_pts = -1;
p_sys->b_slice = false; p_sys->b_slice = false;
......
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