[vlc-commits] packetizer: h264: extract max reference frames value

Francois Cartegnie git at videolan.org
Fri Jan 20 11:22:10 CET 2017


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Sat Jun 11 15:34:18 2016 +0200| [5b55cbcd6f3aa3ec841537952433aad4176823eb] | committer: Thomas Guillem

packetizer: h264: extract max reference frames value

Signed-off-by: Thomas Guillem <thomas at gllm.fr>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=5b55cbcd6f3aa3ec841537952433aad4176823eb
---

 modules/packetizer/h264_nal.c | 114 ++++++++++++++++++++++++++++++++++++++++++
 modules/packetizer/h264_nal.h |   3 ++
 2 files changed, 117 insertions(+)

diff --git a/modules/packetizer/h264_nal.c b/modules/packetizer/h264_nal.c
index 1b0a902..9bdc866 100644
--- a/modules/packetizer/h264_nal.c
+++ b/modules/packetizer/h264_nal.c
@@ -29,6 +29,57 @@
 #include <vlc_es.h>
 #include <limits.h>
 
+/* H264 Level limits from Table A-1 */
+typedef struct
+{
+    unsigned i_max_dpb_mbs;
+} h264_level_limits_t;
+
+enum h264_level_numbers_e
+{
+    H264_LEVEL_NUMBER_1_B = 9, /* special level not following the 10x rule */
+    H264_LEVEL_NUMBER_1   = 10,
+    H264_LEVEL_NUMBER_1_1 = 11,
+    H264_LEVEL_NUMBER_1_2 = 12,
+    H264_LEVEL_NUMBER_1_3 = 13,
+    H264_LEVEL_NUMBER_2   = 20,
+    H264_LEVEL_NUMBER_2_1 = 21,
+    H264_LEVEL_NUMBER_2_2 = 22,
+    H264_LEVEL_NUMBER_3   = 30,
+    H264_LEVEL_NUMBER_3_1 = 31,
+    H264_LEVEL_NUMBER_3_2 = 32,
+    H264_LEVEL_NUMBER_4   = 40,
+    H264_LEVEL_NUMBER_4_1 = 41,
+    H264_LEVEL_NUMBER_4_2 = 42,
+    H264_LEVEL_NUMBER_5   = 50,
+    H264_LEVEL_NUMBER_5_1 = 51,
+    H264_LEVEL_NUMBER_5_2 = 52,
+};
+
+const struct
+{
+    const uint16_t i_level;
+    const h264_level_limits_t limits;
+} h264_levels_limits[] = {
+    { H264_LEVEL_NUMBER_1_B, { 396 } },
+    { H264_LEVEL_NUMBER_1,   { 396 } },
+    { H264_LEVEL_NUMBER_1_1, { 900 } },
+    { H264_LEVEL_NUMBER_1_2, { 2376 } },
+    { H264_LEVEL_NUMBER_1_3, { 2376 } },
+    { H264_LEVEL_NUMBER_2,   { 2376 } },
+    { H264_LEVEL_NUMBER_2_1, { 4752 } },
+    { H264_LEVEL_NUMBER_2_2, { 8100 } },
+    { H264_LEVEL_NUMBER_3,   { 8100 } },
+    { H264_LEVEL_NUMBER_3_1, { 18000 } },
+    { H264_LEVEL_NUMBER_3_2, { 20480 } },
+    { H264_LEVEL_NUMBER_4,   { 32768 } },
+    { H264_LEVEL_NUMBER_4_1, { 32768 } },
+    { H264_LEVEL_NUMBER_4_2, { 34816 } },
+    { H264_LEVEL_NUMBER_5,   { 110400 } },
+    { H264_LEVEL_NUMBER_5_1, { 184320 } },
+    { H264_LEVEL_NUMBER_5_2, { 184320 } },
+};
+
 /*
  * For avcC specification, see ISO/IEC 14496-15,
  * For Annex B specification, see ISO/IEC 14496-10
@@ -581,6 +632,69 @@ block_t *h264_AnnexB_NAL_to_avcC( uint8_t i_nal_length_size,
                              p_pps_buf, i_pps_size );
 }
 
+static const h264_level_limits_t * h264_get_level_limits( const h264_sequence_parameter_set_t *p_sps )
+{
+    uint16_t i_level_number = p_sps->i_level;
+    if( i_level_number == H264_LEVEL_NUMBER_1_1 &&
+       (p_sps->i_constraint_set_flags & H264_CONSTRAINT_SET_FLAG(3)) )
+    {
+        i_level_number = H264_LEVEL_NUMBER_1_B;
+    }
+
+    for( size_t i=0; i< ARRAY_SIZE(h264_levels_limits); i++ )
+        if( h264_levels_limits[i].i_level == i_level_number )
+            return & h264_levels_limits[i].limits;
+
+    return NULL;
+}
+
+static uint8_t h264_get_max_dpb_frames( const h264_sequence_parameter_set_t *p_sps )
+{
+    const h264_level_limits_t *limits = h264_get_level_limits( p_sps );
+    if( limits )
+    {
+        unsigned i_frame_height_in_mbs = ( p_sps->pic_height_in_map_units_minus1 + 1 ) *
+                                         ( 2 - p_sps->frame_mbs_only_flag );
+        unsigned i_den = ( p_sps->pic_width_in_mbs_minus1 + 1 ) * i_frame_height_in_mbs;
+        uint8_t i_max_dpb_frames = limits->i_max_dpb_mbs / i_den;
+        if( i_max_dpb_frames < 16 )
+            return i_max_dpb_frames;
+    }
+    return 16;
+}
+
+bool h264_get_dpb_values( const h264_sequence_parameter_set_t *p_sps,
+                          uint8_t *pi_depth, unsigned *pi_delay )
+{
+    uint8_t i_max_num_reorder_frames = p_sps->vui.i_max_num_reorder_frames;
+    if( !p_sps->vui.b_bitstream_restriction_flag )
+    {
+        switch( p_sps->i_profile ) /* E-2.1 */
+        {
+            case PROFILE_H264_CAVLC_INTRA:
+            case PROFILE_H264_SVC_HIGH:
+            case PROFILE_H264_HIGH:
+            case PROFILE_H264_HIGH_10:
+            case PROFILE_H264_HIGH_422:
+            case PROFILE_H264_HIGH_444_PREDICTIVE:
+                if( p_sps->i_constraint_set_flags & H264_CONSTRAINT_SET_FLAG(3) )
+                {
+                    i_max_num_reorder_frames = 0; /* all IDR */
+                    break;
+                }
+                // ft
+            default:
+                i_max_num_reorder_frames = h264_get_max_dpb_frames( p_sps );
+                break;
+        }
+    }
+
+    *pi_depth = i_max_num_reorder_frames;
+    *pi_delay = 0;
+
+    return true;
+}
+
 bool h264_get_picture_size( const h264_sequence_parameter_set_t *p_sps, unsigned *p_w, unsigned *p_h,
                             unsigned *p_vw, unsigned *p_vh )
 {
diff --git a/modules/packetizer/h264_nal.h b/modules/packetizer/h264_nal.h
index f10d96c..b5776c2 100644
--- a/modules/packetizer/h264_nal.h
+++ b/modules/packetizer/h264_nal.h
@@ -177,6 +177,9 @@ block_t *h264_NAL_to_avcC( uint8_t i_nal_length_size,
 uint8_t * h264_avcC_to_AnnexB_NAL( const uint8_t *p_buf, size_t i_buf,
                                    size_t *pi_result, uint8_t *pi_nal_length_size );
 
+bool h264_get_dpb_values( const h264_sequence_parameter_set_t *,
+                          uint8_t *pi_depth, unsigned *pi_delay );
+
 bool h264_get_picture_size( const h264_sequence_parameter_set_t *, unsigned *p_w, unsigned *p_h,
                             unsigned *p_vw, unsigned *p_vh );
 bool h264_get_chroma_luma( const h264_sequence_parameter_set_t *, uint8_t *pi_chroma_format,



More information about the vlc-commits mailing list