Unified · Split
| @@ -32,6 +32,7 @@ · 31 unmodified lines | |||
| 32 | #include "libswresample/swresample.h" | 32 | #include "libswresample/swresample.h" |
| 33 | #include "avfilter.h" | 33 | #include "avfilter.h" |
| 34 | #include "audio.h" | 34 | #include "audio.h" |
| 35 | #include "filters.h" | ||
| 35 | #include "internal.h" | 36 | #include "internal.h" |
| 36 | 37 | ||
| 37 | typedef struct AResampleContext { | 38 | typedef struct AResampleContext { |
| @@ -41,6 +42,7 @@ typedef struct AResampleContext { · 3 unmodified lines | |||
| 41 | struct SwrContext *swr; | 42 | struct SwrContext *swr; |
| 42 | int64_t next_pts; | 43 | int64_t next_pts; |
| 43 | int more_data; | 44 | int more_data; |
| 45 | int eof; | ||
| 44 | } AResampleContext; | 46 | } AResampleContext; |
| 45 | 47 | ||
| 46 | static av_cold int preinit(AVFilterContext *ctx) | 48 | static av_cold int preinit(AVFilterContext *ctx) |
| @@ -169,7 +171,8 @@ static int config_output(AVFilterLink *outlink) · 122 unmodified lines | |||
| 169 | 171 | ||
| 170 | static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref) | 172 | static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref) |
| 171 | { | 173 | { |
| 172 | AResampleContext *aresample = inlink->dst->priv; | 174 | AVFilterContext *ctx = inlink->dst; |
| 175 | AResampleContext *aresample = ctx->priv; | ||
| 173 | const int n_in = insamplesref->nb_samples; | 176 | const int n_in = insamplesref->nb_samples; |
| 174 | int64_t delay; | 177 | int64_t delay; |
| 175 | int n_out = n_in * aresample->ratio + 32; | 178 | int n_out = n_in * aresample->ratio + 32; |
| @@ -214,6 +217,7 @@ FF_ENABLE_DEPRECATION_WARNINGS · 38 unmodified lines | |||
| 214 | if (n_out <= 0) { | 217 | if (n_out <= 0) { |
| 215 | av_frame_free(&outsamplesref); | 218 | av_frame_free(&outsamplesref); |
| 216 | av_frame_free(&insamplesref); | 219 | av_frame_free(&insamplesref); |
| 220 | ff_inlink_request_frame(inlink); | ||
| 217 | return 0; | 221 | return 0; |
| 218 | } | 222 | } |
| 219 | 223 | ||
| @@ -260,8 +264,10 @@ static int flush_frame(AVFilterLink *outlink, int final, AVFrame **outsamplesref · 40 unmodified lines | |||
| 260 | static int request_frame(AVFilterLink *outlink) | 264 | static int request_frame(AVFilterLink *outlink) |
| 261 | { | 265 | { |
| 262 | AVFilterContext *ctx = outlink->src; | 266 | AVFilterContext *ctx = outlink->src; |
| 267 | AVFilterLink *inlink = ctx->inputs[0]; | ||
| 263 | AResampleContext *aresample = ctx->priv; | 268 | AResampleContext *aresample = ctx->priv; |
| 264 | int ret; | 269 | int ret = 0, status; |
| 270 | int64_t pts; | ||
| 265 | 271 | ||
| 266 | // First try to get data from the internal buffers | 272 | // First try to get data from the internal buffers |
| 267 | if (aresample->more_data) { | 273 | if (aresample->more_data) { |
| @@ -273,19 +279,52 @@ static int request_frame(AVFilterLink *outlink) · 5 unmodified lines | |||
| 273 | } | 279 | } |
| 274 | aresample->more_data = 0; | 280 | aresample->more_data = 0; |
| 275 | 281 | ||
| 282 | if (!aresample->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) | ||
| 283 | aresample->eof = 1; | ||
| 284 | |||
| 276 | // Second request more data from the input | 285 | // Second request more data from the input |
| 277 | ret = ff_request_frame(ctx->inputs[0]); | 286 | if (!aresample->eof) |
| 287 | FF_FILTER_FORWARD_WANTED(outlink, inlink); | ||
| 278 | 288 | ||
| 279 | // Third if we hit the end flush | 289 | // Third if we hit the end flush |
| 280 | if (ret == AVERROR_EOF) { | 290 | if (aresample->eof) { |
| 281 | AVFrame *outsamplesref; | 291 | AVFrame *outsamplesref; |
| 282 | 292 | ||
| 283 | if ((ret = flush_frame(outlink, 1, &outsamplesref)) < 0) | 293 | if ((ret = flush_frame(outlink, 1, &outsamplesref)) < 0) { |
| 294 | if (ret == AVERROR_EOF) { | ||
| 295 | ff_outlink_set_status(outlink, AVERROR_EOF, aresample->next_pts); | ||
| 296 | return 0; | ||
| 297 | } | ||
| 284 | return ret; | 298 | return ret; |
| 299 | } | ||
| 285 | 300 | ||
| 286 | return ff_filter_frame(outlink, outsamplesref); | 301 | return ff_filter_frame(outlink, outsamplesref); |
| 287 | } | 302 | } |
| 288 | return ret; | 303 | |
| 304 | ff_filter_set_ready(ctx, 100); | ||
| 305 | return 0; | ||
| 306 | } | ||
| 307 | |||
| 308 | static int activate(AVFilterContext *ctx) | ||
| 309 | { | ||
| 310 | AResampleContext *aresample = ctx->priv; | ||
| 311 | AVFilterLink *inlink = ctx->inputs[0]; | ||
| 312 | AVFilterLink *outlink = ctx->outputs[0]; | ||
| 313 | |||
| 314 | FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); | ||
| 315 | |||
| 316 | if (!aresample->eof && ff_inlink_queued_frames(inlink)) { | ||
| 317 | AVFrame *frame = NULL; | ||
| 318 | int ret; | ||
| 319 | |||
| 320 | ret = ff_inlink_consume_frame(inlink, &frame); | ||
| 321 | if (ret < 0) | ||
| 322 | return ret; | ||
| 323 | if (ret > 0) | ||
| 324 | return filter_frame(inlink, frame); | ||
| 325 | } | ||
| 326 | |||
| 327 | return request_frame(outlink); | ||
| 289 | } | 328 | } |
| 290 | 329 | ||
| 291 | static const AVClass *resample_child_class_iterate(void **iter) | 330 | static const AVClass *resample_child_class_iterate(void **iter) |
| @@ -322,7 +361,6 @@ static const AVFilterPad aresample_inputs[] = { · 30 unmodified lines | |||
| 322 | { | 361 | { |
| 323 | .name = "default", | 362 | .name = "default", |
| 324 | .type = AVMEDIA_TYPE_AUDIO, | 363 | .type = AVMEDIA_TYPE_AUDIO, |
| 325 | .filter_frame = filter_frame, | ||
| 326 | }, | 364 | }, |
| 327 | }; | 365 | }; |
| 328 | 366 | ||
| @@ -330,7 +368,6 @@ static const AVFilterPad aresample_outputs[] = { · 1 unmodified line | |||
| 330 | { | 368 | { |
| 331 | .name = "default", | 369 | .name = "default", |
| 332 | .config_props = config_output, | 370 | .config_props = config_output, |
| 333 | .request_frame = request_frame, | ||
| 334 | .type = AVMEDIA_TYPE_AUDIO, | 371 | .type = AVMEDIA_TYPE_AUDIO, |
| 335 | }, | 372 | }, |
| 336 | }; | 373 | }; |
| @@ -339,6 +376,7 @@ const AVFilter ff_af_aresample = { · 2 unmodified lines | |||
| 339 | .name = "aresample", | 376 | .name = "aresample", |
| 340 | .description = NULL_IF_CONFIG_SMALL("Resample audio data."), | 377 | .description = NULL_IF_CONFIG_SMALL("Resample audio data."), |
| 341 | .preinit = preinit, | 378 | .preinit = preinit, |
| 379 | .activate = activate, | ||
| 342 | .uninit = uninit, | 380 | .uninit = uninit, |
| 343 | .priv_size = sizeof(AResampleContext), | 381 | .priv_size = sizeof(AResampleContext), |
| 344 | .priv_class = &aresample_class, | 382 | .priv_class = &aresample_class, |