static void _RGB_to_YUV (GstGLColorConvert * convert) { struct ConvertInfo *info = &convert->priv->convert_info; GstVideoFormat in_format = GST_VIDEO_INFO_FORMAT (&convert->in_info); const gchar *in_format_str = gst_video_format_to_string (in_format); GstVideoFormat out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info); gchar *pixel_order = _RGB_pixel_order (in_format_str, "rgba"); const gchar *alpha; info->frag_prog = NULL; info->in_n_textures = 1; info->shader_tex_names[0] = "tex"; switch (out_format) { case GST_VIDEO_FORMAT_AYUV: alpha = _is_RGBx (in_format) ? "1.0" : "texel.a"; info->frag_prog = g_strdup_printf (frag_RGB_to_AYUV, pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3], alpha); info->out_n_textures = 1; break; case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_Y444: case GST_VIDEO_FORMAT_Y42B: case GST_VIDEO_FORMAT_Y41B: info->frag_prog = g_strdup_printf (frag_RGB_to_PLANAR_YUV, pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3], pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]); info->out_n_textures = 3; if (out_format == GST_VIDEO_FORMAT_Y444) { info->chroma_sampling[0] = info->chroma_sampling[1] = 1.0f; } else if (out_format == GST_VIDEO_FORMAT_Y42B) { info->chroma_sampling[0] = 2.0f; info->chroma_sampling[1] = 1.0f; } else if (out_format == GST_VIDEO_FORMAT_Y41B) { info->chroma_sampling[0] = 4.0f; info->chroma_sampling[1] = 1.0f; } else { info->chroma_sampling[0] = info->chroma_sampling[1] = 2.0f; } break; case GST_VIDEO_FORMAT_YUY2: info->frag_prog = g_strdup_printf (frag_RGB_to_YUY2_UYVY, pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3], pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3], "y", "u", "y", "v"); info->out_n_textures = 1; break; case GST_VIDEO_FORMAT_UYVY: info->frag_prog = g_strdup_printf (frag_RGB_to_YUY2_UYVY, pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3], pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3], "u", "y", "v", "y"); info->out_n_textures = 1; break; default: break; } if (gst_video_colorimetry_matches (&convert->in_info.colorimetry, GST_VIDEO_COLORIMETRY_BT709)) { info->cms_offset = (gfloat *) from_rgb_bt709_offset; info->cms_coeff1 = (gfloat *) from_rgb_bt709_ycoeff; info->cms_coeff2 = (gfloat *) from_rgb_bt709_ucoeff; info->cms_coeff3 = (gfloat *) from_rgb_bt709_vcoeff; } else { /* defaults/bt601 */ info->cms_offset = (gfloat *) from_rgb_bt601_offset; info->cms_coeff1 = (gfloat *) from_rgb_bt601_ycoeff; info->cms_coeff2 = (gfloat *) from_rgb_bt601_ucoeff; info->cms_coeff3 = (gfloat *) from_rgb_bt601_vcoeff; } g_free (pixel_order); }
static gboolean gst_rtp_vraw_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps) { GstRtpVRawPay *rtpvrawpay; gboolean res; gint pgroup, xinc, yinc; const gchar *depthstr, *samplingstr, *colorimetrystr; gchar *wstr, *hstr; GstVideoInfo info; rtpvrawpay = GST_RTP_VRAW_PAY (payload); if (!gst_video_info_from_caps (&info, caps)) goto invalid_caps; rtpvrawpay->vinfo = info; if (gst_video_colorimetry_matches (&info.colorimetry, GST_VIDEO_COLORIMETRY_BT601)) { colorimetrystr = "BT601-5"; } else if (gst_video_colorimetry_matches (&info.colorimetry, GST_VIDEO_COLORIMETRY_BT709)) { colorimetrystr = "BT709-2"; } else if (gst_video_colorimetry_matches (&info.colorimetry, GST_VIDEO_COLORIMETRY_SMPTE240M)) { colorimetrystr = "SMPTE240M"; } else { colorimetrystr = "SMPTE240M"; } xinc = yinc = 1; /* these values are the only thing we can do */ depthstr = "8"; switch (GST_VIDEO_INFO_FORMAT (&info)) { case GST_VIDEO_FORMAT_RGBA: samplingstr = "RGBA"; pgroup = 4; break; case GST_VIDEO_FORMAT_BGRA: samplingstr = "BGRA"; pgroup = 4; break; case GST_VIDEO_FORMAT_RGB: samplingstr = "RGB"; pgroup = 3; break; case GST_VIDEO_FORMAT_BGR: samplingstr = "BGR"; pgroup = 3; break; case GST_VIDEO_FORMAT_AYUV: samplingstr = "YCbCr-4:4:4"; pgroup = 3; break; case GST_VIDEO_FORMAT_UYVY: samplingstr = "YCbCr-4:2:2"; pgroup = 4; xinc = 2; break; case GST_VIDEO_FORMAT_Y41B: samplingstr = "YCbCr-4:1:1"; pgroup = 6; xinc = 4; break; case GST_VIDEO_FORMAT_I420: samplingstr = "YCbCr-4:2:0"; pgroup = 6; xinc = yinc = 2; break; case GST_VIDEO_FORMAT_UYVP: samplingstr = "YCbCr-4:2:2"; pgroup = 5; xinc = 2; depthstr = "10"; break; default: goto unknown_format; break; } if (GST_VIDEO_INFO_IS_INTERLACED (&info)) { yinc *= 2; } rtpvrawpay->pgroup = pgroup; rtpvrawpay->xinc = xinc; rtpvrawpay->yinc = yinc; GST_DEBUG_OBJECT (payload, "width %d, height %d, sampling %s", GST_VIDEO_INFO_WIDTH (&info), GST_VIDEO_INFO_HEIGHT (&info), samplingstr); GST_DEBUG_OBJECT (payload, "xinc %d, yinc %d, pgroup %d", xinc, yinc, pgroup); wstr = g_strdup_printf ("%d", GST_VIDEO_INFO_WIDTH (&info)); hstr = g_strdup_printf ("%d", GST_VIDEO_INFO_HEIGHT (&info)); gst_rtp_base_payload_set_options (payload, "video", TRUE, "RAW", 90000); if (GST_VIDEO_INFO_IS_INTERLACED (&info)) { res = gst_rtp_base_payload_set_outcaps (payload, "sampling", G_TYPE_STRING, samplingstr, "depth", G_TYPE_STRING, depthstr, "width", G_TYPE_STRING, wstr, "height", G_TYPE_STRING, hstr, "colorimetry", G_TYPE_STRING, colorimetrystr, "interlace", G_TYPE_STRING, "true", NULL); } else { res = gst_rtp_base_payload_set_outcaps (payload, "sampling", G_TYPE_STRING, samplingstr, "depth", G_TYPE_STRING, depthstr, "width", G_TYPE_STRING, wstr, "height", G_TYPE_STRING, hstr, "colorimetry", G_TYPE_STRING, colorimetrystr, NULL); } g_free (wstr); g_free (hstr); return res; /* ERRORS */ invalid_caps: { GST_ERROR_OBJECT (payload, "could not parse caps"); return FALSE; } unknown_format: { GST_ERROR_OBJECT (payload, "unknown caps format"); return FALSE; } }
static void _YUV_to_RGB (GstGLColorConvert * convert) { struct ConvertInfo *info = &convert->priv->convert_info; GstVideoFormat out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info); const gchar *out_format_str = gst_video_format_to_string (out_format); gchar *pixel_order = _RGB_pixel_order ("rgba", out_format_str); #if GST_GL_HAVE_PLATFORM_EAGL gboolean texture_rg = FALSE; #else gboolean texture_rg = gst_gl_context_check_feature (convert->context, "GL_EXT_texture_rg") || gst_gl_context_check_feature (convert->context, "GL_ARB_texture_rg"); #endif info->out_n_textures = 1; switch (GST_VIDEO_INFO_FORMAT (&convert->in_info)) { case GST_VIDEO_FORMAT_AYUV: info->frag_prog = g_strdup_printf (frag_AYUV_to_RGB, pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]); info->in_n_textures = 1; info->shader_tex_names[0] = "tex"; break; case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_Y444: case GST_VIDEO_FORMAT_Y42B: case GST_VIDEO_FORMAT_Y41B: info->frag_prog = g_strdup_printf (frag_PLANAR_YUV_to_RGB, pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]); info->in_n_textures = 3; info->shader_tex_names[0] = "Ytex"; info->shader_tex_names[1] = "Utex"; info->shader_tex_names[2] = "Vtex"; break; case GST_VIDEO_FORMAT_YV12: info->frag_prog = g_strdup_printf (frag_PLANAR_YUV_to_RGB, pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]); info->in_n_textures = 3; info->shader_tex_names[0] = "Ytex"; info->shader_tex_names[1] = "Vtex"; info->shader_tex_names[2] = "Utex"; break; case GST_VIDEO_FORMAT_YUY2: { char uv_val = texture_rg ? 'g' : 'a'; info->frag_prog = g_strdup_printf (frag_YUY2_UYVY_to_RGB, 'r', uv_val, uv_val, 'g', 'a', pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]); info->in_n_textures = 1; info->shader_tex_names[0] = "Ytex"; break; } case GST_VIDEO_FORMAT_NV12: { char val2 = texture_rg ? 'g' : 'a'; info->frag_prog = g_strdup_printf (frag_NV12_NV21_to_RGB, 'r', val2, pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]); info->in_n_textures = 2; info->shader_tex_names[0] = "Ytex"; info->shader_tex_names[1] = "UVtex"; break; } case GST_VIDEO_FORMAT_NV21: { char val2 = texture_rg ? 'g' : 'a'; info->frag_prog = g_strdup_printf (frag_NV12_NV21_to_RGB, val2, 'r', pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]); info->in_n_textures = 2; info->shader_tex_names[0] = "Ytex"; info->shader_tex_names[1] = "UVtex"; break; } case GST_VIDEO_FORMAT_UYVY: { char y_val = texture_rg ? 'g' : 'a'; info->frag_prog = g_strdup_printf (frag_YUY2_UYVY_to_RGB, y_val, 'g', 'g', 'r', 'b', pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]); info->in_n_textures = 1; info->shader_tex_names[0] = "Ytex"; break; } default: break; } if (gst_video_colorimetry_matches (&convert->in_info.colorimetry, GST_VIDEO_COLORIMETRY_BT709)) { info->cms_offset = (gfloat *) from_yuv_bt709_offset; info->cms_coeff1 = (gfloat *) from_yuv_bt709_rcoeff; info->cms_coeff2 = (gfloat *) from_yuv_bt709_gcoeff; info->cms_coeff3 = (gfloat *) from_yuv_bt709_bcoeff; } else { /* defaults/bt601 */ info->cms_offset = (gfloat *) from_yuv_bt601_offset; info->cms_coeff1 = (gfloat *) from_yuv_bt601_rcoeff; info->cms_coeff2 = (gfloat *) from_yuv_bt601_gcoeff; info->cms_coeff3 = (gfloat *) from_yuv_bt601_bcoeff; } g_free (pixel_order); }