[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