Commit 0da5762a authored by Francois Cartegnie's avatar Francois Cartegnie

packetizer: h264: update sps/pps parsing

parent 5f685c9f
......@@ -419,9 +419,9 @@ libiomx_plugin_la_LIBADD = $(libomxil_plugin_la_LIBADD)
libmediacodec_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil
libmediacodec_plugin_la_SOURCES = codec/omxil/mediacodec.c codec/omxil/mediacodec.h \
codec/omxil/mediacodec_jni.c codec/omxil/mediacodec_ndk.c codec/omxil/utils.c \
video_chroma/copy.c
video_output/android/utils.c video_output/android/utils.h
packetizer/h264_nal.c packetizer/h264_nal.h
video_chroma/copy.c \
video_output/android/utils.c video_output/android/utils.h \
packetizer/hxxx_nal.h packetizer/h264_nal.c packetizer/h264_nal.h \
packetizer/hevc_nal.c packetizer/hevc_nal.h
codec_LTLIBRARIES += $(LTLIBomxil) $(LTLIBomxil_vout)
......
......@@ -44,6 +44,7 @@
#include "mediacodec.h"
#include "../../packetizer/h264_nal.h"
#include "../../packetizer/hevc_nal.h"
#include "../../packetizer/hxxx_nal.h"
#include <OMX_Core.h>
#include <OMX_Component.h>
#include "omxil_utils.h"
......@@ -262,19 +263,31 @@ static int H264SetCSD(decoder_t *p_dec, void *p_buf, size_t i_size,
bool *p_size_changed)
{
decoder_sys_t *p_sys = p_dec->p_sys;
struct h264_nal_sps sps;
uint8_t *p_sps_buf = NULL, *p_pps_buf = NULL;
size_t i_sps_size = 0, i_pps_size = 0;
/* Check if p_buf contains a valid SPS PPS */
if (h264_get_spspps(p_buf, i_size, &p_sps_buf, &i_sps_size,
&p_pps_buf, &i_pps_size) == 0
&& h264_parse_sps(p_sps_buf, i_sps_size, &sps) == 0
&& sps.i_width && sps.i_height)
&p_pps_buf, &i_pps_size) == 0 )
{
struct csd csd[2];
int i_csd_count = 0;
const uint8_t *p_buffer = p_sps_buf;
size_t i_buffer = i_sps_size;
if(!hxxx_strip_AnnexB_startcode(&p_buffer, &i_buffer))
return VLC_EGENERIC;
h264_sequence_parameter_set_t *p_sps = h264_decode_sps(p_buffer, i_buffer, true);
if( !p_sps )
return VLC_EGENERIC;
if( !p_sps->i_width || !p_sps->i_height )
{
h264_release_sps( p_sps );
return VLC_EGENERIC;
}
if (i_sps_size)
{
csd[i_csd_count].p_buf = p_sps_buf;
......@@ -292,23 +305,32 @@ static int H264SetCSD(decoder_t *p_dec, void *p_buf, size_t i_size,
if (!CSDCmp(p_dec, csd, i_csd_count))
{
msg_Warn(p_dec, "New SPS/PPS found, id: %d size: %dx%d sps: %d pps: %d",
sps.i_id, sps.i_width, sps.i_height,
p_sps->i_id, p_sps->i_width, p_sps->i_height,
i_sps_size, i_pps_size);
/* In most use cases, p_sys->p_csd[0] contains a SPS, and
* p_sys->p_csd[1] contains a PPS */
if (CSDDup(p_dec, csd, i_csd_count))
{
h264_release_sps( p_sps );
return VLC_ENOMEM;
}
if (p_size_changed)
*p_size_changed = (sps.i_width != p_sys->u.video.i_width
|| sps.i_height != p_sys->u.video.i_height);
*p_size_changed = (p_sps->i_width != p_sys->u.video.i_width
|| p_sps->i_height != p_sys->u.video.i_height);
p_sys->u.video.i_width = p_sps->i_width;
p_sys->u.video.i_height = p_sps->i_height;
h264_release_sps( p_sps );
p_sys->u.video.i_width = sps.i_width;
p_sys->u.video.i_height = sps.i_height;
return VLC_SUCCESS;
}
h264_release_sps( p_sps );
}
return VLC_EGENERIC;
}
......
......@@ -704,74 +704,89 @@ static block_t *OutputPicture( decoder_t *p_dec )
static void PutSPS( decoder_t *p_dec, block_t *p_frag )
{
decoder_sys_t *p_sys = p_dec->p_sys;
struct h264_nal_sps sps;
if( h264_parse_sps( p_frag->p_buffer, p_frag->i_buffer, &sps ) != 0 )
const uint8_t *p_buffer = p_frag->p_buffer;
size_t i_buffer = p_frag->i_buffer;
if( !hxxx_strip_AnnexB_startcode( &p_buffer, &i_buffer ) )
return;
h264_sequence_parameter_set_t *p_sps = h264_decode_sps( p_buffer, i_buffer, true );
if( !p_sps )
{
msg_Warn( p_dec, "invalid SPS (sps_id=%d)", sps.i_id );
msg_Warn( p_dec, "invalid SPS (sps_id=%d)", p_sps->i_id );
block_Release( p_frag );
return;
}
p_dec->fmt_out.i_profile = sps.i_profile;
p_dec->fmt_out.i_level = sps.i_level;
p_dec->fmt_out.video.i_width = sps.i_width;
p_dec->fmt_out.video.i_height = sps.i_height;
if( sps.vui.i_sar_num != 0 && sps.vui.i_sar_den != 0 )
p_dec->fmt_out.i_profile = p_sps->i_profile;
p_dec->fmt_out.i_level = p_sps->i_level;
p_dec->fmt_out.video.i_width = p_sps->i_width;
p_dec->fmt_out.video.i_height = p_sps->i_height;
if( p_sps->vui.i_sar_num != 0 && p_sps->vui.i_sar_den != 0 )
{
p_dec->fmt_out.video.i_sar_num = sps.vui.i_sar_num;
p_dec->fmt_out.video.i_sar_den = sps.vui.i_sar_den;
p_dec->fmt_out.video.i_sar_num = p_sps->vui.i_sar_num;
p_dec->fmt_out.video.i_sar_den = p_sps->vui.i_sar_den;
}
p_sys->i_log2_max_frame_num = sps.i_log2_max_frame_num;
p_sys->b_frame_mbs_only = sps.b_frame_mbs_only;
p_sys->i_pic_order_cnt_type = sps.i_pic_order_cnt_type;
p_sys->i_delta_pic_order_always_zero_flag = sps.i_delta_pic_order_always_zero_flag;
p_sys->i_log2_max_pic_order_cnt_lsb = sps.i_log2_max_pic_order_cnt_lsb;
p_sys->i_log2_max_frame_num = p_sps->i_log2_max_frame_num;
p_sys->b_frame_mbs_only = p_sps->b_frame_mbs_only;
p_sys->i_pic_order_cnt_type = p_sps->i_pic_order_cnt_type;
p_sys->i_delta_pic_order_always_zero_flag = p_sps->i_delta_pic_order_always_zero_flag;
p_sys->i_log2_max_pic_order_cnt_lsb = p_sps->i_log2_max_pic_order_cnt_lsb;
if( sps.vui.b_valid )
if( p_sps->vui.b_valid )
{
p_sys->b_timing_info_present_flag = sps.vui.b_timing_info_present_flag;
p_sys->i_num_units_in_tick = sps.vui.i_num_units_in_tick;
p_sys->i_time_scale = sps.vui.i_time_scale;
p_sys->b_fixed_frame_rate = sps.vui.b_fixed_frame_rate;
p_sys->b_pic_struct_present_flag = sps.vui.b_pic_struct_present_flag;
p_sys->b_cpb_dpb_delays_present_flag = sps.vui.b_cpb_dpb_delays_present_flag;
p_sys->i_cpb_removal_delay_length_minus1 = sps.vui.i_cpb_removal_delay_length_minus1;
p_sys->i_dpb_output_delay_length_minus1 = sps.vui.i_dpb_output_delay_length_minus1;
p_sys->b_timing_info_present_flag = p_sps->vui.b_timing_info_present_flag;
p_sys->i_num_units_in_tick = p_sps->vui.i_num_units_in_tick;
p_sys->i_time_scale = p_sps->vui.i_time_scale;
p_sys->b_fixed_frame_rate = p_sps->vui.b_fixed_frame_rate;
p_sys->b_pic_struct_present_flag = p_sps->vui.b_pic_struct_present_flag;
p_sys->b_cpb_dpb_delays_present_flag = p_sps->vui.b_cpb_dpb_delays_present_flag;
p_sys->i_cpb_removal_delay_length_minus1 = p_sps->vui.i_cpb_removal_delay_length_minus1;
p_sys->i_dpb_output_delay_length_minus1 = p_sps->vui.i_dpb_output_delay_length_minus1;
}
/* We have a new SPS */
if( !p_sys->b_sps )
msg_Dbg( p_dec, "found NAL_SPS (sps_id=%d)", sps.i_id );
msg_Dbg( p_dec, "found NAL_SPS (sps_id=%d)", p_sps->i_id );
p_sys->b_sps = true;
if( p_sys->pp_sps[sps.i_id] )
block_Release( p_sys->pp_sps[sps.i_id] );
p_sys->pp_sps[sps.i_id] = p_frag;
if( p_sys->pp_sps[p_sps->i_id] )
block_Release( p_sys->pp_sps[p_sps->i_id] );
p_sys->pp_sps[p_sps->i_id] = p_frag;
h264_release_sps( p_sps );
}
static void PutPPS( decoder_t *p_dec, block_t *p_frag )
{
decoder_sys_t *p_sys = p_dec->p_sys;
struct h264_nal_pps pps;
const uint8_t *p_buffer = p_frag->p_buffer;
size_t i_buffer = p_frag->i_buffer;
if( h264_parse_pps( p_frag->p_buffer, p_frag->i_buffer, &pps ) != 0 )
if( !hxxx_strip_AnnexB_startcode( &p_buffer, &i_buffer ) )
return;
h264_picture_parameter_set_t *p_pps = h264_decode_pps( p_buffer, i_buffer, true );
if( !p_pps )
{
msg_Warn( p_dec, "invalid PPS (pps_id=%d sps_id=%d)", pps.i_id, pps.i_sps_id );
msg_Warn( p_dec, "invalid PPS (pps_id=%d sps_id=%d)", p_pps->i_id, p_pps->i_sps_id );
block_Release( p_frag );
return;
}
p_sys->i_pic_order_present_flag = pps.i_pic_order_present_flag;
p_sys->i_pic_order_present_flag = p_pps->i_pic_order_present_flag;
/* We have a new PPS */
if( !p_sys->b_pps )
msg_Dbg( p_dec, "found NAL_PPS (pps_id=%d sps_id=%d)", pps.i_id, pps.i_sps_id );
msg_Dbg( p_dec, "found NAL_PPS (pps_id=%d sps_id=%d)", p_pps->i_id, p_pps->i_sps_id );
p_sys->b_pps = true;
if( p_sys->pp_pps[pps.i_id] )
block_Release( p_sys->pp_pps[pps.i_id] );
p_sys->pp_pps[pps.i_id] = p_frag;
if( p_sys->pp_pps[p_pps->i_id] )
block_Release( p_sys->pp_pps[p_pps->i_id] );
p_sys->pp_pps[p_pps->i_id] = p_frag;
h264_release_pps( p_pps );
}
static bool ParseSlice( decoder_t *p_dec, bool *pb_new_picture, slice_t *p_slice,
......
This diff is collapsed.
......@@ -72,7 +72,16 @@ enum h264_sei_type_e
H264_SEI_RECOVERY_POINT = 6
};
struct h264_nal_sps
typedef struct h264_sequence_parameter_set_t h264_sequence_parameter_set_t;
typedef struct h264_picture_parameter_set_t h264_picture_parameter_set_t;
h264_sequence_parameter_set_t * h264_decode_sps( const uint8_t *, size_t, bool );
h264_picture_parameter_set_t * h264_decode_pps( const uint8_t *, size_t, bool );
void h264_release_sps( h264_sequence_parameter_set_t * );
void h264_release_pps( h264_picture_parameter_set_t * );
struct h264_sequence_parameter_set_t
{
int i_id;
int i_profile, i_profile_compatibility, i_level;
......@@ -97,7 +106,7 @@ struct h264_nal_sps
} vui;
};
struct h264_nal_pps
struct h264_picture_parameter_set_t
{
int i_id;
int i_sps_id;
......@@ -130,16 +139,6 @@ 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 );
/* Parse a SPS into the struct nal_sps
* Returns 0 in case of success */
int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
struct h264_nal_sps *p_sps );
/* Parse a PPS into the struct nal_pps
* Returns 0 in case of success */
int h264_parse_pps( const uint8_t *p_pps_buf, int i_pps_size,
struct h264_nal_pps *p_pps );
/* Create a AVCDecoderConfigurationRecord from SPS/PPS
* Returns a valid block_t on success, must be freed with block_Release */
block_t *h264_AnnexB_NAL_to_avcC( uint8_t i_nal_length_size,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment