236 lines
4.6 KiB
C++
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;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|