mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
优化enhanced-rtmp解析性能 (#2717)
This commit is contained in:
parent
00b3c5184a
commit
bd8ad2eabf
@ -257,50 +257,75 @@ void RtmpHandshake::random_generate(char *bytes, int size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
struct RtmpVideoHeaderEnhanced {
|
||||||
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
uint8_t enhanced : 1;
|
||||||
|
uint8_t frame_type : 3;
|
||||||
|
uint8_t pkt_type : 4;
|
||||||
|
uint32_t fourcc;
|
||||||
|
#else
|
||||||
|
uint8_t pkt_type : 4;
|
||||||
|
uint8_t frame_type : 3;
|
||||||
|
uint8_t enhanced : 1;
|
||||||
|
uint32_t fourcc;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RtmpVideoHeaderClassic {
|
||||||
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
uint8_t frame_type : 4;
|
||||||
|
uint8_t codec_id : 4;
|
||||||
|
uint8_t h264_pkt_type;
|
||||||
|
#else
|
||||||
|
uint8_t codec_id : 4;
|
||||||
|
uint8_t frame_type : 4;
|
||||||
|
uint8_t h264_pkt_type;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
CodecId parseVideoRtmpPacket(const uint8_t *data, size_t size, RtmpPacketInfo *info) {
|
CodecId parseVideoRtmpPacket(const uint8_t *data, size_t size, RtmpPacketInfo *info) {
|
||||||
RtmpPacketInfo save;
|
RtmpPacketInfo save;
|
||||||
info = info ? info : &save;
|
info = info ? info : &save;
|
||||||
info->codec = CodecInvalid;
|
info->codec = CodecInvalid;
|
||||||
|
|
||||||
CHECK(size > 0);
|
CHECK(size > 0);
|
||||||
if (data[0] >> 7) {
|
RtmpVideoHeaderEnhanced *enhanced_header = (RtmpVideoHeaderEnhanced *)data;
|
||||||
|
if (enhanced_header->enhanced) {
|
||||||
// IsExHeader == 1
|
// IsExHeader == 1
|
||||||
CHECK(size >= 5, "Invalid rtmp buffer size: ", size);
|
CHECK(size >= 5, "Invalid rtmp buffer size: ", size);
|
||||||
info->is_enhanced = true;
|
info->is_enhanced = true;
|
||||||
info->video.frame_type = (RtmpFrameType)((data[0] >> 4) & 0x07);
|
info->video.frame_type = (RtmpFrameType)(enhanced_header->frame_type);
|
||||||
info->video.pkt_type = (RtmpPacketType)(data[0] & 0x0f);
|
info->video.pkt_type = (RtmpPacketType)(enhanced_header->pkt_type);
|
||||||
if (memcmp(data + 1, "av01", 4) == 0) {
|
|
||||||
// AV1
|
switch (ntohl(enhanced_header->fourcc)) {
|
||||||
info->codec = CodecAV1;
|
case fourcc_av1: info->codec = CodecAV1; break;
|
||||||
} else if (memcmp(data + 1, "vp09", 4) == 0) {
|
case fourcc_vp9: info->codec = CodecVP9; break;
|
||||||
// VP9
|
case fourcc_hevc: info->codec = CodecH265; break;
|
||||||
info->codec = CodecVP9;
|
default: WarnL << "Rtmp video codec not supported: " << std::string((char *)data + 1, 4);
|
||||||
} else if (memcmp(data + 1, "hvc1", 4) == 0) {
|
|
||||||
// HEVC(H265)
|
|
||||||
info->codec = CodecH265;
|
|
||||||
} else {
|
|
||||||
WarnL << "Rtmp video codec not supported: " << std::string((char *)data + 1, 4);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// IsExHeader == 0
|
// IsExHeader == 0
|
||||||
|
RtmpVideoHeaderClassic *classic_header = (RtmpVideoHeaderClassic *)data;
|
||||||
info->is_enhanced = false;
|
info->is_enhanced = false;
|
||||||
info->video.frame_type = (RtmpFrameType)(data[0] >> 4);
|
info->video.frame_type = (RtmpFrameType)(classic_header->frame_type);
|
||||||
auto rtmp_codec = (RtmpVideoCodec)(data[0] & 0x0f);
|
switch ((RtmpVideoCodec)(classic_header->codec_id)) {
|
||||||
|
|
||||||
switch (rtmp_codec) {
|
|
||||||
case RtmpVideoCodec::h264: {
|
case RtmpVideoCodec::h264: {
|
||||||
CHECK(size >= 1, "Invalid rtmp buffer size: ", size);
|
CHECK(size >= 1, "Invalid rtmp buffer size: ", size);
|
||||||
info->codec = CodecH264;
|
info->codec = CodecH264;
|
||||||
info->video.h264_pkt_type = (RtmpH264PacketType)data[1];
|
info->video.h264_pkt_type = (RtmpH264PacketType)classic_header->h264_pkt_type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RtmpVideoCodec::h265: {
|
case RtmpVideoCodec::h265: {
|
||||||
CHECK(size >= 1, "Invalid rtmp buffer size: ", size);
|
CHECK(size >= 1, "Invalid rtmp buffer size: ", size);
|
||||||
info->codec = CodecH265;
|
info->codec = CodecH265;
|
||||||
info->video.h264_pkt_type = (RtmpH264PacketType)data[1];
|
info->video.h264_pkt_type = (RtmpH264PacketType)classic_header->h264_pkt_type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: WarnL << "Rtmp video codec not supported: " << (int)rtmp_codec; break;
|
default: WarnL << "Rtmp video codec not supported: " << (int)classic_header->codec_id; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return info->codec;
|
return info->codec;
|
||||||
|
@ -357,6 +357,12 @@ struct RtmpPacketInfo {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
// https://github.com/veovera/enhanced-rtmp
|
// https://github.com/veovera/enhanced-rtmp
|
||||||
|
|
||||||
|
// 增强型rtmp FourCC
|
||||||
|
static constexpr uint32_t fourcc_vp9 = 'vp09';
|
||||||
|
static constexpr uint32_t fourcc_av1 = 'av01';
|
||||||
|
static constexpr uint32_t fourcc_hevc = 'hvc1';
|
||||||
|
|
||||||
CodecId parseVideoRtmpPacket(const uint8_t *data, size_t size, RtmpPacketInfo *info = nullptr);
|
CodecId parseVideoRtmpPacket(const uint8_t *data, size_t size, RtmpPacketInfo *info = nullptr);
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
|
Loading…
Reference in New Issue
Block a user