From 0f6a7c16561e595a55fe9a9d0a9e900f02788c08 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sun, 21 Oct 2018 21:45:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/RTP/AACRtpCodec.cpp | 26 ++++-- src/RTP/AACRtpCodec.h | 38 +++++--- src/RTP/H264RtpCodec.cpp | 195 +++++++++++++++++++++------------------ src/RTP/H264RtpCodec.h | 39 +++++--- src/RTP/RtpCodec.h | 13 +-- 5 files changed, 183 insertions(+), 128 deletions(-) diff --git a/src/RTP/AACRtpCodec.cpp b/src/RTP/AACRtpCodec.cpp index f17f5f99..0a7fbc80 100644 --- a/src/RTP/AACRtpCodec.cpp +++ b/src/RTP/AACRtpCodec.cpp @@ -4,10 +4,23 @@ #include "AACRtpCodec.h" -void AACRtpCodec::inputFame(const Frame::Ptr &frame, bool key_pos) { +AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc, + uint32_t ui32MtuSize, + uint32_t ui32SampleRate, + uint8_t ui8PlayloadType, + uint8_t ui8Interleaved) : + RtpInfo(ui32Ssrc, + ui32MtuSize, + ui32SampleRate, + ui8PlayloadType, + ui8Interleaved) { + +} + +void AACRtpEncoder::inputFame(const Frame::Ptr &frame, bool key_pos) { RtpCodec::inputFame(frame, key_pos); - GET_CONFIG_AND_REGISTER(uint32_t,cycleMS,Config::Rtp::kCycleMS); + GET_CONFIG_AND_REGISTER(uint32_t, cycleMS, Config::Rtp::kCycleMS); auto uiStamp = frame->stamp(); auto pcData = frame->data(); auto iLen = frame->size(); @@ -15,7 +28,7 @@ void AACRtpCodec::inputFame(const Frame::Ptr &frame, bool key_pos) { uiStamp %= cycleMS; char *ptr = (char *) pcData; int iSize = iLen; - while (iSize > 0 ) { + while (iSize > 0) { if (iSize <= m_ui32MtuSize - 20) { m_aucSectionBuf[0] = 0; m_aucSectionBuf[1] = 16; @@ -37,7 +50,7 @@ void AACRtpCodec::inputFame(const Frame::Ptr &frame, bool key_pos) { } } -void AACRtpCodec::makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp) { +void AACRtpEncoder::makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp) { uint16_t u16RtpLen = uiLen + 12; m_ui32TimeStamp = (m_ui32SampleRate / 1000) * uiStamp; uint32_t ts = htonl(m_ui32TimeStamp); @@ -75,7 +88,7 @@ void AACRtpCodec::makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, ///////////////////////////////////////////////////////////////////////////////////// -void AACRtpCodec::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { +void AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { RtpCodec::inputRtp(rtppack, key_pos); int length = rtppack->length - rtppack->offset; @@ -95,7 +108,7 @@ void AACRtpCodec::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { } } -void AACRtpCodec::onGetAdts(const AdtsFrame::Ptr &frame) { +void AACRtpDecoder::onGetAdts(const AdtsFrame::Ptr &frame) { //写入环形缓存 RtpCodec::inputFame(frame, false); //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 @@ -103,3 +116,4 @@ void AACRtpCodec::onGetAdts(const AdtsFrame::Ptr &frame) { m_adts->aac_frame_length = 7; } + diff --git a/src/RTP/AACRtpCodec.h b/src/RTP/AACRtpCodec.h index 86ec60c4..dcc95093 100644 --- a/src/RTP/AACRtpCodec.h +++ b/src/RTP/AACRtpCodec.h @@ -8,30 +8,44 @@ #include "RtpCodec.h" -class AACRtpCodec : public RtpEncoder { +class AACRtpDecoder : public RtpCodec { public: - AACRtpCodec(uint32_t ui32Ssrc, - uint32_t ui32MtuSize , - uint32_t ui32SampleRate, - uint8_t ui8PlayloadType = 97, - uint8_t ui8Interleaved = TrackAudio * 2) : - RtpEncoder(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved) { + AACRtpDecoder() { m_framePool.setSize(32); m_adts = m_framePool.obtain(); } - ~AACRtpCodec(){} - void inputFame(const Frame::Ptr &frame,bool key_pos) override; - void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override ; + ~AACRtpDecoder() {} + + void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override; + private: - void makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp); void onGetAdts(const AdtsFrame::Ptr &frame); + private: - unsigned char m_aucSectionBuf[1600]; AdtsFrame::Ptr m_adts; ResourcePool m_framePool; }; +class AACRtpEncoder : public RtpInfo, public RtpCodec { +public: + AACRtpEncoder(uint32_t ui32Ssrc, + uint32_t ui32MtuSize, + uint32_t ui32SampleRate, + uint8_t ui8PlayloadType = 97, + uint8_t ui8Interleaved = TrackAudio * 2); + + ~AACRtpEncoder() {} + + void inputFame(const Frame::Ptr &frame, bool key_pos) override; + +private: + void makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp); + +private: + unsigned char m_aucSectionBuf[1600]; +}; + #endif //ZLMEDIAKIT_AACRTPCODEC_H diff --git a/src/RTP/H264RtpCodec.cpp b/src/RTP/H264RtpCodec.cpp index 21a8cf64..c6779005 100644 --- a/src/RTP/H264RtpCodec.cpp +++ b/src/RTP/H264RtpCodec.cpp @@ -4,100 +4,11 @@ #include "H264RtpCodec.h" -void H264RtpCodec::inputFame(const Frame::Ptr &frame, bool key_pos) { - RtpCodec::inputFame(frame, key_pos); - - GET_CONFIG_AND_REGISTER(uint32_t,cycleMS,Config::Rtp::kCycleMS); - auto uiStamp = frame->stamp(); - auto pcData = frame->data(); - auto iLen = frame->size(); - - uiStamp %= cycleMS; - int iSize = m_ui32MtuSize - 2; - if (iLen > iSize) { //超过MTU - const unsigned char s_e_r_Start = 0x80; - const unsigned char s_e_r_Mid = 0x00; - const unsigned char s_e_r_End = 0x40; - //获取帧头数据,1byte - unsigned char naluType = *((unsigned char *) pcData) & 0x1f; //获取NALU的5bit 帧类型 - - unsigned char nal_ref_idc = *((unsigned char *) pcData) & 0x60; //获取NALU的2bit 帧重要程度 00 可以丢 11不能丢 - //nal_ref_idc = 0x60; - //组装FU-A帧头数据 2byte - unsigned char f_nri_type = nal_ref_idc + 28;//F为0 1bit,nri上面获取到2bit,28为FU-A分片类型5bit - unsigned char s_e_r_type = naluType; - bool bFirst = true; - bool mark = false; - int nOffset = 1; - while (!mark) { - if (iLen < nOffset + iSize) { //是否拆分结束 - iSize = iLen - nOffset; - mark = true; - s_e_r_type = s_e_r_End + naluType; - } else { - if (bFirst == true) { - s_e_r_type = s_e_r_Start + naluType; - bFirst = false; - } else { - s_e_r_type = s_e_r_Mid + naluType; - } - } - memcpy(m_aucSectionBuf, &f_nri_type, 1); - memcpy(m_aucSectionBuf + 1, &s_e_r_type, 1); - memcpy(m_aucSectionBuf + 2, (unsigned char *) pcData + nOffset, iSize); - nOffset += iSize; - makeH264Rtp(m_aucSectionBuf, iSize + 2, mark, uiStamp); - } - } else { - makeH264Rtp(pcData, iLen, true, uiStamp); - } -} - -void H264RtpCodec::makeH264Rtp(const void* data, unsigned int len, bool mark, uint32_t uiStamp) { - uint16_t ui16RtpLen = len + 12; - m_ui32TimeStamp = (m_ui32SampleRate / 1000) * uiStamp; - uint32_t ts = htonl(m_ui32TimeStamp); - uint16_t sq = htons(m_ui16Sequence); - uint32_t sc = htonl(m_ui32Ssrc); - - auto rtppkt = obtainRtp(); - unsigned char *pucRtp = rtppkt->payload; - pucRtp[0] = '$'; - pucRtp[1] = m_ui8Interleaved; - pucRtp[2] = ui16RtpLen >> 8; - pucRtp[3] = ui16RtpLen & 0x00FF; - pucRtp[4] = 0x80; - pucRtp[5] = (mark << 7) | m_ui8PlayloadType; - memcpy(&pucRtp[6], &sq, 2); - memcpy(&pucRtp[8], &ts, 4); - //ssrc - memcpy(&pucRtp[12], &sc, 4); - //playload - memcpy(&pucRtp[16], data, len); - - rtppkt->PT = m_ui8PlayloadType; - rtppkt->interleaved = m_ui8Interleaved; - rtppkt->mark = mark; - rtppkt->length = len + 16; - rtppkt->sequence = m_ui16Sequence; - rtppkt->timeStamp = m_ui32TimeStamp; - rtppkt->ssrc = m_ui32Ssrc; - rtppkt->type = TrackVideo; - rtppkt->offset = 16; - - uint8_t type = ((uint8_t *) (data))[0] & 0x1F; - RtpCodec::inputRtp(rtppkt,type == 5); - m_ui16Sequence++; -} - -//////////////////////////////////////////////////////////////////////// - -void H264RtpCodec::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) { +void H264RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) { RtpCodec::inputRtp(rtp, decodeRtp(rtp,key_pos)); } -bool H264RtpCodec::decodeRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { - +bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { /** * h264帧类型 * Type==1:P/B frame @@ -171,10 +82,110 @@ bool H264RtpCodec::decodeRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { // 31 udef } -void H264RtpCodec::onGetH264(const H264Frame::Ptr &frame) { +void H264RtpDecoder::onGetH264(const H264Frame::Ptr &frame) { //写入环形缓存 RtpCodec::inputFame(frame,frame->type == 5); //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 m_h264frame = m_framePool.obtain(); m_h264frame->buffer.clear(); } + +//////////////////////////////////////////////////////////////////////// + +H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc, + uint32_t ui32MtuSize, + uint32_t ui32SampleRate, + uint8_t ui8PlayloadType, + uint8_t ui8Interleaved) : + RtpInfo(ui32Ssrc, + ui32MtuSize, + ui32SampleRate, + ui8PlayloadType, + ui8Interleaved) { +} + +void H264RtpEncoder::inputFame(const Frame::Ptr &frame, bool key_pos) { + RtpCodec::inputFame(frame, key_pos); + + GET_CONFIG_AND_REGISTER(uint32_t,cycleMS,Config::Rtp::kCycleMS); + auto uiStamp = frame->stamp(); + auto pcData = frame->data(); + auto iLen = frame->size(); + + uiStamp %= cycleMS; + int iSize = m_ui32MtuSize - 2; + if (iLen > iSize) { //超过MTU + const unsigned char s_e_r_Start = 0x80; + const unsigned char s_e_r_Mid = 0x00; + const unsigned char s_e_r_End = 0x40; + //获取帧头数据,1byte + unsigned char naluType = *((unsigned char *) pcData) & 0x1f; //获取NALU的5bit 帧类型 + + unsigned char nal_ref_idc = *((unsigned char *) pcData) & 0x60; //获取NALU的2bit 帧重要程度 00 可以丢 11不能丢 + //nal_ref_idc = 0x60; + //组装FU-A帧头数据 2byte + unsigned char f_nri_type = nal_ref_idc + 28;//F为0 1bit,nri上面获取到2bit,28为FU-A分片类型5bit + unsigned char s_e_r_type = naluType; + bool bFirst = true; + bool mark = false; + int nOffset = 1; + while (!mark) { + if (iLen < nOffset + iSize) { //是否拆分结束 + iSize = iLen - nOffset; + mark = true; + s_e_r_type = s_e_r_End + naluType; + } else { + if (bFirst == true) { + s_e_r_type = s_e_r_Start + naluType; + bFirst = false; + } else { + s_e_r_type = s_e_r_Mid + naluType; + } + } + memcpy(m_aucSectionBuf, &f_nri_type, 1); + memcpy(m_aucSectionBuf + 1, &s_e_r_type, 1); + memcpy(m_aucSectionBuf + 2, (unsigned char *) pcData + nOffset, iSize); + nOffset += iSize; + makeH264Rtp(m_aucSectionBuf, iSize + 2, mark, uiStamp); + } + } else { + makeH264Rtp(pcData, iLen, true, uiStamp); + } +} + +void H264RtpEncoder::makeH264Rtp(const void* data, unsigned int len, bool mark, uint32_t uiStamp) { + uint16_t ui16RtpLen = len + 12; + m_ui32TimeStamp = (m_ui32SampleRate / 1000) * uiStamp; + uint32_t ts = htonl(m_ui32TimeStamp); + uint16_t sq = htons(m_ui16Sequence); + uint32_t sc = htonl(m_ui32Ssrc); + + auto rtppkt = obtainRtp(); + unsigned char *pucRtp = rtppkt->payload; + pucRtp[0] = '$'; + pucRtp[1] = m_ui8Interleaved; + pucRtp[2] = ui16RtpLen >> 8; + pucRtp[3] = ui16RtpLen & 0x00FF; + pucRtp[4] = 0x80; + pucRtp[5] = (mark << 7) | m_ui8PlayloadType; + memcpy(&pucRtp[6], &sq, 2); + memcpy(&pucRtp[8], &ts, 4); + //ssrc + memcpy(&pucRtp[12], &sc, 4); + //playload + memcpy(&pucRtp[16], data, len); + + rtppkt->PT = m_ui8PlayloadType; + rtppkt->interleaved = m_ui8Interleaved; + rtppkt->mark = mark; + rtppkt->length = len + 16; + rtppkt->sequence = m_ui16Sequence; + rtppkt->timeStamp = m_ui32TimeStamp; + rtppkt->ssrc = m_ui32Ssrc; + rtppkt->type = TrackVideo; + rtppkt->offset = 16; + + uint8_t type = ((uint8_t *) (data))[0] & 0x1F; + RtpCodec::inputRtp(rtppkt,type == 5); + m_ui16Sequence++; +} \ No newline at end of file diff --git a/src/RTP/H264RtpCodec.h b/src/RTP/H264RtpCodec.h index 3fd4b685..b5066f3a 100644 --- a/src/RTP/H264RtpCodec.h +++ b/src/RTP/H264RtpCodec.h @@ -10,30 +10,45 @@ using namespace ZL::Util; -class H264RtpCodec : public RtpEncoder { +class H264RtpDecoder : public RtpCodec { public: - H264RtpCodec(uint32_t ui32Ssrc, - uint32_t ui32MtuSize = 1400, - uint32_t ui32SampleRate = 90000, - uint8_t ui8PlayloadType = 96, - uint8_t ui8Interleaved = TrackVideo * 2) : - RtpEncoder(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved) { + H264RtpDecoder() { m_framePool.setSize(32); m_h264frame = m_framePool.obtain(); } - ~H264RtpCodec(){} - void inputFame(const Frame::Ptr &frame,bool key_pos) override; - void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override ; + ~H264RtpDecoder() {} + + void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override; + private: - void makeH264Rtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp); bool decodeRtp(const RtpPacket::Ptr &rtp, bool key_pos); + void onGetH264(const H264Frame::Ptr &frame); + private: - unsigned char m_aucSectionBuf[1600]; H264Frame::Ptr m_h264frame; ResourcePool m_framePool; }; +class H264RtpEncoder : public RtpInfo, public RtpCodec { +public: + H264RtpEncoder(uint32_t ui32Ssrc, + uint32_t ui32MtuSize = 1400, + uint32_t ui32SampleRate = 90000, + uint8_t ui8PlayloadType = 96, + uint8_t ui8Interleaved = TrackVideo * 2); + + ~H264RtpEncoder() {} + + void inputFame(const Frame::Ptr &frame, bool key_pos) override; + +private: + void makeH264Rtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp); + +private: + unsigned char m_aucSectionBuf[1600]; +}; + #endif //ZLMEDIAKIT_H264RTPCODEC_H diff --git a/src/RTP/RtpCodec.h b/src/RTP/RtpCodec.h index aadf9061..389cbea4 100644 --- a/src/RTP/RtpCodec.h +++ b/src/RTP/RtpCodec.h @@ -21,8 +21,9 @@ public: typedef RingBuffer RtpRing; RtpCodec(){ - _frameRing = std::make_shared(); - _rtpRing = std::make_shared(); + //禁用缓存 + _frameRing = std::make_shared(1); + _rtpRing = std::make_shared(1); } virtual ~RtpCodec(){} @@ -45,11 +46,11 @@ private: }; -class RtpEncoder : public RtpCodec{ +class RtpInfo{ public: - typedef std::shared_ptr Ptr; + typedef std::shared_ptr Ptr; - RtpEncoder(uint32_t ui32Ssrc, + RtpInfo(uint32_t ui32Ssrc, uint32_t ui32MtuSize, uint32_t ui32SampleRate, uint8_t ui8PlayloadType, @@ -62,7 +63,7 @@ public: m_rtpPool.setSize(32); } - ~RtpEncoder(){} + virtual ~RtpInfo(){} int getInterleaved() const { return m_ui8Interleaved;