Fix #3181: SRT & WebRTC: Use SrsRawH264Stream to mux SPS/PPS.

pull/3186/head
hondaxiao 2 years ago committed by winlin
parent f974c7c8b0
commit 4acb246c57

@ -417,7 +417,7 @@ srs_error_t SrsMpegtsOverUdp::write_h264_sps_pps(uint32_t dts, uint32_t pts)
// h264 raw to h264 packet.
std::string sh;
if ((err = avc->mux_sequence_header(h264_sps, h264_pps, dts, pts, sh)) != srs_success) {
if ((err = avc->mux_sequence_header(h264_sps, h264_pps, sh)) != srs_success) {
return srs_error_wrap(err, "mux sequence header");
}

@ -35,6 +35,7 @@
#endif
#include <srs_protocol_kbps.hpp>
#include <srs_protocol_raw_avc.hpp>
// The NACK sent by us(SFU).
SrsPps* _srs_pps_snack = NULL;
@ -1480,30 +1481,30 @@ srs_error_t SrsRtmpFromRtcBridge::packet_video_key_frame(SrsRtpPacket* pkt)
if (NULL == sps || NULL == pps) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "no sps or pps in stap-a rtp. sps: %p, pps:%p", sps, pps);
} else {
//type_codec1 + avc_type + composition time + fix header + count of sps + len of sps + sps + count of pps + len of pps + pps
int nb_payload = 1 + 1 + 3 + 5 + 1 + 2 + sps->size + 1 + 2 + pps->size;
// h264 raw to h264 packet.
std::string sh;
SrsRawH264Stream* avc = new SrsRawH264Stream();
SrsAutoFree(SrsRawH264Stream, avc);
if ((err = avc->mux_sequence_header(string(sps->bytes, sps->size), string(pps->bytes, pps->size), sh)) != srs_success) {
return srs_error_wrap(err, "mux sequence header");
}
// h264 packet to flv packet.
char* flv = NULL;
int nb_flv = 0;
if ((err = avc->mux_avc2flv(sh, SrsVideoAvcFrameTypeKeyFrame, SrsVideoAvcFrameTraitSequenceHeader, pkt->get_avsync_time(),
pkt->get_avsync_time(), &flv, &nb_flv)) != srs_success) {
return srs_error_wrap(err, "avc to flv");
}
SrsMessageHeader header;
header.initialize_video(nb_flv, pkt->get_avsync_time(), 1);
SrsCommonMessage rtmp;
rtmp.header.initialize_video(nb_payload, pkt->get_avsync_time(), 1);
rtmp.create_payload(nb_payload);
rtmp.size = nb_payload;
SrsBuffer payload(rtmp.payload, rtmp.size);
//TODO: call api
payload.write_1bytes(0x17);// type(4 bits): key frame; code(4bits): avc
payload.write_1bytes(0x0); // avc_type: sequence header
payload.write_1bytes(0x0); // composition time
payload.write_1bytes(0x0);
payload.write_1bytes(0x0);
payload.write_1bytes(0x01); // version
payload.write_1bytes(sps->bytes[1]);
payload.write_1bytes(sps->bytes[2]);
payload.write_1bytes(sps->bytes[3]);
payload.write_1bytes(0xff);
payload.write_1bytes(0xe1);
payload.write_2bytes(sps->size);
payload.write_bytes(sps->bytes, sps->size);
payload.write_1bytes(0x01);
payload.write_2bytes(pps->size);
payload.write_bytes(pps->bytes, pps->size);
if ((err = rtmp.create(&header, flv, nb_flv)) != srs_success) {
return srs_error_wrap(err, "create rtmp");
}
if ((err = source_->on_video(&rtmp)) != srs_success) {
return err;
}

@ -434,30 +434,28 @@ srs_error_t SrsRtmpFromSrtBridge::check_sps_pps_change(SrsTsMessage* msg)
// ts tbn to flv tbn.
uint32_t dts = (uint32_t)(msg->dts / 90);
//type_codec1 + avc_type + composition time + fix header + count of sps + len of sps + sps + count of pps + len of pps + pps
int nb_payload = 1 + 1 + 3 + 5 + 1 + 2 + sps_.size() + 1 + 2 + pps_.size();
std::string sh;
SrsRawH264Stream* avc = new SrsRawH264Stream();
SrsAutoFree(SrsRawH264Stream, avc);
if ((err = avc->mux_sequence_header(sps_, pps_, sh)) != srs_success) {
return srs_error_wrap(err, "mux sequence header");
}
// h264 packet to flv packet.
char* flv = NULL;
int nb_flv = 0;
if ((err = avc->mux_avc2flv(sh, SrsVideoAvcFrameTypeKeyFrame, SrsVideoAvcFrameTraitSequenceHeader, dts, dts, &flv, &nb_flv)) != srs_success) {
return srs_error_wrap(err, "avc to flv");
}
SrsMessageHeader header;
header.initialize_video(nb_flv, dts, 1);
SrsCommonMessage rtmp;
rtmp.header.initialize_video(nb_payload, dts, 1);
rtmp.create_payload(nb_payload);
rtmp.size = nb_payload;
SrsBuffer payload(rtmp.payload, rtmp.size);
//TODO: call api
payload.write_1bytes(0x17);// type(4 bits): key frame; code(4bits): avc
payload.write_1bytes(0x0); // avc_type: sequence header
payload.write_1bytes(0x0); // composition time
payload.write_1bytes(0x0);
payload.write_1bytes(0x0);
payload.write_1bytes(0x01); // version
payload.write_1bytes(sps_[1]);
payload.write_1bytes(sps_[2]);
payload.write_1bytes(sps_[3]);
payload.write_1bytes(0xff);
payload.write_1bytes(0xe1);
payload.write_2bytes(sps_.size());
payload.write_bytes((char*)sps_.data(), sps_.size());
payload.write_1bytes(0x01);
payload.write_2bytes(pps_.size());
payload.write_bytes((char*)pps_.data(), pps_.size());
if ((err = rtmp.create(&header, flv, nb_flv)) != srs_success) {
return srs_error_wrap(err, "create rtmp");
}
if ((err = live_source_->on_video(&rtmp)) != srs_success) {
return srs_error_wrap(err, "srt to rtmp sps/pps");
}

@ -1073,7 +1073,7 @@ int SrsIngestHlsOutput::write_h264_sps_pps(uint32_t dts, uint32_t pts)
// h264 raw to h264 packet.
std::string sh;
if ((err = avc->mux_sequence_header(h264_sps, h264_pps, dts, pts, sh)) != srs_success) {
if ((err = avc->mux_sequence_header(h264_sps, h264_pps, sh)) != srs_success) {
// TODO: FIXME: Use error
ret = srs_error_code(err);
srs_freep(err);

@ -109,7 +109,7 @@ srs_error_t SrsRawH264Stream::pps_demux(char* frame, int nb_frame, string& pps)
return err;
}
srs_error_t SrsRawH264Stream::mux_sequence_header(string sps, string pps, uint32_t dts, uint32_t pts, string& sh)
srs_error_t SrsRawH264Stream::mux_sequence_header(string sps, string pps, string& sh)
{
srs_error_t err = srs_success;

@ -38,7 +38,7 @@ public:
// The h264 raw data to h264 packet, without flv payload header.
// Mux the sps/pps to flv sequence header packet.
// @param sh output the sequence header.
virtual srs_error_t mux_sequence_header(std::string sps, std::string pps, uint32_t dts, uint32_t pts, std::string& sh);
virtual srs_error_t mux_sequence_header(std::string sps, std::string pps, std::string& sh);
// The h264 raw data to h264 packet, without flv payload header.
// Mux the ibp to flv ibp packet.
// @param ibp output the packet.

@ -113,7 +113,7 @@ VOID TEST(SrsAVCTest, H264SequenceHeader)
// For muxing sequence header.
if (true) {
SrsRawH264Stream h; string sh;
HELPER_ASSERT_SUCCESS(h.mux_sequence_header("Hello", "world", 0, 0, sh));
HELPER_ASSERT_SUCCESS(h.mux_sequence_header("Hello", "world", sh));
EXPECT_EQ(11+5+5, (int)sh.length());
EXPECT_STREQ("Hello", sh.substr(8, 5).c_str());
EXPECT_STREQ("world", sh.substr(16).c_str());

Loading…
Cancel
Save