From 2b592780adf73f0110f73a6d4539fd5fc3bc1146 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Wed, 11 Mar 2020 18:52:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Daac=20rtp=E8=A7=A3=E5=8C=85?= =?UTF-8?q?=E5=86=85=E5=AD=98=E8=B6=8A=E7=95=8C=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Extension/AACRtp.cpp | 96 +++++++++++++++------------------------- src/Extension/AACRtp.h | 2 +- 2 files changed, 37 insertions(+), 61 deletions(-) diff --git a/src/Extension/AACRtp.cpp b/src/Extension/AACRtp.cpp index a84c22be..b55c03d5 100644 --- a/src/Extension/AACRtp.cpp +++ b/src/Extension/AACRtp.cpp @@ -24,6 +24,7 @@ * SOFTWARE. */ #include "AACRtp.h" +#define ADTS_HEADER_LEN 7 namespace mediakit{ @@ -91,8 +92,8 @@ AACRtpDecoder::AACRtpDecoder() { AACFrame::Ptr AACRtpDecoder::obtainFrame() { //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 auto frame = ResourcePoolHelper::obtainObj(); - frame->aac_frame_length = 7; - frame->iPrefixSize = 7; + frame->aac_frame_length = ADTS_HEADER_LEN; + frame->iPrefixSize = ADTS_HEADER_LEN; if(frame->syncword == 0 && !_aac_cfg.empty()) { makeAdtsHeader(_aac_cfg,*frame); } @@ -100,70 +101,45 @@ AACFrame::Ptr AACRtpDecoder::obtainFrame() { } bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { - // 获取rtp数据长度 - int length = rtppack->size() - rtppack->offset; + //rtp数据开始部分 + uint8_t *ptr = (uint8_t *) rtppack->data() + rtppack->offset; + //rtp数据末尾 + const uint8_t *end = (uint8_t *) rtppack->data() + rtppack->size(); - // 获取rtp数据 - const uint8_t *rtp_packet_buf = (uint8_t *)rtppack->data() + rtppack->offset; - - do - { - // 查询头部的偏移,每次2字节 - uint32_t au_header_offset = 0; - //首2字节表示Au-Header的长度,单位bit,所以除以16得到Au-Header字节数 - const uint16_t au_header_length = (((rtp_packet_buf[au_header_offset] << 8) | rtp_packet_buf[au_header_offset + 1]) >> 4); - au_header_offset += 2; - - //assert(length > (2 + au_header_length * 2)); - if (length < (2 + au_header_length * 2)) - break; - - // 存放每一个aac帧长度 - std::vector vec_aac_len; - for (int i = 0; i < au_header_length; ++i) - { - // 之后的2字节是AU_HEADER - const uint16_t au_header = ((rtp_packet_buf[au_header_offset] << 8) | rtp_packet_buf[au_header_offset + 1]); - // 其中高13位表示一帧AAC负载的字节长度,低3位无用 - uint32_t nAac = (au_header >> 3); - vec_aac_len.push_back(nAac); - au_header_offset += 2; - } + //首2字节表示Au-Header的个数,单位bit,所以除以16得到Au-Header个数 + const uint16_t au_header_count = ((ptr[0] << 8) | ptr[1]) >> 4; + //忽略Au-Header区 + ptr += 2 + au_header_count * 2; - // 真正aac负载开始处 - const uint8_t *rtp_packet_payload = rtp_packet_buf + au_header_offset; - // 载荷查找 - uint32_t next_aac_payload_offset = 0; - for (int j = 0; j < au_header_length; ++j) - { - // 当前aac包长度 - const uint32_t cur_aac_payload_len = vec_aac_len.at(j); + static const uint32_t max_size = sizeof(AACFrame::buffer) - ADTS_HEADER_LEN; + while (ptr < end) { + auto size = std::min(max_size, (uint32_t) (end - ptr)); + if (_adts->aac_frame_length + size > sizeof(AACFrame::buffer)) { + //数据太多了,先清空 + flushData(); + } + //追加aac数据 + memcpy(_adts->buffer + _adts->aac_frame_length, ptr, size); + _adts->aac_frame_length += size; + _adts->timeStamp = rtppack->timeStamp; + ptr += size; + } - if (_adts->aac_frame_length + cur_aac_payload_len > sizeof(AACFrame::buffer)) { - _adts->aac_frame_length = 7; - WarnL << "aac负载数据太长"; - return false; - } - - // 提取每一包aac载荷数据 - memcpy(_adts->buffer + _adts->aac_frame_length, rtp_packet_payload + next_aac_payload_offset, cur_aac_payload_len); - _adts->aac_frame_length += (cur_aac_payload_len); - if (rtppack->mark == true) { - _adts->timeStamp = rtppack->timeStamp; - writeAdtsHeader(*_adts, _adts->buffer); - onGetAAC(_adts); - } - - next_aac_payload_offset += cur_aac_payload_len; - } - } while (0); - + if (rtppack->mark) { + //最后一个rtp分片 + flushData(); + } return false; } -void AACRtpDecoder::onGetAAC(const AACFrame::Ptr &frame) { - //写入环形缓存 - RtpCodec::inputFrame(frame); + +void AACRtpDecoder::flushData() { + if(_adts->aac_frame_length == ADTS_HEADER_LEN){ + //没有有效数据 + return; + } + writeAdtsHeader(*_adts, _adts->buffer); + RtpCodec::inputFrame(_adts); _adts = obtainFrame(); } diff --git a/src/Extension/AACRtp.h b/src/Extension/AACRtp.h index 14cfdd30..89f0b279 100644 --- a/src/Extension/AACRtp.h +++ b/src/Extension/AACRtp.h @@ -56,8 +56,8 @@ public: protected: AACRtpDecoder(); private: - void onGetAAC(const AACFrame::Ptr &frame); AACFrame::Ptr obtainFrame(); + void flushData(); private: AACFrame::Ptr _adts; string _aac_cfg;