From efa92752c7bc06b6bdbaa56fc89daec11c3f2278 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Thu, 11 Jun 2020 19:21:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=AF=B9=E9=AB=98=E8=A7=84?= =?UTF-8?q?=E6=A0=BCaac=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Extension/AAC.cpp | 48 ++++++++++++++++++++++++++++++++++--- src/Extension/AAC.h | 10 ++++---- src/Extension/AACRtmp.cpp | 50 ++++++++++++++++----------------------- src/Extension/AACRtmp.h | 11 ++++----- src/Extension/AACRtp.cpp | 45 +++++++++++++++++++---------------- src/Extension/AACRtp.h | 9 +++++-- 6 files changed, 107 insertions(+), 66 deletions(-) diff --git a/src/Extension/AAC.cpp b/src/Extension/AAC.cpp index e138ccf2..b034a462 100644 --- a/src/Extension/AAC.cpp +++ b/src/Extension/AAC.cpp @@ -9,6 +9,9 @@ */ #include "AAC.h" +#ifdef ENABLE_MP4 +#include "mpeg4-aac.h" +#endif namespace mediakit{ @@ -89,7 +92,8 @@ static void parseAacConfig(const string &config, AdtsHeader &adts) { adts.no_raw_data_blocks_in_frame = 0; } -string makeAacConfig(const uint8_t *hex){ +string makeAacConfig(const uint8_t *hex, int length){ +#ifndef ENABLE_MP4 if (!(hex[0] == 0xFF && (hex[1] & 0xF0) == 0xF0)) { return ""; } @@ -112,20 +116,58 @@ string makeAacConfig(const uint8_t *hex){ audioSpecificConfig[0] = (audioObjectType << 3) | (sampling_frequency_index >> 1); audioSpecificConfig[1] = (sampling_frequency_index << 7) | (channel_configuration << 3); return string((char *)audioSpecificConfig,2); +#else + struct mpeg4_aac_t aac = {0}; + if (mpeg4_aac_adts_load(hex, length, &aac) > 0) { + char buf[32] = {0}; + int len = mpeg4_aac_audio_specific_config_save(&aac, (uint8_t *) buf, sizeof(buf)); + if (len > 0) { + return string(buf, len); + } + } + WarnL << "生成aac config失败, adts header:" << hexdump(hex, length); + return ""; +#endif } -void dumpAacConfig(const string &config, int length, uint8_t *out){ +int dumpAacConfig(const string &config, int length, uint8_t *out, int out_size) { +#ifndef ENABLE_MP4 AdtsHeader header; parseAacConfig(config, header); header.aac_frame_length = length; dumpAdtsHeader(header, out); + return ADTS_HEADER_LEN; +#else + struct mpeg4_aac_t aac = {0}; + int ret = mpeg4_aac_audio_specific_config_load((uint8_t *) config.data(), config.size(), &aac); + if (ret > 0) { + ret = mpeg4_aac_adts_save(&aac, length, out, out_size); + } + if (ret < 0) { + WarnL << "生成adts头失败:" << ret << ", aac config:" << hexdump(config.data(), config.size()); + } + return ret; +#endif } -void parseAacConfig(const string &config, int &samplerate, int &channels){ +bool parseAacConfig(const string &config, int &samplerate, int &channels){ +#ifndef ENABLE_MP4 AdtsHeader header; parseAacConfig(config, header); samplerate = samplingFrequencyTable[header.sf_index]; channels = header.channel_configuration; + return true; +#else + struct mpeg4_aac_t aac = {0}; + int ret = mpeg4_aac_audio_specific_config_load((uint8_t *) config.data(), config.size(), &aac); + if (ret > 0) { + samplerate = aac.sampling_frequency; + channels = aac.channels; + return true; + } + WarnL << "获取aac采样率、声道数失败:" << hexdump(config.data(), config.size()); + return false; +#endif } Sdp::Ptr AACTrack::getSdp() { diff --git a/src/Extension/AAC.h b/src/Extension/AAC.h index 6a3bd8ba..e024bb90 100644 --- a/src/Extension/AAC.h +++ b/src/Extension/AAC.h @@ -17,9 +17,9 @@ namespace mediakit{ -string makeAacConfig(const uint8_t *hex); -void dumpAacConfig(const string &config, int length, uint8_t *out); -void parseAacConfig(const string &config, int &samplerate, int &channels); +string makeAacConfig(const uint8_t *hex, int length); +int dumpAacConfig(const string &config, int length, uint8_t *out, int out_size); +bool parseAacConfig(const string &config, int &samplerate, int &channels); /** * aac帧,包含adts头 @@ -137,9 +137,9 @@ public: void inputFrame(const Frame::Ptr &frame) override{ if (_cfg.empty()) { //未获取到aac_cfg信息 - if (frame->prefixSize() >= ADTS_HEADER_LEN) { + if (frame->prefixSize()) { //7个字节的adts头 - _cfg = makeAacConfig((uint8_t *) (frame->data())); + _cfg = makeAacConfig((uint8_t *) (frame->data()), frame->prefixSize()); onReady(); } else { WarnL << "无法获取adts头!"; diff --git a/src/Extension/AACRtmp.cpp b/src/Extension/AACRtmp.cpp index 05a5af52..48102a2d 100644 --- a/src/Extension/AACRtmp.cpp +++ b/src/Extension/AACRtmp.cpp @@ -13,20 +13,6 @@ namespace mediakit{ -AACRtmpDecoder::AACRtmpDecoder(const Track::Ptr &track) { - _frame = obtainFrame(); - _track = dynamic_pointer_cast(track); -} - -AACFrame::Ptr AACRtmpDecoder::obtainFrame() { - //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 - auto frame = ResourcePoolHelper::obtainObj(); - frame->_prefix_size = ADTS_HEADER_LEN; - //预留7个字节的空位以便后续覆盖 - frame->_buffer.assign(ADTS_HEADER_LEN,(char)0); - return frame; -} - static string getAacCfg(const RtmpPacket &thiz) { string ret; if (thiz.getMediaType() != FLV_CODEC_AAC) { @@ -46,12 +32,6 @@ static string getAacCfg(const RtmpPacket &thiz) { bool AACRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt, bool) { if (pkt->isCfgFrame()) { _aac_cfg = getAacCfg(*pkt); - if (_track) { - //设置aac config - _track->setAacCfg(_aac_cfg); - //不再强引用 - _track = nullptr; - } return false; } if (!_aac_cfg.empty()) { @@ -61,20 +41,30 @@ bool AACRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt, bool) { } void AACRtmpDecoder::onGetAAC(const char* data, int len, uint32_t stamp) { - _frame->_dts = stamp; - //先追加数据 - _frame->_buffer.append(data, len); - //覆盖adts头 - dumpAacConfig(_aac_cfg, _frame->size(), (uint8_t *) _frame->data()); + auto frame = ResourcePoolHelper::obtainObj(); + + //生成adts头 + char adts_header[32] = {0}; + auto size = dumpAacConfig(_aac_cfg, len, (uint8_t *) adts_header, sizeof(adts_header)); + if (size > 0) { + frame->_buffer.assign(adts_header, size); + frame->_prefix_size = size; + } else { + frame->_buffer.clear(); + frame->_prefix_size = 0; + } + + //追加负载数据 + frame->_buffer.append(data, len); + frame->_dts = stamp; //写入环形缓存 - RtmpCodec::inputFrame(_frame); - _frame = obtainFrame(); + RtmpCodec::inputFrame(frame); } ///////////////////////////////////////////////////////////////////////////////////// -AACRtmpEncoder::AACRtmpEncoder(const Track::Ptr &track): AACRtmpDecoder(track) { +AACRtmpEncoder::AACRtmpEncoder(const Track::Ptr &track) { _track = dynamic_pointer_cast(track); } @@ -91,9 +81,9 @@ void AACRtmpEncoder::makeConfigPacket() { void AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) { if (_aac_cfg.empty()) { - if (frame->prefixSize() >= 7) { + if (frame->prefixSize()) { //包含adts头,从adts头获取aac配置信息 - _aac_cfg = makeAacConfig((uint8_t *) (frame->data())); + _aac_cfg = makeAacConfig((uint8_t *) (frame->data()), frame->prefixSize()); } makeConfigPacket(); } diff --git a/src/Extension/AACRtmp.h b/src/Extension/AACRtmp.h index 0f5d2f4b..dc7f0d62 100644 --- a/src/Extension/AACRtmp.h +++ b/src/Extension/AACRtmp.h @@ -23,7 +23,7 @@ class AACRtmpDecoder : public RtmpCodec , public ResourcePoolHelper { public: typedef std::shared_ptr Ptr; - AACRtmpDecoder(const Track::Ptr &track); + AACRtmpDecoder() {} ~AACRtmpDecoder() {} /** @@ -37,13 +37,10 @@ public: return CodecAAC; } -protected: +private: void onGetAAC(const char *data, int len, uint32_t stamp); - AACFrame::Ptr obtainFrame(); -protected: - AACFrame::Ptr _frame; - AACTrack::Ptr _track; +private: string _aac_cfg; }; @@ -80,6 +77,8 @@ private: private: uint8_t _audio_flv_flags; + AACTrack::Ptr _track; + string _aac_cfg; }; }//namespace mediakit diff --git a/src/Extension/AACRtp.cpp b/src/Extension/AACRtp.cpp index d8c257cf..08f8307c 100644 --- a/src/Extension/AACRtp.cpp +++ b/src/Extension/AACRtp.cpp @@ -56,30 +56,30 @@ void AACRtpEncoder::inputFrame(const Frame::Ptr &frame) { } void AACRtpEncoder::makeAACRtp(const void *data, unsigned int len, bool mark, uint32_t uiStamp) { - RtpCodec::inputRtp(makeRtp(getTrackType(),data,len,mark,uiStamp), false); + RtpCodec::inputRtp(makeRtp(getTrackType(), data, len, mark, uiStamp), false); } ///////////////////////////////////////////////////////////////////////////////////// -AACRtpDecoder::AACRtpDecoder(const Track::Ptr &track){ +AACRtpDecoder::AACRtpDecoder(const Track::Ptr &track) { auto aacTrack = dynamic_pointer_cast(track); - if(!aacTrack || !aacTrack->ready()){ + if (!aacTrack || !aacTrack->ready()) { WarnL << "该aac track无效!"; - }else{ + } else { _aac_cfg = aacTrack->getAacCfg(); } - _adts = obtainFrame(); + _frame = obtainFrame(); } + AACRtpDecoder::AACRtpDecoder() { - _adts = obtainFrame(); + _frame = obtainFrame(); } AACFrame::Ptr AACRtpDecoder::obtainFrame() { //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 auto frame = ResourcePoolHelper::obtainObj(); - frame->_prefix_size = ADTS_HEADER_LEN; - //预留7个字节的空位以便后续覆盖 - frame->_buffer.assign(ADTS_HEADER_LEN,(char)0); + frame->_prefix_size = 0; + frame->_buffer.clear(); return frame; } @@ -94,19 +94,18 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { //忽略Au-Header区 ptr += 2 + au_header_count * 2; - static const uint32_t max_size = AAC_MAX_FRAME_SIZE - ADTS_HEADER_LEN; while (ptr < end) { auto size = (uint32_t) (end - ptr); - if(size > max_size){ - size = max_size; + if (size > AAC_MAX_FRAME_SIZE) { + size = AAC_MAX_FRAME_SIZE; } - if (_adts->size() + size > AAC_MAX_FRAME_SIZE) { + if (_frame->size() + size > AAC_MAX_FRAME_SIZE) { //数据太多了,先清空 flushData(); } //追加aac数据 - _adts->_buffer.append((char *)ptr, size); - _adts->_dts = rtppack->timeStamp; + _frame->_buffer.append((char *) ptr, size); + _frame->_dts = rtppack->timeStamp; ptr += size; } @@ -118,15 +117,21 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { } void AACRtpDecoder::flushData() { - if (_adts->size() == ADTS_HEADER_LEN) { + if (_frame->_buffer.empty()) { //没有有效数据 return; } - //覆盖adts头 - dumpAacConfig(_aac_cfg, _adts->size(), (uint8_t *) _adts->data()); - RtpCodec::inputFrame(_adts); - _adts = obtainFrame(); + //插入adts头 + char adts_header[32] = {0}; + auto size = dumpAacConfig(_aac_cfg, _frame->_buffer.size(), (uint8_t *) adts_header, sizeof(adts_header)); + if (size > 0) { + //插入adts头 + _frame->_buffer.insert(0, adts_header, size); + _frame->_prefix_size = size; + } + RtpCodec::inputFrame(_frame); + _frame = obtainFrame(); } diff --git a/src/Extension/AACRtp.h b/src/Extension/AACRtp.h index b82b19e2..7b646204 100644 --- a/src/Extension/AACRtp.h +++ b/src/Extension/AACRtp.h @@ -31,16 +31,19 @@ public: */ bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = false) override; - CodecId getCodecId() const override{ + CodecId getCodecId() const override { return CodecAAC; } + protected: AACRtpDecoder(); + private: AACFrame::Ptr obtainFrame(); void flushData(); + private: - AACFrame::Ptr _adts; + AACFrame::Ptr _frame; string _aac_cfg; }; @@ -71,8 +74,10 @@ public: * @param frame 带dats头的aac数据 */ void inputFrame(const Frame::Ptr &frame) override; + private: void makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp); + private: unsigned char _aucSectionBuf[1600]; };