[FFmpeg-devel] [PATCH 4/7] Adds gray floating-point pixel formats.
Sergey Lavrushkin
dualfal at gmail.com
Thu Aug 2 21:52:45 EEST 2018
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
More information about the ffmpeg-devel
mailing list