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];
};