Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | #include "libswresample/swresample.h" |
| 33 | 33 | #include "avfilter.h" |
| 34 | 34 | #include "audio.h" |
| 35 | +#include "filters.h" | |
| 35 | 36 | #include "internal.h" |
| 36 | 37 | |
| 37 | 38 | typedef struct AResampleContext { |
| @@ -41,6 +42,7 @@ typedef struct AResampleContext { · 3 unmodified lines | ||
| 41 | 42 | struct SwrContext *swr; |
| 42 | 43 | int64_t next_pts; |
| 43 | 44 | int more_data; |
| 45 | + int eof; | |
| 44 | 46 | } AResampleContext; |
| 45 | 47 | |
| 46 | 48 | static av_cold int preinit(AVFilterContext *ctx) |
| @@ -169,7 +171,8 @@ static int config_output(AVFilterLink *outlink) · 122 unmodified lines | ||
| 169 | 171 | |
| 170 | 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 | 176 | const int n_in = insamplesref->nb_samples; |
| 174 | 177 | int64_t delay; |
| 175 | 178 | int n_out = n_in * aresample->ratio + 32; |
| @@ -214,6 +217,7 @@ FF_ENABLE_DEPRECATION_WARNINGS · 38 unmodified lines | ||
| 214 | 217 | if (n_out <= 0) { |
| 215 | 218 | av_frame_free(&outsamplesref); |
| 216 | 219 | av_frame_free(&insamplesref); |
| 220 | + ff_inlink_request_frame(inlink); | |
| 217 | 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 | 264 | static int request_frame(AVFilterLink *outlink) |
| 261 | 265 | { |
| 262 | 266 | AVFilterContext *ctx = outlink->src; |
| 267 | + AVFilterLink *inlink = ctx->inputs[0]; | |
| 263 | 268 | AResampleContext *aresample = ctx->priv; |
| 264 | − int ret; | |
| 269 | + int ret = 0, status; | |
| 270 | + int64_t pts; | |
| 265 | 271 | |
| 266 | 272 | // First try to get data from the internal buffers |
| 267 | 273 | if (aresample->more_data) { |
| @@ -273,19 +279,52 @@ static int request_frame(AVFilterLink *outlink) · 5 unmodified lines | ||
| 273 | 279 | } |
| 274 | 280 | aresample->more_data = 0; |
| 275 | 281 | |
| 282 | + if (!aresample->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) | |
| 283 | + aresample->eof = 1; | |
| 284 | + | |
| 276 | 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 | 289 | // Third if we hit the end flush |
| 280 | − if (ret == AVERROR_EOF) { | |
| 290 | + if (aresample->eof) { | |
| 281 | 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 | 298 | return ret; |
| 299 | + } | |
| 285 | 300 | |
| 286 | 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 | 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 | 362 | .name = "default", |
| 324 | 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 | 369 | .name = "default", |
| 332 | 370 | .config_props = config_output, |
| 333 | − .request_frame = request_frame, | |
| 334 | 371 | .type = AVMEDIA_TYPE_AUDIO, |
| 335 | 372 | }, |
| 336 | 373 | }; |
| @@ -339,6 +376,7 @@ const AVFilter ff_af_aresample = { · 2 unmodified lines | ||
| 339 | 376 | .name = "aresample", |
| 340 | 377 | .description = NULL_IF_CONFIG_SMALL("Resample audio data."), |
| 341 | 378 | .preinit = preinit, |
| 379 | + .activate = activate, | |
| 342 | 380 | .uninit = uninit, |
| 343 | 381 | .priv_size = sizeof(AResampleContext), |
| 344 | 382 | .priv_class = &aresample_class, |