diff --git a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json index 5fbadaa1f7..0d7634409a 100644 --- a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json +++ b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json @@ -4892,12 +4892,12 @@ "long-name": "Deinterlacer", "pad-templates": { "sink": { - "caps": "video/x-raw:\n format: { AYUV, ARGB, ABGR, RGBA, BGRA, Y444, xRGB, xBGR, RGBx, BGRx, RGB, BGR, YUY2, YVYU, UYVY, Y42B, I420, YV12, Y41B, NV12, NV21 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(ANY):\n format: { ABGR64_LE, BGRA64_LE, AYUV64, ARGB64_LE, ARGB64, RGBA64_LE, ABGR64_BE, BGRA64_BE, ARGB64_BE, RGBA64_BE, GBRA_12LE, GBRA_12BE, Y412_LE, Y412_BE, A444_10LE, GBRA_10LE, A444_10BE, GBRA_10BE, A422_10LE, A422_10BE, A420_10LE, A420_10BE, RGB10A2_LE, BGR10A2_LE, Y410, GBRA, ABGR, VUYA, BGRA, AYUV, ARGB, RGBA, A420, AV12, Y444_16LE, Y444_16BE, v216, P016_LE, P016_BE, Y444_12LE, GBR_12LE, Y444_12BE, GBR_12BE, I422_12LE, I422_12BE, Y212_LE, Y212_BE, I420_12LE, I420_12BE, P012_LE, P012_BE, Y444_10LE, GBR_10LE, Y444_10BE, GBR_10BE, r210, I422_10LE, I422_10BE, NV16_10LE32, Y210, v210, UYVP, I420_10LE, I420_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, NV12_10BE_8L128, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, YV12, NV21, NV12, NV12_8L128, NV12_64Z32, NV12_4L4, NV12_32L32, NV12_16L32S, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw:\n format: { AYUV, ARGB, ABGR, RGBA, BGRA, Y444, xRGB, xBGR, RGBx, BGRx, RGB, BGR, YUY2, YVYU, UYVY, Y42B, I420, YV12, Y41B, NV12, NV21, Y444_16LE, Y444_12LE, Y444_10LE, I422_12LE, I422_10LE, I420_12LE, I420_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(ANY):\n format: { ABGR64_LE, BGRA64_LE, AYUV64, ARGB64_LE, ARGB64, RGBA64_LE, ABGR64_BE, BGRA64_BE, ARGB64_BE, RGBA64_BE, GBRA_12LE, GBRA_12BE, Y412_LE, Y412_BE, A444_10LE, GBRA_10LE, A444_10BE, GBRA_10BE, A422_10LE, A422_10BE, A420_10LE, A420_10BE, RGB10A2_LE, BGR10A2_LE, Y410, GBRA, ABGR, VUYA, BGRA, AYUV, ARGB, RGBA, A420, AV12, Y444_16LE, Y444_16BE, v216, P016_LE, P016_BE, Y444_12LE, GBR_12LE, Y444_12BE, GBR_12BE, I422_12LE, I422_12BE, Y212_LE, Y212_BE, I420_12LE, I420_12BE, P012_LE, P012_BE, Y444_10LE, GBR_10LE, Y444_10BE, GBR_10BE, r210, I422_10LE, I422_10BE, NV16_10LE32, Y210, v210, UYVP, I420_10LE, I420_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, NV12_10BE_8L128, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, YV12, NV21, NV12, NV12_8L128, NV12_64Z32, NV12_4L4, NV12_32L32, NV12_16L32S, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "sink", "presence": "always" }, "src": { - "caps": "video/x-raw:\n format: { AYUV, ARGB, ABGR, RGBA, BGRA, Y444, xRGB, xBGR, RGBx, BGRx, RGB, BGR, YUY2, YVYU, UYVY, Y42B, I420, YV12, Y41B, NV12, NV21 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(ANY):\n format: { ABGR64_LE, BGRA64_LE, AYUV64, ARGB64_LE, ARGB64, RGBA64_LE, ABGR64_BE, BGRA64_BE, ARGB64_BE, RGBA64_BE, GBRA_12LE, GBRA_12BE, Y412_LE, Y412_BE, A444_10LE, GBRA_10LE, A444_10BE, GBRA_10BE, A422_10LE, A422_10BE, A420_10LE, A420_10BE, RGB10A2_LE, BGR10A2_LE, Y410, GBRA, ABGR, VUYA, BGRA, AYUV, ARGB, RGBA, A420, AV12, Y444_16LE, Y444_16BE, v216, P016_LE, P016_BE, Y444_12LE, GBR_12LE, Y444_12BE, GBR_12BE, I422_12LE, I422_12BE, Y212_LE, Y212_BE, I420_12LE, I420_12BE, P012_LE, P012_BE, Y444_10LE, GBR_10LE, Y444_10BE, GBR_10BE, r210, I422_10LE, I422_10BE, NV16_10LE32, Y210, v210, UYVP, I420_10LE, I420_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, NV12_10BE_8L128, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, YV12, NV21, NV12, NV12_8L128, NV12_64Z32, NV12_4L4, NV12_32L32, NV12_16L32S, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw:\n format: { AYUV, ARGB, ABGR, RGBA, BGRA, Y444, xRGB, xBGR, RGBx, BGRx, RGB, BGR, YUY2, YVYU, UYVY, Y42B, I420, YV12, Y41B, NV12, NV21, Y444_16LE, Y444_12LE, Y444_10LE, I422_12LE, I422_10LE, I420_12LE, I420_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(ANY):\n format: { ABGR64_LE, BGRA64_LE, AYUV64, ARGB64_LE, ARGB64, RGBA64_LE, ABGR64_BE, BGRA64_BE, ARGB64_BE, RGBA64_BE, GBRA_12LE, GBRA_12BE, Y412_LE, Y412_BE, A444_10LE, GBRA_10LE, A444_10BE, GBRA_10BE, A422_10LE, A422_10BE, A420_10LE, A420_10BE, RGB10A2_LE, BGR10A2_LE, Y410, GBRA, ABGR, VUYA, BGRA, AYUV, ARGB, RGBA, A420, AV12, Y444_16LE, Y444_16BE, v216, P016_LE, P016_BE, Y444_12LE, GBR_12LE, Y444_12BE, GBR_12BE, I422_12LE, I422_12BE, Y212_LE, Y212_BE, I420_12LE, I420_12BE, P012_LE, P012_BE, Y444_10LE, GBR_10LE, Y444_10BE, GBR_10BE, r210, I422_10LE, I422_10BE, NV16_10LE32, Y210, v210, UYVP, I420_10LE, I420_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, NV12_10BE_8L128, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, YV12, NV21, NV12, NV12_8L128, NV12_64Z32, NV12_4L4, NV12_32L32, NV12_16L32S, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } diff --git a/subprojects/gst-plugins-good/gst/deinterlace/gstdeinterlace.c b/subprojects/gst-plugins-good/gst/deinterlace/gstdeinterlace.c index 86ee201bb3..3457be020b 100644 --- a/subprojects/gst-plugins-good/gst/deinterlace/gstdeinterlace.c +++ b/subprojects/gst-plugins-good/gst/deinterlace/gstdeinterlace.c @@ -282,9 +282,17 @@ gst_deinterlace_locking_get_type (void) return deinterlace_locking_type; } +#if G_BYTE_ORDER == G_BIG_ENDIAN #define DEINTERLACE_VIDEO_FORMATS \ "{ AYUV, ARGB, ABGR, RGBA, BGRA, Y444, xRGB, xBGR, RGBx, BGRx, RGB, " \ - "BGR, YUY2, YVYU, UYVY, Y42B, I420, YV12, Y41B, NV12, NV21 }" + "BGR, YUY2, YVYU, UYVY, Y42B, I420, YV12, Y41B, NV12, NV21, " \ + "Y444_16BE, Y444_12BE, Y444_10BE, I422_12BE, I422_10BE, I420_12BE, I420_10BE } " +#else +#define DEINTERLACE_VIDEO_FORMATS \ + "{ AYUV, ARGB, ABGR, RGBA, BGRA, Y444, xRGB, xBGR, RGBx, BGRx, RGB, " \ + "BGR, YUY2, YVYU, UYVY, Y42B, I420, YV12, Y41B, NV12, NV21, " \ + "Y444_16LE, Y444_12LE, Y444_10LE, I422_12LE, I422_10LE, I420_12LE, I420_10LE } " +#endif #define DEINTERLACE_CAPS GST_VIDEO_CAPS_MAKE(DEINTERLACE_VIDEO_FORMATS) diff --git a/subprojects/gst-plugins-good/gst/deinterlace/gstdeinterlacemethod.c b/subprojects/gst-plugins-good/gst/deinterlace/gstdeinterlacemethod.c index 24893f8dfa..42fb287a08 100644 --- a/subprojects/gst-plugins-good/gst/deinterlace/gstdeinterlacemethod.c +++ b/subprojects/gst-plugins-good/gst/deinterlace/gstdeinterlacemethod.c @@ -89,6 +89,24 @@ gst_deinterlace_method_supported_impl (GstDeinterlaceMethodClass * klass, return (klass->deinterlace_frame_rgb != NULL); case GST_VIDEO_FORMAT_BGR: return (klass->deinterlace_frame_bgr != NULL); +#if G_BYTE_ORDER == G_BIG_ENDIAN + case GST_VIDEO_FORMAT_Y444_16BE: + case GST_VIDEO_FORMAT_Y444_12BE: + case GST_VIDEO_FORMAT_Y444_10BE: + case GST_VIDEO_FORMAT_I422_12BE: + case GST_VIDEO_FORMAT_I422_10BE: + case GST_VIDEO_FORMAT_I420_12BE: + case GST_VIDEO_FORMAT_I420_10BE: +#else + case GST_VIDEO_FORMAT_Y444_16LE: + case GST_VIDEO_FORMAT_Y444_12LE: + case GST_VIDEO_FORMAT_Y444_10LE: + case GST_VIDEO_FORMAT_I422_12LE: + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_I420_12LE: + case GST_VIDEO_FORMAT_I420_10LE: +#endif + return (klass->deinterlace_frame_planar_high != NULL); default: return FALSE; } @@ -171,6 +189,25 @@ gst_deinterlace_method_setup_impl (GstDeinterlaceMethod * self, case GST_VIDEO_FORMAT_BGR: self->deinterlace_frame = klass->deinterlace_frame_bgr; break; +#if G_BYTE_ORDER == G_BIG_ENDIAN + case GST_VIDEO_FORMAT_Y444_16BE: + case GST_VIDEO_FORMAT_Y444_12BE: + case GST_VIDEO_FORMAT_Y444_10BE: + case GST_VIDEO_FORMAT_I422_12BE: + case GST_VIDEO_FORMAT_I422_10BE: + case GST_VIDEO_FORMAT_I420_12BE: + case GST_VIDEO_FORMAT_I420_10BE: +#else + case GST_VIDEO_FORMAT_Y444_16LE: + case GST_VIDEO_FORMAT_Y444_12LE: + case GST_VIDEO_FORMAT_Y444_10LE: + case GST_VIDEO_FORMAT_I422_12LE: + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_I420_12LE: + case GST_VIDEO_FORMAT_I420_10LE: +#endif + self->deinterlace_frame = klass->deinterlace_frame_planar_high; + break; default: self->deinterlace_frame = NULL; break; @@ -287,6 +324,29 @@ gst_deinterlace_simple_method_supported (GstDeinterlaceMethodClass * mklass, && klass->copy_scanline_planar_u != NULL && klass->interpolate_scanline_planar_v != NULL && klass->copy_scanline_planar_v != NULL); +#if G_BYTE_ORDER == G_BIG_ENDIAN + case GST_VIDEO_FORMAT_Y444_16BE: + case GST_VIDEO_FORMAT_Y444_12BE: + case GST_VIDEO_FORMAT_Y444_10BE: + case GST_VIDEO_FORMAT_I422_12BE: + case GST_VIDEO_FORMAT_I422_10BE: + case GST_VIDEO_FORMAT_I420_12BE: + case GST_VIDEO_FORMAT_I420_10BE: +#else + case GST_VIDEO_FORMAT_Y444_16LE: + case GST_VIDEO_FORMAT_Y444_12LE: + case GST_VIDEO_FORMAT_Y444_10LE: + case GST_VIDEO_FORMAT_I422_12LE: + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_I420_12LE: + case GST_VIDEO_FORMAT_I420_10LE: +#endif + return (klass->interpolate_scanline_planar_y_16bits != NULL + && klass->copy_scanline_planar_y_16bits != NULL && + klass->interpolate_scanline_planar_u_16bits != NULL + && klass->copy_scanline_planar_u_16bits != NULL && + klass->interpolate_scanline_planar_v_16bits != NULL + && klass->copy_scanline_planar_v_16bits != NULL); default: return FALSE; } @@ -743,6 +803,33 @@ gst_deinterlace_simple_method_setup (GstDeinterlaceMethod * method, klass->interpolate_scanline_planar_v; self->copy_scanline_planar[2] = klass->copy_scanline_planar_v; break; +#if G_BYTE_ORDER == G_BIG_ENDIAN + case GST_VIDEO_FORMAT_Y444_16BE: + case GST_VIDEO_FORMAT_Y444_12BE: + case GST_VIDEO_FORMAT_Y444_10BE: + case GST_VIDEO_FORMAT_I422_12BE: + case GST_VIDEO_FORMAT_I422_10BE: + case GST_VIDEO_FORMAT_I420_12BE: + case GST_VIDEO_FORMAT_I420_10BE: +#else + case GST_VIDEO_FORMAT_Y444_16LE: + case GST_VIDEO_FORMAT_Y444_12LE: + case GST_VIDEO_FORMAT_Y444_10LE: + case GST_VIDEO_FORMAT_I422_12LE: + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_I420_12LE: + case GST_VIDEO_FORMAT_I420_10LE: +#endif + self->interpolate_scanline_planar[0] = + klass->interpolate_scanline_planar_y_16bits; + self->copy_scanline_planar[0] = klass->copy_scanline_planar_y_16bits; + self->interpolate_scanline_planar[1] = + klass->interpolate_scanline_planar_u_16bits; + self->copy_scanline_planar[1] = klass->copy_scanline_planar_u_16bits; + self->interpolate_scanline_planar[2] = + klass->interpolate_scanline_planar_v_16bits; + self->copy_scanline_planar[2] = klass->copy_scanline_planar_v_16bits; + break; default: break; } @@ -788,6 +875,9 @@ gst_deinterlace_simple_method_class_init (GstDeinterlaceSimpleMethodClass gst_deinterlace_simple_method_deinterlace_frame_nv12; dm_class->deinterlace_frame_nv21 = gst_deinterlace_simple_method_deinterlace_frame_nv12; + /* same as 8bits planar */ + dm_class->deinterlace_frame_planar_high = + gst_deinterlace_simple_method_deinterlace_frame_planar; dm_class->fields_required = 2; dm_class->setup = gst_deinterlace_simple_method_setup; dm_class->supported = gst_deinterlace_simple_method_supported; @@ -849,6 +939,16 @@ gst_deinterlace_simple_method_class_init (GstDeinterlaceSimpleMethodClass gst_deinterlace_simple_method_interpolate_scanline_planar_v; klass->copy_scanline_planar_v = gst_deinterlace_simple_method_copy_scanline_planar_v; + + /* planar high bitdepth formats use the same methods as 8bits planar, + * (i.e,memcpy) but interpolate_scanline_planar_{y,u,v}_16bits methods will + * be configured by each subclass */ + klass->copy_scanline_planar_y_16bits = + gst_deinterlace_simple_method_copy_scanline_planar_y; + klass->copy_scanline_planar_u_16bits = + gst_deinterlace_simple_method_copy_scanline_planar_u; + klass->copy_scanline_planar_v_16bits = + gst_deinterlace_simple_method_copy_scanline_planar_v; } static void diff --git a/subprojects/gst-plugins-good/gst/deinterlace/gstdeinterlacemethod.h b/subprojects/gst-plugins-good/gst/deinterlace/gstdeinterlacemethod.h index 6c421c1e7b..8390d52ddd 100644 --- a/subprojects/gst-plugins-good/gst/deinterlace/gstdeinterlacemethod.h +++ b/subprojects/gst-plugins-good/gst/deinterlace/gstdeinterlacemethod.h @@ -101,6 +101,8 @@ struct _GstDeinterlaceMethodClass { GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame_rgb; GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame_bgr; + GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame_planar_high; + const gchar *name; const gchar *nick; }; @@ -213,6 +215,14 @@ struct _GstDeinterlaceSimpleMethodClass { GstDeinterlaceSimpleMethodFunction interpolate_scanline_planar_u; GstDeinterlaceSimpleMethodFunction copy_scanline_planar_v; GstDeinterlaceSimpleMethodFunction interpolate_scanline_planar_v; + + /* Planar high bitdepth formats */ + GstDeinterlaceSimpleMethodFunction copy_scanline_planar_y_16bits; + GstDeinterlaceSimpleMethodFunction interpolate_scanline_planar_y_16bits; + GstDeinterlaceSimpleMethodFunction copy_scanline_planar_u_16bits; + GstDeinterlaceSimpleMethodFunction interpolate_scanline_planar_u_16bits; + GstDeinterlaceSimpleMethodFunction copy_scanline_planar_v_16bits; + GstDeinterlaceSimpleMethodFunction interpolate_scanline_planar_v_16bits; }; GType gst_deinterlace_simple_method_get_type (void); diff --git a/subprojects/gst-plugins-good/gst/deinterlace/tvtime-dist.c b/subprojects/gst-plugins-good/gst/deinterlace/tvtime-dist.c index 47c1056e37..0c2628a620 100644 --- a/subprojects/gst-plugins-good/gst/deinterlace/tvtime-dist.c +++ b/subprojects/gst-plugins-good/gst/deinterlace/tvtime-dist.c @@ -99,8 +99,14 @@ void deinterlace_line_vfir (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, const guint8 * ORC_RESTRICT s4, const guint8 * ORC_RESTRICT s5, int n); +void deinterlace_line_vfir_16bits (guint16 * ORC_RESTRICT d1, + const guint16 * ORC_RESTRICT s1, const guint16 * ORC_RESTRICT s2, + const guint16 * ORC_RESTRICT s3, const guint16 * ORC_RESTRICT s4, + const guint16 * ORC_RESTRICT s5, int n); void deinterlace_line_linear (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, int n); +void deinterlace_line_linear_16bits (guint16 * ORC_RESTRICT d1, + const guint16 * ORC_RESTRICT s1, const guint16 * ORC_RESTRICT s2, int n); void deinterlace_line_linear_blend (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n); @@ -440,6 +446,296 @@ deinterlace_line_vfir (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, #endif +/* deinterlace_line_vfir_16bits */ +#ifdef DISABLE_ORC +void +deinterlace_line_vfir_16bits (guint16 * ORC_RESTRICT d1, + const guint16 * ORC_RESTRICT s1, const guint16 * ORC_RESTRICT s2, + const guint16 * ORC_RESTRICT s3, const guint16 * ORC_RESTRICT s4, + const guint16 * ORC_RESTRICT s5, int n) +{ + int i; + orc_union16 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + const orc_union16 *ORC_RESTRICT ptr5; + const orc_union16 *ORC_RESTRICT ptr6; + const orc_union16 *ORC_RESTRICT ptr7; + const orc_union16 *ORC_RESTRICT ptr8; + orc_union16 var35; + orc_union16 var36; + orc_union16 var37; + orc_union16 var38; + orc_union16 var39; +#if defined(__APPLE__) && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && defined (__i386__) + volatile orc_union32 var40; +#else + orc_union32 var40; +#endif + orc_union16 var41; + orc_union32 var42; + orc_union32 var43; + orc_union32 var44; + orc_union32 var45; + orc_union32 var46; + orc_union32 var47; + orc_union32 var48; + orc_union32 var49; + orc_union32 var50; + orc_union32 var51; + orc_union32 var52; + orc_union32 var53; + orc_union32 var54; + + ptr0 = (orc_union16 *) d1; + ptr4 = (orc_union16 *) s1; + ptr5 = (orc_union16 *) s2; + ptr6 = (orc_union16 *) s3; + ptr7 = (orc_union16 *) s4; + ptr8 = (orc_union16 *) s5; + + /* 16: loadpl */ + var40.i = 0x00000004; /* 4 or 1.97626e-323f */ + + for (i = 0; i < n; i++) { + /* 0: loadw */ + var35 = ptr4[i]; + /* 1: convuwl */ + var42.i = (orc_uint16) var35.i; + /* 2: loadw */ + var36 = ptr8[i]; + /* 3: convuwl */ + var43.i = (orc_uint16) var36.i; + /* 4: addl */ + var44.i = ((orc_uint32) var42.i) + ((orc_uint32) var43.i); + /* 5: loadw */ + var37 = ptr5[i]; + /* 6: convuwl */ + var45.i = (orc_uint16) var37.i; + /* 7: loadw */ + var38 = ptr7[i]; + /* 8: convuwl */ + var46.i = (orc_uint16) var38.i; + /* 9: addl */ + var47.i = ((orc_uint32) var45.i) + ((orc_uint32) var46.i); + /* 10: shll */ + var48.i = ((orc_uint32) var47.i) << 2; + /* 11: loadw */ + var39 = ptr6[i]; + /* 12: convuwl */ + var49.i = (orc_uint16) var39.i; + /* 13: shll */ + var50.i = ((orc_uint32) var49.i) << 1; + /* 14: subl */ + var51.i = ((orc_uint32) var48.i) - ((orc_uint32) var44.i); + /* 15: addl */ + var52.i = ((orc_uint32) var51.i) + ((orc_uint32) var50.i); + /* 17: addl */ + var53.i = ((orc_uint32) var52.i) + ((orc_uint32) var40.i); + /* 18: shrsl */ + var54.i = var53.i >> 3; + /* 19: convsuslw */ + var41.i = ORC_CLAMP_UW (var54.i); + /* 20: storew */ + ptr0[i] = var41; + } + +} + +#else +static void +_backup_deinterlace_line_vfir_16bits (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union16 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + const orc_union16 *ORC_RESTRICT ptr5; + const orc_union16 *ORC_RESTRICT ptr6; + const orc_union16 *ORC_RESTRICT ptr7; + const orc_union16 *ORC_RESTRICT ptr8; + orc_union16 var35; + orc_union16 var36; + orc_union16 var37; + orc_union16 var38; + orc_union16 var39; +#if defined(__APPLE__) && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && defined (__i386__) + volatile orc_union32 var40; +#else + orc_union32 var40; +#endif + orc_union16 var41; + orc_union32 var42; + orc_union32 var43; + orc_union32 var44; + orc_union32 var45; + orc_union32 var46; + orc_union32 var47; + orc_union32 var48; + orc_union32 var49; + orc_union32 var50; + orc_union32 var51; + orc_union32 var52; + orc_union32 var53; + orc_union32 var54; + + ptr0 = (orc_union16 *) ex->arrays[0]; + ptr4 = (orc_union16 *) ex->arrays[4]; + ptr5 = (orc_union16 *) ex->arrays[5]; + ptr6 = (orc_union16 *) ex->arrays[6]; + ptr7 = (orc_union16 *) ex->arrays[7]; + ptr8 = (orc_union16 *) ex->arrays[8]; + + /* 16: loadpl */ + var40.i = 0x00000004; /* 4 or 1.97626e-323f */ + + for (i = 0; i < n; i++) { + /* 0: loadw */ + var35 = ptr4[i]; + /* 1: convuwl */ + var42.i = (orc_uint16) var35.i; + /* 2: loadw */ + var36 = ptr8[i]; + /* 3: convuwl */ + var43.i = (orc_uint16) var36.i; + /* 4: addl */ + var44.i = ((orc_uint32) var42.i) + ((orc_uint32) var43.i); + /* 5: loadw */ + var37 = ptr5[i]; + /* 6: convuwl */ + var45.i = (orc_uint16) var37.i; + /* 7: loadw */ + var38 = ptr7[i]; + /* 8: convuwl */ + var46.i = (orc_uint16) var38.i; + /* 9: addl */ + var47.i = ((orc_uint32) var45.i) + ((orc_uint32) var46.i); + /* 10: shll */ + var48.i = ((orc_uint32) var47.i) << 2; + /* 11: loadw */ + var39 = ptr6[i]; + /* 12: convuwl */ + var49.i = (orc_uint16) var39.i; + /* 13: shll */ + var50.i = ((orc_uint32) var49.i) << 1; + /* 14: subl */ + var51.i = ((orc_uint32) var48.i) - ((orc_uint32) var44.i); + /* 15: addl */ + var52.i = ((orc_uint32) var51.i) + ((orc_uint32) var50.i); + /* 17: addl */ + var53.i = ((orc_uint32) var52.i) + ((orc_uint32) var40.i); + /* 18: shrsl */ + var54.i = var53.i >> 3; + /* 19: convsuslw */ + var41.i = ORC_CLAMP_UW (var54.i); + /* 20: storew */ + ptr0[i] = var41; + } + +} + +void +deinterlace_line_vfir_16bits (guint16 * ORC_RESTRICT d1, + const guint16 * ORC_RESTRICT s1, const guint16 * ORC_RESTRICT s2, + const guint16 * ORC_RESTRICT s3, const guint16 * ORC_RESTRICT s4, + const guint16 * ORC_RESTRICT s5, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcCode *c = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + OrcProgram *p; + +#if 1 + static const orc_uint8 bc[] = { + 1, 9, 28, 100, 101, 105, 110, 116, 101, 114, 108, 97, 99, 101, 95, 108, + 105, 110, 101, 95, 118, 102, 105, 114, 95, 49, 54, 98, 105, 116, 115, + 11, + 2, 2, 12, 2, 2, 12, 2, 2, 12, 2, 2, 12, 2, 2, 12, 2, + 2, 14, 4, 2, 0, 0, 0, 14, 4, 1, 0, 0, 0, 14, 4, 4, + 0, 0, 0, 14, 4, 3, 0, 0, 0, 20, 4, 20, 4, 20, 4, 154, + 32, 4, 154, 33, 8, 103, 32, 32, 33, 154, 33, 5, 154, 34, 7, 103, + 33, 33, 34, 124, 33, 33, 16, 154, 34, 6, 124, 34, 34, 17, 129, 33, + 33, 32, 103, 33, 33, 34, 103, 33, 33, 18, 125, 33, 33, 19, 166, 0, + 33, 2, 0, + }; + p = orc_program_new_from_static_bytecode (bc); + orc_program_set_backup_function (p, _backup_deinterlace_line_vfir_16bits); +#else + p = orc_program_new (); + orc_program_set_name (p, "deinterlace_line_vfir_16bits"); + orc_program_set_backup_function (p, _backup_deinterlace_line_vfir_16bits); + orc_program_add_destination (p, 2, "d1"); + orc_program_add_source (p, 2, "s1"); + orc_program_add_source (p, 2, "s2"); + orc_program_add_source (p, 2, "s3"); + orc_program_add_source (p, 2, "s4"); + orc_program_add_source (p, 2, "s5"); + orc_program_add_constant (p, 4, 0x00000002, "c1"); + orc_program_add_constant (p, 4, 0x00000001, "c2"); + orc_program_add_constant (p, 4, 0x00000004, "c3"); + orc_program_add_constant (p, 4, 0x00000003, "c4"); + orc_program_add_temporary (p, 4, "t1"); + orc_program_add_temporary (p, 4, "t2"); + orc_program_add_temporary (p, 4, "t3"); + + orc_program_append_2 (p, "convuwl", 0, ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "convuwl", 0, ORC_VAR_T2, ORC_VAR_S5, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "addl", 0, ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "convuwl", 0, ORC_VAR_T2, ORC_VAR_S2, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "convuwl", 0, ORC_VAR_T3, ORC_VAR_S4, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "addl", 0, ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_T3, + ORC_VAR_D1); + orc_program_append_2 (p, "shll", 0, ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_C1, + ORC_VAR_D1); + orc_program_append_2 (p, "convuwl", 0, ORC_VAR_T3, ORC_VAR_S3, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "shll", 0, ORC_VAR_T3, ORC_VAR_T3, ORC_VAR_C2, + ORC_VAR_D1); + orc_program_append_2 (p, "subl", 0, ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_T1, + ORC_VAR_D1); + orc_program_append_2 (p, "addl", 0, ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_T3, + ORC_VAR_D1); + orc_program_append_2 (p, "addl", 0, ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_C3, + ORC_VAR_D1); + orc_program_append_2 (p, "shrsl", 0, ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_C4, + ORC_VAR_D1); + orc_program_append_2 (p, "convsuslw", 0, ORC_VAR_D1, ORC_VAR_T2, + ORC_VAR_D1, ORC_VAR_D1); +#endif + + orc_program_compile (p); + c = orc_program_take_code (p); + orc_program_free (p); + } + p_inited = TRUE; + orc_once_mutex_unlock (); + } + ex->arrays[ORC_VAR_A2] = c; + ex->program = 0; + + ex->n = n; + ex->arrays[ORC_VAR_D1] = d1; + ex->arrays[ORC_VAR_S1] = (void *) s1; + ex->arrays[ORC_VAR_S2] = (void *) s2; + ex->arrays[ORC_VAR_S3] = (void *) s3; + ex->arrays[ORC_VAR_S4] = (void *) s4; + ex->arrays[ORC_VAR_S5] = (void *) s5; + + func = c->exec; + func (ex); +} +#endif + + /* deinterlace_line_linear */ #ifdef DISABLE_ORC void @@ -558,6 +854,128 @@ deinterlace_line_linear (guint8 * ORC_RESTRICT d1, #endif +/* deinterlace_line_linear_16bits */ +#ifdef DISABLE_ORC +void +deinterlace_line_linear_16bits (guint16 * ORC_RESTRICT d1, + const guint16 * ORC_RESTRICT s1, const guint16 * ORC_RESTRICT s2, int n) +{ + int i; + orc_union16 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + const orc_union16 *ORC_RESTRICT ptr5; + orc_union16 var32; + orc_union16 var33; + orc_union16 var34; + + ptr0 = (orc_union16 *) d1; + ptr4 = (orc_union16 *) s1; + ptr5 = (orc_union16 *) s2; + + + for (i = 0; i < n; i++) { + /* 0: loadw */ + var32 = ptr4[i]; + /* 1: loadw */ + var33 = ptr5[i]; + /* 2: avguw */ + var34.i = ((orc_uint16) var32.i + (orc_uint16) var33.i + 1) >> 1; + /* 3: storew */ + ptr0[i] = var34; + } + +} + +#else +static void +_backup_deinterlace_line_linear_16bits (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union16 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + const orc_union16 *ORC_RESTRICT ptr5; + orc_union16 var32; + orc_union16 var33; + orc_union16 var34; + + ptr0 = (orc_union16 *) ex->arrays[0]; + ptr4 = (orc_union16 *) ex->arrays[4]; + ptr5 = (orc_union16 *) ex->arrays[5]; + + + for (i = 0; i < n; i++) { + /* 0: loadw */ + var32 = ptr4[i]; + /* 1: loadw */ + var33 = ptr5[i]; + /* 2: avguw */ + var34.i = ((orc_uint16) var32.i + (orc_uint16) var33.i + 1) >> 1; + /* 3: storew */ + ptr0[i] = var34; + } + +} + +void +deinterlace_line_linear_16bits (guint16 * ORC_RESTRICT d1, + const guint16 * ORC_RESTRICT s1, const guint16 * ORC_RESTRICT s2, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcCode *c = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + OrcProgram *p; + +#if 1 + static const orc_uint8 bc[] = { + 1, 9, 30, 100, 101, 105, 110, 116, 101, 114, 108, 97, 99, 101, 95, 108, + 105, 110, 101, 95, 108, 105, 110, 101, 97, 114, 95, 49, 54, 98, 105, + 116, + 115, 11, 2, 2, 12, 2, 2, 12, 2, 2, 76, 0, 4, 5, 2, 0, + + }; + p = orc_program_new_from_static_bytecode (bc); + orc_program_set_backup_function (p, + _backup_deinterlace_line_linear_16bits); +#else + p = orc_program_new (); + orc_program_set_name (p, "deinterlace_line_linear_16bits"); + orc_program_set_backup_function (p, + _backup_deinterlace_line_linear_16bits); + orc_program_add_destination (p, 2, "d1"); + orc_program_add_source (p, 2, "s1"); + orc_program_add_source (p, 2, "s2"); + + orc_program_append_2 (p, "avguw", 0, ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_S2, + ORC_VAR_D1); +#endif + + orc_program_compile (p); + c = orc_program_take_code (p); + orc_program_free (p); + } + p_inited = TRUE; + orc_once_mutex_unlock (); + } + ex->arrays[ORC_VAR_A2] = c; + ex->program = 0; + + ex->n = n; + ex->arrays[ORC_VAR_D1] = d1; + ex->arrays[ORC_VAR_S1] = (void *) s1; + ex->arrays[ORC_VAR_S2] = (void *) s2; + + func = c->exec; + func (ex); +} +#endif + + /* deinterlace_line_linear_blend */ #ifdef DISABLE_ORC void diff --git a/subprojects/gst-plugins-good/gst/deinterlace/tvtime-dist.h b/subprojects/gst-plugins-good/gst/deinterlace/tvtime-dist.h index adbc9014af..23e8066ee6 100644 --- a/subprojects/gst-plugins-good/gst/deinterlace/tvtime-dist.h +++ b/subprojects/gst-plugins-good/gst/deinterlace/tvtime-dist.h @@ -1,8 +1,7 @@ /* autogenerated from tvtime.orc */ -#ifndef _TVTIME_H_ -#define _TVTIME_H_ +#pragma once #include @@ -81,7 +80,9 @@ typedef union { orc_int64 i; double f; orc_int32 x2[2]; float x2f[2]; orc_int16 #endif void deinterlace_line_vfir (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, const guint8 * ORC_RESTRICT s4, const guint8 * ORC_RESTRICT s5, int n); +void deinterlace_line_vfir_16bits (guint16 * ORC_RESTRICT d1, const guint16 * ORC_RESTRICT s1, const guint16 * ORC_RESTRICT s2, const guint16 * ORC_RESTRICT s3, const guint16 * ORC_RESTRICT s4, const guint16 * ORC_RESTRICT s5, int n); void deinterlace_line_linear (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, int n); +void deinterlace_line_linear_16bits (guint16 * ORC_RESTRICT d1, const guint16 * ORC_RESTRICT s1, const guint16 * ORC_RESTRICT s2, int n); void deinterlace_line_linear_blend (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n); void deinterlace_line_greedy (orc_uint8 * ORC_RESTRICT d1, const orc_uint8 * ORC_RESTRICT s1, const orc_uint8 * ORC_RESTRICT s2, const orc_uint8 * ORC_RESTRICT s3, const orc_uint8 * ORC_RESTRICT s4, int p1, int n); @@ -89,5 +90,3 @@ void deinterlace_line_greedy (orc_uint8 * ORC_RESTRICT d1, const orc_uint8 * ORC } #endif -#endif - diff --git a/subprojects/gst-plugins-good/gst/deinterlace/tvtime.orc b/subprojects/gst-plugins-good/gst/deinterlace/tvtime.orc index 44217e74db..376d6e4ef8 100644 --- a/subprojects/gst-plugins-good/gst/deinterlace/tvtime.orc +++ b/subprojects/gst-plugins-good/gst/deinterlace/tvtime.orc @@ -26,6 +26,33 @@ shrsw t2, t2, 3 convsuswb d1, t2 +.function deinterlace_line_vfir_16bits +.dest 2 d1 guint16 +.source 2 s1 guint16 +.source 2 s2 guint16 +.source 2 s3 guint16 +.source 2 s4 guint16 +.source 2 s5 guint16 +.temp 4 t1 +.temp 4 t2 +.temp 4 t3 + +convuwl t1, s1 +convuwl t2, s5 +addl t1, t1, t2 +convuwl t2, s2 +convuwl t3, s4 +addl t2, t2, t3 +shll t2, t2, 2 +convuwl t3, s3 +shll t3, t3, 1 +subl t2, t2, t1 +addl t2, t2, t3 +addl t2, t2, 4 +shrsl t2, t2, 3 +convsuslw d1, t2 + + .function deinterlace_line_linear .dest 1 d1 guint8 .source 1 s1 guint8 @@ -34,6 +61,14 @@ convsuswb d1, t2 avgub d1, s1, s2 +.function deinterlace_line_linear_16bits +.dest 2 d1 guint16 +.source 2 s1 guint16 +.source 2 s2 guint16 + +avguw d1, s1, s2 + + .function deinterlace_line_linear_blend .dest 1 d1 guint8 .source 1 s1 guint8 diff --git a/subprojects/gst-plugins-good/gst/deinterlace/tvtime/linear.c b/subprojects/gst-plugins-good/gst/deinterlace/tvtime/linear.c index 9c45353e0b..36a6fce557 100644 --- a/subprojects/gst-plugins-good/gst/deinterlace/tvtime/linear.c +++ b/subprojects/gst-plugins-good/gst/deinterlace/tvtime/linear.c @@ -54,6 +54,13 @@ deinterlace_scanline_linear_c (GstDeinterlaceSimpleMethod * self, deinterlace_line_linear (out, s1, s2, size); } +static void +deinterlace_scanline_linear_c_16bits (GstDeinterlaceSimpleMethod * self, + guint16 * out, const guint16 * s1, const guint16 * s2, gint size) +{ + deinterlace_line_linear_16bits (out, s1, s2, size / 2); +} + static void deinterlace_scanline_linear_packed_c (GstDeinterlaceSimpleMethod * self, guint8 * out, const GstDeinterlaceScanlineData * scanlines, guint size) @@ -82,6 +89,15 @@ deinterlace_scanline_linear_planar_v_c (GstDeinterlaceSimpleMethod * self, deinterlace_scanline_linear_c (self, out, scanlines->t0, scanlines->b0, size); } +static void +deinterlace_scanline_linear_planar_plane_16bits_c (GstDeinterlaceSimpleMethod * + self, guint8 * out, const GstDeinterlaceScanlineData * scanlines, + guint size) +{ + deinterlace_scanline_linear_c_16bits (self, (guint16 *) out, + (const guint16 *) scanlines->t0, (const guint16 *) scanlines->b0, size); +} + G_DEFINE_TYPE (GstDeinterlaceMethodLinear, gst_deinterlace_method_linear, GST_TYPE_DEINTERLACE_SIMPLE_METHOD); @@ -117,6 +133,12 @@ gst_deinterlace_method_linear_class_init (GstDeinterlaceMethodLinearClass * dism_class->interpolate_scanline_planar_v = deinterlace_scanline_linear_planar_v_c; + dism_class->interpolate_scanline_planar_y_16bits = + deinterlace_scanline_linear_planar_plane_16bits_c; + dism_class->interpolate_scanline_planar_u_16bits = + deinterlace_scanline_linear_planar_plane_16bits_c; + dism_class->interpolate_scanline_planar_v_16bits = + deinterlace_scanline_linear_planar_plane_16bits_c; } static void diff --git a/subprojects/gst-plugins-good/gst/deinterlace/tvtime/vfir.c b/subprojects/gst-plugins-good/gst/deinterlace/tvtime/vfir.c index f77178c861..59b8ac21f2 100644 --- a/subprojects/gst-plugins-good/gst/deinterlace/tvtime/vfir.c +++ b/subprojects/gst-plugins-good/gst/deinterlace/tvtime/vfir.c @@ -75,6 +75,19 @@ deinterlace_c (guint8 * dst, const guint8 * lum_m4, const guint8 * lum_m3, } } +static inline void +deinterlace_c_16bits (guint16 * dst, const guint16 * lum_m4, + const guint16 * lum_m3, const guint16 * lum_m2, const guint16 * lum_m1, + const guint16 * lum, gint size) +{ + if (lum_m2 == NULL) { + deinterlace_line_linear_16bits (dst, lum_m1, lum_m3, size); + } else { + deinterlace_line_vfir_16bits (dst, lum_m4, lum_m3, lum_m2, lum_m1, + lum, size); + } +} + static void deinterlace_line_packed_c (GstDeinterlaceSimpleMethod * self, guint8 * dst, const GstDeinterlaceScanlineData * scanlines, guint size) @@ -127,6 +140,20 @@ deinterlace_line_planar_v_c (GstDeinterlaceSimpleMethod * self, guint8 * dst, deinterlace_c (dst, lum_m4, lum_m3, lum_m2, lum_m1, lum, size); } +static void +deinterlace_line_planar_plane_16bits_c (GstDeinterlaceSimpleMethod * self, + guint8 * dst, const GstDeinterlaceScanlineData * scanlines, guint size) +{ + const guint16 *lum_m4 = (const guint16 *) scanlines->tt1; + const guint16 *lum_m3 = (const guint16 *) scanlines->t0; + const guint16 *lum_m2 = (const guint16 *) scanlines->m1; + const guint16 *lum_m1 = (const guint16 *) scanlines->b0; + const guint16 *lum = (const guint16 *) scanlines->bb1; + + deinterlace_c_16bits ((guint16 *) dst, lum_m4, lum_m3, lum_m2, lum_m1, lum, + size); +} + #undef BUILD_X86_ASM #ifdef BUILD_X86_ASM @@ -306,6 +333,13 @@ gst_deinterlace_method_vfir_class_init (GstDeinterlaceMethodVFIRClass * klass) dism_class->interpolate_scanline_planar_u = deinterlace_line_planar_u_c; dism_class->interpolate_scanline_planar_v = deinterlace_line_planar_v_c; #endif + + dism_class->interpolate_scanline_planar_y_16bits = + deinterlace_line_planar_plane_16bits_c; + dism_class->interpolate_scanline_planar_u_16bits = + deinterlace_line_planar_plane_16bits_c; + dism_class->interpolate_scanline_planar_v_16bits = + deinterlace_line_planar_plane_16bits_c; } static void diff --git a/subprojects/gst-plugins-good/gst/deinterlace/tvtime/weave.c b/subprojects/gst-plugins-good/gst/deinterlace/tvtime/weave.c index 804c889f07..1b2c3075a4 100644 --- a/subprojects/gst-plugins-good/gst/deinterlace/tvtime/weave.c +++ b/subprojects/gst-plugins-good/gst/deinterlace/tvtime/weave.c @@ -150,6 +150,14 @@ gst_deinterlace_method_weave_class_init (GstDeinterlaceMethodWeaveClass * klass) dism_class->interpolate_scanline_planar_v = deinterlace_scanline_weave_planar_v; + /* we do just memcpy, nothing different */ + dism_class->interpolate_scanline_planar_y_16bits = + deinterlace_scanline_weave_planar_y; + dism_class->interpolate_scanline_planar_u_16bits = + deinterlace_scanline_weave_planar_u; + dism_class->interpolate_scanline_planar_v_16bits = + deinterlace_scanline_weave_planar_v; + dism_class->copy_scanline_ayuv = copy_scanline_packed; dism_class->copy_scanline_yuy2 = copy_scanline_packed; dism_class->copy_scanline_yvyu = copy_scanline_packed; diff --git a/subprojects/gst-plugins-good/gst/deinterlace/tvtime/weavebff.c b/subprojects/gst-plugins-good/gst/deinterlace/tvtime/weavebff.c index 7424e96fed..d0be4c70e4 100644 --- a/subprojects/gst-plugins-good/gst/deinterlace/tvtime/weavebff.c +++ b/subprojects/gst-plugins-good/gst/deinterlace/tvtime/weavebff.c @@ -151,6 +151,14 @@ gst_deinterlace_method_weave_bff_class_init (GstDeinterlaceMethodWeaveBFFClass * dism_class->interpolate_scanline_planar_v = deinterlace_scanline_weave_planar_v; + /* we do just memcpy, nothing different */ + dism_class->interpolate_scanline_planar_y_16bits = + deinterlace_scanline_weave_planar_y; + dism_class->interpolate_scanline_planar_u_16bits = + deinterlace_scanline_weave_planar_u; + dism_class->interpolate_scanline_planar_v_16bits = + deinterlace_scanline_weave_planar_v; + dism_class->copy_scanline_ayuv = copy_scanline_packed; dism_class->copy_scanline_yuy2 = copy_scanline_packed; dism_class->copy_scanline_yvyu = copy_scanline_packed; diff --git a/subprojects/gst-plugins-good/gst/deinterlace/tvtime/weavetff.c b/subprojects/gst-plugins-good/gst/deinterlace/tvtime/weavetff.c index f33bb2e551..1969256274 100644 --- a/subprojects/gst-plugins-good/gst/deinterlace/tvtime/weavetff.c +++ b/subprojects/gst-plugins-good/gst/deinterlace/tvtime/weavetff.c @@ -152,6 +152,14 @@ gst_deinterlace_method_weave_tff_class_init (GstDeinterlaceMethodWeaveTFFClass * dism_class->interpolate_scanline_planar_v = deinterlace_scanline_weave_planar_v; + /* we do just memcpy, nothing different */ + dism_class->interpolate_scanline_planar_y_16bits = + deinterlace_scanline_weave_planar_y; + dism_class->interpolate_scanline_planar_u_16bits = + deinterlace_scanline_weave_planar_u; + dism_class->interpolate_scanline_planar_v_16bits = + deinterlace_scanline_weave_planar_v; + dism_class->copy_scanline_ayuv = copy_scanline_packed; dism_class->copy_scanline_yuy2 = copy_scanline_packed; dism_class->copy_scanline_yvyu = copy_scanline_packed; diff --git a/subprojects/gst-plugins-good/gst/deinterlace/yadif.c b/subprojects/gst-plugins-good/gst/deinterlace/yadif.c index eddf422cdc..4f271dde02 100644 --- a/subprojects/gst-plugins-good/gst/deinterlace/yadif.c +++ b/subprojects/gst-plugins-good/gst/deinterlace/yadif.c @@ -76,6 +76,10 @@ static void filter_scanline_yadif_planar (GstDeinterlaceSimpleMethod * self, guint8 * out, const GstDeinterlaceScanlineData * scanlines, guint size); +static void +filter_scanline_yadif_planar_16bits (GstDeinterlaceSimpleMethod * self, + guint8 * out, const GstDeinterlaceScanlineData * scanlines, guint size); + static void filter_scanline_yadif_semiplanar (GstDeinterlaceSimpleMethod * self, guint8 * out, const GstDeinterlaceScanlineData * scanlines, guint size); @@ -114,6 +118,24 @@ filter_line_c_planar_mode2 (void *ORC_RESTRICT dst, const void *ORC_RESTRICT ttone, const void *ORC_RESTRICT ttp, const void *ORC_RESTRICT bbone, const void *ORC_RESTRICT bbp, int w); +static void +filter_line_c_planar_mode0_16bits (void *ORC_RESTRICT dst, + const void *ORC_RESTRICT tzero, const void *ORC_RESTRICT bzero, + const void *ORC_RESTRICT mone, const void *ORC_RESTRICT mp, + const void *ORC_RESTRICT ttwo, const void *ORC_RESTRICT btwo, + const void *ORC_RESTRICT tptwo, const void *ORC_RESTRICT bptwo, + const void *ORC_RESTRICT ttone, const void *ORC_RESTRICT ttp, + const void *ORC_RESTRICT bbone, const void *ORC_RESTRICT bbp, int w); + +static void +filter_line_c_planar_mode2_16bits (void *ORC_RESTRICT dst, + const void *ORC_RESTRICT tzero, const void *ORC_RESTRICT bzero, + const void *ORC_RESTRICT mone, const void *ORC_RESTRICT mp, + const void *ORC_RESTRICT ttwo, const void *ORC_RESTRICT btwo, + const void *ORC_RESTRICT tptwo, const void *ORC_RESTRICT bptwo, + const void *ORC_RESTRICT ttone, const void *ORC_RESTRICT ttp, + const void *ORC_RESTRICT bbone, const void *ORC_RESTRICT bbp, int w); + static void (*filter_mode2) (void *ORC_RESTRICT dst, const void *ORC_RESTRICT tzero, const void *ORC_RESTRICT bzero, const void *ORC_RESTRICT mone, const void *ORC_RESTRICT mp, @@ -130,6 +152,21 @@ static void (*filter_mode0) (void *ORC_RESTRICT dst, const void *ORC_RESTRICT ttone, const void *ORC_RESTRICT ttp, const void *ORC_RESTRICT bbone, const void *ORC_RESTRICT bbp, int w); +static void (*filter_mode2_16bits) (void *ORC_RESTRICT dst, + const void *ORC_RESTRICT tzero, const void *ORC_RESTRICT bzero, + const void *ORC_RESTRICT mone, const void *ORC_RESTRICT mp, + const void *ORC_RESTRICT ttwo, const void *ORC_RESTRICT btwo, + const void *ORC_RESTRICT tptwo, const void *ORC_RESTRICT bptwo, + const void *ORC_RESTRICT ttone, const void *ORC_RESTRICT ttp, + const void *ORC_RESTRICT bbone, const void *ORC_RESTRICT bbp, int w); + +static void (*filter_mode0_16bits) (void *ORC_RESTRICT dst, + const void *ORC_RESTRICT tzero, const void *ORC_RESTRICT bzero, + const void *ORC_RESTRICT mone, const void *ORC_RESTRICT mp, + const void *ORC_RESTRICT ttwo, const void *ORC_RESTRICT btwo, + const void *ORC_RESTRICT tptwo, const void *ORC_RESTRICT bptwo, + const void *ORC_RESTRICT ttone, const void *ORC_RESTRICT ttp, + const void *ORC_RESTRICT bbone, const void *ORC_RESTRICT bbp, int w); static void copy_scanline (GstDeinterlaceSimpleMethod * self, guint8 * out, @@ -166,6 +203,9 @@ static void dism_class->copy_scanline_bgr = copy_scanline; dism_class->copy_scanline_nv12 = copy_scanline; dism_class->copy_scanline_nv21 = copy_scanline; + dism_class->copy_scanline_planar_y_16bits = copy_scanline; + dism_class->copy_scanline_planar_u_16bits = copy_scanline; + dism_class->copy_scanline_planar_v_16bits = copy_scanline; dism_class->interpolate_scanline_planar_y = filter_scanline_yadif_planar; dism_class->interpolate_scanline_planar_u = filter_scanline_yadif_planar; @@ -182,6 +222,12 @@ static void dism_class->interpolate_scanline_bgr = filter_scanline_yadif_packed_3; dism_class->interpolate_scanline_nv12 = filter_scanline_yadif_semiplanar; dism_class->interpolate_scanline_nv21 = filter_scanline_yadif_semiplanar; + dism_class->interpolate_scanline_planar_y_16bits = + filter_scanline_yadif_planar_16bits; + dism_class->interpolate_scanline_planar_u_16bits = + filter_scanline_yadif_planar_16bits; + dism_class->interpolate_scanline_planar_v_16bits = + filter_scanline_yadif_planar_16bits; } #define FFABS(a) ABS(a) @@ -299,6 +345,42 @@ filter_line_c_planar (void *ORC_RESTRICT dst, const void *ORC_RESTRICT tzero, FILTER (start, end, 1); } +ALWAYS_INLINE static void +filter_line_c_planar_16bits (void *ORC_RESTRICT dst, + const void *ORC_RESTRICT tzero, + const void *ORC_RESTRICT bzero, const void *ORC_RESTRICT mone, + const void *ORC_RESTRICT mp, const void *ORC_RESTRICT ttwo, + const void *ORC_RESTRICT btwo, const void *ORC_RESTRICT tptwo, + const void *ORC_RESTRICT bptwo, const void *ORC_RESTRICT ttone, + const void *ORC_RESTRICT ttp, const void *ORC_RESTRICT bbone, + const void *ORC_RESTRICT bbp, int w, int mode) +{ + int x; + const int start = 0; + const int colors = 1; + const int y_alternates_every = 0; + const int end = w; + guint16 *sdst = (guint16 *) dst + 3; + guint16 *stzero = (guint16 *) tzero + 3; + guint16 *sbzero = (guint16 *) bzero + 3; + guint16 *smone = (guint16 *) mone + 3; + guint16 *smp = (guint16 *) mp + 3; + guint16 *sttwo = (guint16 *) ttwo + 3; + guint16 *sbtwo = (guint16 *) btwo + 3; + guint16 *stptwo = (guint16 *) tptwo + 3; + guint16 *sbptwo = (guint16 *) bptwo + 3; + guint16 *sttone = (guint16 *) ttone + 3; + guint16 *sttp = (guint16 *) ttp + 3; + guint16 *sbbone = (guint16 *) bbone + 3; + guint16 *sbbp = (guint16 *) bbp + 3; + /* The function is called for processing the middle + * pixels of each line, excluding 3 at each end. + * This allows the FILTER macro to be + * called so that it processes all the pixels normally. A constant value of + * true for is_not_edge lets the compiler ignore the if statement. */ + FILTER (start, end, 1); +} + ALWAYS_INLINE G_GNUC_UNUSED static void filter_line_c_planar_mode0 (void *ORC_RESTRICT dst, const void *ORC_RESTRICT tzero, const void *ORC_RESTRICT bzero, @@ -325,6 +407,32 @@ filter_line_c_planar_mode2 (void *ORC_RESTRICT dst, ttone, ttp, bbone, bbp, w, 2); } +ALWAYS_INLINE G_GNUC_UNUSED static void +filter_line_c_planar_mode0_16bits (void *ORC_RESTRICT dst, + const void *ORC_RESTRICT tzero, const void *ORC_RESTRICT bzero, + const void *ORC_RESTRICT mone, const void *ORC_RESTRICT mp, + const void *ORC_RESTRICT ttwo, const void *ORC_RESTRICT btwo, + const void *ORC_RESTRICT tptwo, const void *ORC_RESTRICT bptwo, + const void *ORC_RESTRICT ttone, const void *ORC_RESTRICT ttp, + const void *ORC_RESTRICT bbone, const void *ORC_RESTRICT bbp, int w) +{ + filter_line_c_planar_16bits (dst, tzero, bzero, mone, mp, ttwo, btwo, tptwo, + bptwo, ttone, ttp, bbone, bbp, w, 0); +} + +ALWAYS_INLINE G_GNUC_UNUSED static void +filter_line_c_planar_mode2_16bits (void *ORC_RESTRICT dst, + const void *ORC_RESTRICT tzero, const void *ORC_RESTRICT bzero, + const void *ORC_RESTRICT mone, const void *ORC_RESTRICT mp, + const void *ORC_RESTRICT ttwo, const void *ORC_RESTRICT btwo, + const void *ORC_RESTRICT tptwo, const void *ORC_RESTRICT bptwo, + const void *ORC_RESTRICT ttone, const void *ORC_RESTRICT ttp, + const void *ORC_RESTRICT bbone, const void *ORC_RESTRICT bbp, int w) +{ + filter_line_c_planar_16bits (dst, tzero, bzero, mone, mp, ttwo, btwo, tptwo, + bptwo, ttone, ttp, bbone, bbp, w, 2); +} + ALWAYS_INLINE static void filter_edges (guint8 * sdst, const guint8 * stzero, const guint8 * sbzero, const guint8 * smone, const guint8 * smp, const guint8 * sttwo, @@ -344,6 +452,39 @@ filter_edges (guint8 * sdst, const guint8 * stzero, const guint8 * sbzero, FILTER (w - border, w, 0); } +ALWAYS_INLINE static void +filter_edges_16bits (guint8 * sdst_, const guint8 * stzero_, + const guint8 * sbzero_, + const guint8 * smone_, const guint8 * smp_, const guint8 * sttwo_, + const guint8 * sbtwo_, const guint8 * stptwo_, const guint8 * sbptwo_, + const guint8 * sttone_, const guint8 * sttp_, const guint8 * sbbone_, + const guint8 * sbbp_, int w, int colors, int y_alternates_every, + int mode, const int bpp) +{ + int x; + const int edge = colors * (MAX_ALIGN / bpp); + const int border = 3 * colors; + guint16 *sdst = (guint16 *) sdst_; + guint16 *stzero = (guint16 *) stzero_; + guint16 *sbzero = (guint16 *) sbzero_; + guint16 *smone = (guint16 *) smone_; + guint16 *smp = (guint16 *) smp_; + guint16 *sttwo = (guint16 *) sttwo_; + guint16 *sbtwo = (guint16 *) sbtwo_; + guint16 *stptwo = (guint16 *) stptwo_; + guint16 *sbptwo = (guint16 *) sbptwo_; + guint16 *sttone = (guint16 *) sttone_; + guint16 *sttp = (guint16 *) sttp_; + guint16 *sbbone = (guint16 *) sbbone_; + guint16 *sbbp = (guint16 *) sbbp_; + + /* Only edge pixels need to be processed here. A constant value of false + * for is_not_edge should let the compiler ignore the whole branch. */ + FILTER (0, border, 0); + FILTER (w - edge, w - border, 1); + FILTER (w - border, w, 0); +} + static void filter_scanline_yadif_semiplanar (GstDeinterlaceSimpleMethod * self, guint8 * out, const GstDeinterlaceScanlineData * s_orig, guint size) @@ -451,9 +592,49 @@ filter_scanline_yadif_planar (GstDeinterlaceSimpleMethod * self, (void *) s.bbp, w - edge); } +ALWAYS_INLINE static void +filter_scanline_yadif_planar_16bits (GstDeinterlaceSimpleMethod * self, + guint8 * out, const GstDeinterlaceScanlineData * s_orig, guint size) +{ + guint8 *dst = out; + const int bpp = 2; + int w = size / bpp; + int edge = MAX_ALIGN / bpp; + GstDeinterlaceScanlineData s = *s_orig; + + int mode = (s.tt1 == NULL || s.bb1 == NULL || s.ttp == NULL + || s.bbp == NULL) ? 2 : 0; + + /* When starting up, some data might not yet be available, so use the current frame */ + if (s.m1 == NULL) + s.m1 = s.mp; + if (s.tt1 == NULL) + s.tt1 = s.ttp; + if (s.bb1 == NULL) + s.bb1 = s.bbp; + if (s.t2 == NULL) + s.t2 = s.tp2; + if (s.b2 == NULL) + s.b2 = s.bp2; + + filter_edges_16bits (dst, s.t0, s.b0, s.m1, s.mp, s.t2, s.b2, s.tp2, s.bp2, + s.tt1, s.ttp, s.bb1, s.bbp, w, 1, 0, mode, bpp); + if (mode == 0) + filter_mode0_16bits (dst, (void *) s.t0, (void *) s.b0, (void *) s.m1, + (void *) s.mp, (void *) s.t2, (void *) s.b2, (void *) s.tp2, + (void *) s.bp2, (void *) s.tt1, (void *) s.ttp, (void *) s.bb1, + (void *) s.bbp, w - edge); + else + filter_mode2_16bits (dst, (void *) s.t0, (void *) s.b0, (void *) s.m1, + (void *) s.mp, (void *) s.t2, (void *) s.b2, (void *) s.tp2, + (void *) s.bp2, (void *) s.tt1, (void *) s.ttp, (void *) s.bb1, + (void *) s.bbp, w - edge); +} + static void gst_deinterlace_method_yadif_init (GstDeinterlaceMethodYadif * self) { + /* TODO: add asm support for high bitdepth */ #if (defined __x86_64__ || defined _M_X64) && defined HAVE_NASM if ( # if defined HAVE_ORC @@ -467,16 +648,22 @@ gst_deinterlace_method_yadif_init (GstDeinterlaceMethodYadif * self) GST_DEBUG ("SSSE3 optimization enabled"); filter_mode0 = gst_yadif_filter_line_mode0_ssse3; filter_mode2 = gst_yadif_filter_line_mode2_ssse3; + filter_mode0_16bits = filter_line_c_planar_mode0_16bits; + filter_mode2_16bits = filter_line_c_planar_mode2_16bits; } else { GST_DEBUG ("SSE2 optimization enabled"); filter_mode0 = gst_yadif_filter_line_mode0_sse2; filter_mode2 = gst_yadif_filter_line_mode2_sse2; + filter_mode0_16bits = filter_line_c_planar_mode0_16bits; + filter_mode2_16bits = filter_line_c_planar_mode2_16bits; } #else { GST_DEBUG ("SSE optimization disabled"); filter_mode0 = filter_line_c_planar_mode0; filter_mode2 = filter_line_c_planar_mode2; + filter_mode0_16bits = filter_line_c_planar_mode0_16bits; + filter_mode2_16bits = filter_line_c_planar_mode2_16bits; } #endif }