大规模修改rtsp相关代码

This commit is contained in:
xiongziliang 2018-10-23 11:09:21 +08:00
parent 393f123e28
commit c1e91620d2
25 changed files with 468 additions and 219 deletions

View File

@ -278,7 +278,7 @@ void DevChannel::initVideo(const VideoInfo& info) {
void DevChannel::initAudio(const AudioInfo& info) { void DevChannel::initAudio(const AudioInfo& info) {
m_audio.reset(new AudioInfo(info)); m_audio.reset(new AudioInfo(info));
m_pAdtsHeader = std::make_shared<AdtsFrame>(); m_pAdtsHeader = std::make_shared<AACFrame>();
m_pAdtsHeader->syncword = 0x0FFF; m_pAdtsHeader->syncword = 0x0FFF;
m_pAdtsHeader->id = 0; m_pAdtsHeader->id = 0;

View File

@ -35,6 +35,7 @@
#include "RTP/RtpMakerAAC.h" #include "RTP/RtpMakerAAC.h"
#include "RTP/RtpMakerH264.h" #include "RTP/RtpMakerH264.h"
#include "Rtsp/RtspToRtmpMediaSource.h" #include "Rtsp/RtspToRtmpMediaSource.h"
#include "Rtsp/RtspEncoder.h"
#include "Util/TimeTicker.h" #include "Util/TimeTicker.h"
using namespace std; using namespace std;
@ -119,7 +120,7 @@ private:
std::shared_ptr<VideoInfo> m_video; std::shared_ptr<VideoInfo> m_video;
std::shared_ptr<AudioInfo> m_audio; std::shared_ptr<AudioInfo> m_audio;
SmoothTicker m_aTicker[2]; SmoothTicker m_aTicker[2];
std::shared_ptr<AdtsFrame> m_pAdtsHeader; std::shared_ptr<AACFrame> m_pAdtsHeader;
}; };

View File

@ -97,7 +97,7 @@ void PlayerProxy::play(const char* strUrl) {
strongSelf->initMedia(); strongSelf->initMedia();
} }
}); });
setOnAudioCB( [weakSelf](const AdtsFrame &data ) { setOnAudioCB( [weakSelf](const AACFrame &data ) {
auto strongSelf = weakSelf.lock(); auto strongSelf = weakSelf.lock();
if(!strongSelf){ if(!strongSelf){
return; return;

View File

@ -74,7 +74,7 @@ private:
uint32_t m_audio_sample_rate = 0; uint32_t m_audio_sample_rate = 0;
uint32_t m_audio_num_channels = 0; uint32_t m_audio_num_channels = 0;
string m_strAacCfg; string m_strAacCfg;
AdtsFrame m_adts; AACFrame m_adts;
int m_iDuration = 0; int m_iDuration = 0;
DevChannel::Ptr m_pChn; DevChannel::Ptr m_pChn;

View File

@ -5,11 +5,43 @@
#ifndef ZLMEDIAKIT_FRAME_H #ifndef ZLMEDIAKIT_FRAME_H
#define ZLMEDIAKIT_FRAME_H #define ZLMEDIAKIT_FRAME_H
#include "Util/RingBuffer.h"
#include "Network/Socket.h" #include "Network/Socket.h"
using namespace ZL::Util;
using namespace ZL::Network; using namespace ZL::Network;
class Frame : public Buffer { typedef enum {
CodecInvalid = -1,
CodecH264 = 0,
CodecAAC = 0x0100,
CodecMax
} CodecId;
typedef enum {
TrackInvalid = -1,
TrackVideo = 0,
TrackAudio,
TrackMax
} TrackType;
class CodecInfo {
public:
CodecInfo(){}
virtual ~CodecInfo(){}
/**
*
*/
virtual TrackType getTrackType() const = 0;
/**
*
*/
virtual CodecId getCodecId() const = 0;
};
class Frame : public Buffer, public CodecInfo{
public: public:
typedef std::shared_ptr<Frame> Ptr; typedef std::shared_ptr<Frame> Ptr;
virtual ~Frame(){} virtual ~Frame(){}
@ -25,6 +57,78 @@ public:
virtual uint32_t prefixSize() = 0; virtual uint32_t prefixSize() = 0;
}; };
/**
*
*/
class FrameRingInterface {
public:
typedef RingBuffer<Frame::Ptr> RingType;
FrameRingInterface(){}
virtual ~FrameRingInterface(){}
/**
*
* @return
*/
virtual RingType::Ptr getFrameRing() const = 0;
/**
*
* @param ring
*/
virtual void setFrameRing(const RingType::Ptr &ring) = 0;
/**
*
* @param frame
* @param key_pos
*/
virtual void inputFrame(const Frame::Ptr &frame,bool key_pos) = 0;
};
class FrameRing : public FrameRingInterface{
public:
typedef std::shared_ptr<FrameRing> Ptr;
FrameRing(){
//禁用缓存
_frameRing = std::make_shared<RingType>(1);
}
virtual ~FrameRing(){}
/**
*
* @return
*/
RingType::Ptr getFrameRing() const override {
return _frameRing;
}
/**
*
* @param ring
*/
void setFrameRing(const RingType::Ptr &ring) override {
_frameRing = ring;
}
/**
*
* @param frame
* @param key_pos
*/
void inputFrame(const Frame::Ptr &frame,bool key_pos) override{
_frameRing->write(frame,key_pos);
}
protected:
RingType::Ptr _frameRing;
};
/**
* 264
*/
class H264Frame : public Frame { class H264Frame : public Frame {
public: public:
typedef std::shared_ptr<H264Frame> Ptr; typedef std::shared_ptr<H264Frame> Ptr;
@ -41,6 +145,14 @@ public:
uint32_t prefixSize() override{ uint32_t prefixSize() override{
return iPrefixSize; return iPrefixSize;
} }
TrackType getTrackType() const override{
return TrackVideo;
}
CodecId getCodecId() const override{
return CodecH264;
}
public: public:
uint16_t sequence; uint16_t sequence;
uint32_t timeStamp; uint32_t timeStamp;
@ -49,10 +161,12 @@ public:
uint32_t iPrefixSize = 4; uint32_t iPrefixSize = 4;
}; };
//ADTS 头中相对有用的信息 采样率、声道数、帧长度 /**
class AdtsFrame : public Frame { * aac帧adts头
*/
class AACFrame : public Frame {
public: public:
typedef std::shared_ptr<AdtsFrame> Ptr; typedef std::shared_ptr<AACFrame> Ptr;
char *data() const override{ char *data() const override{
return (char *)buffer; return (char *)buffer;
@ -66,6 +180,14 @@ public:
uint32_t prefixSize() override{ uint32_t prefixSize() override{
return iPrefixSize; return iPrefixSize;
} }
TrackType getTrackType() const override{
return TrackAudio;
}
CodecId getCodecId() const override{
return CodecAAC;
}
public: public:
unsigned int syncword; //12 bslbf 同步字The bit string 1111 1111 1111说明一个ADTS帧的开始 unsigned int syncword; //12 bslbf 同步字The bit string 1111 1111 1111说明一个ADTS帧的开始
unsigned int id; //1 bslbf MPEG 标示符, 设置为1 unsigned int id; //1 bslbf MPEG 标示符, 设置为1

View File

@ -32,7 +32,7 @@
using namespace ZL::Util; using namespace ZL::Util;
void writeAdtsHeader(const AdtsFrame &hed, uint8_t *pcAdts) { void writeAdtsHeader(const AACFrame &hed, uint8_t *pcAdts) {
pcAdts[0] = (hed.syncword >> 4 & 0xFF); //8bit pcAdts[0] = (hed.syncword >> 4 & 0xFF); //8bit
pcAdts[1] = (hed.syncword << 4 & 0xF0); //4 bit pcAdts[1] = (hed.syncword << 4 & 0xF0); //4 bit
pcAdts[1] |= (hed.id << 3 & 0x08); //1 bit pcAdts[1] |= (hed.id << 3 & 0x08); //1 bit
@ -85,7 +85,7 @@ string makeAdtsConfig(const uint8_t *pcAdts){
audioSpecificConfig[1] = (sampling_frequency_index << 7) | (channel_configuration << 3); audioSpecificConfig[1] = (sampling_frequency_index << 7) | (channel_configuration << 3);
return string((char *)audioSpecificConfig,2); return string((char *)audioSpecificConfig,2);
} }
void makeAdtsHeader(const string &strAudioCfg,AdtsFrame &adts) { void makeAdtsHeader(const string &strAudioCfg,AACFrame &adts) {
uint8_t cfg1 = strAudioCfg[0]; uint8_t cfg1 = strAudioCfg[0];
uint8_t cfg2 = strAudioCfg[1]; uint8_t cfg2 = strAudioCfg[1];
@ -113,7 +113,7 @@ void makeAdtsHeader(const string &strAudioCfg,AdtsFrame &adts) {
adts.adts_buffer_fullness = 2047; adts.adts_buffer_fullness = 2047;
adts.no_raw_data_blocks_in_frame = 0; adts.no_raw_data_blocks_in_frame = 0;
} }
void getAACInfo(const AdtsFrame &adts,int &iSampleRate,int &iChannel){ void getAACInfo(const AACFrame &adts,int &iSampleRate,int &iChannel){
iSampleRate = samplingFrequencyTable[adts.sf_index]; iSampleRate = samplingFrequencyTable[adts.sf_index];
iChannel = adts.channel_configuration; iChannel = adts.channel_configuration;
} }

View File

@ -40,10 +40,10 @@ unsigned const samplingFrequencyTable[16] = { 96000, 88200,
11025, 8000, 11025, 8000,
7350, 0, 0, 0 }; 7350, 0, 0, 0 };
void makeAdtsHeader(const string &strAudioCfg,AdtsFrame &adts); void makeAdtsHeader(const string &strAudioCfg,AACFrame &adts);
void writeAdtsHeader(const AdtsFrame &adts, uint8_t *pcAdts) ; void writeAdtsHeader(const AACFrame &adts, uint8_t *pcAdts) ;
string makeAdtsConfig(const uint8_t *pcAdts); string makeAdtsConfig(const uint8_t *pcAdts);
void getAACInfo(const AdtsFrame &adts,int &iSampleRate,int &iChannel); void getAACInfo(const AACFrame &adts,int &iSampleRate,int &iChannel);
bool getAVCInfo(const string &strSps,int &iVideoWidth, int &iVideoHeight, float &iVideoFps); bool getAVCInfo(const string &strSps,int &iVideoWidth, int &iVideoHeight, float &iVideoFps);
#endif /* SRC_PLAYER_PLAYER_H_ */ #endif /* SRC_PLAYER_PLAYER_H_ */

View File

@ -94,7 +94,7 @@ public:
virtual void setOnShutdown( const function<void(const SockException &)> &cb) {}; virtual void setOnShutdown( const function<void(const SockException &)> &cb) {};
virtual void setOnPlayResult( const function<void(const SockException &ex)> &cb) {}; virtual void setOnPlayResult( const function<void(const SockException &ex)> &cb) {};
virtual void setOnVideoCB( const function<void(const H264Frame &frame)> &cb) {}; virtual void setOnVideoCB( const function<void(const H264Frame &frame)> &cb) {};
virtual void setOnAudioCB( const function<void(const AdtsFrame &frame)> &cb) {}; virtual void setOnAudioCB( const function<void(const AACFrame &frame)> &cb) {};
virtual float getProgress() const { return 0;}; virtual float getProgress() const { return 0;};
virtual void seekTo(float fProgress) {}; virtual void seekTo(float fProgress) {};
@ -140,7 +140,7 @@ public:
} }
m_onGetVideoCB = cb; m_onGetVideoCB = cb;
} }
void setOnAudioCB(const function<void(const AdtsFrame &frame)> &cb) override{ void setOnAudioCB(const function<void(const AACFrame &frame)> &cb) override{
if (m_parser) { if (m_parser) {
m_parser->setOnAudioCB(cb); m_parser->setOnAudioCB(cb);
} }
@ -269,7 +269,7 @@ protected:
function<void(const SockException &ex)> m_playResultCB; function<void(const SockException &ex)> m_playResultCB;
std::shared_ptr<Parser> m_parser; std::shared_ptr<Parser> m_parser;
function<void(const H264Frame &frame)> m_onGetVideoCB; function<void(const H264Frame &frame)> m_onGetVideoCB;
function<void(const AdtsFrame &frame)> m_onGetAudioCB; function<void(const AACFrame &frame)> m_onGetAudioCB;
MediaSource::Ptr m_pMediaSrc; MediaSource::Ptr m_pMediaSrc;
}; };

View File

@ -14,35 +14,11 @@
using namespace std; using namespace std;
using namespace ZL::Util; using namespace ZL::Util;
class TrackFormat { class TrackFormat : public FrameRingInterface , public CodecInfo{
public: public:
typedef std::shared_ptr<TrackFormat> Ptr; typedef std::shared_ptr<TrackFormat> Ptr;
typedef RingBuffer<Frame::Ptr> RingType; TrackFormat(){}
typedef enum {
CodecInvalid = -1,
CodecH264 = 0,
CodecAAC = 0x0100,
CodecMax
} CodecID;
TrackFormat(){
_ring = std::make_shared<RingType>();
}
virtual ~TrackFormat(){} virtual ~TrackFormat(){}
virtual TrackType getTrackType() const = 0;
virtual int getCodecId() const = 0;
void writeFrame(const Frame::Ptr &frame,bool keypos = true){
_ring->write(frame, keypos);
}
RingType::Ptr& getRing() {
return _ring;
}
private:
RingType::Ptr _ring;
}; };
class VideoTrackFormat : public TrackFormat { class VideoTrackFormat : public TrackFormat {
@ -73,8 +49,8 @@ public:
const string &getPps() const{ const string &getPps() const{
return _pps; return _pps;
} }
int getCodecId() const override{ CodecId getCodecId() const override{
return TrackFormat::CodecH264; return CodecH264;
} }
private: private:
string _sps; string _sps;
@ -89,8 +65,8 @@ public:
const string &getAacCfg() const{ const string &getAacCfg() const{
return _cfg; return _cfg;
} }
int getCodecId() const override{ CodecId getCodecId() const override{
return TrackFormat::CodecAAC; return CodecAAC;
} }
private: private:
string _cfg; string _cfg;

View File

@ -9,16 +9,16 @@ AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc,
uint32_t ui32SampleRate, uint32_t ui32SampleRate,
uint8_t ui8PlayloadType, uint8_t ui8PlayloadType,
uint8_t ui8Interleaved) : uint8_t ui8Interleaved) :
RtpInfo(ui32Ssrc, RtpEncoder(ui32Ssrc,
ui32MtuSize, ui32MtuSize,
ui32SampleRate, ui32SampleRate,
ui8PlayloadType, ui8PlayloadType,
ui8Interleaved) { ui8Interleaved) {
} }
void AACRtpEncoder::inputFame(const Frame::Ptr &frame, bool key_pos) { void AACRtpEncoder::inputFrame(const Frame::Ptr &frame, bool key_pos) {
RtpCodec::inputFame(frame, false); RtpCodec::inputFrame(frame, false);
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 uiStamp = frame->stamp();
@ -92,7 +92,7 @@ AACRtpDecoder::AACRtpDecoder(uint32_t ui32SampleRate) {
m_sampleRate = ui32SampleRate; m_sampleRate = ui32SampleRate;
} }
AdtsFrame::Ptr AACRtpDecoder::obtainFrame() { AACFrame::Ptr AACRtpDecoder::obtainFrame() {
//从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象
auto frame = m_framePool.obtain(); auto frame = m_framePool.obtain();
frame->aac_frame_length = 7; frame->aac_frame_length = 7;
@ -104,7 +104,7 @@ void AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
RtpCodec::inputRtp(rtppack, false); RtpCodec::inputRtp(rtppack, false);
int length = rtppack->length - rtppack->offset; int length = rtppack->length - rtppack->offset;
if (m_adts->aac_frame_length + length - 4 > sizeof(AdtsFrame::buffer)) { if (m_adts->aac_frame_length + length - 4 > sizeof(AACFrame::buffer)) {
m_adts->aac_frame_length = 7; m_adts->aac_frame_length = 7;
WarnL << "aac负载数据太长"; WarnL << "aac负载数据太长";
return; return;
@ -120,9 +120,9 @@ void AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
} }
} }
void AACRtpDecoder::onGetAdts(const AdtsFrame::Ptr &frame) { void AACRtpDecoder::onGetAdts(const AACFrame::Ptr &frame) {
//写入环形缓存 //写入环形缓存
RtpCodec::inputFame(frame, false); RtpCodec::inputFrame(frame, false);
m_adts = obtainFrame(); m_adts = obtainFrame();
} }

View File

@ -24,12 +24,20 @@ public:
* @param key_pos false, * @param key_pos false,
*/ */
void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = false) override; void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = false) override;
TrackType getTrackType() const override{
return TrackAudio;
}
CodecId getCodecId() const override{
return CodecAAC;
}
private: private:
void onGetAdts(const AdtsFrame::Ptr &frame); void onGetAdts(const AACFrame::Ptr &frame);
AdtsFrame::Ptr obtainFrame(); AACFrame::Ptr obtainFrame();
private: private:
AdtsFrame::Ptr m_adts; AACFrame::Ptr m_adts;
ResourcePool<AdtsFrame> m_framePool; ResourcePool<AACFrame> m_framePool;
uint32_t m_sampleRate; uint32_t m_sampleRate;
}; };
@ -37,7 +45,7 @@ private:
/** /**
* aac adts转rtp类 * aac adts转rtp类
*/ */
class AACRtpEncoder : public RtpInfo, public RtpCodec { class AACRtpEncoder : public RtpEncoder {
public: public:
/** /**
* @param ui32Ssrc ssrc * @param ui32Ssrc ssrc
@ -58,7 +66,16 @@ public:
* @param frame dats头的aac数据 * @param frame dats头的aac数据
* @param key_pos false, * @param key_pos false,
*/ */
void inputFame(const Frame::Ptr &frame, bool key_pos = false) override; void inputFrame(const Frame::Ptr &frame, bool key_pos = false) override;
TrackType getTrackType() const override{
return TrackAudio;
}
CodecId getCodecId() const override{
return CodecAAC;
}
private: private:
void makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp); void makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp);
private: private:

View File

@ -97,7 +97,7 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
void H264RtpDecoder::onGetH264(const H264Frame::Ptr &frame) { void H264RtpDecoder::onGetH264(const H264Frame::Ptr &frame) {
//写入环形缓存 //写入环形缓存
RtpCodec::inputFame(frame,frame->type == 5); RtpCodec::inputFrame(frame,frame->type == 5);
m_h264frame = obtainFrame(); m_h264frame = obtainFrame();
} }
@ -109,15 +109,15 @@ H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc,
uint32_t ui32SampleRate, uint32_t ui32SampleRate,
uint8_t ui8PlayloadType, uint8_t ui8PlayloadType,
uint8_t ui8Interleaved) : uint8_t ui8Interleaved) :
RtpInfo(ui32Ssrc, RtpEncoder(ui32Ssrc,
ui32MtuSize, ui32MtuSize,
ui32SampleRate, ui32SampleRate,
ui8PlayloadType, ui8PlayloadType,
ui8Interleaved) { ui8Interleaved) {
} }
void H264RtpEncoder::inputFame(const Frame::Ptr &frame, bool key_pos) { void H264RtpEncoder::inputFrame(const Frame::Ptr &frame, bool key_pos) {
RtpCodec::inputFame(frame, key_pos); RtpCodec::inputFrame(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 uiStamp = frame->stamp();

View File

@ -24,6 +24,14 @@ public:
* @param key_pos * @param key_pos
*/ */
void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override; void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override;
TrackType getTrackType() const override{
return TrackVideo;
}
CodecId getCodecId() const override{
return CodecH264;
}
private: private:
bool decodeRtp(const RtpPacket::Ptr &rtp); bool decodeRtp(const RtpPacket::Ptr &rtp);
void onGetH264(const H264Frame::Ptr &frame); void onGetH264(const H264Frame::Ptr &frame);
@ -36,7 +44,7 @@ private:
/** /**
* 264 rtp打包类 * 264 rtp打包类
*/ */
class H264RtpEncoder : public RtpInfo, public RtpCodec { class H264RtpEncoder : public RtpEncoder{
public: public:
/** /**
@ -58,7 +66,15 @@ public:
* @param frame * @param frame
* @param key_pos * @param key_pos
*/ */
void inputFame(const Frame::Ptr &frame, bool key_pos) override; void inputFrame(const Frame::Ptr &frame, bool key_pos) override;
TrackType getTrackType() const override{
return TrackVideo;
}
CodecId getCodecId() const override{
return CodecH264;
}
private: private:
void makeH264Rtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp); void makeH264Rtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp);
private: private:

View File

@ -3,3 +3,16 @@
// //
#include "RtpCodec.h" #include "RtpCodec.h"
RtpEncoder::RtpEncoder(uint32_t ui32Ssrc,
uint32_t ui32MtuSize,
uint32_t ui32SampleRate,
uint8_t ui8PlayloadType,
uint8_t ui8Interleaved) :
RtpInfo(ui32Ssrc,
ui32MtuSize,
ui32SampleRate,
ui8PlayloadType,
ui8Interleaved) {
}

View File

@ -14,35 +14,55 @@ using namespace std;
using namespace ZL::Util; using namespace ZL::Util;
using namespace ZL::Player; using namespace ZL::Player;
class RtpCodec{ class RtpPacket {
public: public:
typedef std::shared_ptr<RtpCodec> Ptr; typedef std::shared_ptr<RtpPacket> Ptr;
typedef RingBuffer<Frame::Ptr> FrameRing; uint8_t interleaved;
typedef RingBuffer<RtpPacket::Ptr> RtpRing; uint8_t PT;
bool mark;
uint32_t length;
uint32_t timeStamp;
uint16_t sequence;
uint32_t ssrc;
uint8_t payload[1560];
uint8_t offset;
TrackType type;
};
RtpCodec(){ class RtpRingInterface {
public:
typedef RingBuffer<RtpPacket::Ptr> RingType;
RtpRingInterface(){}
virtual ~RtpRingInterface(){}
virtual RingType::Ptr getRtpRing() const = 0;
virtual void setRtpRing(const RingType::Ptr &ring) = 0;
virtual void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) = 0;
};
class RtpRing : public RtpRingInterface {
public:
typedef std::shared_ptr<RtpRing> Ptr;
RtpRing(){
//禁用缓存 //禁用缓存
_frameRing = std::make_shared<FrameRing>(1); _rtpRing = std::make_shared<RingType>(1);
_rtpRing = std::make_shared<RtpRing>(1);
} }
virtual ~RtpCodec(){} virtual ~RtpRing(){}
FrameRing::Ptr &getFrameRing() { RingType::Ptr getRtpRing() const override {
return _frameRing;
}
RtpRing::Ptr &getRtpRing() {
return _rtpRing; return _rtpRing;
} }
virtual void inputFame(const Frame::Ptr &frame,bool key_pos){ void setRtpRing(const RingType::Ptr &ring) override {
_frameRing->write(frame,key_pos); _rtpRing = ring;
} }
virtual void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos){
void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override{
_rtpRing->write(rtp,key_pos); _rtpRing->write(rtp,key_pos);
} }
private: protected:
FrameRing::Ptr _frameRing; RingType::Ptr _rtpRing;
RtpRing::Ptr _rtpRing;
}; };
@ -105,6 +125,31 @@ protected:
ResourcePool<RtpPacket> m_rtpPool; ResourcePool<RtpPacket> m_rtpPool;
}; };
class RtpCodec : public RtpRing, public FrameRing , public CodecInfo{
public:
typedef std::shared_ptr<RtpCodec> Ptr;
RtpCodec(){}
virtual ~RtpCodec(){}
};
class RtpEncoder : public RtpInfo, public RtpCodec{
public:
typedef std::shared_ptr<RtpEncoder> Ptr;
/**
* @param ui32Ssrc ssrc
* @param ui32MtuSize mtu大小
* @param ui32SampleRate 90000
* @param ui8PlayloadType pt类型
* @param ui8Interleaved rtsp interleaved
*/
RtpEncoder(uint32_t ui32Ssrc,
uint32_t ui32MtuSize = 1400,
uint32_t ui32SampleRate = 90000,
uint8_t ui8PlayloadType = 96,
uint8_t ui8Interleaved = TrackVideo * 2);
~RtpEncoder() {}
};

View File

@ -57,7 +57,7 @@ public:
lock_guard<recursive_mutex> lck(m_mtxCB); lock_guard<recursive_mutex> lck(m_mtxCB);
onVideo = cb; onVideo = cb;
} }
void setOnAudioCB(const function<void(const AdtsFrame &frame)> &cb) override{ void setOnAudioCB(const function<void(const AACFrame &frame)> &cb) override{
lock_guard<recursive_mutex> lck(m_mtxCB); lock_guard<recursive_mutex> lck(m_mtxCB);
onAudio = cb; onAudio = cb;
} }
@ -140,7 +140,7 @@ private:
//video //video
H264Frame m_h264frame; H264Frame m_h264frame;
//aduio //aduio
AdtsFrame m_adts; AACFrame m_adts;
int m_iSampleRate = 44100; int m_iSampleRate = 44100;
int m_iSampleBit = 16; int m_iSampleBit = 16;
@ -158,7 +158,7 @@ private:
float m_fDuration = 0; float m_fDuration = 0;
mutable Ticker m_ticker; mutable Ticker m_ticker;
function<void(const H264Frame &frame)> onVideo; function<void(const H264Frame &frame)> onVideo;
function<void(const AdtsFrame &frame)> onAudio; function<void(const AACFrame &frame)> onAudio;
recursive_mutex m_mtxCB; recursive_mutex m_mtxCB;

View File

@ -55,7 +55,7 @@ void RtmpToRtspMediaSource::onGetH264(const H264Frame &frame) {
m_pRtpMaker_h264->makeRtp(frame.data() + 4, frame.size() - 4, frame.timeStamp); m_pRtpMaker_h264->makeRtp(frame.data() + 4, frame.size() - 4, frame.timeStamp);
} }
} }
inline void RtmpToRtspMediaSource::onGetAdts(const AdtsFrame &frame) { inline void RtmpToRtspMediaSource::onGetAdts(const AACFrame &frame) {
if(m_pRecorder){ if(m_pRecorder){
m_pRecorder->inputAAC((char *) frame.buffer, frame.aac_frame_length, frame.timeStamp); m_pRecorder->inputAAC((char *) frame.buffer, frame.aac_frame_length, frame.timeStamp);
} }

View File

@ -94,7 +94,7 @@ private:
bool m_bEnableHls; bool m_bEnableHls;
bool m_bEnableMp4; bool m_bEnableMp4;
void onGetH264(const H264Frame &frame); void onGetH264(const H264Frame &frame);
void onGetAdts(const AdtsFrame &frame); void onGetAdts(const AACFrame &frame);
void makeSDP(); void makeSDP();
}; };

View File

@ -242,7 +242,7 @@ inline bool RtpParser::inputAudio(const RtpPacket& rtppack,
char *frame = (char *) rtppack.payload + rtppack.offset; char *frame = (char *) rtppack.payload + rtppack.offset;
int length = rtppack.length - rtppack.offset; int length = rtppack.length - rtppack.offset;
if (m_adts.aac_frame_length + length - 4 > sizeof(AdtsFrame::buffer)) { if (m_adts.aac_frame_length + length - 4 > sizeof(AACFrame::buffer)) {
m_adts.aac_frame_length = 7; m_adts.aac_frame_length = 7;
return false; return false;
} }
@ -302,7 +302,7 @@ inline void RtpParser::onGetH264(H264Frame& frame) {
} }
} }
inline void RtpParser::onGetAdts(AdtsFrame& frame) { inline void RtpParser::onGetAdts(AACFrame& frame) {
//frame.timeStamp=ticker1.elapsedTime(); //frame.timeStamp=ticker1.elapsedTime();
lock_guard<recursive_mutex> lck(m_mtxCB); lock_guard<recursive_mutex> lck(m_mtxCB);
if (onAudio) { if (onAudio) {

View File

@ -32,6 +32,7 @@
#include "Player/Player.h" #include "Player/Player.h"
#include "Player/PlayerBase.h" #include "Player/PlayerBase.h"
#include "Util/TimeTicker.h" #include "Util/TimeTicker.h"
#include "RTP/RtpCodec.h"
using namespace std; using namespace std;
using namespace ZL::Util; using namespace ZL::Util;
@ -51,7 +52,7 @@ public:
lock_guard<recursive_mutex> lck(m_mtxCB); lock_guard<recursive_mutex> lck(m_mtxCB);
onVideo = cb; onVideo = cb;
} }
void setOnAudioCB(const function<void(const AdtsFrame &frame)> &cb) override{ void setOnAudioCB(const function<void(const AACFrame &frame)> &cb) override{
lock_guard<recursive_mutex> lck(m_mtxCB); lock_guard<recursive_mutex> lck(m_mtxCB);
onAudio = cb; onAudio = cb;
} }
@ -120,11 +121,11 @@ private:
inline bool inputAudio(const RtpPacket &rtp, const RtspTrack &track); inline bool inputAudio(const RtpPacket &rtp, const RtspTrack &track);
inline void _onGetH264(H264Frame &frame); inline void _onGetH264(H264Frame &frame);
inline void onGetH264(H264Frame &frame); inline void onGetH264(H264Frame &frame);
inline void onGetAdts(AdtsFrame &frame); inline void onGetAdts(AACFrame &frame);
//video //video
H264Frame m_h264frame; H264Frame m_h264frame;
//aduio //aduio
AdtsFrame m_adts; AACFrame m_adts;
int m_iSampleRate = 44100; int m_iSampleRate = 44100;
int m_iSampleBit = 16; int m_iSampleBit = 16;
@ -142,7 +143,7 @@ private:
bool m_bParseSpsDelay = false; bool m_bParseSpsDelay = false;
function<void(const H264Frame &frame)> onVideo; function<void(const H264Frame &frame)> onVideo;
function<void(const AdtsFrame &frame)> onAudio; function<void(const AACFrame &frame)> onAudio;
recursive_mutex m_mtxCB; recursive_mutex m_mtxCB;
}; };

View File

@ -32,22 +32,17 @@
#include <unordered_map> #include <unordered_map>
#include "Common/config.h" #include "Common/config.h"
#include "Util/util.h" #include "Util/util.h"
#include "Player/Frame.h"
using namespace std; using namespace std;
using namespace ZL::Util; using namespace ZL::Util;
typedef enum {
TrackVideo = 0,
TrackAudio,
TrackInvalid,
TrackMax
} TrackType;
class RtspTrack{ class RtspTrack{
public: public:
uint8_t PT; uint8_t PT;
uint8_t interleaved; uint8_t interleaved;
TrackType type = (TrackType) -1; TrackType type = TrackInvalid;
string trackSdp; string trackSdp;
string controlSuffix; string controlSuffix;
bool inited; bool inited;
@ -56,21 +51,6 @@ public:
uint32_t timeStamp; uint32_t timeStamp;
}; };
class RtpPacket {
public:
typedef std::shared_ptr<RtpPacket> Ptr;
uint8_t interleaved;
uint8_t PT;
bool mark;
uint32_t length;
uint32_t timeStamp;
uint16_t sequence;
uint32_t ssrc;
uint8_t payload[1560];
uint8_t offset;
TrackType type;
};
class RtcpCounter { class RtcpCounter {
public: public:
uint32_t pktCnt = 0; uint32_t pktCnt = 0;

View File

@ -5,51 +5,71 @@
#ifndef ZLMEDIAKIT_RTSPMAKER_H #ifndef ZLMEDIAKIT_RTSPMAKER_H
#define ZLMEDIAKIT_RTSPMAKER_H #define ZLMEDIAKIT_RTSPMAKER_H
#include "Device/base64.h" #include "RTP/H264RtpCodec.h"
#include "Rtsp.h" #include "RTP/AACRtpCodec.h"
#include "RTP/RtpMaker.h" #include "Util/base64.h"
#include "RTP/RtpMakerH264.h"
#include "RTP/RtpMakerAAC.h"
#include "Player/PlayerBase.h"
using namespace ZL::Player;
using namespace ZL::Rtsp;
namespace ZL{ namespace ZL{
namespace Rtsp{ namespace Rtsp{
/** /**
* sdp基类 * sdp基类
*/ */
class Sdp { class Sdp : public TrackFormat , public RtpRingInterface{
public: public:
typedef std::shared_ptr<Sdp> Ptr; typedef std::shared_ptr<Sdp> Ptr;
Sdp(){}
virtual ~Sdp(){} virtual ~Sdp(){}
/** /**
* sdp字符串 * sdp字符串
* @return * @return
*/ */
virtual string getSdp() const { return "";}; virtual string getSdp() const = 0;
/** TrackType getTrackType() const override {
* track类型 return TrackInvalid;
* @return }
*/
virtual TrackType getTrackType() const { return TrackInvalid;};
/** CodecId getCodecId() const override{
* rtp生成器 return CodecInvalid;
* @param cb lambad }
* @param ui32Ssrc rtp ssrc
* @param iMtuSize rtp mtu FrameRingInterface::RingType::Ptr getFrameRing() const override {
* @return return _encoder->getFrameRing();
*/ }
virtual RtpMaker::Ptr createRtpMaker(const RtpMaker::onGetRTP &cb,uint32_t ui32Ssrc, int iMtuSize) const{ return nullptr;};
RtpRingInterface::RingType::Ptr getRtpRing() const override{
return _encoder->getRtpRing();
}
void inputFrame(const Frame::Ptr &frame,bool key_pos) override{
_encoder->inputFrame(frame,key_pos);
}
void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override{
_encoder->inputRtp(rtp,key_pos);
}
virtual void createRtpEncoder(uint32_t ssrc, int mtu) = 0;
void setFrameRing(const FrameRingInterface::RingType::Ptr &ring) override{
if(_encoder){
_encoder->setFrameRing(ring);
}
}
void setRtpRing(const RtpRingInterface::RingType::Ptr &ring) override{
if(_encoder){
_encoder->setRtpRing(ring);
}
}
protected:
RtpEncoder::Ptr _encoder;
}; };
/** /**
* sdp中除音视频外的其他描述部分 * sdp中除音视频外的其他描述部分
*/ */
class SdpTitle : public Sdp{ class SdpTitle : public Sdp{
public: public:
@ -70,8 +90,8 @@ public:
} }
} else { } else {
_printer << "o=- 1383190487994921 1 IN IP4 0.0.0.0\r\n"; _printer << "o=- 1383190487994921 1 IN IP4 0.0.0.0\r\n";
_printer << "s=RTSP Session, streamed by the ZL\r\n"; _printer << "s=RTSP Session, streamed by the ZLMediaKit\r\n";
_printer << "i=ZL Live Stream\r\n"; _printer << "i=ZLMediaKit Live Stream\r\n";
_printer << "c=IN IP4 0.0.0.0\r\n"; _printer << "c=IN IP4 0.0.0.0\r\n";
_printer << "t=0 0\r\n"; _printer << "t=0 0\r\n";
} }
@ -86,14 +106,14 @@ public:
string getSdp() const override { string getSdp() const override {
return _printer; return _printer;
} }
void createRtpEncoder(uint32_t ssrc, int mtu) override {}
private: private:
_StrPrinter _printer; _StrPrinter _printer;
}; };
/** /**
* h264类型sdp * h264类型sdp
*/ */
class SdpH264 : public Sdp { class SdpH264 : public Sdp {
public: public:
@ -111,7 +131,7 @@ public:
int sample_rate = 90000, int sample_rate = 90000,
int playload_type = 96, int playload_type = 96,
int track_id = TrackVideo, int track_id = TrackVideo,
int bitrate = 4000){ int bitrate = 4000) {
_playload_type = playload_type; _playload_type = playload_type;
_sample_rate = sample_rate; _sample_rate = sample_rate;
@ -149,12 +169,19 @@ public:
TrackType getTrackType() const override { TrackType getTrackType() const override {
return TrackVideo; return TrackVideo;
}; }
RtpMaker::Ptr createRtpMaker(const RtpMaker::onGetRTP &cb,uint32_t ui32Ssrc, int iMtuSize) const override{ CodecId getCodecId() const override {
return std::make_shared<RtpMaker_H264>(cb,ui32Ssrc,iMtuSize,_sample_rate,_playload_type,_track_id * 2); return CodecH264;
}; }
void createRtpEncoder(uint32_t ssrc, int mtu) override{
_encoder = std::make_shared<H264RtpEncoder>(ssrc,
mtu,
_sample_rate,
_playload_type,
_track_id * 2);
}
private: private:
_StrPrinter _printer; _StrPrinter _printer;
int _playload_type; int _playload_type;
@ -165,8 +192,8 @@ private:
/** /**
* aac类型SDP * aac类型SDP
*/ */
class SdpAAC : public Sdp { class SdpAAC : public Sdp {
public: public:
@ -207,10 +234,29 @@ public:
TrackType getTrackType() const override { TrackType getTrackType() const override {
return TrackAudio; return TrackAudio;
}; };
CodecId getCodecId() const override {
return CodecAAC;
}
RtpMaker::Ptr createRtpMaker(const RtpMaker::onGetRTP &cb,uint32_t ui32Ssrc, int iMtuSize) const override{ void createRtpEncoder(uint32_t ssrc,
return std::make_shared<RtpMaker_AAC>(cb,ui32Ssrc,iMtuSize,_sample_rate,_playload_type,_track_id * 2); int mtu) override{
}; _encoder = std::make_shared<AACRtpEncoder>(ssrc,
mtu,
_sample_rate,
_playload_type,
_track_id * 2);
}
void setFrameRing(const FrameRingInterface::RingType::Ptr &ring) override{
if(_encoder){
_encoder->setFrameRing(ring);
}
}
void setRtpRing(const RtpRingInterface::RingType::Ptr &ring) override{
if(_encoder){
_encoder->setRtpRing(ring);
}
}
private: private:
_StrPrinter _printer; _StrPrinter _printer;
int _playload_type; int _playload_type;
@ -219,87 +265,118 @@ private:
}; };
/** /**
* rtsp生成器 * rtsp生成器
*/ */
class RtspMaker{ class RtspEncoder : public FrameRingInterface , public RtpRingInterface{
public: public:
/** /**
* *
* @param callback rtp回调lambad
*/ */
RtspMaker(const RtpMaker::onGetRTP &callback) : _vec_rtp_maker(TrackMax){ RtspEncoder(){
_callback = callback; //自适应缓存
_rtpRing = std::make_shared<RtpRingInterface::RingType>(0);
//禁用缓存
_frameRing = std::make_shared<FrameRingInterface::RingType>(1);
} }
virtual ~RtspEncoder(){}
/** /**
* track * track
* @param sdp * @param sdp
* @param ssrc rtp ssrc * @param ssrc rtp ssrc
* @param mtu rtp mtu * @param mtu rtp mtu
* @return
*/ */
bool addTrack(const Sdp & sdp,uint32_t ssrc = 0,int mtu = 1400){ void addTrack(const Sdp::Ptr & sdp,uint32_t ssrc = 0,int mtu = 1400){
auto type = sdp.getTrackType();
if(type < 0 || type >= _vec_rtp_maker.size()){
return false;
}
if(_vec_rtp_maker[type]){
return false;
}
if(ssrc == 0){ if(ssrc == 0){
ssrc = ((uint64_t) &sdp) & 0xFFFFFFFF; ssrc = ((uint64_t) sdp.get()) & 0xFFFFFFFF;
} }
sdp->createRtpEncoder(ssrc, mtu);
auto rtpMaker = sdp.createRtpMaker(_callback, ssrc,mtu); sdp->setFrameRing(_frameRing);
_vec_rtp_maker[sdp.getTrackType()] = rtpMaker; sdp->setRtpRing(_rtpRing);
_printer << sdp.getSdp(); _sdp_map[sdp->getTrackType()] = sdp;
return true;
} }
virtual ~RtspMaker() {};
/** /**
* SDP字符串 * SDP字符串
* @return SDP字符串 * @return SDP字符串
*/ */
string getSdp() { string getSdp() {
return _printer; _StrPrinter printer;
for(auto &pr : _sdp_map){
printer << pr.second->getSdp() ;
}
return printer;
} }
/** /**
* RTP数据包 * rtp
* @param type * @param frame
* @param pcData * @param key_pos
* @param iDataLen
* @param uiStamp
* @return
*/ */
bool makeRtp(TrackType type,const char *pcData, int iDataLen, uint32_t uiStamp){ void inputFrame(const Frame::Ptr &frame,bool key_pos = true) override {
if(type < 0 || type >= _vec_rtp_maker.size()){ auto it = _sdp_map.find(frame->getTrackType());
return false; if(it == _sdp_map.end()){
return ;
} }
auto track = _vec_rtp_maker[type]; it->second->inputFrame(frame,key_pos);
if(!track){
return false;
}
track->makeRtp(pcData,iDataLen,uiStamp);
return true;
} }
/**
* rtp然后再写入
* @param rtp rtp包
* @param key_pos rtp包
*/
void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override {
_rtpRing->write(rtp,key_pos);
}
/**
* rtp环形缓存
* @return
*/
RtpRingInterface::RingType::Ptr getRtpRing() const override{
return _rtpRing;
}
/**
*
* @return
*/
FrameRingInterface::RingType::Ptr getFrameRing() const override{
return _frameRing;
}
/**
*
* @param ring
*/
void setFrameRing(const FrameRingInterface::RingType::Ptr &ring) override{
_frameRing = ring;
for(auto &pr : _sdp_map){
pr.second->setFrameRing(ring);
}
}
/**
* rtp环形缓存
* @param ring
*/
void setRtpRing(const RtpRingInterface::RingType::Ptr &ring) override{
_rtpRing = ring;
for(auto &pr : _sdp_map){
pr.second->setRtpRing(ring);
}
}
private: private:
vector<RtpMaker::Ptr> _vec_rtp_maker; map<int,Sdp::Ptr> _sdp_map;
_StrPrinter _printer; RtpRingInterface::RingType::Ptr _rtpRing;
RtpMaker::onGetRTP _callback; FrameRingInterface::RingType::Ptr _frameRing;
}; };
} }
} }

View File

@ -35,6 +35,7 @@
#include "Rtsp.h" #include "Rtsp.h"
#include "Common/config.h" #include "Common/config.h"
#include "Common/MediaSource.h" #include "Common/MediaSource.h"
#include "RTP/RtpCodec.h"
#include "Util/logger.h" #include "Util/logger.h"
#include "Util/RingBuffer.h" #include "Util/RingBuffer.h"

View File

@ -124,7 +124,7 @@ void RtspToRtmpMediaSource::onGetH264(const H264Frame& frame) {
rtmpPkt->typeId = MSG_VIDEO; rtmpPkt->typeId = MSG_VIDEO;
m_pRtmpSrc->onGetMedia(rtmpPkt); m_pRtmpSrc->onGetMedia(rtmpPkt);
} }
void RtspToRtmpMediaSource::onGetAdts(const AdtsFrame& frame) { void RtspToRtmpMediaSource::onGetAdts(const AACFrame& frame) {
if(m_pRecorder){ if(m_pRecorder){
m_pRecorder->inputAAC((char *) frame.buffer, frame.aac_frame_length, frame.timeStamp); m_pRecorder->inputAAC((char *) frame.buffer, frame.aac_frame_length, frame.timeStamp);
} }

View File

@ -97,7 +97,7 @@ private:
bool m_bEnableHls; bool m_bEnableHls;
bool m_bEnableMp4; bool m_bEnableMp4;
void onGetH264(const H264Frame &frame); void onGetH264(const H264Frame &frame);
void onGetAdts(const AdtsFrame &frame); void onGetAdts(const AACFrame &frame);
void makeVideoConfigPkt(); void makeVideoConfigPkt();
void makeAudioConfigPkt(); void makeAudioConfigPkt();
void makeMetaData(); void makeMetaData();