mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Merge feature/rtc
This commit is contained in:
commit
cc6a447332
20 changed files with 2296 additions and 59 deletions
|
@ -61,31 +61,31 @@ srs_error_t SrsAudioDecoder::initialize()
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
if (codec_name_.compare("aac")) {
|
||||
return srs_error_wrap(err, "Invalid codec name");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Invalid codec name");
|
||||
}
|
||||
|
||||
const AVCodec *codec = avcodec_find_decoder_by_name(codec_name_.c_str());
|
||||
if (!codec) {
|
||||
return srs_error_wrap(err, "Codec not found by name");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Codec not found by name");
|
||||
}
|
||||
|
||||
codec_ctx_ = avcodec_alloc_context3(codec);
|
||||
if (!codec_ctx_) {
|
||||
return srs_error_wrap(err, "Could not allocate audio codec context");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not allocate audio codec context");
|
||||
}
|
||||
|
||||
if (avcodec_open2(codec_ctx_, codec, NULL) < 0) {
|
||||
return srs_error_wrap(err, "Could not open codec");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not open codec");
|
||||
}
|
||||
|
||||
frame_ = av_frame_alloc();
|
||||
if (!frame_) {
|
||||
return srs_error_wrap(err, "Could not allocate audio frame");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not allocate audio frame");
|
||||
}
|
||||
|
||||
packet_ = av_packet_alloc();
|
||||
if (!packet_) {
|
||||
return srs_error_wrap(err, "Could not allocate audio packet");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not allocate audio packet");
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -100,7 +100,7 @@ srs_error_t SrsAudioDecoder::decode(SrsSample *pkt, char *buf, int &size)
|
|||
|
||||
int ret = avcodec_send_packet(codec_ctx_, packet_);
|
||||
if (ret < 0) {
|
||||
return srs_error_wrap(err, "Error submitting the packet to the decoder");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Error submitting the packet to the decoder");
|
||||
}
|
||||
|
||||
int max = size;
|
||||
|
@ -111,12 +111,12 @@ srs_error_t SrsAudioDecoder::decode(SrsSample *pkt, char *buf, int &size)
|
|||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
return err;
|
||||
} else if (ret < 0) {
|
||||
return srs_error_wrap(err, "Error during decoding");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Error during decoding");
|
||||
}
|
||||
|
||||
int pcm_size = av_get_bytes_per_sample(codec_ctx_->sample_fmt);
|
||||
if (pcm_size < 0) {
|
||||
return srs_error_wrap(err, "Failed to calculate data size");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Failed to calculate data size");
|
||||
}
|
||||
|
||||
for (int i = 0; i < frame_->nb_samples; i++) {
|
||||
|
@ -159,7 +159,7 @@ srs_error_t SrsAudioEncoder::initialize()
|
|||
int error = 0;
|
||||
opus_ = opus_encoder_create(sampling_rate_, channels_, OPUS_APPLICATION_VOIP, &error);
|
||||
if (error != OPUS_OK) {
|
||||
return srs_error_wrap(err, "Error create Opus encoder");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Error create Opus encoder");
|
||||
}
|
||||
|
||||
switch (sampling_rate_)
|
||||
|
@ -200,7 +200,7 @@ srs_error_t SrsAudioEncoder::encode(SrsSample *frame, char *buf, int &size)
|
|||
|
||||
int nb_samples = sampling_rate_ * kOpusPacketMs / 1000;
|
||||
if (frame->size != nb_samples * 2 * channels_) {
|
||||
return srs_error_wrap(err, "invalid frame size %d, should be %d", frame->size, nb_samples * 2 * channels_);
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "invalid frame size %d, should be %d", frame->size, nb_samples * 2 * channels_);
|
||||
}
|
||||
|
||||
opus_int16 *data = (opus_int16 *)frame->bytes;
|
||||
|
@ -255,7 +255,7 @@ srs_error_t SrsAudioResample::initialize()
|
|||
|
||||
swr_ctx_ = swr_alloc();
|
||||
if (!swr_ctx_) {
|
||||
return srs_error_wrap(err, "Could not allocate resampler context");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not allocate resampler context");
|
||||
}
|
||||
|
||||
av_opt_set_int(swr_ctx_, "in_channel_layout", src_ch_layout_, 0);
|
||||
|
@ -268,14 +268,14 @@ srs_error_t SrsAudioResample::initialize()
|
|||
|
||||
int ret;
|
||||
if ((ret = swr_init(swr_ctx_)) < 0) {
|
||||
return srs_error_wrap(err, "Failed to initialize the resampling context");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Failed to initialize the resampling context");
|
||||
}
|
||||
|
||||
src_nb_channels_ = av_get_channel_layout_nb_channels(src_ch_layout_);
|
||||
ret = av_samples_alloc_array_and_samples(&src_data_, &src_linesize_, src_nb_channels_,
|
||||
src_nb_samples_, src_sample_fmt_, 0);
|
||||
if (ret < 0) {
|
||||
return srs_error_wrap(err, "Could not allocate source samples");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not allocate source samples");
|
||||
}
|
||||
|
||||
max_dst_nb_samples_ = dst_nb_samples_ =
|
||||
|
@ -285,7 +285,7 @@ srs_error_t SrsAudioResample::initialize()
|
|||
ret = av_samples_alloc_array_and_samples(&dst_data_, &dst_linesize_, dst_nb_channels_,
|
||||
dst_nb_samples_, dst_sample_fmt_, 0);
|
||||
if (ret < 0) {
|
||||
return srs_error_wrap(err, "Could not allocate destination samples");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not allocate destination samples");
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -300,7 +300,7 @@ srs_error_t SrsAudioResample::resample(SrsSample *pcm, char *buf, int &size)
|
|||
plane = 2;
|
||||
}
|
||||
if (src_linesize_ * plane < pcm->size || pcm->size < 0) {
|
||||
return srs_error_wrap(err, "size not ok");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "size not ok");
|
||||
}
|
||||
memcpy(src_data_[0], pcm->bytes, pcm->size);
|
||||
|
||||
|
@ -311,20 +311,20 @@ srs_error_t SrsAudioResample::resample(SrsSample *pcm, char *buf, int &size)
|
|||
ret = av_samples_alloc(dst_data_, &dst_linesize_, dst_nb_channels_,
|
||||
dst_nb_samples_, dst_sample_fmt_, 1);
|
||||
if (ret < 0) {
|
||||
return srs_error_wrap(err, "alloc error");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "alloc error");
|
||||
}
|
||||
max_dst_nb_samples_ = dst_nb_samples_;
|
||||
}
|
||||
|
||||
ret = swr_convert(swr_ctx_, dst_data_, dst_nb_samples_, (const uint8_t **)src_data_, src_nb_samples_);
|
||||
if (ret < 0) {
|
||||
return srs_error_wrap(err, "Error while converting");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Error while converting");
|
||||
}
|
||||
|
||||
int dst_bufsize = av_samples_get_buffer_size(&dst_linesize_, dst_nb_channels_,
|
||||
ret, dst_sample_fmt_, 1);
|
||||
if (dst_bufsize < 0) {
|
||||
return srs_error_wrap(err, "Could not get sample buffer size");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not get sample buffer size");
|
||||
}
|
||||
|
||||
int max = size;
|
||||
|
@ -369,13 +369,13 @@ srs_error_t SrsAudioRecode::initialize()
|
|||
|
||||
dec_ = new SrsAudioDecoder("aac");
|
||||
if (!dec_) {
|
||||
return srs_error_wrap(err, "SrsAudioDecoder failed");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "SrsAudioDecoder failed");
|
||||
}
|
||||
dec_->initialize();
|
||||
|
||||
enc_ = new SrsAudioEncoder(dst_samplerate_, dst_channels_, 1, 1);
|
||||
if (!enc_) {
|
||||
return srs_error_wrap(err, "SrsAudioEncoder failed");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "SrsAudioEncoder failed");
|
||||
}
|
||||
enc_->initialize();
|
||||
|
||||
|
@ -394,12 +394,12 @@ srs_error_t SrsAudioRecode::recode(SrsSample *pkt, char **buf, int *buf_len, int
|
|||
static char encode_buffer[kPacketBufMax];
|
||||
|
||||
if (!dec_) {
|
||||
return srs_error_wrap(err, "dec_ nullptr");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "dec_ nullptr");
|
||||
}
|
||||
|
||||
int decode_len = kPacketBufMax;
|
||||
if ((err = dec_->decode(pkt, decode_buffer, decode_len)) != srs_success) {
|
||||
return srs_error_wrap(err, "decode error");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "decode error");
|
||||
}
|
||||
|
||||
if (!resample_) {
|
||||
|
@ -410,7 +410,7 @@ srs_error_t SrsAudioRecode::recode(SrsSample *pkt, char **buf, int *buf_len, int
|
|||
AV_SAMPLE_FMT_S16);
|
||||
|
||||
if (!resample_) {
|
||||
return srs_error_wrap(err, "SrsAudioResample failed");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "SrsAudioResample failed");
|
||||
}
|
||||
resample_->initialize();
|
||||
}
|
||||
|
@ -420,7 +420,7 @@ srs_error_t SrsAudioRecode::recode(SrsSample *pkt, char **buf, int *buf_len, int
|
|||
pcm.size = decode_len;
|
||||
int resample_len = kFrameBufMax;
|
||||
if ((err = resample_->resample(&pcm, resample_buffer, resample_len)) != srs_success) {
|
||||
return srs_error_wrap(err, "decode error");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "decode error");
|
||||
}
|
||||
|
||||
n = 0;
|
||||
|
@ -439,14 +439,14 @@ srs_error_t SrsAudioRecode::recode(SrsSample *pkt, char **buf, int *buf_len, int
|
|||
index += total - size_;
|
||||
size_ += total - size_;
|
||||
if (!enc_) {
|
||||
return srs_error_wrap(err, "enc_ nullptr");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "enc_ nullptr");
|
||||
}
|
||||
|
||||
int encode_len;
|
||||
pcm.bytes = (char *)data_;
|
||||
pcm.size = size_;
|
||||
if ((err = enc_->encode(&pcm, encode_buffer, encode_len)) != srs_success) {
|
||||
return srs_error_wrap(err, "decode error");
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "decode error");
|
||||
}
|
||||
|
||||
memcpy(buf[n], encode_buffer, encode_len);
|
||||
|
|
|
@ -143,6 +143,14 @@ srs_error_t SrsUdpListener::cycle()
|
|||
if ((nread = srs_recvfrom(lfd, buf, nb_buf, (sockaddr*)&from, &nb_from, SRS_UTIME_NO_TIMEOUT)) <= 0) {
|
||||
return srs_error_new(ERROR_SOCKET_READ, "udp read, nread=%d", nread);
|
||||
}
|
||||
|
||||
// Drop UDP health check packet of Aliyun SLB.
|
||||
// Healthcheck udp check
|
||||
// @see https://help.aliyun.com/document_detail/27595.html
|
||||
if (nread == 21 && buf[0] == 0x48 && buf[1] == 0x65 && buf[2] == 0x61 && buf[3] == 0x6c
|
||||
&& buf[19] == 0x63 && buf[20] == 0x6b) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((err = handler->on_udp_packet((const sockaddr*)&from, nb_from, buf, nread)) != srs_success) {
|
||||
return srs_error_wrap(err, "handle packet %d bytes", nread);
|
||||
|
@ -259,7 +267,16 @@ int SrsUdpMuxSocket::recvfrom(srs_utime_t timeout)
|
|||
fromlen = sizeof(from);
|
||||
nread = srs_recvfrom(lfd, buf, nb_buf, (sockaddr*)&from, &fromlen, timeout);
|
||||
|
||||
// Drop UDP health check packet of Aliyun SLB.
|
||||
// Healthcheck udp check
|
||||
// @see https://help.aliyun.com/document_detail/27595.html
|
||||
if (nread == 21 && buf[0] == 0x48 && buf[1] == 0x65 && buf[2] == 0x61 && buf[3] == 0x6c
|
||||
&& buf[19] == 0x63 && buf[20] == 0x6b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nread > 0) {
|
||||
// TODO: FIXME: Maybe we should not covert to string for each packet.
|
||||
char address_string[64];
|
||||
char port_string[16];
|
||||
if (getnameinfo((sockaddr*)&from, fromlen,
|
||||
|
@ -267,7 +284,7 @@ int SrsUdpMuxSocket::recvfrom(srs_utime_t timeout)
|
|||
(char*)&port_string, sizeof(port_string),
|
||||
NI_NUMERICHOST|NI_NUMERICSERV)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
peer_ip = std::string(address_string);
|
||||
peer_port = atoi(port_string);
|
||||
|
@ -392,15 +409,18 @@ srs_error_t SrsUdpMuxListener::cycle()
|
|||
|
||||
SrsUdpMuxSocket udp_mux_skt(lfd);
|
||||
|
||||
if (udp_mux_skt.recvfrom(SRS_UTIME_NO_TIMEOUT) <= 0) {
|
||||
srs_error("udp recv error");
|
||||
int nread = udp_mux_skt.recvfrom(SRS_UTIME_NO_TIMEOUT);
|
||||
if (nread <= 0) {
|
||||
if (nread < 0) {
|
||||
srs_warn("udp recv error");
|
||||
}
|
||||
// remux udp never return
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((err = handler->on_udp_packet(&udp_mux_skt)) != srs_success) {
|
||||
// remux udp never return
|
||||
srs_error("udp packet handler error:%s", srs_error_desc(err).c_str());
|
||||
srs_warn("udp packet handler error:%s", srs_error_desc(err).c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -327,14 +327,14 @@ SrsRtpOpusMuxer::SrsRtpOpusMuxer()
|
|||
{
|
||||
sequence = 0;
|
||||
timestamp = 0;
|
||||
recoder = NULL;
|
||||
transcode = NULL;
|
||||
}
|
||||
|
||||
SrsRtpOpusMuxer::~SrsRtpOpusMuxer()
|
||||
{
|
||||
if (recoder) {
|
||||
delete recoder;
|
||||
recoder = NULL;
|
||||
if (transcode) {
|
||||
delete transcode;
|
||||
transcode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,11 +342,11 @@ srs_error_t SrsRtpOpusMuxer::initialize()
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
recoder = new SrsAudioRecode(kChannel, kSamplerate);
|
||||
if (!recoder) {
|
||||
return srs_error_wrap(err, "SrsAacOpus init failed");
|
||||
transcode = new SrsAudioRecode(kChannel, kSamplerate);
|
||||
if (!transcode) {
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "SrsAacOpus init failed");
|
||||
}
|
||||
recoder->initialize();
|
||||
transcode->initialize();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -370,7 +370,7 @@ srs_error_t SrsRtpOpusMuxer::frame_to_packet(SrsSharedPtrMessage* shared_audio,
|
|||
pkt.bytes = stream->data();
|
||||
pkt.size = stream->pos();
|
||||
|
||||
if ((err = recoder->recode(&pkt, data_ptr, elen, number)) != srs_success) {
|
||||
if ((err = transcode->recode(&pkt, data_ptr, elen, number)) != srs_success) {
|
||||
return srs_error_wrap(err, "recode error");
|
||||
}
|
||||
|
||||
|
@ -467,11 +467,11 @@ srs_error_t SrsRtc::initialize(SrsOriginHub* h, SrsRequest* r)
|
|||
discard_aac = _srs_config->get_rtc_aac_discard(req->vhost);
|
||||
|
||||
rtp_opus_muxer = new SrsRtpOpusMuxer();
|
||||
if (rtp_opus_muxer) {
|
||||
rtp_opus_muxer->initialize();
|
||||
if (!rtp_opus_muxer) {
|
||||
return srs_error_wrap(err, "rtp_opus_muxer nullptr");
|
||||
}
|
||||
|
||||
return err;
|
||||
return rtp_opus_muxer->initialize();
|
||||
}
|
||||
|
||||
srs_error_t SrsRtc::on_publish()
|
||||
|
@ -547,7 +547,7 @@ srs_error_t SrsRtc::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* forma
|
|||
}
|
||||
|
||||
if (stream) {
|
||||
rtp_opus_muxer->frame_to_packet(shared_audio, format, stream);
|
||||
return rtp_opus_muxer->frame_to_packet(shared_audio, format, stream);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
|
@ -89,7 +89,7 @@ private:
|
|||
// TODO: FIXME: How to handle timestamp overflow?
|
||||
uint32_t timestamp;
|
||||
uint16_t sequence;
|
||||
SrsAudioRecode* recoder;
|
||||
SrsAudioRecode* transcode;
|
||||
public:
|
||||
SrsRtpOpusMuxer();
|
||||
virtual ~SrsRtpOpusMuxer();
|
||||
|
|
|
@ -810,6 +810,13 @@ srs_error_t SrsRtcSession::check_source()
|
|||
return err;
|
||||
}
|
||||
|
||||
#ifdef SRS_AUTO_OSX
|
||||
// These functions are similar to the older byteorder(3) family of functions.
|
||||
// For example, be32toh() is identical to ntohl().
|
||||
// @see https://linux.die.net/man/3/be32toh
|
||||
#define be32toh ntohl
|
||||
#endif
|
||||
|
||||
srs_error_t SrsRtcSession::on_binding_request(SrsUdpMuxSocket* udp_mux_skt, SrsStunPacket* stun_req)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
|
|
@ -2744,7 +2744,7 @@ SrsMp4DataEntryBox* SrsMp4DataReferenceBox::entry_at(int index)
|
|||
return entries.at(index);
|
||||
}
|
||||
|
||||
SrsMp4DataReferenceBox* SrsMp4DataReferenceBox::append(SrsMp4DataEntryBox* v)
|
||||
SrsMp4DataReferenceBox* SrsMp4DataReferenceBox::append2(SrsMp4DataEntryBox* v)
|
||||
{
|
||||
entries.push_back(v);
|
||||
return this;
|
||||
|
@ -3765,7 +3765,7 @@ SrsMp4SampleEntry* SrsMp4SampleDescriptionBox::entrie_at(int index)
|
|||
return entries.at(index);
|
||||
}
|
||||
|
||||
SrsMp4SampleDescriptionBox* SrsMp4SampleDescriptionBox::append(SrsMp4SampleEntry* v)
|
||||
SrsMp4SampleDescriptionBox* SrsMp4SampleDescriptionBox::append2(SrsMp4SampleEntry* v)
|
||||
{
|
||||
entries.push_back(v);
|
||||
return this;
|
||||
|
|
|
@ -1173,7 +1173,7 @@ public:
|
|||
public:
|
||||
virtual uint32_t entry_count();
|
||||
virtual SrsMp4DataEntryBox* entry_at(int index);
|
||||
virtual SrsMp4DataReferenceBox* append(SrsMp4DataEntryBox* v);
|
||||
virtual SrsMp4DataReferenceBox* append2(SrsMp4DataEntryBox* v);
|
||||
protected:
|
||||
virtual int nb_header();
|
||||
virtual srs_error_t encode_header(SrsBuffer* buf);
|
||||
|
@ -1520,7 +1520,7 @@ public:
|
|||
public:
|
||||
virtual uint32_t entry_count();
|
||||
virtual SrsMp4SampleEntry* entrie_at(int index);
|
||||
virtual SrsMp4SampleDescriptionBox* append(SrsMp4SampleEntry* v);
|
||||
virtual SrsMp4SampleDescriptionBox* append2(SrsMp4SampleEntry* v);
|
||||
protected:
|
||||
virtual int nb_header();
|
||||
virtual srs_error_t encode_header(SrsBuffer* buf);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue