swscale/arm/yuv2rgb: add ff_yuv420p_to_{argb,rgba,abgr,bgra}_neon_{16,32}
[ffmpeg.git] / libswscale / arm / swscale_unscaled.c
index 4c12122..1b50acd 100644 (file)
@@ -63,6 +63,50 @@ static int rgbx_to_nv12_neon_16_wrapper(SwsContext *context, const uint8_t *src[
 }
 #endif
 
+#define YUV_TO_RGB_TABLE(precision)                                                         \
+        c->yuv2rgb_v2r_coeff / ((precision) == 16 ? 1 << 7 : 1),                            \
+        c->yuv2rgb_u2g_coeff / ((precision) == 16 ? 1 << 7 : 1),                            \
+        c->yuv2rgb_v2g_coeff / ((precision) == 16 ? 1 << 7 : 1),                            \
+        c->yuv2rgb_u2b_coeff / ((precision) == 16 ? 1 << 7 : 1),                            \
+
+#define DECLARE_FF_YUV420P_TO_RGBX_FUNCS(ofmt, precision)                                   \
+int ff_yuv420p_to_##ofmt##_neon_##precision(int w, int h,                                   \
+                                 uint8_t *dst, int linesize,                                \
+                                 const uint8_t *srcY, int linesizeY,                        \
+                                 const uint8_t *srcU, int linesizeU,                        \
+                                 const uint8_t *srcV, int linesizeV,                        \
+                                 const int16_t *table,                                      \
+                                 int y_offset,                                              \
+                                 int y_coeff);                                              \
+                                                                                            \
+static int yuv420p_to_##ofmt##_neon_wrapper_##precision(SwsContext *c, const uint8_t *src[],\
+                                           int srcStride[], int srcSliceY, int srcSliceH,   \
+                                           uint8_t *dst[], int dstStride[]) {               \
+    const int16_t yuv2rgb_table[] = { YUV_TO_RGB_TABLE(precision) };                        \
+                                                                                            \
+    ff_yuv420p_to_##ofmt##_neon_##precision(c->srcW, srcSliceH,                             \
+                                 dst[0] + srcSliceY * dstStride[0], dstStride[0],           \
+                                 src[0], srcStride[0],                                      \
+                                 src[1], srcStride[1],                                      \
+                                 src[2], srcStride[2],                                      \
+                                 yuv2rgb_table,                                             \
+                                 c->yuv2rgb_y_offset >> 9,                                  \
+                                 c->yuv2rgb_y_coeff / ((precision) == 16 ? 1 << 7 : 1));    \
+                                                                                            \
+    return 0;                                                                               \
+}                                                                                           \
+
+#define DECLARE_FF_YUV420P_TO_ALL_RGBX_FUNCS(precision)                                     \
+DECLARE_FF_YUV420P_TO_RGBX_FUNCS(argb, precision)                                           \
+DECLARE_FF_YUV420P_TO_RGBX_FUNCS(rgba, precision)                                           \
+DECLARE_FF_YUV420P_TO_RGBX_FUNCS(abgr, precision)                                           \
+DECLARE_FF_YUV420P_TO_RGBX_FUNCS(bgra, precision)                                           \
+
+#define DECLARE_FF_YUV420P_TO_ALL_RGBX_ALL_PRECISION_FUNCS                                  \
+DECLARE_FF_YUV420P_TO_ALL_RGBX_FUNCS(16)                                                    \
+
+DECLARE_FF_YUV420P_TO_ALL_RGBX_ALL_PRECISION_FUNCS
+
 #define DECLARE_FF_NVX_TO_RGBX_FUNCS(ifmt, ofmt, precision)                                 \
 int ff_##ifmt##_to_##ofmt##_neon_##precision(int w, int h,                                  \
                                  uint8_t *dst, int linesize,                                \
@@ -75,12 +119,7 @@ int ff_##ifmt##_to_##ofmt##_neon_##precision(int w, int h,
 static int ifmt##_to_##ofmt##_neon_wrapper_##precision(SwsContext *c, const uint8_t *src[], \
                                            int srcStride[], int srcSliceY, int srcSliceH,   \
                                            uint8_t *dst[], int dstStride[]) {               \
-    const int16_t yuv2rgb_table[] = {                                                       \
-        c->yuv2rgb_v2r_coeff / ((precision) == 16 ? 1 << 7 : 1),                            \
-        c->yuv2rgb_u2g_coeff / ((precision) == 16 ? 1 << 7 : 1),                            \
-        c->yuv2rgb_v2g_coeff / ((precision) == 16 ? 1 << 7 : 1),                            \
-        c->yuv2rgb_u2b_coeff / ((precision) == 16 ? 1 << 7 : 1),                            \
-    };                                                                                      \
+    const int16_t yuv2rgb_table[] = { YUV_TO_RGB_TABLE(precision) };                        \
                                                                                             \
     ff_##ifmt##_to_##ofmt##_neon_##precision(c->srcW, srcSliceH,                            \
                                  dst[0] + srcSliceY * dstStride[0], dstStride[0],           \
@@ -138,6 +177,7 @@ static void get_unscaled_swscale_neon(SwsContext *c) {
 
     SET_FF_NVX_TO_ALL_RGBX_FUNC(nv12, NV12, accurate_rnd);
     SET_FF_NVX_TO_ALL_RGBX_FUNC(nv21, NV21, accurate_rnd);
+    SET_FF_NVX_TO_ALL_RGBX_FUNC(yuv420p, YUV420P, accurate_rnd);
 }
 
 void ff_get_unscaled_swscale_arm(SwsContext *c)