If adding the list of input formats to its AVFilterLink fails, the list of output formats (which has not been attached to permanent storage yet) leaks. This has been fixed by not creating the lists of in- and output formats simultaneously. Instead creating said lists is relegated to ff_formats_pixdesc_filter() (this also avoids the reallocations implicit in using ff_add_format()) and the second list is only created after (and if) the first list has been permanently attached to its AVFilterLink.
Unified · Split
| @@ -37,26 +37,13 @@ typedef struct HWDownloadContext { · 36 unmodified lines | |||
| 37 | 37 | ||
| 38 | static int hwdownload_query_formats(AVFilterContext *avctx) | 38 | static int hwdownload_query_formats(AVFilterContext *avctx) |
| 39 | { | 39 | { |
| 40 | AVFilterFormats *infmts = NULL; | 40 | AVFilterFormats *fmts; |
| 41 | AVFilterFormats *outfmts = NULL; | ||
| 42 | const AVPixFmtDescriptor *desc; | ||
| 43 | int err; | 41 | int err; |
| 44 | 42 | ||
| 45 | for (desc = av_pix_fmt_desc_next(NULL); desc; | 43 | if ((err = ff_formats_pixdesc_filter(&fmts, AV_PIX_FMT_FLAG_HWACCEL, 0)) || |
| 46 | desc = av_pix_fmt_desc_next(desc)) { | 44 | (err = ff_formats_ref(fmts, &avctx->inputs[0]->out_formats)) || |
| 47 | if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) | 45 | (err = ff_formats_pixdesc_filter(&fmts, 0, AV_PIX_FMT_FLAG_HWACCEL)) || |
| 48 | err = ff_add_format(&infmts, av_pix_fmt_desc_get_id(desc)); | 46 | (err = ff_formats_ref(fmts, &avctx->outputs[0]->in_formats))) |
| 49 | else | ||
| 50 | err = ff_add_format(&outfmts, av_pix_fmt_desc_get_id(desc)); | ||
| 51 | if (err) { | ||
| 52 | ff_formats_unref(&infmts); | ||
| 53 | ff_formats_unref(&outfmts); | ||
| 54 | return err; | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | if ((err = ff_formats_ref(infmts, &avctx->inputs[0]->out_formats)) < 0 || | ||
| 59 | (err = ff_formats_ref(outfmts, &avctx->outputs[0]->in_formats)) < 0) | ||
| 60 | return err; | 47 | return err; |
| 61 | 48 | ||
| 62 | return 0; | 49 | return 0; |