[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