Commit b3494ff0 authored by François Cartegnie's avatar François Cartegnie 🤞

h264_nal: add h264_get_picture_size

Compute picture size including crop area
parent 90335413
......@@ -282,11 +282,9 @@ static int H264SetCSD(decoder_t *p_dec, void *p_buf, size_t i_size,
if( !p_sps )
return VLC_EGENERIC;
if( !p_sps->i_width || !p_sps->i_height )
{
h264_release_sps( p_sps );
return VLC_EGENERIC;
}
unsigned vsize[4];
(void) h264_get_picture_size( p_sps, &vsize[0], &vsize[1], &vsize[2], &vsize[3] );
/* FIXME: what to do with visible width/height ? */
if (i_sps_size)
{
......@@ -304,8 +302,8 @@ static int H264SetCSD(decoder_t *p_dec, void *p_buf, size_t i_size,
/* Compare the SPS PPS with the old one */
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",
p_sps->i_id, p_sps->i_width, p_sps->i_height,
msg_Warn(p_dec, "New SPS/PPS found, id: %d size: %ux%u sps: %d pps: %d",
p_sps->i_id, vsize[0], vsize[1],
i_sps_size, i_pps_size);
/* In most use cases, p_sys->p_csd[0] contains a SPS, and
......@@ -317,11 +315,11 @@ static int H264SetCSD(decoder_t *p_dec, void *p_buf, size_t i_size,
}
if (p_size_changed)
*p_size_changed = (p_sps->i_width != p_sys->u.video.i_width
|| p_sps->i_height != p_sys->u.video.i_height);
*p_size_changed = (vsize[0] != p_sys->u.video.i_width
|| vsize[1] != 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;
p_sys->u.video.i_width = vsize[0];
p_sys->u.video.i_height = vsize[1];
h264_release_sps( p_sps );
......
......@@ -289,8 +289,8 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
int i_video_width = 0;
int i_video_height = 0;
unsigned i_video_width = 0, i_video_visible_width = 0;
unsigned i_video_height = 0, i_video_visible_height = 0;
int i_sar_den = 0;
int i_sar_num = 0;
......@@ -365,8 +365,11 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
/* this data is more trust-worthy than what we receive
* from the demuxer, so we will use it to over-write
* the current values */
i_video_width = p_sps_data->i_width;
i_video_height = p_sps_data->i_height;
(void)
h264_get_picture_size( p_sps_data, &i_video_width,
&i_video_height,
&i_video_visible_width,
&i_video_visible_height );
i_sar_den = p_sps_data->vui.i_sar_den;
i_sar_num = p_sps_data->vui.i_sar_num;
......@@ -434,10 +437,15 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
/* fallback on the demuxer if we don't have better info */
/* FIXME ?: can't we skip temp storage using directly fmt_out */
if (i_video_width == 0)
i_video_width = p_dec->fmt_in.video.i_width;
if (i_video_height == 0)
i_video_height = p_dec->fmt_in.video.i_height;
if(!i_video_visible_width)
i_video_visible_width = p_dec->fmt_in.video.i_visible_width;
if(!i_video_visible_height)
i_video_visible_height = p_dec->fmt_in.video.i_visible_height;
if (i_sar_num == 0)
i_sar_num = p_dec->fmt_in.video.i_sar_num ? p_dec->fmt_in.video.i_sar_num : 1;
if (i_sar_den == 0)
......@@ -593,6 +601,8 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
p_dec->fmt_out.video.i_width = i_video_width;
p_dec->fmt_out.video.i_height = i_video_height;
p_dec->fmt_out.video.i_visible_width = i_video_visible_width;
p_dec->fmt_out.video.i_visible_height = i_video_visible_height;
p_dec->fmt_out.video.i_sar_den = i_sar_den;
p_dec->fmt_out.video.i_sar_num = i_sar_num;
......
......@@ -721,8 +721,12 @@ static void PutSPS( decoder_t *p_dec, block_t *p_frag )
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;
(void) h264_get_picture_size( p_sps, &p_dec->fmt_out.video.i_width,
&p_dec->fmt_out.video.i_height,
&p_dec->fmt_out.video.i_visible_width,
&p_dec->fmt_out.video.i_visible_height );
if( p_sps->vui.i_sar_num != 0 && p_sps->vui.i_sar_den != 0 )
{
p_dec->fmt_out.video.i_sar_num = p_sps->vui.i_sar_num;
......@@ -730,7 +734,7 @@ static void PutSPS( decoder_t *p_dec, block_t *p_frag )
}
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->b_frame_mbs_only = p_sps->frame_mbs_only_flag;
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;
......
......@@ -510,31 +510,24 @@ static bool h264_parse_sequence_parameter_set_rbsp( bs_t *p_bs,
bs_skip( p_bs, 1 );
/* Read size */
p_sps->i_width = 16 * ( bs_read_ue( p_bs ) + 1 );
p_sps->i_height = 16 * ( bs_read_ue( p_bs ) + 1 );
p_sps->pic_width_in_mbs_minus1 = bs_read_ue( p_bs );
p_sps->pic_height_in_map_units_minus1 = bs_read_ue( p_bs );
/* b_frame_mbs_only */
p_sps->b_frame_mbs_only = bs_read( p_bs, 1 );
p_sps->i_height *= ( 2 - p_sps->b_frame_mbs_only );
if( p_sps->b_frame_mbs_only == 0 )
{
p_sps->frame_mbs_only_flag = bs_read( p_bs, 1 );
if( !p_sps->frame_mbs_only_flag )
bs_skip( p_bs, 1 );
}
/* b_direct8x8_inference */
bs_skip( p_bs, 1 );
/* crop */
i_tmp = bs_read( p_bs, 1 );
if( i_tmp )
if( bs_read1( p_bs ) ) /* frame_cropping_flag */
{
/* left */
bs_read_ue( p_bs );
/* right */
bs_read_ue( p_bs );
/* top */
bs_read_ue( p_bs );
/* bottom */
bs_read_ue( p_bs );
p_sps->frame_crop.left_offset = bs_read_ue( p_bs );
p_sps->frame_crop.right_offset = bs_read_ue( p_bs );
p_sps->frame_crop.right_offset = bs_read_ue( p_bs );
p_sps->frame_crop.bottom_offset = bs_read_ue( p_bs );
}
/* vui */
......@@ -749,6 +742,19 @@ block_t *h264_AnnexB_NAL_to_avcC( uint8_t i_nal_length_size,
return bo.b;
}
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 )
{
*p_w = 16 * p_sps->pic_width_in_mbs_minus1 + 16;
*p_h = 16 * p_sps->pic_height_in_map_units_minus1 + 16;
*p_h *= ( 2 - p_sps->frame_mbs_only_flag );
*p_vw = *p_w - p_sps->frame_crop.left_offset - p_sps->frame_crop.right_offset;
*p_vh = *p_h - p_sps->frame_crop.bottom_offset - p_sps->frame_crop.top_offset;
return true;
}
bool h264_get_profile_level(const es_format_t *p_fmt, size_t *p_profile,
size_t *p_level, uint8_t *pi_nal_length_size)
{
......
......@@ -85,9 +85,17 @@ struct h264_sequence_parameter_set_t
{
int i_id;
int i_profile, i_profile_compatibility, i_level;
int i_width, i_height;
uint32_t pic_width_in_mbs_minus1;
uint32_t pic_height_in_map_units_minus1;
struct
{
uint32_t left_offset;
uint32_t right_offset;
uint32_t top_offset;
uint32_t bottom_offset;
} frame_crop;
uint8_t frame_mbs_only_flag;
int i_log2_max_frame_num;
int b_frame_mbs_only;
int i_pic_order_cnt_type;
int i_delta_pic_order_always_zero_flag;
int i_log2_max_pic_order_cnt_lsb;
......@@ -151,6 +159,8 @@ block_t *h264_AnnexB_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_picture_size( const h264_sequence_parameter_set_t *, unsigned *p_w, unsigned *p_h,
unsigned *p_vw, unsigned *p_vh );
/* Get level and Profile */
bool h264_get_profile_level(const es_format_t *p_fmt, size_t *p_profile,
size_t *p_level, uint8_t *p_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