mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-29 22:32:23 +08:00
Merge branch 'master' of https://gitee.com/xia-chu/ZLMediaKit into feature/transcode2
This commit is contained in:
@@ -388,11 +388,7 @@ Track::Ptr AACTrack::clone() const {
|
||||
}
|
||||
|
||||
Sdp::Ptr AACTrack::getSdp(uint8_t payload_type) const {
|
||||
if (!ready()) {
|
||||
WarnL << getCodecName() << " Track未准备好";
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_shared<AACSdp>(getExtraData()->toString(), payload_type, getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
|
||||
return std::make_shared<AACSdp>(getExtraData()->toString(), payload_type, getAudioSampleRate(), getAudioChannel(), getBitRate() >> 10);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -19,70 +19,14 @@ using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
/**
|
||||
* G711类型SDP
|
||||
* G711 type SDP
|
||||
|
||||
* [AUTO-TRANSLATED:ea72d60a]
|
||||
*/
|
||||
class G711Sdp : public Sdp {
|
||||
public:
|
||||
/**
|
||||
* G711采样率固定为8000
|
||||
* @param codecId G711A G711U
|
||||
* @param payload_type rtp payload type
|
||||
* @param sample_rate 音频采样率
|
||||
* @param channels 通道数
|
||||
* @param bitrate 比特率
|
||||
* G711 sampling rate is fixed at 8000
|
||||
* @param codecId G711A G711U
|
||||
* @param payload_type rtp payload type
|
||||
* @param sample_rate audio sampling rate
|
||||
* @param channels number of channels
|
||||
* @param bitrate bitrate
|
||||
|
||||
* [AUTO-TRANSLATED:5ea4b771]
|
||||
*/
|
||||
G711Sdp(CodecId codecId, int payload_type, int sample_rate, int channels, int bitrate)
|
||||
: Sdp(sample_rate, payload_type) {
|
||||
_printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n";
|
||||
if (bitrate) {
|
||||
_printer << "b=AS:" << bitrate << "\r\n";
|
||||
}
|
||||
_printer << "a=rtpmap:" << payload_type << " " << getCodecName(codecId) << "/" << sample_rate << "/" << channels << "\r\n";
|
||||
}
|
||||
|
||||
string getSdp() const override {
|
||||
return _printer;
|
||||
}
|
||||
|
||||
private:
|
||||
_StrPrinter _printer;
|
||||
};
|
||||
|
||||
Track::Ptr G711Track::clone() const {
|
||||
return std::make_shared<G711Track>(*this);
|
||||
}
|
||||
|
||||
Sdp::Ptr G711Track::getSdp(uint8_t payload_type) const {
|
||||
if (!ready()) {
|
||||
WarnL << getCodecName() << " Track未准备好";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto codec = getCodecId();
|
||||
const auto sample_rate = getAudioSampleRate();
|
||||
const auto audio_channel = getAudioChannel();
|
||||
const auto bitrate = getBitRate() >> 10;
|
||||
if (sample_rate == 8000 && audio_channel == 1) {
|
||||
// https://datatracker.ietf.org/doc/html/rfc3551#section-6
|
||||
payload_type = (codec == CodecG711U) ? Rtsp::PT_PCMU : Rtsp::PT_PCMA;
|
||||
}
|
||||
|
||||
return std::make_shared<G711Sdp>(codec, payload_type, sample_rate, audio_channel, bitrate);
|
||||
return std::make_shared<DefaultSdp>(payload_type, *this);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
CodecId getCodecA() {
|
||||
@@ -94,7 +38,7 @@ CodecId getCodecU() {
|
||||
}
|
||||
|
||||
Track::Ptr getTrackByCodecId_l(CodecId codec, int sample_rate, int channels, int sample_bit) {
|
||||
return (sample_rate && channels && sample_bit) ? std::make_shared<G711Track>(codec, sample_rate, channels, sample_bit) : nullptr;
|
||||
return std::make_shared<G711Track>(codec, sample_rate, 1, 16);
|
||||
}
|
||||
|
||||
Track::Ptr getTrackByCodecIdA(int sample_rate, int channels, int sample_bit) {
|
||||
@@ -119,7 +63,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<G711RtpEncoder>(codec, 1);
|
||||
return std::make_shared<G711RtpEncoder>(8000, 1);
|
||||
}
|
||||
return std::make_shared<CommonRtpEncoder>();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -357,11 +357,7 @@ private:
|
||||
};
|
||||
|
||||
Sdp::Ptr H264Track::getSdp(uint8_t payload_type) const {
|
||||
if (!ready()) {
|
||||
WarnL << getCodecName() << " Track未准备好";
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_shared<H264Sdp>(_sps, _pps, payload_type, getBitRate() / 1024);
|
||||
return std::make_shared<H264Sdp>(_sps, _pps, payload_type, getBitRate() >> 10);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -263,11 +263,7 @@ private:
|
||||
};
|
||||
|
||||
Sdp::Ptr H265Track::getSdp(uint8_t payload_type) const {
|
||||
if (!ready()) {
|
||||
WarnL << getCodecName() << " Track未准备好";
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_shared<H265Sdp>(_vps, _sps, _pps, payload_type, getBitRate() / 1024);
|
||||
return std::make_shared<H265Sdp>(_vps, _sps, _pps, payload_type, getBitRate() >> 10);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -31,26 +31,10 @@ void JPEGTrack::getVideoResolution(const uint8_t *buf, int len) {
|
||||
}
|
||||
}
|
||||
|
||||
class JPEGSdp : public Sdp {
|
||||
public:
|
||||
JPEGSdp(int bitrate) : Sdp(90000, Rtsp::PT_JPEG) {
|
||||
_printer << "m=video 0 RTP/AVP " << (int)getPayloadType() << "\r\n";
|
||||
if (bitrate) {
|
||||
_printer << "b=AS:" << bitrate << "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
std::string getSdp() const { return _printer; }
|
||||
|
||||
private:
|
||||
_StrPrinter _printer;
|
||||
};
|
||||
|
||||
Sdp::Ptr JPEGTrack::getSdp(uint8_t) const {
|
||||
return std::make_shared<JPEGSdp>(getBitRate() / 1024);
|
||||
Sdp::Ptr JPEGTrack::getSdp(uint8_t pt) const {
|
||||
return std::make_shared<DefaultSdp>(pt, *this);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
CodecId getCodec() {
|
||||
|
||||
@@ -18,50 +18,8 @@ using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
/**
|
||||
* L16类型SDP
|
||||
* L16 type SDP
|
||||
|
||||
* [AUTO-TRANSLATED:11b1196d]
|
||||
*/
|
||||
class L16Sdp : public Sdp {
|
||||
public:
|
||||
/**
|
||||
* L16采样位数固定为16位
|
||||
* @param payload_type rtp payload type
|
||||
* @param channels 通道数
|
||||
* @param sample_rate 音频采样率
|
||||
* @param bitrate 比特率
|
||||
* L16 sampling bit width is fixed to 16 bits
|
||||
* @param payload_type rtp payload type
|
||||
* @param channels number of channels
|
||||
* @param sample_rate audio sampling rate
|
||||
* @param bitrate bitrate
|
||||
|
||||
|
||||
* [AUTO-TRANSLATED:7a08a400]
|
||||
*/
|
||||
L16Sdp(int payload_type, int sample_rate, int channels, int bitrate) : Sdp(sample_rate, payload_type) {
|
||||
_printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n";
|
||||
if (bitrate) {
|
||||
_printer << "b=AS:" << bitrate << "\r\n";
|
||||
}
|
||||
_printer << "a=rtpmap:" << payload_type << " " << getCodecName(CodecL16) << "/" << sample_rate << "/" << channels << "\r\n";
|
||||
}
|
||||
|
||||
string getSdp() const override { return _printer; }
|
||||
|
||||
private:
|
||||
_StrPrinter _printer;
|
||||
};
|
||||
|
||||
Sdp::Ptr L16Track::getSdp(uint8_t payload_type) const {
|
||||
WarnL << "Enter L16Track::getSdp function";
|
||||
if (!ready()) {
|
||||
WarnL << getCodecName() << " Track未准备好";
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_shared<L16Sdp>(payload_type, getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
|
||||
return std::make_shared<DefaultSdp>(payload_type, *this);
|
||||
}
|
||||
|
||||
Track::Ptr L16Track::clone() const {
|
||||
|
||||
@@ -18,51 +18,9 @@ using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
/**
|
||||
* Opus类型SDP
|
||||
* Opus type SDP
|
||||
|
||||
* [AUTO-TRANSLATED:6c0a72ed]
|
||||
*/
|
||||
class OpusSdp : public Sdp {
|
||||
public:
|
||||
/**
|
||||
* 构造opus sdp
|
||||
* @param payload_type rtp payload type
|
||||
* @param sample_rate 音频采样率
|
||||
* @param channels 通道数
|
||||
* @param bitrate 比特率
|
||||
* Construct opus sdp
|
||||
* @param payload_type rtp payload type
|
||||
* @param sample_rate audio sample rate
|
||||
* @param channels number of channels
|
||||
* @param bitrate bitrate
|
||||
|
||||
|
||||
* [AUTO-TRANSLATED:40713e9d]
|
||||
*/
|
||||
OpusSdp(int payload_type, int sample_rate, int channels, int bitrate) : Sdp(sample_rate, payload_type) {
|
||||
_printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n";
|
||||
if (bitrate) {
|
||||
_printer << "b=AS:" << bitrate << "\r\n";
|
||||
}
|
||||
_printer << "a=rtpmap:" << payload_type << " " << getCodecName(CodecOpus) << "/" << sample_rate << "/" << channels << "\r\n";
|
||||
}
|
||||
|
||||
string getSdp() const override {
|
||||
return _printer;
|
||||
}
|
||||
|
||||
private:
|
||||
_StrPrinter _printer;
|
||||
};
|
||||
|
||||
Sdp::Ptr OpusTrack::getSdp(uint8_t payload_type) const {
|
||||
if (!ready()) {
|
||||
WarnL << getCodecName() << " Track未准备好";
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_shared<OpusSdp>(payload_type, getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
|
||||
return std::make_shared<DefaultSdp>(payload_type, *this);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
Reference in New Issue
Block a user