/* GStreamer
 * Copyright (C) 2008-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
 *
 * 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.
 */

/* Implementation of SMPTE 384M - Mapping of Uncompressed Pictures into the MXF
 * Generic Container
 */

/* TODO: 
 *   - Handle CDCI essence
 *   - Handle more formats with RGBA descriptor (4:4:4 / 4:4:4:4 YUV, RGB656, ...)
 *   - Handle all the dimensions and other properties in the picture
 *     essence descriptors correctly according to S377M Annex E
 *   - Handle interlaced correctly, i.e. weave until we support one-field-per-buffer
 */

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

#include <gst/gst.h>
#include <string.h>

#include <gst/video/video.h>

#include "mxfup.h"
#include "mxfessence.h"

GST_DEBUG_CATEGORY_EXTERN (mxf_debug);
#define GST_CAT_DEFAULT mxf_debug

static const struct
{
  const gchar *format;
  guint32 n_pixel_layout;
  guint8 pixel_layout[10];
  const gchar *caps_string;
} _rgba_mapping_table[] = {
  {
    "RGB", 3, {
  'R', 8, 'G', 8, 'B', 8}, GST_VIDEO_CAPS_MAKE ("RGB")}, {
    "BGR", 3, {
  'B', 8, 'G', 8, 'R', 8}, GST_VIDEO_CAPS_MAKE ("BGR")}, {
    "v308", 3, {
  'Y', 8, 'U', 8, 'V', 8}, GST_VIDEO_CAPS_MAKE ("v308")}, {
    "xRGB", 4, {
  'F', 8, 'R', 8, 'G', 8, 'B', 8}, GST_VIDEO_CAPS_MAKE ("xRGB")}, {
    "RGBx", 4, {
  'R', 8, 'G', 8, 'B', 8, 'F', 8}, GST_VIDEO_CAPS_MAKE ("RGBx")}, {
    "xBGR", 4, {
  'F', 8, 'B', 8, 'G', 8, 'R', 8}, GST_VIDEO_CAPS_MAKE ("xBGR")}, {
    "BGRx", 4, {
  'B', 8, 'G', 8, 'R', 8, 'F', 8}, GST_VIDEO_CAPS_MAKE ("BGRx")}, {
    "RGBA", 4, {
  'R', 8, 'G', 8, 'B', 8, 'A', 8}, GST_VIDEO_CAPS_MAKE ("RGBA")}, {
    "ARGB", 4, {
  'A', 8, 'R', 8, 'G', 8, 'B', 8}, GST_VIDEO_CAPS_MAKE ("RGBA")}, {
    "BGRA", 4, {
  'B', 8, 'G', 8, 'R', 8, 'A', 8}, GST_VIDEO_CAPS_MAKE ("BGRA")}, {
    "ABGR", 4, {
  'A', 8, 'B', 8, 'G', 8, 'R', 8}, GST_VIDEO_CAPS_MAKE ("ABGR")}, {
    "AYUV", 4, {
  'A', 8, 'Y', 8, 'U', 8, 'V', 8}, GST_VIDEO_CAPS_MAKE ("AYUV")}
};

static const struct
{
  const gchar *format;
  guint bpp;
  guint horizontal_subsampling;
  guint vertical_subsampling;
  gboolean reversed_byte_order;
  const gchar *caps_string;
} _cdci_mapping_table[] = {
  {
  "YUY2", 2, 1, 0, TRUE, GST_VIDEO_CAPS_MAKE ("YUY2")}, {
"UYVY", 2, 1, 0, FALSE, GST_VIDEO_CAPS_MAKE ("UYVY")},};

typedef struct
{
  const gchar *format;          /* video format string */
  gint width, height;
  guint bpp;
  guint32 image_start_offset;
  guint32 image_end_offset;
} MXFUPMappingData;

static gboolean
mxf_is_up_essence_track (const MXFMetadataTimelineTrack * track)
{
  guint i;

  g_return_val_if_fail (track != NULL, FALSE);

  if (track->parent.descriptor == NULL)
    return FALSE;

  for (i = 0; i < track->parent.n_descriptor; i++) {
    MXFMetadataFileDescriptor *d = track->parent.descriptor[i];
    MXFUL *key;

    if (!d)
      continue;

    key = &d->essence_container;
    /* SMPTE 384M 8 */
    if (mxf_is_generic_container_essence_container_label (key) &&
        key->u[12] == 0x02 && key->u[13] == 0x05 && key->u[15] <= 0x03)
      return TRUE;
  }

  return FALSE;
}

static GstFlowReturn
mxf_up_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
    GstCaps * caps,
    MXFMetadataTimelineTrack * track,
    gpointer mapping_data, GstBuffer ** outbuf)
{
  MXFUPMappingData *data = mapping_data;

  /* SMPTE 384M 7.1 */
  if (key->u[12] != 0x15 || (key->u[14] != 0x01 && key->u[14] != 0x02
          && key->u[14] != 0x03 && key->u[14] != 0x04)) {
    GST_ERROR ("Invalid uncompressed picture essence element");
    gst_buffer_unref (buffer);
    return GST_FLOW_ERROR;
  }

  if (!data) {
    GST_ERROR ("Invalid mapping data");
    gst_buffer_unref (buffer);
    return GST_FLOW_ERROR;
  }

  if (data->image_start_offset == 0 && data->image_end_offset == 0) {
  } else {
    if (data->image_start_offset + data->image_end_offset
        > gst_buffer_get_size (buffer)) {
      gst_buffer_unref (buffer);
      GST_ERROR ("Invalid buffer size");
      return GST_FLOW_ERROR;
    } else {
      gst_buffer_resize (buffer, data->image_start_offset,
          data->image_end_offset - data->image_start_offset);
    }
  }

  if (gst_buffer_get_size (buffer) != data->bpp * data->width * data->height) {
    GST_ERROR ("Invalid buffer size");
    gst_buffer_unref (buffer);
    return GST_FLOW_ERROR;
  }

  if (data->bpp != 4
      || GST_ROUND_UP_4 (data->width * data->bpp) != data->width * data->bpp) {
    guint y;
    GstBuffer *ret;
    GstMapInfo inmap, outmap;
    guint8 *indata, *outdata;

    ret =
        gst_buffer_new_and_alloc (GST_ROUND_UP_4 (data->width * data->bpp) *
        data->height);
    gst_buffer_map (buffer, &inmap, GST_MAP_READ);
    gst_buffer_map (ret, &outmap, GST_MAP_WRITE);
    indata = inmap.data;
    outdata = outmap.data;

    for (y = 0; y < data->height; y++) {
      memcpy (outdata, indata, data->width * data->bpp);
      outdata += GST_ROUND_UP_4 (data->width * data->bpp);
      indata += data->width * data->bpp;
    }

    gst_buffer_unmap (buffer, &inmap);
    gst_buffer_unmap (ret, &outmap);

    gst_buffer_unref (buffer);
    *outbuf = ret;
  } else {
    *outbuf = buffer;
  }

  return GST_FLOW_OK;
}

static MXFEssenceWrapping
mxf_up_get_track_wrapping (const MXFMetadataTimelineTrack * track)
{
  guint i;

  g_return_val_if_fail (track != NULL, MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING);

  if (track->parent.descriptor == NULL) {
    GST_ERROR ("No descriptor found for this track");
    return MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING;
  }

  for (i = 0; i < track->parent.n_descriptor; i++) {
    if (!track->parent.descriptor[i])
      continue;

    if (!MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->
            parent.descriptor[i]))
      continue;

    switch (track->parent.descriptor[i]->essence_container.u[15]) {
      case 0x01:
        return MXF_ESSENCE_WRAPPING_FRAME_WRAPPING;
        break;
      case 0x02:
        return MXF_ESSENCE_WRAPPING_CLIP_WRAPPING;
        break;
      default:
        return MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING;
        break;
    }
  }

  return MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING;
}

static GstCaps *
mxf_up_rgba_create_caps (MXFMetadataTimelineTrack * track,
    MXFMetadataRGBAPictureEssenceDescriptor * d, GstTagList ** tags,
    MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
{
  GstCaps *caps = NULL;
  guint i;
  const gchar *format = NULL;
  guint bpp;

  if (!d->pixel_layout) {
    GST_ERROR ("No pixel layout");
    return NULL;
  }

  for (i = 0; i < G_N_ELEMENTS (_rgba_mapping_table); i++) {
    if (d->n_pixel_layout != _rgba_mapping_table[i].n_pixel_layout)
      continue;

    if (memcmp (d->pixel_layout, &_rgba_mapping_table[i].pixel_layout,
            _rgba_mapping_table[i].n_pixel_layout * 2) == 0) {
      caps = gst_caps_from_string (_rgba_mapping_table[i].caps_string);
      format = _rgba_mapping_table[i].format;
      bpp = _rgba_mapping_table[i].n_pixel_layout;
      break;
    }
  }

  if (caps) {
    MXFUPMappingData *data = g_new0 (MXFUPMappingData, 1);

    mxf_metadata_generic_picture_essence_descriptor_set_caps (&d->parent, caps);

    data->width = d->parent.stored_width;
    data->height = d->parent.stored_height;
    data->format = format;
    data->bpp = bpp;
    data->image_start_offset =
        ((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_start_offset;
    data->image_end_offset =
        ((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_end_offset;

    *mapping_data = data;
  } else {
    GST_WARNING ("Unsupported pixel layout");
  }

  return caps;
}

static GstCaps *
mxf_up_cdci_create_caps (MXFMetadataTimelineTrack * track,
    MXFMetadataCDCIPictureEssenceDescriptor * d, GstTagList ** tags,
    MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
{
  GstCaps *caps = NULL;
  guint i;
  const gchar *format;
  guint bpp;

  for (i = 0; i < G_N_ELEMENTS (_cdci_mapping_table); i++) {
    if (_cdci_mapping_table[i].horizontal_subsampling ==
        d->horizontal_subsampling
        && _cdci_mapping_table[i].vertical_subsampling ==
        d->vertical_subsampling
        && _cdci_mapping_table[i].reversed_byte_order ==
        d->reversed_byte_order) {
      caps = gst_caps_from_string (_cdci_mapping_table[i].caps_string);
      format = _cdci_mapping_table[i].format;
      bpp = _cdci_mapping_table[i].bpp;
      break;
    }
  }

  if (caps) {
    MXFUPMappingData *data = g_new0 (MXFUPMappingData, 1);

    mxf_metadata_generic_picture_essence_descriptor_set_caps (&d->parent, caps);

    data->width = d->parent.stored_width;
    data->height = d->parent.stored_height;
    data->format = format;
    data->bpp = bpp;
    data->image_start_offset =
        ((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_start_offset;
    data->image_end_offset =
        ((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_end_offset;

    *mapping_data = data;
  } else {
    GST_WARNING ("Unsupported CDCI format");
  }

  return caps;
}

static GstCaps *
mxf_up_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
    MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
{
  MXFMetadataGenericPictureEssenceDescriptor *p = NULL;
  MXFMetadataCDCIPictureEssenceDescriptor *c = NULL;
  MXFMetadataRGBAPictureEssenceDescriptor *r = NULL;
  guint i;
  GstCaps *caps = NULL;

  g_return_val_if_fail (track != NULL, NULL);

  if (track->parent.descriptor == NULL) {
    GST_ERROR ("No descriptor found for this track");
    return NULL;
  }

  for (i = 0; i < track->parent.n_descriptor; i++) {
    if (!track->parent.descriptor[i])
      continue;

    if (MXF_IS_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (track->parent.
            descriptor[i])) {
      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent.
          descriptor[i];
      r = (MXFMetadataRGBAPictureEssenceDescriptor *) track->parent.
          descriptor[i];
      break;
    } else if (MXF_IS_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (track->
            parent.descriptor[i])) {
      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent.
          descriptor[i];
      c = (MXFMetadataCDCIPictureEssenceDescriptor *) track->parent.
          descriptor[i];
    }
  }

  if (!p) {
    GST_ERROR ("No picture essence descriptor found for this track");
    return NULL;
  }

  *handler = mxf_up_handle_essence_element;

  if (r) {
    caps = mxf_up_rgba_create_caps (track, r, tags, handler, mapping_data);
  } else if (c) {
    caps = mxf_up_cdci_create_caps (track, c, tags, handler, mapping_data);
  } else {
    return NULL;
  }

  return caps;
}

static const MXFEssenceElementHandler mxf_up_essence_element_handler = {
  mxf_is_up_essence_track,
  mxf_up_get_track_wrapping,
  mxf_up_create_caps
};

static GstFlowReturn
mxf_up_write_func (GstBuffer * buffer, gpointer mapping_data,
    GstAdapter * adapter, GstBuffer ** outbuf, gboolean flush)
{
  MXFUPMappingData *data = mapping_data;

  if (!buffer)
    return GST_FLOW_OK;

  if (gst_buffer_get_size (buffer) !=
      GST_ROUND_UP_4 (data->bpp * data->width) * data->height) {
    GST_ERROR ("Invalid buffer size");
    return GST_FLOW_ERROR;
  }

  if (data->bpp != 4
      || GST_ROUND_UP_4 (data->width * data->bpp) != data->width * data->bpp) {
    guint y;
    GstBuffer *ret;
    GstMapInfo inmap, outmap;
    guint8 *indata, *outdata;

    ret = gst_buffer_new_and_alloc (data->width * data->bpp * data->height);
    gst_buffer_map (buffer, &inmap, GST_MAP_READ);
    gst_buffer_map (ret, &outmap, GST_MAP_WRITE);
    indata = inmap.data;
    outdata = outmap.data;

    for (y = 0; y < data->height; y++) {
      memcpy (outdata, indata, data->width * data->bpp);
      indata += GST_ROUND_UP_4 (data->width * data->bpp);
      outdata += data->width * data->bpp;
    }

    gst_buffer_unmap (buffer, &inmap);
    gst_buffer_unmap (ret, &outmap);
    gst_buffer_unref (buffer);

    *outbuf = ret;
  } else {
    *outbuf = buffer;
  }

  return GST_FLOW_OK;
}

static const guint8 up_essence_container_ul[] = {
  0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01,
  0x0D, 0x01, 0x03, 0x01, 0x02, 0x05, 0x7F, 0x01
};

static MXFMetadataFileDescriptor *
mxf_up_get_rgba_descriptor (GstPadTemplate * tmpl, GstCaps * caps,
    MXFEssenceElementWriteFunc * handler, gpointer * mapping_data)
{
  MXFMetadataRGBAPictureEssenceDescriptor *ret;
  guint i;
  GstCaps *tmp, *intersection;
  MXFUPMappingData *md = g_new0 (MXFUPMappingData, 1);

  *mapping_data = md;

  ret = (MXFMetadataRGBAPictureEssenceDescriptor *)
      g_object_new (MXF_TYPE_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR, NULL);

  for (i = 0; i < G_N_ELEMENTS (_rgba_mapping_table); i++) {
    tmp = gst_caps_from_string (_rgba_mapping_table[i].caps_string);
    intersection = gst_caps_intersect (caps, tmp);
    gst_caps_unref (tmp);

    if (!gst_caps_is_empty (intersection)) {
      gst_caps_unref (intersection);
      ret->n_pixel_layout = _rgba_mapping_table[i].n_pixel_layout;
      ret->pixel_layout = g_new0 (guint8, ret->n_pixel_layout * 2);
      md->format = _rgba_mapping_table[i].format;
      md->bpp = _rgba_mapping_table[i].n_pixel_layout;
      memcpy (ret->pixel_layout, _rgba_mapping_table[i].pixel_layout,
          ret->n_pixel_layout * 2);
      break;
    }
    gst_caps_unref (intersection);
  }

  if (md->format == NULL) {
    GST_ERROR ("Invalid caps %" GST_PTR_FORMAT, caps);
    g_object_unref (ret);
    return NULL;
  }


  memcpy (&ret->parent.parent.essence_container, &up_essence_container_ul, 16);

  if (!mxf_metadata_generic_picture_essence_descriptor_from_caps (&ret->parent,
          caps)) {
    g_object_unref (ret);
    return NULL;
  }

  md->width = ret->parent.stored_width;
  md->height = ret->parent.stored_height;

  *handler = mxf_up_write_func;

  return (MXFMetadataFileDescriptor *) ret;
}

static MXFMetadataFileDescriptor *
mxf_up_get_cdci_descriptor (GstPadTemplate * tmpl, GstCaps * caps,
    MXFEssenceElementWriteFunc * handler, gpointer * mapping_data)
{
  MXFMetadataCDCIPictureEssenceDescriptor *ret;
  guint i;
  GstCaps *tmp, *intersection;
  MXFUPMappingData *md = g_new0 (MXFUPMappingData, 1);

  *mapping_data = md;

  ret = (MXFMetadataCDCIPictureEssenceDescriptor *)
      g_object_new (MXF_TYPE_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR, NULL);

  for (i = 0; i < G_N_ELEMENTS (_cdci_mapping_table); i++) {
    tmp = gst_caps_from_string (_cdci_mapping_table[i].caps_string);
    intersection = gst_caps_intersect (caps, tmp);
    gst_caps_unref (tmp);

    if (!gst_caps_is_empty (intersection)) {
      gst_caps_unref (intersection);
      ret->horizontal_subsampling =
          _cdci_mapping_table[i].horizontal_subsampling;
      ret->vertical_subsampling = _cdci_mapping_table[i].vertical_subsampling;
      ret->reversed_byte_order = _cdci_mapping_table[i].reversed_byte_order;
      md->format = _cdci_mapping_table[i].format;
      md->bpp = _cdci_mapping_table[i].bpp;
      break;
    }
    gst_caps_unref (intersection);
  }

  if (md->format == NULL) {
    GST_ERROR ("Invalid caps %" GST_PTR_FORMAT, caps);
    g_object_unref (ret);
    return NULL;
  }

  memcpy (&ret->parent.parent.essence_container, &up_essence_container_ul, 16);

  if (!mxf_metadata_generic_picture_essence_descriptor_from_caps (&ret->parent,
          caps)) {
    g_object_unref (ret);
    return NULL;
  }

  md->width = ret->parent.stored_width;
  md->height = ret->parent.stored_height;

  *handler = mxf_up_write_func;

  return (MXFMetadataFileDescriptor *) ret;
}

static MXFMetadataFileDescriptor *
mxf_up_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps,
    MXFEssenceElementWriteFunc * handler, gpointer * mapping_data)
{
  GstStructure *s;

  s = gst_caps_get_structure (caps, 0);
  if (strcmp (gst_structure_get_name (s), "video/x-raw") == 0) {
    const gchar *format;

    format = gst_structure_get_string (s, "format");
    if (format == NULL)
      return NULL;

    if (g_str_equal (format, "YUY2") || g_str_equal (format, "UYVY"))
      return mxf_up_get_cdci_descriptor (tmpl, caps, handler, mapping_data);
    else
      return mxf_up_get_rgba_descriptor (tmpl, caps, handler, mapping_data);
  }

  g_assert_not_reached ();
  return NULL;
}

static void
mxf_up_update_descriptor (MXFMetadataFileDescriptor * d, GstCaps * caps,
    gpointer mapping_data, GstBuffer * buf)
{
  return;
}

static void
mxf_up_get_edit_rate (MXFMetadataFileDescriptor * a, GstCaps * caps,
    gpointer mapping_data, GstBuffer * buf, MXFMetadataSourcePackage * package,
    MXFMetadataTimelineTrack * track, MXFFraction * edit_rate)
{
  edit_rate->n = a->sample_rate.n;
  edit_rate->d = a->sample_rate.d;
}

static guint32
mxf_up_get_track_number_template (MXFMetadataFileDescriptor * a,
    GstCaps * caps, gpointer mapping_data)
{
  return (0x15 << 24) | (0x02 << 8);
}

static MXFEssenceElementWriter mxf_up_essence_element_writer = {
  mxf_up_get_descriptor,
  mxf_up_update_descriptor,
  mxf_up_get_edit_rate,
  mxf_up_get_track_number_template,
  NULL,
  {{0,}}
};

void
mxf_up_init (void)
{
  mxf_essence_element_handler_register (&mxf_up_essence_element_handler);
  mxf_up_essence_element_writer.pad_template =
      gst_pad_template_new ("up_video_sink_%u", GST_PAD_SINK, GST_PAD_REQUEST,
      gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("RGB") "; "
          GST_VIDEO_CAPS_MAKE ("BGR") "; "
          GST_VIDEO_CAPS_MAKE ("RGBx") "; "
          GST_VIDEO_CAPS_MAKE ("xRGB") "; "
          GST_VIDEO_CAPS_MAKE ("BGRx") "; "
          GST_VIDEO_CAPS_MAKE ("xBGR") "; "
          GST_VIDEO_CAPS_MAKE ("ARGB") "; "
          GST_VIDEO_CAPS_MAKE ("RGBA") "; "
          GST_VIDEO_CAPS_MAKE ("ABGR") "; "
          GST_VIDEO_CAPS_MAKE ("BGRA") "; "
          GST_VIDEO_CAPS_MAKE ("AYUV") "; "
          GST_VIDEO_CAPS_MAKE ("v308") "; "
          GST_VIDEO_CAPS_MAKE ("UYVY") "; " GST_VIDEO_CAPS_MAKE ("YUY2")));

  memcpy (&mxf_up_essence_element_writer.data_definition,
      mxf_metadata_track_identifier_get (MXF_METADATA_TRACK_PICTURE_ESSENCE),
      16);
  mxf_essence_element_writer_register (&mxf_up_essence_element_writer);
}
