mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 20:58:07 +03:00
parent
3696e84925
commit
0ba717edd5
1 changed files with 33 additions and 18 deletions
|
@ -148,34 +148,49 @@ static int64_t M_SeekAVBuffer(void *opaque, int64_t offset, int32_t whence)
|
||||||
static int32_t M_OutputAudioFrame(
|
static int32_t M_OutputAudioFrame(
|
||||||
M_SWR_CONTEXT *const swr, AVFrame *const frame)
|
M_SWR_CONTEXT *const swr, AVFrame *const frame)
|
||||||
{
|
{
|
||||||
|
// Determine the maximum number of output samples this call can produce,
|
||||||
|
// based on the current delay already inside the resampler plus the new
|
||||||
|
// input. Using av_rescale_rnd() keeps everything in integer domain and
|
||||||
|
// avoids cumulative rounding errors.
|
||||||
|
const int64_t delay = swr_get_delay(swr->ctx, swr->src.sample_rate);
|
||||||
|
const int32_t out_samples = (int32_t)av_rescale_rnd(
|
||||||
|
delay + frame->nb_samples, swr->dst.sample_rate, swr->src.sample_rate,
|
||||||
|
AV_ROUND_UP);
|
||||||
|
if (out_samples <= 0) {
|
||||||
|
return 0; // nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t *out_buffer = nullptr;
|
uint8_t *out_buffer = nullptr;
|
||||||
const int32_t out_samples =
|
if (av_samples_alloc(
|
||||||
swr_get_out_samples(swr->ctx, frame->nb_samples);
|
&out_buffer, nullptr, swr->dst.ch_layout.nb_channels, out_samples,
|
||||||
av_samples_alloc(
|
swr->dst.format, 1)
|
||||||
&out_buffer, nullptr, swr->dst.ch_layout.nb_channels, out_samples,
|
< 0) {
|
||||||
swr->dst.format, 1);
|
return AVERROR(ENOMEM);
|
||||||
int32_t resampled_size = swr_convert(
|
}
|
||||||
|
|
||||||
|
// Convert – we do *not* drain the resampler here.
|
||||||
|
const int32_t converted = swr_convert(
|
||||||
swr->ctx, &out_buffer, out_samples, (const uint8_t **)frame->data,
|
swr->ctx, &out_buffer, out_samples, (const uint8_t **)frame->data,
|
||||||
frame->nb_samples);
|
frame->nb_samples);
|
||||||
while (resampled_size > 0) {
|
|
||||||
int32_t out_buffer_size = av_samples_get_buffer_size(
|
|
||||||
nullptr, swr->dst.ch_layout.nb_channels, resampled_size,
|
|
||||||
swr->dst.format, 1);
|
|
||||||
|
|
||||||
|
if (converted < 0) {
|
||||||
|
av_freep(&out_buffer);
|
||||||
|
return converted; // propagate error
|
||||||
|
}
|
||||||
|
|
||||||
|
if (converted > 0) {
|
||||||
|
const int32_t out_buffer_size = av_samples_get_buffer_size(
|
||||||
|
nullptr, swr->dst.ch_layout.nb_channels, converted, swr->dst.format,
|
||||||
|
1);
|
||||||
if (out_buffer_size > 0) {
|
if (out_buffer_size > 0) {
|
||||||
swr->working_buffer = Memory_Realloc(
|
swr->working_buffer = Memory_Realloc(
|
||||||
swr->working_buffer,
|
swr->working_buffer,
|
||||||
swr->working_buffer_size + out_buffer_size);
|
swr->working_buffer_size + out_buffer_size);
|
||||||
if (out_buffer) {
|
memcpy(
|
||||||
memcpy(
|
swr->working_buffer + swr->working_buffer_size, out_buffer,
|
||||||
swr->working_buffer + swr->working_buffer_size, out_buffer,
|
out_buffer_size);
|
||||||
out_buffer_size);
|
|
||||||
}
|
|
||||||
swr->working_buffer_size += out_buffer_size;
|
swr->working_buffer_size += out_buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
resampled_size =
|
|
||||||
swr_convert(swr->ctx, &out_buffer, out_samples, nullptr, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
av_freep(&out_buffer);
|
av_freep(&out_buffer);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue