diff --git a/subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json b/subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json index 75e281b7a3..d7326d1ae3 100644 --- a/subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json +++ b/subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json @@ -15141,7 +15141,7 @@ "long-name": "Video test source", "pad-templates": { "src": { - "caps": "video/x-raw:\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 multiview-mode: { (string)mono, (string)left, (string)right }\nvideo/x-bayer:\n format: { bggr, rggb, grbg, gbrg }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n multiview-mode: { (string)mono, (string)left, (string)right }\n", + "caps": "video/x-raw:\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 multiview-mode: { (string)mono, (string)left, (string)right }\nvideo/x-bayer:\n format: { bggr, rggb, grbg, gbrg, bggr10le, rggb10le, grbg10le, gbrg10le, bggr10be, rggb10be, grbg10be, gbrg10be, bggr12le, rggb12le, grbg12le, gbrg12le, bggr12be, rggb12be, grbg12be, gbrg12be, bggr14le, rggb14le, grbg14le, gbrg14le, bggr14be, rggb14be, grbg14be, gbrg14be, bggr16le, rggb16le, grbg16le, gbrg16le, bggr16be, rggb16be, grbg16be, gbrg16be }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n multiview-mode: { (string)mono, (string)left, (string)right }\n", "direction": "src", "presence": "always" } diff --git a/subprojects/gst-plugins-base/gst/videotestsrc/gstvideotestsrc.c b/subprojects/gst-plugins-base/gst/videotestsrc/gstvideotestsrc.c index cef6809351..f736adaebd 100644 --- a/subprojects/gst-plugins-base/gst/videotestsrc/gstvideotestsrc.c +++ b/subprojects/gst-plugins-base/gst/videotestsrc/gstvideotestsrc.c @@ -89,11 +89,30 @@ enum PROP_LAST }; +#define BAYER_CAPS_GEN(mask, bits, endian) \ + " "#mask#bits#endian -#define VTS_VIDEO_CAPS GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) "," \ +#define BAYER_CAPS_ORD(bits, endian) \ + BAYER_CAPS_GEN(bggr, bits, endian)"," \ + BAYER_CAPS_GEN(rggb, bits, endian)"," \ + BAYER_CAPS_GEN(grbg, bits, endian)"," \ + BAYER_CAPS_GEN(gbrg, bits, endian) + +#define BAYER_CAPS_BITS(bits) \ + BAYER_CAPS_ORD(bits, le)"," \ + BAYER_CAPS_ORD(bits, be) + +#define BAYER_CAPS_ALL \ + BAYER_CAPS_ORD(,)"," \ + BAYER_CAPS_BITS(10)"," \ + BAYER_CAPS_BITS(12)"," \ + BAYER_CAPS_BITS(14)"," \ + BAYER_CAPS_BITS(16) + +#define VTS_VIDEO_CAPS GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) "," \ "multiview-mode = { mono, left, right }" \ ";" \ - "video/x-bayer, format=(string) { bggr, rggb, grbg, gbrg }, " \ + "video/x-bayer, format=(string) {" BAYER_CAPS_ALL " },"\ "width = " GST_VIDEO_SIZE_RANGE ", " \ "height = " GST_VIDEO_SIZE_RANGE ", " \ "framerate = " GST_VIDEO_FPS_RANGE ", " \ @@ -826,6 +845,8 @@ gst_video_test_src_get_property (GObject * object, guint prop_id, } } +#define DIV_ROUND_UP(s,v) (((s) + ((v)-1)) / (v)) + static gboolean gst_video_test_src_parse_caps (const GstCaps * caps, GstVideoInfo * info, GstVideoTestSrc * videotestsrc) @@ -834,7 +855,7 @@ gst_video_test_src_parse_caps (const GstCaps * caps, GstVideoInfo * info, gboolean ret; const GValue *framerate; const gchar *str; - gint x_inv = 0, y_inv = 0; + gint x_inv = 0, y_inv = 0, bpp = 0, bigendian = 0; GST_DEBUG ("parsing caps"); @@ -868,14 +889,39 @@ gst_video_test_src_parse_caps (const GstCaps * caps, GstVideoInfo * info, y_inv = 0; } else goto invalid_format; + + if (strlen (str) == 4) { /* 8bit bayer */ + bpp = 8; + } else if (strlen (str) == 8) { /* 10/12/14/16 le/be bayer */ + bpp = (gint) g_ascii_strtoull (str + 4, NULL, 10); + if (bpp & 1) /* odd bpp bayer formats not supported */ + goto invalid_format; + if (bpp < 10 || bpp > 16) /* bayer 10,12,14,16 only */ + goto invalid_format; + + if (g_str_has_suffix (str, "le")) + bigendian = 0; + else if (g_str_has_suffix (str, "be")) + bigendian = 1; + else + goto invalid_format; + } else + goto invalid_format; + + if (bpp == 8) + info->finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_GRAY8); + else if (bigendian) + info->finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_GRAY16_BE); + else + info->finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_GRAY16_LE); } videotestsrc->bayer = TRUE; + videotestsrc->bpp = bpp; videotestsrc->x_invert = x_inv; videotestsrc->y_invert = y_inv; - info->finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_GRAY8); - info->stride[0] = GST_ROUND_UP_4 (info->width); + info->stride[0] = GST_ROUND_UP_4 (info->width) * DIV_ROUND_UP (bpp, 8); info->size = info->stride[0] * info->height; return ret; @@ -971,7 +1017,7 @@ gst_video_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps) goto parse_failed; } else if (gst_structure_has_name (structure, "video/x-bayer")) { - if (!gst_video_test_src_parse_caps (caps, &info, &videotestsrc)) + if (!gst_video_test_src_parse_caps (caps, &info, videotestsrc)) goto parse_failed; } else { goto unsupported_caps; diff --git a/subprojects/gst-plugins-base/gst/videotestsrc/gstvideotestsrc.h b/subprojects/gst-plugins-base/gst/videotestsrc/gstvideotestsrc.h index e0a2dad9b4..10819f55d8 100644 --- a/subprojects/gst-plugins-base/gst/videotestsrc/gstvideotestsrc.h +++ b/subprojects/gst-plugins-base/gst/videotestsrc/gstvideotestsrc.h @@ -149,6 +149,7 @@ struct _GstVideoTestSrc { GstVideoInfo info; /* protected by the object or stream lock */ GstVideoChromaResample *subsample; gboolean bayer; + gint bpp; gint x_invert; gint y_invert; diff --git a/subprojects/gst-plugins-base/gst/videotestsrc/videotestsrc.c b/subprojects/gst-plugins-base/gst/videotestsrc/videotestsrc.c index 21e52fe4c9..dfaee8a764 100644 --- a/subprojects/gst-plugins-base/gst/videotestsrc/videotestsrc.c +++ b/subprojects/gst-plugins-base/gst/videotestsrc/videotestsrc.c @@ -158,7 +158,8 @@ static void paint_tmpline_ARGB (paintinfo * p, int x, int w); static void paint_tmpline_AYUV (paintinfo * p, int x, int w); static void convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y); -static void convert_hline_bayer (paintinfo * p, GstVideoFrame * frame, int y); +static void convert_hline_bayer8 (paintinfo * p, GstVideoFrame * frame, int y); +static void convert_hline_bayer16 (paintinfo * p, GstVideoFrame * frame, int y); #define SCALEBITS 10 #define ONE_HALF (1 << (SCALEBITS - 1)) @@ -208,7 +209,6 @@ videotestsrc_setup_paintinfo (GstVideoTestSrc * v, paintinfo * p, int w, int h) GstVideoInfo *info = &v->info; width = GST_VIDEO_INFO_WIDTH (info); - if (info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601) { p->colors = vts_colors_bt601_ycbcr_100; } else { @@ -217,7 +217,10 @@ videotestsrc_setup_paintinfo (GstVideoTestSrc * v, paintinfo * p, int w, int h) if (v->bayer) { p->paint_tmpline = paint_tmpline_ARGB; - p->convert_tmpline = convert_hline_bayer; + if (v->bpp == 8) + p->convert_tmpline = convert_hline_bayer8; + else + p->convert_tmpline = convert_hline_bayer16; } else { p->convert_tmpline = convert_hline_generic; if (GST_VIDEO_INFO_IS_RGB (info)) { @@ -236,6 +239,7 @@ videotestsrc_setup_paintinfo (GstVideoTestSrc * v, paintinfo * p, int w, int h) p->x_offset = (v->horizontal_speed * v->n_frames) % width; if (p->x_offset < 0) p->x_offset += width; + p->bpp = v->bpp; p->x_invert = v->x_invert; p->y_invert = v->y_invert; @@ -1679,7 +1683,7 @@ convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y) } static void -convert_hline_bayer (paintinfo * p, GstVideoFrame * frame, int y) +convert_hline_bayer8 (paintinfo * p, GstVideoFrame * frame, int y) { int i; guint8 *data = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); @@ -1696,6 +1700,41 @@ convert_hline_bayer (paintinfo * p, GstVideoFrame * frame, int y) } } +static guint16 +bayer_scale_and_swap (paintinfo * p, const GstVideoFormatInfo * finfo, + guint8 r8) +{ + guint16 r16 = (r8 << (p->bpp - 8)) | (r8 >> (16 - p->bpp)); +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + if (!GST_VIDEO_FORMAT_INFO_IS_LE (finfo)) + r16 = GUINT16_SWAP_LE_BE (r16); +#else + if (GST_VIDEO_FORMAT_INFO_IS_LE (finfo)) + r16 = GUINT16_SWAP_LE_BE (r16); +#endif + return r16; +} + +static void +convert_hline_bayer16 (paintinfo * p, GstVideoFrame * frame, int y) +{ + const GstVideoFormatInfo *finfo = frame->info.finfo; + guint8 *data = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); + guint16 *R16 = + (guint16 *) (data + y * GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0)); + guint8 *argb = p->tmpline; + gint width = GST_VIDEO_FRAME_WIDTH (frame); + int x_inv = p->x_invert; + int y_inv = p->y_invert; + int y_offset = 1 - ((y ^ y_inv) & 1); + int i; + + for (i = 0; i < width; i++) { + int x_offset = 2 - ((i ^ x_inv) & 1); + R16[i] = bayer_scale_and_swap (p, finfo, argb[4 * i + y_offset + x_offset]); + } +} + void gst_video_test_src_pinwheel (GstVideoTestSrc * v, GstClockTime pts, GstVideoFrame * frame) diff --git a/subprojects/gst-plugins-base/gst/videotestsrc/videotestsrc.h b/subprojects/gst-plugins-base/gst/videotestsrc/videotestsrc.h index c0d6933139..9304824911 100644 --- a/subprojects/gst-plugins-base/gst/videotestsrc/videotestsrc.h +++ b/subprojects/gst-plugins-base/gst/videotestsrc/videotestsrc.h @@ -42,6 +42,7 @@ struct paintinfo_struct GstVideoChromaResample *subsample; int x_offset; + int bpp; int x_invert; int y_invert;