vlc | branch: master | Thomas Guillem <tho...@gllm.fr> | Thu Apr 23 18:22:51 2015 +0200| [f815b9e52a34d27271b0cae71a25c277be6f4a0b] | committer: Thomas Guillem
h264_nal: add h264_get_spspps It fetches the SPS and PPS pointers from an Annex B buffer. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f815b9e52a34d27271b0cae71a25c277be6f4a0b --- modules/packetizer/h264_nal.c | 68 +++++++++++++++++++++++++++++++++++++++++ modules/packetizer/h264_nal.h | 6 ++++ 2 files changed, 74 insertions(+) diff --git a/modules/packetizer/h264_nal.c b/modules/packetizer/h264_nal.c index 2a375c2..9e7eb70 100644 --- a/modules/packetizer/h264_nal.c +++ b/modules/packetizer/h264_nal.c @@ -22,6 +22,8 @@ #include <limits.h> +static const uint8_t annexb_startcode[] = { 0x00, 0x00, 0x00, 0x01 }; + int convert_sps_pps( decoder_t *p_dec, const uint8_t *p_buf, uint32_t i_buf_size, uint8_t *p_out_buf, uint32_t i_out_buf_size, uint32_t *p_sps_pps_size, @@ -138,6 +140,72 @@ void convert_h264_to_annexb( uint8_t *p_buf, uint32_t i_len, } } +int h264_get_spspps( uint8_t *p_buf, size_t i_buf, + uint8_t **pp_sps, size_t *p_sps_size, + uint8_t **pp_pps, size_t *p_pps_size ) +{ + uint8_t *p_sps = NULL, *p_pps = NULL; + size_t i_sps_size = 0, i_pps_size = 0; + int i_nal_type = NAL_UNKNOWN; + + while( true ) + { + int i_inc = 0; + + if( i_buf > 5 && memcmp( p_buf, annexb_startcode, 4 ) == 0 ) + { + i_nal_type = p_buf[4] & 0x1F; + + /* size of startcode + nal_type */ + i_inc = 5; + + /* pointer to the beginning of the sps/pps */ + if( i_nal_type == NAL_SPS && !p_sps ) + p_sps = p_buf; + if( i_nal_type == NAL_PPS && !p_pps ) + p_pps = p_buf; + } else { + i_inc = 1; + } + + /* cf. 7.4.1.2.3 */ + if( i_nal_type == NAL_UNKNOWN || i_nal_type > 18 + || (i_nal_type >= 10 && i_nal_type <= 12)) + return -1; + + /* update SPS/PPS size if the new NAL is different than the last one */ + if( !i_sps_size && p_sps && i_nal_type != NAL_SPS ) + i_sps_size = p_buf - p_sps; + if( !i_pps_size && p_pps && i_nal_type != NAL_PPS ) + i_pps_size = p_buf - p_pps; + + /* SPS/PPS are before the slices */ + if (i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR ) + break; + + i_buf -= i_inc; + p_buf += i_inc; + + if( i_buf == 0 ) + { + /* update SPS/PPS size if we reach the end of the buffer */ + if( !i_sps_size && p_sps ) + i_sps_size = p_buf - p_sps; + if( !i_pps_size && p_pps ) + i_pps_size = p_buf - p_pps; + break; + } + } + if( ( !p_sps || !i_sps_size ) && ( !p_pps || !i_pps_size ) ) + return -1; + *pp_sps = p_sps; + *p_sps_size = i_sps_size; + *pp_pps = p_pps; + *p_pps_size = i_pps_size; + + return 0; +} + bool h264_get_profile_level(const es_format_t *p_fmt, size_t *p_profile, size_t *p_level, size_t *p_nal_size) { diff --git a/modules/packetizer/h264_nal.h b/modules/packetizer/h264_nal.h index 6358fe6..bc346cf 100644 --- a/modules/packetizer/h264_nal.h +++ b/modules/packetizer/h264_nal.h @@ -82,6 +82,12 @@ void convert_h264_to_annexb( uint8_t *p_buf, uint32_t i_len, size_t i_nal_size, struct H264ConvertState *state ); +/* Get the SPS/PPS pointers from an Annex B buffer + * Returns 0 if a SPS and/or a PPS is found */ +int h264_get_spspps( uint8_t *p_buf, size_t i_buf, + uint8_t **pp_sps, size_t *p_sps_size, + uint8_t **pp_pps, size_t *p_pps_size ); + /* Get level and Profile */ bool h264_get_profile_level(const es_format_t *p_fmt, size_t *p_profile, size_t *p_level, size_t *p_nal_size); _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits