mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-12-02 00:12:33 +08:00
初步完成Rtp解包
This commit is contained in:
parent
49daa1baad
commit
8930dd099e
@ -27,6 +27,8 @@ typedef enum {
|
|||||||
|
|
||||||
class CodecInfo {
|
class CodecInfo {
|
||||||
public:
|
public:
|
||||||
|
typedef std::shared_ptr<CodecInfo> Ptr;
|
||||||
|
|
||||||
CodecInfo(){}
|
CodecInfo(){}
|
||||||
virtual ~CodecInfo(){}
|
virtual ~CodecInfo(){}
|
||||||
|
|
||||||
@ -63,6 +65,7 @@ public:
|
|||||||
class FrameRingInterface {
|
class FrameRingInterface {
|
||||||
public:
|
public:
|
||||||
typedef RingBuffer<Frame::Ptr> RingType;
|
typedef RingBuffer<Frame::Ptr> RingType;
|
||||||
|
typedef std::shared_ptr<FrameRingInterface> Ptr;
|
||||||
|
|
||||||
FrameRingInterface(){}
|
FrameRingInterface(){}
|
||||||
virtual ~FrameRingInterface(){}
|
virtual ~FrameRingInterface(){}
|
||||||
@ -83,8 +86,9 @@ public:
|
|||||||
* 写入帧数据
|
* 写入帧数据
|
||||||
* @param frame 帧
|
* @param frame 帧
|
||||||
* @param key_pos 是否为关键帧
|
* @param key_pos 是否为关键帧
|
||||||
|
* @return 是否为关键帧
|
||||||
*/
|
*/
|
||||||
virtual void inputFrame(const Frame::Ptr &frame,bool key_pos) = 0;
|
virtual bool inputFrame(const Frame::Ptr &frame,bool key_pos) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -118,8 +122,9 @@ public:
|
|||||||
* @param frame
|
* @param frame
|
||||||
* @param key_pos
|
* @param key_pos
|
||||||
*/
|
*/
|
||||||
void inputFrame(const Frame::Ptr &frame,bool key_pos) override{
|
bool inputFrame(const Frame::Ptr &frame,bool key_pos) override{
|
||||||
_frameRing->write(frame,key_pos);
|
_frameRing->write(frame,key_pos);
|
||||||
|
return key_pos;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
RingType::Ptr _frameRing;
|
RingType::Ptr _frameRing;
|
||||||
|
@ -87,8 +87,7 @@ public:
|
|||||||
virtual float getRtpLossRate(int trackType) const {return 0; }
|
virtual float getRtpLossRate(int trackType) const {return 0; }
|
||||||
virtual float getDuration() const { return 0;}
|
virtual float getDuration() const { return 0;}
|
||||||
|
|
||||||
virtual int getTrackCount() const { return 0;}
|
virtual vector<Track::Ptr> getTracks() const { return vector<Track::Ptr>();}
|
||||||
virtual Track::Ptr getTrack(int index) const {return nullptr;}
|
|
||||||
protected:
|
protected:
|
||||||
virtual void onShutdown(const SockException &ex) {}
|
virtual void onShutdown(const SockException &ex) {}
|
||||||
virtual void onPlayResult(const SockException &ex) {}
|
virtual void onPlayResult(const SockException &ex) {}
|
||||||
@ -146,18 +145,12 @@ public:
|
|||||||
m_pMediaSrc = src;
|
m_pMediaSrc = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int getTrackCount() const override{
|
vector<Track::Ptr> getTracks() const override{
|
||||||
if (m_parser) {
|
if (m_parser) {
|
||||||
return m_parser->getTrackCount();
|
return m_parser->getTracks();
|
||||||
}
|
}
|
||||||
return PlayerBase::getTrackCount();
|
return PlayerBase::getTracks();
|
||||||
}
|
}
|
||||||
virtual Track::Ptr getTrack(int index) const override{
|
|
||||||
if (m_parser) {
|
|
||||||
return m_parser->getTrack(index);
|
|
||||||
}
|
|
||||||
return PlayerBase::getTrack(index);
|
|
||||||
}
|
|
||||||
protected:
|
protected:
|
||||||
void onShutdown(const SockException &ex) override {
|
void onShutdown(const SockException &ex) override {
|
||||||
if (m_shutdownCB) {
|
if (m_shutdownCB) {
|
||||||
|
@ -26,6 +26,8 @@ public:
|
|||||||
|
|
||||||
class VideoTrack : public Track {
|
class VideoTrack : public Track {
|
||||||
public:
|
public:
|
||||||
|
typedef std::shared_ptr<VideoTrack> Ptr;
|
||||||
|
|
||||||
TrackType getTrackType() const override { return TrackVideo;};
|
TrackType getTrackType() const override { return TrackVideo;};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,6 +51,8 @@ public:
|
|||||||
|
|
||||||
class AudioTrack : public Track {
|
class AudioTrack : public Track {
|
||||||
public:
|
public:
|
||||||
|
typedef std::shared_ptr<AudioTrack> Ptr;
|
||||||
|
|
||||||
TrackType getTrackType() const override { return TrackAudio;};
|
TrackType getTrackType() const override { return TrackAudio;};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,6 +76,7 @@ public:
|
|||||||
|
|
||||||
class H264Track : public VideoTrack{
|
class H264Track : public VideoTrack{
|
||||||
public:
|
public:
|
||||||
|
typedef std::shared_ptr<H264Track> Ptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 不指定sps pps构造h264类型的媒体
|
* 不指定sps pps构造h264类型的媒体
|
||||||
@ -162,7 +167,7 @@ public:
|
|||||||
* @param frame 数据帧
|
* @param frame 数据帧
|
||||||
* @param key_pos 是否为关键帧
|
* @param key_pos 是否为关键帧
|
||||||
*/
|
*/
|
||||||
void inputFrame(const Frame::Ptr &frame,bool key_pos) override{
|
bool inputFrame(const Frame::Ptr &frame,bool key_pos) override{
|
||||||
int type = (*((uint8_t *)frame->data() + frame->prefixSize())) & 0x1F;
|
int type = (*((uint8_t *)frame->data() + frame->prefixSize())) & 0x1F;
|
||||||
switch (type){
|
switch (type){
|
||||||
case 7:{
|
case 7:{
|
||||||
@ -209,6 +214,7 @@ public:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return type == 5;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@ -228,6 +234,8 @@ private:
|
|||||||
|
|
||||||
class AACTrack : public AudioTrack{
|
class AACTrack : public AudioTrack{
|
||||||
public:
|
public:
|
||||||
|
typedef std::shared_ptr<AACTrack> Ptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造aac类型的媒体
|
* 构造aac类型的媒体
|
||||||
* @param aac_cfg aac两个字节的配置信息
|
* @param aac_cfg aac两个字节的配置信息
|
||||||
|
@ -17,7 +17,7 @@ AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc,
|
|||||||
AACRtpDecoder(ui32SampleRate){
|
AACRtpDecoder(ui32SampleRate){
|
||||||
}
|
}
|
||||||
|
|
||||||
void AACRtpEncoder::inputFrame(const Frame::Ptr &frame, bool key_pos) {
|
bool AACRtpEncoder::inputFrame(const Frame::Ptr &frame, bool key_pos) {
|
||||||
RtpCodec::inputFrame(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);
|
||||||
@ -46,8 +46,8 @@ void AACRtpEncoder::inputFrame(const Frame::Ptr &frame, bool key_pos) {
|
|||||||
makeAACRtp(m_aucSectionBuf, m_ui32MtuSize - 16, false, uiStamp);
|
makeAACRtp(m_aucSectionBuf, m_ui32MtuSize - 16, false, uiStamp);
|
||||||
ptr += (m_ui32MtuSize - 20);
|
ptr += (m_ui32MtuSize - 20);
|
||||||
iSize -= (m_ui32MtuSize - 20);
|
iSize -= (m_ui32MtuSize - 20);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AACRtpEncoder::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) {
|
||||||
@ -100,24 +100,24 @@ AACFrame::Ptr AACRtpDecoder::obtainFrame() {
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
|
bool 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(AACFrame::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 false;
|
||||||
}
|
}
|
||||||
memcpy(m_adts->buffer + m_adts->aac_frame_length, rtppack->payload + rtppack->offset + 4, length - 4);
|
memcpy(m_adts->buffer + m_adts->aac_frame_length, rtppack->payload + rtppack->offset + 4, length - 4);
|
||||||
m_adts->aac_frame_length += (length - 4);
|
m_adts->aac_frame_length += (length - 4);
|
||||||
if (rtppack->mark == true) {
|
if (rtppack->mark == true) {
|
||||||
m_adts->sequence = rtppack->sequence;
|
m_adts->sequence = rtppack->sequence;
|
||||||
//todo(xzl) 此处完成时间戳转换
|
|
||||||
m_adts->timeStamp = rtppack->timeStamp * (1000.0 / m_sampleRate);
|
m_adts->timeStamp = rtppack->timeStamp * (1000.0 / m_sampleRate);
|
||||||
writeAdtsHeader(*m_adts, m_adts->buffer);
|
writeAdtsHeader(*m_adts, m_adts->buffer);
|
||||||
onGetAdts(m_adts);
|
onGetAdts(m_adts);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AACRtpDecoder::onGetAdts(const AACFrame::Ptr &frame) {
|
void AACRtpDecoder::onGetAdts(const AACFrame::Ptr &frame) {
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
class AACRtpDecoder : public RtpCodec {
|
class AACRtpDecoder : public RtpCodec {
|
||||||
public:
|
public:
|
||||||
|
typedef std::shared_ptr<AACRtpDecoder> Ptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ui32SampleRate 采样率,用于时间戳转换用
|
* @param ui32SampleRate 采样率,用于时间戳转换用
|
||||||
*/
|
*/
|
||||||
@ -23,7 +25,7 @@ public:
|
|||||||
* @param rtp rtp数据包
|
* @param rtp rtp数据包
|
||||||
* @param key_pos 此参数内部强制转换为false,请忽略之
|
* @param key_pos 此参数内部强制转换为false,请忽略之
|
||||||
*/
|
*/
|
||||||
void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = false) override;
|
bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = false) override;
|
||||||
|
|
||||||
TrackType getTrackType() const override{
|
TrackType getTrackType() const override{
|
||||||
return TrackAudio;
|
return TrackAudio;
|
||||||
@ -47,6 +49,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
class AACRtpEncoder : public AACRtpDecoder , public RtpInfo {
|
class AACRtpEncoder : public AACRtpDecoder , public RtpInfo {
|
||||||
public:
|
public:
|
||||||
|
typedef std::shared_ptr<AACRtpEncoder> Ptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ui32Ssrc ssrc
|
* @param ui32Ssrc ssrc
|
||||||
* @param ui32MtuSize mtu 大小
|
* @param ui32MtuSize mtu 大小
|
||||||
@ -66,7 +70,7 @@ public:
|
|||||||
* @param frame 带dats头的aac数据
|
* @param frame 带dats头的aac数据
|
||||||
* @param key_pos 此参数内部强制转换为false,请忽略之
|
* @param key_pos 此参数内部强制转换为false,请忽略之
|
||||||
*/
|
*/
|
||||||
void inputFrame(const Frame::Ptr &frame, bool key_pos = false) override;
|
bool inputFrame(const Frame::Ptr &frame, bool key_pos = false) override;
|
||||||
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:
|
||||||
|
@ -17,8 +17,10 @@ H264Frame::Ptr H264RtpDecoder::obtainFrame() {
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void H264RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) {
|
bool H264RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) {
|
||||||
RtpCodec::inputRtp(rtp, decodeRtp(rtp));
|
key_pos = decodeRtp(rtp);
|
||||||
|
RtpCodec::inputRtp(rtp, key_pos);
|
||||||
|
return key_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
|
bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
|
||||||
@ -116,12 +118,14 @@ H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc,
|
|||||||
ui8Interleaved) {
|
ui8Interleaved) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void H264RtpEncoder::inputFrame(const Frame::Ptr &frame, bool key_pos) {
|
bool H264RtpEncoder::inputFrame(const Frame::Ptr &frame, bool key_pos) {
|
||||||
|
auto pcData = frame->data() + frame->prefixSize();
|
||||||
|
|
||||||
|
key_pos = (((uint8_t *) (pcData))[0] & 0x1F) == 5;
|
||||||
RtpCodec::inputFrame(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();
|
||||||
auto pcData = frame->data() + frame->prefixSize();
|
|
||||||
auto iLen = frame->size() - frame->prefixSize();
|
auto iLen = frame->size() - frame->prefixSize();
|
||||||
|
|
||||||
uiStamp %= cycleMS;
|
uiStamp %= cycleMS;
|
||||||
@ -163,6 +167,8 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame, bool key_pos) {
|
|||||||
} else {
|
} else {
|
||||||
makeH264Rtp(pcData, iLen, true, uiStamp);
|
makeH264Rtp(pcData, iLen, true, uiStamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return key_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void H264RtpEncoder::makeH264Rtp(const void* data, unsigned int len, bool mark, uint32_t uiStamp) {
|
void H264RtpEncoder::makeH264Rtp(const void* data, unsigned int len, bool mark, uint32_t uiStamp) {
|
||||||
|
@ -15,6 +15,8 @@ using namespace ZL::Util;
|
|||||||
*/
|
*/
|
||||||
class H264RtpDecoder : public RtpCodec {
|
class H264RtpDecoder : public RtpCodec {
|
||||||
public:
|
public:
|
||||||
|
typedef std::shared_ptr<H264RtpDecoder> Ptr;
|
||||||
|
|
||||||
H264RtpDecoder();
|
H264RtpDecoder();
|
||||||
~H264RtpDecoder() {}
|
~H264RtpDecoder() {}
|
||||||
|
|
||||||
@ -23,7 +25,7 @@ public:
|
|||||||
* @param rtp rtp包
|
* @param rtp rtp包
|
||||||
* @param key_pos 此参数忽略之
|
* @param key_pos 此参数忽略之
|
||||||
*/
|
*/
|
||||||
void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override;
|
bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override;
|
||||||
|
|
||||||
TrackType getTrackType() const override{
|
TrackType getTrackType() const override{
|
||||||
return TrackVideo;
|
return TrackVideo;
|
||||||
@ -46,6 +48,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
class H264RtpEncoder : public H264RtpDecoder ,public RtpInfo{
|
class H264RtpEncoder : public H264RtpDecoder ,public RtpInfo{
|
||||||
public:
|
public:
|
||||||
|
typedef std::shared_ptr<H264RtpEncoder> Ptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ui32Ssrc ssrc
|
* @param ui32Ssrc ssrc
|
||||||
@ -66,7 +69,7 @@ public:
|
|||||||
* @param frame 帧数据,必须
|
* @param frame 帧数据,必须
|
||||||
* @param key_pos
|
* @param key_pos
|
||||||
*/
|
*/
|
||||||
void inputFrame(const Frame::Ptr &frame, bool key_pos) override;
|
bool inputFrame(const Frame::Ptr &frame, bool key_pos) override;
|
||||||
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:
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
#include "AACRtpCodec.h"
|
#include "AACRtpCodec.h"
|
||||||
#include "H264RtpCodec.h"
|
#include "H264RtpCodec.h"
|
||||||
|
|
||||||
RtpCodec::Ptr RtpCodec::getRtpCodecById(CodecId codecId,
|
RtpCodec::Ptr RtpCodec::getRtpEncoderById(CodecId codecId,
|
||||||
uint32_t ui32Ssrc,
|
uint32_t ui32Ssrc,
|
||||||
uint32_t ui32MtuSize,
|
uint32_t ui32MtuSize,
|
||||||
uint32_t ui32SampleRate,
|
uint32_t ui32SampleRate,
|
||||||
uint8_t ui8PlayloadType,
|
uint8_t ui8PlayloadType,
|
||||||
uint8_t ui8Interleaved) {
|
uint8_t ui8Interleaved) {
|
||||||
switch (codecId){
|
switch (codecId){
|
||||||
case CodecH264:
|
case CodecH264:
|
||||||
return std::make_shared<H264RtpEncoder>(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved);
|
return std::make_shared<H264RtpEncoder>(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved);
|
||||||
@ -21,3 +21,15 @@ RtpCodec::Ptr RtpCodec::getRtpCodecById(CodecId codecId,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtpCodec::Ptr RtpCodec::getRtpDecoderById(CodecId codecId, uint32_t ui32SampleRate) {
|
||||||
|
switch (codecId){
|
||||||
|
case CodecH264:
|
||||||
|
return std::make_shared<H264RtpDecoder>();
|
||||||
|
case CodecAAC:
|
||||||
|
return std::make_shared<AACRtpDecoder>(ui32SampleRate);
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -41,12 +41,30 @@ public:
|
|||||||
class RtpRingInterface {
|
class RtpRingInterface {
|
||||||
public:
|
public:
|
||||||
typedef RingBuffer<RtpPacket::Ptr> RingType;
|
typedef RingBuffer<RtpPacket::Ptr> RingType;
|
||||||
|
typedef std::shared_ptr<RtpRingInterface> Ptr;
|
||||||
|
|
||||||
RtpRingInterface(){}
|
RtpRingInterface(){}
|
||||||
virtual ~RtpRingInterface(){}
|
virtual ~RtpRingInterface(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取rtp环形缓存
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
virtual RingType::Ptr getRtpRing() const = 0;
|
virtual RingType::Ptr getRtpRing() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置rtp环形缓存
|
||||||
|
* @param ring
|
||||||
|
*/
|
||||||
virtual void setRtpRing(const RingType::Ptr &ring) = 0;
|
virtual void setRtpRing(const RingType::Ptr &ring) = 0;
|
||||||
virtual void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) = 0;
|
|
||||||
|
/**
|
||||||
|
* 输入rtp包
|
||||||
|
* @param rtp rtp包
|
||||||
|
* @param key_pos 是否为关键帧第一个rtp包
|
||||||
|
* @return 是否为关键帧第一个rtp包
|
||||||
|
*/
|
||||||
|
virtual bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RtpRing : public RtpRingInterface {
|
class RtpRing : public RtpRingInterface {
|
||||||
@ -67,8 +85,9 @@ public:
|
|||||||
_rtpRing = ring;
|
_rtpRing = ring;
|
||||||
}
|
}
|
||||||
|
|
||||||
void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override{
|
bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override{
|
||||||
_rtpRing->write(rtp,key_pos);
|
_rtpRing->write(rtp,key_pos);
|
||||||
|
return key_pos;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
RingType::Ptr _rtpRing;
|
RingType::Ptr _rtpRing;
|
||||||
@ -143,12 +162,14 @@ public:
|
|||||||
RtpCodec(){}
|
RtpCodec(){}
|
||||||
virtual ~RtpCodec(){}
|
virtual ~RtpCodec(){}
|
||||||
|
|
||||||
static Ptr getRtpCodecById(CodecId codecId,
|
static Ptr getRtpEncoderById(CodecId codecId,
|
||||||
uint32_t ui32Ssrc,
|
uint32_t ui32Ssrc,
|
||||||
uint32_t ui32MtuSize,
|
uint32_t ui32MtuSize,
|
||||||
uint32_t ui32SampleRate,
|
uint32_t ui32SampleRate,
|
||||||
uint8_t ui8PlayloadType,
|
uint8_t ui8PlayloadType,
|
||||||
uint8_t ui8Interleaved);
|
uint8_t ui8Interleaved);
|
||||||
|
|
||||||
|
static Ptr getRtpDecoderById(CodecId codecId,uint32_t ui32SampleRate);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ public:
|
|||||||
lock_guard<recursive_mutex> lock(m_mtxMap);
|
lock_guard<recursive_mutex> lock(m_mtxMap);
|
||||||
m_metadata = _metadata;
|
m_metadata = _metadata;
|
||||||
RtmpParser parser(_metadata);
|
RtmpParser parser(_metadata);
|
||||||
m_iCfgFrameSize = parser.getTrackCount();
|
m_iCfgFrameSize = parser.getTracks().size();
|
||||||
if(ready()){
|
if(ready()){
|
||||||
MediaSource::regist();
|
MediaSource::regist();
|
||||||
m_bRegisted = true;
|
m_bRegisted = true;
|
||||||
|
@ -53,76 +53,73 @@ static int getTimeInSDP(const string &sdp) {
|
|||||||
RtpParser::RtpParser(const string& sdp) {
|
RtpParser::RtpParser(const string& sdp) {
|
||||||
RtspTrack tmp[2];
|
RtspTrack tmp[2];
|
||||||
int cnt = parserSDP(sdp, tmp);
|
int cnt = parserSDP(sdp, tmp);
|
||||||
if (0 == cnt) {
|
|
||||||
throw std::runtime_error("parse sdp failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < cnt; i++) {
|
for (int i = 0; i < cnt; i++) {
|
||||||
switch (tmp[i].type) {
|
switch (tmp[i].type) {
|
||||||
case TrackVideo: {
|
case TrackVideo: {
|
||||||
try {
|
onGetVideoTrack(tmp[i]);
|
||||||
onGetVideoTrack(tmp[i]);
|
|
||||||
m_bHaveVideo = true;
|
|
||||||
m_mapTracks.emplace(tmp[i].PT, tmp[i]);
|
|
||||||
} catch (std::exception &ex) {
|
|
||||||
WarnL << ex.what();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TrackAudio: {
|
case TrackAudio: {
|
||||||
try {
|
onGetAudioTrack(tmp[i]);
|
||||||
onGetAudioTrack(tmp[i]);
|
|
||||||
m_bHaveAudio = true;
|
|
||||||
m_mapTracks.emplace(tmp[i].PT, tmp[i]);
|
|
||||||
} catch (std::exception &ex) {
|
|
||||||
WarnL << ex.what();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!m_bHaveVideo && !m_bHaveAudio) {
|
|
||||||
throw std::runtime_error("不支持该RTSP媒体格式");
|
|
||||||
}
|
|
||||||
m_fDuration = getTimeInSDP(sdp);
|
m_fDuration = getTimeInSDP(sdp);
|
||||||
}
|
}
|
||||||
RtpParser::~RtpParser() {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RtpParser::inputRtp(const RtpPacket::Ptr & rtp) {
|
bool RtpParser::inputRtp(const RtpPacket::Ptr & rtp) {
|
||||||
auto &track = m_mapTracks[rtp->PT];
|
switch (rtp->getTrackType()) {
|
||||||
switch (track.type) {
|
|
||||||
case TrackVideo:
|
case TrackVideo:
|
||||||
if (m_bHaveVideo) {
|
return inputVideo(rtp);
|
||||||
return inputVideo(rtp, track);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
case TrackAudio:
|
case TrackAudio:
|
||||||
if (m_bHaveAudio) {
|
return inputAudio(rtp);
|
||||||
return inputAudio(rtp, track);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool RtpParser::inputVideo(const RtpPacket::Ptr & rtp, const RtspTrack& track) {
|
inline bool RtpParser::inputVideo(const RtpPacket::Ptr &rtp) {
|
||||||
|
if(_videoRtpDecoder){
|
||||||
|
return _videoRtpDecoder->inputRtp(rtp, true);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool RtpParser::inputAudio(const RtpPacket::Ptr &rtp) {
|
||||||
|
if(_audioRtpDecoder){
|
||||||
|
return _audioRtpDecoder->inputRtp(rtp, false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RtpParser::onGetAudioTrack(const RtspTrack& audio) {
|
inline void RtpParser::onGetAudioTrack(const RtspTrack& audio) {
|
||||||
|
_audioTrack = dynamic_pointer_cast<AudioTrack>(Track::getTrackBySdp(audio.trackSdp));
|
||||||
|
if(_audioTrack){
|
||||||
|
_audioRtpDecoder = RtpCodec::getRtpDecoderById(_audioTrack->getCodecId(),_audioTrack->getAudioSampleRate());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RtpParser::onGetVideoTrack(const RtspTrack& video) {
|
inline void RtpParser::onGetVideoTrack(const RtspTrack& video) {
|
||||||
|
_videoTrack = dynamic_pointer_cast<VideoTrack>(Track::getTrackBySdp(video.trackSdp));
|
||||||
|
if(_videoTrack){
|
||||||
|
_videoRtpDecoder = RtpCodec::getRtpDecoderById(_videoTrack->getCodecId(),90000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool RtpParser::inputAudio(const RtpPacket::Ptr &rtppack, const RtspTrack& track) {
|
vector<Track::Ptr> RtpParser::getTracks() const {
|
||||||
|
vector<Track::Ptr> ret;
|
||||||
|
if(_videoTrack){
|
||||||
|
ret.emplace_back(_videoTrack);
|
||||||
|
}
|
||||||
|
if(_audioTrack){
|
||||||
|
ret.emplace_back(_audioTrack);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} /* namespace Rtsp */
|
} /* namespace Rtsp */
|
||||||
} /* namespace ZL */
|
} /* namespace ZL */
|
||||||
|
@ -45,7 +45,8 @@ class RtpParser : public PlayerBase{
|
|||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<RtpParser> Ptr;
|
typedef std::shared_ptr<RtpParser> Ptr;
|
||||||
RtpParser(const string &sdp);
|
RtpParser(const string &sdp);
|
||||||
virtual ~RtpParser();
|
virtual ~RtpParser(){};
|
||||||
|
|
||||||
//返回值:true 代表是i帧第一个rtp包
|
//返回值:true 代表是i帧第一个rtp包
|
||||||
bool inputRtp(const RtpPacket::Ptr &rtp);
|
bool inputRtp(const RtpPacket::Ptr &rtp);
|
||||||
|
|
||||||
@ -54,32 +55,22 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isInited() const override{
|
bool isInited() const override{
|
||||||
if (m_bHaveAudio && !m_strAudioCfg.size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (m_bHaveVideo && !m_strSPS.size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
std::unordered_map<uint8_t, RtspTrack> m_mapTracks;
|
|
||||||
|
|
||||||
|
vector<Track::Ptr> getTracks() const override;
|
||||||
|
private:
|
||||||
inline void onGetAudioTrack(const RtspTrack &audio);
|
inline void onGetAudioTrack(const RtspTrack &audio);
|
||||||
inline void onGetVideoTrack(const RtspTrack &video);
|
inline void onGetVideoTrack(const RtspTrack &video);
|
||||||
|
|
||||||
//返回值:true 代表是i帧第一个rtp包
|
//返回值:true 代表是i帧第一个rtp包
|
||||||
inline bool inputVideo(const RtpPacket::Ptr &rtp, const RtspTrack &track);
|
inline bool inputVideo(const RtpPacket::Ptr &rtp);
|
||||||
inline bool inputAudio(const RtpPacket::Ptr &rtp, const RtspTrack &track);
|
inline bool inputAudio(const RtpPacket::Ptr &rtp);
|
||||||
|
private:
|
||||||
string m_strSPS;
|
|
||||||
string m_strPPS;
|
|
||||||
string m_strAudioCfg;
|
|
||||||
bool m_bHaveAudio = false;
|
|
||||||
bool m_bHaveVideo= false;
|
|
||||||
float m_fDuration = 0;
|
float m_fDuration = 0;
|
||||||
|
AudioTrack::Ptr _audioTrack;
|
||||||
recursive_mutex m_mtxCB;
|
VideoTrack::Ptr _videoTrack;
|
||||||
|
RtpCodec::Ptr _audioRtpDecoder;
|
||||||
|
RtpCodec::Ptr _videoRtpDecoder;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace Rtsp */
|
} /* namespace Rtsp */
|
||||||
|
@ -73,8 +73,8 @@ public:
|
|||||||
* @param frame 帧数据
|
* @param frame 帧数据
|
||||||
* @param key_pos 是否为关键帧
|
* @param key_pos 是否为关键帧
|
||||||
*/
|
*/
|
||||||
void inputFrame(const Frame::Ptr &frame,bool key_pos) override{
|
bool inputFrame(const Frame::Ptr &frame,bool key_pos) override{
|
||||||
_encoder->inputFrame(frame,key_pos);
|
return _encoder->inputFrame(frame,key_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,8 +82,8 @@ public:
|
|||||||
* @param rtp rtp数据包
|
* @param rtp rtp数据包
|
||||||
* @param key_pos 是否为关键帧第一个rtp包
|
* @param key_pos 是否为关键帧第一个rtp包
|
||||||
*/
|
*/
|
||||||
void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override{
|
bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override{
|
||||||
_encoder->inputRtp(rtp,key_pos);
|
return _encoder->inputRtp(rtp,key_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,12 +108,12 @@ public:
|
|||||||
* @param mtu mtu大小,一般小于1500字节,推荐1400
|
* @param mtu mtu大小,一般小于1500字节,推荐1400
|
||||||
*/
|
*/
|
||||||
virtual void createRtpEncoder(uint32_t ssrc, int mtu) {
|
virtual void createRtpEncoder(uint32_t ssrc, int mtu) {
|
||||||
_encoder = RtpCodec::getRtpCodecById(getCodecId(),
|
_encoder = RtpCodec::getRtpEncoderById(getCodecId(),
|
||||||
ssrc,
|
ssrc,
|
||||||
mtu,
|
mtu,
|
||||||
_sample_rate,
|
_sample_rate,
|
||||||
_playload_type,
|
_playload_type,
|
||||||
getTrackType() * 2);
|
getTrackType() * 2);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
RtpCodec::Ptr _encoder;
|
RtpCodec::Ptr _encoder;
|
||||||
@ -315,12 +315,12 @@ public:
|
|||||||
* @param frame 帧数据
|
* @param frame 帧数据
|
||||||
* @param key_pos 是否为关键帧
|
* @param key_pos 是否为关键帧
|
||||||
*/
|
*/
|
||||||
void inputFrame(const Frame::Ptr &frame,bool key_pos = true) override {
|
bool inputFrame(const Frame::Ptr &frame,bool key_pos = true) override {
|
||||||
auto it = _sdp_map.find(frame->getTrackType());
|
auto it = _sdp_map.find(frame->getTrackType());
|
||||||
if(it == _sdp_map.end()){
|
if(it == _sdp_map.end()){
|
||||||
return ;
|
return false;
|
||||||
}
|
}
|
||||||
it->second->inputFrame(frame,key_pos);
|
return it->second->inputFrame(frame,key_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -328,12 +328,12 @@ public:
|
|||||||
* @param rtp rtp包
|
* @param rtp rtp包
|
||||||
* @param key_pos 是否为关键帧的第一个rtp包
|
* @param key_pos 是否为关键帧的第一个rtp包
|
||||||
*/
|
*/
|
||||||
void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override {
|
bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override {
|
||||||
auto it = _sdp_map.find(rtp->getTrackType());
|
auto it = _sdp_map.find(rtp->getTrackType());
|
||||||
if(it == _sdp_map.end()){
|
if(it == _sdp_map.end()){
|
||||||
return ;
|
return false;
|
||||||
}
|
}
|
||||||
it->second->inputRtp(rtp,key_pos);
|
return it->second->inputRtp(rtp,key_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user