mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
RTC: Fix FFmpeg opus audio noisy issue. v5.0.195 v6.0.95 (#3845)
Follow the example in FFmpeg's doc, before calling the API `avcodec_send_frame`, always use `av_frame_alloc` to create a new frame. --------- Co-authored-by: Haibo Chen <495810242@qq.com>
This commit is contained in:
parent
9b07d840ed
commit
9238f09b0b
10 changed files with 119 additions and 23 deletions
|
@ -242,7 +242,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;
|
||||
|
@ -261,14 +261,6 @@ srs_error_t SrsAudioTranscoder::init_enc(SrsAudioCodecId dst_codec, int dst_chan
|
|||
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");
|
||||
|
@ -380,25 +372,35 @@ 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) {
|
||||
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) {
|
||||
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;
|
||||
enc_frame_->pts = next_out_pts_;
|
||||
next_out_pts_ += enc_->frame_size;
|
||||
int error = avcodec_send_frame(enc_, enc_frame_);
|
||||
av_frame_unref(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));
|
||||
|
@ -419,6 +421,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);
|
||||
|
@ -429,8 +435,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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue