Commit bd8ad2ea by 夏楚 Committed by GitHub

优化enhanced-rtmp解析性能 (#2717)

parent 00b3c518
...@@ -257,50 +257,75 @@ void RtmpHandshake::random_generate(char *bytes, int size) { ...@@ -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 { ...@@ -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
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论