From a64664058082125f25c476bdd0f3cc2285dc9ef2 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Thu, 24 Jan 2019 12:21:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DAAC=20rtp=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Extension/AAC.h | 15 ++++++++++----- src/Extension/Factory.cpp | 8 ++++---- src/Extension/Factory.h | 7 +++---- src/RtspMuxer/AACRtpCodec.cpp | 20 +++++++++++++++++--- src/RtspMuxer/AACRtpCodec.h | 6 ++++-- src/RtspMuxer/RtspDemuxer.cpp | 4 ++-- 6 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/Extension/AAC.h b/src/Extension/AAC.h index 69f7621e..c92a35f5 100644 --- a/src/Extension/AAC.h +++ b/src/Extension/AAC.h @@ -82,7 +82,7 @@ public: return false; } 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 layer; //2 uimsbf Indicates which layer is used. Set to ‘00’ unsigned int protection_absent; //1 bslbf 表示是否误码校验 @@ -234,10 +234,15 @@ public: * @param frame 数据帧 */ void inputFrame(const Frame::Ptr &frame) override{ - if(_cfg.empty() && frame->prefixSize() >= 7){ - //7个字节的adts头 - _cfg = makeAdtsConfig(reinterpret_cast(frame->data())); - onReady(); + if(_cfg.empty()){ + //未获取到aac_cfg信息 + if(frame->prefixSize() >= 7) { + //7个字节的adts头 + _cfg = makeAdtsConfig(reinterpret_cast(frame->data())); + onReady(); + }else{ + WarnL << "无法获取adts头!"; + } } AudioTrack::inputFrame(frame); } diff --git a/src/Extension/Factory.cpp b/src/Extension/Factory.cpp index 22c5d87c..f5346c96 100644 --- a/src/Extension/Factory.cpp +++ b/src/Extension/Factory.cpp @@ -181,16 +181,16 @@ RtpCodec::Ptr Factory::getRtpEncoderById(CodecId codecId, } } -RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId) { - switch (codecId){ +RtpCodec::Ptr Factory::getRtpDecoderByTrack(const Track::Ptr &track) { + switch (track->getCodecId()){ case CodecH264: return std::make_shared(); case CodecH265: return std::make_shared(); case CodecAAC: - return std::make_shared(); + return std::make_shared(track->clone()); default: - WarnL << "暂不支持该CodecId:" << codecId; + WarnL << "暂不支持该CodecId:" << track->getCodecId(); return nullptr; } } diff --git a/src/Extension/Factory.h b/src/Extension/Factory.h index a0924ad1..fb223ac7 100644 --- a/src/Extension/Factory.h +++ b/src/Extension/Factory.h @@ -81,12 +81,11 @@ public: uint8_t ui8Interleaved); /** - * 根据CodecId生成Rtp解包器 - * @param codecId - * @param ui32SampleRate + * 根据Track生成Rtp解包器 + * @param track * @return */ - static RtpCodec::Ptr getRtpDecoderById(CodecId codecId); + static RtpCodec::Ptr getRtpDecoderByTrack(const Track::Ptr &track); ////////////////////////////////rtmp相关////////////////////////////////// diff --git a/src/RtspMuxer/AACRtpCodec.cpp b/src/RtspMuxer/AACRtpCodec.cpp index 41277819..3a0897c3 100644 --- a/src/RtspMuxer/AACRtpCodec.cpp +++ b/src/RtspMuxer/AACRtpCodec.cpp @@ -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(track); + if(!aacTrack || !aacTrack->ready()){ + WarnL << "该aac track无效!"; + }else{ + _aac_cfg = aacTrack->getAacCfg(); + } + _adts = obtainFrame(); +} AACRtpDecoder::AACRtpDecoder() { _adts = obtainFrame(); } @@ -85,6 +95,9 @@ AACFrame::Ptr AACRtpDecoder::obtainFrame() { auto frame = ResourcePoolHelper::obtainObj(); frame->aac_frame_length = 7; frame->iPrefixSize = 7; + if(frame->syncword == 0 && !_aac_cfg.empty()) { + makeAdtsHeader(_aac_cfg,*frame); + } return frame; } @@ -92,13 +105,13 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { RtpCodec::inputRtp(rtppack, false); 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; WarnL << "aac负载数据太长"; return false; } - memcpy(_adts->buffer + _adts->aac_frame_length, rtppack->payload + rtppack->offset, length); - _adts->aac_frame_length += length; + memcpy(_adts->buffer + _adts->aac_frame_length, rtppack->payload + rtppack->offset + 4, length - 4); + _adts->aac_frame_length += (length - 4); if (rtppack->mark == true) { _adts->sequence = rtppack->sequence; _adts->timeStamp = rtppack->timeStamp; @@ -114,6 +127,7 @@ void AACRtpDecoder::onGetAAC(const AACFrame::Ptr &frame) { _adts = obtainFrame(); } + }//namespace mediakit diff --git a/src/RtspMuxer/AACRtpCodec.h b/src/RtspMuxer/AACRtpCodec.h index 35f9aaf6..8b9ce9d5 100644 --- a/src/RtspMuxer/AACRtpCodec.h +++ b/src/RtspMuxer/AACRtpCodec.h @@ -37,7 +37,7 @@ class AACRtpDecoder : public RtpCodec , public ResourcePoolHelper { public: typedef std::shared_ptr Ptr; - AACRtpDecoder(); + AACRtpDecoder(const Track::Ptr &track); ~AACRtpDecoder() {} /** @@ -50,15 +50,17 @@ public: TrackType getTrackType() const override{ return TrackAudio; } - CodecId getCodecId() const override{ return CodecAAC; } +protected: + AACRtpDecoder(); private: void onGetAAC(const AACFrame::Ptr &frame); AACFrame::Ptr obtainFrame(); private: AACFrame::Ptr _adts; + string _aac_cfg; }; diff --git a/src/RtspMuxer/RtspDemuxer.cpp b/src/RtspMuxer/RtspDemuxer.cpp index bf22e0ff..b9a8253b 100644 --- a/src/RtspMuxer/RtspDemuxer.cpp +++ b/src/RtspMuxer/RtspDemuxer.cpp @@ -90,7 +90,7 @@ void RtspDemuxer::makeAudioTrack(const SdpTrack::Ptr &audio) { _audioTrack = dynamic_pointer_cast(Factory::getTrackBySdp(audio)); if(_audioTrack){ //生成RtpCodec对象以便解码rtp - _audioRtpDecoder = Factory::getRtpDecoderById(_audioTrack->getCodecId()); + _audioRtpDecoder = Factory::getRtpDecoderByTrack(_audioTrack); if(_audioRtpDecoder){ //设置rtp解码器代理,生成的frame写入该Track _audioRtpDecoder->addDelegate(_audioTrack); @@ -106,7 +106,7 @@ void RtspDemuxer::makeVideoTrack(const SdpTrack::Ptr &video) { _videoTrack = dynamic_pointer_cast(Factory::getTrackBySdp(video)); if(_videoTrack){ //生成RtpCodec对象以便解码rtp - _videoRtpDecoder = Factory::getRtpDecoderById(_videoTrack->getCodecId()); + _videoRtpDecoder = Factory::getRtpDecoderByTrack(_videoTrack); if(_videoRtpDecoder){ //设置rtp解码器代理,生成的frame写入该Track _videoRtpDecoder->addDelegate(_videoTrack);