Skip to content

Commit

Permalink
RTC: Fix FFmpeg opus audio noisy issue
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaozhihong committed Oct 21, 2023
1 parent 4e7c075 commit 00027b6
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 29 deletions.
55 changes: 27 additions & 28 deletions trunk/src/app/srs_app_rtc_codec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ SrsAudioTranscoder::SrsAudioTranscoder()
dec_frame_ = NULL;
dec_packet_ = NULL;
enc_ = NULL;
enc_frame_ = NULL;
enc_packet_ = NULL;
swr_ = NULL;
swr_data_ = NULL;
Expand Down Expand Up @@ -123,10 +122,6 @@ SrsAudioTranscoder::~SrsAudioTranscoder()
avcodec_free_context(&enc_);
}

if (enc_frame_) {
av_frame_free(&enc_frame_);
}

if (enc_packet_) {
av_packet_free(&enc_packet_);
}
Expand Down Expand Up @@ -242,7 +237,7 @@ srs_error_t SrsAudioTranscoder::init_enc(SrsAudioCodecId dst_codec, int dst_chan
enc_->channel_layout = av_get_default_channel_layout(dst_channels);
enc_->bit_rate = dst_bit_rate;
enc_->sample_fmt = codec->sample_fmts[0];
enc_->time_base.num = 1; enc_->time_base.den = 1000; // {1, 1000}
enc_->time_base.num = 1; enc_->time_base.den = dst_samplerate; // {1, dst_samplerate}
if (dst_codec == SrsAudioCodecIdOpus) {
//TODO: for more level setting
enc_->compression_level = 1;
Expand All @@ -256,19 +251,6 @@ srs_error_t SrsAudioTranscoder::init_enc(SrsAudioCodecId dst_codec, int dst_chan
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not open codec");
}

enc_frame_ = av_frame_alloc();
if (!enc_frame_) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not allocate audio encode in frame");
}

enc_frame_->format = enc_->sample_fmt;
enc_frame_->nb_samples = enc_->frame_size;
enc_frame_->channel_layout = enc_->channel_layout;

if (av_frame_get_buffer(enc_frame_, 0) < 0) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not get audio frame buffer");
}

enc_packet_ = av_packet_alloc();
if (!enc_packet_) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not allocate audio encode out packet");
Expand Down Expand Up @@ -380,25 +362,40 @@ srs_error_t SrsAudioTranscoder::encode(std::vector<SrsAudioFrame*> &pkts)
if (next_out_pts_ == AV_NOPTS_VALUE) {
next_out_pts_ = new_pkt_pts_;
} else {
int64_t diff = llabs(new_pkt_pts_ - next_out_pts_);
int64_t diff = llabs(new_pkt_pts_ - av_rescale(next_out_pts_, 1000, enc_->time_base.den));
if (diff > 1000) {
srs_trace("time diff to large=%lld, next out=%lld, new pkt=%lld, set to new pkt",
diff, next_out_pts_, new_pkt_pts_);
next_out_pts_ = new_pkt_pts_;
next_out_pts_ = av_rescale(new_pkt_pts_, enc_->time_base.den, 1000);
}
}

int frame_cnt = 0;
while (av_audio_fifo_size(fifo_) >= enc_->frame_size) {
AVFrame* enc_frame = av_frame_alloc();
if (!enc_frame) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not allocate audio encode in frame");
}

enc_frame->format = enc_->sample_fmt;
enc_frame->nb_samples = enc_->frame_size;
enc_frame->channel_layout = enc_->channel_layout;

if (av_frame_get_buffer(enc_frame, 0) < 0) {
av_frame_free(&enc_frame);
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not get audio frame buffer");
}

/* Read as many samples from the FIFO buffer as required to fill the frame.
* The samples are stored in the frame temporarily. */
if (av_audio_fifo_read(fifo_, (void **)enc_frame_->data, enc_->frame_size) < enc_->frame_size) {
if (av_audio_fifo_read(fifo_, (void **)enc_frame->data, enc_->frame_size) < enc_->frame_size) {
av_frame_free(&enc_frame);
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not read data from FIFO");
}
/* send the frame for encoding */
enc_frame_->pts = next_out_pts_ + av_rescale(enc_->frame_size * frame_cnt, 1000, enc_->sample_rate);
++frame_cnt;
int error = avcodec_send_frame(enc_, enc_frame_);
enc_frame->pts = next_out_pts_;
next_out_pts_ += enc_->frame_size;
int error = avcodec_send_frame(enc_, enc_frame);
av_frame_free(&enc_frame);
if (error < 0) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "Error sending the frame to the encoder(%d,%s)", error,
av_make_error_string(err_buf, AV_ERROR_MAX_STRING_SIZE, error));
Expand All @@ -419,6 +416,10 @@ srs_error_t SrsAudioTranscoder::encode(std::vector<SrsAudioFrame*> &pkts)
av_make_error_string(err_buf, AV_ERROR_MAX_STRING_SIZE, error));
}

// rescale time base from sample_rate 1000.
enc_packet_->dts = av_rescale(enc_packet_->dts, 1000, enc_->time_base.den);
enc_packet_->pts = av_rescale(enc_packet_->pts, 1000, enc_->time_base.den);

SrsAudioFrame *out_frame = new SrsAudioFrame;
char *buf = new char[enc_packet_->size];
memcpy(buf, enc_packet_->data, enc_packet_->size);
Expand All @@ -429,8 +430,6 @@ srs_error_t SrsAudioTranscoder::encode(std::vector<SrsAudioFrame*> &pkts)
}
}

next_out_pts_ += av_rescale(enc_->frame_size * frame_cnt, 1000, enc_->sample_rate);

return srs_success;
}

Expand Down
1 change: 0 additions & 1 deletion trunk/src/app/srs_app_rtc_codec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class SrsAudioTranscoder
AVPacket *dec_packet_;

AVCodecContext *enc_;
AVFrame *enc_frame_;
AVPacket *enc_packet_;

SwrContext *swr_;
Expand Down

0 comments on commit 00027b6

Please sign in to comment.