/* GStreamer Wayland video sink
 *
 * Copyright (C) 2016 STMicroelectronics SA
 * Copyright (C) 2016 Fabien Dessenne <fabien.dessenne@st.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 Street, Fifth Floor,
 * Boston, MA 02110-1301 USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <gst/allocators/gstdmabuf.h>
#include <gst/allocators/gstdmabufmeta.h>
#include <gst/allocators/gstphymemmeta.h>

#include "wllinuxdmabuf.h"
#include "wlvideoformat.h"

GST_DEBUG_CATEGORY_EXTERN (gstwayland_debug);
#define GST_CAT_DEFAULT gstwayland_debug

typedef struct
{
  GMutex lock;
  GCond cond;
  struct wl_buffer *wbuf;
} ConstructBufferData;

static void
create_succeeded (void *data, struct zwp_linux_buffer_params_v1 *params,
    struct wl_buffer *new_buffer)
{
  ConstructBufferData *d = data;

  g_mutex_lock (&d->lock);
  d->wbuf = new_buffer;
  zwp_linux_buffer_params_v1_destroy (params);
  g_cond_signal (&d->cond);
  g_mutex_unlock (&d->lock);
}

static void
create_failed (void *data, struct zwp_linux_buffer_params_v1 *params)
{
  ConstructBufferData *d = data;

  g_mutex_lock (&d->lock);
  d->wbuf = NULL;
  zwp_linux_buffer_params_v1_destroy (params);
  g_cond_signal (&d->cond);
  g_mutex_unlock (&d->lock);
}

static const struct zwp_linux_buffer_params_v1_listener params_listener = {
  create_succeeded,
  create_failed
};

struct wl_buffer *
gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf,
    GstWlDisplay * display, const GstVideoInfo * info)
{
  GstMemory *mem;
  int format;
  guint i, width, height;
  guint nplanes, flags = 0;
  struct zwp_linux_buffer_params_v1 *params;
  gint64 timeout;
  ConstructBufferData data;
  GstDmabufMeta *dmabuf_meta;
  gint64 drm_modifier = 0;
  GstPhyMemMeta *phymemmeta = NULL;

  g_return_val_if_fail (gst_wl_display_check_format_for_dmabuf (display,
          GST_VIDEO_INFO_FORMAT (info)), NULL);

  mem = gst_buffer_peek_memory (buf, 0);
  format = gst_video_format_to_wl_dmabuf_format (GST_VIDEO_INFO_FORMAT (info));

  g_cond_init (&data.cond);
  g_mutex_init (&data.lock);
  g_mutex_lock (&data.lock);

  width = GST_VIDEO_INFO_WIDTH (info);
  height = GST_VIDEO_INFO_HEIGHT (info);
  nplanes = GST_VIDEO_INFO_N_PLANES (info);

  dmabuf_meta = gst_buffer_get_dmabuf_meta (buf);
  if (dmabuf_meta)
    drm_modifier = dmabuf_meta->drm_modifier;

  GST_DEBUG_OBJECT (display, "Creating wl_buffer from DMABuf of size %"
      G_GSSIZE_FORMAT " (%d x %d), format %s modifier 0x%016"PRIx64, info->size, width, height,
      gst_wl_dmabuf_format_to_string (format), drm_modifier);

  /* Creation and configuration of planes  */
  params = zwp_linux_dmabuf_v1_create_params (display->dmabuf);

  for (i = 0; i < nplanes; i++) {
    guint offset, stride, mem_idx, length;
    gsize skip;

    offset = GST_VIDEO_INFO_PLANE_OFFSET (info, i);
    stride = GST_VIDEO_INFO_PLANE_STRIDE (info, i);
    if (gst_buffer_find_memory (buf, offset, 1, &mem_idx, &length, &skip)) {
      GstMemory *m = gst_buffer_peek_memory (buf, mem_idx);
      gint fd = gst_dmabuf_memory_get_fd (m);
      zwp_linux_buffer_params_v1_add (params, fd, i, m->offset + skip,
          stride, drm_modifier >> 32, drm_modifier & 0xffffffff);
    } else {
      GST_ERROR_OBJECT (mem->allocator, "memory does not seem to contain "
          "enough data for the specified format");
      zwp_linux_buffer_params_v1_destroy (params);
      data.wbuf = NULL;
      goto out;
    }
  }

  if (GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_FLAG_INTERLACED)) {
    GST_DEBUG_OBJECT (mem->allocator, "interlaced buffer");
    flags = ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_INTERLACED;

    if (!GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_FLAG_TFF)) {
      GST_DEBUG_OBJECT (mem->allocator, "with bottom field first");
      flags |= ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_BOTTOM_FIRST;
    }
  }

  phymemmeta = GST_PHY_MEM_META_GET (buf);
  if (drm_modifier != 0 && phymemmeta) {
    GST_DEBUG_OBJECT (display, "physical memory meta x_padding: %d y_padding: %d \
          RFC luma offset: %d chroma offset: %d",
          phymemmeta->x_padding, phymemmeta->y_padding, phymemmeta->rfc_luma_offset, phymemmeta->rfc_chroma_offset);
    zwp_linux_buffer_params_v1_add_dtrc_meta (params, phymemmeta->rfc_chroma_offset, phymemmeta->rfc_luma_offset);
  } else {
    zwp_linux_buffer_params_v1_add_dtrc_meta (params, 0, 0);
  }

  /* Request buffer creation */
  zwp_linux_buffer_params_v1_add_listener (params, &params_listener, &data);
  zwp_linux_buffer_params_v1_create (params, width, height, format, flags);

  /* Wait for the request answer */
  wl_display_flush (display->display);
  data.wbuf = (gpointer) 0x1;
  timeout = g_get_monotonic_time () + G_TIME_SPAN_SECOND;
  while (data.wbuf == (gpointer) 0x1) {
    if (!g_cond_wait_until (&data.cond, &data.lock, timeout)) {
      GST_ERROR_OBJECT (mem->allocator, "zwp_linux_buffer_params_v1 time out");
      zwp_linux_buffer_params_v1_destroy (params);
      data.wbuf = NULL;
    }
  }

out:
  if (!data.wbuf) {
    GST_ERROR_OBJECT (mem->allocator, "can't create linux-dmabuf buffer");
  } else {
    GST_DEBUG_OBJECT (mem->allocator, "created linux_dmabuf wl_buffer (%p):"
        "%dx%d, fmt=%.4s, %d planes",
        data.wbuf, width, height, (char *) &format, nplanes);
  }

  g_mutex_unlock (&data.lock);
  g_mutex_clear (&data.lock);
  g_cond_clear (&data.cond);

  return data.wbuf;
}
