From 1888f755e3b8debef5ca71a34b97156950b01667 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 279911b101..6b5c6887b8 100644 --- a/trunk/src/app/srs_app_gb28181.cpp +++ b/trunk/src/app/srs_app_gb28181.cpp @@ -100,7 +100,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; } @@ -1843,9 +1845,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 @@ -1861,9 +1864,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; } @@ -1880,10 +1883,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); @@ -1974,13 +1983,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) { @@ -2213,7 +2221,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 0f61e96017..4f9043a7aa 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -2377,7 +2377,11 @@ srs_error_t SrsSource::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