修复AAC rtp解码相关的bug

This commit is contained in:
xiongziliang 2019-01-24 12:21:29 +08:00
parent 22962a407e
commit a646640580
6 changed files with 40 additions and 20 deletions

View File

@ -82,7 +82,7 @@ public:
return false; return false;
} }
public: public:
unsigned int syncword; //12 bslbf 同步字The bit string 1111 1111 1111说明一个ADTS帧的开始 unsigned int syncword = 0; //12 bslbf 同步字The bit string 1111 1111 1111说明一个ADTS帧的开始
unsigned int id; //1 bslbf MPEG 标示符, 设置为1 unsigned int id; //1 bslbf MPEG 标示符, 设置为1
unsigned int layer; //2 uimsbf Indicates which layer is used. Set to 00 unsigned int layer; //2 uimsbf Indicates which layer is used. Set to 00
unsigned int protection_absent; //1 bslbf 表示是否误码校验 unsigned int protection_absent; //1 bslbf 表示是否误码校验
@ -234,10 +234,15 @@ public:
* @param frame * @param frame
*/ */
void inputFrame(const Frame::Ptr &frame) override{ void inputFrame(const Frame::Ptr &frame) override{
if(_cfg.empty() && frame->prefixSize() >= 7){ if(_cfg.empty()){
//7个字节的adts头 //未获取到aac_cfg信息
_cfg = makeAdtsConfig(reinterpret_cast<const uint8_t *>(frame->data())); if(frame->prefixSize() >= 7) {
onReady(); //7个字节的adts头
_cfg = makeAdtsConfig(reinterpret_cast<const uint8_t *>(frame->data()));
onReady();
}else{
WarnL << "无法获取adts头!";
}
} }
AudioTrack::inputFrame(frame); AudioTrack::inputFrame(frame);
} }

View File

@ -181,16 +181,16 @@ RtpCodec::Ptr Factory::getRtpEncoderById(CodecId codecId,
} }
} }
RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId) { RtpCodec::Ptr Factory::getRtpDecoderByTrack(const Track::Ptr &track) {
switch (codecId){ switch (track->getCodecId()){
case CodecH264: case CodecH264:
return std::make_shared<H264RtpDecoder>(); return std::make_shared<H264RtpDecoder>();
case CodecH265: case CodecH265:
return std::make_shared<H265RtpDecoder>(); return std::make_shared<H265RtpDecoder>();
case CodecAAC: case CodecAAC:
return std::make_shared<AACRtpDecoder>(); return std::make_shared<AACRtpDecoder>(track->clone());
default: default:
WarnL << "暂不支持该CodecId:" << codecId; WarnL << "暂不支持该CodecId:" << track->getCodecId();
return nullptr; return nullptr;
} }
} }

View File

@ -81,12 +81,11 @@ public:
uint8_t ui8Interleaved); uint8_t ui8Interleaved);
/** /**
* CodecId生成Rtp解包器 * Track生成Rtp解包器
* @param codecId * @param track
* @param ui32SampleRate
* @return * @return
*/ */
static RtpCodec::Ptr getRtpDecoderById(CodecId codecId); static RtpCodec::Ptr getRtpDecoderByTrack(const Track::Ptr &track);
////////////////////////////////rtmp相关////////////////////////////////// ////////////////////////////////rtmp相关//////////////////////////////////

View File

@ -76,6 +76,16 @@ void AACRtpEncoder::makeAACRtp(const void *data, unsigned int len, bool mark, ui
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
AACRtpDecoder::AACRtpDecoder(const Track::Ptr &track){
auto aacTrack = dynamic_pointer_cast<AACTrack>(track);
if(!aacTrack || !aacTrack->ready()){
WarnL << "该aac track无效!";
}else{
_aac_cfg = aacTrack->getAacCfg();
}
_adts = obtainFrame();
}
AACRtpDecoder::AACRtpDecoder() { AACRtpDecoder::AACRtpDecoder() {
_adts = obtainFrame(); _adts = obtainFrame();
} }
@ -85,6 +95,9 @@ AACFrame::Ptr AACRtpDecoder::obtainFrame() {
auto frame = ResourcePoolHelper<AACFrame>::obtainObj(); auto frame = ResourcePoolHelper<AACFrame>::obtainObj();
frame->aac_frame_length = 7; frame->aac_frame_length = 7;
frame->iPrefixSize = 7; frame->iPrefixSize = 7;
if(frame->syncword == 0 && !_aac_cfg.empty()) {
makeAdtsHeader(_aac_cfg,*frame);
}
return frame; return frame;
} }
@ -92,13 +105,13 @@ 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 (_adts->aac_frame_length + length > sizeof(AACFrame::buffer)) { if (_adts->aac_frame_length + length - 4 > sizeof(AACFrame::buffer)) {
_adts->aac_frame_length = 7; _adts->aac_frame_length = 7;
WarnL << "aac负载数据太长"; WarnL << "aac负载数据太长";
return false; return false;
} }
memcpy(_adts->buffer + _adts->aac_frame_length, rtppack->payload + rtppack->offset, length); memcpy(_adts->buffer + _adts->aac_frame_length, rtppack->payload + rtppack->offset + 4, length - 4);
_adts->aac_frame_length += length; _adts->aac_frame_length += (length - 4);
if (rtppack->mark == true) { if (rtppack->mark == true) {
_adts->sequence = rtppack->sequence; _adts->sequence = rtppack->sequence;
_adts->timeStamp = rtppack->timeStamp; _adts->timeStamp = rtppack->timeStamp;
@ -114,6 +127,7 @@ void AACRtpDecoder::onGetAAC(const AACFrame::Ptr &frame) {
_adts = obtainFrame(); _adts = obtainFrame();
} }
}//namespace mediakit }//namespace mediakit

View File

@ -37,7 +37,7 @@ class AACRtpDecoder : public RtpCodec , public ResourcePoolHelper<AACFrame> {
public: public:
typedef std::shared_ptr<AACRtpDecoder> Ptr; typedef std::shared_ptr<AACRtpDecoder> Ptr;
AACRtpDecoder(); AACRtpDecoder(const Track::Ptr &track);
~AACRtpDecoder() {} ~AACRtpDecoder() {}
/** /**
@ -50,15 +50,17 @@ public:
TrackType getTrackType() const override{ TrackType getTrackType() const override{
return TrackAudio; return TrackAudio;
} }
CodecId getCodecId() const override{ CodecId getCodecId() const override{
return CodecAAC; return CodecAAC;
} }
protected:
AACRtpDecoder();
private: private:
void onGetAAC(const AACFrame::Ptr &frame); void onGetAAC(const AACFrame::Ptr &frame);
AACFrame::Ptr obtainFrame(); AACFrame::Ptr obtainFrame();
private: private:
AACFrame::Ptr _adts; AACFrame::Ptr _adts;
string _aac_cfg;
}; };

View File

@ -90,7 +90,7 @@ void RtspDemuxer::makeAudioTrack(const SdpTrack::Ptr &audio) {
_audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackBySdp(audio)); _audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackBySdp(audio));
if(_audioTrack){ if(_audioTrack){
//生成RtpCodec对象以便解码rtp //生成RtpCodec对象以便解码rtp
_audioRtpDecoder = Factory::getRtpDecoderById(_audioTrack->getCodecId()); _audioRtpDecoder = Factory::getRtpDecoderByTrack(_audioTrack);
if(_audioRtpDecoder){ if(_audioRtpDecoder){
//设置rtp解码器代理生成的frame写入该Track //设置rtp解码器代理生成的frame写入该Track
_audioRtpDecoder->addDelegate(_audioTrack); _audioRtpDecoder->addDelegate(_audioTrack);
@ -106,7 +106,7 @@ void RtspDemuxer::makeVideoTrack(const SdpTrack::Ptr &video) {
_videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackBySdp(video)); _videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackBySdp(video));
if(_videoTrack){ if(_videoTrack){
//生成RtpCodec对象以便解码rtp //生成RtpCodec对象以便解码rtp
_videoRtpDecoder = Factory::getRtpDecoderById(_videoTrack->getCodecId()); _videoRtpDecoder = Factory::getRtpDecoderByTrack(_videoTrack);
if(_videoRtpDecoder){ if(_videoRtpDecoder){
//设置rtp解码器代理生成的frame写入该Track //设置rtp解码器代理生成的frame写入该Track
_videoRtpDecoder->addDelegate(_videoTrack); _videoRtpDecoder->addDelegate(_videoTrack);