Skip to content

Commit

Permalink
Fix #3181: SRT & WebRTC: Use SrsRawH264Stream to mux SPS/PPS.
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaozhihong authored and winlinvip committed Sep 22, 2022
1 parent f974c7c commit 4acb246
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 51 deletions.
2 changes: 1 addition & 1 deletion trunk/src/app/srs_app_mpegts_udp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand Down
47 changes: 24 additions & 23 deletions trunk/src/app/srs_app_rtc_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
44 changes: 21 additions & 23 deletions trunk/src/app/srs_app_srt_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/main/srs_main_ingest_hls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/protocol/srs_protocol_raw_avc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion trunk/src/protocol/srs_protocol_raw_avc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class SrsRawH264Stream
// 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.
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/utest/srs_utest_avc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down

0 comments on commit 4acb246

Please sign in to comment.