static gboolean
_upload_memory (GstGLUpload * upload)
{
    guint in_width, in_height;
    guint in_texture[GST_VIDEO_MAX_PLANES];
    GstBuffer *inbuf;
    GstVideoFrame out_frame;
    GstVideoInfo out_info;
    gint i;

    in_width = GST_VIDEO_INFO_WIDTH (&upload->in_info);
    in_height = GST_VIDEO_INFO_HEIGHT (&upload->in_info);

    if (!upload->initted) {
        if (!_init_upload (upload)) {
            return FALSE;
        }
    }

    inbuf = gst_buffer_new ();
    for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->in_info); i++) {
        in_texture[i] = upload->in_tex[i]->tex_id;
        gst_buffer_append_memory (inbuf,
                                  gst_memory_ref ((GstMemory *) upload->in_tex[i]));
    }

    GST_TRACE ("uploading with textures:%u,%u,%u dimensions:%ux%u",
               in_texture[0], in_texture[1], in_texture[2], in_width, in_height);

    upload->priv->outbuf = gst_gl_color_convert_perform (upload->convert, inbuf);
    gst_buffer_unref (inbuf);

    gst_video_info_set_format (&out_info, GST_VIDEO_FORMAT_RGBA, in_width,
                               in_height);
    if (!gst_video_frame_map (&out_frame, &out_info, upload->priv->outbuf,
                              GST_MAP_READ | GST_MAP_GL)) {
        gst_buffer_unref (upload->priv->outbuf);
        upload->priv->outbuf = NULL;
        return FALSE;
    }

    upload->out_tex->tex_id = *(guint *) out_frame.data[0];

    gst_video_frame_unmap (&out_frame);
    upload->priv->released = FALSE;

    return TRUE;
}
static gboolean
_do_download (GstGLDownload * download, guint texture_id,
    gpointer data[GST_VIDEO_MAX_PLANES])
{
  guint out_width, out_height;
  GstBuffer *inbuf, *outbuf;
  GstMapInfo map_info;
  gboolean ret = TRUE;
  gint i;

  out_width = GST_VIDEO_INFO_WIDTH (&download->info);
  out_height = GST_VIDEO_INFO_HEIGHT (&download->info);

  if (!download->initted) {
    if (!_init_download (download))
      return FALSE;
  }

  GST_TRACE ("doing download of texture:%u (%ux%u)",
      download->priv->in_tex[0]->tex_id, out_width, out_height);

  inbuf = gst_buffer_new ();
  gst_buffer_append_memory (inbuf,
      gst_memory_ref ((GstMemory *) download->priv->in_tex[0]));

  outbuf = gst_gl_color_convert_perform (download->convert, inbuf);
  if (!outbuf)
    return FALSE;

  for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&download->info); i++) {
    GstMemory *out_mem = gst_buffer_peek_memory (outbuf, i);
    gpointer temp_data = ((GstGLMemory *) out_mem)->data;
    ((GstGLMemory *) out_mem)->data = data[i];

    if (!gst_memory_map (out_mem, &map_info, GST_MAP_READ)) {
      GST_ERROR_OBJECT (download, "Failed to map memory");
      ret = FALSE;
    }
    gst_memory_unmap (out_mem, &map_info);
    ((GstGLMemory *) out_mem)->data = temp_data;
  }

  gst_buffer_unref (inbuf);
  gst_buffer_unref (outbuf);

  return ret;
}
static void
check_conversion (TestFrame * frames, guint size)
{
  gint i, j, k, l;
  gint ref_count = 0;

  for (i = 0; i < size; i++) {
    GstBuffer *inbuf;
    GstVideoInfo in_info;
    gint in_width = frames[i].width;
    gint in_height = frames[i].height;
    GstVideoFormat in_v_format = frames[i].v_format;
    gchar *in_data[GST_VIDEO_MAX_PLANES] = { 0 };
    GstGLMemory *in_mem[GST_VIDEO_MAX_PLANES] = { 0 };
    GstVideoFrame in_frame;
    GstCaps *in_caps;

    gst_video_info_set_format (&in_info, in_v_format, in_width, in_height);
    in_caps = gst_video_info_to_caps (&in_info);
    gst_caps_set_features (in_caps, 0,
        gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY));

    for (j = 0; j < GST_VIDEO_INFO_N_PLANES (&in_info); j++) {
      in_data[j] = frames[i].data[j];
    }

    /* create GL buffer */
    ref_count += GST_VIDEO_INFO_N_PLANES (&in_info);
    inbuf = gst_buffer_new ();
    fail_unless (gst_gl_memory_setup_wrapped (context, GST_GL_TEXTURE_TARGET_2D,
            &in_info, NULL, (gpointer *) in_data, in_mem, &ref_count,
            _frame_unref));

    for (j = 0; j < GST_VIDEO_INFO_N_PLANES (&in_info); j++) {
      gst_buffer_append_memory (inbuf, (GstMemory *) in_mem[j]);
    }

    fail_unless (gst_video_frame_map (&in_frame, &in_info, inbuf,
            GST_MAP_READ));

    /* sanity check that the correct values were wrapped */
    for (j = 0; j < GST_VIDEO_INFO_N_PLANES (&in_info); j++) {
      for (k = 0; k < _video_info_plane_size (&in_info, j); k++) {
        if (in_data[j][k] != IGNORE_MAGIC)
          fail_unless (((gchar *) in_frame.data[j])[k] == in_data[j][k]);
      }
    }

    for (j = 0; j < size; j++) {
      GstBuffer *outbuf;
      GstVideoInfo out_info;
      gint out_width = frames[j].width;
      gint out_height = frames[j].height;
      GstVideoFormat out_v_format = frames[j].v_format;
      gchar *out_data[GST_VIDEO_MAX_PLANES] = { 0 };
      GstVideoFrame out_frame;
      GstCaps *out_caps;

      gst_video_info_set_format (&out_info, out_v_format, out_width,
          out_height);
      out_caps = gst_video_info_to_caps (&out_info);
      gst_caps_set_features (out_caps, 0,
          gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY));

      for (k = 0; k < GST_VIDEO_INFO_N_PLANES (&out_info); k++) {
        out_data[k] = frames[j].data[k];
      }

      gst_gl_color_convert_set_caps (convert, in_caps, out_caps);

      /* convert the data */
      outbuf = gst_gl_color_convert_perform (convert, inbuf);
      if (outbuf == NULL) {
        const gchar *in_str = gst_video_format_to_string (in_v_format);
        const gchar *out_str = gst_video_format_to_string (out_v_format);
        GST_WARNING ("failed to convert from %s to %s", in_str, out_str);
      }

      fail_unless (gst_video_frame_map (&out_frame, &out_info, outbuf,
              GST_MAP_READ));

      /* check that the converted values are correct */
      for (k = 0; k < GST_VIDEO_INFO_N_PLANES (&out_info); k++) {
        for (l = 0; l < _video_info_plane_size (&out_info, k); l++) {
          gchar out_pixel = ((gchar *) out_frame.data[k])[l];
          if (out_data[k][l] != IGNORE_MAGIC && out_pixel != IGNORE_MAGIC)
            fail_unless (out_pixel == out_data[k][l]);
          /* FIXME: check alpha clobbering */
        }
      }

      gst_caps_unref (out_caps);
      gst_video_frame_unmap (&out_frame);
      gst_buffer_unref (outbuf);
    }

    gst_caps_unref (in_caps);
    gst_video_frame_unmap (&in_frame);
    gst_buffer_unref (inbuf);

    fail_unless_equals_int (ref_count, 0);
  }
}
static GstFlowReturn
stereosplit_chain (GstPad * pad, GstGLStereoSplit * split, GstBuffer * buf)
{
  GstBuffer *uploaded_buffer, *converted_buffer, *left, *right;
  GstBuffer *split_buffer = NULL;
  GstFlowReturn ret;
  gint i, n_planes;

  if (!split->upload)
    _init_upload (split);

  n_planes = GST_VIDEO_INFO_N_PLANES (&split->viewconvert->out_info);

  GST_LOG_OBJECT (split, "chaining buffer %" GST_PTR_FORMAT, buf);

  if (GST_GL_UPLOAD_DONE != gst_gl_upload_perform_with_buffer (split->upload,
          buf, &uploaded_buffer)) {
    gst_buffer_unref (buf);
    GST_ELEMENT_ERROR (split, RESOURCE, NOT_FOUND, ("%s",
            "Failed to upload buffer"), (NULL));
    return GST_FLOW_ERROR;
  }
  gst_buffer_unref (buf);

  if (!(converted_buffer =
          gst_gl_color_convert_perform (split->convert, uploaded_buffer))) {
    GST_ELEMENT_ERROR (split, RESOURCE, NOT_FOUND, ("%s",
            "Failed to convert buffer"), (NULL));
    gst_buffer_unref (uploaded_buffer);
    return GST_FLOW_ERROR;
  }
  gst_buffer_unref (uploaded_buffer);

  if (gst_gl_view_convert_submit_input_buffer (split->viewconvert,
          GST_BUFFER_IS_DISCONT (converted_buffer),
          converted_buffer) != GST_FLOW_OK) {
    GST_ELEMENT_ERROR (split, RESOURCE, NOT_FOUND, ("%s",
            "Failed to 3d convert buffer"),
        ("Could not get submit input buffer"));
    return GST_FLOW_ERROR;
  }

  ret = gst_gl_view_convert_get_output (split->viewconvert, &split_buffer);
  if (ret != GST_FLOW_OK) {
    GST_ELEMENT_ERROR (split, RESOURCE, NOT_FOUND, ("%s",
            "Failed to 3d convert buffer"), ("Could not get output buffer"));
    return GST_FLOW_ERROR;
  }
  if (split_buffer == NULL)
    return GST_FLOW_OK;         /* Need another input buffer */

  left = gst_buffer_new ();
  gst_buffer_copy_into (left, buf,
      GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
  GST_BUFFER_FLAG_UNSET (left, GST_VIDEO_BUFFER_FLAG_FIRST_IN_BUNDLE);

  gst_buffer_add_parent_buffer_meta (left, split_buffer);

  for (i = 0; i < n_planes; i++) {
    GstMemory *mem = gst_buffer_get_memory (split_buffer, i);
    gst_buffer_append_memory (left, mem);
  }

  ret = gst_pad_push (split->left_pad, gst_buffer_ref (left));
  /* Allow unlinked on the first pad - as long as the 2nd isn't unlinked */
  gst_buffer_unref (left);
  if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_LINKED)) {
    gst_buffer_unref (split_buffer);
    return ret;
  }

  right = gst_buffer_new ();
  gst_buffer_copy_into (right, buf,
      GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
  GST_BUFFER_FLAG_UNSET (left, GST_VIDEO_BUFFER_FLAG_FIRST_IN_BUNDLE);
  gst_buffer_add_parent_buffer_meta (right, split_buffer);
  for (i = n_planes; i < n_planes * 2; i++) {
    GstMemory *mem = gst_buffer_get_memory (split_buffer, i);
    gst_buffer_append_memory (right, mem);
  }

  ret = gst_pad_push (split->right_pad, gst_buffer_ref (right));
  gst_buffer_unref (right);
  gst_buffer_unref (split_buffer);
  return ret;
}
static void
check_conversion (TestFrame * frames, guint size)
{
  GstGLBaseMemoryAllocator *base_mem_alloc;
  gint i, j, k, l;
  gint ref_count = 0;

  base_mem_alloc =
      GST_GL_BASE_MEMORY_ALLOCATOR (gst_allocator_find
      (GST_GL_MEMORY_ALLOCATOR_NAME));

  for (i = 0; i < size; i++) {
    GstBuffer *inbuf;
    GstVideoInfo in_info;
    gint in_width = frames[i].width;
    gint in_height = frames[i].height;
    GstVideoFormat in_v_format = frames[i].v_format;
    GstVideoFrame in_frame;
    GstCaps *in_caps;

    gst_video_info_set_format (&in_info, in_v_format, in_width, in_height);
    in_caps = gst_video_info_to_caps (&in_info);
    gst_caps_set_features (in_caps, 0,
        gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY));

    /* create GL buffer */
    inbuf = gst_buffer_new ();
    for (j = 0; j < GST_VIDEO_INFO_N_PLANES (&in_info); j++) {
      GstVideoGLTextureType tex_type = gst_gl_texture_type_from_format (context,
          GST_VIDEO_INFO_FORMAT (&in_info), j);
      GstGLVideoAllocationParams *params;
      GstGLBaseMemory *mem;

      ref_count++;
      params = gst_gl_video_allocation_params_new_wrapped_data (context, NULL,
          &in_info, j, NULL, GST_GL_TEXTURE_TARGET_2D, tex_type,
          frames[i].data[j], &ref_count, _frame_unref);

      mem = gst_gl_base_memory_alloc (base_mem_alloc,
          (GstGLAllocationParams *) params);
      gst_buffer_append_memory (inbuf, GST_MEMORY_CAST (mem));

      gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
    }

    fail_unless (gst_video_frame_map (&in_frame, &in_info, inbuf,
            GST_MAP_READ));

    /* sanity check that the correct values were wrapped */
    for (j = 0; j < GST_VIDEO_INFO_N_PLANES (&in_info); j++) {
      for (k = 0; k < _video_info_plane_size (&in_info, j); k++) {
        if (frames[i].data[j][k] != IGNORE_MAGIC)
          fail_unless (((gchar *) in_frame.data[j])[k] == frames[i].data[j][k]);
      }
    }

    for (j = 0; j < size; j++) {
      GstBuffer *outbuf;
      GstVideoInfo out_info;
      gint out_width = frames[j].width;
      gint out_height = frames[j].height;
      GstVideoFormat out_v_format = frames[j].v_format;
      gchar *out_data[GST_VIDEO_MAX_PLANES] = { 0 };
      GstVideoFrame out_frame;
      GstCaps *out_caps;

      gst_video_info_set_format (&out_info, out_v_format, out_width,
          out_height);
      out_caps = gst_video_info_to_caps (&out_info);
      gst_caps_set_features (out_caps, 0,
          gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY));

      for (k = 0; k < GST_VIDEO_INFO_N_PLANES (&out_info); k++) {
        out_data[k] = frames[j].data[k];
      }

      gst_gl_color_convert_set_caps (convert, in_caps, out_caps);

      /* convert the data */
      outbuf = gst_gl_color_convert_perform (convert, inbuf);
      if (outbuf == NULL) {
        const gchar *in_str = gst_video_format_to_string (in_v_format);
        const gchar *out_str = gst_video_format_to_string (out_v_format);
        GST_WARNING ("failed to convert from %s to %s", in_str, out_str);
      }

      fail_unless (gst_video_frame_map (&out_frame, &out_info, outbuf,
              GST_MAP_READ));

      /* check that the converted values are correct */
      for (k = 0; k < GST_VIDEO_INFO_N_PLANES (&out_info); k++) {
        for (l = 0; l < _video_info_plane_size (&out_info, k); l++) {
          gchar out_pixel = ((gchar *) out_frame.data[k])[l];
          if (out_data[k][l] != IGNORE_MAGIC && out_pixel != IGNORE_MAGIC)
            fail_unless (out_pixel == out_data[k][l]);
          /* FIXME: check alpha clobbering */
        }
      }

      gst_caps_unref (out_caps);
      gst_video_frame_unmap (&out_frame);
      gst_buffer_unref (outbuf);
    }

    gst_caps_unref (in_caps);
    gst_video_frame_unmap (&in_frame);
    gst_buffer_unref (inbuf);

    fail_unless_equals_int (ref_count, 0);
  }

  gst_object_unref (base_mem_alloc);
}
Beispiel #6
-1
static GstBuffer *
_default_pad_upload_buffer (GstGLMixer * mix, GstGLMixerFrameData * frame,
                            GstBuffer * buffer)
{
    GstVideoAggregatorPad *vaggpad = GST_VIDEO_AGGREGATOR_PAD (frame->pad);
    GstGLMixerPad *pad = frame->pad;
    GstBuffer *uploaded_buf, *gl_buffer;
    GstCaps *gl_caps;
    GstCapsFeatures *gl_features;
    GstVideoInfo gl_info;
    GstVideoFrame gl_frame;
    GstGLSyncMeta *sync_meta;

    gst_video_info_set_format (&gl_info,
                               GST_VIDEO_FORMAT_RGBA,
                               GST_VIDEO_INFO_WIDTH (&vaggpad->info),
                               GST_VIDEO_INFO_HEIGHT (&vaggpad->info));
    gl_features =
        gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);

    gl_caps = gst_video_info_to_caps (&gl_info);
    gst_caps_set_features (gl_caps, 0, gst_caps_features_copy (gl_features));

    if (!pad->upload) {
        GstCaps *in_caps = gst_pad_get_current_caps (GST_PAD (pad));
        GstCaps *upload_caps = gst_caps_copy (in_caps);

        pad->upload = gst_gl_upload_new (mix->context);

        gst_caps_set_features (upload_caps, 0,
                               gst_caps_features_copy (gl_features));
        gst_gl_upload_set_caps (pad->upload, in_caps, upload_caps);

        if (!pad->convert) {
            pad->convert = gst_gl_color_convert_new (mix->context);

            gst_gl_color_convert_set_caps (pad->convert, upload_caps, gl_caps);
        }

        gst_caps_unref (upload_caps);
        gst_caps_unref (in_caps);
    }

    gst_caps_features_free (gl_features);
    gst_caps_unref (gl_caps);

    sync_meta = gst_buffer_get_gl_sync_meta (vaggpad->buffer);
    if (sync_meta)
        gst_gl_sync_meta_wait (sync_meta);

    if (gst_gl_upload_perform_with_buffer (pad->upload,
                                           vaggpad->buffer, &uploaded_buf) != GST_GL_UPLOAD_DONE) {
        return NULL;
    }

    if (!(gl_buffer = gst_gl_color_convert_perform (pad->convert, uploaded_buf))) {
        gst_buffer_unref (uploaded_buf);
        return NULL;
    }

    if (!gst_video_frame_map (&gl_frame, &gl_info, gl_buffer,
                              GST_MAP_READ | GST_MAP_GL)) {
        gst_buffer_unref (uploaded_buf);
        gst_buffer_unref (gl_buffer);
        return NULL;
    }

    frame->texture = *(guint *) gl_frame.data[0];

    gst_buffer_unref (uploaded_buf);
    gst_video_frame_unmap (&gl_frame);

    return gl_buffer;
}