mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-12-02 00:12:33 +08:00
完善Rtmp复用器,可以灵活设置sps pps等信息
This commit is contained in:
parent
413b18521d
commit
186f4e4683
@ -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:
|
|||||||
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
|
|||||||
}
|
}
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
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()){
|
||||||
_aac_cfg = makeAdtsConfig(reinterpret_cast<const uint8_t *>(frame->data()));
|
if(frame->prefixSize() >= 7){
|
||||||
makeAudioConfigPkt();
|
//包含adts头,从adts头获取aac配置信息
|
||||||
|
_aac_cfg = makeAdtsConfig(reinterpret_cast<const uint8_t *>(frame->data()));
|
||||||
|
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() {
|
|||||||
inputRtmp(rtmpPkt, false);
|
inputRtmp(rtmpPkt, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
@ -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
|
|||||||
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
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
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) {
|
|||||||
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) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
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 @@
|
|||||||
#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
|
|||||||
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) {
|
|||||||
_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) {
|
|||||||
_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);
|
||||||
|
Loading…
Reference in New Issue
Block a user