优化G711 rtp打包分片逻辑相关代码

This commit is contained in:
xia-chu 2024-11-29 20:19:30 +08:00
parent f5d5b71731
commit 64285b6b09
3 changed files with 35 additions and 38 deletions

View File

@ -119,7 +119,7 @@ Track::Ptr getTrackBySdpU(const SdpTrack::Ptr &track) {
RtpCodec::Ptr getRtpEncoderByCodecId_l(CodecId codec, uint8_t pt) { RtpCodec::Ptr getRtpEncoderByCodecId_l(CodecId codec, uint8_t pt) {
if (pt == Rtsp::PT_PCMA || pt == Rtsp::PT_PCMU) { if (pt == Rtsp::PT_PCMA || pt == Rtsp::PT_PCMU) {
return std::make_shared<G711RtpEncoder>(codec, 1); return std::make_shared<G711RtpEncoder>(8000, 1);
} }
return std::make_shared<CommonRtpEncoder>(); return std::make_shared<CommonRtpEncoder>();
} }

View File

@ -2,10 +2,10 @@
namespace mediakit { namespace mediakit {
G711RtpEncoder::G711RtpEncoder(CodecId codec, uint32_t channels){ G711RtpEncoder::G711RtpEncoder(int sample_rate, int channels, int sample_bit) {
_cache_frame = FrameImp::create(); _sample_rate = sample_rate;
_cache_frame->_codec_id = codec;
_channels = channels; _channels = channels;
_sample_bit = sample_bit;
} }
void G711RtpEncoder::setOpt(int opt, const toolkit::Any &param) { void G711RtpEncoder::setOpt(int opt, const toolkit::Any &param) {
@ -24,36 +24,24 @@ void G711RtpEncoder::setOpt(int opt, const toolkit::Any &param) {
} }
bool G711RtpEncoder::inputFrame(const Frame::Ptr &frame) { bool G711RtpEncoder::inputFrame(const Frame::Ptr &frame) {
auto dur = (_cache_frame->size() - _cache_frame->prefixSize()) / (8 * _channels); auto ptr = frame->data() + frame->prefixSize();
auto next_pts = _cache_frame->pts() + dur; auto size = frame->size() - frame->prefixSize();
if (next_pts == 0) { _buffer.append(ptr, size);
_cache_frame->_pts = frame->pts(); _in_size += size;
} else { _in_pts = frame->pts();
if ((next_pts + _pkt_dur_ms) < frame->pts()) { // 有丢包超过20ms
_cache_frame->_pts = frame->pts() - dur;
}
}
_cache_frame->_buffer.append(frame->data() + frame->prefixSize(), frame->size() - frame->prefixSize());
auto stamp = _cache_frame->pts(); if (!_pkt_bytes) {
auto ptr = _cache_frame->data() + _cache_frame->prefixSize(); // G711压缩率固定是2倍
auto len = _cache_frame->size() - _cache_frame->prefixSize(); _pkt_bytes = _pkt_dur_ms * _channels * (_sample_bit / 8) * _sample_rate / 1000 / 2;
auto remain_size = len;
size_t max_size = 160 * _channels * _pkt_dur_ms / 20; // 20 ms per 160 byte
size_t n = 0;
bool mark = false;
while (remain_size >= max_size) {
assert(remain_size >= max_size);
const size_t rtp_size = max_size;
n++;
stamp += _pkt_dur_ms;
RtpCodec::inputRtp(getRtpInfo().makeRtp(TrackAudio, ptr, rtp_size, mark, stamp), false);
ptr += rtp_size;
remain_size -= rtp_size;
} }
_cache_frame->_buffer.erase(0, n * max_size);
_cache_frame->_pts += (uint64_t)_pkt_dur_ms * n; while (_buffer.size() >= _pkt_bytes) {
return len > 0; _out_size += _pkt_bytes;
auto pts = _in_pts - (_in_size - _out_size) * (_pkt_dur_ms / (float)_pkt_bytes);
RtpCodec::inputRtp(getRtpInfo().makeRtp(TrackAudio, _buffer.data(), _pkt_bytes, false, pts), false);
_buffer.erase(0, _pkt_bytes);
}
return true;
} }
} // namespace mediakit } // namespace mediakit

View File

@ -29,15 +29,17 @@ public:
/** /**
* *
* @param codec * @param sample_rate
* @param channels * @param channels
* @param sample_bit
* Constructor * Constructor
* @param codec Encoding type * @param sample_rate audio sample rate
* @param channels Number of channels * @param channels Number of channels
* @param sample_bit audio sample bits
* [AUTO-TRANSLATED:dbbd593e] * [AUTO-TRANSLATED:dbbd593e]
*/ */
G711RtpEncoder(CodecId codec, uint32_t channels); G711RtpEncoder(int sample_rate = 8000, int channels = 1, int sample_bit = 16);
/** /**
* rtp * rtp
@ -51,9 +53,16 @@ public:
void setOpt(int opt, const toolkit::Any &param) override; void setOpt(int opt, const toolkit::Any &param) override;
private: private:
uint32_t _channels = 1; int _channels;
int _sample_rate;
int _sample_bit;
uint32_t _pkt_dur_ms = 20; uint32_t _pkt_dur_ms = 20;
FrameImp::Ptr _cache_frame; uint32_t _pkt_bytes = 0;
uint64_t _in_size = 0;
uint64_t _out_size = 0;
int64_t _in_pts = 0;
toolkit::BufferLikeString _buffer;
}; };
}//namespace mediakit }//namespace mediakit