On Tue, Aug 07, 2018 at 12:17:58AM +0300, Sergey Lavrushkin wrote: > I split patch to one for libavutil and another for libswscale, > also added LUT for unscaled conversion, added > conversions for scaling and updated fate tests.
> libavutil/pixdesc.c | 22 ++++++++++++++++++++++ > libavutil/pixfmt.h | 5 +++++ > libavutil/version.h | 2 +- > tests/ref/fate/sws-pixdesc-query | 3 +++ > 4 files changed, 31 insertions(+), 1 deletion(-) > b58f328f5d90954c62957f127b1acbfad5795a4d > 0004-libavutil-Adds-gray-floating-point-pixel-formats.patch > From 8bcc10b49c41612b4d6549e64d90acf3f0b3fc6a Mon Sep 17 00:00:00 2001 > From: Sergey Lavrushkin <dual...@gmail.com> > Date: Fri, 3 Aug 2018 18:02:49 +0300 > Subject: [PATCH 4/9] libavutil: Adds gray floating-point pixel formats. > > --- > libavutil/pixdesc.c | 22 ++++++++++++++++++++++ > libavutil/pixfmt.h | 5 +++++ > libavutil/version.h | 2 +- > tests/ref/fate/sws-pixdesc-query | 3 +++ > 4 files changed, 31 insertions(+), 1 deletion(-) > > diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c > index 96e079584a..970a83214c 100644 > --- a/libavutil/pixdesc.c > +++ b/libavutil/pixdesc.c > @@ -2206,6 +2206,28 @@ static const AVPixFmtDescriptor > av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { > .name = "opencl", > .flags = AV_PIX_FMT_FLAG_HWACCEL, > }, > + [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", > + }, > }; > #if FF_API_PLUS1_MINUS1 > FF_ENABLE_DEPRECATION_WARNINGS > diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h > index 2b3307845e..7b254732d8 100644 > --- a/libavutil/pixfmt.h > +++ b/libavutil/pixfmt.h > @@ -337,6 +337,9 @@ enum AVPixelFormat { > AV_PIX_FMT_GRAY14BE, ///< Y , 14bpp, big-endian > AV_PIX_FMT_GRAY14LE, ///< Y , 14bpp, 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 > + > AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if > you want to link with shared libav* because the number of formats might > differ between versions > }; > > @@ -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/libavutil/version.h b/libavutil/version.h > index 44bdebdc93..5205c5bc60 100644 > --- a/libavutil/version.h > +++ b/libavutil/version.h > @@ -79,7 +79,7 @@ > */ > > #define LIBAVUTIL_VERSION_MAJOR 56 > -#define LIBAVUTIL_VERSION_MINOR 18 > +#define LIBAVUTIL_VERSION_MINOR 19 > #define LIBAVUTIL_VERSION_MICRO 102 > > #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ > diff --git a/tests/ref/fate/sws-pixdesc-query > b/tests/ref/fate/sws-pixdesc-query > index 8071ec484d..451c7d83b9 100644 > --- a/tests/ref/fate/sws-pixdesc-query > +++ b/tests/ref/fate/sws-pixdesc-query > @@ -126,6 +126,7 @@ isBE: > gray14be > gray16be > gray9be > + grayf32be > nv20be > p010be > p016be > @@ -412,6 +413,8 @@ Gray: > gray16le > gray9be > gray9le > + grayf32be > + grayf32le > ya16be > ya16le > ya8 > -- > 2.14.1 > > libswscale/input.c | 38 +++++++++++++++++++ > libswscale/output.c | 60 > +++++++++++++++++++++++++++++++ > libswscale/ppc/swscale_altivec.c | 1 > libswscale/swscale_internal.h | 9 ++++ > libswscale/swscale_unscaled.c | 54 ++++++++++++++++++++++++++- > libswscale/utils.c | 20 +++++++++- > libswscale/x86/swscale_template.c | 3 + > tests/ref/fate/filter-pixdesc-grayf32be | 1 > tests/ref/fate/filter-pixdesc-grayf32le | 1 > tests/ref/fate/filter-pixfmts-copy | 2 + > tests/ref/fate/filter-pixfmts-crop | 2 + > tests/ref/fate/filter-pixfmts-field | 2 + > tests/ref/fate/filter-pixfmts-fieldorder | 2 + > tests/ref/fate/filter-pixfmts-hflip | 2 + > tests/ref/fate/filter-pixfmts-il | 2 + > tests/ref/fate/filter-pixfmts-null | 2 + > tests/ref/fate/filter-pixfmts-scale | 2 + > tests/ref/fate/filter-pixfmts-transpose | 2 + > tests/ref/fate/filter-pixfmts-vflip | 2 + > 19 files changed, 203 insertions(+), 4 deletions(-) > 19652102078d9ddbf157bd51332e3bfd1971481e > 0005-libswscale-Adds-conversions-from-to-float-gray-forma.patch > From 35f97f77465bec4344ac7d5a6742388d9c1470cc Mon Sep 17 00:00:00 2001 > From: Sergey Lavrushkin <dual...@gmail.com> > Date: Fri, 3 Aug 2018 18:06:50 +0300 > Subject: [PATCH 5/9] libswscale: Adds conversions from/to float gray format. > > --- > libswscale/input.c | 38 ++++++++++++++++++++ > libswscale/output.c | 60 > ++++++++++++++++++++++++++++++++ > libswscale/ppc/swscale_altivec.c | 1 + > libswscale/swscale_internal.h | 9 +++++ > libswscale/swscale_unscaled.c | 54 ++++++++++++++++++++++++++-- > libswscale/utils.c | 20 ++++++++++- > libswscale/x86/swscale_template.c | 3 +- > tests/ref/fate/filter-pixdesc-grayf32be | 1 + > tests/ref/fate/filter-pixdesc-grayf32le | 1 + > tests/ref/fate/filter-pixfmts-copy | 2 ++ > tests/ref/fate/filter-pixfmts-crop | 2 ++ > tests/ref/fate/filter-pixfmts-field | 2 ++ > tests/ref/fate/filter-pixfmts-fieldorder | 2 ++ > tests/ref/fate/filter-pixfmts-hflip | 2 ++ > tests/ref/fate/filter-pixfmts-il | 2 ++ > tests/ref/fate/filter-pixfmts-null | 2 ++ > tests/ref/fate/filter-pixfmts-scale | 2 ++ > tests/ref/fate/filter-pixfmts-transpose | 2 ++ > tests/ref/fate/filter-pixfmts-vflip | 2 ++ > 19 files changed, 203 insertions(+), 4 deletions(-) > create mode 100644 tests/ref/fate/filter-pixdesc-grayf32be > create mode 100644 tests/ref/fate/filter-pixdesc-grayf32le > > diff --git a/libswscale/input.c b/libswscale/input.c > index 3fd3a5d81e..bd2000470a 100644 > --- a/libswscale/input.c > +++ b/libswscale/input.c > @@ -942,6 +942,30 @@ static av_always_inline void planar_rgb16_to_uv(uint8_t > *_dstU, uint8_t *_dstV, > } > #undef rdpx > > +static av_always_inline void grayf32ToY16_c(uint8_t *_dst, const uint8_t > *_src, const uint8_t *unused1, > + const uint8_t *unused2, int > width, uint32_t *unused) > +{ > + int i; > + const float *src = (const float *)_src; > + uint16_t *dst = (uint16_t *)_dst; > + > + for (i = 0; i < width; ++i){ > + dst[i] = (uint16_t)(65535.0f * FFMIN(FFMAX(src[i], 0.0f), 1.0f) + > 0.5f); > + } > +} we generally use lrintf() to convert float to integers casts may requires change to rounding settings of the FPU on some platforms > + > +static av_always_inline void grayf32ToY16_bswap_c(uint8_t *_dst, const > uint8_t *_src, const uint8_t *unused1, > + const uint8_t *unused2, > int width, uint32_t *unused) > +{ > + int i; > + const float *src = (const float *)_src; > + uint16_t *dst = (uint16_t *)_dst; > + > + for (i = 0; i < width; ++i){ > + dst[i] = (uint16_t)(65535.0f * FFMIN(FFMAX(av_bswap32(src[i]), > 0.0f), 1.0f) + 0.5f); > + } > +} Was this tested ? > + > #define rgb9plus_planar_funcs_endian(nbits, endian_name, endian) > \ > static void planar_rgb##nbits##endian_name##_to_y(uint8_t *dst, const > uint8_t *src[4], \ > int w, int32_t *rgb2yuv) > \ > @@ -1538,6 +1562,20 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) > case AV_PIX_FMT_P010BE: > c->lumToYV12 = p010BEToY_c; > break; > + case AV_PIX_FMT_GRAYF32LE: > + #if HAVE_BIGENDIAN > + c->lumToYV12 = grayf32ToY16_bswap_c; > + #else > + c->lumToYV12 = grayf32ToY16_c; > + #endif > + break; > + case AV_PIX_FMT_GRAYF32BE: > + #if HAVE_BIGENDIAN > + c->lumToYV12 = grayf32ToY16_c; > + #else > + c->lumToYV12 = grayf32ToY16_bswap_c; > + #endif > + break; please put preprocessor stuff with the "#" at the first column. There was some compatibility issue if this is not done > } > if (c->needAlpha) { > if (is16BPS(srcFormat) || isNBPS(srcFormat)) { > diff --git a/libswscale/output.c b/libswscale/output.c > index 0af2fffea4..f388c74d1c 100644 > --- a/libswscale/output.c > +++ b/libswscale/output.c > @@ -208,6 +208,60 @@ static void yuv2p016cX_c(SwsContext *c, const int16_t > *chrFilter, int chrFilterS > } > } > > +static av_always_inline void > +yuv2plane1_float_c_template(const int32_t *src, float *dest, int dstW, int > big_endian) > +{ > + static const int shift = 3; > + static const float float_mult = 1.0f / 65535.0f; > + int i, val; > + uint16_t val_uint; > + > + for (i = 0; i < dstW; ++i){ > + val = src[i] + (1 << (shift - 1)); > + output_pixel(&val_uint, val, 0, uint); > + dest[i] = float_mult * (float)val_uint; > + } > +} > + > +static av_always_inline void > +yuv2planeX_float_c_template(const int16_t *filter, int filterSize, const > int32_t **src, > + float *dest, int dstW, int big_endian) > +{ > + static const int shift = 15; > + static const float float_mult = 1.0f / 65535.0f; > + int i, j, val; > + uint16_t val_uint; > + > + for (i = 0; i < dstW; ++i){ > + val = (1 << (shift - 1)) - 0x40000000; > + for (j = 0; j < filterSize; ++j){ > + val += src[j][i] * (unsigned)filter[j]; > + } > + output_pixel(&val_uint, val, 0x8000, int); > + dest[i] = float_mult * (float)val_uint; > + } > +} > + > +#define yuv2plane1_float(is_be, BE_LE) \ > +static void yuv2plane1_float ## BE_LE ## _c(const int16_t *src, uint8_t > *dest, int dstW, \ > + const uint8_t *dither, int > offset) \ > +{ \ > + yuv2plane1_float_c_template((const int32_t *)src, (float *)dest, dstW, > is_be); \ > +} > + > +#define yuv2planeX_float(is_be, BE_LE) \ > +static void yuv2planeX_float ## BE_LE ## _c(const int16_t *filter, int > filterSize, \ > + const int16_t **src, uint8_t > *dest, int dstW, \ > + const uint8_t *dither, int > offset) \ > +{ \ > + yuv2planeX_float_c_template(filter, filterSize, (const int32_t **)src, > (float *)dest, dstW, is_be); \ > +} > + > +yuv2plane1_float(0, LE) > +yuv2plane1_float(1, BE) > +yuv2planeX_float(0, LE) > +yuv2planeX_float(1, BE) > + > #undef output_pixel > > #define output_pixel(pos, val) \ > @@ -2303,6 +2357,12 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c, > *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_14BE_c : > yuv2plane1_14LE_c; > } else > av_assert0(0); > + } else if (dstFormat == AV_PIX_FMT_GRAYF32BE) { > + *yuv2planeX = yuv2planeX_floatBE_c; > + *yuv2plane1 = yuv2plane1_floatBE_c; > + } else if (dstFormat == AV_PIX_FMT_GRAYF32LE) { > + *yuv2planeX = yuv2planeX_floatLE_c; > + *yuv2plane1 = yuv2plane1_floatLE_c; > } else { > *yuv2plane1 = yuv2plane1_8_c; > *yuv2planeX = yuv2planeX_8_c; > diff --git a/libswscale/ppc/swscale_altivec.c > b/libswscale/ppc/swscale_altivec.c > index 9438a63ff2..2fb2337769 100644 > --- a/libswscale/ppc/swscale_altivec.c > +++ b/libswscale/ppc/swscale_altivec.c > @@ -339,6 +339,7 @@ av_cold void ff_sws_init_swscale_ppc(SwsContext *c) > } > if (!is16BPS(dstFormat) && !isNBPS(dstFormat) && > dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21 && > + dstFormat != AV_PIX_FMT_GRAYF32BE && dstFormat != > AV_PIX_FMT_GRAYF32LE && > !c->needAlpha) { > c->yuv2planeX = yuv2planeX_altivec; > } > diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h > index 1703856ab2..4fa59386a6 100644 > --- a/libswscale/swscale_internal.h > +++ b/libswscale/swscale_internal.h > @@ -336,6 +336,8 @@ typedef struct SwsContext { > uint32_t pal_yuv[256]; > uint32_t pal_rgb[256]; > > + float uint2float_lut[256]; > + > /** > * @name Scaled horizontal lines ring buffer. > * The horizontal scaler keeps just enough scaled lines in a ring buffer > @@ -764,6 +766,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..f2242fe185 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; > + ptrdiff_t dstStrideFloat = dstStride[0] >> 2; > + 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] = c->uint2float_lut[srcPtr[x]]; > + } > + srcPtr += srcStride[0]; > + dstPtr += dstStrideFloat; > + } > + > + return srcSliceH; > +} > + > +static int float_y_to_uint_y_wrapper(SwsContext *c, const uint8_t* src[], > + int srcStride[], int srcSliceY, > + int srcSliceH, uint8_t* dst[], int > dstStride[]) > +{ > + int y, x; > + ptrdiff_t srcStrideFloat = srcStride[0] >> 2; > + const float *srcPtr = (const float *)src[0]; > + uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY; > + > + for (y = 0; y < srcSliceH; ++y){ > + for (x = 0; x < c->srcW; ++x){ > + dstPtr[x] = (uint8_t)(255.0f * FFMIN(FFMAX(srcPtr[x], 0.0f), > 1.0f) + 0.5f); > + } > + srcPtr += srcStrideFloat; > + dstPtr += dstStride[0]; > + } > + > + return srcSliceH; > +} > + > /* unscaled copy like stuff (assumes nearly identical formats) */ > static int packedCopyWrapper(SwsContext *c, const uint8_t *src[], > int srcStride[], int srcSliceY, int srcSliceH, > @@ -1899,6 +1939,16 @@ void ff_get_unscaled_swscale(SwsContext *c) > c->swscale = yuv422pToUyvyWrapper; > } > > + /* uint Y to float Y */ > + if (srcFormat == AV_PIX_FMT_GRAY8 && dstFormat == AV_PIX_FMT_GRAYF32){ > + c->swscale = uint_y_to_float_y_wrapper; > + } > + > + /* float Y to uint Y */ > + if (srcFormat == AV_PIX_FMT_GRAYF32 && dstFormat == AV_PIX_FMT_GRAY8){ > + c->swscale = float_y_to_uint_y_wrapper; > + } > + > /* LQ converters if -sws 0 or -sws 4*/ > if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)) { > /* yv12_to_yuy2 */ > @@ -1925,13 +1975,13 @@ void ff_get_unscaled_swscale(SwsContext *c) > if ( srcFormat == dstFormat || > (srcFormat == AV_PIX_FMT_YUVA420P && dstFormat == > AV_PIX_FMT_YUV420P) || > (srcFormat == AV_PIX_FMT_YUV420P && dstFormat == > AV_PIX_FMT_YUVA420P) || > - (isPlanarYUV(srcFormat) && isPlanarGray(dstFormat)) || > + (isFloat(srcFormat) == isFloat(dstFormat)) && > ((isPlanarYUV(srcFormat) && isPlanarGray(dstFormat)) || > (isPlanarYUV(dstFormat) && isPlanarGray(srcFormat)) || > (isPlanarGray(dstFormat) && isPlanarGray(srcFormat)) || > (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat) && > c->chrDstHSubSample == c->chrSrcHSubSample && > c->chrDstVSubSample == c->chrSrcVSubSample && > - !isSemiPlanarYUV(srcFormat) && !isSemiPlanarYUV(dstFormat))) > + !isSemiPlanarYUV(srcFormat) && !isSemiPlanarYUV(dstFormat)))) > { > if (isPacked(c->srcFormat)) > c->swscale = packedCopyWrapper; > diff --git a/libswscale/utils.c b/libswscale/utils.c > index 61b47182f8..f10638b045 100644 > --- a/libswscale/utils.c > +++ b/libswscale/utils.c > @@ -258,6 +258,8 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { > [AV_PIX_FMT_P010BE] = { 1, 1 }, > [AV_PIX_FMT_P016LE] = { 1, 1 }, > [AV_PIX_FMT_P016BE] = { 1, 1 }, > + [AV_PIX_FMT_GRAYF32LE] = { 1, 1 }, > + [AV_PIX_FMT_GRAYF32BE] = { 1, 1 }, please keep teh = vertically aligned [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB You can kill me, but you cannot change the truth.
signature.asc
Description: PGP signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel