From 83400290a8c7463ce1b0fee8bfd9e557106dcea5 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sat, 4 Apr 2020 22:54:49 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86rtmp=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Extension/AACRtmp.cpp | 21 ++++++++- src/Extension/Factory.cpp | 12 +++-- src/Extension/H264Rtmp.cpp | 95 ++++++++++++++++++++++++++++++-------- src/Rtmp/Rtmp.h | 82 ++------------------------------ 4 files changed, 106 insertions(+), 104 deletions(-) diff --git a/src/Extension/AACRtmp.cpp b/src/Extension/AACRtmp.cpp index 80b05ce4..ab34caff 100644 --- a/src/Extension/AACRtmp.cpp +++ b/src/Extension/AACRtmp.cpp @@ -9,6 +9,7 @@ */ #include "AACRtmp.h" +#include "Rtmp/Rtmp.h" namespace mediakit{ @@ -24,9 +25,25 @@ AACFrame::Ptr AACRtmpDecoder::obtainFrame() { return frame; } +static string getAacCfg(const RtmpPacket &thiz) { + string ret; + if (thiz.getMediaType() != FLV_CODEC_AAC) { + return ret; + } + if (!thiz.isCfgFrame()) { + return ret; + } + if (thiz.strBuf.size() < 4) { + WarnL << "bad aac cfg!"; + return ret; + } + ret = thiz.strBuf.substr(2, 2); + return ret; +} + bool AACRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt, bool key_pos) { if (pkt->isCfgFrame()) { - _aac_cfg = pkt->getAacCfg(); + _aac_cfg = getAacCfg(*pkt); return false; } if (!_aac_cfg.empty()) { @@ -126,7 +143,7 @@ void AACRtmpEncoder::makeAudioConfigPkt() { break; } uint8_t flvSampleBit = iSampleBit == 16; - uint8_t flvAudioType = 10; //aac + uint8_t flvAudioType = FLV_CODEC_AAC; _ui8AudioFlags = (flvAudioType << 4) | (flvSampleRate << 2) | (flvSampleBit << 1) | flvStereoOrMono; diff --git a/src/Extension/Factory.cpp b/src/Extension/Factory.cpp index 87090782..e0a10d2f 100644 --- a/src/Extension/Factory.cpp +++ b/src/Extension/Factory.cpp @@ -9,7 +9,9 @@ */ #include "Factory.h" +#include "Rtmp/Rtmp.h" #include "H264Rtmp.h" +#include "H265Rtmp.h" #include "AACRtmp.h" #include "H264Rtp.h" #include "AACRtp.h" @@ -173,9 +175,9 @@ CodecId Factory::getCodecIdByAmf(const AMFValue &val){ if (val.type() != AMF_NULL){ auto type_id = val.as_integer(); switch (type_id){ - case 7: return CodecH264; - case 10: return CodecAAC; - case 12: return CodecH265; + case FLV_CODEC_H264: return CodecH264; + case FLV_CODEC_AAC: return CodecAAC; + case FLV_CODEC_H265: return CodecH265; default: WarnL << "暂不支持该Amf:" << type_id; return CodecInvalid; @@ -194,6 +196,8 @@ RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track) { return std::make_shared(track); case CodecAAC: return std::make_shared(track); + case CodecH265: + return std::make_shared(track); default: WarnL << "暂不支持该CodecId:" << track->getCodecName(); return nullptr; @@ -204,7 +208,7 @@ AMFValue Factory::getAmfByCodecId(CodecId codecId) { switch (codecId){ case CodecAAC: return AMFValue("mp4a"); case CodecH264: return AMFValue("avc1"); - case CodecH265: return AMFValue(12); + case CodecH265: return AMFValue(FLV_CODEC_H265); default: return AMFValue(AMF_NULL); } } diff --git a/src/Extension/H264Rtmp.cpp b/src/Extension/H264Rtmp.cpp index 690d065d..53ecef62 100644 --- a/src/Extension/H264Rtmp.cpp +++ b/src/Extension/H264Rtmp.cpp @@ -9,7 +9,6 @@ */ #include "H264Rtmp.h" - namespace mediakit{ H264RtmpDecoder::H264RtmpDecoder() { @@ -28,11 +27,74 @@ bool H264RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &rtmp, bool key_pos) { return decodeRtmp(rtmp); } +/** + * 返回不带0x00 00 00 01头的sps + * @return + */ +static string getH264SPS(const RtmpPacket &thiz) { + string ret; + if (thiz.getMediaType() != FLV_CODEC_H264) { + return ret; + } + if (!thiz.isCfgFrame()) { + return ret; + } + if (thiz.strBuf.size() < 13) { + WarnL << "bad H264 cfg!"; + return ret; + } + uint16_t sps_size ; + memcpy(&sps_size, thiz.strBuf.data() + 11,2); + sps_size = ntohs(sps_size); + if ((int) thiz.strBuf.size() < 13 + sps_size) { + WarnL << "bad H264 cfg!"; + return ret; + } + ret.assign(thiz.strBuf.data() + 13, sps_size); + return ret; +} + +/** + * 返回不带0x00 00 00 01头的pps + * @return + */ +static string getH264PPS(const RtmpPacket &thiz) { + string ret; + if (thiz.getMediaType() != FLV_CODEC_H264) { + return ret; + } + if (!thiz.isCfgFrame()) { + return ret; + } + if (thiz.strBuf.size() < 13) { + WarnL << "bad H264 cfg!"; + return ret; + } + uint16_t sps_size ; + memcpy(&sps_size,thiz.strBuf.data() + 11,2); + sps_size = ntohs(sps_size); + + if ((int) thiz.strBuf.size() < 13 + sps_size + 1 + 2) { + WarnL << "bad H264 cfg!"; + return ret; + } + uint16_t pps_size ; + memcpy(&pps_size, thiz.strBuf.data() + 13 + sps_size + 1,2); + pps_size = ntohs(pps_size); + + if ((int) thiz.strBuf.size() < 13 + sps_size + 1 + 2 + pps_size) { + WarnL << "bad H264 cfg!"; + return ret; + } + ret.assign(thiz.strBuf.data() + 13 + sps_size + 1 + 2, pps_size); + return ret; +} + bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) { if (pkt->isCfgFrame()) { //缓存sps pps,后续插入到I帧之前 - _sps = pkt->getH264SPS(); - _pps = pkt->getH264PPS(); + _sps = getH264SPS(*pkt); + _pps = getH264PPS(*pkt); onGetH264(_sps.data(), _sps.size(), pkt->timeStamp , pkt->timeStamp); onGetH264(_pps.data(), _pps.size(), pkt->timeStamp , pkt->timeStamp); return false; @@ -61,6 +123,9 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) { } inline void H264RtmpDecoder::onGetH264(const char* pcData, int iLen, uint32_t dts,uint32_t pts) { + if(iLen == 0){ + return; + } #if 1 _h264frame->_dts = dts; _h264frame->_pts = pts; @@ -77,8 +142,6 @@ inline void H264RtmpDecoder::onGetH264(const char* pcData, int iLen, uint32_t dt #endif } - - //////////////////////////////////////////////////////////////////////// H264RtmpEncoder::H264RtmpEncoder(const Track::Ptr &track) { @@ -135,7 +198,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) { if(!_lastPacket) { //I or P or B frame - int8_t flags = 7; //h.264 + int8_t flags = FLV_CODEC_H264; bool is_config = false; flags |= (((frame->configFrame() || frame->keyFrame()) ? FLV_KEY_FRAME : FLV_INTER_FRAME) << 4); @@ -159,35 +222,33 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) { _lastPacket->bodySize = _lastPacket->strBuf.size(); } - void H264RtmpEncoder::makeVideoConfigPkt() { - int8_t flags = 7; //h.264 + int8_t flags = FLV_CODEC_H264; flags |= (FLV_KEY_FRAME << 4); bool is_config = true; RtmpPacket::Ptr rtmpPkt = ResourcePoolHelper::obtainObj(); rtmpPkt->strBuf.clear(); - //////////header + //header rtmpPkt->strBuf.push_back(flags); rtmpPkt->strBuf.push_back(!is_config); + //cts rtmpPkt->strBuf.append("\x0\x0\x0", 3); - ////////////sps + //AVCDecoderConfigurationRecord start rtmpPkt->strBuf.push_back(1); // version - - //DebugL<strBuf.push_back(_sps[1]); // profile rtmpPkt->strBuf.push_back(_sps[2]); // compat rtmpPkt->strBuf.push_back(_sps[3]); // level rtmpPkt->strBuf.push_back(0xff); // 6 bits reserved + 2 bits nal size length - 1 (11) rtmpPkt->strBuf.push_back(0xe1); // 3 bits reserved + 5 bits number of sps (00001) + //sps uint16_t size = _sps.size(); size = htons(size); rtmpPkt->strBuf.append((char *) &size, 2); rtmpPkt->strBuf.append(_sps); - - /////////////pps + //pps rtmpPkt->strBuf.push_back(1); // version size = _pps.size(); size = htons(size); @@ -202,10 +263,4 @@ void H264RtmpEncoder::makeVideoConfigPkt() { RtmpCodec::inputRtmp(rtmpPkt, false); } - }//namespace mediakit - - - - - diff --git a/src/Rtmp/Rtmp.h b/src/Rtmp/Rtmp.h index 3286f46b..a02fc0d8 100644 --- a/src/Rtmp/Rtmp.h +++ b/src/Rtmp/Rtmp.h @@ -72,6 +72,10 @@ using namespace toolkit; #define FLV_KEY_FRAME 1 #define FLV_INTER_FRAME 2 +#define FLV_CODEC_AAC 10 +#define FLV_CODEC_H264 7 +#define FLV_CODEC_H265 12 + namespace mediakit { #if defined(_WIN32) @@ -200,84 +204,6 @@ public: const static int channel[] = { 1, 2 }; return channel[flvStereoOrMono]; } - - /** - * 返回不带0x00 00 00 01头的sps - * @return - */ - string getH264SPS() const { - string ret; - if (getMediaType() != 7) { - return ret; - } - if (!isCfgFrame()) { - return ret; - } - if (strBuf.size() < 13) { - WarnL << "bad H264 cfg!"; - return ret; - } - uint16_t sps_size ; - memcpy(&sps_size,strBuf.data() + 11,2); - sps_size = ntohs(sps_size); - if ((int) strBuf.size() < 13 + sps_size) { - WarnL << "bad H264 cfg!"; - return ret; - } - ret.assign(strBuf.data() + 13, sps_size); - return ret; - } - - /** - * 返回不带0x00 00 00 01头的pps - * @return - */ - string getH264PPS() const { - string ret; - if (getMediaType() != 7) { - return ret; - } - if (!isCfgFrame()) { - return ret; - } - if (strBuf.size() < 13) { - WarnL << "bad H264 cfg!"; - return ret; - } - uint16_t sps_size ; - memcpy(&sps_size,strBuf.data() + 11,2); - sps_size = ntohs(sps_size); - - if ((int) strBuf.size() < 13 + sps_size + 1 + 2) { - WarnL << "bad H264 cfg!"; - return ret; - } - uint16_t pps_size ; - memcpy(&pps_size,strBuf.data() + 13 + sps_size + 1,2); - pps_size = ntohs(pps_size); - - if ((int) strBuf.size() < 13 + sps_size + 1 + 2 + pps_size) { - WarnL << "bad H264 cfg!"; - return ret; - } - ret.assign(strBuf.data() + 13 + sps_size + 1 + 2, pps_size); - return ret; - } - string getAacCfg() const { - string ret; - if (getMediaType() != 10) { - return ret; - } - if (!isCfgFrame()) { - return ret; - } - if (strBuf.size() < 4) { - WarnL << "bad aac cfg!"; - return ret; - } - ret = strBuf.substr(2, 2); - return ret; - } };