[vlc-commits] packetizer: h264: regroup and explicitely name nal in switch
Francois Cartegnie
git at videolan.org
Thu Nov 9 11:11:27 CET 2017
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Nov 7 23:46:34 2017 +0100| [415966183a94d610d4a93a9afc732349d32c786d] | committer: Francois Cartegnie
packetizer: h264: regroup and explicitely name nal in switch
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=415966183a94d610d4a93a9afc732349d32c786d
---
modules/packetizer/h264.c | 254 ++++++++++++++++++++++++++--------------------
1 file changed, 142 insertions(+), 112 deletions(-)
diff --git a/modules/packetizer/h264.c b/modules/packetizer/h264.c
index cdb0d4c326..beced99e42 100644
--- a/modules/packetizer/h264.c
+++ b/modules/packetizer/h264.c
@@ -76,10 +76,12 @@ 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;
+ struct
+ {
+ block_t *p_head;
+ block_t **pp_append;
+ } frame, leading;
+
/* a new sps/pps can be transmitted outside of iframes */
bool b_new_sps;
bool b_new_pps;
@@ -131,7 +133,8 @@ struct decoder_sys_t
};
#define BLOCK_FLAG_PRIVATE_AUD (1 << BLOCK_FLAG_PRIVATE_SHIFT)
-#define BLOCK_FLAG_DROP (2 << BLOCK_FLAG_PRIVATE_SHIFT)
+#define BLOCK_FLAG_PRIVATE_SEI (2 << BLOCK_FLAG_PRIVATE_SHIFT)
+#define BLOCK_FLAG_DROP (4 << BLOCK_FLAG_PRIVATE_SHIFT)
static block_t *Packetize( decoder_t *, block_t ** );
static block_t *PacketizeAVC1( decoder_t *, block_t ** );
@@ -261,12 +264,12 @@ static bool IsFirstVCLNALUnit( const h264_slice_t *p_prev, const h264_slice_t *p
static void DropStoredNAL( decoder_sys_t *p_sys )
{
- 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;
+ block_ChainRelease( p_sys->frame.p_head );
+ block_ChainRelease( p_sys->leading.p_head );
+ p_sys->frame.p_head = NULL;
+ p_sys->frame.pp_append = &p_sys->frame.p_head;
+ p_sys->leading.p_head = NULL;
+ p_sys->leading.pp_append = &p_sys->leading.p_head;
}
/*****************************************************************************
@@ -306,10 +309,10 @@ static int Open( vlc_object_t *p_this )
PacketizeReset, PacketizeParse, PacketizeValidate, p_dec );
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->frame.p_head = NULL;
+ p_sys->frame.pp_append = &p_sys->frame.p_head;
+ p_sys->leading.p_head = NULL;
+ p_sys->leading.pp_append = &p_sys->leading.p_head;
p_sys->b_new_sps = false;
p_sys->b_new_pps = false;
@@ -568,111 +571,136 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
cc_storage_reset( p_sys->p_ccs );
}
- if( i_nal_type >= H264_NAL_SLICE && i_nal_type <= H264_NAL_SLICE_IDR )
+ switch( i_nal_type )
{
- h264_slice_t newslice;
-
- if( i_nal_type == H264_NAL_SLICE_IDR )
+ /*** Slices ***/
+ case H264_NAL_SLICE:
+ case H264_NAL_SLICE_DPA:
+ case H264_NAL_SLICE_DPB:
+ case H264_NAL_SLICE_DPC:
+ case H264_NAL_SLICE_IDR:
{
- p_sys->b_recovered = true;
- p_sys->i_recovery_frame_cnt = UINT_MAX;
- p_sys->i_recoveryfnum = UINT_MAX;
- }
+ h264_slice_t newslice;
- if( ParseSliceHeader( p_dec, p_frag, &newslice ) )
- {
- /* Only IDR carries the id, to be propagated */
- if( newslice.i_idr_pic_id == -1 )
- newslice.i_idr_pic_id = p_sys->slice.i_idr_pic_id;
+ if( i_nal_type == H264_NAL_SLICE_IDR )
+ {
+ p_sys->b_recovered = true;
+ p_sys->i_recovery_frame_cnt = UINT_MAX;
+ p_sys->i_recoveryfnum = UINT_MAX;
+ }
- b_new_picture = IsFirstVCLNALUnit( &p_sys->slice, &newslice );
- if( b_new_picture )
+ if( ParseSliceHeader( p_dec, p_frag, &newslice ) )
{
- /* Parse SEI for that frame now we should have matched SPS/PPS */
- for( block_t *p_sei = p_sys->p_sei; p_sei; p_sei = p_sei->p_next )
+ /* Only IDR carries the id, to be propagated */
+ if( newslice.i_idr_pic_id == -1 )
+ newslice.i_idr_pic_id = p_sys->slice.i_idr_pic_id;
+
+ b_new_picture = IsFirstVCLNALUnit( &p_sys->slice, &newslice );
+ if( b_new_picture )
{
- HxxxParse_AnnexB_SEI( p_sei->p_buffer, p_sei->i_buffer,
- 1 /* nal header */, ParseSeiCallback, p_dec );
+ /* Parse SEI for that frame now we should have matched SPS/PPS */
+ for( block_t *p_sei = p_sys->leading.p_head; p_sei; p_sei = p_sei->p_next )
+ {
+ if( (p_sei->i_flags & BLOCK_FLAG_PRIVATE_SEI) == 0 )
+ continue;
+ HxxxParse_AnnexB_SEI( p_sei->p_buffer, p_sei->i_buffer,
+ 1 /* nal header */, ParseSeiCallback, p_dec );
+ }
+
+ if( p_sys->b_slice )
+ p_pic = OutputPicture( p_dec );
}
- if( p_sys->b_slice )
- p_pic = OutputPicture( p_dec );
+ /* */
+ p_sys->slice = newslice;
}
+ else
+ {
+ p_sys->p_active_pps = NULL;
+ /* Fragment will be discarded later on */
+ }
+ p_sys->b_slice = true;
- /* */
- p_sys->slice = newslice;
- }
- else
- {
- p_sys->p_active_pps = NULL;
- /* Fragment will be discarded later on */
- }
- p_sys->b_slice = true;
- }
- else if( i_nal_type == H264_NAL_SPS )
- {
- if( p_sys->b_slice )
- p_pic = OutputPicture( p_dec );
+ block_ChainLastAppend( &p_sys->frame.pp_append, p_frag );
+ } break;
- PutSPS( p_dec, p_frag );
- p_sys->b_new_sps = true;
+ /*** Prefix NALs ***/
- /* Do not append the SPS because we will insert it on keyframes */
- p_frag = NULL;
- }
- else if( i_nal_type == H264_NAL_PPS )
- {
- if( p_sys->b_slice )
- p_pic = OutputPicture( p_dec );
+ case H264_NAL_AU_DELIMITER:
+ if( p_sys->b_slice )
+ p_pic = OutputPicture( p_dec );
- PutPPS( p_dec, p_frag );
- p_sys->b_new_pps = true;
+ /* clear junk if no pic, we're always the first nal */
+ DropStoredNAL( p_sys );
- /* 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 );
+ p_frag->i_flags |= BLOCK_FLAG_PRIVATE_AUD;
- block_ChainLastAppend( &p_sys->pp_sei_last, p_frag );
- p_frag = NULL;
- }
- else if( i_nal_type == H264_NAL_END_OF_SEQ || i_nal_type == H264_NAL_END_OF_STREAM )
- {
- /* Early end of packetization */
- block_ChainLastAppend( &p_sys->pp_sei_last, p_frag );
- p_frag = NULL;
- /* important for still pictures/menus */
- p_sys->i_next_block_flags |= BLOCK_FLAG_END_OF_SEQUENCE;
- if( p_sys->b_slice )
- p_pic = OutputPicture( p_dec );
- }
- else if( i_nal_type == H264_NAL_AU_DELIMITER ||
- ( i_nal_type >= H264_NAL_PREFIX && i_nal_type <= H264_NAL_RESERVED_18 ) )
- {
- if( p_sys->b_slice )
- p_pic = OutputPicture( p_dec );
+ block_ChainLastAppend( &p_sys->leading.pp_append, p_frag );
+ break;
- if( i_nal_type == H264_NAL_AU_DELIMITER )
- {
- if( p_sys->p_frame && (p_sys->p_frame->i_flags & BLOCK_FLAG_PRIVATE_AUD) )
+ case H264_NAL_SPS:
+ case H264_NAL_PPS:
+ if( p_sys->b_slice )
+ p_pic = OutputPicture( p_dec );
+
+ /* Stored for insert on keyframes */
+ if( i_nal_type == H264_NAL_SPS )
{
- block_Release( p_frag );
- p_frag = NULL;
+ PutSPS( p_dec, p_frag );
+ p_sys->b_new_sps = true;
}
else
{
- p_frag->i_flags |= BLOCK_FLAG_PRIVATE_AUD;
+ PutPPS( p_dec, p_frag );
+ p_sys->b_new_pps = true;
}
- }
+ break;
+
+ case H264_NAL_SEI:
+ if( p_sys->b_slice )
+ p_pic = OutputPicture( p_dec );
+
+ p_frag->i_flags |= BLOCK_FLAG_PRIVATE_SEI;
+ block_ChainLastAppend( &p_sys->leading.pp_append, p_frag );
+ break;
+
+ case H264_NAL_SPS_EXT:
+ case H264_NAL_PREFIX: /* first slice/VCL associated data */
+ case H264_NAL_SUBSET_SPS:
+ case H264_NAL_DEPTH_PS:
+ case H264_NAL_RESERVED_17:
+ case H264_NAL_RESERVED_18:
+ if( p_sys->b_slice )
+ p_pic = OutputPicture( p_dec );
+
+ block_ChainLastAppend( &p_sys->leading.pp_append, p_frag );
+ break;
+
+ /*** Suffix NALs ***/
+
+ case H264_NAL_END_OF_SEQ:
+ case H264_NAL_END_OF_STREAM:
+ /* Early end of packetization */
+ block_ChainLastAppend( &p_sys->frame.pp_append, p_frag );
+
+ /* important for still pictures/menus */
+ p_sys->i_next_block_flags |= BLOCK_FLAG_END_OF_SEQUENCE;
+ if( p_sys->b_slice )
+ p_pic = OutputPicture( p_dec );
+ break;
+
+ case H264_NAL_SLICE_WP: // post
+ case H264_NAL_UNKNOWN:
+ case H264_NAL_FILLER_DATA:
+ case H264_NAL_SLICE_EXT:
+ case H264_NAL_SLICE_3D_EXT:
+ case H264_NAL_RESERVED_22:
+ case H264_NAL_RESERVED_23:
+ default: /* others 24..31, including unknown */
+ block_ChainLastAppend( &p_sys->frame.pp_append, p_frag );
+ break;
}
- /* Append the block */
- if( p_frag )
- block_ChainLastAppend( &p_sys->pp_frame_last, p_frag );
-
*pb_ts_used = false;
if( p_sys->i_frame_dts <= VLC_TS_INVALID &&
p_sys->i_frame_pts <= VLC_TS_INVALID && b_new_picture )
@@ -699,9 +727,9 @@ static block_t *OutputPicture( decoder_t *p_dec )
block_t *p_pic = NULL;
block_t **pp_pic_last = &p_pic;
- if( unlikely(!p_sys->p_frame) )
+ if( unlikely(!p_sys->frame.p_head) )
{
- assert( p_sys->p_frame );
+ assert( p_sys->frame.p_head );
return NULL;
}
@@ -766,36 +794,38 @@ static block_t *OutputPicture( decoder_t *p_dec )
}
/* Now rebuild NAL Sequence, inserting PPS/SPS if any */
- if( p_sys->p_frame->i_flags & BLOCK_FLAG_PRIVATE_AUD )
+ if( p_sys->frame.p_head->i_flags & BLOCK_FLAG_PRIVATE_AUD )
{
- block_t *p_au = p_sys->p_frame;
- p_sys->p_frame = p_au->p_next;
+ block_t *p_au = p_sys->frame.p_head;
+ p_sys->frame.p_head = p_au->p_next;
p_au->p_next = NULL;
- p_au->i_flags &= ~BLOCK_FLAG_PRIVATE_AUD;
block_ChainLastAppend( &pp_pic_last, p_au );
}
if( p_xpsnal )
block_ChainLastAppend( &pp_pic_last, p_xpsnal );
- if( p_sys->p_sei )
- block_ChainLastAppend( &pp_pic_last, p_sys->p_sei );
+ if( p_sys->leading.p_head )
+ block_ChainLastAppend( &pp_pic_last, p_sys->leading.p_head );
- assert( p_sys->p_frame );
- if( p_sys->p_frame )
- block_ChainLastAppend( &pp_pic_last, p_sys->p_frame );
+ assert( p_sys->frame.p_head );
+ if( p_sys->frame.p_head )
+ block_ChainLastAppend( &pp_pic_last, p_sys->frame.p_head );
/* 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_sys->frame.p_head = NULL;
+ p_sys->frame.pp_append = &p_sys->frame.p_head;
+ p_sys->leading.p_head = NULL;
+ p_sys->leading.pp_append = &p_sys->leading.p_head;
p_pic = block_ChainGather( p_pic );
if( !p_pic )
return NULL;
+ /* clear up flags gathered */
+ p_pic->i_flags &= ~BLOCK_FLAG_PRIVATE_MASK;
+
/* for PTS Fixup, interlaced fields (multiple AU/block) */
int tFOC = 0, bFOC = 0, PictureOrderCount = 0;
h264_compute_poc( p_sps, &p_sys->slice, &p_sys->pocctx, &PictureOrderCount, &tFOC, &bFOC );
More information about the vlc-commits
mailing list