各协议全面支持vp8/vp9/av1编码,ertmp新增支持opus编码 (#4498)

实现功能:
- rtp 增加vp8,vp9和av1编码支持
- 实现MP4录像所需的extra_data接口
- 扩展rtmp增加对opus、vp8、vp9和av1的支持

已知问题:
- 开启enhance rtmp后,ffmpeg暂时不支持播放vp8编码格式,其他格式的支持
- vp9和av1开始播放时容易遇到卡顿情况,过几秒后好了,原因暂时未知

---------

Co-authored-by: xia-chu <771730766@qq.com>
This commit is contained in:
mtdxc
2025-10-16 19:26:46 +08:00
committed by GitHub
parent 046bdecd1e
commit b003eb3eec
26 changed files with 1609 additions and 69 deletions

View File

@@ -21,6 +21,8 @@ namespace mediakit {
static std::unordered_map<int, const CodecPlugin *> s_plugins;
REGISTER_CODEC(vp8_plugin);
REGISTER_CODEC(vp9_plugin);
REGISTER_CODEC(h264_plugin);
REGISTER_CODEC(h265_plugin);
REGISTER_CODEC(av1_plugin);
@@ -97,10 +99,15 @@ static CodecId getVideoCodecIdByAmf(const AMFValue &val) {
if (val.type() != AMF_NULL) {
auto type_id = (RtmpVideoCodec)val.as_integer();
switch (type_id) {
case RtmpVideoCodec::fourcc_avc1:
case RtmpVideoCodec::h264: return CodecH264;
case RtmpVideoCodec::fourcc_hevc:
case RtmpVideoCodec::h265: return CodecH265;
case RtmpVideoCodec::av1:
case RtmpVideoCodec::fourcc_av1: return CodecAV1;
case RtmpVideoCodec::vp8:
case RtmpVideoCodec::fourcc_vp8: return CodecVP8;
case RtmpVideoCodec::vp9:
case RtmpVideoCodec::fourcc_vp9: return CodecVP9;
default: WarnL << "Unsupported codec: " << (int)type_id; return CodecInvalid;
}
@@ -191,15 +198,16 @@ AMFValue Factory::getAmfByCodecId(CodecId codecId) {
GET_CONFIG(bool, enhanced, Rtmp::kEnhanced);
switch (codecId) {
case CodecAAC: return AMFValue((int)RtmpAudioCodec::aac);
case CodecH264: return AMFValue((int)RtmpVideoCodec::h264);
case CodecH264: return enhanced ? AMFValue((int)RtmpVideoCodec::fourcc_avc1) : AMFValue((int)RtmpVideoCodec::h264);
case CodecH265: return enhanced ? AMFValue((int)RtmpVideoCodec::fourcc_hevc) : AMFValue((int)RtmpVideoCodec::h265);
case CodecG711A: return AMFValue((int)RtmpAudioCodec::g711a);
case CodecG711U: return AMFValue((int)RtmpAudioCodec::g711u);
case CodecOpus: return AMFValue((int)RtmpAudioCodec::opus);
case CodecADPCM: return AMFValue((int)RtmpAudioCodec::adpcm);
case CodecMP3: return AMFValue((int)RtmpAudioCodec::mp3);
case CodecAV1: return AMFValue((int)RtmpVideoCodec::fourcc_av1);
case CodecVP9: return AMFValue((int)RtmpVideoCodec::fourcc_vp9);
case CodecAV1: return enhanced ? AMFValue((int)RtmpVideoCodec::fourcc_av1) : AMFValue((int)RtmpVideoCodec::av1);
case CodecVP8: return enhanced ? AMFValue((int)RtmpVideoCodec::fourcc_vp8) : AMFValue((int)RtmpVideoCodec::vp8);
case CodecVP9: return enhanced ? AMFValue((int)RtmpVideoCodec::fourcc_vp9) : AMFValue((int)RtmpVideoCodec::vp9);
default: return AMFValue(AMF_NULL);
}
}

View File

@@ -195,16 +195,21 @@ public:
_fps = fps;
}
VideoTrackImp(CodecId codec_id) {
_codec_id = codec_id;
_fps = 30;
}
int getVideoWidth() const override { return _width; }
int getVideoHeight() const override { return _height; }
float getVideoFps() const override { return _fps; }
bool ready() const override { return true; }
bool ready() const override { return _width > 0 && _height > 0; }
Track::Ptr clone() const override { return std::make_shared<VideoTrackImp>(*this); }
Sdp::Ptr getSdp(uint8_t payload_type) const override;
CodecId getCodecId() const override { return _codec_id; }
private:
protected:
CodecId _codec_id;
int _width = 0;
int _height = 0;
@@ -324,7 +329,7 @@ public:
Track::Ptr clone() const override { return std::make_shared<AudioTrackImp>(*this); }
Sdp::Ptr getSdp(uint8_t payload_type) const override;
private:
protected:
CodecId _codecid;
int _sample_rate;
int _channels;

View File

@@ -271,6 +271,8 @@ CodecId parseVideoRtmpPacket(const uint8_t *data, size_t size, RtmpPacketInfo *i
switch ((RtmpVideoCodec)ntohl(enhanced_header->fourcc)) {
case RtmpVideoCodec::fourcc_av1: info->codec = CodecAV1; break;
case RtmpVideoCodec::fourcc_vp9: info->codec = CodecVP9; break;
case RtmpVideoCodec::fourcc_vp8: info->codec = CodecVP8; break;
case RtmpVideoCodec::fourcc_avc1: info->codec = CodecH264; break;
case RtmpVideoCodec::fourcc_hevc: info->codec = CodecH265; break;
default: WarnL << "Rtmp video codec not supported: " << std::string((char *)data + 1, 4);
}
@@ -292,6 +294,21 @@ CodecId parseVideoRtmpPacket(const uint8_t *data, size_t size, RtmpPacketInfo *i
info->video.h264_pkt_type = (RtmpH264PacketType)classic_header->h264_pkt_type;
break;
}
case RtmpVideoCodec::vp8: {
CHECK(size >= 0, "Invalid rtmp buffer size: ", size);
info->codec = CodecVP8;
break;
}
case RtmpVideoCodec::vp9: {
CHECK(size >= 0, "Invalid rtmp buffer size: ", size);
info->codec = CodecVP9;
break;
}
case RtmpVideoCodec::av1: {
CHECK(size >= 0, "Invalid rtmp buffer size: ", size);
info->codec = CodecAV1;
break;
}
default: WarnL << "Rtmp video codec not supported: " << (int)classic_header->codec_id; break;
}
}

View File

@@ -306,11 +306,15 @@ enum class RtmpVideoCodec : uint32_t {
screen_video2 = 6, // Screen video version 2
h264 = 7, // avc
h265 = 12, // 国内扩展
av1 = 13,
vp8 = 14,
vp9 = 15,
// 增强型rtmp FourCC [AUTO-TRANSLATED:442b77fb]
// Enhanced rtmp FourCC
fourcc_vp8 = MKBETAG('v', 'p', '0', '8'),
fourcc_vp9 = MKBETAG('v', 'p', '0', '9'),
fourcc_av1 = MKBETAG('a', 'v', '0', '1'),
fourcc_avc1 = MKBETAG('a', 'v', 'c', '1'),
fourcc_hevc = MKBETAG('h', 'v', 'c', '1')
};
@@ -375,6 +379,7 @@ enum class RtmpAudioCodec : uint8_t {
mp3 = 2,
g711a = 7,
g711u = 8,
FOURCC = 9, // Enhanced audio
aac = 10,
opus = 13 // 国内扩展
};