first commit
This commit is contained in:
219
GB28181Device/rtp/h265_util.cpp
Normal file
219
GB28181Device/rtp/h265_util.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* 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-2022, 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 "h265.h"
|
||||
#include "h265_util.h"
|
||||
|
||||
|
||||
int h265_extract_rbsp(const uint8 *src, int length, uint8 *dst)
|
||||
{
|
||||
int i, si, di;
|
||||
|
||||
for (i = 0; i + 1 < length; i += 2)
|
||||
{
|
||||
if (src[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i > 0 && src[i - 1] == 0)
|
||||
{
|
||||
i--;
|
||||
}
|
||||
|
||||
if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3)
|
||||
{
|
||||
if (src[i + 2] != 3 && src[i + 2] != 0)
|
||||
{
|
||||
/* startcode, so we must be past the end */
|
||||
length = i;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= length - 1)
|
||||
{
|
||||
// no escaped 0
|
||||
memcpy(dst, src, length);
|
||||
return length;
|
||||
}
|
||||
else if (i > length)
|
||||
{
|
||||
i = length;
|
||||
}
|
||||
|
||||
memcpy(dst, src, i);
|
||||
si = di = i;
|
||||
|
||||
while (si + 2 < length)
|
||||
{
|
||||
// remove escapes (very rare 1:2^22)
|
||||
if (src[si + 2] > 3)
|
||||
{
|
||||
dst[di++] = src[si++];
|
||||
dst[di++] = src[si++];
|
||||
}
|
||||
else if (src[si] == 0 && src[si + 1] == 0 && src[si + 2] != 0)
|
||||
{
|
||||
if (src[si + 2] == 3)
|
||||
{
|
||||
// escape
|
||||
dst[di++] = 0;
|
||||
dst[di++] = 0;
|
||||
si += 3;
|
||||
|
||||
continue;
|
||||
}
|
||||
else // next start code
|
||||
{
|
||||
return si;
|
||||
}
|
||||
}
|
||||
|
||||
dst[di++] = src[si++];
|
||||
}
|
||||
|
||||
while (si < length)
|
||||
{
|
||||
dst[di++] = src[si++];
|
||||
}
|
||||
|
||||
return si;
|
||||
}
|
||||
|
||||
void h265_parser_init(h265_t * h)
|
||||
{
|
||||
memset(h, 0, sizeof(h265_t));
|
||||
}
|
||||
|
||||
int h265_parser_parse(h265_t * h, uint8 * p_data, int len)
|
||||
{
|
||||
uint32 i;
|
||||
bs_t s;
|
||||
uint8 bufs[512];
|
||||
|
||||
if (len > (int)sizeof(bufs))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = h265_extract_rbsp(p_data, len, bufs);
|
||||
|
||||
bs_init(&s, bufs, len);
|
||||
|
||||
bs_read(&s, 4); // sps_video_parameter_set_id u(4)
|
||||
h->sps_max_sub_layers_minus1 = bs_read(&s, 3); // sps_max_sub_layers_minus1 u(3)
|
||||
if (h->sps_max_sub_layers_minus1 > 6)
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, sps_max_sub_layers_minus1[%d]>6!!!\r\n", __FUNCTION__, h->sps_max_sub_layers_minus1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bs_read(&s, 1); // sps_temporal_id_nesting_flag u(1)
|
||||
|
||||
// profile_tier_level( maxNumSubLayersMinus1 )
|
||||
{
|
||||
bs_read(&s, 2); // general_profile_space u(2)
|
||||
bs_read(&s, 1); // general_tier_flag u(1)
|
||||
h->general_profile_idc = bs_read(&s, 5); // general_profile_idc u(5)
|
||||
bs_read(&s, 32); // general_profile_compatibility_flag[ j ] u(5)
|
||||
bs_read(&s, 1); // general_progressive_source_flag u(1)
|
||||
bs_read(&s, 1); // general_interlaced_source_flag u(1)
|
||||
bs_read(&s, 1); // general_non_packed_constraint_flag u(1)
|
||||
bs_read(&s, 1); // general_frame_only_constraint_flag u(1)
|
||||
bs_skip(&s, 44); // general_reserved_zero_44bits u(44)
|
||||
h->general_level_idc = bs_read(&s, 8); // general_level_idc u(8)
|
||||
|
||||
uint8 sub_layer_profile_present_flag[6] = {0};
|
||||
uint8 sub_layer_level_present_flag[6] = {0};
|
||||
|
||||
for (i = 0; i < h->sps_max_sub_layers_minus1; i++)
|
||||
{
|
||||
sub_layer_profile_present_flag[i]= bs_read(&s, 1);
|
||||
sub_layer_level_present_flag[i]= bs_read(&s, 1);
|
||||
}
|
||||
|
||||
if (h->sps_max_sub_layers_minus1 > 0)
|
||||
{
|
||||
for (i = h->sps_max_sub_layers_minus1; i < 8; i++)
|
||||
{
|
||||
bs_read(&s, 2);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < h->sps_max_sub_layers_minus1; i++)
|
||||
{
|
||||
if (sub_layer_profile_present_flag[i])
|
||||
{
|
||||
bs_read(&s, 2); // sub_layer_profile_space[i]
|
||||
bs_read(&s, 1); // sub_layer_tier_flag[i]
|
||||
bs_read(&s, 5); // sub_layer_profile_idc[i]
|
||||
bs_read(&s, 32); // sub_layer_profile_compatibility_flag[i][32]
|
||||
bs_read(&s, 1); // sub_layer_progressive_source_flag[i]
|
||||
bs_read(&s, 1); // sub_layer_interlaced_source_flag[i]
|
||||
bs_read(&s, 1); // sub_layer_non_packed_constraint_flag[i]
|
||||
bs_read(&s, 1); // sub_layer_frame_only_constraint_flag[i]
|
||||
bs_read(&s, 44); // sub_layer_reserved_zero_44bits[i]
|
||||
}
|
||||
|
||||
if (sub_layer_level_present_flag[i])
|
||||
{
|
||||
bs_read(&s, 8); // sub_layer_level_idc[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h->sps_seq_parameter_set_id = bs_read_ue(&s); // sps_seq_parameter_set_id ue(v)
|
||||
h->chroma_format_idc = bs_read_ue(&s); // chroma_format_idc ue(v)
|
||||
if (h->sps_seq_parameter_set_id > 15 || h->chroma_format_idc > 3)
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, sps_seq_parameter_set_id[%d],chroma_format_idc[%d]!!!\r\n", __FUNCTION__, h->sps_seq_parameter_set_id, h->chroma_format_idc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (h->chroma_format_idc == 3)
|
||||
{
|
||||
h->separate_colour_plane_flag = bs_read(&s, 1); // separate_colour_plane_flag
|
||||
}
|
||||
|
||||
h->pic_width_in_luma_samples = bs_read_ue(&s); // pic_width_in_luma_samples ue(v)
|
||||
h->pic_height_in_luma_samples = bs_read_ue(&s); // pic_height_in_luma_samples ue(v)
|
||||
|
||||
h->conformance_window_flag = bs_read(&s, 1 ); // conformance_window_flag u(1)
|
||||
if (h->conformance_window_flag)
|
||||
{
|
||||
h->conf_win_left_offset = bs_read_ue(&s); // conf_win_left_offset ue(v)
|
||||
h->conf_win_right_offset = bs_read_ue(&s); // conf_win_right_offset ue(v)
|
||||
h->conf_win_top_offset = bs_read_ue(&s); // conf_win_top_offset ue(v)
|
||||
h->conf_win_bottom_offset = bs_read_ue(&s); // conf_win_bottom_offset ue(v)
|
||||
}
|
||||
|
||||
h->bit_depth_luma_minus8 = bs_read_ue(&s); // bit_depth_luma_minus8 ue(v)
|
||||
h->bit_depth_chroma_minus8 = bs_read_ue(&s); // bit_depth_chroma_minus8 ue(v)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user