diff options
Diffstat (limited to 'audio')
30 files changed, 571 insertions, 382 deletions
diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index 08b789a709..39cd74cd2a 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -17,7 +17,6 @@ #include <stdio.h> #include <stdlib.h> -#include <unistd.h> #include <stdbool.h> #include <assert.h> @@ -44,6 +43,7 @@ #include "options/options.h" struct priv { + struct mp_codec_params *codec; AVCodecContext *avctx; AVFrame *avframe; AVPacket *avpkt; @@ -156,7 +156,7 @@ static bool init(struct mp_filter *da, struct mp_codec_params *codec, return true; } -static void destroy(struct mp_filter *da) +static void ad_lavc_destroy(struct mp_filter *da) { struct priv *ctx = da->priv; @@ -165,7 +165,7 @@ static void destroy(struct mp_filter *da) mp_free_av_packet(&ctx->avpkt); } -static void reset(struct mp_filter *da) +static void ad_lavc_reset(struct mp_filter *da) { struct priv *ctx = da->priv; @@ -219,6 +219,8 @@ static int receive_frame(struct mp_filter *da, struct mp_frame *out) if (!priv->avframe->buf[0]) return ret; + mp_codec_info_from_av(avctx, priv->codec); + double out_pts = mp_pts_from_av(priv->avframe->pts, &priv->codec_timebase); struct mp_aframe *mpframe = mp_aframe_from_avframe(priv->avframe); @@ -276,7 +278,7 @@ static int receive_frame(struct mp_filter *da, struct mp_frame *out) return ret; } -static void process(struct mp_filter *ad) +static void ad_lavc_process(struct mp_filter *ad) { struct priv *priv = ad->priv; @@ -286,9 +288,9 @@ static void process(struct mp_filter *ad) static const struct mp_filter_info ad_lavc_filter = { .name = "ad_lavc", .priv_size = sizeof(struct priv), - .process = process, - .reset = reset, - .destroy = destroy, + .process = ad_lavc_process, + .reset = ad_lavc_reset, + .destroy = ad_lavc_destroy, }; static struct mp_decoder *create(struct mp_filter *parent, @@ -305,12 +307,16 @@ static struct mp_decoder *create(struct mp_filter *parent, da->log = mp_log_new(da, parent->log, NULL); struct priv *priv = da->priv; + priv->codec = codec; priv->public.f = da; if (!init(da, codec, decoder)) { talloc_free(da); return NULL; } + + codec->codec_desc = priv->avctx->codec_descriptor->long_name; + return &priv->public; } diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c index a8e77b4e99..1d9e9711fe 100644 --- a/audio/decode/ad_spdif.c +++ b/audio/decode/ad_spdif.c @@ -79,7 +79,7 @@ static int write_packet(void *p, const uint8_t *buf, int buf_size) } // (called on both filter destruction _and_ if lavf fails to init) -static void destroy(struct mp_filter *da) +static void ad_spdif_destroy(struct mp_filter *da) { struct spdifContext *spdif_ctx = da->priv; AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx; @@ -89,7 +89,7 @@ static void destroy(struct mp_filter *da) av_write_trailer(lavf_ctx); if (lavf_ctx->pb) av_freep(&lavf_ctx->pb->buffer); - av_freep(&lavf_ctx->pb); + avio_context_free(&lavf_ctx->pb); avformat_free_context(lavf_ctx); spdif_ctx->lavf_ctx = NULL; } @@ -181,7 +181,7 @@ static int init_filter(struct mp_filter *da) goto fail; void *buffer = av_mallocz(OUTBUF_SIZE); - MP_HANDLE_OOM(buffer); + MP_HANDLE_OOM(buffer); lavf_ctx->pb = avio_alloc_context(buffer, OUTBUF_SIZE, 1, spdif_ctx, NULL, write_packet, NULL); if (!lavf_ctx->pb) { @@ -196,7 +196,8 @@ static int init_filter(struct mp_filter *da) if (!stream) goto fail; - stream->codecpar->codec_id = spdif_ctx->codec_id; + stream->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; + stream->codecpar->codec_id = spdif_ctx->codec_id; AVDictionary *format_opts = NULL; @@ -260,6 +261,8 @@ static int init_filter(struct mp_filter *da) abort(); } + stream->codecpar->sample_rate = samplerate; + struct mp_chmap chmap; mp_chmap_from_channels(&chmap, num_channels); mp_aframe_set_chmap(spdif_ctx->fmt, &chmap); @@ -280,12 +283,12 @@ static int init_filter(struct mp_filter *da) return 0; fail: - destroy(da); + ad_spdif_destroy(da); mp_filter_internal_mark_failed(da); return -1; } -static void process(struct mp_filter *da) +static void ad_spdif_process(struct mp_filter *da) { struct spdifContext *spdif_ctx = da->priv; @@ -410,8 +413,8 @@ struct mp_decoder_list *select_spdif_codec(const char *codec, const char *pref) static const struct mp_filter_info ad_spdif_filter = { .name = "ad_spdif", .priv_size = sizeof(struct spdifContext), - .process = process, - .destroy = destroy, + .process = ad_spdif_process, + .destroy = ad_spdif_destroy, }; static struct mp_decoder *create(struct mp_filter *parent, diff --git a/audio/filter/af_drop.c b/audio/filter/af_drop.c index 724c482720..499389dd2b 100644 --- a/audio/filter/af_drop.c +++ b/audio/filter/af_drop.c @@ -11,7 +11,7 @@ struct priv { struct mp_aframe *last; // for repeating }; -static void process(struct mp_filter *f) +static void af_drop_process(struct mp_filter *f) { struct priv *p = f->priv; @@ -52,7 +52,7 @@ static void process(struct mp_filter *f) mp_pin_in_write(f->ppins[1], frame); } -static bool command(struct mp_filter *f, struct mp_filter_command *cmd) +static bool af_drop_command(struct mp_filter *f, struct mp_filter_command *cmd) { struct priv *p = f->priv; @@ -65,7 +65,7 @@ static bool command(struct mp_filter *f, struct mp_filter_command *cmd) return false; } -static void reset(struct mp_filter *f) +static void af_drop_reset(struct mp_filter *f) { struct priv *p = f->priv; @@ -73,18 +73,18 @@ static void reset(struct mp_filter *f) p->diff = 0; } -static void destroy(struct mp_filter *f) +static void af_drop_destroy(struct mp_filter *f) { - reset(f); + af_drop_reset(f); } static const struct mp_filter_info af_drop_filter = { .name = "drop", .priv_size = sizeof(struct priv), - .process = process, - .command = command, - .reset = reset, - .destroy = destroy, + .process = af_drop_process, + .command = af_drop_command, + .reset = af_drop_reset, + .destroy = af_drop_destroy, }; static struct mp_filter *af_drop_create(struct mp_filter *parent, void *options) diff --git a/audio/filter/af_format.c b/audio/filter/af_format.c index 2d1c1cc97d..eddce6422f 100644 --- a/audio/filter/af_format.c +++ b/audio/filter/af_format.c @@ -38,7 +38,7 @@ struct priv { struct mp_pin *in_pin; }; -static void process(struct mp_filter *f) +static void af_format_process(struct mp_filter *f) { struct priv *p = f->priv; @@ -85,7 +85,7 @@ error: static const struct mp_filter_info af_format_filter = { .name = "format", .priv_size = sizeof(struct priv), - .process = process, + .process = af_format_process, }; static struct mp_filter *af_format_create(struct mp_filter *parent, diff --git a/audio/filter/af_lavcac3enc.c b/audio/filter/af_lavcac3enc.c index ec3330f17b..def9700d18 100644 --- a/audio/filter/af_lavcac3enc.c +++ b/audio/filter/af_lavcac3enc.c @@ -139,18 +139,18 @@ static bool reinit(struct mp_filter *f) return true; } -static void reset(struct mp_filter *f) +static void af_lavcac3enc_reset(struct mp_filter *f) { struct priv *s = f->priv; TA_FREEP(&s->in_frame); } -static void destroy(struct mp_filter *f) +static void af_lavcac3enc_destroy(struct mp_filter *f) { struct priv *s = f->priv; - reset(f); + af_lavcac3enc_reset(f); av_packet_free(&s->lavc_pkt); avcodec_free_context(&s->lavc_actx); } @@ -161,7 +161,7 @@ static void swap_16(uint16_t *ptr, size_t size) ptr[n] = av_bswap16(ptr[n]); } -static void process(struct mp_filter *f) +static void af_lavcac3enc_process(struct mp_filter *f) { struct priv *s = f->priv; @@ -281,9 +281,9 @@ error: static const struct mp_filter_info af_lavcac3enc_filter = { .name = "lavcac3enc", .priv_size = sizeof(struct priv), - .process = process, - .reset = reset, - .destroy = destroy, + .process = af_lavcac3enc_process, + .reset = af_lavcac3enc_reset, + .destroy = af_lavcac3enc_destroy, }; static void add_chmaps_to_autoconv(struct mp_filter *f, diff --git a/audio/filter/af_rubberband.c b/audio/filter/af_rubberband.c index 48e5cc1e86..e71937fcb2 100644 --- a/audio/filter/af_rubberband.c +++ b/audio/filter/af_rubberband.c @@ -105,7 +105,7 @@ static bool init_rubberband(struct mp_filter *f) return true; } -static void process(struct mp_filter *f) +static void af_rubberband_process(struct mp_filter *f) { struct priv *p = f->priv; @@ -233,7 +233,7 @@ error: mp_filter_internal_mark_failed(f); } -static bool command(struct mp_filter *f, struct mp_filter_command *cmd) +static bool af_rubberband_command(struct mp_filter *f, struct mp_filter_command *cmd) { struct priv *p = f->priv; @@ -263,7 +263,7 @@ static bool command(struct mp_filter *f, struct mp_filter_command *cmd) return false; } -static void reset(struct mp_filter *f) +static void af_rubberband_reset(struct mp_filter *f) { struct priv *p = f->priv; @@ -274,7 +274,7 @@ static void reset(struct mp_filter *f) TA_FREEP(&p->pending); } -static void destroy(struct mp_filter *f) +static void af_rubberband_destroy(struct mp_filter *f) { struct priv *p = f->priv; @@ -286,10 +286,10 @@ static void destroy(struct mp_filter *f) static const struct mp_filter_info af_rubberband_filter = { .name = "rubberband", .priv_size = sizeof(struct priv), - .process = process, - .command = command, - .reset = reset, - .destroy = destroy, + .process = af_rubberband_process, + .command = af_rubberband_command, + .reset = af_rubberband_reset, + .destroy = af_rubberband_destroy, }; static struct mp_filter *af_rubberband_create(struct mp_filter *parent, diff --git a/audio/filter/af_scaletempo.c b/audio/filter/af_scaletempo.c index f06478f750..482b91209e 100644 --- a/audio/filter/af_scaletempo.c +++ b/audio/filter/af_scaletempo.c @@ -2,7 +2,7 @@ * scaletempo audio filter * * scale tempo while maintaining pitch - * (WSOLA technique with cross correlation) + * (WSOLA technique with taxicab distance) * inspired by SoundTouch library by Olli Parviainen * * basic algorithm @@ -35,6 +35,7 @@ #include <string.h> #include <limits.h> #include <assert.h> +#include <math.h> #include "audio/aframe.h" #include "audio/format.h" @@ -87,8 +88,6 @@ struct priv { // best overlap int frames_search; int num_channels; - void *buf_pre_corr; - void *table_window; int (*best_overlap_offset)(struct priv *s); }; @@ -135,72 +134,144 @@ static bool fill_queue(struct priv *s) return bytes_needed == 0; } -#define UNROLL_PADDING (4 * 4) +// Fit the curve f(x) = a * x^2 + b * x + c such that +// f(-1) = y[0] +// f(0) = y[1] +// f(1) = y[2] +// and return the extremum position and value +// assuming y[0] <= y[1] >= y[2] || y[0] >= y[1] <= y[2] +static void quadratic_interpolation_float( + const float* y_values, float* x, float* value) +{ + const float b = (y_values[2] - y_values[0]) * 0.5f; + const float c = y_values[1]; + const float a = y_values[0] + b - c; + + if (a == 0.f) { + // it's a flat line + *x = 0; + *value = c; + } else { + const float pos = -b / (2.f * a); + *x = pos; + *value = a * pos * pos + b * pos + c; + } +} + +static void quadratic_interpolation_s16( + const int32_t* y_values, float* x, int32_t* value) +{ + const float b = (y_values[2] - y_values[0]) * 0.5f; + const float c = y_values[1]; + const float a = y_values[0] + b - c; + + if (a == 0.f) { + // it's a flat line + *x = 0; + *value = c; + } else { + const float pos = -b / (2.f * a); + *x = pos; + *value = a * pos * pos + b * pos + c; + } +} static int best_overlap_offset_float(struct priv *s) { - float best_corr = INT_MIN; - int best_off = 0; - - float *pw = s->table_window; - float *po = s->buf_overlap; - po += s->num_channels; - float *ppc = s->buf_pre_corr; - for (int i = s->num_channels; i < s->samples_overlap; i++) - *ppc++ = *pw++ **po++; - - float *search_start = (float *)s->buf_queue + s->num_channels; - for (int off = 0; off < s->frames_search; off++) { - float corr = 0; - float *ps = search_start; - ppc = s->buf_pre_corr; - for (int i = s->num_channels; i < s->samples_overlap; i++) - corr += *ppc++ **ps++; - if (corr > best_corr) { - best_corr = corr; - best_off = off; + int num_channels = s->num_channels, frames_search = s->frames_search; + float *source = (float *)s->buf_queue + num_channels; + float *target = (float *)s->buf_overlap + num_channels; + int num_samples = s->samples_overlap - num_channels; + int step_size = 3; + float history[3] = {}; + + float best_distance = FLT_MAX; + int best_offset_approx = 0; + for (int offset = 0; offset < frames_search; offset += step_size) { + float distance = 0; + for (int i = 0; i < num_samples; i++) + distance += fabsf(target[i] - source[offset * num_channels + i]); + + int offset_approx = offset; + history[0] = history[1]; + history[1] = history[2]; + history[2] = distance; + if(offset >= 2 && history[0] >= history[1] && history[1] <= history[2]) { + float extremum; + quadratic_interpolation_float(history, &extremum, &distance); + offset_approx = offset - step_size + (int)(extremum * step_size + 0.5f); + } + + if (distance < best_distance) { + best_distance = distance; + best_offset_approx = offset_approx; + } + } + + best_distance = FLT_MAX; + int best_offset = 0; + int min_offset = MPMAX(0, best_offset_approx - step_size + 1); + int max_offset = MPMIN(frames_search, best_offset_approx + step_size); + for (int offset = min_offset; offset < max_offset; offset++) { + float distance = 0; + for (int i = 0; i < num_samples; i++) + distance += fabsf(target[i] - source[offset * num_channels + i]); + if (distance < best_distance) { + best_distance = distance; + best_offset = offset; } - search_start += s->num_channels; } - return best_off * 4 * s->num_channels; + return best_offset * 4 * num_channels; } static int best_overlap_offset_s16(struct priv *s) { - int64_t best_corr = INT64_MIN; - int best_off = 0; - - int32_t *pw = s->table_window; - int16_t *po = s->buf_overlap; - po += s->num_channels; - int32_t *ppc = s->buf_pre_corr; - for (long i = s->num_channels; i < s->samples_overlap; i++) - *ppc++ = (*pw++ **po++) >> 15; - - int16_t *search_start = (int16_t *)s->buf_queue + s->num_channels; - for (int off = 0; off < s->frames_search; off++) { - int64_t corr = 0; - int16_t *ps = search_start; - ppc = s->buf_pre_corr; - ppc += s->samples_overlap - s->num_channels; - ps += s->samples_overlap - s->num_channels; - long i = -(s->samples_overlap - s->num_channels); - do { - corr += ppc[i + 0] * (int64_t)ps[i + 0]; - corr += ppc[i + 1] * (int64_t)ps[i + 1]; - corr += ppc[i + 2] * (int64_t)ps[i + 2]; - corr += ppc[i + 3] * (int64_t)ps[i + 3]; - i += 4; - } while (i < 0); - if (corr > best_corr) { - best_corr = corr; - best_off = off; + int num_channels = s->num_channels, frames_search = s->frames_search; + int16_t *source = (int16_t *)s->buf_queue + num_channels; + int16_t *target = (int16_t *)s->buf_overlap + num_channels; + int num_samples = s->samples_overlap - num_channels; + int step_size = 3; + int32_t history[3] = {}; + + int32_t best_distance = INT32_MAX; + int best_offset_approx = 0; + for (int offset = 0; offset < frames_search; offset += step_size) { + int32_t distance = 0; + for (int i = 0; i < num_samples; i++) + distance += abs((int32_t)target[i] - source[offset * num_channels + i]); + + int offset_approx = offset; + history[0] = history[1]; + history[1] = history[2]; + history[2] = distance; + if(offset >= 2 && history[0] >= history[1] && history[1] <= history[2]) { + float extremum; + quadratic_interpolation_s16(history, &extremum, &distance); + offset_approx = offset - step_size + (int)(extremum * step_size + 0.5f); + } + + if (distance < best_distance) { + best_distance = distance; + best_offset_approx = offset_approx; } - search_start += s->num_channels; } - return best_off * 2 * s->num_channels; + best_distance = INT32_MAX; + int best_offset = 0; + int min_offset = MPMAX(0, best_offset_approx - step_size + 1); + int max_offset = MPMIN(frames_search, best_offset_approx + step_size); + for (int offset = min_offset; offset < max_offset; offset++) { + int32_t distance = 0; + for (int i = 0; i < num_samples; i++) + distance += abs((int32_t)target[i] - source[offset * num_channels + i]); + if (distance < best_distance) { + best_distance = distance; + best_offset = offset; + } + } + + return best_offset * 2 * s->num_channels; } static void output_overlap_float(struct priv *s, void *buf_out, @@ -211,8 +282,9 @@ static void output_overlap_float(struct priv *s, void *buf_out, float *po = s->buf_overlap; float *pin = (float *)(s->buf_queue + bytes_off); for (int i = 0; i < s->samples_overlap; i++) { - *pout++ = *po - *pb++ *(*po - *pin++); - po++; + // the math is equal to *po * (1 - *pb) + *pin * *pb + float o = *po++; + *pout++ = o - *pb++ * (o - *pin++); } } @@ -224,12 +296,13 @@ static void output_overlap_s16(struct priv *s, void *buf_out, int16_t *po = s->buf_overlap; int16_t *pin = (int16_t *)(s->buf_queue + bytes_off); for (int i = 0; i < s->samples_overlap; i++) { - *pout++ = *po - ((*pb++ *(*po - *pin++)) >> 16); - po++; + // the math is equal to *po * (1 - *pb) + *pin * *pb + int32_t o = *po++; + *pout++ = o - ((*pb++ *(o - *pin++)) >> 16); } } -static void process(struct mp_filter *f) +static void af_scaletempo_process(struct mp_filter *f) { struct priv *s = f->priv; @@ -420,18 +493,20 @@ static bool reinit(struct mp_filter *f) memset(s->buf_overlap, 0, s->bytes_overlap); if (use_int) { int32_t *pb = s->table_blend; - int64_t blend = 0; + const float scale = M_PI / frames_overlap; for (int i = 0; i < frames_overlap; i++) { - int32_t v = blend / frames_overlap; + // Hann function + const int32_t v = 0.5f * (1.0f - cosf(i * scale)) * 65536 + 0.5; for (int j = 0; j < nch; j++) *pb++ = v; - blend += 65536; // 2^16 } s->output_overlap = output_overlap_s16; } else { float *pb = s->table_blend; + const float scale = M_PI / frames_overlap; for (int i = 0; i < frames_overlap; i++) { - float v = i / (float)frames_overlap; + // Hann function + const float v = 0.5f * (1.0f - cosf(i * scale)); for (int j = 0; j < nch; j++) *pb++ = v; } @@ -444,39 +519,8 @@ static bool reinit(struct mp_filter *f) s->best_overlap_offset = NULL; else { if (use_int) { - int64_t t = frames_overlap; - int32_t n = 8589934588LL / (t * t); // 4 * (2^31 - 1) / t^2 - s->buf_pre_corr = realloc(s->buf_pre_corr, - s->bytes_overlap * 2 + UNROLL_PADDING); - s->table_window = realloc(s->table_window, - s->bytes_overlap * 2 - nch * bps * 2); - if (!s->buf_pre_corr || !s->table_window) { - MP_FATAL(f, "Out of memory\n"); - return false; - } - memset((char *)s->buf_pre_corr + s->bytes_overlap * 2, 0, - UNROLL_PADDING); - int32_t *pw = s->table_window; - for (int i = 1; i < frames_overlap; i++) { - int32_t v = (i * (t - i) * n) >> 15; - for (int j = 0; j < nch; j++) - *pw++ = v; - } s->best_overlap_offset = best_overlap_offset_s16; } else { - s->buf_pre_corr = realloc(s->buf_pre_corr, s->bytes_overlap); - s->table_window = realloc(s->table_window, - s->bytes_overlap - nch * bps); - if (!s->buf_pre_corr || !s->table_window) { - MP_FATAL(f, "Out of memory\n"); - return false; - } - float *pw = s->table_window; - for (int i = 1; i < frames_overlap; i++) { - float v = i * (frames_overlap - i); - for (int j = 0; j < nch; j++) - *pw++ = v; - } s->best_overlap_offset = best_overlap_offset_float; } } @@ -486,7 +530,7 @@ static bool reinit(struct mp_filter *f) s->bytes_queue = (s->frames_search + s->frames_stride + frames_overlap) * bps * nch; - s->buf_queue = realloc(s->buf_queue, s->bytes_queue + UNROLL_PADDING); + s->buf_queue = realloc(s->buf_queue, s->bytes_queue); if (!s->buf_queue) { MP_FATAL(f, "Out of memory\n"); return false; @@ -511,7 +555,7 @@ static bool reinit(struct mp_filter *f) return true; } -static bool command(struct mp_filter *f, struct mp_filter_command *cmd) +static bool af_scaletempo_command(struct mp_filter *f, struct mp_filter_command *cmd) { struct priv *s = f->priv; @@ -530,7 +574,7 @@ static bool command(struct mp_filter *f, struct mp_filter_command *cmd) return false; } -static void reset(struct mp_filter *f) +static void af_scaletempo_reset(struct mp_filter *f) { struct priv *s = f->priv; @@ -543,14 +587,12 @@ static void reset(struct mp_filter *f) TA_FREEP(&s->in); } -static void destroy(struct mp_filter *f) +static void af_scaletempo_destroy(struct mp_filter *f) { struct priv *s = f->priv; free(s->buf_queue); free(s->buf_overlap); - free(s->buf_pre_corr); free(s->table_blend); - free(s->table_window); TA_FREEP(&s->in); mp_filter_free_children(f); } @@ -558,10 +600,10 @@ static void destroy(struct mp_filter *f) static const struct mp_filter_info af_scaletempo_filter = { .name = "scaletempo", .priv_size = sizeof(struct priv), - .process = process, - .command = command, - .reset = reset, - .destroy = destroy, + .process = af_scaletempo_process, + .command = af_scaletempo_command, + .reset = af_scaletempo_reset, + .destroy = af_scaletempo_destroy, }; static struct mp_filter *af_scaletempo_create(struct mp_filter *parent, diff --git a/audio/filter/af_scaletempo2.c b/audio/filter/af_scaletempo2.c index 7ad8e3566d..749e219454 100644 --- a/audio/filter/af_scaletempo2.c +++ b/audio/filter/af_scaletempo2.c @@ -8,7 +8,7 @@ #include "options/m_option.h" struct priv { - struct mp_scaletempo2 data; + struct mp_scaletempo2 *data; struct mp_pin *in_pin; struct mp_aframe *cur_format; struct mp_aframe_pool *out_pool; @@ -19,9 +19,9 @@ struct priv { }; static bool init_scaletempo2(struct mp_filter *f); -static void reset(struct mp_filter *f); +static void af_scaletempo2_reset(struct mp_filter *f); -static void process(struct mp_filter *f) +static void af_scaletempo2_process(struct mp_filter *f) { struct priv *p = f->priv; @@ -29,7 +29,7 @@ static void process(struct mp_filter *f) return; while (!p->initialized || !p->pending || - !mp_scaletempo2_frames_available(&p->data, p->speed)) + !mp_scaletempo2_frames_available(p->data, p->speed)) { bool eof = false; if (!p->pending || !mp_aframe_get_size(p->pending)) { @@ -64,16 +64,16 @@ static void process(struct mp_filter *f) if (p->pending && !format_change && !p->sent_final) { int frame_size = mp_aframe_get_size(p->pending); uint8_t **planes = mp_aframe_get_data_ro(p->pending); - int read = mp_scaletempo2_fill_input_buffer(&p->data, + int read = mp_scaletempo2_fill_input_buffer(p->data, planes, frame_size, p->speed); mp_aframe_skip_samples(p->pending, read); } if (final && p->pending && !p->sent_final) { - mp_scaletempo2_set_final(&p->data); + mp_scaletempo2_set_final(p->data); p->sent_final = true; } - if (mp_scaletempo2_frames_available(&p->data, p->speed)) { + if (mp_scaletempo2_frames_available(p->data, p->speed)) { if (eof) { mp_pin_out_repeat_eof(p->in_pin); // drain more next time } @@ -89,9 +89,9 @@ static void process(struct mp_filter *f) } assert(p->pending); - if (mp_scaletempo2_frames_available(&p->data, p->speed)) { + if (mp_scaletempo2_frames_available(p->data, p->speed)) { struct mp_aframe *out = mp_aframe_new_ref(p->cur_format); - int out_samples = p->data.ola_hop_size; + int out_samples = p->data->ola_hop_size; if (mp_aframe_pool_allocate(p->out_pool, out, out_samples) < 0) { talloc_free(out); goto error; @@ -101,14 +101,14 @@ static void process(struct mp_filter *f) uint8_t **planes = mp_aframe_get_data_rw(out); assert(planes); - assert(mp_aframe_get_planes(out) == p->data.channels); + assert(mp_aframe_get_planes(out) == p->data->channels); - out_samples = mp_scaletempo2_fill_buffer(&p->data, + out_samples = mp_scaletempo2_fill_buffer(p->data, (float**)planes, out_samples, p->speed); double pts = mp_aframe_get_pts(p->pending); if (pts != MP_NOPTS_VALUE) { - double frame_delay = mp_scaletempo2_get_latency(&p->data, p->speed) + double frame_delay = mp_scaletempo2_get_latency(p->data, p->speed) + out_samples * p->speed; mp_aframe_set_pts(out, pts - frame_delay / mp_aframe_get_effective_rate(out)); @@ -122,7 +122,7 @@ static void process(struct mp_filter *f) // reset the filter to ensure it stops generating audio |