/*
 * GStreamer
 * Copyright (C) 2016 Matthew Waters <matthew@centricular.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-vulkanupload
 *
 * vulkanupload uploads data into Vulkan memory objects.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <string.h>

#include "vkupload.h"

GST_DEBUG_CATEGORY (gst_debug_vulkan_upload);
#define GST_CAT_DEFAULT gst_debug_vulkan_upload

static GstCaps *
_set_caps_features_with_passthrough (const GstCaps * caps,
    const gchar * feature_name, GstCapsFeatures * passthrough)
{
  guint i, j, m, n;
  GstCaps *tmp;

  tmp = gst_caps_copy (caps);

  n = gst_caps_get_size (caps);
  for (i = 0; i < n; i++) {
    GstCapsFeatures *features, *orig_features;

    orig_features = gst_caps_get_features (caps, i);
    features = gst_caps_features_new (feature_name, NULL);

    m = gst_caps_features_get_size (orig_features);
    for (j = 0; j < m; j++) {
      const gchar *feature = gst_caps_features_get_nth (orig_features, j);

      /* if we already have the features */
      if (gst_caps_features_contains (features, feature))
        continue;

      if (g_strcmp0 (feature, GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY) == 0)
        continue;

      if (passthrough && gst_caps_features_contains (passthrough, feature)) {
        gst_caps_features_add (features, feature);
      }
    }

    gst_caps_set_features (tmp, i, features);
  }

  return tmp;
}

struct BufferUpload
{
  GstVulkanUpload *upload;
};

static gpointer
_buffer_new_impl (GstVulkanUpload * upload)
{
  struct BufferUpload *raw = g_new0 (struct BufferUpload, 1);

  raw->upload = upload;

  return raw;
}

static GstCaps *
_buffer_transform_caps (gpointer impl, GstPadDirection direction,
    GstCaps * caps)
{
  return gst_caps_ref (caps);
}

static gboolean
_buffer_set_caps (gpointer impl, GstCaps * in_caps, GstCaps * out_caps)
{
  return TRUE;
}

static void
_buffer_propose_allocation (gpointer impl, GstQuery * decide_query,
    GstQuery * query)
{
  struct BufferUpload *raw = impl;
  gboolean need_pool;
  GstCaps *caps;
  guint size;

  gst_query_parse_allocation (query, &caps, &need_pool);

  if (caps == NULL)
    return;

  if (need_pool) {
    GstBufferPool *pool;
    GstStructure *config;
    GstVideoInfo info;

    if (!gst_video_info_from_caps (&info, caps))
      return;

    /* the normal size of a frame */
    size = info.size;

    pool = gst_vulkan_buffer_pool_new (raw->upload->device);

    config = gst_buffer_pool_get_config (pool);
    gst_buffer_pool_config_set_params (config, caps, size, 0, 0);

    if (!gst_buffer_pool_set_config (pool, config)) {
      g_object_unref (pool);
      return;
    }

    gst_query_add_allocation_pool (query, pool, size, 1, 0);
    g_object_unref (pool);
  }

  return;
}

static GstFlowReturn
_buffer_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
{
  if (!gst_is_vulkan_buffer_memory (gst_buffer_peek_memory (inbuf, 0)))
    return GST_FLOW_ERROR;

  *outbuf = inbuf;

  return GST_FLOW_OK;
}

static void
_buffer_free (gpointer impl)
{
  g_free (impl);
}

static GstStaticCaps _buffer_in_templ =
    GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_VULKAN_BUFFER ") ;"
    "video/x-raw");
static GstStaticCaps _buffer_out_templ =
GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_VULKAN_BUFFER ")");

static const struct UploadMethod buffer_upload = {
  "VulkanBuffer",
  &_buffer_in_templ,
  &_buffer_out_templ,
  _buffer_new_impl,
  _buffer_transform_caps,
  _buffer_set_caps,
  _buffer_propose_allocation,
  _buffer_perform,
  _buffer_free,
};

struct RawToBufferUpload
{
  GstVulkanUpload *upload;

  GstVideoInfo in_info;
  GstVideoInfo out_info;

  GstBufferPool *pool;
  gboolean pool_active;

  gsize alloc_sizes[GST_VIDEO_MAX_PLANES];
};

static gpointer
_raw_to_buffer_new_impl (GstVulkanUpload * upload)
{
  struct RawToBufferUpload *raw = g_new0 (struct RawToBufferUpload, 1);

  raw->upload = upload;

  return raw;
}

static GstCaps *
_raw_to_buffer_transform_caps (gpointer impl, GstPadDirection direction,
    GstCaps * caps)
{
  GstCaps *ret;

  if (direction == GST_PAD_SINK) {
    ret =
        _set_caps_features_with_passthrough (caps,
        GST_CAPS_FEATURE_MEMORY_VULKAN_BUFFER, NULL);
  } else {
    ret =
        _set_caps_features_with_passthrough (caps,
        GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY, NULL);
  }

  return ret;
}

static gboolean
_raw_to_buffer_set_caps (gpointer impl, GstCaps * in_caps, GstCaps * out_caps)
{
  struct RawToBufferUpload *raw = impl;
  guint out_width, out_height;
  guint i;

  if (!gst_video_info_from_caps (&raw->in_info, in_caps))
    return FALSE;

  if (!gst_video_info_from_caps (&raw->out_info, out_caps))
    return FALSE;

  out_width = GST_VIDEO_INFO_WIDTH (&raw->out_info);
  out_height = GST_VIDEO_INFO_HEIGHT (&raw->out_info);

  for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&raw->out_info); i++) {
    GstVideoFormat v_format = GST_VIDEO_INFO_FORMAT (&raw->out_info);
    GstVulkanImageMemory *img_mem;
    VkFormat vk_format;

    vk_format = gst_vulkan_format_from_video_format (v_format, i);

    img_mem = (GstVulkanImageMemory *)
        gst_vulkan_image_memory_alloc (raw->upload->device, vk_format,
        out_width, out_height, VK_IMAGE_TILING_OPTIMAL,
        VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
        VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

    raw->alloc_sizes[i] = img_mem->requirements.size;

    gst_memory_unref (GST_MEMORY_CAST (img_mem));
  }

  return TRUE;
}

static void
_raw_to_buffer_propose_allocation (gpointer impl, GstQuery * decide_query,
    GstQuery * query)
{
  /* a little trickery with the impl pointer */
  _buffer_propose_allocation (impl, decide_query, query);
}

static GstFlowReturn
_raw_to_buffer_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
{
  struct RawToBufferUpload *raw = impl;
  GstVideoFrame v_frame;
  GstFlowReturn ret;
  guint i;

  if (!raw->pool) {
    GstStructure *config;
    guint min = 0, max = 0;
    gsize size = 1;

    raw->pool = gst_vulkan_buffer_pool_new (raw->upload->device);
    config = gst_buffer_pool_get_config (raw->pool);
    gst_buffer_pool_config_set_params (config, raw->upload->out_caps, size, min,
        max);
    gst_buffer_pool_set_config (raw->pool, config);
  }
  if (!raw->pool_active) {
    gst_buffer_pool_set_active (raw->pool, TRUE);
    raw->pool_active = TRUE;
  }

  if ((ret =
          gst_buffer_pool_acquire_buffer (raw->pool, outbuf,
              NULL)) != GST_FLOW_OK)
    goto out;

  if (!gst_video_frame_map (&v_frame, &raw->in_info, inbuf, GST_MAP_READ)) {
    GST_ELEMENT_ERROR (raw->upload, RESOURCE, NOT_FOUND,
        ("%s", "Failed to map input buffer"), NULL);
    return GST_FLOW_ERROR;
  }

  for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&raw->out_info); i++) {
    GstMapInfo map_info;
    gsize plane_size;
    GstMemory *mem;

    mem = gst_buffer_peek_memory (*outbuf, i);
    if (!gst_memory_map (GST_MEMORY_CAST (mem), &map_info, GST_MAP_WRITE)) {
      GST_ELEMENT_ERROR (raw->upload, RESOURCE, NOT_FOUND,
          ("%s", "Failed to map output memory"), NULL);
      gst_buffer_unref (*outbuf);
      *outbuf = NULL;
      ret = GST_FLOW_ERROR;
      goto out;
    }

    plane_size =
        GST_VIDEO_INFO_PLANE_STRIDE (&raw->out_info,
        i) * GST_VIDEO_INFO_COMP_HEIGHT (&raw->out_info, i);
    g_assert (plane_size < map_info.size);
    memcpy (map_info.data, v_frame.data[i], plane_size);

    gst_memory_unmap (GST_MEMORY_CAST (mem), &map_info);
  }

  gst_video_frame_unmap (&v_frame);

  ret = GST_FLOW_OK;

out:
  return ret;
}

static void
_raw_to_buffer_free (gpointer impl)
{
  struct RawToBufferUpload *raw = impl;

  if (raw->pool) {
    if (raw->pool_active) {
      gst_buffer_pool_set_active (raw->pool, FALSE);
    }
    raw->pool_active = FALSE;
    gst_object_unref (raw->pool);
    raw->pool = NULL;
  }

  g_free (impl);
}

static GstStaticCaps _raw_to_buffer_in_templ = GST_STATIC_CAPS ("video/x-raw");
static GstStaticCaps _raw_to_buffer_out_templ =
GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_VULKAN_BUFFER ")");

static const struct UploadMethod raw_to_buffer_upload = {
  "RawToVulkanBuffer",
  &_raw_to_buffer_in_templ,
  &_raw_to_buffer_out_templ,
  _raw_to_buffer_new_impl,
  _raw_to_buffer_transform_caps,
  _raw_to_buffer_set_caps,
  _raw_to_buffer_propose_allocation,
  _raw_to_buffer_perform,
  _raw_to_buffer_free,
};

static const struct UploadMethod *upload_methods[] = {
  &buffer_upload,
  &raw_to_buffer_upload,
};

static GstCaps *
_get_input_template_caps (void)
{
  GstCaps *ret = NULL;
  gint i;

  /* FIXME: cache this and invalidate on changes to upload_methods */
  for (i = 0; i < G_N_ELEMENTS (upload_methods); i++) {
    GstCaps *template = gst_static_caps_get (upload_methods[i]->in_template);
    ret = ret == NULL ? template : gst_caps_merge (ret, template);
  }

  ret = gst_caps_simplify (ret);

  return ret;
}

static GstCaps *
_get_output_template_caps (void)
{
  GstCaps *ret = NULL;
  gint i;

  /* FIXME: cache this and invalidate on changes to upload_methods */
  for (i = 0; i < G_N_ELEMENTS (upload_methods); i++) {
    GstCaps *template = gst_static_caps_get (upload_methods[i]->out_template);
    ret = ret == NULL ? template : gst_caps_merge (ret, template);
  }

  ret = gst_caps_simplify (ret);

  return ret;
}

static void gst_vulkan_upload_finalize (GObject * object);
static void gst_vulkan_upload_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * param_spec);
static void gst_vulkan_upload_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * param_spec);

static gboolean gst_vulkan_upload_query (GstBaseTransform * bt,
    GstPadDirection direction, GstQuery * query);
static void gst_vulkan_upload_set_context (GstElement * element,
    GstContext * context);
static GstStateChangeReturn gst_vulkan_upload_change_state (GstElement *
    element, GstStateChange transition);

static gboolean gst_vulkan_upload_set_caps (GstBaseTransform * bt,
    GstCaps * in_caps, GstCaps * out_caps);
static GstCaps *gst_vulkan_upload_transform_caps (GstBaseTransform * bt,
    GstPadDirection direction, GstCaps * caps, GstCaps * filter);
static gboolean gst_vulkan_upload_propose_allocation (GstBaseTransform * bt,
    GstQuery * decide_query, GstQuery * query);
static gboolean gst_vulkan_upload_decide_allocation (GstBaseTransform * bt,
    GstQuery * query);
static GstFlowReturn gst_vulkan_upload_transform (GstBaseTransform * bt,
    GstBuffer * inbuf, GstBuffer * outbuf);
static GstFlowReturn gst_vulkan_upload_prepare_output_buffer (GstBaseTransform *
    bt, GstBuffer * inbuf, GstBuffer ** outbuf);

enum
{
  PROP_0,
};

enum
{
  SIGNAL_0,
  LAST_SIGNAL
};

/* static guint gst_vulkan_upload_signals[LAST_SIGNAL] = { 0 }; */

#define gst_vulkan_upload_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstVulkanUpload, gst_vulkan_upload,
    GST_TYPE_BASE_TRANSFORM, GST_DEBUG_CATEGORY_INIT (gst_debug_vulkan_upload,
        "vulkanupload", 0, "Vulkan Uploader"));

static void
gst_vulkan_upload_class_init (GstVulkanUploadClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseTransformClass *gstbasetransform_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstbasetransform_class = (GstBaseTransformClass *) klass;

  gobject_class->set_property = gst_vulkan_upload_set_property;
  gobject_class->get_property = gst_vulkan_upload_get_property;

  gst_element_class_set_metadata (gstelement_class, "Vulkan Uploader",
      "Filter/Video", "A Vulkan data uploader",
      "Matthew Waters <matthew@centricular.com>");

  {
    GstCaps *caps;

    caps = _get_input_template_caps ();
    gst_element_class_add_pad_template (gstelement_class,
        gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps));
    gst_caps_unref (caps);

    caps = _get_output_template_caps ();
    gst_element_class_add_pad_template (gstelement_class,
        gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps));
    gst_caps_unref (caps);
  }

  gobject_class->finalize = gst_vulkan_upload_finalize;

  gstelement_class->change_state = gst_vulkan_upload_change_state;
  gstelement_class->set_context = gst_vulkan_upload_set_context;
  gstbasetransform_class->query = GST_DEBUG_FUNCPTR (gst_vulkan_upload_query);
  gstbasetransform_class->set_caps = gst_vulkan_upload_set_caps;
  gstbasetransform_class->transform_caps = gst_vulkan_upload_transform_caps;
  gstbasetransform_class->propose_allocation =
      gst_vulkan_upload_propose_allocation;
  gstbasetransform_class->decide_allocation =
      gst_vulkan_upload_decide_allocation;
  gstbasetransform_class->transform = gst_vulkan_upload_transform;
  gstbasetransform_class->prepare_output_buffer =
      gst_vulkan_upload_prepare_output_buffer;
}

static void
gst_vulkan_upload_init (GstVulkanUpload * vk_upload)
{
  guint i, n;

  n = G_N_ELEMENTS (upload_methods);
  vk_upload->upload_impls = g_malloc (sizeof (gpointer) * n);
  for (i = 0; i < n; i++) {
    vk_upload->upload_impls[i] = upload_methods[i]->new_impl (vk_upload);
  }
}

static void
gst_vulkan_upload_finalize (GObject * object)
{
  GstVulkanUpload *vk_upload = GST_VULKAN_UPLOAD (object);
  guint i;

  gst_caps_replace (&vk_upload->in_caps, NULL);
  gst_caps_replace (&vk_upload->out_caps, NULL);

  for (i = 0; i < G_N_ELEMENTS (upload_methods); i++) {
    upload_methods[i]->free (vk_upload->upload_impls[i]);
  }

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_vulkan_upload_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
//  GstVulkanUpload *vk_upload = GST_VULKAN_UPLOAD (object);

  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_vulkan_upload_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
//  GstVulkanUpload *vk_upload = GST_VULKAN_UPLOAD (object);

  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_vulkan_upload_query (GstBaseTransform * bt, GstPadDirection direction,
    GstQuery * query)
{
  GstVulkanUpload *vk_upload = GST_VULKAN_UPLOAD (bt);
  gboolean res = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CONTEXT:{
      res = gst_vulkan_handle_context_query (GST_ELEMENT (vk_upload), query,
          &vk_upload->display, &vk_upload->instance, &vk_upload->device);

      if (res)
        return res;
      break;
    }
    default:
      break;
  }

  return GST_BASE_TRANSFORM_CLASS (parent_class)->query (bt, direction, query);
}

static void
gst_vulkan_upload_set_context (GstElement * element, GstContext * context)
{
  GstVulkanUpload *vk_upload = GST_VULKAN_UPLOAD (element);

  gst_vulkan_handle_set_context (element, context, &vk_upload->display,
      &vk_upload->instance);

  GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}

static GstStateChangeReturn
gst_vulkan_upload_change_state (GstElement * element, GstStateChange transition)
{
  GstVulkanUpload *vk_upload = GST_VULKAN_UPLOAD (element);
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

  GST_DEBUG ("changing state: %s => %s",
      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      if (!gst_vulkan_ensure_element_data (element, &vk_upload->display,
              &vk_upload->instance)) {
        GST_ELEMENT_ERROR (vk_upload, RESOURCE, NOT_FOUND,
            ("Failed to retreive vulkan instance/display"), (NULL));
        return GST_STATE_CHANGE_FAILURE;
      }
      if (!gst_vulkan_device_run_context_query (GST_ELEMENT (vk_upload),
              &vk_upload->device)) {
        GST_ELEMENT_ERROR (vk_upload, RESOURCE, NOT_FOUND,
            ("Failed to retreive vulkan device"), (NULL));
        return GST_STATE_CHANGE_FAILURE;
      }
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      if (vk_upload->display)
        gst_object_unref (vk_upload->display);
      vk_upload->display = NULL;
      if (vk_upload->device)
        gst_object_unref (vk_upload->device);
      vk_upload->device = NULL;
      if (vk_upload->instance)
        gst_object_unref (vk_upload->instance);
      vk_upload->instance = NULL;
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;
}

static GstCaps *
gst_vulkan_upload_transform_caps (GstBaseTransform * bt,
    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
  GstVulkanUpload *vk_upload = GST_VULKAN_UPLOAD (bt);
  GstCaps *result, *tmp;
  gint i;

  tmp = gst_caps_new_empty ();

  for (i = 0; i < G_N_ELEMENTS (upload_methods); i++) {
    GstCaps *tmp2;
    GstCaps *templ;

    if (direction == GST_PAD_SINK) {
      templ = gst_static_caps_get (upload_methods[i]->in_template);
    } else {
      templ = gst_static_caps_get (upload_methods[i]->out_template);
    }
    if (!gst_caps_can_intersect (caps, templ)) {
      gst_caps_unref (templ);
      continue;
    }
    gst_caps_unref (templ);

    tmp2 = upload_methods[i]->transform_caps (vk_upload->upload_impls[i],
        direction, caps);

    if (tmp2)
      tmp = gst_caps_merge (tmp, tmp2);
  }

  if (filter) {
    result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (tmp);
  } else {
    result = tmp;
  }

  return result;
}

static gboolean
gst_vulkan_upload_set_caps (GstBaseTransform * bt, GstCaps * in_caps,
    GstCaps * out_caps)
{
  GstVulkanUpload *vk_upload = GST_VULKAN_UPLOAD (bt);
  gboolean found_method = FALSE;
  guint i;

  gst_caps_replace (&vk_upload->in_caps, in_caps);
  gst_caps_replace (&vk_upload->out_caps, out_caps);

  for (i = 0; i < G_N_ELEMENTS (upload_methods); i++) {
    GstCaps *templ;

    templ = gst_static_caps_get (upload_methods[i]->in_template);
    if (!gst_caps_can_intersect (in_caps, templ)) {
      gst_caps_unref (templ);
      continue;
    }
    gst_caps_unref (templ);

    templ = gst_static_caps_get (upload_methods[i]->out_template);
    if (!gst_caps_can_intersect (out_caps, templ)) {
      gst_caps_unref (templ);
      continue;
    }
    gst_caps_unref (templ);

    if (!upload_methods[i]->set_caps (vk_upload->upload_impls[i], in_caps,
            out_caps))
      continue;

    GST_LOG_OBJECT (bt, "uploader %s accepted caps in: %" GST_PTR_FORMAT
        " out: %" GST_PTR_FORMAT, upload_methods[i]->name, in_caps, out_caps);

    vk_upload->current_impl = i;
    found_method = TRUE;
    break;
  }

  GST_DEBUG_OBJECT (bt,
      "set caps in: %" GST_PTR_FORMAT " out: %" GST_PTR_FORMAT, in_caps,
      out_caps);

  return found_method;
}

static gboolean
gst_vulkan_upload_propose_allocation (GstBaseTransform * bt,
    GstQuery * decide_query, GstQuery * query)
{
  GstVulkanUpload *vk_upload = GST_VULKAN_UPLOAD (bt);
  guint i;

  for (i = 0; i < G_N_ELEMENTS (upload_methods); i++) {
    GstCaps *templ;

    templ = gst_static_caps_get (upload_methods[i]->in_template);
    if (!gst_caps_can_intersect (vk_upload->in_caps, templ)) {
      gst_caps_unref (templ);
      continue;
    }
    gst_caps_unref (templ);

    templ = gst_static_caps_get (upload_methods[i]->out_template);
    if (!gst_caps_can_intersect (vk_upload->out_caps, templ)) {
      gst_caps_unref (templ);
      continue;
    }
    gst_caps_unref (templ);

    upload_methods[i]->propose_allocation (vk_upload->upload_impls[i],
        decide_query, query);
  }

  return TRUE;
}

static gboolean
gst_vulkan_upload_decide_allocation (GstBaseTransform * bt, GstQuery * query)
{
  return TRUE;
}

static gboolean
_upload_find_method (GstVulkanUpload * vk_upload)
{
  vk_upload->current_impl++;

  if (vk_upload->current_impl > G_N_ELEMENTS (upload_methods))
    return FALSE;

  GST_DEBUG_OBJECT (vk_upload, "attempting upload with uploader %s",
      upload_methods[vk_upload->current_impl]->name);

  return TRUE;
}

static GstFlowReturn
gst_vulkan_upload_prepare_output_buffer (GstBaseTransform * bt,
    GstBuffer * inbuf, GstBuffer ** outbuf)
{
  GstBaseTransformClass *bclass = GST_BASE_TRANSFORM_GET_CLASS (bt);
  GstVulkanUpload *vk_upload = GST_VULKAN_UPLOAD (bt);
  GstFlowReturn ret;

  do {
    gpointer method_impl;
    const struct UploadMethod *method;

    method = upload_methods[vk_upload->current_impl];
    method_impl = vk_upload->upload_impls[vk_upload->current_impl];

    ret = method->perform (method_impl, inbuf, outbuf);
    if (ret != GST_FLOW_OK) {
      do {
        if (!_upload_find_method (vk_upload)) {
          GST_ELEMENT_ERROR (bt, RESOURCE, NOT_FOUND,
              ("Could not find suitable uploader"), (NULL));
          return GST_FLOW_ERROR;
        }

        method = upload_methods[vk_upload->current_impl];
        method_impl = vk_upload->upload_impls[vk_upload->current_impl];
        if (!method->set_caps (method_impl, vk_upload->in_caps,
                vk_upload->out_caps))
          /* try the next method */
          continue;
      } while (FALSE);
      /* try the uploading with the next method */
      continue;
    }
  } while (FALSE);

  if (ret == GST_FLOW_OK) {
    /* basetransform doesn't unref if they're the same */
    if (inbuf != *outbuf)
      bclass->copy_metadata (bt, inbuf, *outbuf);
  }

  return ret;
}

static GstFlowReturn
gst_vulkan_upload_transform (GstBaseTransform * bt, GstBuffer * inbuf,
    GstBuffer * outbuf)
{
  return GST_FLOW_OK;
}
