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 +++- 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. * @@ -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;; + 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; + } + 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; + int 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)); + } + 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..dffb236724 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 }, }; int sws_isSupportedInput(enum AVPixelFormat pix_fmt) @@ -1793,7 +1795,8 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, /* unscaled special cases */ if (unscaled && !usesHFilter && !usesVFilter && - (c->srcRange == c->dstRange || isAnyRGB(dstFormat))) { + (c->srcRange == c->dstRange || isAnyRGB(dstFormat) || + srcFormat == AV_PIX_FMT_GRAYF32 || dstFormat == AV_PIX_FMT_GRAYF32)) { ff_get_unscaled_swscale(c); if (c->swscale) { -- 2.14.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel