mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 02:34:26 +08:00
rtp send rtp g711 audio can config duration (#3325)
optimization for this [issue](https://github.com/ZLMediaKit/ZLMediaKit/issues/3316)
This commit is contained in:
parent
87cb488b04
commit
06abbd0eb7
@ -329,6 +329,10 @@ opus_pt=100
|
||||
#如果不调用startSendRtp相关接口,可以置0节省内存
|
||||
gop_cache=1
|
||||
|
||||
#国标发送g711 rtp 打包时,每个包的语音时长是多少,默认是100 ms,范围为20~180ms (gb28181-2016,c.2.4规定),
|
||||
#最好为20 的倍数,程序自动向20的倍数取整
|
||||
rtp_g711_dur_ms = 100
|
||||
|
||||
[rtc]
|
||||
#rtc播放推流、播放超时时间
|
||||
timeoutSec=15
|
||||
|
@ -8,13 +8,27 @@ G711RtpEncoder::G711RtpEncoder(CodecId codec, uint32_t channels){
|
||||
_channels = channels;
|
||||
}
|
||||
|
||||
void G711RtpEncoder::setOpt(int opt, const toolkit::Any ¶m) {
|
||||
if (opt == RTP_ENCODER_PKT_DUR_MS) {
|
||||
if (param.is<uint32_t>()) {
|
||||
auto dur = param.get<uint32_t>();
|
||||
if (dur < 20 || dur > 180) {
|
||||
WarnL << "set g711 rtp encoder duration ms failed for " << dur;
|
||||
return;
|
||||
}
|
||||
// 向上 20ms 取整
|
||||
_pkt_dur_ms = (dur + 19) / 20 * 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool G711RtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
||||
auto dur = (_cache_frame->size() - _cache_frame->prefixSize()) / (8 * _channels);
|
||||
auto next_pts = _cache_frame->pts() + dur;
|
||||
if (next_pts == 0) {
|
||||
_cache_frame->_pts = frame->pts();
|
||||
} else {
|
||||
if ((next_pts + 20) < frame->pts()) { // 有丢包超过20ms
|
||||
if ((next_pts + _pkt_dur_ms) < frame->pts()) { // 有丢包超过20ms
|
||||
_cache_frame->_pts = frame->pts() - dur;
|
||||
}
|
||||
}
|
||||
@ -24,9 +38,9 @@ bool G711RtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
||||
auto ptr = _cache_frame->data() + _cache_frame->prefixSize();
|
||||
auto len = _cache_frame->size() - _cache_frame->prefixSize();
|
||||
auto remain_size = len;
|
||||
auto max_size = 160 * _channels; // 20 ms per rtp
|
||||
int n = 0;
|
||||
bool mark = false;
|
||||
auto max_size = 160 * _channels * _pkt_dur_ms / 20; // 20 ms per 160 byte
|
||||
uint32_t n = 0;
|
||||
bool mark = true;
|
||||
while (remain_size >= max_size) {
|
||||
size_t rtp_size;
|
||||
if (remain_size >= max_size) {
|
||||
@ -35,13 +49,13 @@ bool G711RtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
||||
break;
|
||||
}
|
||||
n++;
|
||||
stamp += 20;
|
||||
RtpCodec::inputRtp(getRtpInfo().makeRtp(TrackAudio, ptr, rtp_size, mark, stamp), false);
|
||||
stamp += _pkt_dur_ms;
|
||||
RtpCodec::inputRtp(getRtpInfo().makeRtp(TrackAudio, ptr, rtp_size, mark, stamp), true);
|
||||
ptr += rtp_size;
|
||||
remain_size -= rtp_size;
|
||||
}
|
||||
_cache_frame->_buffer.erase(0, n * max_size);
|
||||
_cache_frame->_pts += 20 * n;
|
||||
_cache_frame->_pts += (uint64_t)_pkt_dur_ms * n;
|
||||
return len > 0;
|
||||
}
|
||||
|
||||
|
@ -36,8 +36,11 @@ public:
|
||||
*/
|
||||
bool inputFrame(const Frame::Ptr &frame) override;
|
||||
|
||||
void setOpt(int opt, const toolkit::Any ¶m) override;
|
||||
|
||||
private:
|
||||
uint32_t _channels = 1;
|
||||
uint32_t _pkt_dur_ms = 20;
|
||||
FrameImp::Ptr _cache_frame;
|
||||
};
|
||||
|
||||
|
@ -338,6 +338,7 @@ const string kH265PT = RTP_PROXY_FIELD "h265_pt";
|
||||
const string kPSPT = RTP_PROXY_FIELD "ps_pt";
|
||||
const string kOpusPT = RTP_PROXY_FIELD "opus_pt";
|
||||
const string kGopCache = RTP_PROXY_FIELD "gop_cache";
|
||||
const string kRtpG711DurMs = RTP_PROXY_FIELD "rtp_g711_dur_ms";
|
||||
|
||||
static onceToken token([]() {
|
||||
mINI::Instance()[kDumpDir] = "";
|
||||
@ -348,6 +349,7 @@ static onceToken token([]() {
|
||||
mINI::Instance()[kPSPT] = 96;
|
||||
mINI::Instance()[kOpusPT] = 100;
|
||||
mINI::Instance()[kGopCache] = 1;
|
||||
mINI::Instance()[kRtpG711DurMs] = 100;
|
||||
});
|
||||
} // namespace RtpProxy
|
||||
|
||||
|
@ -382,6 +382,9 @@ extern const std::string kPSPT;
|
||||
extern const std::string kOpusPT;
|
||||
// RtpSender相关功能是否提前开启gop缓存优化级联秒开体验,默认开启
|
||||
extern const std::string kGopCache;
|
||||
//国标发送g711 rtp 打包时,每个包的语音时长是多少,默认是100 ms,范围为20~180ms (gb28181-2016,c.2.4规定),
|
||||
//最好为20 的倍数,程序自动向20的倍数取整
|
||||
extern const std::string kRtpG711DurMs;
|
||||
} // namespace RtpProxy
|
||||
|
||||
/**
|
||||
|
@ -34,6 +34,12 @@ bool RawEncoderImp::addTrack(const Track::Ptr &track) {
|
||||
auto ring = std::make_shared<RtpRing::RingType>();
|
||||
ring->setDelegate(std::make_shared<RingDelegateHelper>([this](RtpPacket::Ptr rtp, bool is_key) { onRTP(std::move(rtp), true); }));
|
||||
_rtp_encoder->setRtpRing(std::move(ring));
|
||||
if (track->getCodecId() == CodecG711A || track->getCodecId() == CodecG711U) {
|
||||
GET_CONFIG(uint32_t, dur_ms, RtpProxy::kRtpG711DurMs);
|
||||
Any param;
|
||||
param.set<uint32_t>(dur_ms);
|
||||
_rtp_encoder->setOpt(RtpCodec::RTP_ENCODER_PKT_DUR_MS, param);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,17 @@ public:
|
||||
|
||||
RtpInfo &getRtpInfo() { return *_rtp_info; }
|
||||
|
||||
enum {
|
||||
RTP_ENCODER_PKT_DUR_MS = 1 // 主要应用于g711 rtp 打包器每个包的时间长度,option_value 为int*, option_len 为4
|
||||
};
|
||||
/**
|
||||
* @brief 设置rtp打包器与解包器的相关参数,主要应用与g711 rtp 打包器,使用方法类似setsockopt
|
||||
*
|
||||
* @param opt 设置的选项
|
||||
* @param param 设置的参数
|
||||
*/
|
||||
virtual void setOpt(int opt, const toolkit::Any ¶m) {};
|
||||
|
||||
private:
|
||||
std::unique_ptr<RtpInfo> _rtp_info;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user