[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