Exemplo n.º 1
0
static void
gst_gl_filter_stop_gl (GstGLDisplay * display, gpointer data)
{
  GstGLFilter *filter = GST_GL_FILTER (data);
  GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);

  filter_class->display_reset_cb (filter);
}
Exemplo n.º 2
0
static void
gst_gl_filter_start_gl (GstGLContext * context, gpointer data)
{
  GstGLFilter *filter = GST_GL_FILTER (data);
  GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);

  filter_class->display_init_cb (filter);
}
Exemplo n.º 3
0
static gboolean
gst_gl_filter_do_transform (GstGLFilter * filter,
    GstGLBuffer * inbuf, GstGLBuffer * outbuf)
{
  GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);

  filter_class->filter (filter, inbuf, outbuf);

  return TRUE;
}
Exemplo n.º 4
0
static gboolean
gst_gl_filter_start (GstBaseTransform * bt)
{
  GstGLFilter *filter = GST_GL_FILTER (bt);
  GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);

  if (filter_class->onStart)
    filter_class->onStart (filter);

  return TRUE;
}
Exemplo n.º 5
0
static gboolean
gst_gl_filter_start (GstBaseTransform * bt)
{
  GstGLFilter *filter = GST_GL_FILTER (bt);
  GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);

  if (!gst_gl_ensure_display (filter, &filter->display))
    return FALSE;

  if (filter_class->onStart)
    filter_class->onStart (filter);

  return TRUE;
}
Exemplo n.º 6
0
static void
gst_gl_filter_reset (GstGLFilter * filter)
{
  GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);

  if (filter->upload) {
    gst_object_unref (filter->upload);
    filter->upload = NULL;
  }

  if (filter->download) {
    gst_object_unref (filter->download);
    filter->download = NULL;
  }

  if (filter->context) {
    if (filter_class->onReset)
      filter_class->onReset (filter);

    if (filter_class->display_reset_cb != NULL) {
      gst_gl_context_thread_add (filter->context, gst_gl_filter_stop_gl,
          filter);
    }
    //blocking call, delete the FBO
    if (filter->fbo != 0) {
      gst_gl_context_del_fbo (filter->context, filter->fbo,
          filter->depthbuffer);
    }
    gst_object_unref (filter->context);
    filter->context = NULL;
  }

  if (filter->display) {
    gst_object_unref (filter->display);
    filter->display = NULL;
  }

  filter->fbo = 0;
  filter->depthbuffer = 0;
  filter->default_shader = NULL;
  if (filter->other_context)
    gst_object_unref (filter->other_context);
  filter->other_context = NULL;

  if (filter->context)
    gst_object_unref (filter->context);
  filter->context = NULL;
}
Exemplo n.º 7
0
static gboolean
gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstGLFilter *filter = GST_GL_FILTER (bt);
  gboolean ret = FALSE;
  GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);

  ret = gst_gl_buffer_parse_caps (outcaps, &filter->width, &filter->height);

  if (filter_class->set_caps)
    filter_class->set_caps (filter, incaps, outcaps);

  if (!ret) {
    GST_DEBUG ("bad caps");
    return FALSE;
  }

  GST_DEBUG ("set_caps %d %d", filter->width, filter->height);

  return ret;
}
Exemplo n.º 8
0
static GstFlowReturn
gst_gl_filter_prepare_output_buffer (GstBaseTransform * trans,
    GstBuffer * inbuf, gint size, GstCaps * caps, GstBuffer ** buf)
{
  GstGLFilter *filter = NULL;
  GstGLBuffer *gl_inbuf = GST_GL_BUFFER (inbuf);
  GstGLBuffer *gl_outbuf = NULL;

  filter = GST_GL_FILTER (trans);

  if (filter->display == NULL) {
    GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);

    filter->display = g_object_ref (gl_inbuf->display);

    //blocking call, generate a FBO
    gst_gl_display_gen_fbo (filter->display, filter->width, filter->height,
        &filter->fbo, &filter->depthbuffer);

    if (filter_class->display_init_cb != NULL) {
      gst_gl_display_thread_add (filter->display, gst_gl_filter_start_gl,
          filter);
    }

    if (filter_class->onInitFBO)
      filter_class->onInitFBO (filter);
  }

  gl_outbuf = gst_gl_buffer_new (filter->display,
      filter->width, filter->height);

  *buf = GST_BUFFER (gl_outbuf);
  gst_buffer_set_caps (*buf, caps);

  if (gl_outbuf->texture)
    return GST_FLOW_OK;
  else
    return GST_FLOW_UNEXPECTED;
}
Exemplo n.º 9
0
static GstFlowReturn
gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf,
    GstBuffer * outbuf)
{
  GstGLFilter *filter;
  GstGLFilterClass *filter_class;

  filter = GST_GL_FILTER (bt);
  filter_class = GST_GL_FILTER_GET_CLASS (bt);

  if (!gst_gl_ensure_display (filter, &filter->display))
    return GST_FLOW_NOT_NEGOTIATED;

  g_assert (filter_class->filter || filter_class->filter_texture);

  if (filter_class->filter)
    filter_class->filter (filter, inbuf, outbuf);
  else if (filter_class->filter_texture)
    gst_gl_filter_filter_texture (filter, inbuf, outbuf);

  return GST_FLOW_OK;
}
Exemplo n.º 10
0
static void
gst_gl_filter_reset (GstGLFilter * filter)
{
  GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);

  if (filter->display) {
    if (filter_class->onReset)
      filter_class->onReset (filter);

    if (filter_class->display_reset_cb != NULL) {
      gst_gl_display_thread_add (filter->display, gst_gl_filter_stop_gl,
          filter);
    }
    //blocking call, delete the FBO
    gst_gl_display_del_fbo (filter->display, filter->fbo, filter->depthbuffer);
    g_object_unref (filter->display);
    filter->display = NULL;
  }
  filter->width = 0;
  filter->height = 0;
  filter->fbo = 0;
  filter->depthbuffer = 0;
}
Exemplo n.º 11
0
static gboolean
gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstGLFilter *filter;
  GstGLFilterClass *filter_class;

  filter = GST_GL_FILTER (bt);
  filter_class = GST_GL_FILTER_GET_CLASS (filter);

  if (!gst_video_info_from_caps (&filter->in_info, incaps))
    goto wrong_caps;
  if (!gst_video_info_from_caps (&filter->out_info, outcaps))
    goto wrong_caps;

  if (filter_class->set_caps) {
    if (!filter_class->set_caps (filter, incaps, outcaps))
      goto error;
  }

  GST_DEBUG ("set_caps %dx%d", GST_VIDEO_INFO_WIDTH (&filter->out_info),
      GST_VIDEO_INFO_HEIGHT (&filter->out_info));

  return TRUE;

/* ERRORS */
wrong_caps:
  {
    GST_WARNING ("Wrong caps");
    return FALSE;
  }
error:
  {
    return FALSE;
  }
}
Exemplo n.º 12
0
/**
 * gst_gl_filter_filter_texture:
 * @filter: a #GstGLFilter
 * @inbuf: an input buffer
 * @outbuf: an output buffer
 *
 * Perform automatic upload if needed, call filter_texture vfunc and then an
 * automatic download if needed.
 *
 * Returns: whether the transformation succeeded
 */
gboolean
gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf,
    GstBuffer * outbuf)
{
  GstGLFilterClass *filter_class;
  guint in_tex, out_tex;
  GstVideoFrame out_frame;
  gboolean ret, out_gl_mem;
  GstVideoGLTextureUploadMeta *out_tex_upload_meta;

  filter_class = GST_GL_FILTER_GET_CLASS (filter);

  if (!gst_gl_upload_perform_with_buffer (filter->upload, inbuf, &in_tex))
    return FALSE;

  if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf,
          GST_MAP_WRITE | GST_MAP_GL)) {
    ret = FALSE;
    goto inbuf_error;
  }

  out_gl_mem = gst_is_gl_memory (out_frame.map[0].memory);
  out_tex_upload_meta = gst_buffer_get_video_gl_texture_upload_meta (outbuf);

  if (out_gl_mem) {
    out_tex = *(guint *) out_frame.data[0];
  } else {
    GST_LOG ("Output Buffer does not contain correct memory, "
        "attempting to wrap for download");

    if (!filter->download) {
      filter->download = gst_gl_download_new (filter->context);

      if (!gst_gl_download_init_format (filter->download,
              GST_VIDEO_FRAME_FORMAT (&out_frame),
              GST_VIDEO_FRAME_WIDTH (&out_frame),
              GST_VIDEO_FRAME_HEIGHT (&out_frame))) {
        GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND,
            ("%s", "Failed to init download format"), (NULL));
        ret = FALSE;
        goto error;
      }
    }
    out_tex = filter->out_tex_id;
  }

  GST_DEBUG ("calling filter_texture with textures in:%i out:%i", in_tex,
      out_tex);

  g_assert (filter_class->filter_texture);
  ret = filter_class->filter_texture (filter, in_tex, out_tex);

  if (!out_gl_mem && !out_tex_upload_meta) {
    if (!gst_gl_download_perform_with_data (filter->download, out_tex,
            out_frame.data)) {
      GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND,
          ("%s", "Failed to download video frame"), (NULL));
      ret = FALSE;
      goto error;
    }
  }

error:
  gst_video_frame_unmap (&out_frame);
inbuf_error:
  gst_gl_upload_release_buffer (filter->upload);

  return ret;
}
Exemplo n.º 13
0
static gboolean
gst_gl_filter_decide_allocation (GstBaseTransform * trans, GstQuery * query)
{
  GstGLFilter *filter = GST_GL_FILTER (trans);
  GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
  GstBufferPool *pool = NULL;
  GstStructure *config;
  GstCaps *caps;
  guint min, max, size;
  gboolean update_pool;
  guint idx;
  GError *error = NULL;
  guint in_width, in_height, out_width, out_height;

  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 (!gst_gl_ensure_display (filter, &filter->display))
    return FALSE;

  if (gst_query_find_allocation_meta (query,
          GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx)) {
    GstGLContext *context;
    const GstStructure *upload_meta_params;

    gst_query_parse_nth_allocation_meta (query, idx, &upload_meta_params);
    if (gst_structure_get (upload_meta_params, "gst.gl.GstGLContext",
            GST_GL_TYPE_CONTEXT, &context, NULL) && context) {
      GstGLContext *old = filter->context;

      filter->context = context;
      if (old)
        gst_object_unref (old);
    }
  }

  if (!filter->context) {
    filter->context = gst_gl_context_new (filter->display);
    if (!gst_gl_context_create (filter->context, filter->other_context, &error))
      goto context_error;
  }

  in_width = GST_VIDEO_INFO_WIDTH (&filter->in_info);
  in_height = GST_VIDEO_INFO_HEIGHT (&filter->in_info);
  out_width = GST_VIDEO_INFO_WIDTH (&filter->out_info);
  out_height = GST_VIDEO_INFO_HEIGHT (&filter->out_info);

  if (!filter->upload) {
    filter->upload = gst_gl_upload_new (filter->context);
    gst_gl_upload_init_format (filter->upload, filter->in_info,
        filter->out_info);
  }
  //blocking call, generate a FBO
  if (!gst_gl_context_gen_fbo (filter->context, out_width, out_height,
          &filter->fbo, &filter->depthbuffer))
    goto context_error;

  gst_gl_context_gen_texture (filter->context, &filter->in_tex_id,
      GST_VIDEO_FORMAT_RGBA, in_width, in_height);

  gst_gl_context_gen_texture (filter->context, &filter->out_tex_id,
      GST_VIDEO_FORMAT_RGBA, out_width, out_height);

  if (filter_class->display_init_cb != NULL) {
    gst_gl_context_thread_add (filter->context, gst_gl_filter_start_gl, filter);
  }

  if (filter_class->onInitFBO) {
    if (!filter_class->onInitFBO (filter))
      goto error;
  }

  if (!pool)
    pool = gst_gl_buffer_pool_new (filter->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);
  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_object_unref (pool);

  return TRUE;

context_error:
  {
    GST_ELEMENT_ERROR (trans, RESOURCE, NOT_FOUND, ("%s", error->message),
        (NULL));
    return FALSE;
  }
error:
  {
    GST_ELEMENT_ERROR (trans, LIBRARY, INIT,
        ("Subclass failed to initialize."), (NULL));
    return FALSE;
  }
}