[FFmpeg-devel] [PATCH 4/7] Adds gray floating-point pixel formats.

Sergey Lavrushkin dualfal at gmail.com
Fri Aug 3 22:33:00 EEST 2018


2018-08-03 16:07 GMT+03:00 Michael Niedermayer <michael at niedermayer.cc>:

> On Thu, Aug 02, 2018 at 09:52:45PM +0300, Sergey Lavrushkin wrote:
> > This patch adds two floating-point gray formats to use them in sr filter
> for
> > conversion with libswscale. I added conversion from uint gray to float
> and
> > backwards in swscale_unscaled.c, that is enough for sr filter. But for
> > proper format addition, should I add anything else?
> >
> > ---
> >  libavutil/pixdesc.c           | 22 ++++++++++++++++++
> >  libavutil/pixfmt.h            |  5 ++++
> >  libswscale/swscale_internal.h |  7 ++++++
> >  libswscale/swscale_unscaled.c | 54 ++++++++++++++++++++++++++++++
> +++++++++++--
> >  libswscale/utils.c            |  5 +++-
>
> please split this in a patch or libavutil and one for libswscale
> they also need some version.h bump
>

Ok.

also fate tests need an update, (make fate) fails otherwise, the update
> should
> be part of the patch that causes the failure otherwise


In one test for these formats I get:

filter-pixfmts-scale
grayf32be           grayf32le           monob
 f01cb0b623357387827902d9d0963435

I guess, it is because I only implemented conversion in swscale_unscaled.
What can I do to fix it? Should I implement conversion for scaling or maybe
change something in the test, so it would not check these formats (if it is
possible).
Anyway, I need to know what changes should I do and where.


> >  5 files changed, 90 insertions(+), 3 deletions(-)
> >
> > diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
> > index 96e079584a..7d307d9120 100644
> > --- a/libavutil/pixdesc.c
> > +++ b/libavutil/pixdesc.c
> > @@ -2198,6 +2198,28 @@ static const AVPixFmtDescriptor
> av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
> >          .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA |
> >                   AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_FLOAT,
> >      },
> > +    [AV_PIX_FMT_GRAYF32BE] = {
> > +        .name = "grayf32be",
> > +        .nb_components = 1,
> > +        .log2_chroma_w = 0,
> > +        .log2_chroma_h = 0,
> > +        .comp = {
> > +            { 0, 4, 0, 0, 32, 3, 31, 1 },       /* Y */
> > +        },
> > +        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_FLOAT,
> > +        .alias = "yf32be",
> > +    },
> > +    [AV_PIX_FMT_GRAYF32LE] = {
> > +        .name = "grayf32le",
> > +        .nb_components = 1,
> > +        .log2_chroma_w = 0,
> > +        .log2_chroma_h = 0,
> > +        .comp = {
> > +            { 0, 4, 0, 0, 32, 3, 31, 1 },       /* Y */
> > +        },
> > +        .flags = AV_PIX_FMT_FLAG_FLOAT,
> > +        .alias = "yf32le",
> > +    },
> >      [AV_PIX_FMT_DRM_PRIME] = {
> >          .name = "drm_prime",
> >          .flags = AV_PIX_FMT_FLAG_HWACCEL,
>
> > diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
> > index 2b3307845e..aa9a4f60c1 100644
> > --- a/libavutil/pixfmt.h
> > +++ b/libavutil/pixfmt.h
> > @@ -320,6 +320,9 @@ enum AVPixelFormat {
> >      AV_PIX_FMT_GBRAPF32BE, ///< IEEE-754 single precision planar GBRA
> 4:4:4:4, 128bpp, big-endian
> >      AV_PIX_FMT_GBRAPF32LE, ///< IEEE-754 single precision planar GBRA
> 4:4:4:4, 128bpp, little-endian
> >
> > +    AV_PIX_FMT_GRAYF32BE,  ///< IEEE-754 single precision Y, 32bpp,
> big-endian
> > +    AV_PIX_FMT_GRAYF32LE,  ///< IEEE-754 single precision Y, 32bpp,
> little-endian
> > +
> >      /**
> >       * DRM-managed buffers exposed through PRIME buffer sharing.
> >       *
>
> new enum values can only be added in such a way that no value of an
> existing
> enum changes. This would change the value of the following enums


Ok.

> @@ -405,6 +408,8 @@ enum AVPixelFormat {
> >  #define AV_PIX_FMT_GBRPF32    AV_PIX_FMT_NE(GBRPF32BE,  GBRPF32LE)
> >  #define AV_PIX_FMT_GBRAPF32   AV_PIX_FMT_NE(GBRAPF32BE, GBRAPF32LE)
> >
> > +#define AV_PIX_FMT_GRAYF32 AV_PIX_FMT_NE(GRAYF32BE, GRAYF32LE)
> > +
> >  #define AV_PIX_FMT_YUVA420P9  AV_PIX_FMT_NE(YUVA420P9BE , YUVA420P9LE)
> >  #define AV_PIX_FMT_YUVA422P9  AV_PIX_FMT_NE(YUVA422P9BE , YUVA422P9LE)
> >  #define AV_PIX_FMT_YUVA444P9  AV_PIX_FMT_NE(YUVA444P9BE , YUVA444P9LE)
> > diff --git a/libswscale/swscale_internal.h
> b/libswscale/swscale_internal.h
> > index 1703856ab2..4a2cdfe658 100644
> > --- a/libswscale/swscale_internal.h
> > +++ b/libswscale/swscale_internal.h
> > @@ -764,6 +764,13 @@ static av_always_inline int isAnyRGB(enum
> AVPixelFormat pix_fmt)
> >              pix_fmt == AV_PIX_FMT_MONOBLACK || pix_fmt ==
> AV_PIX_FMT_MONOWHITE;
> >  }
> >
> > +static av_always_inline int isFloat(enum AVPixelFormat pix_fmt)
> > +{
> > +    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
> > +    av_assert0(desc);
> > +    return desc->flags & AV_PIX_FMT_FLAG_FLOAT;
> > +}
> > +
> >  static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt)
> >  {
> >      const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
>
> > diff --git a/libswscale/swscale_unscaled.c
> b/libswscale/swscale_unscaled.c
> > index 6480070cbf..f5b4c9be9d 100644
> > --- a/libswscale/swscale_unscaled.c
> > +++ b/libswscale/swscale_unscaled.c
> > @@ -1467,6 +1467,46 @@ static int yvu9ToYv12Wrapper(SwsContext *c, const
> uint8_t *src[],
> >      return srcSliceH;
> >  }
> >
> > +static int uint_y_to_float_y_wrapper(SwsContext *c, const uint8_t
> *src[],
> > +                                     int srcStride[], int srcSliceY,
> > +                                     int srcSliceH, uint8_t *dst[], int
> dstStride[])
> > +{
> > +    int y, x;
> > +    int dstStrideFloat = dstStride[0] >> 2;;
>
> theres a ; too much
> also newly added strides should probably be ptrdiff_t


Ok.

> +    const uint8_t *srcPtr = src[0];
> > +    float *dstPtr = (float *)(dst[0] + dstStride[0] * srcSliceY);
> > +
> > +    for (y = 0; y < srcSliceH; ++y){
> > +        for (x = 0; x < c->srcW; ++x){
> > +            dstPtr[x] = (float)srcPtr[x] / 255.0f;
>
> division is slow. This should either be a multiplication with the
> inverse or a LUT with 8bit index changing to float.
>
> The faster of them should be used
>

LUT seems to be faster. Can I place it in SwsContext and initialize it in
sws_init_context when necessary?


More information about the ffmpeg-devel mailing list