mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
RTC: Refine FFmpeg opus audio noisy issue. v5.0.197 v6.0.97 (#3852)
### Description When converting between AAC and Opus formats (aac2opus or opus2aac), the `av_frame_get_buffer` API is frequently called. ### Objective The goal is to optimize the code logic and reduce the frequent allocation and deallocation of memory. In the case of aac2opus, av_frame_get_buffer is still frequently called. In the case of opus2aac, the goal is to avoid calling av_frame_get_buffer and reduce memory allocations. ### Additional Note Before calling the `av_audio_fifo_read` API, use `av_frame_make_writable` to check if the frame is writable. If it is not writable, create a new frame. --------- Co-authored-by: john <hondaxiao@tencent.com>
This commit is contained in:
parent
4a100616fc
commit
e7b629cd39
10 changed files with 27 additions and 24 deletions
|
@ -260,6 +260,13 @@ srs_error_t SrsAudioTranscoder::init_enc(SrsAudioCodecId dst_codec, int dst_chan
|
|||
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_) {
|
||||
|
@ -381,26 +388,21 @@ srs_error_t SrsAudioTranscoder::encode(std::vector<SrsAudioFrame*> &pkts)
|
|||
}
|
||||
|
||||
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");
|
||||
// make sure the frame is writable
|
||||
if (av_frame_make_writable(enc_frame_) < 0) {
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "Could not make writable frame");
|
||||
}
|
||||
|
||||
/* 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_;
|
||||
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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue