mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 04:08:57 +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节省内存
|
#如果不调用startSendRtp相关接口,可以置0节省内存
|
||||||
gop_cache=1
|
gop_cache=1
|
||||||
|
|
||||||
|
#国标发送g711 rtp 打包时,每个包的语音时长是多少,默认是100 ms,范围为20~180ms (gb28181-2016,c.2.4规定),
|
||||||
|
#最好为20 的倍数,程序自动向20的倍数取整
|
||||||
|
rtp_g711_dur_ms = 100
|
||||||
|
|
||||||
[rtc]
|
[rtc]
|
||||||
#rtc播放推流、播放超时时间
|
#rtc播放推流、播放超时时间
|
||||||
timeoutSec=15
|
timeoutSec=15
|
||||||
|
@ -8,13 +8,27 @@ G711RtpEncoder::G711RtpEncoder(CodecId codec, uint32_t channels){
|
|||||||
_channels = 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) {
|
bool G711RtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
||||||
auto dur = (_cache_frame->size() - _cache_frame->prefixSize()) / (8 * _channels);
|
auto dur = (_cache_frame->size() - _cache_frame->prefixSize()) / (8 * _channels);
|
||||||
auto next_pts = _cache_frame->pts() + dur;
|
auto next_pts = _cache_frame->pts() + dur;
|
||||||
if (next_pts == 0) {
|
if (next_pts == 0) {
|
||||||
_cache_frame->_pts = frame->pts();
|
_cache_frame->_pts = frame->pts();
|
||||||
} else {
|
} else {
|
||||||
if ((next_pts + 20) < frame->pts()) { // 有丢包超过20ms
|
if ((next_pts + _pkt_dur_ms) < frame->pts()) { // 有丢包超过20ms
|
||||||
_cache_frame->_pts = frame->pts() - dur;
|
_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 ptr = _cache_frame->data() + _cache_frame->prefixSize();
|
||||||
auto len = _cache_frame->size() - _cache_frame->prefixSize();
|
auto len = _cache_frame->size() - _cache_frame->prefixSize();
|
||||||
auto remain_size = len;
|
auto remain_size = len;
|
||||||
auto max_size = 160 * _channels; // 20 ms per rtp
|
auto max_size = 160 * _channels * _pkt_dur_ms / 20; // 20 ms per 160 byte
|
||||||
int n = 0;
|
uint32_t n = 0;
|
||||||
bool mark = false;
|
bool mark = true;
|
||||||
while (remain_size >= max_size) {
|
while (remain_size >= max_size) {
|
||||||
size_t rtp_size;
|
size_t rtp_size;
|
||||||
if (remain_size >= max_size) {
|
if (remain_size >= max_size) {
|
||||||
@ -35,13 +49,13 @@ bool G711RtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
stamp += 20;
|
stamp += _pkt_dur_ms;
|
||||||
RtpCodec::inputRtp(getRtpInfo().makeRtp(TrackAudio, ptr, rtp_size, mark, stamp), false);
|
RtpCodec::inputRtp(getRtpInfo().makeRtp(TrackAudio, ptr, rtp_size, mark, stamp), true);
|
||||||
ptr += rtp_size;
|
ptr += rtp_size;
|
||||||
remain_size -= rtp_size;
|
remain_size -= rtp_size;
|
||||||
}
|
}
|
||||||
_cache_frame->_buffer.erase(0, n * max_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;
|
return len > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +36,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool inputFrame(const Frame::Ptr &frame) override;
|
bool inputFrame(const Frame::Ptr &frame) override;
|
||||||
|
|
||||||
|
void setOpt(int opt, const toolkit::Any ¶m) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t _channels = 1;
|
uint32_t _channels = 1;
|
||||||
|
uint32_t _pkt_dur_ms = 20;
|
||||||
FrameImp::Ptr _cache_frame;
|
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 kPSPT = RTP_PROXY_FIELD "ps_pt";
|
||||||
const string kOpusPT = RTP_PROXY_FIELD "opus_pt";
|
const string kOpusPT = RTP_PROXY_FIELD "opus_pt";
|
||||||
const string kGopCache = RTP_PROXY_FIELD "gop_cache";
|
const string kGopCache = RTP_PROXY_FIELD "gop_cache";
|
||||||
|
const string kRtpG711DurMs = RTP_PROXY_FIELD "rtp_g711_dur_ms";
|
||||||
|
|
||||||
static onceToken token([]() {
|
static onceToken token([]() {
|
||||||
mINI::Instance()[kDumpDir] = "";
|
mINI::Instance()[kDumpDir] = "";
|
||||||
@ -348,6 +349,7 @@ static onceToken token([]() {
|
|||||||
mINI::Instance()[kPSPT] = 96;
|
mINI::Instance()[kPSPT] = 96;
|
||||||
mINI::Instance()[kOpusPT] = 100;
|
mINI::Instance()[kOpusPT] = 100;
|
||||||
mINI::Instance()[kGopCache] = 1;
|
mINI::Instance()[kGopCache] = 1;
|
||||||
|
mINI::Instance()[kRtpG711DurMs] = 100;
|
||||||
});
|
});
|
||||||
} // namespace RtpProxy
|
} // namespace RtpProxy
|
||||||
|
|
||||||
|
@ -382,6 +382,9 @@ extern const std::string kPSPT;
|
|||||||
extern const std::string kOpusPT;
|
extern const std::string kOpusPT;
|
||||||
// RtpSender相关功能是否提前开启gop缓存优化级联秒开体验,默认开启
|
// RtpSender相关功能是否提前开启gop缓存优化级联秒开体验,默认开启
|
||||||
extern const std::string kGopCache;
|
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
|
} // namespace RtpProxy
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,6 +34,12 @@ bool RawEncoderImp::addTrack(const Track::Ptr &track) {
|
|||||||
auto ring = std::make_shared<RtpRing::RingType>();
|
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); }));
|
ring->setDelegate(std::make_shared<RingDelegateHelper>([this](RtpPacket::Ptr rtp, bool is_key) { onRTP(std::move(rtp), true); }));
|
||||||
_rtp_encoder->setRtpRing(std::move(ring));
|
_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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +93,17 @@ public:
|
|||||||
|
|
||||||
RtpInfo &getRtpInfo() { return *_rtp_info; }
|
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:
|
private:
|
||||||
std::unique_ptr<RtpInfo> _rtp_info;
|
std::unique_ptr<RtpInfo> _rtp_info;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user