From ec95eb62ee9049b75ae27236ef3e933f986883a8 Mon Sep 17 00:00:00 2001 From: PieerePi Date: Fri, 22 Jan 2021 16:55:29 +0800 Subject: [PATCH] h265: fix some important bugs (#2156) * For #1747, Support HEVC/H.265 in SRT/RTMP/HLS. * Fixed compile error. * 1. optimize when to send hevc vps sps pps header 2. fix hevc I frame dropped by rtc before sending to consumer 3. fix overread in nalu parsing * ignore unknown payload data, otherwise it will be processed in other place * free err before return Co-authored-by: runner365 Co-authored-by: yinjiaoyuan --- trunk/src/app/srs_app_gb28181.cpp | 33 ++++++++++++++++++++----------- trunk/src/app/srs_app_source.cpp | 6 +++++- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/trunk/src/app/srs_app_gb28181.cpp b/trunk/src/app/srs_app_gb28181.cpp index b4a1f016bd..808626e493 100644 --- a/trunk/src/app/srs_app_gb28181.cpp +++ b/trunk/src/app/srs_app_gb28181.cpp @@ -85,7 +85,9 @@ srs_error_t SrsPsRtpPacket::decode(SrsBuffer* stream) } // append left bytes to payload. payload->append(stream->data() + stream->pos() , stream->size()-stream->pos()); - } + } else { + return srs_error_new(ERROR_RTP_HEADER_CORRUPT, "unknown payload data"); + } return err; } @@ -1533,9 +1535,10 @@ srs_error_t SrsGb28181RtmpMuxer::write_hevc_ipb_frame2(char *frame, int frame_si h265_vps = vps; //write hevc vps_sps_pps - if ((err = write_hevc_sps_pps(dts, pts)) != srs_success) { - return srs_error_wrap(err, "hevc write vps/sps/pps"); - } + // if ((err = write_hevc_sps_pps(dts, pts)) != srs_success) { + // return srs_error_wrap(err, "hevc write vps/sps/pps"); + // } + return err; } // for sps @@ -1551,9 +1554,9 @@ srs_error_t SrsGb28181RtmpMuxer::write_hevc_ipb_frame2(char *frame, int frame_si hevc_sps_changed = true; h265_sps = sps; - if ((err = write_hevc_sps_pps(dts, pts)) != srs_success) { - return srs_error_wrap(err, "write hevc sps/pps"); - } + // if ((err = write_hevc_sps_pps(dts, pts)) != srs_success) { + // return srs_error_wrap(err, "write hevc sps/pps"); + // } return err; } @@ -1570,10 +1573,16 @@ srs_error_t SrsGb28181RtmpMuxer::write_hevc_ipb_frame2(char *frame, int frame_si hevc_pps_changed = true; h265_pps = pps; + // if ((err = write_hevc_sps_pps(dts, pts)) != srs_success) { + // return srs_error_wrap(err, "write hevc sps/pps"); + // } + return err; + } + + if (hevc_sps_changed || hevc_pps_changed || hevc_vps_changed) { if ((err = write_hevc_sps_pps(dts, pts)) != srs_success) { return srs_error_wrap(err, "write hevc sps/pps"); } - return err; } srs_info("gb28181: demux hevc ibp frame size=%d, dts=%d", frame_size, dts); @@ -1664,13 +1673,12 @@ srs_error_t SrsGb28181RtmpMuxer::write_hevc_ipb_frame2(char *frame, int frame_si std::list list_index; for (; index < size; index++) { + if (index > (size - 4)) + break; if (video_data[index] == 0x00 && video_data[index + 1] == 0x00 && video_data[index + 2] == 0x00 && video_data[index + 3] == 0x01) { list_index.push_back(index); } - - if (index > (size - 4)) - break; } if (list_index.size() == 1) { @@ -1903,7 +1911,8 @@ srs_error_t SrsGb28181RtmpMuxer::write_hevc_sps_pps(uint32_t dts, uint32_t pts) // when sps or pps changed, update the sequence header, // for the pps maybe not changed while sps changed. // so, we must check when each video ts message frame parsed. - if (!hevc_sps_changed || !hevc_pps_changed || !hevc_vps_changed) { + // if (!hevc_sps_changed || !hevc_pps_changed || !hevc_vps_changed) { + if (!(hevc_sps_changed || hevc_pps_changed || hevc_vps_changed)) { return err; } diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 3d65409d73..d8342519ac 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -2342,7 +2342,11 @@ srs_error_t SrsLiveSource::on_video_imp(SrsSharedPtrMessage* msg) // For bridger to consume the message. if (bridger_ && (err = bridger_->on_video(msg)) != srs_success) { - return srs_error_wrap(err, "bridger consume video"); + // rtc doesn't support hevc, here fails if it's a hevc key frame + // so consumers can't get 1c01 VideoTag + // return srs_error_wrap(err, "bridger consume video"); + // srs_warn("rtc on video err %s", srs_error_desc(err).c_str()); + srs_freep(err); } // copy to all consumer