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
|
@ -1253,3 +1253,4 @@ srs_error_t SrsSdp::update_msid(string id)
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -483,6 +483,23 @@ void SrsRtcSource::init_for_play_before_publishing()
|
||||||
video_track_desc->media_ = video_payload;
|
video_track_desc->media_ = video_payload;
|
||||||
|
|
||||||
video_payload->set_h264_param_desc("level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f");
|
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());
|
set_stream_desc(stream_desc.get());
|
||||||
|
@ -1084,10 +1101,6 @@ srs_error_t SrsRtcRtpBuilder::on_video(SrsSharedPtrMessage* msg)
|
||||||
if (has_idr) {
|
if (has_idr) {
|
||||||
SrsUniquePtr<SrsRtpPacket> pkt(new SrsRtpPacket());
|
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) {
|
if ((err = package_stap_a(msg, pkt.get())) != srs_success) {
|
||||||
return srs_error_wrap(err, "package stap-a");
|
return srs_error_wrap(err, "package stap-a");
|
||||||
}
|
}
|
||||||
|
@ -1323,7 +1336,7 @@ srs_error_t SrsRtcRtpBuilder::package_nalus(SrsSharedPtrMessage* msg, const vect
|
||||||
SrsRtpFUAPayloadHevc* fua = new SrsRtpFUAPayloadHevc();
|
SrsRtpFUAPayloadHevc* fua = new SrsRtpFUAPayloadHevc();
|
||||||
if ((err = raw->read_samples(fua->nalus, packet_size)) != srs_success) {
|
if ((err = raw->read_samples(fua->nalus, packet_size)) != srs_success) {
|
||||||
srs_freep(fua);
|
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->nalu_type = SrsHevcNaluTypeParse(header);
|
||||||
fua->start = bool(i == 0);
|
fua->start = bool(i == 0);
|
||||||
|
@ -1630,7 +1643,6 @@ srs_error_t SrsRtcFrameBuilder::packet_video(SrsRtpPacket* src)
|
||||||
SrsRtpPacket* pkt = src->copy();
|
SrsRtpPacket* pkt = src->copy();
|
||||||
|
|
||||||
if (pkt->is_keyframe()) {
|
if (pkt->is_keyframe()) {
|
||||||
// TODO: 处理H265
|
|
||||||
return packet_video_key_frame(pkt);
|
return packet_video_key_frame(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include <srs_protocol_rtmp_stack.hpp>
|
#include <srs_protocol_rtmp_stack.hpp>
|
||||||
#include <srs_kernel_rtc_rtp.hpp>
|
#include <srs_kernel_rtc_rtp.hpp>
|
||||||
#include <srs_core_autofree.hpp>
|
#include <srs_core_autofree.hpp>
|
||||||
#include <srs_protocol_utility.hpp>
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -157,25 +156,6 @@ srs_error_t SrsFrameToRtcBridge::on_rtp(SrsRtpPacket* pkt)
|
||||||
return source_->on_rtp(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
|
#endif
|
||||||
|
|
||||||
SrsCompositeBridge::SrsCompositeBridge()
|
SrsCompositeBridge::SrsCompositeBridge()
|
||||||
|
|
|
@ -74,7 +74,6 @@ public:
|
||||||
virtual void on_unpublish();
|
virtual void on_unpublish();
|
||||||
virtual srs_error_t on_frame(SrsSharedPtrMessage* frame);
|
virtual srs_error_t on_frame(SrsSharedPtrMessage* frame);
|
||||||
srs_error_t on_rtp(SrsRtpPacket* pkt);
|
srs_error_t on_rtp(SrsRtpPacket* pkt);
|
||||||
srs_error_t update_codec(SrsVideoCodecId id);
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -676,7 +676,7 @@ srs_error_t SrsVideoFrame::add_sample(char* bytes, int size)
|
||||||
|
|
||||||
// By default, use AVC(H.264) to parse NALU.
|
// By default, use AVC(H.264) to parse NALU.
|
||||||
// For video, parse the nalu type, set the IDR flag.
|
// 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) {
|
if (nal_unit_type == SrsAvcNaluTypeIDR) {
|
||||||
has_idr = true;
|
has_idr = true;
|
||||||
|
@ -756,7 +756,7 @@ srs_error_t SrsVideoFrame::parse_hevc_nalu_type(const SrsSample *sample, SrsHevc
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
if (sample == NULL || sample->size < 1) {
|
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];
|
uint8_t header = sample->bytes[0];
|
||||||
|
@ -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");
|
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) {
|
if (nalu_type > SrsHevcNaluType_CODED_SLICE_BLA && nalu_type < SrsHevcNaluType_RESERVED_23) {
|
||||||
bs.skip_bits(1);
|
|
||||||
is_b_frame = false;
|
is_b_frame = false;
|
||||||
return err;
|
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;
|
uint32_t slice_pic_parameter_set_id;
|
||||||
if ((err = bs.read_bits_ue(slice_pic_parameter_set_id)) != srs_success) {
|
if ((err = bs.read_bits_ue(slice_pic_parameter_set_id)) != srs_success) {
|
||||||
return srs_error_wrap(err, "read slice pic parameter set id");
|
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]);
|
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 (!first_slice_segment_in_pic_flag) {
|
||||||
if (pps->dependent_slice_segments_enabled_flag) {
|
if (pps->dependent_slice_segments_enabled_flag) {
|
||||||
dependent_slice_segment_flag = bs.read_bit();
|
dependent_slice_segment_flag = bs.read_bit();
|
||||||
} else {
|
|
||||||
dependent_slice_segment_flag = 0;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
dependent_slice_segment_flag = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dependent_slice_segment_flag) {
|
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");
|
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
|
// no need to evaluate the rest
|
||||||
|
|
||||||
|
@ -2337,7 +2337,7 @@ srs_error_t SrsFormat::avc_demux_sps()
|
||||||
// 7.4.1 NAL unit semantics
|
// 7.4.1 NAL unit semantics
|
||||||
// ISO_IEC_14496-10-AVC-2012.pdf, page 61.
|
// 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.
|
// 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) {
|
if (nal_unit_type != 7) {
|
||||||
return srs_error_new(ERROR_HLS_DECODE_ERROR, "for sps, nal_unit_type shall be equal to 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
|
// @see https://datatracker.ietf.org/doc/html/rfc7798#section-1.1.4
|
||||||
#define SrsHevcNaluTypeParse(code) (SrsHevcNaluType)((code & 0x7E) >> 1)
|
#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 {
|
enum SrsHevcSliceType {
|
||||||
SrsHevcSliceTypeB = 0,
|
SrsHevcSliceTypeB = 0,
|
||||||
SrsHevcSliceTypeP = 1,
|
SrsHevcSliceTypeP = 1,
|
||||||
|
|
|
@ -488,7 +488,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// FU, for one NALU with multiple fragments.
|
// 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
|
class SrsRtpFUAPayloadHevc : public ISrsRtpPayloader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -511,7 +511,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// FU, for one NALU with multiple fragments.
|
// FU, for one NALU with multiple fragments.
|
||||||
// With only one payload. For HEVC.
|
// With only one payload for HEVC.
|
||||||
class SrsRtpFUAPayloadHevc2 : public ISrsRtpPayloader
|
class SrsRtpFUAPayloadHevc2 : public ISrsRtpPayloader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue