Commit 9536a4e5 authored by François Cartegnie's avatar François Cartegnie 🤞

packetizer: h264: store SEI nal apart

Some SEI requires parsing context from picture
header. We are then currently always wrong for
first frame or first frame before a change in those
params. We need to delay parsing.
parent 55428248
...@@ -96,6 +96,8 @@ struct decoder_sys_t ...@@ -96,6 +96,8 @@ struct decoder_sys_t
bool b_slice; bool b_slice;
block_t *p_frame; block_t *p_frame;
block_t **pp_frame_last; block_t **pp_frame_last;
block_t *p_sei;
block_t **pp_sei_last;
/* a new sps/pps can be transmitted outside of iframes */ /* a new sps/pps can be transmitted outside of iframes */
bool b_new_sps; bool b_new_sps;
bool b_new_pps; bool b_new_pps;
...@@ -335,6 +337,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -335,6 +337,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->pp_frame_last = &p_sys->p_frame; p_sys->pp_frame_last = &p_sys->p_frame;
p_sys->p_sei = NULL;
p_sys->pp_sei_last = &p_sys->p_sei;
p_sys->b_new_sps = false; p_sys->b_new_sps = false;
p_sys->b_new_pps = false; p_sys->b_new_pps = false;
...@@ -457,8 +461,8 @@ static void Close( vlc_object_t *p_this ) ...@@ -457,8 +461,8 @@ static void Close( vlc_object_t *p_this )
decoder_sys_t *p_sys = p_dec->p_sys; decoder_sys_t *p_sys = p_dec->p_sys;
int i; int i;
if( p_sys->p_frame ) block_ChainRelease( p_sys->p_frame );
block_ChainRelease( p_sys->p_frame ); block_ChainRelease( p_sys->p_sei );
for( i = 0; i <= H264_SPS_ID_MAX; i++ ) for( i = 0; i <= H264_SPS_ID_MAX; i++ )
StoreSPS( p_sys, i, NULL, NULL ); StoreSPS( p_sys, i, NULL, NULL );
for( i = 0; i <= H264_PPS_ID_MAX; i++ ) for( i = 0; i <= H264_PPS_ID_MAX; i++ )
...@@ -521,10 +525,12 @@ static void PacketizeReset( void *p_private, bool b_broken ) ...@@ -521,10 +525,12 @@ static void PacketizeReset( void *p_private, bool b_broken )
if( b_broken ) if( b_broken )
{ {
if( p_sys->p_frame ) block_ChainRelease( p_sys->p_frame );
block_ChainRelease( p_sys->p_frame ); block_ChainRelease( p_sys->p_sei );
p_sys->p_frame = NULL; p_sys->p_frame = NULL;
p_sys->pp_frame_last = &p_sys->p_frame; p_sys->pp_frame_last = &p_sys->p_frame;
p_sys->p_sei = NULL;
p_sys->pp_sei_last = &p_sys->p_sei;
p_sys->b_new_sps = false; p_sys->b_new_sps = false;
p_sys->b_new_pps = false; p_sys->b_new_pps = false;
p_sys->p_active_pps = NULL; p_sys->p_active_pps = NULL;
...@@ -573,12 +579,15 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr ...@@ -573,12 +579,15 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
if( p_sys->b_slice && (!p_sys->p_active_pps || !p_sys->p_active_sps) ) if( p_sys->b_slice && (!p_sys->p_active_pps || !p_sys->p_active_sps) )
{ {
block_ChainRelease( p_sys->p_frame ); block_ChainRelease( p_sys->p_frame );
block_ChainRelease( p_sys->p_sei );
msg_Warn( p_dec, "waiting for SPS/PPS" ); msg_Warn( p_dec, "waiting for SPS/PPS" );
/* Reset context */ /* Reset context */
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->pp_frame_last = &p_sys->p_frame; p_sys->pp_frame_last = &p_sys->p_frame;
p_sys->p_sei = NULL;
p_sys->pp_sei_last = &p_sys->p_sei;
p_sys->b_slice = false; p_sys->b_slice = false;
cc_storage_reset( p_sys->p_ccs ); cc_storage_reset( p_sys->p_ccs );
} }
...@@ -629,20 +638,23 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr ...@@ -629,20 +638,23 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
/* Do not append the PPS because we will insert it on keyframes */ /* Do not append the PPS because we will insert it on keyframes */
p_frag = NULL; p_frag = NULL;
} }
else if( i_nal_type == H264_NAL_SEI )
{
if( p_sys->b_slice )
p_pic = OutputPicture( p_dec );
/* Parse SEI for CC support */
HxxxParse_AnnexB_SEI( p_frag->p_buffer, p_frag->i_buffer,
1 /* nal header */, ParseSeiCallback, p_dec );
block_ChainLastAppend( &p_sys->pp_sei_last, p_frag );
p_frag = NULL;
}
else if( i_nal_type == H264_NAL_AU_DELIMITER || else if( i_nal_type == H264_NAL_AU_DELIMITER ||
i_nal_type == H264_NAL_SEI ||
( i_nal_type >= H264_NAL_PREFIX && i_nal_type <= H264_NAL_RESERVED_18 ) ) ( i_nal_type >= H264_NAL_PREFIX && i_nal_type <= H264_NAL_RESERVED_18 ) )
{ {
if( p_sys->b_slice ) if( p_sys->b_slice )
p_pic = OutputPicture( p_dec ); p_pic = OutputPicture( p_dec );
/* Parse SEI for CC support */ if( i_nal_type == H264_NAL_AU_DELIMITER )
if( i_nal_type == H264_NAL_SEI )
{
HxxxParse_AnnexB_SEI( p_frag->p_buffer, p_frag->i_buffer,
1 /* nal header */, ParseSeiCallback, p_dec );
}
else if( i_nal_type == H264_NAL_AU_DELIMITER )
{ {
if( p_sys->p_frame && (p_sys->p_frame->i_flags & BLOCK_FLAG_PRIVATE_AUD) ) if( p_sys->p_frame && (p_sys->p_frame->i_flags & BLOCK_FLAG_PRIVATE_AUD) )
{ {
...@@ -740,6 +752,9 @@ static block_t *OutputPicture( decoder_t *p_dec ) ...@@ -740,6 +752,9 @@ static block_t *OutputPicture( decoder_t *p_dec )
if( p_xpsnal ) if( p_xpsnal )
block_ChainLastAppend( &pp_pic_last, p_xpsnal ); block_ChainLastAppend( &pp_pic_last, p_xpsnal );
if( p_sys->p_sei )
block_ChainLastAppend( &pp_pic_last, p_sys->p_sei );
assert( p_sys->p_frame ); assert( p_sys->p_frame );
if( p_sys->p_frame ) if( p_sys->p_frame )
block_ChainLastAppend( &pp_pic_last, p_sys->p_frame ); block_ChainLastAppend( &pp_pic_last, p_sys->p_frame );
...@@ -747,6 +762,8 @@ static block_t *OutputPicture( decoder_t *p_dec ) ...@@ -747,6 +762,8 @@ static block_t *OutputPicture( decoder_t *p_dec )
/* Reset chains, now empty */ /* Reset chains, now empty */
p_sys->p_frame = NULL; p_sys->p_frame = NULL;
p_sys->pp_frame_last = &p_sys->p_frame; p_sys->pp_frame_last = &p_sys->p_frame;
p_sys->p_sei = NULL;
p_sys->pp_sei_last = &p_sys->p_sei;
p_pic = block_ChainGather( p_pic ); p_pic = block_ChainGather( p_pic );
...@@ -849,8 +866,8 @@ static block_t *OutputPicture( decoder_t *p_dec ) ...@@ -849,8 +866,8 @@ static block_t *OutputPicture( decoder_t *p_dec )
p_sys->i_frame_pts = VLC_TS_INVALID; p_sys->i_frame_pts = VLC_TS_INVALID;
p_sys->i_dpb_output_delay = 0; p_sys->i_dpb_output_delay = 0;
p_sys->slice.i_frame_type = 0; p_sys->slice.i_frame_type = 0;
p_sys->p_frame = NULL; p_sys->p_sei = NULL;
p_sys->pp_frame_last = &p_sys->p_frame; p_sys->pp_sei_last = &p_sys->p_sei;
p_sys->b_new_sps = false; p_sys->b_new_sps = false;
p_sys->b_new_pps = false; p_sys->b_new_pps = false;
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