mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Optimize init h265 track and format.
This commit is contained in:
parent
83e8877623
commit
8953dbfba1
7 changed files with 49 additions and 53 deletions
|
@ -1252,4 +1252,5 @@ srs_error_t SrsSdp::update_msid(string id)
|
|||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
|
|
@ -74,7 +74,6 @@ public:
|
|||
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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
@ -488,7 +488,7 @@ public:
|
|||
};
|
||||
|
||||
// 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:
|
||||
|
@ -511,7 +511,7 @@ public:
|
|||
};
|
||||
|
||||
// FU, for one NALU with multiple fragments.
|
||||
// With only one payload. For HEVC.
|
||||
// With only one payload for HEVC.
|
||||
class SrsRtpFUAPayloadHevc2 : public ISrsRtpPayloader
|
||||
{
|
||||
public:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue