Commit 186f4e46 by xiongziliang

完善Rtmp复用器,可以灵活设置sps pps等信息

parent 413b1852
...@@ -196,18 +196,19 @@ RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId, uint32_t ui32SampleRat ...@@ -196,18 +196,19 @@ RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId, uint32_t ui32SampleRat
} }
} }
RtmpCodec::Ptr Factory::getRtmpCodecById(CodecId codecId) { RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track) {
switch (codecId){ switch (track->getCodecId()){
case CodecH264: case CodecH264:
return std::make_shared<H264RtmpEncoder>(); return std::make_shared<H264RtmpEncoder>(track);
case CodecAAC: case CodecAAC:
return std::make_shared<AACRtmpEncoder>(); return std::make_shared<AACRtmpEncoder>(track);
default: default:
WarnL << "暂不支持该CodecId:" << codecId; WarnL << "暂不支持该CodecId:" << track->getCodecId();
return nullptr; return nullptr;
} }
} }
}//namespace mediakit }//namespace mediakit
...@@ -106,11 +106,11 @@ public: ...@@ -106,11 +106,11 @@ public:
static CodecId getCodecIdByAmf(const AMFValue &val); static CodecId getCodecIdByAmf(const AMFValue &val);
/** /**
* 根据CodecId获取Rtmp的编解码器 * 根据Track获取Rtmp的编解码器
* @param codecId CodecId * @param track 媒体描述对象
* @return * @return
*/ */
static RtmpCodec::Ptr getRtmpCodecById(CodecId codecId); static RtmpCodec::Ptr getRtmpCodecByTrack(const Track::Ptr &track);
}; };
......
...@@ -75,12 +75,23 @@ void AACRtmpDecoder::onGetAAC(const char* pcData, int iLen, uint32_t ui32TimeSta ...@@ -75,12 +75,23 @@ void AACRtmpDecoder::onGetAAC(const char* pcData, int iLen, uint32_t ui32TimeSta
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
AACRtmpEncoder::AACRtmpEncoder(const Track::Ptr &track) {
_track = dynamic_pointer_cast<AACTrack>(track);
}
void AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) { void AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) {
RtmpCodec::inputFrame(frame); RtmpCodec::inputFrame(frame);
if(frame->prefixSize() >= 7 && _aac_cfg.empty()){
//包含adts头 if(_aac_cfg.empty()){
if(frame->prefixSize() >= 7){
//包含adts头,从adts头获取aac配置信息
_aac_cfg = makeAdtsConfig(reinterpret_cast<const uint8_t *>(frame->data())); _aac_cfg = makeAdtsConfig(reinterpret_cast<const uint8_t *>(frame->data()));
makeAudioConfigPkt(); makeAudioConfigPkt();
} else if(_track && _track->ready()){
//从track中和获取aac配置信息
_aac_cfg = _track->getAacCfg();
makeAudioConfigPkt();
}
} }
if(!_aac_cfg.empty()){ if(!_aac_cfg.empty()){
...@@ -149,6 +160,4 @@ void AACRtmpEncoder::makeAudioConfigPkt() { ...@@ -149,6 +160,4 @@ void AACRtmpEncoder::makeAudioConfigPkt() {
inputRtmp(rtmpPkt, false); inputRtmp(rtmpPkt, false);
} }
}//namespace mediakit }//namespace mediakit
\ No newline at end of file
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define ZLMEDIAKIT_AACRTMPCODEC_H #define ZLMEDIAKIT_AACRTMPCODEC_H
#include "RtmpCodec.h" #include "RtmpCodec.h"
#include "Player/Track.h"
namespace mediakit{ namespace mediakit{
/** /**
...@@ -71,18 +72,26 @@ class AACRtmpEncoder : public AACRtmpDecoder , public ResourcePoolHelper<RtmpPa ...@@ -71,18 +72,26 @@ class AACRtmpEncoder : public AACRtmpDecoder , public ResourcePoolHelper<RtmpPa
public: public:
typedef std::shared_ptr<AACRtmpEncoder> Ptr; typedef std::shared_ptr<AACRtmpEncoder> Ptr;
AACRtmpEncoder(){} /**
* 构造函数,track可以为空,此时则在inputFrame时输入adts头
* 如果track不为空且包含adts头相关信息,
* 那么inputFrame时可以不输入adts头
* @param track
*/
AACRtmpEncoder(const Track::Ptr &track);
~AACRtmpEncoder() {} ~AACRtmpEncoder() {}
/** /**
* 输入aac 数据,必须带dats头 * 输入aac 数据,可以不带adts头
* @param frame 带dats头的aac数据 * @param frame aac数据
*/ */
void inputFrame(const Frame::Ptr &frame) override; void inputFrame(const Frame::Ptr &frame) override;
private: private:
void makeAudioConfigPkt(); void makeAudioConfigPkt();
private:
uint8_t _ui8AudioFlags; uint8_t _ui8AudioFlags;
AACTrack::Ptr _track;
}; };
}//namespace mediakit }//namespace mediakit
......
...@@ -105,7 +105,8 @@ inline void H264RtmpDecoder::onGetH264(const char* pcData, int iLen, uint32_t ui ...@@ -105,7 +105,8 @@ inline void H264RtmpDecoder::onGetH264(const char* pcData, int iLen, uint32_t ui
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
H264RtmpEncoder::H264RtmpEncoder() { H264RtmpEncoder::H264RtmpEncoder(const Track::Ptr &track) {
_track = dynamic_pointer_cast<H264Track>(track);
} }
void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) { void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
...@@ -115,6 +116,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) { ...@@ -115,6 +116,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
auto iLen = frame->size() - frame->prefixSize(); auto iLen = frame->size() - frame->prefixSize();
auto type = ((uint8_t*)pcData)[0] & 0x1F; auto type = ((uint8_t*)pcData)[0] & 0x1F;
//尝试从frame中获取sps pps
switch (type){ switch (type){
case 7:{ case 7:{
//sps //sps
...@@ -136,6 +138,18 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) { ...@@ -136,6 +138,18 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
} }
} }
break; break;
default:
break;
}
//尝试从track中获取sps pps信息
if((!_sps.empty() || !_pps.empty()) && _track && _track->ready()){
_sps = _track->getSps();
_pps = _track->getPps();
makeVideoConfigPkt();
}
switch (type){
case 1: case 1:
case 5:{ case 5:{
//I or P or B frame //I or P or B frame
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define ZLMEDIAKIT_H264RTMPCODEC_H #define ZLMEDIAKIT_H264RTMPCODEC_H
#include "RtmpCodec.h" #include "RtmpCodec.h"
#include "Player/Track.h"
#include "Util/ResourcePool.h" #include "Util/ResourcePool.h"
using namespace toolkit; using namespace toolkit;
...@@ -74,16 +75,24 @@ class H264RtmpEncoder : public H264RtmpDecoder, public ResourcePoolHelper<RtmpPa ...@@ -74,16 +75,24 @@ class H264RtmpEncoder : public H264RtmpDecoder, public ResourcePoolHelper<RtmpPa
public: public:
typedef std::shared_ptr<H264RtmpEncoder> Ptr; typedef std::shared_ptr<H264RtmpEncoder> Ptr;
H264RtmpEncoder(); /**
* 构造函数,track可以为空,此时则在inputFrame时输入sps pps
* 如果track不为空且包含sps pps信息,
* 那么inputFrame时可以不输入sps pps
* @param track
*/
H264RtmpEncoder(const Track::Ptr &track);
~H264RtmpEncoder() {} ~H264RtmpEncoder() {}
/** /**
* 输入264帧,需要指出的是,必须输入sps pps帧 * 输入264帧,可以不带sps pps
* @param frame 帧数据 * @param frame 帧数据
*/ */
void inputFrame(const Frame::Ptr &frame) override; void inputFrame(const Frame::Ptr &frame) override;
private: private:
void makeVideoConfigPkt(); void makeVideoConfigPkt();
private:
H264Track::Ptr _track;
}; };
}//namespace mediakit }//namespace mediakit
......
...@@ -81,7 +81,7 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) { ...@@ -81,7 +81,7 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
_videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackByAmf(videoCodec)); _videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackByAmf(videoCodec));
if (_videoTrack) { if (_videoTrack) {
//生成rtmpCodec对象以便解码rtmp //生成rtmpCodec对象以便解码rtmp
_videoRtmpDecoder = Factory::getRtmpCodecById(_videoTrack->getCodecId()); _videoRtmpDecoder = Factory::getRtmpCodecByTrack(_videoTrack);
if (_videoRtmpDecoder) { if (_videoRtmpDecoder) {
//设置rtmp解码器代理,生成的frame写入该Track //设置rtmp解码器代理,生成的frame写入该Track
_videoRtmpDecoder->setDelegate(_videoTrack); _videoRtmpDecoder->setDelegate(_videoTrack);
...@@ -97,7 +97,7 @@ void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) { ...@@ -97,7 +97,7 @@ void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) {
_audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackByAmf(audioCodec)); _audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackByAmf(audioCodec));
if (_audioTrack) { if (_audioTrack) {
//生成rtmpCodec对象以便解码rtmp //生成rtmpCodec对象以便解码rtmp
_audioRtmpDecoder = Factory::getRtmpCodecById(_audioTrack->getCodecId()); _audioRtmpDecoder = Factory::getRtmpCodecByTrack(_audioTrack);
if (_audioRtmpDecoder) { if (_audioRtmpDecoder) {
//设置rtmp解码器代理,生成的frame写入该Track //设置rtmp解码器代理,生成的frame写入该Track
_audioRtmpDecoder->setDelegate(_audioTrack); _audioRtmpDecoder->setDelegate(_audioTrack);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论