コード例 #1
0
ファイル: gstglmixer.c プロジェクト: asdlei00/gst-plugins-bad
gboolean
gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
{
  guint i;
  GList *walk;
  guint out_tex;
  gboolean res = TRUE;
  guint array_index = 0;
  GstVideoFrame out_frame;
  gboolean out_gl_wrapped = FALSE;
  GstElement *element = GST_ELEMENT (mix);
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix);
  GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix);
  GstGLMixerPrivate *priv = mix->priv;

  GST_TRACE ("Processing buffers");

  if (!gst_video_frame_map (&out_frame, &vagg->info, outbuf,
          GST_MAP_WRITE | GST_MAP_GL)) {
    return FALSE;
  }

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

    out_tex = mix->out_tex_id;;

    if (!mix->download)
      mix->download = gst_gl_download_new (mix->context);

    gst_gl_download_set_format (mix->download, &out_frame.info);
    out_gl_wrapped = TRUE;
  }

  GST_OBJECT_LOCK (mix);
  walk = element->sinkpads;

  i = mix->frames->len;
  g_ptr_array_set_size (mix->frames, element->numsinkpads);
  for (; i < element->numsinkpads; i++)
    mix->frames->pdata[i] = g_slice_new0 (GstGLMixerFrameData);
  while (walk) {
    GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
    GstVideoAggregatorPad *vaggpad = walk->data;
    GstGLMixerFrameData *frame;

    frame = g_ptr_array_index (mix->frames, array_index);
    frame->pad = pad;
    frame->texture = 0;

    walk = g_list_next (walk);

    if (vaggpad->buffer != NULL) {
      guint in_tex;

      if (!pad->upload) {
        pad->upload = gst_gl_upload_new (mix->context);

        gst_gl_upload_set_format (pad->upload, &vaggpad->info);
      }

      if (!gst_gl_upload_perform_with_buffer (pad->upload,
              vaggpad->buffer, &in_tex)) {
        ++array_index;
        pad->mapped = FALSE;
        continue;
      }
      pad->mapped = TRUE;

      frame->texture = in_tex;
    }
    ++array_index;
  }

  g_mutex_lock (&priv->gl_resource_lock);
  if (!priv->gl_resource_ready)
    g_cond_wait (&priv->gl_resource_cond, &priv->gl_resource_lock);

  if (!priv->gl_resource_ready) {
    g_mutex_unlock (&priv->gl_resource_lock);
    GST_ERROR_OBJECT (mix,
        "fbo used to render can't be created, do not run process_textures");
    res = FALSE;
    goto out;
  }

  mix_class->process_textures (mix, mix->frames, out_tex);

  g_mutex_unlock (&priv->gl_resource_lock);

  if (out_gl_wrapped) {
    if (!gst_gl_download_perform_with_data (mix->download, out_tex,
            out_frame.data)) {
      GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s",
              "Failed to download video frame"), (NULL));
      res = FALSE;
      goto out;
    }
  }

out:
  i = 0;
  walk = GST_ELEMENT (mix)->sinkpads;
  while (walk) {
    GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);

    if (pad->mapped)
      gst_gl_upload_release_buffer (pad->upload);

    pad->mapped = FALSE;
    walk = g_list_next (walk);
    i++;
  }
  GST_OBJECT_UNLOCK (mix);

  gst_video_frame_unmap (&out_frame);

  return res;
}
コード例 #2
0
ファイル: gstglmixer.c プロジェクト: ego5710/gst-plugins-bad
gboolean
gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
{
    guint i;
    GList *walk;
    guint out_tex, out_tex_target;
    gboolean res = TRUE;
    guint array_index = 0;
    GstVideoFrame out_frame;
    GstElement *element = GST_ELEMENT (mix);
    GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix);
    GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix);
    GstGLMixerPrivate *priv = mix->priv;
    gboolean to_download =
        gst_caps_features_is_equal (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY,
                                    gst_caps_get_features (mix->out_caps, 0));
    GstMapFlags out_map_flags = GST_MAP_WRITE;

    GST_TRACE ("Processing buffers");

    to_download |= !gst_is_gl_memory (gst_buffer_peek_memory (outbuf, 0));

    if (!to_download)
        out_map_flags |= GST_MAP_GL;

    if (!gst_video_frame_map (&out_frame, &vagg->info, outbuf, out_map_flags)) {
        return FALSE;
    }

    if (!to_download) {
        out_tex = *(guint *) out_frame.data[0];
        out_tex_target =
            ((GstGLMemory *) gst_buffer_peek_memory (outbuf, 0))->tex_target;
    } else {
        GST_INFO ("Output Buffer does not contain correct memory, "
                  "attempting to wrap for download");

        if (!mix->download)
            mix->download = gst_gl_download_new (mix->context);

        gst_gl_download_set_format (mix->download, &out_frame.info);
        out_tex = mix->out_tex_id;
        out_tex_target = GL_TEXTURE_2D;
    }

    GST_OBJECT_LOCK (mix);
    walk = element->sinkpads;

    i = mix->frames->len;
    g_ptr_array_set_size (mix->frames, element->numsinkpads);
    for (; i < element->numsinkpads; i++)
        mix->frames->pdata[i] = g_slice_new0 (GstGLMixerFrameData);
    while (walk) {
        GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
        GstGLMixerPadClass *pad_class = GST_GL_MIXER_PAD_GET_CLASS (pad);
        GstVideoAggregatorPad *vaggpad = walk->data;
        GstGLMixerFrameData *frame;

        frame = g_ptr_array_index (mix->frames, array_index);
        frame->pad = pad;
        frame->texture = 0;

        walk = g_list_next (walk);

        if (vaggpad->buffer != NULL) {
            g_assert (pad_class->upload_buffer);

            if (pad->gl_buffer)
                gst_buffer_unref (pad->gl_buffer);
            pad->gl_buffer = pad_class->upload_buffer (mix, frame, vaggpad->buffer);

            GST_DEBUG_OBJECT (pad,
                              "uploaded buffer %" GST_PTR_FORMAT " from buffer %" GST_PTR_FORMAT,
                              pad->gl_buffer, vaggpad->buffer);
        }

        ++array_index;
    }

    g_mutex_lock (&priv->gl_resource_lock);
    if (!priv->gl_resource_ready)
        g_cond_wait (&priv->gl_resource_cond, &priv->gl_resource_lock);

    if (!priv->gl_resource_ready) {
        g_mutex_unlock (&priv->gl_resource_lock);
        GST_ERROR_OBJECT (mix,
                          "fbo used to render can't be created, do not run process_textures");
        res = FALSE;
        goto out;
    }

    mix_class->process_textures (mix, mix->frames, out_tex);

    g_mutex_unlock (&priv->gl_resource_lock);

    if (to_download) {
        if (!gst_gl_download_perform_with_data (mix->download,
                                                out_tex, out_tex_target, out_frame.data)) {
            GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s",
                               "Failed to download video frame"), (NULL));
            res = FALSE;
            goto out;
        }
    }

out:
    i = 0;
    walk = GST_ELEMENT (mix)->sinkpads;
    while (walk) {
        GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);

        if (pad->upload)
            gst_gl_upload_release_buffer (pad->upload);

        walk = g_list_next (walk);
        i++;
    }
    GST_OBJECT_UNLOCK (mix);

    gst_video_frame_unmap (&out_frame);

    return res;
}