Skip to content

Commit

Permalink
Optimize init h265 track and format.
Browse files Browse the repository at this point in the history
  • Loading branch information
chundonglinlin committed Feb 21, 2025
1 parent 83e8877 commit 8953dbf
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 53 deletions.
3 changes: 2 additions & 1 deletion trunk/src/app/srs_app_rtc_sdp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1252,4 +1252,5 @@ srs_error_t SrsSdp::update_msid(string id)
}

return err;
}
}

26 changes: 19 additions & 7 deletions trunk/src/app/srs_app_rtc_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,23 @@ void SrsRtcSource::init_for_play_before_publishing()
video_track_desc->media_ = video_payload;

video_payload->set_h264_param_desc("level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f");

#ifdef SRS_H265
// default h265 video track description
SrsRtcTrackDescription* h265_video_track_desc = new SrsRtcTrackDescription();
stream_desc->video_track_descs_.push_back(h265_video_track_desc);

h265_video_track_desc->type_ = "video";
h265_video_track_desc->id_ = "video-" + srs_random_str(8);
h265_video_track_desc->ssrc_ = video_ssrc;
h265_video_track_desc->direction_ = "recvonly";

SrsVideoPayload* h265_video_payload = new SrsVideoPayload(kVideoPayloadType, "H265", kVideoSamplerate);
h265_video_track_desc->media_ = h265_video_payload;

h265_video_payload->set_h265_param_desc("level-id=180;profile-id=1;tier-flag=0;tx-mode=SRST");
#endif

}

set_stream_desc(stream_desc.get());
Expand Down Expand Up @@ -1084,10 +1101,6 @@ srs_error_t SrsRtcRtpBuilder::on_video(SrsSharedPtrMessage* msg)
if (has_idr) {
SrsUniquePtr<SrsRtpPacket> pkt(new SrsRtpPacket());

if ((err = bridge_->update_codec(format->vcodec->id)) != srs_success) {
return srs_error_wrap(err, "update codec");
}

if ((err = package_stap_a(msg, pkt.get())) != srs_success) {
return srs_error_wrap(err, "package stap-a");
}
Expand Down Expand Up @@ -1235,7 +1248,7 @@ srs_error_t SrsRtcRtpBuilder::package_stap_a(SrsSharedPtrMessage* msg, SrsRtpPac
}

memcpy(payload, (char*)param->data(), param->size());
payload += (int)param->size();
payload += (int)param->size();
}

return err;
Expand Down Expand Up @@ -1323,7 +1336,7 @@ srs_error_t SrsRtcRtpBuilder::package_nalus(SrsSharedPtrMessage* msg, const vect
SrsRtpFUAPayloadHevc* fua = new SrsRtpFUAPayloadHevc();
if ((err = raw->read_samples(fua->nalus, packet_size)) != srs_success) {
srs_freep(fua);
return srs_error_wrap(err, "read samples %d bytes, left %d, total %d", packet_size, nb_left, nn_bytes);
return srs_error_wrap(err, "read hevc samples %d bytes, left %d, total %d", packet_size, nb_left, nn_bytes);
}
fua->nalu_type = SrsHevcNaluTypeParse(header);
fua->start = bool(i == 0);
Expand Down Expand Up @@ -1630,7 +1643,6 @@ srs_error_t SrsRtcFrameBuilder::packet_video(SrsRtpPacket* src)
SrsRtpPacket* pkt = src->copy();

if (pkt->is_keyframe()) {
// TODO: 处理H265
return packet_video_key_frame(pkt);
}

Expand Down
22 changes: 1 addition & 21 deletions trunk/src/app/srs_app_stream_bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include <srs_protocol_rtmp_stack.hpp>
#include <srs_kernel_rtc_rtp.hpp>
#include <srs_core_autofree.hpp>
#include <srs_protocol_utility.hpp>

#include <vector>
using namespace std;
Expand Down Expand Up @@ -145,7 +144,7 @@ void SrsFrameToRtcBridge::on_unpublish()

srs_error_t SrsFrameToRtcBridge::on_frame(SrsSharedPtrMessage* frame)
{
#ifdef SRS_FFMPEG_FIT
#ifdef SRS_FFMPEG_FIT
return rtp_builder_->on_frame(frame);
#else
return srs_success;
Expand All @@ -157,25 +156,6 @@ srs_error_t SrsFrameToRtcBridge::on_rtp(SrsRtpPacket* pkt)
return source_->on_rtp(pkt);
}

srs_error_t SrsFrameToRtcBridge::update_codec(SrsVideoCodecId id)
{
// init with H264 default, so we need check if it's H265 only.
if (id == SrsVideoCodecIdHEVC) {
if (source_->get_track_desc("video", "H265").empty()) {
std::vector<SrsRtcTrackDescription*> video_track_descs = source_->get_track_desc("video", "H264");
if (!video_track_descs.empty()) {
SrsRtcTrackDescription* video_track_desc = video_track_descs.at(0);
SrsVideoPayload* video_payload = (SrsVideoPayload*)video_track_desc->media_;
video_payload->name_ = "H265";
video_payload->set_h265_param_desc("level-id=180;profile-id=1;tier-flag=0;tx-mode=SRST");
srs_trace("RTC: Switch video codec %d(%s) to %d(%s)", SrsVideoCodecIdAVC, srs_video_codec_id2str(SrsVideoCodecIdAVC).c_str(),
id, srs_video_codec_id2str(id).c_str());
}
}
}
return srs_success;
}

#endif

SrsCompositeBridge::SrsCompositeBridge()
Expand Down
1 change: 0 additions & 1 deletion trunk/src/app/srs_app_stream_bridge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ class SrsFrameToRtcBridge : public ISrsStreamBridge
virtual void on_unpublish();
virtual srs_error_t on_frame(SrsSharedPtrMessage* frame);
srs_error_t on_rtp(SrsRtpPacket* pkt);
srs_error_t update_codec(SrsVideoCodecId id);
};
#endif

Expand Down
38 changes: 19 additions & 19 deletions trunk/src/kernel/srs_kernel_codec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ srs_error_t SrsVideoFrame::add_sample(char* bytes, int size)

// By default, use AVC(H.264) to parse NALU.
// For video, parse the nalu type, set the IDR flag.
SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(bytes[0] & 0x1f);
SrsAvcNaluType nal_unit_type = SrsAvcNaluTypeParse(bytes[0]);

if (nal_unit_type == SrsAvcNaluTypeIDR) {
has_idr = true;
Expand Down Expand Up @@ -751,12 +751,12 @@ srs_error_t SrsVideoFrame::parse_avc_b_frame(const SrsSample* sample, bool& is_b
return err;
}

srs_error_t SrsVideoFrame::parse_hevc_nalu_type(const SrsSample *sample, SrsHevcNaluType &hevc_nalu_type)
srs_error_t SrsVideoFrame::parse_hevc_nalu_type(const SrsSample* sample, SrsHevcNaluType& hevc_nalu_type)
{
srs_error_t err = srs_success;

if (sample == NULL || sample->size < 1) {
return srs_error_new(ERROR_NALU_EMPTY, "empty nalu");
return srs_error_new(ERROR_NALU_EMPTY, "empty hevc nalu");
}

uint8_t header = sample->bytes[0];
Expand All @@ -765,7 +765,7 @@ srs_error_t SrsVideoFrame::parse_hevc_nalu_type(const SrsSample *sample, SrsHevc
return err;
}

srs_error_t SrsVideoFrame::parse_hevc_b_frame(const SrsSample *sample, SrsFormat *format, bool &is_b_frame)
srs_error_t SrsVideoFrame::parse_hevc_b_frame(const SrsSample* sample, SrsFormat *format, bool& is_b_frame)
{
srs_error_t err = srs_success;

Expand All @@ -774,19 +774,20 @@ srs_error_t SrsVideoFrame::parse_hevc_b_frame(const SrsSample *sample, SrsFormat
return srs_error_wrap(err, "parse hevc nalu type error");
}

SrsBuffer stream(sample->bytes, sample->size);
stream.skip(2);

// @see 7.3.6.1 General slice segment header syntax
// @doc ITU-T-H.265-2021.pdf, page 66.
SrsBitBuffer bs(&stream);
uint8_t first_slice_segment_in_pic_flag = bs.read_bit();
if (nalu_type > SrsHevcNaluType_CODED_SLICE_BLA && nalu_type < SrsHevcNaluType_RESERVED_23) {
bs.skip_bits(1);
is_b_frame = false;
return err;
}

SrsUniquePtr<SrsBuffer> stream(new SrsBuffer(sample->bytes, sample->size));
stream->skip(2);

// @see 7.3.6.1 General slice segment header syntax
// @doc ITU-T-H.265-2021.pdf, page 66.
SrsBitBuffer bs(stream.get());

uint8_t first_slice_segment_in_pic_flag = bs.read_bit();

uint32_t slice_pic_parameter_set_id;
if ((err = bs.read_bits_ue(slice_pic_parameter_set_id)) != srs_success) {
return srs_error_wrap(err, "read slice pic parameter set id");
Expand All @@ -798,15 +799,11 @@ srs_error_t SrsVideoFrame::parse_hevc_b_frame(const SrsSample *sample, SrsFormat

SrsHevcRbspPps *pps = &(format->vcodec->hevc_dec_conf_record_.pps_table[slice_pic_parameter_set_id]);

uint8_t dependent_slice_segment_flag;
uint8_t dependent_slice_segment_flag = 0;
if (!first_slice_segment_in_pic_flag) {
if (pps->dependent_slice_segments_enabled_flag) {
dependent_slice_segment_flag = bs.read_bit();
} else {
dependent_slice_segment_flag = 0;
}
} else {
dependent_slice_segment_flag = 0;
}

if (dependent_slice_segment_flag) {
Expand All @@ -822,7 +819,10 @@ srs_error_t SrsVideoFrame::parse_hevc_b_frame(const SrsSample *sample, SrsFormat
return srs_error_wrap(err, "read slice type");
}

is_b_frame = (slice_type == SrsHevcSliceTypeB) ? true : false;
is_b_frame = slice_type == SrsHevcSliceTypeB;
if (is_b_frame) {
srs_verbose("nalu_type=%d, slice type=%d", nalu_type, slice_type);
}

// no need to evaluate the rest

Expand Down Expand Up @@ -2337,7 +2337,7 @@ srs_error_t SrsFormat::avc_demux_sps()
// 7.4.1 NAL unit semantics
// ISO_IEC_14496-10-AVC-2012.pdf, page 61.
// nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1.
SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(nutv & 0x1f);
SrsAvcNaluType nal_unit_type = SrsAvcNaluTypeParse(nutv);
if (nal_unit_type != 7) {
return srs_error_new(ERROR_HLS_DECODE_ERROR, "for sps, nal_unit_type shall be equal to 7");
}
Expand Down
4 changes: 4 additions & 0 deletions trunk/src/kernel/srs_kernel_codec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,10 @@ enum SrsHevcNaluType {
// @see https://datatracker.ietf.org/doc/html/rfc7798#section-1.1.4
#define SrsHevcNaluTypeParse(code) (SrsHevcNaluType)((code & 0x7E) >> 1)

/**
* @see Table 7-7 – Name association to slice_type
* @doc ITU-T-H.265-2021.pdf, page 96.
*/
enum SrsHevcSliceType {
SrsHevcSliceTypeB = 0,
SrsHevcSliceTypeP = 1,
Expand Down
8 changes: 4 additions & 4 deletions trunk/src/kernel/srs_kernel_rtc_rtp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ const uint8_t kStapA = 24;
const uint8_t kFuA = 28;

// @see: https://datatracker.ietf.org/doc/html/rfc7798#section-4.4.2
const uint8_t kStapHevc = 48;
const uint8_t kStapHevc = 48;
// @see: https://datatracker.ietf.org/doc/html/rfc7798#section-4.4.3
const uint8_t kFuHevc = 49;
const uint8_t kFuHevc = 49;

// @see: https://tools.ietf.org/html/rfc6184#section-5.8
const uint8_t kStart = 0x80; // Fu-header start bit
Expand Down Expand Up @@ -488,7 +488,7 @@ class SrsRtpSTAPPayloadHevc : public ISrsRtpPayloader
};

// FU, for one NALU with multiple fragments.
// With more than one payload. For HEVC.
// With more than one payload for HEVC.
class SrsRtpFUAPayloadHevc : public ISrsRtpPayloader
{
public:
Expand All @@ -511,7 +511,7 @@ class SrsRtpFUAPayloadHevc : public ISrsRtpPayloader
};

// FU, for one NALU with multiple fragments.
// With only one payload. For HEVC.
// With only one payload for HEVC.
class SrsRtpFUAPayloadHevc2 : public ISrsRtpPayloader
{
public:
Expand Down

0 comments on commit 8953dbf

Please sign in to comment.