MT#55283 amend resample_frame() semantics

In many transcoding scenarios resampling is not actually required. We
can shortcut the operation by just returning the original frame, instead
of a cloned and newly allocated one. We just need to distinguish between
the cases to determine whether the frame returned by resample_frame()
needs to be freed.

Change-Id: I3f36a46bd3b967f140c8353119fdb24ad8363c15
pull/1897/head
Richard Fuchs 1 year ago
parent 461f663e58
commit acc30ec0fa

@ -4180,6 +4180,7 @@ static void __dtmf_detect(struct codec_ssrc_handler *ch, AVFrame *frame) {
num_samples = ret; num_samples = ret;
} }
ch->dtmf_ts = dsp_frame->pts + dsp_frame->nb_samples; ch->dtmf_ts = dsp_frame->pts + dsp_frame->nb_samples;
if (dsp_frame != frame)
av_frame_free(&dsp_frame); av_frame_free(&dsp_frame);
} }

@ -1238,6 +1238,7 @@ static int __decoder_input_data(decoder_t *dec, const str *data, unsigned long t
if (callback(dec, rsmp_frame, u1, u2)) if (callback(dec, rsmp_frame, u1, u2))
ret = -1; ret = -1;
} }
if (rsmp_frame != frame)
av_frame_free(&frame); av_frame_free(&frame);
} }
@ -2158,6 +2159,7 @@ int encoder_input_fifo(encoder_t *enc, AVFrame *frame,
} }
if (av_audio_fifo_write(enc->fifo, (void **) rsmp_frame->extended_data, rsmp_frame->nb_samples) < 0) if (av_audio_fifo_write(enc->fifo, (void **) rsmp_frame->extended_data, rsmp_frame->nb_samples) < 0)
return -1; return -1;
if (rsmp_frame != frame)
av_frame_free(&rsmp_frame); av_frame_free(&rsmp_frame);
return encoder_fifo_flush(enc, callback, u1, u2); return encoder_fifo_flush(enc, callback, u1, u2);

@ -31,7 +31,7 @@ AVFrame *resample_frame(resample_t *resample, AVFrame *frame, const format_t *to
if (!CH_LAYOUT_EQ(frame->CH_LAYOUT, to_channel_layout)) if (!CH_LAYOUT_EQ(frame->CH_LAYOUT, to_channel_layout))
goto resample; goto resample;
return av_frame_clone(frame); return frame;
resample: resample:

@ -121,13 +121,16 @@ static int decoder_got_frame(decoder_t *dec, AVFrame *frame, void *sp, void *dp)
goto no_mix_out; goto no_mix_out;
mix_config(metafile->mix, &actual_format); mix_config(metafile->mix, &actual_format);
// XXX might be a second resampling to same format // XXX might be a second resampling to same format
AVFrame *dec_frame = resample_frame(&deco->mix_resampler, frame, &actual_format); AVFrame *copy_frame = av_frame_clone(frame);
AVFrame *dec_frame = resample_frame(&deco->mix_resampler, copy_frame, &actual_format);
if (!dec_frame) { if (!dec_frame) {
pthread_mutex_unlock(&metafile->mix_lock); pthread_mutex_unlock(&metafile->mix_lock);
goto err; goto err;
} }
if (mix_add(metafile->mix, dec_frame, deco->mixer_idx, ssrc, metafile->mix_out)) if (mix_add(metafile->mix, dec_frame, deco->mixer_idx, ssrc, metafile->mix_out))
ilog(LOG_ERR, "Failed to add decoded packet to mixed output"); ilog(LOG_ERR, "Failed to add decoded packet to mixed output");
if (dec_frame != copy_frame)
av_frame_free(&copy_frame);
} }
no_mix_out: no_mix_out:
pthread_mutex_unlock(&metafile->mix_lock); pthread_mutex_unlock(&metafile->mix_lock);
@ -183,6 +186,7 @@ no_recording:
int linesize = av_get_bytes_per_sample(dec_frame->format) * dec_frame->nb_samples; int linesize = av_get_bytes_per_sample(dec_frame->format) * dec_frame->nb_samples;
dbg("Writing %u bytes PCM to TLS", linesize); dbg("Writing %u bytes PCM to TLS", linesize);
streambuf_write(ssrc->tls_fwd_stream, (char *) dec_frame->extended_data[0], linesize); streambuf_write(ssrc->tls_fwd_stream, (char *) dec_frame->extended_data[0], linesize);
if (dec_frame != frame)
av_frame_free(&dec_frame); av_frame_free(&dec_frame);
} }

@ -393,6 +393,7 @@ int mix_add(mix_t *mix, AVFrame *frame, unsigned int idx, void *ptr, output_t *o
ret = output_add(output, frame); ret = output_add(output, frame);
av_frame_unref(mix->sink_frame); av_frame_unref(mix->sink_frame);
if (frame != mix->sink_frame)
av_frame_free(&frame); av_frame_free(&frame);
if (ret) if (ret)

Loading…
Cancel
Save