This fixes a segmentation fault because request_frame in fifo.c assumes that the call to ff_request_frame will populate fifo->root.next. Before, it was possible for request_frame in af_compand to not do this, resulting in a null pointer access. Now, request_frame in af_compand always will return at least one frame or an error, as per the API specifications in avfilter.h for request_frame.
Unified · Split
| @@ -71,6 +71,8 @@ typedef struct CompandContext { · 70 unmodified lines | |||
| 71 | int64_t pts; | 71 | int64_t pts; |
| 72 | 72 | ||
| 73 | int (*compand)(AVFilterContext *ctx, AVFrame *frame); | 73 | int (*compand)(AVFilterContext *ctx, AVFrame *frame); |
| 74 | /* set by filter_frame() to signal an output frame to request_frame() */ | ||
| 75 | int got_output; | ||
| 74 | } CompandContext; | 76 | } CompandContext; |
| 75 | 77 | ||
| 76 | #define OFFSET(x) offsetof(CompandContext, x) | 78 | #define OFFSET(x) offsetof(CompandContext, x) |
| @@ -287,7 +289,15 @@ static int compand_delay(AVFilterContext *ctx, AVFrame *frame) · 210 unmodified lines | |||
| 287 | s->delay_index = dindex; | 289 | s->delay_index = dindex; |
| 288 | 290 | ||
| 289 | av_frame_free(&frame); | 291 | av_frame_free(&frame); |
| 290 | return out_frame ? ff_filter_frame(ctx->outputs[0], out_frame) : 0; | 292 | |
| 293 | if (out_frame) { | ||
| 294 | err = ff_filter_frame(ctx->outputs[0], out_frame); | ||
| 295 | if (err >= 0) | ||
| 296 | s->got_output = 1; | ||
| 297 | return err; | ||
| 298 | } | ||
| 299 | |||
| 300 | return 0; | ||
| 291 | } | 301 | } |
| 292 | 302 | ||
| 293 | static int compand_drain(AVFilterLink *outlink) | 303 | static int compand_drain(AVFilterLink *outlink) |
| @@ -559,9 +569,11 @@ static int request_frame(AVFilterLink *outlink) · 265 unmodified lines | |||
| 559 | { | 569 | { |
| 560 | AVFilterContext *ctx = outlink->src; | 570 | AVFilterContext *ctx = outlink->src; |
| 561 | CompandContext *s = ctx->priv; | 571 | CompandContext *s = ctx->priv; |
| 562 | int ret; | 572 | int ret = 0; |
| 563 | 573 | ||
| 564 | ret = ff_request_frame(ctx->inputs[0]); | 574 | s->got_output = 0; |
| 575 | while (ret >= 0 && !s->got_output) | ||
| 576 | ret = ff_request_frame(ctx->inputs[0]); | ||
| 565 | 577 | ||
| 566 | if (ret == AVERROR_EOF && s->delay_count) | 578 | if (ret == AVERROR_EOF && s->delay_count) |
| 567 | ret = compand_drain(outlink); | 579 | ret = compand_drain(outlink); |