From b3f048f1940b698b59a1d8f8102e1fcde30e0489 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sat, 8 Aug 2020 12:19:04 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dadts=E7=AC=A6=E5=90=88?= =?UTF-8?q?=E5=8C=85=E7=9B=B8=E5=85=B3bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Extension/AAC.cpp | 10 ++++++++++ src/Extension/AAC.h | 24 +++++++++++++++++++++++- src/Extension/Frame.h | 16 ++++++++++++++-- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/Extension/AAC.cpp b/src/Extension/AAC.cpp index b034a462..0a1e082e 100644 --- a/src/Extension/AAC.cpp +++ b/src/Extension/AAC.cpp @@ -92,6 +92,16 @@ static void parseAacConfig(const string &config, AdtsHeader &adts) { adts.no_raw_data_blocks_in_frame = 0; } +int getAacFrameLength(const uint8_t *data, int bytes) { + uint16_t len; + if (bytes < 7) return -1; + if (0xFF != data[0] || 0xF0 != (data[1] & 0xF0)) { + return -1; + } + len = ((uint16_t) (data[3] & 0x03) << 11) | ((uint16_t) data[4] << 3) | ((uint16_t) (data[5] >> 5) & 0x07); + return len; +} + string makeAacConfig(const uint8_t *hex, int length){ #ifndef ENABLE_MP4 if (!(hex[0] == 0xFF && (hex[1] & 0xF0) == 0xF0)) { diff --git a/src/Extension/AAC.h b/src/Extension/AAC.h index 21fa4322..243f919f 100644 --- a/src/Extension/AAC.h +++ b/src/Extension/AAC.h @@ -18,6 +18,7 @@ namespace mediakit{ string makeAacConfig(const uint8_t *hex, int length); +int getAacFrameLength(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); @@ -100,6 +101,28 @@ public: * @param frame 数据帧 */ void inputFrame(const Frame::Ptr &frame) override{ + if (frame->prefixSize()) { + //有adts头,尝试分帧 + auto ptr = frame->data(); + auto end = frame->data() + frame->size(); + while (ptr < end) { + auto frame_len = getAacFrameLength((uint8_t *) ptr, end - ptr); + if (frame_len < ADTS_HEADER_LEN) { + break; + } + + auto sub_frame = std::make_shared >(frame, (char *) ptr, frame_len, ADTS_HEADER_LEN); + ptr += frame_len; + sub_frame->setCodecId(CodecAAC); + inputFrame_l(sub_frame); + } + } else { + inputFrame_l(frame); + } + } + +private: + void inputFrame_l(const Frame::Ptr &frame) { if (_cfg.empty()) { //未获取到aac_cfg信息 if (frame->prefixSize()) { @@ -116,7 +139,6 @@ public: AudioTrack::inputFrame(frame); } } -private: /** * 解析2个字节的aac配置 */ diff --git a/src/Extension/Frame.h b/src/Extension/Frame.h index 6066d370..4de0278f 100644 --- a/src/Extension/Frame.h +++ b/src/Extension/Frame.h @@ -314,8 +314,13 @@ private: class FrameFromPtr : public Frame{ public: typedef std::shared_ptr Ptr; - FrameFromPtr(CodecId codec_id, char *ptr, uint32_t size, uint32_t dts, uint32_t pts = 0, int prefix_size = 0){ + + FrameFromPtr(CodecId codec_id, char *ptr, uint32_t size, uint32_t dts, uint32_t pts = 0, int prefix_size = 0) + : FrameFromPtr(ptr, size, dts, pts, prefix_size) { _codec_id = codec_id; + } + + FrameFromPtr(char *ptr, uint32_t size, uint32_t dts, uint32_t pts = 0, int prefix_size = 0){ _ptr = ptr; _size = size; _dts = dts; @@ -347,10 +352,17 @@ public: return false; } - CodecId getCodecId() const override{ + CodecId getCodecId() const override { + if (_codec_id == CodecInvalid) { + throw std::invalid_argument("FrameFromPtr对象未设置codec类型"); + } return _codec_id; } + void setCodecId(CodecId codec_id) { + _codec_id = codec_id; + } + bool keyFrame() const override { return false; }