/* GStreamer mplex (mjpegtools) wrapper
 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
 *
 * gstmplexjob.hh: gstreamer/mplex multiplex-job wrapper
 *
 * 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 "gstmplexjob.hh"


enum
{
  ARG_0,
  ARG_FORMAT,
  ARG_MUX_BITRATE,
  ARG_VBR,
  ARG_SYSTEM_HEADERS,
  ARG_SPLIT_SEQUENCE,
  ARG_SEGMENT_SIZE,
  ARG_PACKETS_PER_PACK,
  ARG_SECTOR_SIZE,
  ARG_BUFSIZE
      /* FILL ME */
};

#define DEFAULT_FORMAT MPEG_FORMAT_DVD
/*
 * Property enumeration types.
 */

#define GST_TYPE_MPLEX_FORMAT \
  (gst_mplex_format_get_type ())

static GType
gst_mplex_format_get_type (void)
{
  static GType mplex_format_type = 0;

  if (!mplex_format_type) {
    static const GEnumValue mplex_formats[] = {
      {MPEG_FORMAT_MPEG1, "Generic MPEG-1", "mpeg-1"},
      {MPEG_FORMAT_VCD, "Standard VCD", "vcd"},
      {MPEG_FORMAT_VCD_NSR, "User VCD", "vcd-nsr"},
      {MPEG_FORMAT_MPEG2, "Generic MPEG-2", "mpeg-2"},
      {MPEG_FORMAT_SVCD, "Standard SVCD", "svcd"},
      {MPEG_FORMAT_SVCD_NSR, "User SVCD", "svcd-nsr"},
      {MPEG_FORMAT_VCD_STILL, "VCD Stills sequences", "vcd-still"},
      {MPEG_FORMAT_SVCD_STILL, "SVCD Stills sequences", "svcd-still"},
      {MPEG_FORMAT_DVD_NAV, "DVD MPEG-2 for dvdauthor", "dvd-nav"},
      {MPEG_FORMAT_DVD, "DVD MPEG-2", "dvd"},
      {MPEG_FORMAT_ATSC480i, "ATSC 480i", "atsc-480i"},
      {MPEG_FORMAT_ATSC480p, "ATSC 480p", "atsc-480p"},
      {MPEG_FORMAT_ATSC720p, "ATSC 720p", "atsc-720p"},
      {MPEG_FORMAT_ATSC1080i, "ATSC 1080i", "atsc-1080i"},
      {0, NULL, NULL},
    };

    mplex_format_type =
        g_enum_register_static ("GstMplexFormat", mplex_formats);
  }

  return mplex_format_type;
}

/*
 * Class init functions.
 */

GstMplexJob::GstMplexJob (void):
MultiplexJob ()
{
  /* blabla */
  bufsize = 0;
}

/*
 * GObject properties.
 */

void
GstMplexJob::initProperties (GObjectClass * klass)
{
  /* encoding profile */
  g_object_class_install_property (klass, ARG_FORMAT,
      g_param_spec_enum ("format", "Format", "Encoding profile format",
          GST_TYPE_MPLEX_FORMAT, DEFAULT_FORMAT,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  /* total stream datarate. Normally, this shouldn't be needed, but
   * some DVD/VCD/SVCD players really need strict values to handle
   * the created files correctly. */
  g_object_class_install_property (klass, ARG_MUX_BITRATE,
      g_param_spec_int ("mux-bitrate", "Mux. bitrate",
          "Bitrate of output stream in kbps (0 = autodetect)",
          0, 15 * 1024, 0,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  /* override decode buffer size otherwise determined by format */
  g_object_class_install_property (klass, ARG_BUFSIZE,
      g_param_spec_int ("bufsize", "Decoder buf. size",
          "Target decoders video buffer size (kB) "
          "[default determined by format if not explicitly set]",
          20, 4000, 46,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  /* some boolean stuff for headers */
  g_object_class_install_property (klass, ARG_VBR,
      g_param_spec_boolean ("vbr", "VBR",
          "Whether the input video stream is variable bitrate",
          FALSE,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
  g_object_class_install_property (klass, ARG_SYSTEM_HEADERS,
      g_param_spec_boolean ("system-headers", "System headers",
          "Create system header in every pack for generic formats",
          FALSE,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
#if 0                           /* not supported */
  g_object_class_install_property (klass, ARG_SPLIT_SEQUENCE,
      g_param_spec_boolean ("split-sequence", "Split sequence",
          "Simply split a sequence across files "
          "(rather than building run-out/run-in)",
          FALSE,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  /* size of a segment */
  g_object_class_install_property (klass, ARG_SEGMENT_SIZE,
      g_param_spec_int ("max-segment-size", "Max. segment size",
          "Max. size per segment/file in MB (0 = unlimited)",
          0, 10 * 1024, 0,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
#endif

  /* packets per pack (generic formats) */
  g_object_class_install_property (klass, ARG_PACKETS_PER_PACK,
      g_param_spec_int ("packets-per-pack", "Packets per pack",
          "Number of packets per pack for generic formats",
          1, 100, 1,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  /* size of one sector */
  g_object_class_install_property (klass, ARG_SECTOR_SIZE,
      g_param_spec_int ("sector-size", "Sector size",
          "Specify sector size in bytes for generic formats",
          256, 16384, 2048,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
}

/*
 * set/get gobject properties.
 */

void
GstMplexJob::getProperty (guint prop_id, GValue * value)
{
  switch (prop_id) {
    case ARG_FORMAT:
      g_value_set_enum (value, mux_format);
      break;
    case ARG_MUX_BITRATE:
      /* convert from bytes back to bits */
      g_value_set_int (value, (data_rate * 8) / 1000);
      break;
    case ARG_VBR:
      g_value_set_boolean (value, VBR);
      break;
    case ARG_SYSTEM_HEADERS:
      g_value_set_boolean (value, always_system_headers);
      break;
    case ARG_SPLIT_SEQUENCE:
      g_value_set_boolean (value, multifile_segment);
      break;
    case ARG_SEGMENT_SIZE:
      g_value_set_int (value, max_segment_size);
      break;
    case ARG_PACKETS_PER_PACK:
      g_value_set_int (value, packets_per_pack);
      break;
    case ARG_SECTOR_SIZE:
      g_value_set_int (value, sector_size);
      break;
    case ARG_BUFSIZE:
      g_value_set_int (value, bufsize);
      break;
    default:
      break;
  }
}

void
GstMplexJob::setProperty (guint prop_id, const GValue * value)
{
  switch (prop_id) {
    case ARG_FORMAT:
      mux_format = g_value_get_enum (value);
      break;
    case ARG_MUX_BITRATE:
      /* data_rate expects bytes (don't ask me why the property itself is
       * in bits, I'm just staying compatible to mjpegtools options), and
       * rounded up to 50-bytes. */
      data_rate = ((g_value_get_int (value) * 1000 / 8 + 49) / 50) * 50;
      break;
    case ARG_VBR:
      VBR = g_value_get_boolean (value);
      break;
    case ARG_SYSTEM_HEADERS:
      always_system_headers = g_value_get_boolean (value);
      break;
    case ARG_SPLIT_SEQUENCE:
      multifile_segment = g_value_get_boolean (value);
      break;
    case ARG_SEGMENT_SIZE:
      max_segment_size = g_value_get_int (value);
      break;
    case ARG_PACKETS_PER_PACK:
      packets_per_pack = g_value_get_int (value);
      break;
    case ARG_SECTOR_SIZE:
      sector_size = g_value_get_int (value);
      break;
    case ARG_BUFSIZE:
      bufsize = g_value_get_int (value);
      break;
    default:
      break;
  }
}
