rename HEVC-related mux functions to enhance consistency and readability. (#4506)

This commit is contained in:
Haibo Chen(陈海博) 2025-09-22 19:48:40 +08:00 committed by GitHub
parent 2dfa54e21b
commit ea14caeee5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 50 additions and 40 deletions

View File

@ -1087,7 +1087,7 @@ srs_error_t SrsGbMuxer::write_h265_vps_sps_pps(uint32_t dts, uint32_t pts)
char *flv = NULL;
int nb_flv = 0;
if ((err = hevc_->mux_avc2flv(sh, frame_type, hevc_packet_type, dts, pts, &flv, &nb_flv)) != srs_success) {
if ((err = hevc_->mux_hevc2flv(sh, frame_type, hevc_packet_type, dts, pts, &flv, &nb_flv)) != srs_success) {
return srs_error_wrap(err, "hevc to flv");
}
@ -1131,7 +1131,7 @@ srs_error_t SrsGbMuxer::write_h265_ipb_frame(char *frame, int frame_size, uint32
char *flv = NULL;
int nb_flv = 0;
if ((err = hevc_->mux_avc2flv(ipb, frame_type, hevc_packet_type, dts, pts, &flv, &nb_flv)) != srs_success) {
if ((err = hevc_->mux_hevc2flv(ipb, frame_type, hevc_packet_type, dts, pts, &flv, &nb_flv)) != srs_success) {
return srs_error_wrap(err, "hevc to flv");
}

View File

@ -2163,7 +2163,7 @@ srs_error_t SrsRtcFrameBuilder::do_packet_sequence_header_hevc(SrsRtpPacket *pkt
char *flv = NULL;
int nb_flv = 0;
if ((err = hevc->mux_avc2flv_enhanced(sh, SrsVideoAvcFrameTypeKeyFrame, SrsVideoHEVCFrameTraitPacketTypeSequenceStart, pkt->get_avsync_time(),
if ((err = hevc->mux_hevc2flv_enhanced(sh, SrsVideoAvcFrameTypeKeyFrame, SrsVideoHEVCFrameTraitPacketTypeSequenceStart, pkt->get_avsync_time(),
pkt->get_avsync_time(), &flv, &nb_flv)) != srs_success) {
return srs_error_wrap(err, "mux sequence header");
}

View File

@ -683,7 +683,7 @@ srs_error_t SrsSrtFrameBuilder::check_vps_sps_pps_change(SrsTsMessage *msg)
// h265 packet to flv packet.
char *flv = NULL;
int nb_flv = 0;
if ((err = hevc->mux_avc2flv_enhanced(sh,
if ((err = hevc->mux_hevc2flv_enhanced(sh,
SrsVideoAvcFrameTypeKeyFrame,
SrsVideoHEVCFrameTraitPacketTypeSequenceStart,
dts,

View File

@ -564,13 +564,15 @@ srs_error_t SrsRawHEVCStream::mux_ipb_frame(char *frame, int nb_frame, std::stri
return err;
}
srs_error_t SrsRawHEVCStream::mux_avc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char **flv, int *nb_flv)
srs_error_t SrsRawHEVCStream::mux_hevc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char **flv, int *nb_flv)
{
srs_error_t err = srs_success;
// for h265 in RTMP video payload, there is 5bytes header:
// 1bytes, FrameType | CodecID
// 1bytes, AVCPacketType
// Non-standard HEVC support using codec ID 12 in FLV video tag.
// This follows the conventional approach adopted by domestic CDN vendors in China.
// For h265 in RTMP video payload, there is 5bytes header:
// 1bytes, FrameType | CodecID (CodecID = 12 for HEVC)
// 1bytes, AVCPacketType (reused from AVC for compatibility)
// 3bytes, CompositionTime, the cts.
// @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
int size = (int)video.length() + 5;
@ -605,11 +607,13 @@ srs_error_t SrsRawHEVCStream::mux_avc2flv(std::string video, int8_t frame_type,
return err;
}
srs_error_t SrsRawHEVCStream::mux_avc2flv_enhanced(std::string video, int8_t frame_type, int8_t packet_type, uint32_t dts, uint32_t pts, char **flv, int *nb_flv)
srs_error_t SrsRawHEVCStream::mux_hevc2flv_enhanced(std::string video, int8_t frame_type, int8_t packet_type, uint32_t dts, uint32_t pts, char **flv, int *nb_flv)
{
srs_error_t err = srs_success;
// for h265 in RTMP video payload, there is 5bytes header:
// Standard enhanced-rtmp HEVC support using fourcc 'hvc1'.
// This is the more universal and standardized approach for HEVC in FLV/RTMP.
// For h265 in enhanced-rtmp video payload, there is 5bytes header:
// 1bytes, IsExHeader | FrameType | PacketType
// 4bytes, Video FourCC. AV1 = { 'a', 'v', '0', '1' }
// VP9 = { 'v', 'p', '0', '9' }

View File

@ -89,22 +89,28 @@ public:
// @param ibp output the packet.
// @param frame_type output the frame type.
virtual srs_error_t mux_ipb_frame(char *frame, int nb_frame, std::string &ibp);
// Mux the hevc video packet to flv video packet.
// Mux the hevc video packet to flv video packet using non-standard HEVC codec ID.
// This method uses the conventional approach adopted by domestic CDN vendors in China,
// which adds a new codecID (12) to the FLV video tag for HEVC support.
// NOTE: This is a non-standard extension compared to enhanced-rtmp.
// The enhanced-rtmp approach (mux_hevc2flv_enhanced) is more universal and recommended.
// @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame.
// @param avc_packet_type, SrsVideoAvcFrameTraitSequenceHeader or SrsVideoAvcFrameTraitNALU.
// @param video the hevc raw data.
// @param flv output the muxed flv packet.
// @param nb_flv output the muxed flv size.
virtual srs_error_t mux_avc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char **flv, int *nb_flv);
// Mux the hevc video packet to flv video packet, enhanced mode.
virtual srs_error_t mux_hevc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char **flv, int *nb_flv);
// Mux the hevc video packet to flv video packet using enhanced-rtmp standard.
// This method follows the enhanced-rtmp specification, which is the more universal
// and standardized approach for HEVC support in FLV/RTMP streams.
// Enhanced-rtmp uses fourcc 'hvc1' for HEVC codec identification instead of codec ID.
// @see https://veovera.org/docs/enhanced/enhanced-rtmp-v1.pdf
// @param packet_type, SrsVideoHEVCFrameTraitPacketTypeSequenceStart or SrsVideoHEVCFrameTraitPacketTypeCodedFrames.
// @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame.
// @param video the hevc raw data.
// @param flv output the muxed flv packet.
// @param nb_flv output the muxed flv size.
// TODO: Rename method to mux_hevc2flv_enhanced since AVC is an alias for H.264, not H.265/HEVC.
// This affects other modules like SRT and GB28181, so should be done in a separate refactoring.
virtual srs_error_t mux_avc2flv_enhanced(std::string video, int8_t frame_type, int8_t packet_type, uint32_t dts, uint32_t pts, char **flv, int *nb_flv);
virtual srs_error_t mux_hevc2flv_enhanced(std::string video, int8_t frame_type, int8_t packet_type, uint32_t dts, uint32_t pts, char **flv, int *nb_flv);
};
// The header of adts sample.

View File

@ -760,13 +760,13 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxIpbFrame)
}
}
VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flv)
VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxHevc2flv)
{
srs_error_t err = srs_success;
SrsRawHEVCStream hevc;
// Test mux_avc2flv with sequence header
// Test mux_hevc2flv with sequence header
if (true) {
std::string video_data = std::string("\x01\x64\x00\x20\xff\xe1\x00\x19\x67\x64\x00\x20", 12);
int8_t frame_type = 1; // keyframe
@ -776,7 +776,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flv)
char *flv_data = NULL;
int nb_flv = 0;
HELPER_EXPECT_SUCCESS(hevc.mux_avc2flv(video_data, frame_type, avc_packet_type, dts, pts, &flv_data, &nb_flv));
HELPER_EXPECT_SUCCESS(hevc.mux_hevc2flv(video_data, frame_type, avc_packet_type, dts, pts, &flv_data, &nb_flv));
// Should produce FLV packet with 5-byte header + video data
EXPECT_TRUE(flv_data != NULL);
@ -798,7 +798,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flv)
}
}
// Test mux_avc2flv with NALU frame
// Test mux_hevc2flv with NALU frame
if (true) {
std::string video_data = std::string("\x00\x00\x00\x0e\x26\x01\xaf\x06\xb8\x63\xef\x3a\x7f\x3c\x00\x01\x00\x80", 18);
int8_t frame_type = 1; // keyframe
@ -808,7 +808,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flv)
char *flv_data = NULL;
int nb_flv = 0;
HELPER_EXPECT_SUCCESS(hevc.mux_avc2flv(video_data, frame_type, avc_packet_type, dts, pts, &flv_data, &nb_flv));
HELPER_EXPECT_SUCCESS(hevc.mux_hevc2flv(video_data, frame_type, avc_packet_type, dts, pts, &flv_data, &nb_flv));
EXPECT_TRUE(flv_data != NULL);
EXPECT_EQ(5 + video_data.length(), nb_flv);
@ -822,7 +822,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flv)
}
}
// Test mux_avc2flv with inter frame
// Test mux_hevc2flv with inter frame
if (true) {
std::string video_data = std::string("\x00\x00\x00\x08\x02\x01\xd0\x80\x93\x25\x88\x84", 12);
int8_t frame_type = 2; // inter frame
@ -832,7 +832,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flv)
char *flv_data = NULL;
int nb_flv = 0;
HELPER_EXPECT_SUCCESS(hevc.mux_avc2flv(video_data, frame_type, avc_packet_type, dts, pts, &flv_data, &nb_flv));
HELPER_EXPECT_SUCCESS(hevc.mux_hevc2flv(video_data, frame_type, avc_packet_type, dts, pts, &flv_data, &nb_flv));
EXPECT_TRUE(flv_data != NULL);
if (flv_data) {
@ -842,7 +842,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flv)
}
}
// Test mux_avc2flv with empty video data
// Test mux_hevc2flv with empty video data
if (true) {
std::string empty_video_data;
int8_t frame_type = 1; // keyframe
@ -852,7 +852,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flv)
char *flv_data = NULL;
int nb_flv = 0;
HELPER_EXPECT_SUCCESS(hevc.mux_avc2flv(empty_video_data, frame_type, avc_packet_type, dts, pts, &flv_data, &nb_flv));
HELPER_EXPECT_SUCCESS(hevc.mux_hevc2flv(empty_video_data, frame_type, avc_packet_type, dts, pts, &flv_data, &nb_flv));
// Should produce FLV packet with 5-byte header only
EXPECT_TRUE(flv_data != NULL);
@ -871,7 +871,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flv)
}
}
// Test mux_avc2flv with large composition time offset
// Test mux_hevc2flv with large composition time offset
if (true) {
std::string video_data = std::string("\x00\x00\x00\x04\x26\x01\xaf\x06", 8);
int8_t frame_type = 1; // keyframe
@ -881,7 +881,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flv)
char *flv_data = NULL;
int nb_flv = 0;
HELPER_EXPECT_SUCCESS(hevc.mux_avc2flv(video_data, frame_type, avc_packet_type, dts, pts, &flv_data, &nb_flv));
HELPER_EXPECT_SUCCESS(hevc.mux_hevc2flv(video_data, frame_type, avc_packet_type, dts, pts, &flv_data, &nb_flv));
EXPECT_TRUE(flv_data != NULL);
if (flv_data) {
@ -894,13 +894,13 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flv)
}
}
VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flvEnhanced)
VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxHevc2flvEnhanced)
{
srs_error_t err = srs_success;
SrsRawHEVCStream hevc;
// Test mux_avc2flv_enhanced with sequence header
// Test mux_hevc2flv_enhanced with sequence header
if (true) {
std::string video_data = std::string("\x01\x64\x00\x20\xff\xe1\x00\x19\x67\x64\x00\x20", 12);
int8_t frame_type = 1; // keyframe
@ -910,7 +910,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flvEnhanced)
char *flv_data = NULL;
int nb_flv = 0;
HELPER_EXPECT_SUCCESS(hevc.mux_avc2flv_enhanced(video_data, frame_type, packet_type, dts, pts, &flv_data, &nb_flv));
HELPER_EXPECT_SUCCESS(hevc.mux_hevc2flv_enhanced(video_data, frame_type, packet_type, dts, pts, &flv_data, &nb_flv));
// Should produce enhanced FLV packet with 5-byte header + video data
EXPECT_TRUE(flv_data != NULL);
@ -936,7 +936,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flvEnhanced)
}
}
// Test mux_avc2flv_enhanced with coded frames
// Test mux_hevc2flv_enhanced with coded frames
if (true) {
std::string video_data = std::string("\x00\x00\x00\x0e\x26\x01\xaf\x06\xb8\x63\xef\x3a\x7f\x3c\x00\x01\x00\x80", 18);
int8_t frame_type = 1; // keyframe
@ -946,7 +946,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flvEnhanced)
char *flv_data = NULL;
int nb_flv = 0;
HELPER_EXPECT_SUCCESS(hevc.mux_avc2flv_enhanced(video_data, frame_type, packet_type, dts, pts, &flv_data, &nb_flv));
HELPER_EXPECT_SUCCESS(hevc.mux_hevc2flv_enhanced(video_data, frame_type, packet_type, dts, pts, &flv_data, &nb_flv));
EXPECT_TRUE(flv_data != NULL);
EXPECT_EQ(5 + video_data.length(), nb_flv);
@ -960,7 +960,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flvEnhanced)
}
}
// Test mux_avc2flv_enhanced with inter frame
// Test mux_hevc2flv_enhanced with inter frame
if (true) {
std::string video_data = std::string("\x00\x00\x00\x08\x02\x01\xd0\x80\x93\x25\x88\x84", 12);
int8_t frame_type = 2; // inter frame
@ -970,7 +970,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flvEnhanced)
char *flv_data = NULL;
int nb_flv = 0;
HELPER_EXPECT_SUCCESS(hevc.mux_avc2flv_enhanced(video_data, frame_type, packet_type, dts, pts, &flv_data, &nb_flv));
HELPER_EXPECT_SUCCESS(hevc.mux_hevc2flv_enhanced(video_data, frame_type, packet_type, dts, pts, &flv_data, &nb_flv));
EXPECT_TRUE(flv_data != NULL);
if (flv_data) {
@ -982,7 +982,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flvEnhanced)
}
}
// Test mux_avc2flv_enhanced with sequence end packet
// Test mux_hevc2flv_enhanced with sequence end packet
if (true) {
std::string video_data; // Empty for sequence end
int8_t frame_type = 1; // keyframe
@ -992,7 +992,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flvEnhanced)
char *flv_data = NULL;
int nb_flv = 0;
HELPER_EXPECT_SUCCESS(hevc.mux_avc2flv_enhanced(video_data, frame_type, packet_type, dts, pts, &flv_data, &nb_flv));
HELPER_EXPECT_SUCCESS(hevc.mux_hevc2flv_enhanced(video_data, frame_type, packet_type, dts, pts, &flv_data, &nb_flv));
EXPECT_TRUE(flv_data != NULL);
EXPECT_EQ(5, nb_flv); // Should produce 5-byte header only
@ -1014,7 +1014,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flvEnhanced)
}
}
// Test mux_avc2flv_enhanced with different frame types
// Test mux_hevc2flv_enhanced with different frame types
if (true) {
std::string video_data = std::string("\x00\x00\x00\x06\x04\x01\x70\x80\x12\x34", 10);
int8_t frame_type = 3; // disposable inter frame
@ -1024,7 +1024,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flvEnhanced)
char *flv_data = NULL;
int nb_flv = 0;
HELPER_EXPECT_SUCCESS(hevc.mux_avc2flv_enhanced(video_data, frame_type, packet_type, dts, pts, &flv_data, &nb_flv));
HELPER_EXPECT_SUCCESS(hevc.mux_hevc2flv_enhanced(video_data, frame_type, packet_type, dts, pts, &flv_data, &nb_flv));
EXPECT_TRUE(flv_data != NULL);
if (flv_data) {
@ -1036,7 +1036,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flvEnhanced)
}
}
// Test mux_avc2flv_enhanced with empty video data
// Test mux_hevc2flv_enhanced with empty video data
if (true) {
std::string empty_video_data;
int8_t frame_type = 1; // keyframe
@ -1046,7 +1046,7 @@ VOID TEST(ProtocolRawAvcTest, SrsRawHEVCStreamMuxAvc2flvEnhanced)
char *flv_data = NULL;
int nb_flv = 0;
HELPER_EXPECT_SUCCESS(hevc.mux_avc2flv_enhanced(empty_video_data, frame_type, packet_type, dts, pts, &flv_data, &nb_flv));
HELPER_EXPECT_SUCCESS(hevc.mux_hevc2flv_enhanced(empty_video_data, frame_type, packet_type, dts, pts, &flv_data, &nb_flv));
// Should produce enhanced FLV packet with 5-byte header only
EXPECT_TRUE(flv_data != NULL);