From 2cab19629723563b89f7c1de38678f5347c57bc1 Mon Sep 17 00:00:00 2001 From: tao3 Date: Sat, 13 Jul 2024 14:37:04 +0800 Subject: [PATCH] change: add flv enhanced rtmp flag --- libflv/include/flv-header.h | 2 + libflv/include/flv-muxer.h | 3 ++ libflv/source/flv-header.c | 85 ++++++++++++++++++------------------- libflv/source/flv-muxer.c | 25 ++++++++--- 4 files changed, 66 insertions(+), 49 deletions(-) diff --git a/libflv/include/flv-header.h b/libflv/include/flv-header.h index e11f1d45..1dfa3696 100644 --- a/libflv/include/flv-header.h +++ b/libflv/include/flv-header.h @@ -41,6 +41,8 @@ struct flv_video_tag_header_t uint8_t keyframe; /// video frame type: 1-key frame, 2-inter frame uint8_t avpacket; /// H.264/H.265/AV1 only:FLV_SEQUENCE_HEADER/FLV_AVPACKET/FLV_END_OF_SEQUENCE int32_t cts; /// video composition time(PTS - DTS), AVC/HEVC/AV1 only + + int enhanced_rtmp; /// https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp.pdf }; /// Read FLV File Header diff --git a/libflv/include/flv-muxer.h b/libflv/include/flv-muxer.h index 1afe22b4..1fb51615 100644 --- a/libflv/include/flv-muxer.h +++ b/libflv/include/flv-muxer.h @@ -23,6 +23,9 @@ void flv_muxer_destroy(flv_muxer_t* muxer); /// re-create AAC/AVC sequence header int flv_muxer_reset(flv_muxer_t* muxer); +/// @param[in] enable muxer h264 with enhance rtmp +void flv_muxer_set_enhanced_rtmp(flv_muxer_t* muxer, int enable); + /// @param[in] data AAC ADTS stream, 0xFFF15C40011FFC... int flv_muxer_aac(flv_muxer_t* muxer, const void* data, size_t bytes, uint32_t pts, uint32_t dts); diff --git a/libflv/source/flv-header.c b/libflv/source/flv-header.c index 73760346..e6ce3060 100644 --- a/libflv/source/flv-header.c +++ b/libflv/source/flv-header.c @@ -236,58 +236,57 @@ int flv_audio_tag_header_write(const struct flv_audio_tag_header_t* audio, uint8 int flv_video_tag_header_write(const struct flv_video_tag_header_t* video, uint8_t* buf, size_t len) { -#ifdef FLV_ENHANCE_RTMP // https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp.pdf + if (video->enhanced_rtmp) + { + if (len < 5) + return -1; - if (len < 5) - return -1; + buf[0] = 0x80 | (video->keyframe << 4) /*FrameType*/; + buf[0] |= (0 == video->cts && FLV_AVPACKET == video->avpacket) ? FLV_PACKET_TYPE_CODED_FRAMES_X : video->avpacket; - buf[0] = 0x80 | (video->keyframe << 4) /*FrameType*/; - buf[0] |= (0 == video->cts && FLV_AVPACKET == video->avpacket) ? FLV_PACKET_TYPE_CODED_FRAMES_X : video->avpacket; + switch (video->codecid) + { + case FLV_VIDEO_AV1: + buf[1] = (FLV_VIDEO_FOURCC_AV1 >> 24) & 0xFF; + buf[2] = (FLV_VIDEO_FOURCC_AV1 >> 16) & 0xFF; + buf[3] = (FLV_VIDEO_FOURCC_AV1 >> 8) & 0xFF; + buf[4] = (FLV_VIDEO_FOURCC_AV1) & 0xFF; + return 5; - switch (video->codecid) - { - case FLV_VIDEO_AV1: - buf[1] = (FLV_VIDEO_FOURCC_AV1 >> 24) & 0xFF; - buf[2] = (FLV_VIDEO_FOURCC_AV1 >> 16) & 0xFF; - buf[3] = (FLV_VIDEO_FOURCC_AV1 >> 8) & 0xFF; - buf[4] = (FLV_VIDEO_FOURCC_AV1) & 0xFF; - return 5; + case FLV_VIDEO_H265: + buf[1] = (FLV_VIDEO_FOURCC_HEVC >> 24) & 0xFF; + buf[2] = (FLV_VIDEO_FOURCC_HEVC >> 16) & 0xFF; + buf[3] = (FLV_VIDEO_FOURCC_HEVC >> 8) & 0xFF; + buf[4] = (FLV_VIDEO_FOURCC_HEVC) & 0xFF; + if (len >= 8 && FLV_AVPACKET == video->avpacket && video->cts != 0) + { + buf[5] = (video->cts >> 16) & 0xFF; + buf[6] = (video->cts >> 8) & 0xFF; + buf[7] = video->cts & 0xFF; + return 8; + } + return 5; - case FLV_VIDEO_H265: - buf[1] = (FLV_VIDEO_FOURCC_HEVC >> 24) & 0xFF; - buf[2] = (FLV_VIDEO_FOURCC_HEVC >> 16) & 0xFF; - buf[3] = (FLV_VIDEO_FOURCC_HEVC >> 8) & 0xFF; - buf[4] = (FLV_VIDEO_FOURCC_HEVC) & 0xFF; - if (len >= 8 && FLV_AVPACKET == video->avpacket && video->cts != 0) - { - buf[5] = (video->cts >> 16) & 0xFF; - buf[6] = (video->cts >> 8) & 0xFF; - buf[7] = video->cts & 0xFF; - return 8; - } - return 5; + case FLV_VIDEO_H266: + buf[1] = (FLV_VIDEO_FOURCC_VVC >> 24) & 0xFF; + buf[2] = (FLV_VIDEO_FOURCC_VVC >> 16) & 0xFF; + buf[3] = (FLV_VIDEO_FOURCC_VVC >> 8) & 0xFF; + buf[4] = (FLV_VIDEO_FOURCC_VVC) & 0xFF; + if (len >= 8 && FLV_AVPACKET == video->avpacket && video->cts != 0) + { + buf[5] = (video->cts >> 16) & 0xFF; + buf[6] = (video->cts >> 8) & 0xFF; + buf[7] = video->cts & 0xFF; + return 8; + } + return 5; - case FLV_VIDEO_H266: - buf[1] = (FLV_VIDEO_FOURCC_VVC >> 24) & 0xFF; - buf[2] = (FLV_VIDEO_FOURCC_VVC >> 16) & 0xFF; - buf[3] = (FLV_VIDEO_FOURCC_VVC >> 8) & 0xFF; - buf[4] = (FLV_VIDEO_FOURCC_VVC) & 0xFF; - if (len >= 8 && FLV_AVPACKET == video->avpacket && video->cts != 0) - { - buf[5] = (video->cts >> 16) & 0xFF; - buf[6] = (video->cts >> 8) & 0xFF; - buf[7] = video->cts & 0xFF; - return 8; + default: + break; // fallthrough } - return 5; - - default: - break; // fallthrough } -#endif - if (len < 1) return -1; diff --git a/libflv/source/flv-muxer.c b/libflv/source/flv-muxer.c index 6597fab9..87df4ead 100644 --- a/libflv/source/flv-muxer.c +++ b/libflv/source/flv-muxer.c @@ -24,6 +24,8 @@ struct flv_muxer_t flv_muxer_handler handler; void* param; + int enhanced_rtmp; // support enhance rtmp extension + uint8_t audio_sequence_header; uint8_t video_sequence_header; @@ -59,6 +61,9 @@ struct flv_muxer_t* flv_muxer_create(flv_muxer_handler handler, void* param) flv_muxer_reset(flv); flv->handler = handler; flv->param = param; +#ifdef FLV_ENHANCE_RTMP + flv->enhanced_rtmp = 1; +#endif return flv; } @@ -82,6 +87,11 @@ int flv_muxer_reset(struct flv_muxer_t* flv) return 0; } +void flv_muxer_set_enhanced_rtmp(flv_muxer_t* muxer, int enable) +{ + muxer->enhanced_rtmp = enable; +} + static int flv_muxer_alloc(struct flv_muxer_t* flv, size_t bytes) { void* p; @@ -261,6 +271,7 @@ static int flv_muxer_h264(struct flv_muxer_t* flv, uint32_t pts, uint32_t dts) struct flv_video_tag_header_t video; video.codecid = FLV_VIDEO_H264; + video.enhanced_rtmp = flv->enhanced_rtmp; if ( /*0 == flv->video_sequence_header &&*/ flv->update && flv->v.avc.nb_sps > 0 && flv->v.avc.nb_pps > 0) { video.cts = 0; @@ -313,6 +324,7 @@ static int flv_muxer_h265(struct flv_muxer_t* flv, uint32_t pts, uint32_t dts) struct flv_video_tag_header_t video; video.codecid = FLV_VIDEO_H265; + video.enhanced_rtmp = flv->enhanced_rtmp; if ( /*0 == flv->avc_sequence_header &&*/ flv->update && flv->v.hevc.numOfArrays >= 3) // vps + sps + pps { video.cts = 0; @@ -351,9 +363,8 @@ int flv_muxer_hevc(struct flv_muxer_t* flv, const void* data, size_t bytes, uint } flv->bytes = 5; -#ifdef FLV_ENHANCE_RTMP - flv->bytes += dts == pts ? 0 : 3; -#endif + if(flv->enhanced_rtmp) + flv->bytes += dts == pts ? 0 : 3; flv->bytes += h265_annexbtomp4(&flv->v.hevc, data, bytes, flv->ptr + flv->bytes, flv->capacity - flv->bytes, &flv->vcl, &flv->update); if (flv->bytes <= 5) return -ENOMEM; @@ -368,6 +379,7 @@ static int flv_muxer_h266(struct flv_muxer_t* flv, uint32_t pts, uint32_t dts) struct flv_video_tag_header_t video; video.codecid = FLV_VIDEO_H266; + video.enhanced_rtmp = flv->enhanced_rtmp; if ( /*0 == flv->avc_sequence_header &&*/ flv->update && flv->v.vvc.numOfArrays >= 3) // vps + sps + pps { video.cts = 0; @@ -406,9 +418,8 @@ int flv_muxer_vvc(struct flv_muxer_t* flv, const void* data, size_t bytes, uint3 } flv->bytes = 5; -#ifdef FLV_ENHANCE_RTMP - flv->bytes += dts == pts ? 0 : 3; -#endif + if(flv->enhanced_rtmp) + flv->bytes += dts == pts ? 0 : 3; flv->bytes += h266_annexbtomp4(&flv->v.vvc, data, bytes, flv->ptr + flv->bytes, flv->capacity - flv->bytes, &flv->vcl, &flv->update); if (flv->bytes <= 5) return -ENOMEM; @@ -429,6 +440,7 @@ int flv_muxer_av1(flv_muxer_t* flv, const void* data, size_t bytes, uint32_t pts } video.codecid = FLV_VIDEO_AV1; + video.enhanced_rtmp = flv->enhanced_rtmp; if (0 == flv->video_sequence_header) { // load av1 information @@ -476,6 +488,7 @@ int flv_muxer_avs3(flv_muxer_t* flv, const void* data, size_t bytes, uint32_t pt } video.codecid = FLV_VIDEO_H266; // codec 14, same as H.266 + video.enhanced_rtmp = flv->enhanced_rtmp; if (0 == flv->video_sequence_header) { // load avs information