Пример #1
0
static gboolean
ensure_context (GstGLStereoSplit * self)
{
  GError *error = NULL;

  if (!gst_gl_ensure_element_data (self, &self->display, &self->other_context))
    return FALSE;

  gst_gl_display_filter_gl_api (self->display, SUPPORTED_GL_APIS);

  _find_local_gl_context (self);

  if (!self->context) {
    GST_OBJECT_LOCK (self->display);
    do {
      if (self->context)
        gst_object_unref (self->context);
      /* just get a GL context.  we don't care */
      self->context =
          gst_gl_display_get_gl_context_for_thread (self->display, NULL);
      if (!self->context) {
        if (!gst_gl_display_create_context (self->display, self->other_context,
                &self->context, &error)) {
          GST_OBJECT_UNLOCK (self->display);
          goto context_error;
        }
      }
    } while (!gst_gl_display_add_context (self->display, self->context));
    GST_OBJECT_UNLOCK (self->display);
  }

  return TRUE;

context_error:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND, ("%s", error->message),
        (NULL));
    g_clear_error (&error);
    return FALSE;
  }
}
static gboolean
gst_gl_base_mixer_decide_allocation (GstGLBaseMixer * mix, GstQuery * query)
{
    GstGLBaseMixerClass *mix_class = GST_GL_BASE_MIXER_GET_CLASS (mix);
    GError *error = NULL;
    gboolean ret = TRUE;

    if (!gst_gl_ensure_element_data (mix, &mix->display,
                                     &mix->priv->other_context))
        return FALSE;

    gst_gl_display_filter_gl_api (mix->display, mix_class->supported_gl_api);

    _find_local_gl_context (mix);

    if (!mix->context) {
        GST_OBJECT_LOCK (mix->display);
        do {
            if (mix->context) {
                gst_object_unref (mix->context);
                mix->context = NULL;
            }
            /* just get a GL context.  we don't care */
            mix->context =
                gst_gl_display_get_gl_context_for_thread (mix->display, NULL);
            if (!mix->context) {
                if (!gst_gl_display_create_context (mix->display,
                                                    mix->priv->other_context, &mix->context, &error)) {
                    GST_OBJECT_UNLOCK (mix->display);
                    goto context_error;
                }
            }
        } while (!gst_gl_display_add_context (mix->display, mix->context));
        GST_OBJECT_UNLOCK (mix->display);
    }

    {
        GstGLAPI current_gl_api = gst_gl_context_get_gl_api (mix->context);
        if ((current_gl_api & mix_class->supported_gl_api) == 0)
            goto unsupported_gl_api;
    }

    if (mix_class->decide_allocation)
        ret = mix_class->decide_allocation (mix, query);

    return ret;

unsupported_gl_api:
    {
        GstGLAPI gl_api = gst_gl_context_get_gl_api (mix->context);
        gchar *gl_api_str = gst_gl_api_to_string (gl_api);
        gchar *supported_gl_api_str =
            gst_gl_api_to_string (mix_class->supported_gl_api);
        GST_ELEMENT_ERROR (mix, RESOURCE, BUSY,
                           ("GL API's not compatible context: %s supported: %s", gl_api_str,
                            supported_gl_api_str), (NULL));

        g_free (supported_gl_api_str);
        g_free (gl_api_str);
        return FALSE;
    }
context_error:
    {
        GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s", error->message),
                           (NULL));
        g_clear_error (&error);
        return FALSE;
    }
}
Пример #3
0
static gboolean
gst_gl_test_src_decide_allocation (GstBaseSrc * basesrc, GstQuery * query)
{
  GstGLTestSrc *src = GST_GL_TEST_SRC (basesrc);
  GstBufferPool *pool = NULL;
  GstStructure *config;
  GstCaps *caps;
  guint min, max, size;
  gboolean update_pool;
  GError *error = NULL;

  if (!gst_gl_ensure_element_data (src, &src->display, &src->other_context))
    return FALSE;

  gst_gl_display_filter_gl_api (src->display, SUPPORTED_GL_APIS);

  _find_local_gl_context (src);

  if (!src->context) {
    GST_OBJECT_LOCK (src->display);
    do {
      if (src->context) {
        gst_object_unref (src->context);
        src->context = NULL;
      }
      /* just get a GL context.  we don't care */
      src->context =
          gst_gl_display_get_gl_context_for_thread (src->display, NULL);
      if (!src->context) {
        if (!gst_gl_display_create_context (src->display, src->other_context,
                &src->context, &error)) {
          GST_OBJECT_UNLOCK (src->display);
          goto context_error;
        }
      }
    } while (!gst_gl_display_add_context (src->display, src->context));
    GST_OBJECT_UNLOCK (src->display);
  }

  if ((gst_gl_context_get_gl_api (src->context) & SUPPORTED_GL_APIS) == 0)
    goto unsupported_gl_api;

  gst_gl_context_thread_add (src->context,
      (GstGLContextThreadFunc) _src_generate_fbo_gl, src);
  if (!src->fbo)
    goto context_error;

  gst_query_parse_allocation (query, &caps, NULL);

  if (gst_query_get_n_allocation_pools (query) > 0) {
    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);

    update_pool = TRUE;
  } else {
    GstVideoInfo vinfo;

    gst_video_info_init (&vinfo);
    gst_video_info_from_caps (&vinfo, caps);
    size = vinfo.size;
    min = max = 0;
    update_pool = FALSE;
  }

  if (!pool || !GST_IS_GL_BUFFER_POOL (pool)) {
    /* can't use this pool */
    if (pool)
      gst_object_unref (pool);
    pool = gst_gl_buffer_pool_new (src->context);
  }
  config = gst_buffer_pool_get_config (pool);

  gst_buffer_pool_config_set_params (config, caps, size, min, max);
  gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
  if (gst_query_find_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, NULL))
    gst_buffer_pool_config_add_option (config,
        GST_BUFFER_POOL_OPTION_GL_SYNC_META);
  gst_buffer_pool_config_add_option (config,
      GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META);

  gst_buffer_pool_set_config (pool, config);

  if (update_pool)
    gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
  else
    gst_query_add_allocation_pool (query, pool, size, min, max);

  gst_gl_test_src_init_shader (src);

  gst_object_unref (pool);

  return TRUE;

unsupported_gl_api:
  {
    GstGLAPI gl_api = gst_gl_context_get_gl_api (src->context);
    gchar *gl_api_str = gst_gl_api_to_string (gl_api);
    gchar *supported_gl_api_str = gst_gl_api_to_string (SUPPORTED_GL_APIS);
    GST_ELEMENT_ERROR (src, RESOURCE, BUSY,
        ("GL API's not compatible context: %s supported: %s", gl_api_str,
            supported_gl_api_str), (NULL));

    g_free (supported_gl_api_str);
    g_free (gl_api_str);
    return FALSE;
  }
context_error:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("%s", error->message),
        (NULL));
    g_clear_error (&error);
    if (src->context)
      gst_object_unref (src->context);
    src->context = NULL;
    return FALSE;
  }
}
Пример #4
0
void
gst_gl_context_helper_ensure_context (GstGLContextHelper * ctxh)
{
  GError *error = NULL;
  GstGLContext *context;

  g_return_if_fail (ctxh != NULL);

  if (!ctxh->display)
    gst_gl_ensure_element_data (ctxh->element, &ctxh->display,
        &ctxh->other_context);

  if (!ctxh->display)
    goto display_error;

  context = _find_local_gl_context (ctxh);
  if (context) {
    GST_INFO_OBJECT (ctxh->element, "found local context %p, old context %p",
        context, ctxh->context);
    if (ctxh->context)
      gst_object_unref (ctxh->context);
    ctxh->context = context;
  }

  if (!ctxh->context) {
    GST_OBJECT_LOCK (ctxh->display);
    do {
      if (ctxh->context)
        gst_object_unref (ctxh->context);
      ctxh->context =
          gst_gl_display_get_gl_context_for_thread (ctxh->display, NULL);
      if (!ctxh->context) {
        if (!gst_gl_display_create_context (ctxh->display,
                ctxh->other_context, &ctxh->context, &error)) {
          GST_OBJECT_UNLOCK (ctxh->display);
          goto context_error;
        }
      }
    } while (!gst_gl_display_add_context (ctxh->display, ctxh->context));
    GST_OBJECT_UNLOCK (ctxh->display);
  }

  return;

context_error:
  {
    GST_ELEMENT_ERROR (ctxh->element, RESOURCE, NOT_FOUND, ("%s",
            error->message), (NULL));
    g_clear_error (&error);

    return;
  }

display_error:
  {
    GST_ELEMENT_ERROR (ctxh->element, RESOURCE, NOT_FOUND,
        ("Failed to obtain display"), (NULL));

    return;
  }
}