1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

H265: Demux sps for log print and statistic streams.(#3271) (#3286)

* BitBuffer: add method to implement bit read operation.

* Codec: demux hevc sps for profile level resolution.

* Statistic: refine hevc profile level resolution.

* Kernel: return error code for demux hevc.

* Kernel: check bitstream length for hevc sps.

* UTest: add BitBuffer read bits utest.

* Kernel: refine print log and utest.

* Kernel: add comment for hevc sps.

Co-authored-by: winlin <winlin@vip.126.com>
This commit is contained in:
chundonglinlin 2022-12-04 22:46:14 +08:00 committed by GitHub
parent e6c395e473
commit a0803b556b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 729 additions and 19 deletions

View file

@ -1074,9 +1074,10 @@ srs_error_t SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_se
c->width, c->height, c->video_data_rate / 1000, c->frame_rate, c->duration);
#ifdef SRS_H265
} else if (c->id == SrsVideoCodecIdHEVC) {
// TODO: FIXME: Use the correct information for HEVC.
err = stat->on_video_info(req_, c->id, c->avc_profile, c->avc_level, c->width, c->height);
srs_trace("%dB video sh, codec(%d)", msg->size, c->id);
err = stat->on_video_info(req_, c->id, c->hevc_profile, c->hevc_level, c->width, c->height);
srs_trace("%dB video sh, codec(%d, profile=%s, level=%s, %dx%d, %dkbps, %.1ffps, %.1fs)",
msg->size, c->id, srs_hevc_profile2str(c->hevc_profile).c_str(), srs_hevc_level2str(c->hevc_level).c_str(),
c->width, c->height, c->video_data_rate / 1000, c->frame_rate, c->duration);
#endif
}
if (err != srs_success) {

View file

@ -143,8 +143,20 @@ srs_error_t SrsStatisticStream::dumps(SrsJsonObject* obj)
obj->set("video", video);
video->set("codec", SrsJsonAny::str(srs_video_codec_id2str(vcodec).c_str()));
video->set("profile", SrsJsonAny::str(srs_avc_profile2str(avc_profile).c_str()));
video->set("level", SrsJsonAny::str(srs_avc_level2str(avc_level).c_str()));
if (vcodec == SrsVideoCodecIdAVC) {
video->set("profile", SrsJsonAny::str(srs_avc_profile2str(avc_profile).c_str()));
video->set("level", SrsJsonAny::str(srs_avc_level2str(avc_level).c_str()));
#ifdef SRS_H265
} else if (vcodec == SrsVideoCodecIdHEVC) {
video->set("profile", SrsJsonAny::str(srs_hevc_profile2str(hevc_profile).c_str()));
video->set("level", SrsJsonAny::str(srs_hevc_level2str(hevc_level).c_str()));
#endif
} else {
video->set("profile", SrsJsonAny::str("Other"));
video->set("level", SrsJsonAny::str("Other"));
}
video->set("width", SrsJsonAny::integer(width));
video->set("height", SrsJsonAny::integer(height));
}
@ -335,7 +347,7 @@ SrsStatisticClient* SrsStatistic::find_client(string client_id)
return NULL;
}
srs_error_t SrsStatistic::on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level, int width, int height)
srs_error_t SrsStatistic::on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, int profile, int level, int width, int height)
{
srs_error_t err = srs_success;
@ -344,9 +356,20 @@ srs_error_t SrsStatistic::on_video_info(SrsRequest* req, SrsVideoCodecId vcodec,
stream->has_video = true;
stream->vcodec = vcodec;
stream->avc_profile = avc_profile;
stream->avc_level = avc_level;
if (vcodec == SrsVideoCodecIdAVC) {
stream->avc_profile = (SrsAvcProfile)profile;
stream->avc_level = (SrsAvcLevel)level;
#ifdef SRS_H265
} else if (vcodec == SrsVideoCodecIdHEVC) {
stream->hevc_profile = (SrsHevcProfile)profile;
stream->hevc_level = (SrsHevcLevel)level;
#endif
} else {
stream->avc_profile = (SrsAvcProfile)profile;
stream->avc_level = (SrsAvcLevel)level;
}
stream->width = width;
stream->height = height;

View file

@ -70,6 +70,12 @@ public:
SrsAvcProfile avc_profile;
// The level_idc, ISO_IEC_14496-10-AVC-2003.pdf, page 45.
SrsAvcLevel avc_level;
#ifdef SRS_H265
// The profile_idc, T-REC-H.265-202108-I!!PDF-E.pdf, page 559.
SrsHevcProfile hevc_profile;
// The level_idc, T-REC-H.265-202108-I!!PDF-E.pdf, page 684.
SrsHevcLevel hevc_level;
#endif
// The width and height in codec info.
int width;
int height;
@ -157,8 +163,7 @@ public:
virtual SrsStatisticClient* find_client(std::string client_id);
public:
// When got video info for stream.
virtual srs_error_t on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile,
SrsAvcLevel avc_level, int width, int height);
virtual srs_error_t on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, int avc_profile, int avc_level, int width, int height);
// When got audio info for stream.
virtual srs_error_t on_audio_info(SrsRequest* req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate,
SrsAudioChannels asound_type, SrsAacObjectType aac_object);

View file

@ -379,6 +379,15 @@ bool SrsBitBuffer::empty() {
return stream->empty();
}
bool SrsBitBuffer::require_bits(int n)
{
if (n < 0) {
return false;
}
return n <= left_bits();
}
int8_t SrsBitBuffer::read_bit() {
if (!cb_left) {
srs_assert(!stream->empty());
@ -391,3 +400,75 @@ int8_t SrsBitBuffer::read_bit() {
return v;
}
int SrsBitBuffer::left_bits()
{
return cb_left + stream->left() * 8;
}
void SrsBitBuffer::skip_bits(int n)
{
srs_assert(n <= left_bits());
for (int i = 0; i < n; i++) {
read_bit();
}
}
int32_t SrsBitBuffer::read_bits(int n)
{
srs_assert(n <= left_bits());
int32_t v = 0;
for (int i = 0; i < n; i++) {
v |= (read_bit() << (n - i - 1));
}
return v;
}
int8_t SrsBitBuffer::read_8bits()
{
// FAST_8
if (!cb_left) {
srs_assert(!stream->empty());
return stream->read_1bytes();
}
return read_bits(8);
}
int16_t SrsBitBuffer::read_16bits()
{
// FAST_16
if (!cb_left) {
srs_assert(!stream->empty());
return stream->read_2bytes();
}
return read_bits(16);
}
int32_t SrsBitBuffer::read_32bits()
{
// FAST_32
if (!cb_left) {
srs_assert(!stream->empty());
return stream->read_4bytes();
}
return read_bits(32);
}
int32_t SrsBitBuffer::read_bits_ue()
{
int32_t r = 0;
int i = 0;
while((read_bit() == 0) && (i < 32) && (left_bits() > 0) ) {
i++;
}
r = read_bits(i);
r += (1 << i) - 1;
return r;
}

View file

@ -174,6 +174,14 @@ public:
public:
bool empty();
int8_t read_bit();
bool require_bits(int n);
int left_bits();
void skip_bits(int n);
int32_t read_bits(int n);
int8_t read_8bits();
int16_t read_16bits();
int32_t read_32bits();
int32_t read_bits_ue();
};
#endif

View file

@ -416,6 +416,41 @@ string srs_avc_level2str(SrsAvcLevel level)
}
}
#ifdef SRS_H265
string srs_hevc_profile2str(SrsHevcProfile profile)
{
switch (profile) {
case SrsHevcProfileMain: return "Main";
case SrsHevcProfileMain10: return "Main10";
case SrsHevcProfileMainStillPicture: return "Main Still Picture";
case SrsHevcProfileRext: return "Rext";
default: return "Other";
}
}
string srs_hevc_level2str(SrsHevcLevel level)
{
switch (level) {
case SrsHevcLevel_1: return "1";
case SrsHevcLevel_2: return "2";
case SrsHevcLevel_21: return "2.1";
case SrsHevcLevel_3: return "3";
case SrsHevcLevel_31: return "3.1";
case SrsHevcLevel_4: return "4";
case SrsHevcLevel_41: return "4.1";
case SrsHevcLevel_5: return "5";
case SrsHevcLevel_51: return "5.1";
case SrsHevcLevel_52: return "5.2";
case SrsHevcLevel_6: return "6";
case SrsHevcLevel_61: return "6.1";
case SrsHevcLevel_62: return "6.2";
default: return "Other";
}
}
#endif
SrsSample::SrsSample()
{
size = 0;
@ -882,6 +917,8 @@ srs_error_t SrsFormat::video_avc_demux(SrsBuffer* stream, int64_t timestamp)
// Parse the hevc vps/sps/pps
srs_error_t SrsFormat::hevc_demux_hvcc(SrsBuffer* stream)
{
srs_error_t err = srs_success;
int avc_extra_size = stream->size() - stream->pos();
if (avc_extra_size > 0) {
char *copy_stream_from = stream->data() + stream->pos();
@ -890,13 +927,13 @@ srs_error_t SrsFormat::hevc_demux_hvcc(SrsBuffer* stream)
const int HEVC_MIN_SIZE = 23; // From configuration_version to numOfArrays
if (!stream->require(HEVC_MIN_SIZE)) {
return srs_error_new(ERROR_HLS_DECODE_ERROR, "requires %d only %d bytes", HEVC_MIN_SIZE, stream->left());
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "requires %d only %d bytes", HEVC_MIN_SIZE, stream->left());
}
SrsHevcDecoderConfigurationRecord* dec_conf_rec_p = &(vcodec->hevc_dec_conf_record_);
dec_conf_rec_p->configuration_version = stream->read_1bytes();
if (dec_conf_rec_p->configuration_version != 1) {
return srs_error_new(ERROR_HLS_DECODE_ERROR, "invalid version=%d", dec_conf_rec_p->configuration_version);
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "invalid version=%d", dec_conf_rec_p->configuration_version);
}
// Read general_profile_space(2bits), general_tier_flag(1bit), general_profile_idc(5bits)
@ -934,7 +971,7 @@ srs_error_t SrsFormat::hevc_demux_hvcc(SrsBuffer* stream)
dec_conf_rec_p->bit_depth_luma_minus8, dec_conf_rec_p->bit_depth_chroma_minus8);
//avg_frame_rate: 16bits
dec_conf_rec_p->avg_frame_rate = stream->read_2bytes();
vcodec->frame_rate = dec_conf_rec_p->avg_frame_rate = stream->read_2bytes();
//8bits: constant_frame_rate(2bits), num_temporal_layers(3bits),
// temporal_id_nested(1bit), length_size_minus_one(2bits)
data_byte = stream->read_1bytes();
@ -952,7 +989,7 @@ srs_error_t SrsFormat::hevc_demux_hvcc(SrsBuffer* stream)
// The value of this field shall be one of 0, 1, or 3 corresponding to a
// length encoded with 1, 2, or 4 bytes, respectively.
if (vcodec->NAL_unit_length == 2) {
return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps lengthSizeMinusOne should never be 2");
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "sps lengthSizeMinusOne should never be 2");
}
uint8_t numOfArrays = stream->read_1bytes();
@ -965,7 +1002,7 @@ srs_error_t SrsFormat::hevc_demux_hvcc(SrsBuffer* stream)
SrsHevcHvccNalu hevc_unit;
if (!stream->require(5)) {
return srs_error_new(ERROR_HLS_DECODE_ERROR, "requires 5 only %d bytes", stream->left());
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "requires 5 only %d bytes", stream->left());
}
data_byte = stream->read_1bytes();
hevc_unit.array_completeness = (data_byte >> 7) & 0x01;
@ -977,7 +1014,7 @@ srs_error_t SrsFormat::hevc_demux_hvcc(SrsBuffer* stream)
data_item.nal_unit_length = stream->read_2bytes();
if (!stream->require(data_item.nal_unit_length)) {
return srs_error_new(ERROR_HLS_DECODE_ERROR, "requires %d only %d bytes",
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "requires %d only %d bytes",
data_item.nal_unit_length, stream->left());
}
//copy vps/pps/sps data
@ -989,10 +1026,376 @@ srs_error_t SrsFormat::hevc_demux_hvcc(SrsBuffer* stream)
hevc_unit.nal_data_vec.push_back(data_item);
}
dec_conf_rec_p->nalu_vec.push_back(hevc_unit);
// demux nalu
if ((err = hevc_demux_vps_sps_pps(&hevc_unit)) != srs_success) {
return srs_error_wrap(err, "hevc demux vps sps pps failed");
}
}
return srs_success;
return err;
}
srs_error_t SrsFormat::hevc_demux_vps_sps_pps(SrsHevcHvccNalu* nal)
{
srs_error_t err = srs_success;
// nal data
switch (nal->nal_unit_type)
{
case SrsHevcNaluType_VPS:
// TODO: FIXME: implements it.
break;
case SrsHevcNaluType_SPS:
err = hevc_demux_sps(nal);
break;
case SrsHevcNaluType_PPS:
// TODO: FIXME: implements it.
break;
default:
break;
}
return err;
}
srs_error_t SrsFormat::hevc_demux_sps(SrsHevcHvccNalu* nal)
{
srs_error_t err = srs_success;
if (nal->nal_data_vec.empty()) {
return err;
}
// FIXME: Support for multiple SPS, then pick the first non-empty one.
char* sps = (char*)(&nal->nal_data_vec[0].nal_unit_data[0]);
int nb_sps = nal->nal_data_vec[0].nal_unit_length;
SrsBuffer stream(sps, nb_sps);
// for NALU, ITU-T H.265 7.3.2.2 Sequence parameter set RBSP syntax
// T-REC-H.265-202108-I!!PDF-E.pdf, page 33.
if (!stream.require(1)) {
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "decode hevc sps requires 1 only %d bytes", stream.left());
}
int8_t nutv = stream.read_1bytes();
// forbidden_zero_bit shall be equal to 0.
int8_t forbidden_zero_bit = (nutv >> 7) & 0x01;
if (forbidden_zero_bit) {
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc forbidden_zero_bit=%d shall be equal to 0", forbidden_zero_bit);
}
// 7.4.2 NAL unit semantics
// T-REC-H.265-202108-I!!PDF-E.pdf, page 64.
// nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1.
SrsHevcNaluType nal_unit_type = (SrsHevcNaluType)((nutv >> 1) & 0x3f);
if (nal_unit_type != SrsHevcNaluType_SPS) {
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "hevc sps nal_unit_type=%d shall be equal to 33", nal_unit_type);
}
// nuh(nuh_layer_id + nuh_temporal_id_plus1)
int8_t nuh = stream.read_1bytes();
(void)nuh;
// decode the rbsp from sps.
// rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes.
std::vector<int8_t> rbsp(nb_sps);
int nb_rbsp = 0;
while (!stream.empty()) {
rbsp[nb_rbsp] = stream.read_1bytes();
// XX 00 00 03 XX, the 03 byte should be drop.
if (nb_rbsp > 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) {
// read 1byte more.
if (stream.empty()) {
break;
}
rbsp[nb_rbsp] = stream.read_1bytes();
nb_rbsp++;
continue;
}
nb_rbsp++;
}
return hevc_demux_sps_rbsp((char*)&rbsp[0], nb_rbsp);
}
srs_error_t SrsFormat::hevc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
{
srs_error_t err = srs_success;
// we donot parse the detail of sps.
// @see https://github.com/ossrs/srs/issues/474
if (!avc_parse_sps) {
return err;
}
// reparse the rbsp.
SrsBuffer stream(rbsp, nb_rbsp);
/* Rec. ITU-T H.265 7.3.2.2.1, page 35.
* seq_parameter_set_rbsp
* sps_video_parameter_set_id 4 bits
* sps_max_sub_layers_minus1 3 bits
* sps_temporal_id_nesting_flag 1 bit
*
* sps_seq_parameter_set_id v
* chroma_format_idc v
* if (chroma_format_idc == 3)
* separate_colour_plane_flag 1 bit
* pic_width_in_luma_samples v
* pic_height_in_luma_samples v
* conformance_window_flag 1 bit
* if (conformance_window_flag) {
* conf_win_left_offset v
* conf_win_right_offset v
* conf_win_top_offset v
* conf_win_bottom_offset v
* }
*/
if (!stream.require(2)) {
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "sps requires 2 only %d bytes", stream.left());
}
uint8_t nutv = stream.read_1bytes();
(void)nutv;
// id/minus/flag
int sps_video_parameter_set_id = (nutv >> 4) & 0x0f;
int sps_max_sub_layers_minus1 = (nutv >> 1) & 0x07;
int sps_temporal_id_nesting_flag = nutv & 0x01;
(void)sps_video_parameter_set_id;
(void)sps_temporal_id_nesting_flag;
SrsBitBuffer bs(&stream);
// profile tier level...
SrsHevcSpsProfileTierLevel profile_tier_level;
memset(&profile_tier_level, 0, sizeof(SrsHevcSpsProfileTierLevel));
if ((err = hevc_demux_sps_rbsp_ptl(&bs, &profile_tier_level, 1, sps_max_sub_layers_minus1)) != srs_success) {
return srs_error_wrap(err, "sps rbsp ptl sps_max_sub_layers_minus1=%d", sps_max_sub_layers_minus1);
}
vcodec->hevc_profile = (SrsHevcProfile)profile_tier_level.general_profile_idc;
vcodec->hevc_level = (SrsHevcLevel)profile_tier_level.general_level_idc;
// for sps_table
int sps_seq_parameter_set_id = bs.read_bits_ue();
(void)sps_seq_parameter_set_id;
int separate_colour_plane_flag = 0;
int chroma_format_idc = bs.read_bits_ue();
if (chroma_format_idc == 3) {
separate_colour_plane_flag = bs.read_bits_ue();
}
int pic_width_in_luma_samples = bs.read_bits_ue();
int pic_height_in_luma_samples = bs.read_bits_ue();
vcodec->width = pic_width_in_luma_samples;
vcodec->height = pic_height_in_luma_samples;
int conformance_window_flag = bs.read_bit();
if (conformance_window_flag) {
int conf_win_left_offset = bs.read_bits_ue();
int conf_win_right_offset = bs.read_bits_ue();
int conf_win_top_offset = bs.read_bits_ue();
int conf_win_bottom_offset = bs.read_bits_ue();
// Table 6-1, 7.4.3.2.1
// Recalculate width and height
// Note: 1 is added to the manual, but it is not actually used
// https://github.com/mbunkus/mkvtoolnix/issues/1152
int sub_width_c = ((1 == chroma_format_idc) || (2 == chroma_format_idc)) && (0 == separate_colour_plane_flag) ? 2 : 1;
int sub_height_c = (1 == chroma_format_idc) && (0 == separate_colour_plane_flag) ? 2 : 1;
vcodec->width -= (sub_width_c * conf_win_right_offset + sub_width_c * conf_win_left_offset);
vcodec->height -= (sub_height_c * conf_win_bottom_offset + sub_height_c * conf_win_top_offset);
}
// TODO: FIXME: Implements it, you might parse remain bits for seq_parameter_set_rbsp.
// 7.4.3.2.1
// T-REC-H.265-202108-I!!PDF-E.pdf, page 35 ~ page 36.
// bit_depth_luma_minus8
// bit_depth_chroma_minus8
// 7.3.2.11 RBSP trailing bits syntax
// T-REC-H.265-202108-I!!PDF-E.pdf, page 41.
// rbsp_trailing_bits()
return err;
}
srs_error_t SrsFormat::hevc_demux_sps_rbsp_ptl(SrsBitBuffer* bs, SrsHevcSpsProfileTierLevel* ptl, int profile_resent_flag, int max_sub_layers_minus1)
{
srs_error_t err = srs_success;
if (profile_resent_flag) {
if (!bs->require_bits(88)) {
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl profile requires 88 only %d bits", bs->left_bits());
}
ptl->general_profile_space = bs->read_bits(2);
ptl->general_tier_flag = bs->read_bit();
ptl->general_profile_idc = bs->read_bits(5);
for (int i = 0; i < 32; i++) {
ptl->general_profile_compatibility_flag[i] = bs->read_bit();
}
ptl->general_progressive_source_flag = bs->read_bit();
ptl->general_interlaced_source_flag = bs->read_bit();
ptl->general_non_packed_constraint_flag = bs->read_bit();
ptl->general_frame_only_constraint_flag = bs->read_bit();
if (ptl->general_profile_idc == 4 || ptl->general_profile_compatibility_flag[4] ||
ptl->general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] ||
ptl->general_profile_idc == 6 || ptl->general_profile_compatibility_flag[6] ||
ptl->general_profile_idc == 7 || ptl->general_profile_compatibility_flag[7])
{
ptl->general_max_12bit_constraint_flag = bs->read_bit();
ptl->general_max_10bit_constraint_flag = bs->read_bit();
ptl->general_max_8bit_constraint_flag = bs->read_bit();
ptl->general_max_422chroma_constraint_flag = bs->read_bit();
ptl->general_max_420chroma_constraint_flag = bs->read_bit();
ptl->general_max_monochrome_constraint_flag = bs->read_bit();
ptl->general_intra_constraint_flag = bs->read_bit();
ptl->general_one_picture_only_constraint_flag = bs->read_bit();
ptl->general_lower_bit_rate_constraint_flag = bs->read_bit();
uint64_t tmp1 = bs->read_32bits();
uint64_t tmp2 = bs->read_bits(2);
ptl->general_reserved_zero_34bits = tmp1 + tmp2;
} else {
uint64_t tmp1 = bs->read_32bits();
uint64_t tmp2 = bs->read_bits(11);
ptl->general_reserved_zero_43bits = tmp1 + tmp2;
}
if ((ptl->general_profile_idc >= 1 && ptl->general_profile_idc<=5) ||
ptl->general_profile_compatibility_flag[1] || ptl->general_profile_compatibility_flag[2] ||
ptl->general_profile_compatibility_flag[3] || ptl->general_profile_compatibility_flag[4] ||
ptl->general_profile_compatibility_flag[5])
{
ptl->general_inbld_flag = bs->read_bit();
} else {
ptl->general_reserved_zero_bit = bs->read_bit();
}
}
if (!bs->require_bits(8)) {
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl level requires 8 only %d bits", bs->left_bits());
}
// level
ptl->general_level_idc = bs->read_8bits();
ptl->sub_layer_profile_present_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_level_present_flag.resize(max_sub_layers_minus1);
for (int i = 0; i < max_sub_layers_minus1; i++) {
if (!bs->require_bits(2)) {
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl present_flag requires 2 only %d bits", bs->left_bits());
}
ptl->sub_layer_profile_present_flag[i] = bs->read_bit();
ptl->sub_layer_level_present_flag[i] = bs->read_bit();
}
for (int i = max_sub_layers_minus1; max_sub_layers_minus1 > 0 && i < 8; i++) {
if (!bs->require_bits(2)) {
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl reserved_zero requires 2 only %d bits", bs->left_bits());
}
ptl->reserved_zero_2bits[i] = bs->read_bits(2);
}
ptl->sub_layer_profile_space.resize(max_sub_layers_minus1);
ptl->sub_layer_tier_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_profile_idc.resize(max_sub_layers_minus1);
ptl->sub_layer_profile_compatibility_flag.resize(max_sub_layers_minus1);
for (int i = 0; i < max_sub_layers_minus1; i++) {
ptl->sub_layer_profile_compatibility_flag[i].resize(32);
}
ptl->sub_layer_progressive_source_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_interlaced_source_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_non_packed_constraint_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_frame_only_constraint_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_max_12bit_constraint_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_max_10bit_constraint_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_max_8bit_constraint_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_max_422chroma_constraint_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_max_420chroma_constraint_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_max_monochrome_constraint_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_intra_constraint_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_one_picture_only_constraint_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_lower_bit_rate_constraint_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_reserved_zero_34bits.resize(max_sub_layers_minus1);
ptl->sub_layer_reserved_zero_43bits.resize(max_sub_layers_minus1);
ptl->sub_layer_inbld_flag.resize(max_sub_layers_minus1);
ptl->sub_layer_reserved_zero_bit.resize(max_sub_layers_minus1);
ptl->sub_layer_level_idc.resize(max_sub_layers_minus1);
for (int i = 0; i < max_sub_layers_minus1; i++) {
if (ptl->sub_layer_profile_present_flag[i]) {
if (!bs->require_bits(88)) {
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl sub_layer_profile requires 88 only %d bits", bs->left_bits());
}
ptl->sub_layer_profile_space[i] = bs->read_bits(2);
ptl->sub_layer_tier_flag[i] = bs->read_bit();
ptl->sub_layer_profile_idc[i] = bs->read_bits(5);
for (int j = 0; j < 32; j++) {
ptl->sub_layer_profile_compatibility_flag[i][j] = bs->read_bit();
}
ptl->sub_layer_progressive_source_flag[i] = bs->read_bit();
ptl->sub_layer_interlaced_source_flag[i] = bs->read_bit();
ptl->sub_layer_non_packed_constraint_flag[i] = bs->read_bit();
ptl->sub_layer_frame_only_constraint_flag[i] = bs->read_bit();
if (ptl->sub_layer_profile_idc[i] == 4 || ptl->sub_layer_profile_compatibility_flag[i][4] ||
ptl->sub_layer_profile_idc[i] == 5 || ptl->sub_layer_profile_compatibility_flag[i][5] ||
ptl->sub_layer_profile_idc[i] == 6 || ptl->sub_layer_profile_compatibility_flag[i][6] ||
ptl->sub_layer_profile_idc[i] == 7 || ptl->sub_layer_profile_compatibility_flag[i][7])
{
ptl->sub_layer_max_12bit_constraint_flag[i] = bs->read_bit();
ptl->sub_layer_max_10bit_constraint_flag[i] = bs->read_bit();
ptl->sub_layer_max_8bit_constraint_flag[i] = bs->read_bit();
ptl->sub_layer_max_422chroma_constraint_flag[i] = bs->read_bit();
ptl->sub_layer_max_420chroma_constraint_flag[i] = bs->read_bit();
ptl->sub_layer_max_monochrome_constraint_flag[i] = bs->read_bit();
ptl->sub_layer_intra_constraint_flag[i] = bs->read_bit();
ptl->sub_layer_one_picture_only_constraint_flag[i] = bs->read_bit();
ptl->sub_layer_lower_bit_rate_constraint_flag[i] = bs->read_bit();
uint64_t tmp1 = bs->read_32bits();
uint64_t tmp2 = bs->read_bits(2);
ptl->sub_layer_reserved_zero_34bits[i] = tmp1 + tmp2;
} else {
uint64_t tmp1 = bs->read_32bits();
uint64_t tmp2 = bs->read_bits(11);
ptl->sub_layer_reserved_zero_43bits[i] = tmp1 + tmp2;
}
// to check
if ((ptl->sub_layer_profile_idc[i]>=1 && ptl->sub_layer_profile_idc[i] <= 5) ||
ptl->sub_layer_profile_compatibility_flag[i][1] ||
ptl->sub_layer_profile_compatibility_flag[i][2] ||
ptl->sub_layer_profile_compatibility_flag[i][3] ||
ptl->sub_layer_profile_compatibility_flag[i][4] ||
ptl->sub_layer_profile_compatibility_flag[i][5])
{
ptl->sub_layer_inbld_flag[i] = bs->read_bit();
} else {
ptl->sub_layer_reserved_zero_bit[i] = bs->read_bit();
}
}
if (ptl->sub_layer_level_present_flag[i]) {
if (!bs->require_bits(8)) {
return srs_error_new(ERROR_HEVC_DECODE_ERROR, "ptl sub_layer_level requires 8 only %d bits", bs->left_bits());
}
ptl->sub_layer_level_idc[i] = bs->read_8bits();
}
}
return err;
}
#endif
srs_error_t SrsFormat::avc_demux_sps_pps(SrsBuffer* stream)

View file

@ -13,6 +13,7 @@
#include <vector>
class SrsBuffer;
class SrsBitBuffer;
/**
* The video codec id.
@ -502,6 +503,63 @@ struct SrsHevcDecoderConfigurationRecord {
uint8_t length_size_minus_one;
std::vector<SrsHevcHvccNalu> nalu_vec;
};
/**
Profile, tier and level
@see 7.3.3 Profile, tier and level syntax
*/
struct SrsHevcSpsProfileTierLevel
{
uint8_t general_profile_space;
uint8_t general_tier_flag;
uint8_t general_profile_idc;
uint8_t general_profile_compatibility_flag[32];
uint8_t general_progressive_source_flag;
uint8_t general_interlaced_source_flag;
uint8_t general_non_packed_constraint_flag;
uint8_t general_frame_only_constraint_flag;
uint8_t general_max_12bit_constraint_flag;
uint8_t general_max_10bit_constraint_flag;
uint8_t general_max_8bit_constraint_flag;
uint8_t general_max_422chroma_constraint_flag;
uint8_t general_max_420chroma_constraint_flag;
uint8_t general_max_monochrome_constraint_flag;
uint8_t general_intra_constraint_flag;
uint8_t general_one_picture_only_constraint_flag;
uint8_t general_lower_bit_rate_constraint_flag;
uint64_t general_reserved_zero_34bits; // todo
uint64_t general_reserved_zero_43bits; // todo
uint8_t general_inbld_flag;
uint8_t general_reserved_zero_bit;
uint8_t general_level_idc;
std::vector<uint8_t> sub_layer_profile_present_flag;
std::vector<uint8_t> sub_layer_level_present_flag;
uint8_t reserved_zero_2bits[8];
std::vector<uint8_t> sub_layer_profile_space;
std::vector<uint8_t> sub_layer_tier_flag;
std::vector<uint8_t> sub_layer_profile_idc;
std::vector<std::vector<uint8_t> > sub_layer_profile_compatibility_flag;
std::vector<uint8_t> sub_layer_progressive_source_flag;
std::vector<uint8_t> sub_layer_interlaced_source_flag;
std::vector<uint8_t> sub_layer_non_packed_constraint_flag;
std::vector<uint8_t> sub_layer_frame_only_constraint_flag;
std::vector<uint8_t> sub_layer_max_12bit_constraint_flag;
std::vector<uint8_t> sub_layer_max_10bit_constraint_flag;
std::vector<uint8_t> sub_layer_max_8bit_constraint_flag;
std::vector<uint8_t> sub_layer_max_422chroma_constraint_flag;
std::vector<uint8_t> sub_layer_max_420chroma_constraint_flag;
std::vector<uint8_t> sub_layer_max_monochrome_constraint_flag;
std::vector<uint8_t> sub_layer_intra_constraint_flag;
std::vector<uint8_t> sub_layer_one_picture_only_constraint_flag;
std::vector<uint8_t> sub_layer_lower_bit_rate_constraint_flag;
std::vector<uint64_t> sub_layer_reserved_zero_34bits;
std::vector<uint64_t> sub_layer_reserved_zero_43bits;
std::vector<uint8_t> sub_layer_inbld_flag;
std::vector<uint8_t> sub_layer_reserved_zero_bit;
std::vector<uint8_t> sub_layer_level_idc;
};
#endif
/**
@ -627,6 +685,50 @@ enum SrsAvcLevel
};
std::string srs_avc_level2str(SrsAvcLevel level);
#ifdef SRS_H265
/**
* the profile for hevc/h.265.
* @see Annex A Profiles and levels, T-REC-H.265-202108-I!!PDF-E.pdf, page 559.
*/
enum SrsHevcProfile
{
SrsHevcProfileReserved = 0,
// @see ffmpeg, libavcodec/avcodec.h:2986
SrsHevcProfileMain = 1,
SrsHevcProfileMain10 = 2,
SrsHevcProfileMainStillPicture = 3,
SrsHevcProfileRext = 4,
};
std::string srs_hevc_profile2str(SrsHevcProfile profile);
/**
* the level for hevc/h.265.
* @see Annex A Profiles and levels, T-REC-H.265-202108-I!!PDF-E.pdf, page 684.
*/
enum SrsHevcLevel
{
SrsHevcLevelReserved = 0,
SrsHevcLevel_1 = 30,
SrsHevcLevel_2 = 60,
SrsHevcLevel_21 = 63,
SrsHevcLevel_3 = 90,
SrsHevcLevel_31 = 93,
SrsHevcLevel_4 = 120,
SrsHevcLevel_41 = 123,
SrsHevcLevel_5 = 150,
SrsHevcLevel_51 = 153,
SrsHevcLevel_52 = 156,
SrsHevcLevel_6 = 180,
SrsHevcLevel_61 = 183,
SrsHevcLevel_62 = 186,
};
std::string srs_hevc_level2str(SrsHevcLevel level);
#endif
/**
* A sample is the unit of frame.
* It's a NALU for H.264.
@ -741,6 +843,12 @@ public:
SrsAvcProfile avc_profile;
// level_idc, ISO_IEC_14496-10-AVC-2003.pdf, page 45.
SrsAvcLevel avc_level;
#ifdef SRS_H265
// The profile_idc, T-REC-H.265-202108-I!!PDF-E.pdf, page 559.
SrsHevcProfile hevc_profile;
// The level_idc, T-REC-H.265-202108-I!!PDF-E.pdf, page 684.
SrsHevcLevel hevc_level;
#endif
// lengthSizeMinusOne, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16
int8_t NAL_unit_length;
// Note that we may resize the vector, so the under-layer bytes may change.
@ -874,6 +982,10 @@ private:
#ifdef SRS_H265
private:
virtual srs_error_t hevc_demux_hvcc(SrsBuffer* stream);
virtual srs_error_t hevc_demux_vps_sps_pps(SrsHevcHvccNalu* nal);
virtual srs_error_t hevc_demux_sps(SrsHevcHvccNalu* nal);
virtual srs_error_t hevc_demux_sps_rbsp(char* rbsp, int nb_rbsp);
virtual srs_error_t hevc_demux_sps_rbsp_ptl(SrsBitBuffer* bs, SrsHevcSpsProfileTierLevel* ptl, int profile_resent_flag, int max_sub_layers_minus1);
#endif
private:
// Parse the H.264 SPS/PPS.

View file

@ -267,7 +267,8 @@
XX(ERROR_INOTIFY_WATCH , 3095, "InotfyWatch", "Failed to watch inotify for config listener") \
XX(ERROR_HTTP_URL_UNESCAPE , 3096, "HttpUrlUnescape", "Failed to unescape URL for HTTP") \
XX(ERROR_HTTP_WITH_BODY , 3097, "HttpWithBody", "Failed for HTTP body") \
XX(ERROR_HEVC_DISABLED , 3098, "HevcDisabled", "HEVC is disabled")
XX(ERROR_HEVC_DISABLED , 3098, "HevcDisabled", "HEVC is disabled") \
XX(ERROR_HEVC_DECODE_ERROR , 3099, "HevcDecode", "HEVC decode av stream failed")
/**************************************************/
/* HTTP/StreamConverter protocol error. */

View file

@ -4455,6 +4455,25 @@ VOID TEST(KernelMp3Test, CoverAll)
}
}
/**
* test the bitbuffer utility, access require
*/
VOID TEST(KernelUtilityTest, BitBufferRequire)
{
char data[128];
SrsBuffer b(data, 128);
SrsBitBuffer bb(&b);
EXPECT_TRUE(bb.require_bits(1));
EXPECT_TRUE(bb.require_bits(1024));
bb.read_bits(1000);
EXPECT_TRUE(bb.require_bits(1));
bb.read_bits(24);
EXPECT_FALSE(bb.require_bits(1));
}
VOID TEST(KernelUtilityTest, CoverBitsBufferAll)
{
if (true) {
@ -4492,6 +4511,63 @@ VOID TEST(KernelUtilityTest, CoverBitsBufferAll)
srs_error_t err = srs_avc_nalu_read_bit(&bb, v);
HELPER_EXPECT_FAILED(err);
}
if (true) {
SrsBuffer b((char*)"\x20\x01", 2);
SrsBitBuffer bb(&b);
int8_t v = bb.read_8bits();
EXPECT_EQ(0x20, v);
}
if (true) {
SrsBuffer b((char*)"\x04\x00\x01\x01", 4);
SrsBitBuffer bb(&b);
int16_t v = bb.read_16bits();
EXPECT_EQ(0x0400, v);
}
if (true) {
SrsBuffer b((char*)"\x00\x00\x04\x00\x01\x01", 6);
SrsBitBuffer bb(&b);
int32_t v = bb.read_32bits();
EXPECT_EQ(0x0400, v);
}
if (true) {
SrsBuffer b((char*)"\x00\x28\x08\x02\xd1\x65\x95\x9a", 8);
SrsBitBuffer bb(&b);
int32_t v = bb.read_bits_ue();
EXPECT_EQ(1280, v);
v = bb.read_bits_ue();
EXPECT_EQ(720, v);
}
if (true) {
SrsBuffer b((char*)"\x10\x00\x04\x00\x01\x01\x04\x00", 8);
SrsBitBuffer bb(&b);
int32_t v = bb.read_bits(1);
EXPECT_EQ(0, v);
v = bb.read_bits(7);
EXPECT_EQ(0x10, v);
v = bb.read_bits(13);
EXPECT_EQ(0, v);
v = bb.read_bits(20);
//100 0000 0000 0000 0001 0
EXPECT_EQ(0x80002, v);
v = bb.read_bits(23);
//000 0001 0000 0100 0000 0000
EXPECT_EQ(0x10400, v);
}
}
#ifndef SRS_OSX