diff options
author | Carl Eugen Hoyos <ceffmpeg@gmail.com> | 2020-09-05 21:14:01 +0200 |
---|---|---|
committer | Carl Eugen Hoyos <ceffmpeg@gmail.com> | 2021-02-15 00:12:38 +0100 |
commit | 3490108f95b5a350f75df8443b00fbeebcdf068d (patch) | |
tree | 189d0795200077016f23bae48e77803c6862248a | |
parent | ca781761d61de20f28b5c6486c64dbf2c2c4c944 (diff) | |
download | ffmpeg-3490108f95b5a350f75df8443b00fbeebcdf068d.tar.gz |
lavfi/vflip: Support Bayer vertical flip.
Fixes ticket #8819.
-rw-r--r-- | libavfilter/vf_vflip.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c index c7c39d3341..1de3dc5dac 100644 --- a/libavfilter/vf_vflip.c +++ b/libavfilter/vf_vflip.c @@ -33,6 +33,7 @@ typedef struct FlipContext { const AVClass *class; int vsub; ///< vertical chroma subsampling + int bayer; } FlipContext; static const AVOption vflip_options[] = { @@ -47,6 +48,7 @@ static int config_input(AVFilterLink *link) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); flip->vsub = desc->log2_chroma_h; + flip->bayer = !!(desc->flags & AV_PIX_FMT_FLAG_BAYER); return 0; } @@ -74,11 +76,43 @@ static AVFrame *get_video_buffer(AVFilterLink *link, int w, int h) return frame; } +static int flip_bayer(AVFilterLink *link, AVFrame *in) +{ + AVFilterContext *ctx = link->dst; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out; + uint8_t *inrow = in->data[0], *outrow; + int i, width = outlink->w << (av_pix_fmt_desc_get(link->format)->comp[0].step > 1); + if (outlink->h & 1) { + av_log(ctx, AV_LOG_ERROR, "Bayer vertical flip needs even height\n"); + return AVERROR_INVALIDDATA; + } + + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + outrow = out->data[0] + out->linesize[0] * (outlink->h - 2); + for (i = 0; i < outlink->h >> 1; i++) { + memcpy(outrow, inrow, width); + memcpy(outrow + out->linesize[0], inrow + in->linesize[0], width); + inrow += 2 * in->linesize[0]; + outrow -= 2 * out->linesize[0]; + } + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + static int filter_frame(AVFilterLink *link, AVFrame *frame) { FlipContext *flip = link->dst->priv; int i; + if (flip->bayer) + return flip_bayer(link, frame); + for (i = 0; i < 4; i ++) { int vsub = i == 1 || i == 2 ? flip->vsub : 0; int height = AV_CEIL_RSHIFT(link->h, vsub); |