Files
ANSCORE/MediaClient/rtp/h264_util.cpp

236 lines
4.6 KiB
C++

/***************************************************************************************
*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
*
* Redistribution and use in binary forms, with or without modification, are permitted.
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*
****************************************************************************************/
#include "sys_inc.h"
#include "bs.h"
#include "h264.h"
#include "h264_util.h"
void h264_parser_init(h264_t * h)
{
h->i_width = 0;
h->i_height = 0;
h->b_key = 0;
h->i_nal_type = -1;
h->i_ref_idc = -1;
h->i_idr_pic_id = -1;
h->i_frame_num = -1;
h->i_log2_max_frame_num = 0;
h->i_poc = -1;
h->i_poc_type = -1;
}
void h264_parser_parse(h264_t * h, nal_t * nal, int * pb_nal_start)
{
bs_t s;
*pb_nal_start = 0;
if (nal->i_type == H264_NAL_SPS || nal->i_type == H264_NAL_PPS)
{
*pb_nal_start = 1;
}
bs_init(&s, nal->p_payload, nal->i_payload);
if (nal->i_type == H264_NAL_SPS)
{
int i_tmp;
i_tmp = bs_read(&s, 8);
bs_skip(&s, 1+1+1 + 5 + 8);
/* sps id */
bs_read_ue(&s);
if (i_tmp >= 100)
{
bs_read_ue(&s); // chroma_format_idc
bs_read_ue(&s); // bit_depth_luma_minus8
bs_read_ue(&s); // bit_depth_chroma_minus8
bs_skip(&s, 1); // qpprime_y_zero_transform_bypass_flag
if (bs_read(&s, 1)) // seq_scaling_matrix_present_flag
{
int i, j;
for (i = 0; i < 8; i++)
{
if (bs_read(&s, 1)) // seq_scaling_list_present_flag[i]
{
uint8 i_tmp = 8;
for (j = 0; j < (i<6?16:64); j++)
{
i_tmp += bs_read_se(&s);
if (i_tmp == 0)
{
break;
}
}
}
}
}
}
/* Skip i_log2_max_frame_num */
h->i_log2_max_frame_num = bs_read_ue(&s) + 4;
/* Read poc_type */
h->i_poc_type = bs_read_ue(&s);
if (h->i_poc_type == 0)
{
h->i_log2_max_poc_lsb = bs_read_ue(&s) + 4;
}
else if (h->i_poc_type == 1)
{
int i_cycle;
/* skip b_delta_pic_order_always_zero */
bs_skip(&s, 1);
/* skip i_offset_for_non_ref_pic */
bs_read_se(&s);
/* skip i_offset_for_top_to_bottom_field */
bs_read_se(&s);
/* read i_num_ref_frames_in_poc_cycle */
i_cycle = bs_read_ue(&s);
if (i_cycle > 256)
{
i_cycle = 256;
}
while (i_cycle > 0)
{
/* skip i_offset_for_ref_frame */
bs_read_se(&s);
i_cycle--;
}
}
/* i_num_ref_frames */
bs_read_ue(&s);
/* b_gaps_in_frame_num_value_allowed */
bs_skip(&s, 1);
/* Read size */
h->i_width = 16 * (bs_read_ue( &s ) + 1);
h->i_height = 16 * (bs_read_ue( &s ) + 1);
/* b_frame_mbs_only */
i_tmp = bs_read(&s, 1);
if (i_tmp == 0)
{
bs_skip(&s, 1);
}
/* b_direct8x8_inference */
bs_skip(&s, 1);
/* crop ? */
i_tmp = bs_read(&s, 1);
if (i_tmp)
{
/* left */
h->i_width -= 2 * bs_read_ue(&s);
/* right */
h->i_width -= 2 * bs_read_ue(&s);
/* top */
h->i_height -= 2 * bs_read_ue(&s);
/* bottom */
h->i_height -= 2 * bs_read_ue(&s);
}
/* vui: ignored */
}
else if (nal->i_type >= H264_NAL_SLICE && nal->i_type <= H264_NAL_IDR)
{
int i_tmp;
/* i_first_mb */
bs_read_ue(&s);
/* picture type */
switch (bs_read_ue(&s))
{
case 0: case 5: /* P */
case 1: case 6: /* B */
case 3: case 8: /* SP */
h->b_key = 0;
break;
case 2: case 7: /* I */
case 4: case 9: /* SI */
h->b_key = (nal->i_type == H264_NAL_IDR);
break;
}
/* pps id */
bs_read_ue(&s);
/* frame num */
i_tmp = bs_read(&s, h->i_log2_max_frame_num);
if (i_tmp != h->i_frame_num)
{
*pb_nal_start = 1;
}
h->i_frame_num = i_tmp;
if (nal->i_type == H264_NAL_IDR)
{
i_tmp = bs_read_ue(&s);
if (h->i_nal_type == H264_NAL_IDR && h->i_idr_pic_id != i_tmp)
{
*pb_nal_start = 1;
}
h->i_idr_pic_id = i_tmp;
}
if (h->i_poc_type == 0)
{
i_tmp = bs_read(&s, h->i_log2_max_poc_lsb);
if (i_tmp != h->i_poc)
{
*pb_nal_start = 1;
}
h->i_poc = i_tmp;
}
}
h->i_nal_type = nal->i_type;
h->i_ref_idc = nal->i_ref_idc;
}