[vlc-commits] packetizer: h264: store SEI nal apart
Francois Cartegnie
git at videolan.org
Wed Mar 15 17:59:25 CET 2017
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Mar 15 17:23:35 2017 +0100| [9536a4e55b8d1264591784ae9fbce63d5220294f] | committer: Francois 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.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=9536a4e55b8d1264591784ae9fbce63d5220294f
---
modules/packetizer/h264.c | 45 +++++++++++++++++++++++++++++++--------------
1 file changed, 31 insertions(+), 14 deletions(-)
diff --git a/modules/packetizer/h264.c b/modules/packetizer/h264.c
index ae005e9..f381372 100644
--- a/modules/packetizer/h264.c
+++ b/modules/packetizer/h264.c
@@ -96,6 +96,8 @@ struct decoder_sys_t
bool b_slice;
block_t *p_frame;
block_t **pp_frame_last;
+ block_t *p_sei;
+ block_t **pp_sei_last;
/* a new sps/pps can be transmitted outside of iframes */
bool b_new_sps;
bool b_new_pps;
@@ -335,6 +337,8 @@ static int Open( vlc_object_t *p_this )
p_sys->b_slice = false;
p_sys->p_frame = NULL;
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_pps = false;
@@ -457,8 +461,8 @@ static void Close( vlc_object_t *p_this )
decoder_sys_t *p_sys = p_dec->p_sys;
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++ )
StoreSPS( p_sys, i, NULL, NULL );
for( i = 0; i <= H264_PPS_ID_MAX; i++ )
@@ -521,10 +525,12 @@ static void PacketizeReset( void *p_private, bool 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->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_pps = false;
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
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_sei );
msg_Warn( p_dec, "waiting for SPS/PPS" );
/* Reset context */
p_sys->slice.i_frame_type = 0;
p_sys->p_frame = NULL;
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;
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
/* Do not append the PPS because we will insert it on keyframes */
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 ||
- i_nal_type == H264_NAL_SEI ||
( i_nal_type >= H264_NAL_PREFIX && i_nal_type <= H264_NAL_RESERVED_18 ) )
{
if( p_sys->b_slice )
p_pic = OutputPicture( p_dec );
- /* Parse SEI for CC support */
- 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( i_nal_type == H264_NAL_AU_DELIMITER )
{
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 )
if( 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 );
if( 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 )
/* Reset chains, now empty */
p_sys->p_frame = NULL;
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 );
@@ -849,8 +866,8 @@ static block_t *OutputPicture( decoder_t *p_dec )
p_sys->i_frame_pts = VLC_TS_INVALID;
p_sys->i_dpb_output_delay = 0;
p_sys->slice.i_frame_type = 0;
- p_sys->p_frame = NULL;
- 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_pps = false;
p_sys->b_slice = false;
More information about the vlc-commits
mailing list