From 393f123e28f35c38591ac1146178cb13e8a6c4b8 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sun, 21 Oct 2018 22:24:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86=E4=BB=A3=E7=A0=81=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Player/Frame.h | 19 +++++++++++++++-- src/RTP/AACRtpCodec.cpp | 28 +++++++++++++++++-------- src/RTP/AACRtpCodec.h | 44 ++++++++++++++++++++++++++++------------ src/RTP/H264RtpCodec.cpp | 28 +++++++++++++++++-------- src/RTP/H264RtpCodec.h | 41 +++++++++++++++++++++++++------------ 5 files changed, 116 insertions(+), 44 deletions(-) diff --git a/src/Player/Frame.h b/src/Player/Frame.h index 4f2d3133..88cf82e7 100644 --- a/src/Player/Frame.h +++ b/src/Player/Frame.h @@ -13,7 +13,16 @@ class Frame : public Buffer { public: typedef std::shared_ptr Ptr; virtual ~Frame(){} + /** + * 时间戳 + */ virtual uint32_t stamp() = 0; + + /** + * 前缀长度,譬如264前缀为0x00 00 00 01,那么前缀长度就是4 + * aac前缀则为7个字节 + */ + virtual uint32_t prefixSize() = 0; }; class H264Frame : public Frame { @@ -29,15 +38,17 @@ public: uint32_t stamp() override { return timeStamp; } + uint32_t prefixSize() override{ + return iPrefixSize; + } public: uint16_t sequence; uint32_t timeStamp; unsigned char type; string buffer; + uint32_t iPrefixSize = 4; }; - - //ADTS 头中相对有用的信息 采样率、声道数、帧长度 class AdtsFrame : public Frame { public: @@ -52,6 +63,9 @@ public: uint32_t stamp() override { return timeStamp; } + uint32_t prefixSize() override{ + return iPrefixSize; + } public: unsigned int syncword; //12 bslbf 同步字The bit string ‘1111 1111 1111’,说明一个ADTS帧的开始 unsigned int id; //1 bslbf MPEG 标示符, 设置为1 @@ -75,6 +89,7 @@ public: unsigned char buffer[2 * 1024 + 7]; uint16_t sequence; uint32_t timeStamp; + uint32_t iPrefixSize = 4; } ; diff --git a/src/RTP/AACRtpCodec.cpp b/src/RTP/AACRtpCodec.cpp index 0a7fbc80..285c412f 100644 --- a/src/RTP/AACRtpCodec.cpp +++ b/src/RTP/AACRtpCodec.cpp @@ -18,12 +18,12 @@ AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc, } void AACRtpEncoder::inputFame(const Frame::Ptr &frame, bool key_pos) { - RtpCodec::inputFame(frame, key_pos); + RtpCodec::inputFame(frame, false); GET_CONFIG_AND_REGISTER(uint32_t, cycleMS, Config::Rtp::kCycleMS); auto uiStamp = frame->stamp(); - auto pcData = frame->data(); - auto iLen = frame->size(); + auto pcData = frame->data() + frame->prefixSize(); + auto iLen = frame->size() - frame->prefixSize(); uiStamp %= cycleMS; char *ptr = (char *) pcData; @@ -87,9 +87,21 @@ void AACRtpEncoder::makeAACRtp(const void *pData, unsigned int uiLen, bool bMark } ///////////////////////////////////////////////////////////////////////////////////// +AACRtpDecoder::AACRtpDecoder(uint32_t ui32SampleRate) { + m_adts = obtainFrame(); + m_sampleRate = ui32SampleRate; +} + +AdtsFrame::Ptr AACRtpDecoder::obtainFrame() { + //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 + auto frame = m_framePool.obtain(); + frame->aac_frame_length = 7; + frame->iPrefixSize = 7; + return frame; +} void AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { - RtpCodec::inputRtp(rtppack, key_pos); + RtpCodec::inputRtp(rtppack, false); int length = rtppack->length - rtppack->offset; if (m_adts->aac_frame_length + length - 4 > sizeof(AdtsFrame::buffer)) { @@ -102,7 +114,7 @@ void AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { if (rtppack->mark == true) { m_adts->sequence = rtppack->sequence; //todo(xzl) 此处完成时间戳转换 -// m_adts->timeStamp = rtppack->timeStamp * (1000.0 / m_iSampleRate); + m_adts->timeStamp = rtppack->timeStamp * (1000.0 / m_sampleRate); writeAdtsHeader(*m_adts, m_adts->buffer); onGetAdts(m_adts); } @@ -111,9 +123,9 @@ void AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { void AACRtpDecoder::onGetAdts(const AdtsFrame::Ptr &frame) { //写入环形缓存 RtpCodec::inputFame(frame, false); - //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 - m_adts = m_framePool.obtain(); - m_adts->aac_frame_length = 7; + m_adts = obtainFrame(); } + + diff --git a/src/RTP/AACRtpCodec.h b/src/RTP/AACRtpCodec.h index dcc95093..f8143d72 100644 --- a/src/RTP/AACRtpCodec.h +++ b/src/RTP/AACRtpCodec.h @@ -5,44 +5,62 @@ #ifndef ZLMEDIAKIT_AACRTPCODEC_H #define ZLMEDIAKIT_AACRTPCODEC_H - #include "RtpCodec.h" +/** + * aac rtp转adts类 + */ class AACRtpDecoder : public RtpCodec { public: - AACRtpDecoder() { - m_framePool.setSize(32); - m_adts = m_framePool.obtain(); - } - + /** + * @param ui32SampleRate 采样率,用于时间戳转换用 + */ + AACRtpDecoder(uint32_t ui32SampleRate); ~AACRtpDecoder() {} - void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override; - + /** + * 输入rtp并解码 + * @param rtp rtp数据包 + * @param key_pos 此参数内部强制转换为false,请忽略之 + */ + void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = false) override; private: void onGetAdts(const AdtsFrame::Ptr &frame); - + AdtsFrame::Ptr obtainFrame(); private: AdtsFrame::Ptr m_adts; ResourcePool m_framePool; + uint32_t m_sampleRate; }; +/** + * aac adts转rtp类 + */ class AACRtpEncoder : public RtpInfo, public RtpCodec { public: + /** + * @param ui32Ssrc ssrc + * @param ui32MtuSize mtu 大小 + * @param ui32SampleRate 采样率 + * @param ui8PlayloadType pt类型 + * @param ui8Interleaved rtsp interleaved 值 + */ 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; - + /** + * 输入aac 数据,必须带dats头 + * @param frame 带dats头的aac数据 + * @param key_pos 此参数内部强制转换为false,请忽略之 + */ + void inputFame(const Frame::Ptr &frame, bool key_pos = false) override; private: void makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp); - private: unsigned char m_aucSectionBuf[1600]; }; diff --git a/src/RTP/H264RtpCodec.cpp b/src/RTP/H264RtpCodec.cpp index c6779005..81c58278 100644 --- a/src/RTP/H264RtpCodec.cpp +++ b/src/RTP/H264RtpCodec.cpp @@ -4,11 +4,24 @@ #include "H264RtpCodec.h" -void H264RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) { - RtpCodec::inputRtp(rtp, decodeRtp(rtp,key_pos)); + +H264RtpDecoder::H264RtpDecoder() { + m_h264frame = obtainFrame(); } -bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { +H264Frame::Ptr H264RtpDecoder::obtainFrame() { + //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 + auto frame = m_framePool.obtain(); + frame->buffer.clear(); + frame->iPrefixSize = 4; + return frame; +} + +void H264RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) { + RtpCodec::inputRtp(rtp, decodeRtp(rtp)); +} + +bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) { /** * h264帧类型 * Type==1:P/B frame @@ -85,11 +98,10 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { void H264RtpDecoder::onGetH264(const H264Frame::Ptr &frame) { //写入环形缓存 RtpCodec::inputFame(frame,frame->type == 5); - //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 - m_h264frame = m_framePool.obtain(); - m_h264frame->buffer.clear(); + m_h264frame = obtainFrame(); } + //////////////////////////////////////////////////////////////////////// H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc, @@ -109,8 +121,8 @@ void H264RtpEncoder::inputFame(const Frame::Ptr &frame, bool key_pos) { GET_CONFIG_AND_REGISTER(uint32_t,cycleMS,Config::Rtp::kCycleMS); auto uiStamp = frame->stamp(); - auto pcData = frame->data(); - auto iLen = frame->size(); + auto pcData = frame->data() + frame->prefixSize(); + auto iLen = frame->size() - frame->prefixSize(); uiStamp %= cycleMS; int iSize = m_ui32MtuSize - 2; diff --git a/src/RTP/H264RtpCodec.h b/src/RTP/H264RtpCodec.h index b5066f3a..05d87f58 100644 --- a/src/RTP/H264RtpCodec.h +++ b/src/RTP/H264RtpCodec.h @@ -10,42 +10,57 @@ using namespace ZL::Util; +/** + * h264 rtp解码类 + */ class H264RtpDecoder : public RtpCodec { public: - H264RtpDecoder() { - m_framePool.setSize(32); - m_h264frame = m_framePool.obtain(); - } - + H264RtpDecoder(); ~H264RtpDecoder() {} - void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override; - + /** + * 输入264 rtp包 + * @param rtp rtp包 + * @param key_pos 此参数忽略之 + */ + void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override; private: - bool decodeRtp(const RtpPacket::Ptr &rtp, bool key_pos); - + bool decodeRtp(const RtpPacket::Ptr &rtp); void onGetH264(const H264Frame::Ptr &frame); - + H264Frame::Ptr obtainFrame(); private: H264Frame::Ptr m_h264frame; ResourcePool m_framePool; }; +/** + * 264 rtp打包类 + */ class H264RtpEncoder : public RtpInfo, public RtpCodec { public: + + /** + * @param ui32Ssrc ssrc + * @param ui32MtuSize mtu大小 + * @param ui32SampleRate 采样率,强制为90000 + * @param ui8PlayloadType pt类型 + * @param ui8Interleaved rtsp interleaved + */ H264RtpEncoder(uint32_t ui32Ssrc, uint32_t ui32MtuSize = 1400, uint32_t ui32SampleRate = 90000, uint8_t ui8PlayloadType = 96, uint8_t ui8Interleaved = TrackVideo * 2); - ~H264RtpEncoder() {} + /** + * 输入264帧 + * @param frame 帧数据,必须 + * @param key_pos + */ 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]; };