Skip to content

Commit

Permalink
fix hevc hls msg error
Browse files Browse the repository at this point in the history
PPS id out of range: 0
Invalid NAL unit 4, skipping
  • Loading branch information
wnpllrzodiac committed Jan 24, 2018
1 parent d4bbaa6 commit 8982c87
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 20 deletions.
47 changes: 35 additions & 12 deletions trunk/src/kernel/srs_kernel_codec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ SrsCodecSample::~SrsCodecSample()
void SrsCodecSample::clear()
{
is_video = false;
is_hevc = false;
nb_sample_units = 0;

cts = 0;
Expand Down Expand Up @@ -401,19 +402,40 @@ int SrsCodecSample::add_sample_unit(char* bytes, int size)

// for video, parse the nalu type, set the IDR flag.
if (is_video) {
SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(bytes[0] & 0x1f);
if (is_hevc)
{
SrsHevcNaluType nal_unit_type = (SrsHevcNaluType)((bytes[0] & 0x7e) >> 1);

if (nal_unit_type == HEVC_NAL_IDR_W_RADL || nal_unit_type == HEVC_NAL_IDR_N_LP) {
has_idr = true;
} else if (nal_unit_type == HEVC_NAL_VPS || nal_unit_type == HEVC_NAL_SPS || nal_unit_type == HEVC_NAL_PPS) {
has_sps_pps = true;
} else if (nal_unit_type == HEVC_NAL_AUD) {
has_aud = true;
}

// fix me. useless code?
/*if (first_nalu_type == SrsAvcNaluTypeReserved) {
first_nalu_type = nal_unit_type;
}*/
}
else
{
SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(bytes[0] & 0x1f);

if (nal_unit_type == SrsAvcNaluTypeIDR) {
has_idr = true;
} else if (nal_unit_type == SrsAvcNaluTypeSPS || nal_unit_type == SrsAvcNaluTypePPS) {
has_sps_pps = true;
} else if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) {
has_aud = true;
}

if (first_nalu_type == SrsAvcNaluTypeReserved) {
first_nalu_type = nal_unit_type;
}
}

if (nal_unit_type == SrsAvcNaluTypeIDR) {
has_idr = true;
} else if (nal_unit_type == SrsAvcNaluTypeSPS || nal_unit_type == SrsAvcNaluTypePPS) {
has_sps_pps = true;
} else if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) {
has_aud = true;
}

if (first_nalu_type == SrsAvcNaluTypeReserved) {
first_nalu_type = nal_unit_type;
}
}

return ret;
Expand Down Expand Up @@ -701,6 +723,7 @@ int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample
frame_type = (frame_type >> 4) & 0x0f;

sample->frame_type = (SrsCodecVideoAVCFrame)frame_type;
sample->is_hevc = (codec_id == SrsCodecVideoHEVC);

// ignore info frame without error,
// @see https://github.com/ossrs/srs/issues/288#issuecomment-69863909
Expand Down
50 changes: 50 additions & 0 deletions trunk/src/kernel/srs_kernel_codec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,52 @@ enum SrsAvcNaluType
};
std::string srs_codec_avc_nalu2str(SrsAvcNaluType nalu_type);

enum SrsHevcNaluType
{
HEVC_NAL_TRAIL_N = 0,
HEVC_NAL_TRAIL_R = 1,
HEVC_NAL_TSA_N = 2,
HEVC_NAL_TSA_R = 3,
HEVC_NAL_STSA_N = 4,
HEVC_NAL_STSA_R = 5,
HEVC_NAL_RADL_N = 6,
HEVC_NAL_RADL_R = 7,
HEVC_NAL_RASL_N = 8,
HEVC_NAL_RASL_R = 9,
HEVC_NAL_VCL_N10 = 10,
HEVC_NAL_VCL_R11 = 11,
HEVC_NAL_VCL_N12 = 12,
HEVC_NAL_VCL_R13 = 13,
HEVC_NAL_VCL_N14 = 14,
HEVC_NAL_VCL_R15 = 15,
HEVC_NAL_BLA_W_LP = 16,
HEVC_NAL_BLA_W_RADL = 17,
HEVC_NAL_BLA_N_LP = 18,
HEVC_NAL_IDR_W_RADL = 19,
HEVC_NAL_IDR_N_LP = 20,
HEVC_NAL_CRA_NUT = 21,
HEVC_NAL_IRAP_VCL22 = 22,
HEVC_NAL_IRAP_VCL23 = 23,
HEVC_NAL_RSV_VCL24 = 24,
HEVC_NAL_RSV_VCL25 = 25,
HEVC_NAL_RSV_VCL26 = 26,
HEVC_NAL_RSV_VCL27 = 27,
HEVC_NAL_RSV_VCL28 = 28,
HEVC_NAL_RSV_VCL29 = 29,
HEVC_NAL_RSV_VCL30 = 30,
HEVC_NAL_RSV_VCL31 = 31,
HEVC_NAL_VPS = 32,
HEVC_NAL_SPS = 33,
HEVC_NAL_PPS = 34,
HEVC_NAL_AUD = 35,
HEVC_NAL_EOS_NUT = 36,
HEVC_NAL_EOB_NUT = 37,
HEVC_NAL_FD_NUT = 38,
HEVC_NAL_SEI_PREFIX = 39,
HEVC_NAL_SEI_SUFFIX = 40,
};


/**
* the codec sample unit.
* for h.264 video packet, a NALU is a sample unit.
Expand Down Expand Up @@ -381,6 +427,10 @@ class SrsCodecSample
* whether the sample is video sample which demux from video packet.
*/
bool is_video;
/**
* whether the sample is hevc video sample.
*/
bool is_hevc;
/**
* CompositionTime, video_file_format_spec_v10_1.pdf, page 78.
* cts = pts - dts, where dts = flvheader->timestamp.
Expand Down
23 changes: 15 additions & 8 deletions trunk/src/kernel/srs_kernel_ts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3018,7 +3018,7 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample)
bool aud_inserted = false;

// Insert a default AUD NALU when no AUD in samples.
if (!sample->has_aud) {
if (!sample->has_aud && (SrsCodecVideo)codec->video_codec_id == SrsCodecVideoAVC) {
// the aud(access unit delimiter) before each frame.
// 7.3.2.4 Access unit delimiter RBSP syntax
// H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 66.
Expand Down Expand Up @@ -3088,13 +3088,14 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample)
}
else if (codec->video_codec_id == SrsCodecVideoHEVC)
{
// 5bits, 7.3.1 NAL unit syntax,
// H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 83.
SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)((sample_unit->bytes[0] & 0x7e) >> 1);
SrsHevcNaluType nal_unit_type = (SrsHevcNaluType)((sample_unit->bytes[0] & 0x7e) >> 1);

// Insert sps/pps before IDR when there is no sps/pps in samples.
// The sps/pps is parsed from sequence header(generally the first flv packet).
if (nal_unit_type >= 16 && nal_unit_type <= 21 && !sample->has_sps_pps && !is_sps_pps_appended) {
// Insert vps/sps/pps before IDR when there is no vps/sps/pps in samples.
// The vps/sps/pps is parsed from sequence header(generally the first flv packet).
//if (nal_unit_type >= 16 && nal_unit_type <= 21 && !sample->has_sps_pps && !is_sps_pps_appended) {
if ((nal_unit_type == HEVC_NAL_IDR_W_RADL || nal_unit_type == HEVC_NAL_IDR_N_LP) &&
!sample->has_sps_pps && !is_sps_pps_appended)
{
if (codec->videoParameterSetLength > 0) {
srs_avc_insert_aud(video->payload, aud_inserted);
video->payload->append(codec->videoParameterSetNALUnit, codec->videoParameterSetLength);
Expand Down Expand Up @@ -3232,7 +3233,13 @@ int SrsTsEncoder::write_video(int64_t timestamp, char* data, int size)
if (codec->video_codec_id != SrsCodecVideoAVC && codec->video_codec_id != SrsCodecVideoHEVC) {
return ret;
}


// when codec changed, write new header.
if ((ret = muxer->update_vcodec(vcodec)) != ERROR_SUCCESS) {
srs_error("http: ts video write header failed. ret=%d", ret);
return ret;
}

// ignore sequence header
if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame
&& sample->avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader) {
Expand Down

0 comments on commit 8982c87

Please sign in to comment.