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; }