Unified · Split
| @@ -50,6 +50,7 @@ typedef struct AudioNLMeansContext { · 49 unmodified lines | ||
| 50 | 50 | int N; |
| 51 | 51 | int H; |
| 52 | 52 | |
| 53 | + AVFrame *in; | |
| 53 | 54 | AVFrame *cache; |
| 54 | 55 | AVFrame *window; |
| 55 | 56 | |
| @@ -201,6 +202,8 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) · 145 unmodified lines | ||
| 201 | 202 | AVFrame *out = arg; |
| 202 | 203 | const int S = s->S; |
| 203 | 204 | const int K = s->K; |
| 205 | + const int N = s->N; | |
| 206 | + const int H = s->H; | |
| 204 | 207 | const int om = s->om; |
| 205 | 208 | const float *f = (const float *)(s->window->extended_data[ch]) + K; |
| 206 | 209 | float *cache = (float *)s->cache->extended_data[ch]; |
| @@ -209,8 +212,15 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) · 2 unmodified lines | ||
| 209 | 212 | const float *const weight_lut = s->weight_lut; |
| 210 | 213 | const float pdiff_lut_scale = s->pdiff_lut_scale; |
| 211 | 214 | const float smooth = fminf(s->m, WEIGHT_LUT_SIZE / pdiff_lut_scale); |
| 215 | + const int offset = N - H; | |
| 216 | + float *src = (float *)s->window->extended_data[ch]; | |
| 217 | + const AVFrame *const in = s->in; | |
| 212 | 218 | |
| 213 | − for (int i = S; i < s->H + S; i++) { | |
| 219 | + memmove(src, &src[H], offset * sizeof(float)); | |
| 220 | + memcpy(&src[offset], in->extended_data[ch], in->nb_samples * sizeof(float)); | |
| 221 | + memset(&src[offset + in->nb_samples], 0, (H - in->nb_samples) * sizeof(float)); | |
| 222 | + | |
| 223 | + for (int i = S; i < H + S; i++) { | |
| 214 | 224 | float P = 0.f, Q = 0.f; |
| 215 | 225 | int v = 0; |
| 216 | 226 | |
| @@ -260,25 +270,25 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 43 unmodified lines | ||
| 260 | 270 | AVFilterContext *ctx = inlink->dst; |
| 261 | 271 | AVFilterLink *outlink = ctx->outputs[0]; |
| 262 | 272 | AudioNLMeansContext *s = ctx->priv; |
| 263 | − const int offset = s->N - s->H; | |
| 264 | 273 | AVFrame *out; |
| 265 | 274 | |
| 266 | − out = ff_get_audio_buffer(outlink, in->nb_samples); | |
| 267 | − if (!out) | |
| 268 | − return AVERROR(ENOMEM); | |
| 269 | − | |
| 270 | − for (int ch = 0; ch < in->channels; ch++) { | |
| 271 | − float *src = (float *)s->window->extended_data[ch]; | |
| 275 | + if (av_frame_is_writable(in)) { | |
| 276 | + out = in; | |
| 277 | + } else { | |
| 278 | + out = ff_get_audio_buffer(outlink, in->nb_samples); | |
| 279 | + if (!out) { | |
| 280 | + av_frame_free(&in); | |
| 281 | + return AVERROR(ENOMEM); | |
| 282 | + } | |
| 272 | 283 | |
| 273 | − memmove(src, &src[s->H], offset * sizeof(float)); | |
| 274 | − memcpy(&src[offset], in->extended_data[ch], in->nb_samples * sizeof(float)); | |
| 275 | − memset(&src[offset + in->nb_samples], 0, (s->H - in->nb_samples) * sizeof(float)); | |
| 284 | + out->pts = in->pts; | |
| 276 | 285 | } |
| 277 | 286 | |
| 287 | + s->in = in; | |
| 278 | 288 | ff_filter_execute(ctx, filter_channel, out, NULL, inlink->channels); |
| 279 | 289 | |
| 280 | − out->pts = in->pts; | |
| 281 | − av_frame_free(&in); | |
| 290 | + if (out != in) | |
| 291 | + av_frame_free(&in); | |
| 282 | 292 | return ff_filter_frame(outlink, out); |
| 283 | 293 | } |
| 284 | 294 | |