From 9773314f78d20b3daaac00506a289a962e4cd509 Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Sun, 10 Dec 2023 09:48:31 +0800 Subject: [PATCH] feat: add support of codec plugin --- src/Extension/AAC.cpp | 75 +++++++++++++- src/Extension/Factory.cpp | 200 ++++++++++++-------------------------- src/Extension/Factory.h | 26 ++++- src/Extension/G711.cpp | 116 ++++++++++++++++++++++ src/Extension/H264.cpp | 62 +++++++++++- src/Extension/H265.cpp | 58 +++++++++++ src/Extension/JPEG.cpp | 51 ++++++++++ src/Extension/L16.cpp | 50 ++++++++++ src/Extension/Opus.cpp | 48 +++++++++ 9 files changed, 547 insertions(+), 139 deletions(-) diff --git a/src/Extension/AAC.cpp b/src/Extension/AAC.cpp index 148504ac..3c2974b0 100644 --- a/src/Extension/AAC.cpp +++ b/src/Extension/AAC.cpp @@ -9,6 +9,10 @@ */ #include "AAC.h" +#include "AACRtmp.h" +#include "AACRtp.h" +#include "Factory.h" +#include "Common/Parser.h" #ifdef ENABLE_MP4 #include "mpeg4-aac.h" #endif @@ -357,4 +361,73 @@ Sdp::Ptr AACTrack::getSdp(uint8_t payload_type) const { return std::make_shared(getExtraData()->toString(), payload_type, getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024); } -}//namespace mediakit \ No newline at end of file +namespace { + +CodecId getCodec() { + return CodecAAC; +} + +Track::Ptr getTrackByCodecId(int sample_rate, int channels, int sample_bit) { + return std::make_shared(); +} + +Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) { + string aac_cfg_str = findSubString(track->_fmtp.data(), "config=", ";"); + if (aac_cfg_str.empty()) { + aac_cfg_str = findSubString(track->_fmtp.data(), "config=", nullptr); + } + if (aac_cfg_str.empty()) { + // 如果sdp中获取不到aac config信息,那么在rtp也无法获取,那么忽略该Track + return nullptr; + } + string aac_cfg; + for (size_t i = 0; i < aac_cfg_str.size() / 2; ++i) { + unsigned int cfg; + sscanf(aac_cfg_str.substr(i * 2, 2).data(), "%02X", &cfg); + cfg &= 0x00FF; + aac_cfg.push_back((char)cfg); + } + return std::make_shared(aac_cfg); +} + +RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) { + return std::make_shared(); +} + +RtpCodec::Ptr getRtpDecoderByCodecId() { + return std::make_shared(); +} + +RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) { + return std::make_shared(track); +} + +RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) { + return std::make_shared(track); +} + +size_t aacPrefixSize(const char *data, size_t bytes) { + uint8_t *ptr = (uint8_t *)data; + size_t prefix = 0; + if (!(bytes > ADTS_HEADER_LEN && ptr[0] == 0xFF && (ptr[1] & 0xF0) == 0xF0)) { + return 0; + } + return ADTS_HEADER_LEN; +} + +Frame::Ptr getFrameFromPtr(const char *data, size_t bytes, uint64_t dts, uint64_t pts) { + return std::make_shared(CodecAAC, (char *)data, bytes, dts, pts, aacPrefixSize(data, bytes)); +} + +} // namespace + +CodecPlugin aac_plugin = { .getCodec = getCodec, + .getTrackByCodecId = getTrackByCodecId, + .getTrackBySdp = getTrackBySdp, + .getRtpEncoderByCodecId = getRtpEncoderByCodecId, + .getRtpDecoderByCodecId = getRtpDecoderByCodecId, + .getRtmpEncoderByTrack = getRtmpEncoderByTrack, + .getRtmpDecoderByTrack = getRtmpDecoderByTrack, + .getFrameFromPtr = getFrameFromPtr }; + +} // namespace mediakit \ No newline at end of file diff --git a/src/Extension/Factory.cpp b/src/Extension/Factory.cpp index b787a5f2..740aab6f 100644 --- a/src/Extension/Factory.cpp +++ b/src/Extension/Factory.cpp @@ -31,75 +31,45 @@ using namespace std; using namespace toolkit; -namespace mediakit{ +namespace mediakit { + +static std::unordered_map s_plugins; + +extern CodecPlugin h264_plugin; +extern CodecPlugin h265_plugin; +extern CodecPlugin jpeg_plugin; +extern CodecPlugin aac_plugin; +extern CodecPlugin opus_plugin; +extern CodecPlugin g711a_plugin; +extern CodecPlugin g711u_plugin; +extern CodecPlugin l16_plugin; + +REGISTER_CODEC(h264_plugin); +REGISTER_CODEC(h265_plugin); +REGISTER_CODEC(jpeg_plugin); +REGISTER_CODEC(aac_plugin); +REGISTER_CODEC(opus_plugin); +REGISTER_CODEC(g711a_plugin) +REGISTER_CODEC(g711u_plugin); +REGISTER_CODEC(l16_plugin); + +void Factory::registerPlugin(const CodecPlugin &plugin) { + InfoL << "Load codec: " << getCodecName(plugin.getCodec()); + s_plugins[(int)(plugin.getCodec())] = &plugin; +} Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) { auto codec = getCodecId(track->_codec); if (codec == CodecInvalid) { - //根据传统的payload type 获取编码类型以及采样率等信息 + // 根据传统的payload type 获取编码类型以及采样率等信息 codec = RtpPayload::getCodecId(track->_pt); } - switch (codec) { - case CodecG711A: - case CodecG711U: return std::make_shared(codec, track->_samplerate, track->_channel, 16); - case CodecL16: return std::make_shared(track->_samplerate, track->_channel); - case CodecOpus : return std::make_shared(); - - case CodecAAC : { - string aac_cfg_str = findSubString(track->_fmtp.data(), "config=", ";"); - if (aac_cfg_str.empty()) { - aac_cfg_str = findSubString(track->_fmtp.data(), "config=", nullptr); - } - if (aac_cfg_str.empty()) { - //如果sdp中获取不到aac config信息,那么在rtp也无法获取,那么忽略该Track - return nullptr; - } - string aac_cfg; - for (size_t i = 0; i < aac_cfg_str.size() / 2; ++i) { - unsigned int cfg; - sscanf(aac_cfg_str.substr(i * 2, 2).data(), "%02X", &cfg); - cfg &= 0x00FF; - aac_cfg.push_back((char) cfg); - } - return std::make_shared(aac_cfg); - } - - case CodecH264 : { - //a=fmtp:96 packetization-mode=1;profile-level-id=42C01F;sprop-parameter-sets=Z0LAH9oBQBboQAAAAwBAAAAPI8YMqA==,aM48gA== - auto map = Parser::parseArgs(track->_fmtp, ";", "="); - auto sps_pps = map["sprop-parameter-sets"]; - string base64_SPS = findSubString(sps_pps.data(), NULL, ","); - string base64_PPS = findSubString(sps_pps.data(), ",", NULL); - auto sps = decodeBase64(base64_SPS); - auto pps = decodeBase64(base64_PPS); - if (sps.empty() || pps.empty()) { - //如果sdp里面没有sps/pps,那么可能在后续的rtp里面恢复出sps/pps - return std::make_shared(); - } - return std::make_shared(sps, pps, 0, 0); - } - - case CodecH265: { - //a=fmtp:96 sprop-sps=QgEBAWAAAAMAsAAAAwAAAwBdoAKAgC0WNrkky/AIAAADAAgAAAMBlQg=; sprop-pps=RAHA8vA8kAA= - auto map = Parser::parseArgs(track->_fmtp, ";", "="); - auto vps = decodeBase64(map["sprop-vps"]); - auto sps = decodeBase64(map["sprop-sps"]); - auto pps = decodeBase64(map["sprop-pps"]); - if (sps.empty() || pps.empty()) { - //如果sdp里面没有sps/pps,那么可能在后续的rtp里面恢复出sps/pps - return std::make_shared(); - } - return std::make_shared(vps, sps, pps, 0, 0, 0); - } - - case CodecJPEG : return std::make_shared(); - - default: { - //其他codec不支持 - WarnL << "Unsupported rtsp sdp: " << track->getName(); - return nullptr; - } + auto it = s_plugins.find(codec); + if (it == s_plugins.end()) { + WarnL << "Unsupported codec: " << track->getName(); + return nullptr; } + return it->second->getTrackBySdp(track); } Track::Ptr Factory::getTrackByAbstractTrack(const Track::Ptr &track) { @@ -111,37 +81,22 @@ Track::Ptr Factory::getTrackByAbstractTrack(const Track::Ptr &track) { return getTrackByCodecId(codec, audio_track->getAudioSampleRate(), audio_track->getAudioChannel(), audio_track->getAudioSampleBit()); } -RtpCodec::Ptr Factory::getRtpEncoderByCodecId(CodecId codec_id, uint8_t pt) { - switch (codec_id) { - case CodecH264: return std::make_shared(); - case CodecH265: return std::make_shared(); - case CodecAAC: return std::make_shared(); - case CodecL16: - case CodecOpus: return std::make_shared(); - case CodecG711A: - case CodecG711U: { - if (pt == Rtsp::PT_PCMA || pt == Rtsp::PT_PCMU) { - return std::make_shared(codec_id, 1); - } - return std::make_shared(); - } - case CodecJPEG: return std::make_shared(); - default: WarnL << "Unsupported codec: " << codec_id; return nullptr; +RtpCodec::Ptr Factory::getRtpEncoderByCodecId(CodecId codec, uint8_t pt) { + auto it = s_plugins.find(codec); + if (it == s_plugins.end()) { + WarnL << "Unsupported codec: " << getCodecName(codec); + return nullptr; } + return it->second->getRtpEncoderByCodecId(pt); } RtpCodec::Ptr Factory::getRtpDecoderByCodecId(CodecId codec) { - switch (codec){ - case CodecH264 : return std::make_shared(); - case CodecH265 : return std::make_shared(); - case CodecAAC : return std::make_shared(); - case CodecL16 : - case CodecOpus : - case CodecG711A : - case CodecG711U : return std::make_shared(codec); - case CodecJPEG: return std::make_shared(); - default : WarnL << "Unsupported codec: " << getCodecName(codec); return nullptr; + auto it = s_plugins.find(codec); + if (it == s_plugins.end()) { + WarnL << "Unsupported codec: " << getCodecName(codec); + return nullptr; } + return it->second->getRtpDecoderByCodecId(); } /////////////////////////////rtmp相关/////////////////////////////////////////// @@ -173,18 +128,13 @@ static CodecId getVideoCodecIdByAmf(const AMFValue &val){ return CodecInvalid; } -Track::Ptr Factory::getTrackByCodecId(CodecId codecId, int sample_rate, int channels, int sample_bit) { - switch (codecId){ - case CodecH264 : return std::make_shared(); - case CodecH265 : return std::make_shared(); - case CodecAAC : return std::make_shared(); - case CodecOpus: return std::make_shared(); - case CodecL16: return std::make_shared(sample_rate, channels); - case CodecG711A : - case CodecG711U : return (sample_rate && channels && sample_bit) ? std::make_shared(codecId, sample_rate, channels, sample_bit) : nullptr; - case CodecJPEG : return std::make_shared(); - default : WarnL << "Unsupported codec: " << codecId; return nullptr; +Track::Ptr Factory::getTrackByCodecId(CodecId codec, int sample_rate, int channels, int sample_bit) { + auto it = s_plugins.find(codec); + if (it == s_plugins.end()) { + WarnL << "Unsupported codec: " << getCodecName(codec); + return nullptr; } + return it->second->getTrackByCodecId(sample_rate, channels, sample_bit); } Track::Ptr Factory::getVideoTrackByAmf(const AMFValue &amf) { @@ -228,39 +178,21 @@ Track::Ptr Factory::getAudioTrackByAmf(const AMFValue& amf, int sample_rate, int } RtmpCodec::Ptr Factory::getRtmpDecoderByTrack(const Track::Ptr &track) { - switch (track->getCodecId()){ - case CodecH264 : return std::make_shared(track); - case CodecAAC : return std::make_shared(track); - case CodecH265 : return std::make_shared(track); - case CodecOpus : - case CodecG711A : - case CodecG711U : return std::make_shared(track); - default : WarnL << "Unsupported codec: " << track->getCodecName(); return nullptr; + auto it = s_plugins.find(track->getCodecId()); + if (it == s_plugins.end()) { + WarnL << "Unsupported codec: " << track->getCodecName(); + return nullptr; } + return it->second->getRtmpDecoderByTrack(track); } RtmpCodec::Ptr Factory::getRtmpEncoderByTrack(const Track::Ptr &track) { - switch (track->getCodecId()){ - case CodecH264 : return std::make_shared(track); - case CodecAAC : return std::make_shared(track); - case CodecH265 : return std::make_shared(track); - case CodecOpus : return std::make_shared(track); - case CodecG711A : - case CodecG711U : { - auto audio_track = dynamic_pointer_cast(track); - if (audio_track->getAudioSampleRate() != 8000 || audio_track->getAudioChannel() != 1 || audio_track->getAudioSampleBit() != 16) { - //rtmp对g711只支持8000/1/16规格,但是ZLMediaKit可以解析其他规格的G711 - WarnL << "RTMP only support G711 with 8000/1/16, now is" - << audio_track->getAudioSampleRate() << "/" - << audio_track->getAudioChannel() << "/" - << audio_track->getAudioSampleBit() - << ", ignored it"; - return nullptr; - } - return std::make_shared(track); - } - default : WarnL << "Unsupported codec: " << track->getCodecName(); return nullptr; + auto it = s_plugins.find(track->getCodecId()); + if (it == s_plugins.end()) { + WarnL << "Unsupported codec: " << track->getCodecName(); + return nullptr; } + return it->second->getRtmpEncoderByTrack(track); } AMFValue Factory::getAmfByCodecId(CodecId codecId) { @@ -288,16 +220,12 @@ static size_t aacPrefixSize(const char *data, size_t bytes) { } Frame::Ptr Factory::getFrameFromPtr(CodecId codec, const char *data, size_t bytes, uint64_t dts, uint64_t pts) { - switch (codec) { - case CodecH264: return std::make_shared((char *)data, bytes, dts, pts, prefixSize(data, bytes)); - case CodecH265: return std::make_shared((char *)data, bytes, dts, pts, prefixSize(data, bytes)); - case CodecJPEG: return std::make_shared>(0, codec, (char *)data, bytes, dts, pts); - case CodecAAC: return std::make_shared(codec, (char *)data, bytes, dts, pts, aacPrefixSize(data, bytes)); - case CodecOpus: - case CodecG711A: - case CodecG711U: return std::make_shared(codec, (char *)data, bytes, dts, pts); - default: return nullptr; + auto it = s_plugins.find(codec); + if (it == s_plugins.end()) { + WarnL << "Unsupported codec: " << getCodecName(codec); + return nullptr; } + return it->second->getFrameFromPtr(data, bytes, dts, pts); } Frame::Ptr Factory::getFrameFromBuffer(CodecId codec, Buffer::Ptr data, uint64_t dts, uint64_t pts) { diff --git a/src/Extension/Factory.h b/src/Extension/Factory.h index 528b3b2c..8ec446bc 100644 --- a/src/Extension/Factory.h +++ b/src/Extension/Factory.h @@ -17,11 +17,35 @@ #include "Extension/Frame.h" #include "Rtsp/RtpCodec.h" #include "Rtmp/RtmpCodec.h" +#include "Util/onceToken.h" -namespace mediakit{ +#define REGISTER_STATIC_VAR_INNER(var_name, line) var_name##_##line##__ +#define REGISTER_STATIC_VAR(var_name, line) REGISTER_STATIC_VAR_INNER(var_name, line) + +#define REGISTER_CODEC(plugin) \ +static toolkit::onceToken REGISTER_STATIC_VAR(s_token, __LINE__) ([]() { \ + Factory::registerPlugin(plugin); \ +}); + +namespace mediakit { + +struct CodecPlugin { + CodecId (*getCodec)(); + Track::Ptr (*getTrackByCodecId)(int sample_rate, int channels, int sample_bit); + Track::Ptr (*getTrackBySdp)(const SdpTrack::Ptr &track); + RtpCodec::Ptr (*getRtpEncoderByCodecId)(uint8_t pt); + RtpCodec::Ptr (*getRtpDecoderByCodecId)(); + RtmpCodec::Ptr (*getRtmpEncoderByTrack)(const Track::Ptr &track); + RtmpCodec::Ptr (*getRtmpDecoderByTrack)(const Track::Ptr &track); + Frame::Ptr (*getFrameFromPtr)(const char *data, size_t bytes, uint64_t dts, uint64_t pts); +}; class Factory { public: + /** + * 注册插件,非线程安全的 + */ + static void registerPlugin(const CodecPlugin &plugin); /** * 根据codec_id 获取track diff --git a/src/Extension/G711.cpp b/src/Extension/G711.cpp index bdab522b..96184e1a 100644 --- a/src/Extension/G711.cpp +++ b/src/Extension/G711.cpp @@ -9,6 +9,10 @@ */ #include "G711.h" +#include "G711Rtp.h" +#include "CommonRtp.h" +#include "CommonRtmp.h" +#include "Factory.h" using namespace std; using namespace toolkit; @@ -67,6 +71,118 @@ Sdp::Ptr G711Track::getSdp(uint8_t payload_type) const { return std::make_shared(codec, payload_type, sample_rate, audio_channel, bitrate); } + +namespace { + +CodecId getCodecA() { + return CodecG711A; +} + +CodecId getCodecU() { + return CodecG711A; +} + +Track::Ptr getTrackByCodecId_l(CodecId codec, int sample_rate, int channels, int sample_bit) { + return (sample_rate && channels && sample_bit) ? std::make_shared(codec, sample_rate, channels, sample_bit) : nullptr; +} + +Track::Ptr getTrackByCodecIdA(int sample_rate, int channels, int sample_bit) { + return getTrackByCodecId_l(CodecG711A, sample_rate, channels, sample_bit); +} + +Track::Ptr getTrackByCodecIdU(int sample_rate, int channels, int sample_bit) { + return getTrackByCodecId_l(CodecG711U, sample_rate, channels, sample_bit); +} + +Track::Ptr getTrackBySdp_l(CodecId codec, const SdpTrack::Ptr &track) { + return std::make_shared(codec, track->_samplerate, track->_channel, 16); +} + +Track::Ptr getTrackBySdpA(const SdpTrack::Ptr &track) { + return getTrackBySdp_l(CodecG711A, track); +} + +Track::Ptr getTrackBySdpU(const SdpTrack::Ptr &track) { + return getTrackBySdp_l(CodecG711U, track); +} + +RtpCodec::Ptr getRtpEncoderByCodecId_l(CodecId codec, uint8_t pt) { + if (pt == Rtsp::PT_PCMA || pt == Rtsp::PT_PCMU) { + return std::make_shared(codec, 1); + } + return std::make_shared(); +} + +RtpCodec::Ptr getRtpEncoderByCodecIdA(uint8_t pt) { + return getRtpEncoderByCodecId_l(CodecG711A, pt); +} + +RtpCodec::Ptr getRtpEncoderByCodecIdU(uint8_t pt) { + return getRtpEncoderByCodecId_l(CodecG711U, pt); +} + +RtpCodec::Ptr getRtpDecoderByCodecId_l(CodecId codec) { + return std::make_shared(codec); +} + +RtpCodec::Ptr getRtpDecoderByCodecIdA() { + return getRtpDecoderByCodecId_l(CodecG711A); +} + +RtpCodec::Ptr getRtpDecoderByCodecIdU() { + return getRtpDecoderByCodecId_l(CodecG711U); +} + +RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) { + auto audio_track = dynamic_pointer_cast(track); + if (audio_track->getAudioSampleRate() != 8000 || audio_track->getAudioChannel() != 1 || audio_track->getAudioSampleBit() != 16) { + //rtmp对g711只支持8000/1/16规格,但是ZLMediaKit可以解析其他规格的G711 + WarnL << "RTMP only support G711 with 8000/1/16, now is" + << audio_track->getAudioSampleRate() << "/" + << audio_track->getAudioChannel() << "/" + << audio_track->getAudioSampleBit() + << ", ignored it"; + return nullptr; + } + return std::make_shared(track); +} + +RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) { + return std::make_shared(track); +} + +Frame::Ptr getFrameFromPtr_l(CodecId codec, const char *data, size_t bytes, uint64_t dts, uint64_t pts) { + return std::make_shared(codec, (char *)data, bytes, dts, pts); +} + +Frame::Ptr getFrameFromPtrA(const char *data, size_t bytes, uint64_t dts, uint64_t pts) { + return getFrameFromPtr_l(CodecG711A, (char *)data, bytes, dts, pts); +} + +Frame::Ptr getFrameFromPtrU(const char *data, size_t bytes, uint64_t dts, uint64_t pts) { + return getFrameFromPtr_l(CodecG711U, (char *)data, bytes, dts, pts); +} + +} // namespace + +CodecPlugin g711a_plugin = { .getCodec = getCodecA, + .getTrackByCodecId = getTrackByCodecIdA, + .getTrackBySdp = getTrackBySdpA, + .getRtpEncoderByCodecId = getRtpEncoderByCodecIdA, + .getRtpDecoderByCodecId = getRtpDecoderByCodecIdA, + .getRtmpEncoderByTrack = getRtmpEncoderByTrack, + .getRtmpDecoderByTrack = getRtmpDecoderByTrack, + .getFrameFromPtr = getFrameFromPtrA }; + +CodecPlugin g711u_plugin = { .getCodec = getCodecU, + .getTrackByCodecId = getTrackByCodecIdU, + .getTrackBySdp = getTrackBySdpU, + .getRtpEncoderByCodecId = getRtpEncoderByCodecIdU, + .getRtpDecoderByCodecId = getRtpDecoderByCodecIdU, + .getRtmpEncoderByTrack = getRtmpEncoderByTrack, + .getRtmpDecoderByTrack = getRtmpDecoderByTrack, + .getFrameFromPtr = getFrameFromPtrU }; + }//namespace mediakit diff --git a/src/Extension/H264.cpp b/src/Extension/H264.cpp index c147011e..611e279c 100644 --- a/src/Extension/H264.cpp +++ b/src/Extension/H264.cpp @@ -9,9 +9,13 @@ */ #include "H264.h" -#include "SPSParser.h" +#include "H264Rtmp.h" +#include "H264Rtp.h" +#include "Factory.h" #include "Util/logger.h" #include "Util/base64.h" +#include "SPSParser.h" +#include "Common/Parser.h" #include "Common/config.h" #ifdef ENABLE_MP4 @@ -346,4 +350,60 @@ Sdp::Ptr H264Track::getSdp(uint8_t payload_type) const { return std::make_shared(_sps, _pps, payload_type, getBitRate() / 1024); } +namespace { + +CodecId getCodec() { + return CodecH264; +} + +Track::Ptr getTrackByCodecId(int sample_rate, int channels, int sample_bit) { + return std::make_shared(); +} + +Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) { + //a=fmtp:96 packetization-mode=1;profile-level-id=42C01F;sprop-parameter-sets=Z0LAH9oBQBboQAAAAwBAAAAPI8YMqA==,aM48gA== + auto map = Parser::parseArgs(track->_fmtp, ";", "="); + auto sps_pps = map["sprop-parameter-sets"]; + string base64_SPS = findSubString(sps_pps.data(), NULL, ","); + string base64_PPS = findSubString(sps_pps.data(), ",", NULL); + auto sps = decodeBase64(base64_SPS); + auto pps = decodeBase64(base64_PPS); + if (sps.empty() || pps.empty()) { + //如果sdp里面没有sps/pps,那么可能在后续的rtp里面恢复出sps/pps + return std::make_shared(); + } + return std::make_shared(sps, pps, 0, 0); +} + +RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) { + return std::make_shared(); +} + +RtpCodec::Ptr getRtpDecoderByCodecId() { + return std::make_shared(); +} + +RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) { + return std::make_shared(track); +} + +RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) { + return std::make_shared(track); +} + +Frame::Ptr getFrameFromPtr(const char *data, size_t bytes, uint64_t dts, uint64_t pts) { + return std::make_shared((char *)data, bytes, dts, pts, prefixSize(data, bytes)); +} + +} // namespace + +CodecPlugin h264_plugin = { .getCodec = getCodec, + .getTrackByCodecId = getTrackByCodecId, + .getTrackBySdp = getTrackBySdp, + .getRtpEncoderByCodecId = getRtpEncoderByCodecId, + .getRtpDecoderByCodecId = getRtpDecoderByCodecId, + .getRtmpEncoderByTrack = getRtmpEncoderByTrack, + .getRtmpDecoderByTrack = getRtmpDecoderByTrack, + .getFrameFromPtr = getFrameFromPtr }; + } // namespace mediakit diff --git a/src/Extension/H265.cpp b/src/Extension/H265.cpp index e8daf399..06c6f476 100644 --- a/src/Extension/H265.cpp +++ b/src/Extension/H265.cpp @@ -9,8 +9,12 @@ */ #include "H265.h" +#include "H265Rtmp.h" +#include "H265Rtp.h" +#include "Factory.h" #include "SPSParser.h" #include "Util/base64.h" +#include "Common/Parser.h" #ifdef ENABLE_MP4 #include "mpeg4-hevc.h" @@ -263,5 +267,59 @@ Sdp::Ptr H265Track::getSdp(uint8_t payload_type) const { return std::make_shared(_vps, _sps, _pps, payload_type, getBitRate() / 1024); } +namespace { + +CodecId getCodec() { + return CodecH265; +} + +Track::Ptr getTrackByCodecId(int sample_rate, int channels, int sample_bit) { + return std::make_shared(); +} + +Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) { + // a=fmtp:96 sprop-sps=QgEBAWAAAAMAsAAAAwAAAwBdoAKAgC0WNrkky/AIAAADAAgAAAMBlQg=; sprop-pps=RAHA8vA8kAA= + auto map = Parser::parseArgs(track->_fmtp, ";", "="); + auto vps = decodeBase64(map["sprop-vps"]); + auto sps = decodeBase64(map["sprop-sps"]); + auto pps = decodeBase64(map["sprop-pps"]); + if (sps.empty() || pps.empty()) { + // 如果sdp里面没有sps/pps,那么可能在后续的rtp里面恢复出sps/pps + return std::make_shared(); + } + return std::make_shared(vps, sps, pps, 0, 0, 0); +} + +RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) { + return std::make_shared(); +} + +RtpCodec::Ptr getRtpDecoderByCodecId() { + return std::make_shared(); +} + +RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) { + return std::make_shared(track); +} + +RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) { + return std::make_shared(track); +} + +Frame::Ptr getFrameFromPtr(const char *data, size_t bytes, uint64_t dts, uint64_t pts) { + return std::make_shared((char *)data, bytes, dts, pts, prefixSize(data, bytes)); +} + +} // namespace + +CodecPlugin h265_plugin = { .getCodec = getCodec, + .getTrackByCodecId = getTrackByCodecId, + .getTrackBySdp = getTrackBySdp, + .getRtpEncoderByCodecId = getRtpEncoderByCodecId, + .getRtpDecoderByCodecId = getRtpDecoderByCodecId, + .getRtmpEncoderByTrack = getRtmpEncoderByTrack, + .getRtmpDecoderByTrack = getRtmpDecoderByTrack, + .getFrameFromPtr = getFrameFromPtr }; + }//namespace mediakit diff --git a/src/Extension/JPEG.cpp b/src/Extension/JPEG.cpp index 52d98073..9696db2f 100644 --- a/src/Extension/JPEG.cpp +++ b/src/Extension/JPEG.cpp @@ -1,6 +1,8 @@ #include "JPEG.h" +#include "JPEGRtp.h" #include "Rtsp/Rtsp.h" #include "Util/util.h" +#include "Factory.h" using namespace toolkit; @@ -47,4 +49,53 @@ private: Sdp::Ptr JPEGTrack::getSdp(uint8_t) const { return std::make_shared(getBitRate() / 1024); } + + +namespace { + +CodecId getCodec() { + return CodecJPEG; +} + +Track::Ptr getTrackByCodecId(int sample_rate, int channels, int sample_bit) { + return std::make_shared(); +} + +Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) { + return std::make_shared(); +} + +RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) { + return std::make_shared(); +} + +RtpCodec::Ptr getRtpDecoderByCodecId() { + return std::make_shared(); +} + +RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) { + WarnL << "Unsupported jpeg rtmp encoder"; + return nullptr; +} + +RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) { + WarnL << "Unsupported jpeg rtmp decoder"; + return nullptr; +} + +Frame::Ptr getFrameFromPtr(const char *data, size_t bytes, uint64_t dts, uint64_t pts) { + return std::make_shared>(0, CodecJPEG, (char *)data, bytes, dts, pts); +} + +} // namespace + +CodecPlugin jpeg_plugin = { .getCodec = getCodec, + .getTrackByCodecId = getTrackByCodecId, + .getTrackBySdp = getTrackBySdp, + .getRtpEncoderByCodecId = getRtpEncoderByCodecId, + .getRtpDecoderByCodecId = getRtpDecoderByCodecId, + .getRtmpEncoderByTrack = getRtmpEncoderByTrack, + .getRtmpDecoderByTrack = getRtmpDecoderByTrack, + .getFrameFromPtr = getFrameFromPtr }; + } // namespace mediakit diff --git a/src/Extension/L16.cpp b/src/Extension/L16.cpp index 70a23da2..07662993 100644 --- a/src/Extension/L16.cpp +++ b/src/Extension/L16.cpp @@ -9,6 +9,9 @@ */ #include "L16.h" +#include "CommonRtp.h" +#include "CommonRtmp.h" +#include "Factory.h" using namespace std; using namespace toolkit; @@ -54,6 +57,53 @@ Track::Ptr L16Track::clone() const { return std::make_shared(*this); } +namespace { + +CodecId getCodec() { + return CodecL16; +} + +Track::Ptr getTrackByCodecId(int sample_rate, int channels, int sample_bit) { + return std::make_shared(sample_rate, channels); +} + +Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) { + return std::make_shared(track->_samplerate, track->_channel); +} + +RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) { + return std::make_shared(); +} + +RtpCodec::Ptr getRtpDecoderByCodecId() { + return std::make_shared(CodecL16); +} + +RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) { + WarnL << "Unsupported L16 rtmp encoder"; + return nullptr; +} + +RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) { + WarnL << "Unsupported L16 rtmp decoder"; + return nullptr; +} + +Frame::Ptr getFrameFromPtr(const char *data, size_t bytes, uint64_t dts, uint64_t pts) { + return std::make_shared(CodecL16, (char *)data, bytes, dts, pts); +} + +} // namespace + +CodecPlugin l16_plugin = { .getCodec = getCodec, + .getTrackByCodecId = getTrackByCodecId, + .getTrackBySdp = getTrackBySdp, + .getRtpEncoderByCodecId = getRtpEncoderByCodecId, + .getRtpDecoderByCodecId = getRtpDecoderByCodecId, + .getRtmpEncoderByTrack = getRtmpEncoderByTrack, + .getRtmpDecoderByTrack = getRtmpDecoderByTrack, + .getFrameFromPtr = getFrameFromPtr }; + }//namespace mediakit diff --git a/src/Extension/Opus.cpp b/src/Extension/Opus.cpp index 30f0bbc8..c96e4775 100644 --- a/src/Extension/Opus.cpp +++ b/src/Extension/Opus.cpp @@ -9,6 +9,9 @@ */ #include "Opus.h" +#include "CommonRtp.h" +#include "CommonRtmp.h" +#include "Factory.h" using namespace std; using namespace toolkit; @@ -51,4 +54,49 @@ Sdp::Ptr OpusTrack::getSdp(uint8_t payload_type) const { return std::make_shared(payload_type, getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024); } +namespace { + +CodecId getCodec() { + return CodecOpus; +} + +Track::Ptr getTrackByCodecId(int sample_rate, int channels, int sample_bit) { + return std::make_shared(); +} + +Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) { + return std::make_shared(); +} + +RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) { + return std::make_shared(); +} + +RtpCodec::Ptr getRtpDecoderByCodecId() { + return std::make_shared(CodecOpus); +} + +RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) { + return std::make_shared(track); +} + +RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) { + return std::make_shared(track); +} + +Frame::Ptr getFrameFromPtr(const char *data, size_t bytes, uint64_t dts, uint64_t pts) { + return std::make_shared(CodecOpus, (char *)data, bytes, dts, pts); +} + +} // namespace + +CodecPlugin opus_plugin = { .getCodec = getCodec, + .getTrackByCodecId = getTrackByCodecId, + .getTrackBySdp = getTrackBySdp, + .getRtpEncoderByCodecId = getRtpEncoderByCodecId, + .getRtpDecoderByCodecId = getRtpDecoderByCodecId, + .getRtmpEncoderByTrack = getRtmpEncoderByTrack, + .getRtmpDecoderByTrack = getRtmpDecoderByTrack, + .getFrameFromPtr = getFrameFromPtr }; + }//namespace mediakit \ No newline at end of file