[FFmpeg-devel] [PATCH v2] fbdetile cpu based framebuffer layout detiling v02

C Hanish Menon hanishkvc at gmail.com
Sun Jun 28 19:10:50 EEST 2020


Hi Paul,

At one level I agree that compared to using gpu for doing the detiling,
this will be slower. However, what I have seen from some discussions
online, the extensions in vulkan and opengl with the format modifier aware
export weren't fully there yet. Also in case of intel, it potentially
requires using fenced view provided by the gpu to get the linear view, but
inturn this fence is a limited resource in it.

Parallely, in my case, few days back I for one wanted to capture my wayland
session at good fps and full screen, but was limited by the screencapture
dbus service provided by gnome.shell, which limited me to framerate of less
than 10-14 fps and limited compression. And also currently ffmpeg with
kmsgrab doesnt allow me to capture such a tile layout based screen, because
its outputs will be the tiles and not the linear proper screen.

This is what lead to me implementing this. This allows me to capture full
screen (1080p) at 24-30 fps, with out overloading the cpu. Also even if
someone is capturing lets say 4K or larger screens, in that case they can
still capture the screen without using this filter and later inturn run the
captured tiled video throu this filter and it will convert it into proper
video. So I feel it will be very useful for many usecases, which is
currently not possible with ffmpeg and its current filters (unless I have
missed some setup of ffmpeg, which is also possible, would be interested in
knowing such a path, if any).

Keep ;-)
HanishKVC




On Sun, Jun 28, 2020 at 2:55 PM Paul B Mahol <onemda at gmail.com> wrote:

> On 6/27/20, C Hanish Menon <hanishkvc at gmail.com> wrote:
> > Hi,
> >
> > It is a new video filter which I created to do detailing of the Intel
> > Tile-X and Tile-Y framebuffer layouts into linear layout using a logic
> > which runs on the cpu. It can be used if one uses kmsgrab and hwdownload
> to
> > capture screen on a Intel GPU based system, so that one can get proper
> > screen capture.
> >
> > Without this kmsgrab will generate a unusable/scrambled capture, because
> > the contents will be tiled. I had this issue few days back when trying to
> > capture screen with wayland, so created this.
> >
> > In the patch submitted, I have added the doc/filters.texi, which mentions
> > the same.
>
> Filter is marginally useful, it is done in CPU, completely
> invalidating any possible gain using hw path.
>
> >
> >
> >
> > On Sun, Jun 28, 2020 at 1:30 AM Paul B Mahol <onemda at gmail.com> wrote:
> >
> >> What is this?
> >>
> >> Missing documentation.
> >> NAK
> >>
> >> On 6/27/20, hanishkvc <hanishkvc at gmail.com> wrote:
> >> > v02-20200627IST2331
> >> >
> >> > Unrolled Intel Legacy Tile-Y detiling logic.
> >> >
> >> > Also a consolidated patch file, instead of the previous development
> >> > flow based multiple patch files.
> >> >
> >> > v01-20200627IST1308
> >> >
> >> > Implemented Intel Legacy Tile-X and Tile-Y detiling logic
> >> >
> >> > NOTES:
> >> >
> >> > This video filter allows framebuffers which are tiled to be detiled
> >> > using logic running on the cpu, into a linear layout.
> >> >
> >> > Currently it supports Intel Legacy Tile-X and Tile-Y layout detiling.
> >> > THis should help one to work with frames captured (say using kmsgrab)
> >> > on laptops having Intel GPU.
> >> >
> >> > Tile-X conversion logic has been explicitly cross checked, with Tile-X
> >> > based frames. However Tile-Y conv logic hasnt been tested with Tile-Y
> >> > based frames, but it should potentially do the job, based on my
> current
> >> > understanding of the Tile-Y layout format.
> >> >
> >> > TODO1: At a later time have to generate Tile-Y based frames, and then
> >> > cross check the corresponding logic explicitly.
> >> >
> >> > TODO2: May be use OpenGL or Vulcan buffer helper routines to do the
> >> > layout conversion. But some online discussions from sometime back seem
> >> > to indicate that this path is not fully bug free currently.
> >> > ---
> >> >  Changelog                 |   1 +
> >> >  doc/filters.texi          |  62 ++++++++
> >> >  libavfilter/Makefile      |   1 +
> >> >  libavfilter/allfilters.c  |   1 +
> >> >  libavfilter/vf_fbdetile.c | 309
> ++++++++++++++++++++++++++++++++++++++
> >> >  5 files changed, 374 insertions(+)
> >> >  create mode 100644 libavfilter/vf_fbdetile.c
> >> >
> >> > diff --git a/Changelog b/Changelog
> >> > index a60e7d2eb8..0e03491f6a 100644
> >> > --- a/Changelog
> >> > +++ b/Changelog
> >> > @@ -2,6 +2,7 @@ Entries are sorted chronologically from oldest to
> >> youngest
> >> > within each release,
> >> >  releases are sorted from youngest to oldest.
> >> >
> >> >  version <next>:
> >> > +- fbdetile cpu based framebuffer layout detiling video filter
> >> >  - AudioToolbox output device
> >> >  - MacCaption demuxer
> >> >
> >> > diff --git a/doc/filters.texi b/doc/filters.texi
> >> > index 3c2dd2eb90..73ba21af89 100644
> >> > --- a/doc/filters.texi
> >> > +++ b/doc/filters.texi
> >> > @@ -12210,6 +12210,68 @@ It accepts the following optional parameters:
> >> >  The number of the CUDA device to use
> >> >  @end table
> >> >
> >> > + at anchor{fbdetile}
> >> > + at section fbdetile
> >> > +
> >> > +Detiles the Framebuffer tile layout into a linear layout using CPU.
> >> > +
> >> > +It currently supports conversion from Intel legacy tile-x and tile-y
> >> > layouts
> >> > +into a linear layout. This is useful if one is using kmsgrab and
> >> hwdownload
> >> > +to capture a screen which is using one of these non-linear layouts.
> >> > +
> >> > +Currently it expects the data to be a 32bit RGB based pixel format.
> >> However
> >> > +the logic doesnt do any pixel format conversion or so. Later will be
> >> > enabling
> >> > +16bit RGB data also, as the logic is transparent to it at one level.
> >> > +
> >> > +One could either insert this into the filter chain while capturing
> >> itself,
> >> > +or else, if it is slowing things down or so, then one could instead
> >> insert
> >> > +it into the filter chain during playback or transcoding or so.
> >> > +
> >> > +It supports the following optional parameters
> >> > +
> >> > + at table @option
> >> > + at item type
> >> > +Specify which detiling conversion to apply. The supported values are
> >> > + at table @var
> >> > + at item 0
> >> > +intel tile-x to linear conversion (the default)
> >> > + at item 1
> >> > +intel tile-y to linear conversion.
> >> > + at end table
> >> > + at end table
> >> > +
> >> > +If one wants to convert during capture itself, one could do
> >> > + at example
> >> > +ffmpeg -f kmsgrab -i - -vf "hwdownload, fbdetile" OUTPUT
> >> > + at end example
> >> > +
> >> > +However if one wants to convert after the tiled data has been already
> >> > captured
> >> > + at example
> >> > +ffmpeg -i INPUT -vf "fbdetile" OUTPUT
> >> > + at end example
> >> > + at example
> >> > +ffplay -i INPUT -vf "fbdetile"
> >> > + at end example
> >> > +
> >> > +NOTE: While transcoding a test 1080p h264 stream, with 276 frames,
> >> > with
> >> two
> >> > +runs of each situation, the performance was has given below. However
> >> this
> >> > +was for the older | initial version of the logic, as well as it was
> >> > run
> >> on
> >> > +the default linux chromebook->vm->container, so the perf values need
> >> not be
> >> > +proper. But in a relative sense the overhead would be similar.
> >> > + at example
> >> > +rm out.mp4; time ./ffmpeg -i input.mp4 out.mp4
> >> > +rm out.mp4; time ./ffmpeg -i input.mp4 -vf fbdetile=0 out.mp4
> >> > +rm out.mp4; time ./ffmpeg -i input.mp4 -vf fbdetile=1 out.mp4
> >> > + at end example
> >> > + at table @option
> >> > + at item with no fbdetile filter
> >> > +it took ~7.28 secs,
> >> > + at item with fbdetile=0 filter
> >> > +it took ~8.69 secs,
> >> > + at item with fbdetile=1 filter
> >> > +it took ~9.20 secs.
> >> > + at end table
> >> > +
> >> >  @section hqx
> >> >
> >> >  Apply a high-quality magnification filter designed for pixel art.
> This
> >> > filter
> >> > diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> >> > index 5123540653..bdb0c379ae 100644
> >> > --- a/libavfilter/Makefile
> >> > +++ b/libavfilter/Makefile
> >> > @@ -280,6 +280,7 @@ OBJS-$(CONFIG_HWDOWNLOAD_FILTER)             +=
> >> > vf_hwdownload.o
> >> >  OBJS-$(CONFIG_HWMAP_FILTER)                  += vf_hwmap.o
> >> >  OBJS-$(CONFIG_HWUPLOAD_CUDA_FILTER)          += vf_hwupload_cuda.o
> >> >  OBJS-$(CONFIG_HWUPLOAD_FILTER)               += vf_hwupload.o
> >> > +OBJS-$(CONFIG_FBDETILE_FILTER)               += vf_fbdetile.o
> >> >  OBJS-$(CONFIG_HYSTERESIS_FILTER)             += vf_hysteresis.o
> >> framesync.o
> >> >  OBJS-$(CONFIG_IDET_FILTER)                   += vf_idet.o
> >> >  OBJS-$(CONFIG_IL_FILTER)                     += vf_il.o
> >> > diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
> >> > index 1183e40267..f8dceb2a88 100644
> >> > --- a/libavfilter/allfilters.c
> >> > +++ b/libavfilter/allfilters.c
> >> > @@ -265,6 +265,7 @@ extern AVFilter ff_vf_hwdownload;
> >> >  extern AVFilter ff_vf_hwmap;
> >> >  extern AVFilter ff_vf_hwupload;
> >> >  extern AVFilter ff_vf_hwupload_cuda;
> >> > +extern AVFilter ff_vf_fbdetile;
> >> >  extern AVFilter ff_vf_hysteresis;
> >> >  extern AVFilter ff_vf_idet;
> >> >  extern AVFilter ff_vf_il;
> >> > diff --git a/libavfilter/vf_fbdetile.c b/libavfilter/vf_fbdetile.c
> >> > new file mode 100644
> >> > index 0000000000..8b20c96d2c
> >> > --- /dev/null
> >> > +++ b/libavfilter/vf_fbdetile.c
> >> > @@ -0,0 +1,309 @@
> >> > +/*
> >> > + * Copyright (c) 2020 HanishKVC
> >> > + *
> >> > + * This file is part of FFmpeg.
> >> > + *
> >> > + * FFmpeg is free software; you can redistribute it and/or
> >> > + * modify it under the terms of the GNU Lesser General Public
> >> > + * License as published by the Free Software Foundation; either
> >> > + * version 2.1 of the License, or (at your option) any later version.
> >> > + *
> >> > + * FFmpeg is distributed in the hope that it will be useful,
> >> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> >> > + * Lesser General Public License for more details.
> >> > + *
> >> > + * You should have received a copy of the GNU Lesser General Public
> >> > + * License along with FFmpeg; if not, write to the Free Software
> >> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> >> 02110-1301
> >> > USA
> >> > + */
> >> > +
> >> > +/**
> >> > + * @file
> >> > + * Detile the Frame buffer's tile layout using the cpu
> >> > + * Currently it supports the legacy Intel Tile X layout detiling.
> >> > + *
> >> > + */
> >> > +
> >> > +/*
> >> > + * ToThink|Check: Optimisations
> >> > + *
> >> > + * Does gcc setting used by ffmpeg allows memcpy | stringops
> inlining,
> >> > + * loop unrolling, better native matching instructions, additional
> >> > + * optimisations, ...
> >> > + *
> >> > + * Does gcc map to optimal memcpy logic, based on the situation it is
> >> > + * used in.
> >> > + *
> >> > + * If not, may be look at vector_size or intrinsics or appropriate
> >> > arch
> >> > + * and cpu specific inline asm or ...
> >> > + *
> >> > + */
> >> > +
> >> > +#include "libavutil/avassert.h"
> >> > +#include "libavutil/imgutils.h"
> >> > +#include "libavutil/opt.h"
> >> > +#include "avfilter.h"
> >> > +#include "formats.h"
> >> > +#include "internal.h"
> >> > +#include "video.h"
> >> > +
> >> > +enum FilterMode {
> >> > +    TYPE_INTELX,
> >> > +    TYPE_INTELY,
> >> > +    NB_TYPE
> >> > +};
> >> > +
> >> > +typedef struct FBDetileContext {
> >> > +    const AVClass *class;
> >> > +    int width, height;
> >> > +    int type;
> >> > +} FBDetileContext;
> >> > +
> >> > +#define OFFSET(x) offsetof(FBDetileContext, x)
> >> > +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
> >> > +static const AVOption fbdetile_options[] = {
> >> > +    { "type", "set framebuffer format_modifier type", OFFSET(type),
> >> > AV_OPT_TYPE_INT, {.i64=TYPE_INTELX}, 0, NB_TYPE-1, FLAGS, "type" },
> >> > +        { "intelx", "Intel Tile-X layout", 0, AV_OPT_TYPE_CONST,
> >> > {.i64=TYPE_INTELX}, INT_MIN, INT_MAX, FLAGS, "type" },
> >> > +        { "intely", "Intel Tile-Y layout", 0, AV_OPT_TYPE_CONST,
> >> > {.i64=TYPE_INTELY}, INT_MIN, INT_MAX, FLAGS, "type" },
> >> > +    { NULL }
> >> > +};
> >> > +
> >> > +AVFILTER_DEFINE_CLASS(fbdetile);
> >> > +
> >> > +static av_cold int init(AVFilterContext *ctx)
> >> > +{
> >> > +    FBDetileContext *fbdetile = ctx->priv;
> >> > +
> >> > +    if (fbdetile->type == TYPE_INTELX) {
> >> > +        fprintf(stderr,"INFO:fbdetile:init: Intel tile-x to
> >> > linear\n");
> >> > +    } else if (fbdetile->type == TYPE_INTELY) {
> >> > +        fprintf(stderr,"INFO:fbdetile:init: Intel tile-y to
> >> > linear\n");
> >> > +    } else {
> >> > +        fprintf(stderr,"DBUG:fbdetile:init: Unknown Tile format
> >> specified,
> >> > shouldnt reach here\n");
> >> > +    }
> >> > +    fbdetile->width = 1920;
> >> > +    fbdetile->height = 1080;
> >> > +    return 0;
> >> > +}
> >> > +
> >> > +static int query_formats(AVFilterContext *ctx)
> >> > +{
> >> > +    // Currently only RGB based 32bit formats are specified
> >> > +    // TODO: Technically the logic is transparent to 16bit RGB
> formats
> >> also
> >> > +    static const enum AVPixelFormat pix_fmts[] = {AV_PIX_FMT_RGB0,
> >> > AV_PIX_FMT_0RGB, AV_PIX_FMT_BGR0, AV_PIX_FMT_0BGR,
> >> > +                                                  AV_PIX_FMT_RGBA,
> >> > AV_PIX_FMT_ARGB, AV_PIX_FMT_BGRA, AV_PIX_FMT_ABGR,
> >> > +                                                  AV_PIX_FMT_NONE};
> >> > +    AVFilterFormats *fmts_list;
> >> > +
> >> > +    fmts_list = ff_make_format_list(pix_fmts);
> >> > +    if (!fmts_list)
> >> > +        return AVERROR(ENOMEM);
> >> > +    return ff_set_common_formats(ctx, fmts_list);
> >> > +}
> >> > +
> >> > +static int config_props(AVFilterLink *inlink)
> >> > +{
> >> > +    AVFilterContext *ctx = inlink->dst;
> >> > +    FBDetileContext *fbdetile = ctx->priv;
> >> > +
> >> > +    fbdetile->width = inlink->w;
> >> > +    fbdetile->height = inlink->h;
> >> > +    fprintf(stderr,"DBUG:fbdetile:config_props: %d x %d\n",
> >> > fbdetile->width, fbdetile->height);
> >> > +
> >> > +    return 0;
> >> > +}
> >> > +
> >> > +static void detile_intelx(AVFilterContext *ctx, int w, int h,
> >> > +                                uint8_t *dst, int dstLineSize,
> >> > +                          const uint8_t *src, int srcLineSize)
> >> > +{
> >> > +    // Offsets and LineSize are in bytes
> >> > +    int tileW = 128; // For a 32Bit / Pixel framebuffer, 512/4
> >> > +    int tileH = 8;
> >> > +
> >> > +    if (w*4 != srcLineSize) {
> >> > +        fprintf(stderr,"DBUG:fbdetile:intelx: w%dxh%d, dL%d, sL%d\n",
> >> w, h,
> >> > dstLineSize, srcLineSize);
> >> > +        fprintf(stderr,"ERRR:fbdetile:intelx: dont support LineSize |
> >> Pitch
> >> > going beyond width\n");
> >> > +    }
> >> > +    int sO = 0;
> >> > +    int dX = 0;
> >> > +    int dY = 0;
> >> > +    int nTRows = (w*h)/tileW;
> >> > +    int cTR = 0;
> >> > +    while (cTR < nTRows) {
> >> > +        int dO = dY*dstLineSize + dX*4;
> >> > +#ifdef DEBUG_FBTILE
> >> > +        fprintf(stderr,"DBUG:fbdetile:intelx: dX%d dY%d, sO%d,
> >> > dO%d\n",
> >> dX,
> >> > dY, sO, dO);
> >> > +#endif
> >> > +        memcpy(dst+dO+0*dstLineSize, src+sO+0*512, 512);
> >> > +        memcpy(dst+dO+1*dstLineSize, src+sO+1*512, 512);
> >> > +        memcpy(dst+dO+2*dstLineSize, src+sO+2*512, 512);
> >> > +        memcpy(dst+dO+3*dstLineSize, src+sO+3*512, 512);
> >> > +        memcpy(dst+dO+4*dstLineSize, src+sO+4*512, 512);
> >> > +        memcpy(dst+dO+5*dstLineSize, src+sO+5*512, 512);
> >> > +        memcpy(dst+dO+6*dstLineSize, src+sO+6*512, 512);
> >> > +        memcpy(dst+dO+7*dstLineSize, src+sO+7*512, 512);
> >> > +        dX += tileW;
> >> > +        if (dX >= w) {
> >> > +            dX = 0;
> >> > +            dY += 8;
> >> > +        }
> >> > +        sO = sO + 8*512;
> >> > +        cTR += 8;
> >> > +    }
> >> > +}
> >> > +
> >> > +/*
> >> > + * Intel Legacy Tile-Y layout conversion support
> >> > + *
> >> > + * currently done in a simple dumb way. Two low hanging optimisations
> >> > + * that could be readily applied are
> >> > + *
> >> > + * a) unrolling the inner for loop
> >> > + *    --- Given small size memcpy, should help, DONE
> >> > + *
> >> > + * b) using simd based 128bit loading and storing along with prefetch
> >> > + *    hinting.
> >> > + *
> >> > + *    TOTHINK|CHECK: Does memcpy already does this and more if
> >> > situation
> >> > + *    is right?!
> >> > + *
> >> > + *    As code (or even intrinsics) would be specific to each
> >> architecture,
> >> > + *    avoiding for now. Later have to check if vector_size attribute
> >> > and
> >> > + *    corresponding implementation by gcc can handle different
> >> > architectures
> >> > + *    properly, such that it wont become worse than memcpy provided
> >> > for
> >> > that
> >> > + *    architecture.
> >> > + *
> >> > + * Or maybe I could even merge the two intel detiling logics into
> one,
> >> as
> >> > + * the semantic and flow is almost same for both logics.
> >> > + *
> >> > + */
> >> > +static void detile_intely(AVFilterContext *ctx, int w, int h,
> >> > +                                uint8_t *dst, int dstLineSize,
> >> > +                          const uint8_t *src, int srcLineSize)
> >> > +{
> >> > +    // Offsets and LineSize are in bytes
> >> > +    int tileW = 4; // For a 32Bit / Pixel framebuffer, 16/4
> >> > +    int tileH = 32;
> >> > +
> >> > +    if (w*4 != srcLineSize) {
> >> > +        fprintf(stderr,"DBUG:fbdetile:intely: w%dxh%d, dL%d, sL%d\n",
> >> w, h,
> >> > dstLineSize, srcLineSize);
> >> > +        fprintf(stderr,"ERRR:fbdetile:intely: dont support LineSize |
> >> Pitch
> >> > going beyond width\n");
> >> > +    }
> >> > +    int sO = 0;
> >> > +    int dX = 0;
> >> > +    int dY = 0;
> >> > +    int nTRows = (w*h)/tileW;
> >> > +    int cTR = 0;
> >> > +    while (cTR < nTRows) {
> >> > +        int dO = dY*dstLineSize + dX*4;
> >> > +#ifdef DEBUG_FBTILE
> >> > +        fprintf(stderr,"DBUG:fbdetile:intely: dX%d dY%d, sO%d,
> >> > dO%d\n",
> >> dX,
> >> > dY, sO, dO);
> >> > +#endif
> >> > +
> >> > +        memcpy(dst+dO+0*dstLineSize, src+sO+0*16, 16);
> >> > +        memcpy(dst+dO+1*dstLineSize, src+sO+1*16, 16);
> >> > +        memcpy(dst+dO+2*dstLineSize, src+sO+2*16, 16);
> >> > +        memcpy(dst+dO+3*dstLineSize, src+sO+3*16, 16);
> >> > +        memcpy(dst+dO+4*dstLineSize, src+sO+4*16, 16);
> >> > +        memcpy(dst+dO+5*dstLineSize, src+sO+5*16, 16);
> >> > +        memcpy(dst+dO+6*dstLineSize, src+sO+6*16, 16);
> >> > +        memcpy(dst+dO+7*dstLineSize, src+sO+7*16, 16);
> >> > +        memcpy(dst+dO+8*dstLineSize, src+sO+8*16, 16);
> >> > +        memcpy(dst+dO+9*dstLineSize, src+sO+9*16, 16);
> >> > +        memcpy(dst+dO+10*dstLineSize, src+sO+10*16, 16);
> >> > +        memcpy(dst+dO+11*dstLineSize, src+sO+11*16, 16);
> >> > +        memcpy(dst+dO+12*dstLineSize, src+sO+12*16, 16);
> >> > +        memcpy(dst+dO+13*dstLineSize, src+sO+13*16, 16);
> >> > +        memcpy(dst+dO+14*dstLineSize, src+sO+14*16, 16);
> >> > +        memcpy(dst+dO+15*dstLineSize, src+sO+15*16, 16);
> >> > +        memcpy(dst+dO+16*dstLineSize, src+sO+16*16, 16);
> >> > +        memcpy(dst+dO+17*dstLineSize, src+sO+17*16, 16);
> >> > +        memcpy(dst+dO+18*dstLineSize, src+sO+18*16, 16);
> >> > +        memcpy(dst+dO+19*dstLineSize, src+sO+19*16, 16);
> >> > +        memcpy(dst+dO+20*dstLineSize, src+sO+20*16, 16);
> >> > +        memcpy(dst+dO+21*dstLineSize, src+sO+21*16, 16);
> >> > +        memcpy(dst+dO+22*dstLineSize, src+sO+22*16, 16);
> >> > +        memcpy(dst+dO+23*dstLineSize, src+sO+23*16, 16);
> >> > +        memcpy(dst+dO+24*dstLineSize, src+sO+24*16, 16);
> >> > +        memcpy(dst+dO+25*dstLineSize, src+sO+25*16, 16);
> >> > +        memcpy(dst+dO+26*dstLineSize, src+sO+26*16, 16);
> >> > +        memcpy(dst+dO+27*dstLineSize, src+sO+27*16, 16);
> >> > +        memcpy(dst+dO+28*dstLineSize, src+sO+28*16, 16);
> >> > +        memcpy(dst+dO+29*dstLineSize, src+sO+29*16, 16);
> >> > +        memcpy(dst+dO+30*dstLineSize, src+sO+30*16, 16);
> >> > +        memcpy(dst+dO+31*dstLineSize, src+sO+31*16, 16);
> >> > +
> >> > +        dX += tileW;
> >> > +        if (dX >= w) {
> >> > +            dX = 0;
> >> > +            dY += 32;
> >> > +        }
> >> > +        sO = sO + 32*16;
> >> > +        cTR += 32;
> >> > +    }
> >> > +}
> >> > +
> >> > +static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> >> > +{
> >> > +    AVFilterContext *ctx = inlink->dst;
> >> > +    FBDetileContext *fbdetile = ctx->priv;
> >> > +    AVFilterLink *outlink = ctx->outputs[0];
> >> > +    AVFrame *out;
> >> > +
> >> > +    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);
> >> > +
> >> > +    if (fbdetile->type == TYPE_INTELX) {
> >> > +        detile_intelx(ctx, fbdetile->width, fbdetile->height,
> >> > +                      out->data[0], out->linesize[0],
> >> > +                      in->data[0], in->linesize[0]);
> >> > +    } else if (fbdetile->type == TYPE_INTELY) {
> >> > +        detile_intely(ctx, fbdetile->width, fbdetile->height,
> >> > +                      out->data[0], out->linesize[0],
> >> > +                      in->data[0], in->linesize[0]);
> >> > +    }
> >> > +
> >> > +    av_frame_free(&in);
> >> > +    return ff_filter_frame(outlink, out);
> >> > +}
> >> > +
> >> > +static av_cold void uninit(AVFilterContext *ctx)
> >> > +{
> >> > +
> >> > +}
> >> > +
> >> > +static const AVFilterPad fbdetile_inputs[] = {
> >> > +    {
> >> > +        .name         = "default",
> >> > +        .type         = AVMEDIA_TYPE_VIDEO,
> >> > +        .config_props = config_props,
> >> > +        .filter_frame = filter_frame,
> >> > +    },
> >> > +    { NULL }
> >> > +};
> >> > +
> >> > +static const AVFilterPad fbdetile_outputs[] = {
> >> > +    {
> >> > +        .name = "default",
> >> > +        .type = AVMEDIA_TYPE_VIDEO,
> >> > +    },
> >> > +    { NULL }
> >> > +};
> >> > +
> >> > +AVFilter ff_vf_fbdetile = {
> >> > +    .name          = "fbdetile",
> >> > +    .description   = NULL_IF_CONFIG_SMALL("Detile Framebuffer using
> >> CPU"),
> >> > +    .priv_size     = sizeof(FBDetileContext),
> >> > +    .init          = init,
> >> > +    .uninit        = uninit,
> >> > +    .query_formats = query_formats,
> >> > +    .inputs        = fbdetile_inputs,
> >> > +    .outputs       = fbdetile_outputs,
> >> > +    .priv_class    = &fbdetile_class,
> >> > +};
> >> > --
> >> > 2.20.1
> >> >
> >> > _______________________________________________
> >> > ffmpeg-devel mailing list
> >> > ffmpeg-devel at ffmpeg.org
> >> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >> >
> >> > To unsubscribe, visit link above, or email
> >> > ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
> >>
> >
> >
> > --
> > Keep ;-)
> > HanishKVC
> >
>


-- 
Keep ;-)
HanishKVC


More information about the ffmpeg-devel mailing list