[FFmpeg-devel,2/6] swscale: add swscale support for 422/444 decode outputs

Submitted by Linjie Fu on Sept. 10, 2019, 4:06 p.m.

Details

Message ID 1568131613-19349-1-git-send-email-linjie.fu@intel.com
State New
Headers show

Commit Message

Linjie Fu Sept. 10, 2019, 4:06 p.m.
Signed-off-by: Linjie Fu <linjie.fu@intel.com>
---
 libswscale/input.c   | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 libswscale/output.c  | 50 +++++++++++++++++++++++++++++++++++
 libswscale/utils.c   |  3 +++
 libswscale/version.h |  2 +-
 4 files changed, 128 insertions(+), 1 deletion(-)

Comments

Carl Eugen Hoyos Sept. 10, 2019, 7:32 p.m.
Am Di., 10. Sept. 2019 um 18:09 Uhr schrieb Linjie Fu <linjie.fu@intel.com>:

> --- a/libswscale/output.c
> +++ b/libswscale/output.c
> @@ -2403,6 +2403,53 @@ yuv2ya8_X_c(SwsContext *c, const int16_t *lumFilter,
>  }
>
>  static void
> +yuv2ayuv_X_c(SwsContext *c, const int16_t *lumFilter,
> +                 const int16_t **lumSrc, int lumFilterSize,
> +                 const int16_t *chrFilter, const int16_t **chrUSrc,
> +                 const int16_t **chrVSrc, int chrFilterSize,
> +                 const int16_t **alpSrc, uint8_t *dest, int dstW, int y)

The commit message does not match this change.
Do I understand correctly that encoding is expected from AYUV
but not from the other formats?
Or is this the result of an earlier comment?
I don't know if splitting the patch would make it clearer.

Carl Eugen
Linjie Fu Sept. 11, 2019, 5:35 a.m.
> -----Original Message-----

> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf

> Of Carl Eugen Hoyos

> Sent: Wednesday, September 11, 2019 03:32

> To: FFmpeg development discussions and patches <ffmpeg-

> devel@ffmpeg.org>

> Subject: Re: [FFmpeg-devel] [PATCH 2/6] swscale: add swscale support for

> 422/444 decode outputs

> 

> Am Di., 10. Sept. 2019 um 18:09 Uhr schrieb Linjie Fu <linjie.fu@intel.com>:

> 

> > --- a/libswscale/output.c

> > +++ b/libswscale/output.c

> > @@ -2403,6 +2403,53 @@ yuv2ya8_X_c(SwsContext *c, const int16_t

> *lumFilter,

> >  }

> >

> >  static void

> > +yuv2ayuv_X_c(SwsContext *c, const int16_t *lumFilter,

> > +                 const int16_t **lumSrc, int lumFilterSize,

> > +                 const int16_t *chrFilter, const int16_t **chrUSrc,

> > +                 const int16_t **chrVSrc, int chrFilterSize,

> > +                 const int16_t **alpSrc, uint8_t *dest, int dstW, int y)

> 

> The commit message does not match this change.

> Do I understand correctly that encoding is expected from AYUV

> but not from the other formats?

> Or is this the result of an earlier comment?


+    [AV_PIX_FMT_Y210BE]      = { 1, 0 },
+    [AV_PIX_FMT_Y210LE]      = { 1, 0 },
+    [AV_PIX_FMT_AYUV]        = { 1, 1 },

This patch aims at adding swscale input support  for Y210/AYUV and
output/encoding support for AYUV only.

IMHO swscale input support for these packed pixel format is good 
at current stage.(since there is no requirement for software
CSC to these packed pixel formats)

For Y410, it's kind of different:
https://docs.microsoft.com/en-us/windows/win32/medfound/10-bit-and-16-bit-yuv-video-formats#y410

Bits 0-9 contain the U sample, bits 10-19 contain the Y sample, bits 20-29
contain the V sample, and bits 30-31 contain the alpha value.

Some attempts have been made locally to support swscale input for Y410:
https://github.com/fulinjie/ffmpeg/commits/pr-y410

And I think the swscale input support for Y410 could be held.

> I don't know if splitting the patch would make it clearer.

Sure, will split it for each pixel format.

Regards,
Linjie

Patch hide | download patch | download mbox

diff --git a/libswscale/input.c b/libswscale/input.c
index 064f8da..1642807 100644
--- a/libswscale/input.c
+++ b/libswscale/input.c
@@ -552,6 +552,61 @@  static void yvy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *unused0, con
     av_assert1(src1 == src2);
 }
 
+static void y210le_UV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *unused0, const uint8_t *src,
+                        const uint8_t *unused1, int width, uint32_t *unused2)
+{
+    int i;
+    for (i = 0; i < width; i++) {
+        AV_WN16(dstU + i * 2, AV_RL16(src + i * 8 + 2) >> 6);
+        AV_WN16(dstV + i * 2, AV_RL16(src + i * 8 + 6) >> 6);
+    }
+}
+
+static void y210be_UV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *unused0, const uint8_t *src,
+                        const uint8_t *unused1, int width, uint32_t *unused2)
+{
+    int i;
+    for (i = 0; i < width; i++) {
+        AV_WN16(dstU + i * 2, AV_RB16(src + i * 8 + 2) >> 6);
+        AV_WN16(dstV + i * 2, AV_RB16(src + i * 8 + 6) >> 6);
+    }
+}
+
+static void y210le_Y_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused0,
+                       const uint8_t *unused1, int width, uint32_t *unused2)
+{
+    int i;
+    for (i = 0; i < width; i++)
+        AV_WN16(dst + i * 2, AV_RL16(src + i * 4) >> 6);
+}
+
+static void y210be_Y_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused0,
+                       const uint8_t *unused1, int width, uint32_t *unused2)
+{
+    int i;
+    for (i = 0; i < width; i++)
+        AV_WN16(dst + i * 2 ,AV_RB16(src + i * 4) >> 6);
+}
+
+static void ayuvToY_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,  int width,
+                      uint32_t *unused)
+{
+    int i;
+    for (i = 0; i < width; i++)
+        dst[i] = src[4 * i + 2];
+}
+
+static void ayuvToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *unused0, const uint8_t *src1,
+                       const uint8_t *src2, int width, uint32_t *unused)
+{
+    int i;
+    for (i = 0; i < width; i++) {
+        dstV[i] = src1[4 * i];
+        dstU[i] = src1[4 * i + 1];
+    }
+    av_assert1(src1 == src2);
+}
+
 static void bswap16Y_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused1, const uint8_t *unused2, int width,
                        uint32_t *unused)
 {
@@ -1154,6 +1209,15 @@  av_cold void ff_sws_init_input_funcs(SwsContext *c)
     case AV_PIX_FMT_P016BE:
         c->chrToYV12 = p016BEToUV_c;
         break;
+    case AV_PIX_FMT_Y210LE:
+        c->chrToYV12 = y210le_UV_c;
+        break;
+    case AV_PIX_FMT_Y210BE:
+        c->chrToYV12 = y210be_UV_c;
+        break;
+    case AV_PIX_FMT_AYUV:
+        c->chrToYV12 = ayuvToUV_c;
+        break;
     }
     if (c->chrSrcHSubSample) {
         switch (srcFormat) {
@@ -1586,6 +1650,15 @@  av_cold void ff_sws_init_input_funcs(SwsContext *c)
         c->lumToYV12 = grayf32ToY16_bswap_c;
 #endif
         break;
+    case AV_PIX_FMT_Y210LE:
+        c->lumToYV12 = y210le_Y_c;
+        break;
+    case AV_PIX_FMT_Y210BE:
+        c->chrToYV12 = y210be_Y_c;
+        break;
+    case AV_PIX_FMT_AYUV:
+        c->lumToYV12 = ayuvToY_c;
+        break;
     }
     if (c->needAlpha) {
         if (is16BPS(srcFormat) || isNBPS(srcFormat)) {
@@ -1599,6 +1672,7 @@  av_cold void ff_sws_init_input_funcs(SwsContext *c)
         case AV_PIX_FMT_RGBA64BE:  c->alpToYV12 = rgba64beToA_c; break;
         case AV_PIX_FMT_BGRA:
         case AV_PIX_FMT_RGBA:
+        case AV_PIX_FMT_AYUV:
             c->alpToYV12 = rgbaToA_c;
             break;
         case AV_PIX_FMT_ABGR:
diff --git a/libswscale/output.c b/libswscale/output.c
index 7eb4644..ebd4f93 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -2403,6 +2403,53 @@  yuv2ya8_X_c(SwsContext *c, const int16_t *lumFilter,
 }
 
 static void
+yuv2ayuv_X_c(SwsContext *c, const int16_t *lumFilter,
+                 const int16_t **lumSrc, int lumFilterSize,
+                 const int16_t *chrFilter, const int16_t **chrUSrc,
+                 const int16_t **chrVSrc, int chrFilterSize,
+                 const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
+{
+    int hasAlpha = !!alpSrc;
+    int i;
+
+    for (i = 0; i < dstW; i++) {
+        int j;
+        int A = 1 << 18;
+        int Y = 1 << 18;
+        int U = 1 << 18;
+        int V = 1 << 18;
+
+        for (j = 0; j < lumFilterSize; j++) {
+            Y += lumSrc[j][i]  * lumFilter[j];
+        }
+        for (j = 0; j < chrFilterSize; j++) {
+            U += chrUSrc[j][i] * chrFilter[j];
+            V += chrVSrc[j][i] * chrFilter[j];
+        }
+        if (hasAlpha)
+            for (j = 0; j < lumFilterSize; j++)
+                A += alpSrc[j][i] * lumFilter[j];
+        A >>= 19;
+        Y >>= 19;
+        U >>= 19;
+        V >>= 19;
+        A = hasAlpha ? A : 255;
+
+        if ((A | Y | U | V) & 0x100) {
+            A = av_clip_uint8(A);
+            Y = av_clip_uint8(Y);
+            U = av_clip_uint8(U);
+            V = av_clip_uint8(V);
+        }
+
+        dest[4*i]     = V;
+        dest[4*i + 1] = U;
+        dest[4*i + 2] = Y;
+        dest[4*i + 3] = A;
+    }
+}
+
+static void
 yuv2ayuv64le_X_c(SwsContext *c, const int16_t *lumFilter,
                  const int16_t **_lumSrc, int lumFilterSize,
                  const int16_t *chrFilter, const int16_t **_chrUSrc,
@@ -2932,6 +2979,9 @@  av_cold void ff_sws_init_output_funcs(SwsContext *c,
         *yuv2packed2 = yuv2ya16be_2_c;
         *yuv2packedX = yuv2ya16be_X_c;
         break;
+    case AV_PIX_FMT_AYUV:
+        *yuv2packedX = yuv2ayuv_X_c;
+        break;
     case AV_PIX_FMT_AYUV64LE:
         *yuv2packedX = yuv2ayuv64le_X_c;
         break;
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 1b1f779..ad5f669 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -266,6 +266,9 @@  static const FormatEntry format_entries[AV_PIX_FMT_NB] = {
     [AV_PIX_FMT_YUVA444P12LE] = { 1, 1 },
     [AV_PIX_FMT_NV24]        = { 1, 1 },
     [AV_PIX_FMT_NV42]        = { 1, 1 },
+    [AV_PIX_FMT_Y210BE]      = { 1, 0 },
+    [AV_PIX_FMT_Y210LE]      = { 1, 0 },
+    [AV_PIX_FMT_AYUV]        = { 1, 1 },
 };
 
 int sws_isSupportedInput(enum AVPixelFormat pix_fmt)
diff --git a/libswscale/version.h b/libswscale/version.h
index cc434c0..1dbb561 100644
--- a/libswscale/version.h
+++ b/libswscale/version.h
@@ -28,7 +28,7 @@ 
 
 #define LIBSWSCALE_VERSION_MAJOR   5
 #define LIBSWSCALE_VERSION_MINOR   6
-#define LIBSWSCALE_VERSION_MICRO 100
+#define LIBSWSCALE_VERSION_MICRO 101
 
 #define LIBSWSCALE_VERSION_INT  AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
                                                LIBSWSCALE_VERSION_MINOR, \