diff --git a/ext-codec/G711.cpp b/ext-codec/G711.cpp index 7a60fcda..dae2260f 100644 --- a/ext-codec/G711.cpp +++ b/ext-codec/G711.cpp @@ -119,7 +119,7 @@ Track::Ptr getTrackBySdpU(const SdpTrack::Ptr &track) { RtpCodec::Ptr getRtpEncoderByCodecId_l(CodecId codec, uint8_t pt) { if (pt == Rtsp::PT_PCMA || pt == Rtsp::PT_PCMU) { - return std::make_shared(codec, 1); + return std::make_shared(8000, 1); } return std::make_shared(); } diff --git a/ext-codec/G711Rtp.cpp b/ext-codec/G711Rtp.cpp index ac630563..ed70b619 100644 --- a/ext-codec/G711Rtp.cpp +++ b/ext-codec/G711Rtp.cpp @@ -2,10 +2,10 @@ namespace mediakit { -G711RtpEncoder::G711RtpEncoder(CodecId codec, uint32_t channels){ - _cache_frame = FrameImp::create(); - _cache_frame->_codec_id = codec; +G711RtpEncoder::G711RtpEncoder(int sample_rate, int channels, int sample_bit) { + _sample_rate = sample_rate; _channels = channels; + _sample_bit = sample_bit; } void G711RtpEncoder::setOpt(int opt, const toolkit::Any ¶m) { @@ -24,36 +24,24 @@ void G711RtpEncoder::setOpt(int opt, const toolkit::Any ¶m) { } 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 + _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 ptr = frame->data() + frame->prefixSize(); + auto size = frame->size() - frame->prefixSize(); + _buffer.append(ptr, size); + _in_size += size; + _in_pts = frame->pts(); - auto stamp = _cache_frame->pts(); - auto ptr = _cache_frame->data() + _cache_frame->prefixSize(); - auto len = _cache_frame->size() - _cache_frame->prefixSize(); - 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; + if (!_pkt_bytes) { + // G711压缩率固定是2倍 + _pkt_bytes = _pkt_dur_ms * _channels * (_sample_bit / 8) * _sample_rate / 1000 / 2; } - _cache_frame->_buffer.erase(0, n * max_size); - _cache_frame->_pts += (uint64_t)_pkt_dur_ms * n; - return len > 0; + + while (_buffer.size() >= _pkt_bytes) { + _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 \ No newline at end of file diff --git a/ext-codec/G711Rtp.h b/ext-codec/G711Rtp.h index e81ca9fc..957911d3 100644 --- a/ext-codec/G711Rtp.h +++ b/ext-codec/G711Rtp.h @@ -29,15 +29,17 @@ public: /** * 构造函数 - * @param codec 编码类型 + * @param sample_rate 音频采样率 * @param channels 通道数 + * @param sample_bit 音频采样位数 * Constructor - * @param codec Encoding type + * @param sample_rate audio sample rate * @param channels Number of channels - + * @param sample_bit audio sample bits + * [AUTO-TRANSLATED:dbbd593e] */ - G711RtpEncoder(CodecId codec, uint32_t channels); + G711RtpEncoder(int sample_rate = 8000, int channels = 1, int sample_bit = 16); /** * 输入帧数据并编码成rtp @@ -51,9 +53,16 @@ public: void setOpt(int opt, const toolkit::Any ¶m) override; private: - uint32_t _channels = 1; + int _channels; + int _sample_rate; + int _sample_bit; + 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