From patchwork Mon Sep 27 12:07:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Soft Works X-Patchwork-Id: 30605 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:6506:0:0:0:0:0 with SMTP id z6csp4076806iob; Mon, 27 Sep 2021 05:07:42 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzivxAClpwexRIJlLhNlP0THdoge0BqlWd9qL8pZO9dLW8a1A9EuvfHqvaJGEIYbZLbvKXM X-Received: by 2002:a50:e184:: with SMTP id k4mr19720551edl.217.1632744462701; Mon, 27 Sep 2021 05:07:42 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id hs6si15400120ejc.12.2021.09.27.05.07.42; Mon, 27 Sep 2021 05:07:42 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@hotmail.com header.s=selector1 header.b=GpyAnXI4; arc=fail (body hash mismatch); spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=hotmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 170106891F1; Mon, 27 Sep 2021 15:07:40 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12olkn2053.outbound.protection.outlook.com [40.92.21.53]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1718F687F20 for ; Mon, 27 Sep 2021 15:07:33 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=E/4vxR4Q/5EIZpXbCYrXs02R3D8Qr0xrYrIh2J8XbOp/aHDxmDvHKfbBLHWirpdN646r6LmMsMKpn1a+uVyYNdd+lVN8wBXv15jmYfvdvh+4tKpY3plZxFRbDmmev615nD6m2INKVotOwpAhUMl8ZqetYvUaPjfzorC9m89B58T6t7ROoaF1wi0/2/pglPYoYYa+lWhvTn8JbwpvOw0FpHgys9DpavcoQ/Ym34d8GhmiC407u6j6gqiT2MQfKxIzqNnVhNrmIiH1pKXu0hl8zfs4AyektpfOZ1BVwXqAb0Y2PIGzp+KZQBTxf8NvFZkS77LV3qFNAu1M1+49L8YS8A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=6MeI70YQqmrAskSzDfUaQEf7igkW5fq8XM59Ahu6uGw=; b=dr+238XB8+BTqQFWryckrXVDTd9mN8B6th0k3BeP/DsRFGPeYaC94UQ60C6BPfRDDm/QPeW3uzhXDVN3XxrmkEOmQyrnRUm1gWoM72d8F030S3rg7xXnPNHuQOgPgmOW0ZxNbiyelLFnxJdNKMwA9VAubMm7zuwcwUfWlKeUVGU859LTX7BzuUNiQ9++oZMBJ1pjdwPVovajRvL79ESsV60s+B1G/tTNM888bTyBxAC3jiIvQrJGjRtJBEu04MTtgNRGyjtjtdUna5Q0EiqOzRS15UJLP/TnyuUm7RReIp9sJ5YjQIBHfPWtZkdy2EJqE0eka+dn1mOM/7laFpyV9w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hotmail.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=6MeI70YQqmrAskSzDfUaQEf7igkW5fq8XM59Ahu6uGw=; b=GpyAnXI4CgHePYyDxFEznqrO11ZcHImyzgxPOSKCndIneBXYxm+cQ8M4gF3DylL0n6AiDS/DLhNRj64i4lUKSAYA2gBl5PZrtGS98tOFXzF/o9wm6Nkv5fYWTRf0DLnyVqPm2Zu35cHLq1QO1WoVyeony52Em39EsQkpRa+Gw42w2emCkxQVTczoEQkaqPxBw8TaJMbXbp96kEn4eFx82S60prtZptqL+oczPu3Om19tKG/kL/plmJzGdDTBS2g461CIThqbTGgWtAhpgbQomoocJGGxqGk71sKKpu3VI8YqeVdLdryKQeWJRufxfQn5savVxgfRZ2B0o2ivw55mSg== Received: from MN2PR04MB5981.namprd04.prod.outlook.com (2603:10b6:208:da::10) by MN2PR04MB5502.namprd04.prod.outlook.com (2603:10b6:208:e0::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.18; Mon, 27 Sep 2021 12:07:28 +0000 Received: from MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::ecfe:2528:2012:22cb]) by MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::ecfe:2528:2012:22cb%5]) with mapi id 15.20.4544.021; Mon, 27 Sep 2021 12:07:28 +0000 From: Soft Works To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH] avfilter/frames: Ensure frames are writable when processing in-place Thread-Index: AdezlQqYErO4Rdw1SBaWtR80cT/xjQ== Date: Mon, 27 Sep 2021 12:07:28 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [RDbNdXdpG89v6OQh/wK4ac8EDfHpoelE] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: ef011b75-c660-4e33-2ad0-08d981af6042 x-ms-traffictypediagnostic: MN2PR04MB5502: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: c9+hKvYN9KtbjQOkry//bb+2RW0Z4zfxoIRaWHzs81IeihBuF5ZDYSOK9l0vJHaapqwDjtqxRaJVJTE7B2O9MrqfDWVBi5bg5G/2LQ9+Rh5xX2nmZIthBqQmrmX7dOGXxzm7xEvxxJhT/UnBOxBMsAFm8HjKNQ4prE1QgCa5qaWgjjCCmOJbkywnF9mpSEkdGdftWdrzNAYRo1GiYrplNMMi/PHK46p0AwGg8cGEYjNuNnFF9Bd9+fPBHk7Bu0iqGphhul137pHs1QIejrCeLFTJbQNpa5Ao3/lrIJkAnP8/oR8KXY9dpUbFHNqUhsKohX9uqxYjupitmgu8vc9q+S59bkwu99uVa41Vls360CrcXY17z2yk0t/crHQnnQJwfkLAp9MemI8775Yl6XtuAf7Oc5m5EdHbKbAffuMf2p0crxivOQi1ZSKjZY4ozzGM x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: 8NFkUZ7FB0z11R/g7Lh1GhorlkK78XSrAbI1QKge4Ib74k1hKPzJ4HQi661oBmJpZYGht0i9ebAXZ1NWEMcSZ8zsSS4JMDEcp71ZMYQaA4fgRkL9QO0C0KH5ZRuVEEka+VYCcE9+HUAGqnpQg9oV7g== x-ms-exchange-transport-forked: True MIME-Version: 1.0 X-OriginatorOrg: sct-15-20-3174-20-msonline-outlook-529c7.templateTenant X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MN2PR04MB5981.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-CrossTenant-Network-Message-Id: ef011b75-c660-4e33-2ad0-08d981af6042 X-MS-Exchange-CrossTenant-originalarrivaltime: 27 Sep 2021 12:07:28.3225 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-rms-persistedconsumerorg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR04MB5502 Subject: [FFmpeg-devel] [PATCH] avfilter/frames: Ensure frames are writable when processing in-place X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: fAgJAnnMdWVU With the introduction of subtitle filtering, subsequent video frames which are sharing the same data won't be as rare as this happened to occur yet. Ensuring per-frame uniqueness when data is modified is not only important to avoid issues in the future, but a common API requirement anyway. Signed-off-by: softworkz --- libavfilter/vf_chromakey.c | 5 +++++ libavfilter/vf_codecview.c | 6 ++++++ libavfilter/vf_colorcontrast.c | 5 +++++ libavfilter/vf_colorcorrect.c | 6 ++++++ libavfilter/vf_colorize.c | 6 ++++++ libavfilter/vf_colorkey.c | 5 +++++ libavfilter/vf_colortemperature.c | 6 ++++++ libavfilter/vf_cover_rect.c | 7 +++++-- libavfilter/vf_datascope.c | 7 ++++++- libavfilter/vf_despill.c | 5 +++++ libavfilter/vf_exposure.c | 6 ++++++ libavfilter/vf_fade.c | 6 ++++++ libavfilter/vf_fillborders.c | 6 ++++++ libavfilter/vf_floodfill.c | 5 +++++ libavfilter/vf_hsvkey.c | 5 +++++ libavfilter/vf_lumakey.c | 5 +++++ libavfilter/vf_subtitles.c | 7 ++++++- libavfilter/vf_swaprect.c | 5 +++++ libavfilter/vf_vflip.c | 7 ++++++- libavfilter/vf_vibrance.c | 5 +++++ 20 files changed, 110 insertions(+), 5 deletions(-) diff --git a/libavfilter/vf_chromakey.c b/libavfilter/vf_chromakey.c index 304cb9ee6c..cf28cbadcb 100644 --- a/libavfilter/vf_chromakey.c +++ b/libavfilter/vf_chromakey.c @@ -260,6 +260,11 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) ChromakeyContext *ctx = avctx->priv; int res; + if ((res = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return res; + } + if (res = ff_filter_execute(avctx, ctx->do_slice, frame, NULL, FFMIN(frame->height, ff_filter_get_nb_threads(avctx)))) return res; diff --git a/libavfilter/vf_codecview.c b/libavfilter/vf_codecview.c index dc3d3acd82..61416ae733 100644 --- a/libavfilter/vf_codecview.c +++ b/libavfilter/vf_codecview.c @@ -215,7 +215,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) AVFilterContext *ctx = inlink->dst; CodecViewContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; + int ret; + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } + if (s->qp) { int qstride, qp_type, ret; int8_t *qp_table; diff --git a/libavfilter/vf_colorcontrast.c b/libavfilter/vf_colorcontrast.c index e89b3e7af4..410a51cba7 100644 --- a/libavfilter/vf_colorcontrast.c +++ b/libavfilter/vf_colorcontrast.c @@ -303,6 +303,11 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) ColorContrastContext *s = ctx->priv; int res; + if ((res = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return res; + } + if (res = ff_filter_execute(ctx, s->do_slice, frame, NULL, FFMIN(frame->height, ff_filter_get_nb_threads(ctx)))) return res; diff --git a/libavfilter/vf_colorcorrect.c b/libavfilter/vf_colorcorrect.c index 2570bb105c..ce18413697 100644 --- a/libavfilter/vf_colorcorrect.c +++ b/libavfilter/vf_colorcorrect.c @@ -398,6 +398,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) AVFilterContext *ctx = inlink->dst; ColorCorrectContext *s = ctx->priv; const int nb_threads = s->analyze == MEDIAN ? 1 : FFMIN(s->planeheight[1], ff_filter_get_nb_threads(ctx)); + int ret; if (s->analyze) { const int nb_athreads = s->analyze == MEDIAN ? 1 : nb_threads; @@ -423,6 +424,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) s->rh = -rh; } + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } + ff_filter_execute(ctx, s->do_slice, frame, NULL, nb_threads); return ff_filter_frame(ctx->outputs[0], frame); diff --git a/libavfilter/vf_colorize.c b/libavfilter/vf_colorize.c index 4b57998a22..3f14547c00 100644 --- a/libavfilter/vf_colorize.c +++ b/libavfilter/vf_colorize.c @@ -199,6 +199,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) AVFilterContext *ctx = inlink->dst; ColorizeContext *s = ctx->priv; float c[3]; + int ret; + + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } hsl2rgb(s->hue, s->saturation, s->lightness, &c[0], &c[1], &c[2]); rgb2yuv(c[0], c[1], c[2], &s->c[0], &s->c[1], &s->c[2], s->depth); diff --git a/libavfilter/vf_colorkey.c b/libavfilter/vf_colorkey.c index bef3e37414..45a61df104 100644 --- a/libavfilter/vf_colorkey.c +++ b/libavfilter/vf_colorkey.c @@ -135,6 +135,11 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) ColorkeyContext *ctx = avctx->priv; int res; + if ((res = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return res; + } + if (res = ff_filter_execute(avctx, ctx->do_slice, frame, NULL, FFMIN(frame->height, ff_filter_get_nb_threads(avctx)))) return res; diff --git a/libavfilter/vf_colortemperature.c b/libavfilter/vf_colortemperature.c index da2e3bf908..4e8e18af30 100644 --- a/libavfilter/vf_colortemperature.c +++ b/libavfilter/vf_colortemperature.c @@ -267,9 +267,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) { AVFilterContext *ctx = inlink->dst; ColorTemperatureContext *s = ctx->priv; + int ret; kelvin2rgb(s->temperature, s->color); + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } + ff_filter_execute(ctx, s->do_slice, frame, NULL, FFMIN(frame->height, ff_filter_get_nb_threads(ctx))); diff --git a/libavfilter/vf_cover_rect.c b/libavfilter/vf_cover_rect.c index 0a8c10e06d..2367afb4b3 100644 --- a/libavfilter/vf_cover_rect.c +++ b/libavfilter/vf_cover_rect.c @@ -136,7 +136,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFilterContext *ctx = inlink->dst; CoverContext *cover = ctx->priv; AVDictionaryEntry *ex, *ey, *ew, *eh; - int x = -1, y = -1, w = -1, h = -1; + int x = -1, y = -1, w = -1, h = -1, ret; char *xendptr = NULL, *yendptr = NULL, *wendptr = NULL, *hendptr = NULL; ex = av_dict_get(in->metadata, "lavfi.rect.x", NULL, AV_DICT_MATCH_CASE); @@ -181,7 +181,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) x = av_clip(x, 0, in->width - w); y = av_clip(y, 0, in->height - h); - av_frame_make_writable(in); + if ((ret = av_frame_make_writable(in)) < 0) { + av_frame_free(&in); + return ret; + } if (cover->mode == MODE_BLUR) { blur (cover, in, x, y); diff --git a/libavfilter/vf_datascope.c b/libavfilter/vf_datascope.c index a60d061d18..c5b78d90cd 100644 --- a/libavfilter/vf_datascope.c +++ b/libavfilter/vf_datascope.c @@ -1051,7 +1051,12 @@ static int oscilloscope_filter_frame(AVFilterLink *inlink, AVFrame *frame) float average[4] = { 0 }; int max[4] = { 0 }; int min[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX }; - int i, c; + int i, c, ret; + + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } s->nb_values = 0; draw_scope(s, s->x1, s->y1, s->x2, s->y2, frame, s->values, inlink->frame_count_in & 1); diff --git a/libavfilter/vf_despill.c b/libavfilter/vf_despill.c index 2c60112b48..c6c12b9b4a 100644 --- a/libavfilter/vf_despill.c +++ b/libavfilter/vf_despill.c @@ -94,6 +94,11 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) AVFilterContext *ctx = link->dst; int ret; + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } + if (ret = ff_filter_execute(ctx, do_despill_slice, frame, NULL, FFMIN(frame->height, ff_filter_get_nb_threads(ctx)))) return ret; diff --git a/libavfilter/vf_exposure.c b/libavfilter/vf_exposure.c index 2b6e6f1586..07c45acc1b 100644 --- a/libavfilter/vf_exposure.c +++ b/libavfilter/vf_exposure.c @@ -67,6 +67,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) { AVFilterContext *ctx = inlink->dst; ExposureContext *s = ctx->priv; + int ret; + + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } s->scale = 1.f / (exp2f(-s->exposure) - s->black); ff_filter_execute(ctx, s->do_slice, frame, NULL, diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index 71d40c4928..563c4819ab 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -492,6 +492,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) } if (s->factor < UINT16_MAX) { + int ret; + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } + if (s->alpha) { ff_filter_execute(ctx, s->filter_slice_alpha, frame, NULL, FFMIN(frame->height, ff_filter_get_nb_threads(ctx))); diff --git a/libavfilter/vf_fillborders.c b/libavfilter/vf_fillborders.c index 4a799422b4..eaabf5f36f 100644 --- a/libavfilter/vf_fillborders.c +++ b/libavfilter/vf_fillborders.c @@ -587,8 +587,14 @@ static void margins_borders16(FillBordersContext *s, AVFrame *frame) static int filter_frame(AVFilterLink *inlink, AVFrame *frame) { + int ret; FillBordersContext *s = inlink->dst->priv; + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } + s->fillborders(s, frame); return ff_filter_frame(inlink->dst->outputs[0], frame); diff --git a/libavfilter/vf_floodfill.c b/libavfilter/vf_floodfill.c index 21741cdb4f..292b27505e 100644 --- a/libavfilter/vf_floodfill.c +++ b/libavfilter/vf_floodfill.c @@ -294,6 +294,11 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) const int h = frame->height; int i, ret; + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } + if (is_inside(s->x, s->y, w, h)) { s->pick_pixel(frame, s->x, s->y, &s0, &s1, &s2, &s3); diff --git a/libavfilter/vf_hsvkey.c b/libavfilter/vf_hsvkey.c index 2f2f037714..83e17f00c7 100644 --- a/libavfilter/vf_hsvkey.c +++ b/libavfilter/vf_hsvkey.c @@ -216,6 +216,11 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) HSVKeyContext *s = avctx->priv; int res; + if ((res = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return res; + } + s->hue = FFSIGN(s->hue_opt) *M_PI * fmodf(526.f - fabsf(s->hue_opt), 360.f) / 180.f; if (res = ff_filter_execute(avctx, s->do_slice, frame, NULL, FFMIN(frame->height, ff_filter_get_nb_threads(avctx)))) diff --git a/libavfilter/vf_lumakey.c b/libavfilter/vf_lumakey.c index b3bfb0a278..60a75c6253 100644 --- a/libavfilter/vf_lumakey.c +++ b/libavfilter/vf_lumakey.c @@ -135,6 +135,11 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) LumakeyContext *s = ctx->priv; int ret; + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } + if (ret = ff_filter_execute(ctx, s->do_lumakey_slice, frame, NULL, FFMIN(frame->height, ff_filter_get_nb_threads(ctx)))) return ret; diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c index 9b2e57fe0e..ac43a8f1ed 100644 --- a/libavfilter/vf_subtitles.c +++ b/libavfilter/vf_subtitles.c @@ -179,7 +179,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; AssContext *ass = ctx->priv; - int detect_change = 0; + int detect_change = 0, ret; double time_ms = picref->pts * av_q2d(inlink->time_base) * 1000; ASS_Image *image = ass_render_frame(ass->renderer, ass->track, time_ms, &detect_change); @@ -187,6 +187,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) if (detect_change) av_log(ctx, AV_LOG_DEBUG, "Change happened at time ms:%f\n", time_ms); + if ((ret = av_frame_make_writable(picref)) < 0) { + av_frame_free(&picref); + return ret; + } + overlay_ass_image(ass, picref, image); return ff_filter_frame(outlink, picref); diff --git a/libavfilter/vf_swaprect.c b/libavfilter/vf_swaprect.c index e03603fe5a..d776aef3c0 100644 --- a/libavfilter/vf_swaprect.c +++ b/libavfilter/vf_swaprect.c @@ -134,6 +134,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) if (ret < 0) return ret; + if ((ret = av_frame_make_writable(in)) < 0) { + av_frame_free(&in); + return ret; + } + w = dw; h = dh; x1[0] = dx1; y1[0] = dy1; x2[0] = dx2; y2[0] = dy2; x1[0] = av_clip(x1[0], 0, inlink->w - 1); diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c index 0d624512f9..622bd46db3 100644 --- a/libavfilter/vf_vflip.c +++ b/libavfilter/vf_vflip.c @@ -108,11 +108,16 @@ static int flip_bayer(AVFilterLink *link, AVFrame *in) static int filter_frame(AVFilterLink *link, AVFrame *frame) { FlipContext *flip = link->dst->priv; - int i; + int i, ret; if (flip->bayer) return flip_bayer(link, frame); + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } + for (i = 0; i < 4; i ++) { int vsub = i == 1 || i == 2 ? flip->vsub : 0; int height = AV_CEIL_RSHIFT(link->h, vsub); diff --git a/libavfilter/vf_vibrance.c b/libavfilter/vf_vibrance.c index 7253ebd594..9abeb6e3a7 100644 --- a/libavfilter/vf_vibrance.c +++ b/libavfilter/vf_vibrance.c @@ -285,6 +285,11 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) VibranceContext *s = avctx->priv; int res; + if ((res = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return res; + } + if (res = ff_filter_execute(avctx, s->do_slice, frame, NULL, FFMIN(frame->height, ff_filter_get_nb_threads(avctx)))) return res;