/* GStreamer
*
* Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.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.
*/

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

#include "gstvdpdecoder.h"
#include "gstvdpvideomemory.h"
#include "gstvdpvideobufferpool.h"

GST_DEBUG_CATEGORY_STATIC (gst_vdp_decoder_debug);
#define GST_CAT_DEFAULT gst_vdp_decoder_debug

#define DEBUG_INIT \
    GST_DEBUG_CATEGORY_INIT (gst_vdp_decoder_debug, "vdpdecoder", 0, \
    "VDPAU decoder base class");
#define gst_vdp_decoder_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstVdpDecoder, gst_vdp_decoder, GST_TYPE_VIDEO_DECODER,
    DEBUG_INIT);

enum
{
  PROP_0,
  PROP_DISPLAY
};

void
gst_vdp_decoder_post_error (GstVdpDecoder * decoder, GError * error)
{
  GstMessage *message;

  g_return_if_fail (GST_IS_VDP_DECODER (decoder));
  g_return_if_fail (decoder != NULL);

  message = gst_message_new_error (GST_OBJECT (decoder), error, NULL);
  gst_element_post_message (GST_ELEMENT (decoder), message);
  g_error_free (error);
}


GstFlowReturn
gst_vdp_decoder_render (GstVdpDecoder * vdp_decoder, VdpPictureInfo * info,
    guint n_bufs, VdpBitstreamBuffer * bufs, GstVideoCodecFrame * frame)
{
  GstFlowReturn ret;

  VdpStatus status;

  GstVdpVideoMemory *vmem;
#ifndef GST_DISABLE_GST_DEBUG
  GstClockTime before, after;
#endif

  GST_DEBUG_OBJECT (vdp_decoder, "n_bufs:%d, frame:%d", n_bufs,
      frame->system_frame_number);

  ret =
      gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER (vdp_decoder),
      frame);
  if (ret != GST_FLOW_OK)
    goto fail_alloc;

  vmem = (GstVdpVideoMemory *) gst_buffer_get_memory (frame->output_buffer, 0);
  if (!vmem
      || !gst_memory_is_type ((GstMemory *) vmem,
          GST_VDP_VIDEO_MEMORY_ALLOCATOR))
    goto no_mem;

  GST_DEBUG_OBJECT (vdp_decoder, "Calling VdpDecoderRender()");
#ifndef GST_DISABLE_GST_DEBUG
  before = gst_util_get_timestamp ();
#endif
  status =
      vdp_decoder->device->vdp_decoder_render (vdp_decoder->decoder,
      vmem->surface, info, n_bufs, bufs);
#ifndef GST_DISABLE_GST_DEBUG
  after = gst_util_get_timestamp ();
#endif
  if (status != VDP_STATUS_OK)
    goto decode_error;

  GST_DEBUG_OBJECT (vdp_decoder, "VdpDecoderRender() took %" GST_TIME_FORMAT,
      GST_TIME_ARGS (after - before));

  return GST_FLOW_OK;

decode_error:
  GST_ELEMENT_ERROR (vdp_decoder, RESOURCE, READ,
      ("Could not decode"),
      ("Error returned from vdpau was: %s",
          vdp_decoder->device->vdp_get_error_string (status)));

  gst_video_decoder_drop_frame (GST_VIDEO_DECODER (vdp_decoder), frame);

  return GST_FLOW_ERROR;

fail_alloc:
  {
    GST_WARNING_OBJECT (vdp_decoder, "Failed to get an output frame");
    return ret;
  }

no_mem:
  {
    GST_ERROR_OBJECT (vdp_decoder, "Didn't get VdpVideoSurface backed buffer");
    return GST_FLOW_ERROR;
  }
}

GstFlowReturn
gst_vdp_decoder_init_decoder (GstVdpDecoder * vdp_decoder,
    VdpDecoderProfile profile, guint32 max_references,
    GstVideoCodecState * output_state)
{
  GstVdpDevice *device;

  VdpStatus status;

  device = vdp_decoder->device;

  if (vdp_decoder->decoder != VDP_INVALID_HANDLE) {
    status = device->vdp_decoder_destroy (vdp_decoder->decoder);
    if (status != VDP_STATUS_OK)
      goto destroy_decoder_error;
  }

  GST_DEBUG_OBJECT (vdp_decoder,
      "device:%u, profile:%d, width:%d, height:%d, max_references:%d",
      device->device, profile, output_state->info.width,
      output_state->info.height, max_references);

  status = device->vdp_decoder_create (device->device, profile,
      output_state->info.width, output_state->info.height, max_references,
      &vdp_decoder->decoder);
  if (status != VDP_STATUS_OK)
    goto create_decoder_error;

  return GST_FLOW_OK;

destroy_decoder_error:
  GST_ELEMENT_ERROR (vdp_decoder, RESOURCE, READ,
      ("Could not destroy vdpau decoder"),
      ("Error returned from vdpau was: %s",
          device->vdp_get_error_string (status)));

  return GST_FLOW_ERROR;

create_decoder_error:
  GST_ELEMENT_ERROR (vdp_decoder, RESOURCE, READ,
      ("Could not create vdpau decoder"),
      ("Error returned from vdpau was: %s",
          device->vdp_get_error_string (status)));

  return GST_FLOW_ERROR;
}

static gboolean
gst_vdp_decoder_decide_allocation (GstVideoDecoder * video_decoder,
    GstQuery * query)
{
  GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (video_decoder);
  GstCaps *outcaps;
  GstBufferPool *pool = NULL;
  guint size, min = 0, max = 0;
  GstStructure *config;
  GstVideoInfo vinfo;
  gboolean update_pool;

  gst_query_parse_allocation (query, &outcaps, NULL);
  gst_video_info_init (&vinfo);
  gst_video_info_from_caps (&vinfo, outcaps);

  if (gst_query_get_n_allocation_pools (query) > 0) {
    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
    size = MAX (size, vinfo.size);
    update_pool = TRUE;
  } else {
    pool = NULL;
    size = vinfo.size;
    min = max = 0;

    update_pool = FALSE;
  }

  if (pool == NULL
      || !gst_buffer_pool_has_option (pool,
          GST_BUFFER_POOL_OPTION_VDP_VIDEO_META)) {
    if (pool)
      gst_object_unref (pool);
    /* no pool or pool doesn't support GstVdpVideoMeta, we can make our own */
    GST_DEBUG_OBJECT (video_decoder,
        "no pool or doesn't support GstVdpVideoMeta, making new pool");
    pool = gst_vdp_video_buffer_pool_new (vdp_decoder->device);
  }

  /* now configure */
  config = gst_buffer_pool_get_config (pool);
  gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
  gst_buffer_pool_config_add_option (config,
      GST_BUFFER_POOL_OPTION_VDP_VIDEO_META);
  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);

  if (pool)
    gst_object_unref (pool);

  return TRUE;

}

static gboolean
gst_vdp_decoder_start (GstVideoDecoder * video_decoder)
{
  GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (video_decoder);
  GError *err = NULL;

  GST_DEBUG_OBJECT (video_decoder, "Starting");

  vdp_decoder->device = gst_vdp_get_device (vdp_decoder->display, &err);
  if (G_UNLIKELY (!vdp_decoder->device))
    goto device_error;

  vdp_decoder->decoder = VDP_INVALID_HANDLE;

  return TRUE;

device_error:
  gst_vdp_decoder_post_error (vdp_decoder, err);
  return FALSE;
}

static gboolean
gst_vdp_decoder_stop (GstVideoDecoder * video_decoder)
{
  GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (video_decoder);

  if (vdp_decoder->decoder != VDP_INVALID_HANDLE) {
    GstVdpDevice *device = vdp_decoder->device;
    VdpStatus status;

    status = device->vdp_decoder_destroy (vdp_decoder->decoder);
    if (status != VDP_STATUS_OK) {
      GST_ELEMENT_ERROR (vdp_decoder, RESOURCE, READ,
          ("Could not destroy vdpau decoder"),
          ("Error returned from vdpau was: %s",
              device->vdp_get_error_string (status)));
      return FALSE;
    }
  }

  g_object_unref (vdp_decoder->device);

  return TRUE;
}

static void
gst_vdp_decoder_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (object);

  switch (prop_id) {
    case PROP_DISPLAY:
      g_value_set_string (value, vdp_decoder->display);
      break;

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

static void
gst_vdp_decoder_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (object);

  switch (prop_id) {
    case PROP_DISPLAY:
      g_free (vdp_decoder->display);
      vdp_decoder->display = g_value_dup_string (value);
      break;

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

static void
gst_vdp_decoder_finalize (GObject * object)
{
  GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (object);

  g_free (vdp_decoder->display);

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

static void
gst_vdp_decoder_init (GstVdpDecoder * vdp_decoder)
{

}

static void
gst_vdp_decoder_class_init (GstVdpDecoderClass * klass)
{
  GObjectClass *object_class;
  GstVideoDecoderClass *video_decoder_class;
  GstElementClass *element_class;

  GstCaps *src_caps;
  GstPadTemplate *src_template;

  object_class = G_OBJECT_CLASS (klass);
  element_class = GST_ELEMENT_CLASS (klass);
  video_decoder_class = GST_VIDEO_DECODER_CLASS (klass);

  object_class->get_property = gst_vdp_decoder_get_property;
  object_class->set_property = gst_vdp_decoder_set_property;
  object_class->finalize = gst_vdp_decoder_finalize;

  video_decoder_class->start = gst_vdp_decoder_start;
  video_decoder_class->stop = gst_vdp_decoder_stop;
  video_decoder_class->decide_allocation = gst_vdp_decoder_decide_allocation;

  GST_FIXME ("Actually create srcpad template from hw capabilities");
  src_caps =
      gst_caps_from_string (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
      (GST_CAPS_FEATURE_MEMORY_VDPAU,
          "{ YV12 }") ";" GST_VIDEO_CAPS_MAKE ("{ YV12 }"));
  src_template =
      gst_pad_template_new (GST_VIDEO_DECODER_SRC_NAME, GST_PAD_SRC,
      GST_PAD_ALWAYS, src_caps);

  gst_element_class_add_pad_template (element_class, src_template);

  if (src_caps)
    gst_caps_unref (src_caps);

  g_object_class_install_property (object_class,
      PROP_DISPLAY, g_param_spec_string ("display", "Display", "X Display name",
          NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
}
