/* GStreamer
 * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
 * Copyright (c) 2012 Collabora Ltd.
 *	Author : Edward Hervey <edward@collabora.com>
 *      Author : Mark Nauwelaerts <mark.nauwelaerts@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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
 * SECTION:element-theoraenc
 * @see_also: theoradec, oggmux
 *
 * This element encodes raw video into a Theora stream.
 * <ulink url="http://www.theora.org/">Theora</ulink> is a royalty-free
 * video codec maintained by the <ulink url="http://www.xiph.org/">Xiph.org
 * Foundation</ulink>, based on the VP3 codec.
 *
 * The theora codec internally only supports encoding of images that are a
 * multiple of 16 pixels in both X and Y direction. It is however perfectly
 * possible to encode images with other dimensions because an arbitrary
 * rectangular cropping region can be set up. This element will automatically
 * set up a correct cropping region if the dimensions are not multiples of 16
 * pixels.
 *
 * To control the quality of the encoding, the #GstTheoraEnc::bitrate and
 * #GstTheoraEnc::quality properties can be used. These two properties are
 * mutualy exclusive. Setting the bitrate property will produce a constant
 * bitrate (CBR) stream while setting the quality property will produce a
 * variable bitrate (VBR) stream.
 *
 * <refsect2>
 * <title>Example pipeline</title>
 * |[
 * gst-launch -v videotestsrc num-buffers=1000 ! theoraenc ! oggmux ! filesink location=videotestsrc.ogg
 * ]| This example pipeline will encode a test video source to theora muxed in an
 * ogg container. Refer to the theoradec documentation to decode the create
 * stream.
 * </refsect2>
 *
 * Last reviewed on 2006-03-01 (0.10.4)
 */

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

#include "gsttheoraenc.h"

#include <string.h>
#include <stdlib.h>             /* free */

#include <gst/tag/tag.h>
#include <gst/video/video.h>
#include <gst/video/gstvideometa.h>

#define GST_CAT_DEFAULT theoraenc_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

#define GST_TYPE_MULTIPASS_MODE (gst_multipass_mode_get_type())
static GType
gst_multipass_mode_get_type (void)
{
  static GType multipass_mode_type = 0;
  static const GEnumValue multipass_mode[] = {
    {MULTIPASS_MODE_SINGLE_PASS, "Single pass", "single-pass"},
    {MULTIPASS_MODE_FIRST_PASS, "First pass", "first-pass"},
    {MULTIPASS_MODE_SECOND_PASS, "Second pass", "second-pass"},
    {0, NULL, NULL},
  };

  if (!multipass_mode_type) {
    multipass_mode_type =
        g_enum_register_static ("GstTheoraEncMultipassMode", multipass_mode);
  }
  return multipass_mode_type;
}

/* taken from theora/lib/toplevel.c */
static int
_ilog (unsigned int v)
{
  int ret = 0;

  while (v) {
    ret++;
    v >>= 1;
  }
  return (ret);
}

#define THEORA_DEF_BITRATE              0
#define THEORA_DEF_QUALITY              48
#define THEORA_DEF_KEYFRAME_AUTO        TRUE
#define THEORA_DEF_KEYFRAME_FREQ        64
#define THEORA_DEF_KEYFRAME_FREQ_FORCE  64
#define THEORA_DEF_SPEEDLEVEL           1
#define THEORA_DEF_VP3_COMPATIBLE       FALSE
#define THEORA_DEF_DROP_FRAMES          TRUE
#define THEORA_DEF_CAP_OVERFLOW         TRUE
#define THEORA_DEF_CAP_UNDERFLOW        FALSE
#define THEORA_DEF_RATE_BUFFER          0
#define THEORA_DEF_MULTIPASS_CACHE_FILE NULL
#define THEORA_DEF_MULTIPASS_MODE       MULTIPASS_MODE_SINGLE_PASS
enum
{
  PROP_0,
  PROP_BITRATE,
  PROP_QUALITY,
  PROP_KEYFRAME_AUTO,
  PROP_KEYFRAME_FREQ,
  PROP_KEYFRAME_FREQ_FORCE,
  PROP_SPEEDLEVEL,
  PROP_VP3_COMPATIBLE,
  PROP_DROP_FRAMES,
  PROP_CAP_OVERFLOW,
  PROP_CAP_UNDERFLOW,
  PROP_RATE_BUFFER,
  PROP_MULTIPASS_CACHE_FILE,
  PROP_MULTIPASS_MODE
      /* FILL ME */
};

/* this function does a straight granulepos -> timestamp conversion */
static GstClockTime
granulepos_to_timestamp (GstTheoraEnc * theoraenc, ogg_int64_t granulepos)
{
  guint64 iframe, pframe;
  int shift = theoraenc->info.keyframe_granule_shift;

  if (granulepos < 0)
    return GST_CLOCK_TIME_NONE;

  iframe = granulepos >> shift;
  pframe = granulepos - (iframe << shift);

  /* num and den are 32 bit, so we can safely multiply with GST_SECOND */
  return gst_util_uint64_scale ((guint64) (iframe + pframe),
      GST_SECOND * theoraenc->info.fps_denominator,
      theoraenc->info.fps_numerator);
}

static GstStaticPadTemplate theora_enc_sink_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-raw, "
        "format = (string) { I420, Y42B, Y444 }, "
        "framerate = (fraction) [1/MAX, MAX], "
        "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
    );

static GstStaticPadTemplate theora_enc_src_factory =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-theora, "
        "framerate = (fraction) [1/MAX, MAX], "
        "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
    );

#define gst_theora_enc_parent_class parent_class
G_DEFINE_TYPE (GstTheoraEnc, gst_theora_enc, GST_TYPE_VIDEO_ENCODER);

static gboolean theora_enc_start (GstVideoEncoder * enc);
static gboolean theora_enc_stop (GstVideoEncoder * enc);
static gboolean theora_enc_set_format (GstVideoEncoder * enc,
    GstVideoCodecState * state);
static GstFlowReturn theora_enc_handle_frame (GstVideoEncoder * enc,
    GstVideoCodecFrame * frame);
static GstFlowReturn theora_enc_pre_push (GstVideoEncoder * benc,
    GstVideoCodecFrame * frame);
static GstFlowReturn theora_enc_finish (GstVideoEncoder * enc);
static gboolean theora_enc_propose_allocation (GstVideoEncoder * encoder,
    GstQuery * query);

static GstCaps *theora_enc_getcaps (GstVideoEncoder * encoder,
    GstCaps * filter);
static void theora_enc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void theora_enc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void theora_enc_finalize (GObject * object);

static gboolean theora_enc_write_multipass_cache (GstTheoraEnc * enc,
    gboolean begin, gboolean eos);

static void
gst_theora_enc_class_init (GstTheoraEncClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *element_class = (GstElementClass *) klass;
  GstVideoEncoderClass *gstvideo_encoder_class =
      GST_VIDEO_ENCODER_CLASS (klass);

  gobject_class->set_property = theora_enc_set_property;
  gobject_class->get_property = theora_enc_get_property;
  gobject_class->finalize = theora_enc_finalize;

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&theora_enc_src_factory));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&theora_enc_sink_factory));
  gst_element_class_set_static_metadata (element_class,
      "Theora video encoder", "Codec/Encoder/Video",
      "encode raw YUV video to a theora stream",
      "Wim Taymans <wim@fluendo.com>");

  gstvideo_encoder_class->start = GST_DEBUG_FUNCPTR (theora_enc_start);
  gstvideo_encoder_class->stop = GST_DEBUG_FUNCPTR (theora_enc_stop);
  gstvideo_encoder_class->set_format =
      GST_DEBUG_FUNCPTR (theora_enc_set_format);
  gstvideo_encoder_class->handle_frame =
      GST_DEBUG_FUNCPTR (theora_enc_handle_frame);
  gstvideo_encoder_class->pre_push = GST_DEBUG_FUNCPTR (theora_enc_pre_push);
  gstvideo_encoder_class->finish = GST_DEBUG_FUNCPTR (theora_enc_finish);
  gstvideo_encoder_class->getcaps = GST_DEBUG_FUNCPTR (theora_enc_getcaps);
  gstvideo_encoder_class->propose_allocation =
      GST_DEBUG_FUNCPTR (theora_enc_propose_allocation);

  /* general encoding stream options */
  g_object_class_install_property (gobject_class, PROP_BITRATE,
      g_param_spec_int ("bitrate", "Bitrate", "Compressed video bitrate (kbps)",
          0, (1 << 24) - 1, THEORA_DEF_BITRATE,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
          GST_PARAM_MUTABLE_PLAYING));
  g_object_class_install_property (gobject_class, PROP_QUALITY,
      g_param_spec_int ("quality", "Quality", "Video quality", 0, 63,
          THEORA_DEF_QUALITY,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
          GST_PARAM_MUTABLE_PLAYING));
  g_object_class_install_property (gobject_class, PROP_KEYFRAME_AUTO,
      g_param_spec_boolean ("keyframe-auto", "Keyframe Auto",
          "Automatic keyframe detection", THEORA_DEF_KEYFRAME_AUTO,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_KEYFRAME_FREQ,
      g_param_spec_int ("keyframe-freq", "Keyframe frequency",
          "Keyframe frequency", 1, 32768, THEORA_DEF_KEYFRAME_FREQ,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_KEYFRAME_FREQ_FORCE,
      g_param_spec_int ("keyframe-force", "Keyframe force",
          "Force keyframe every N frames", 1, 32768,
          THEORA_DEF_KEYFRAME_FREQ_FORCE,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_SPEEDLEVEL,
      g_param_spec_int ("speed-level", "Speed level",
          "Controls the amount of motion vector searching done while encoding",
          0, 3, THEORA_DEF_SPEEDLEVEL,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_VP3_COMPATIBLE,
      g_param_spec_boolean ("vp3-compatible", "VP3 compatible",
          "Disables non-VP3 compatible features",
          THEORA_DEF_VP3_COMPATIBLE,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_DROP_FRAMES,
      g_param_spec_boolean ("drop-frames", "Drop frames",
          "Allow or disallow frame dropping",
          THEORA_DEF_DROP_FRAMES,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_CAP_OVERFLOW,
      g_param_spec_boolean ("cap-overflow", "Cap overflow",
          "Enable capping of bit reservoir overflows",
          THEORA_DEF_CAP_OVERFLOW,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_CAP_UNDERFLOW,
      g_param_spec_boolean ("cap-underflow", "Cap underflow",
          "Enable capping of bit reservoir underflows",
          THEORA_DEF_CAP_UNDERFLOW,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_RATE_BUFFER,
      g_param_spec_int ("rate-buffer", "Rate Control Buffer",
          "Sets the size of the rate control buffer, in units of frames.  "
          "The default value of 0 instructs the encoder to automatically "
          "select an appropriate value",
          0, 1000, THEORA_DEF_RATE_BUFFER,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_MULTIPASS_CACHE_FILE,
      g_param_spec_string ("multipass-cache-file", "Multipass Cache File",
          "Multipass cache file", THEORA_DEF_MULTIPASS_CACHE_FILE,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_MULTIPASS_MODE,
      g_param_spec_enum ("multipass-mode", "Multipass mode",
          "Single pass or first/second pass", GST_TYPE_MULTIPASS_MODE,
          THEORA_DEF_MULTIPASS_MODE,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  GST_DEBUG_CATEGORY_INIT (theoraenc_debug, "theoraenc", 0, "Theora encoder");
}

static void
gst_theora_enc_init (GstTheoraEnc * enc)
{
  enc->video_bitrate = THEORA_DEF_BITRATE;
  enc->video_quality = THEORA_DEF_QUALITY;
  enc->keyframe_auto = THEORA_DEF_KEYFRAME_AUTO;
  enc->keyframe_freq = THEORA_DEF_KEYFRAME_FREQ;
  enc->keyframe_force = THEORA_DEF_KEYFRAME_FREQ_FORCE;

  enc->speed_level = THEORA_DEF_SPEEDLEVEL;
  enc->vp3_compatible = THEORA_DEF_VP3_COMPATIBLE;
  enc->drop_frames = THEORA_DEF_DROP_FRAMES;
  enc->cap_overflow = THEORA_DEF_CAP_OVERFLOW;
  enc->cap_underflow = THEORA_DEF_CAP_UNDERFLOW;
  enc->rate_buffer = THEORA_DEF_RATE_BUFFER;

  enc->multipass_mode = THEORA_DEF_MULTIPASS_MODE;
  enc->multipass_cache_file = THEORA_DEF_MULTIPASS_CACHE_FILE;
}

static void
theora_enc_clear_multipass_cache (GstTheoraEnc * enc)
{
  if (enc->multipass_cache_fd) {
    g_io_channel_shutdown (enc->multipass_cache_fd, TRUE, NULL);
    g_io_channel_unref (enc->multipass_cache_fd);
    enc->multipass_cache_fd = NULL;
  }

  if (enc->multipass_cache_adapter) {
    gst_object_unref (enc->multipass_cache_adapter);
    enc->multipass_cache_adapter = NULL;
  }
}

static void
theora_enc_finalize (GObject * object)
{
  GstTheoraEnc *enc = GST_THEORA_ENC (object);

  GST_DEBUG_OBJECT (enc, "Finalizing");
  if (enc->encoder)
    th_encode_free (enc->encoder);
  th_comment_clear (&enc->comment);
  th_info_clear (&enc->info);
  g_free (enc->multipass_cache_file);

  theora_enc_clear_multipass_cache (enc);

  if (enc->input_state)
    gst_video_codec_state_unref (enc->input_state);

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

static void
theora_enc_reset (GstTheoraEnc * enc)
{
  ogg_uint32_t keyframe_force;
  int rate_flags;

  GST_OBJECT_LOCK (enc);
  enc->info.target_bitrate = enc->video_bitrate;
  enc->info.quality = enc->video_quality;
  enc->bitrate_changed = FALSE;
  enc->quality_changed = FALSE;
  GST_OBJECT_UNLOCK (enc);

  if (enc->encoder)
    th_encode_free (enc->encoder);
  enc->encoder = th_encode_alloc (&enc->info);
  /* We ensure this function cannot fail. */
  g_assert (enc->encoder != NULL);
  th_encode_ctl (enc->encoder, TH_ENCCTL_SET_SPLEVEL, &enc->speed_level,
      sizeof (enc->speed_level));
  th_encode_ctl (enc->encoder, TH_ENCCTL_SET_VP3_COMPATIBLE,
      &enc->vp3_compatible, sizeof (enc->vp3_compatible));

  rate_flags = 0;
  if (enc->drop_frames)
    rate_flags |= TH_RATECTL_DROP_FRAMES;
  if (enc->drop_frames)
    rate_flags |= TH_RATECTL_CAP_OVERFLOW;
  if (enc->drop_frames)
    rate_flags |= TH_RATECTL_CAP_UNDERFLOW;
  th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_FLAGS,
      &rate_flags, sizeof (rate_flags));

  if (enc->rate_buffer) {
    th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_BUFFER,
        &enc->rate_buffer, sizeof (enc->rate_buffer));
  } else {
    /* FIXME */
  }

  keyframe_force = enc->keyframe_auto ?
      enc->keyframe_force : enc->keyframe_freq;
  th_encode_ctl (enc->encoder, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
      &keyframe_force, sizeof (keyframe_force));

  /* Get placeholder data */
  if (enc->multipass_cache_fd
      && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS)
    theora_enc_write_multipass_cache (enc, TRUE, FALSE);
}

static gboolean
theora_enc_start (GstVideoEncoder * benc)
{
  GstTheoraEnc *enc;

  GST_DEBUG_OBJECT (benc, "start: init theora");
  enc = GST_THEORA_ENC (benc);

  th_info_init (&enc->info);
  th_comment_init (&enc->comment);
  enc->packetno = 0;

  if (enc->multipass_mode >= MULTIPASS_MODE_FIRST_PASS) {
    GError *err = NULL;

    if (!enc->multipass_cache_file) {
      GST_ELEMENT_ERROR (enc, LIBRARY, SETTINGS, (NULL), (NULL));
      return FALSE;
    }
    enc->multipass_cache_fd =
        g_io_channel_new_file (enc->multipass_cache_file,
        (enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS ? "w" : "r"), &err);

    if (enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS)
      enc->multipass_cache_adapter = gst_adapter_new ();

    if (!enc->multipass_cache_fd) {
      GST_ELEMENT_ERROR (enc, RESOURCE, OPEN_READ, (NULL),
          ("Failed to open multipass cache file: %s", err->message));
      g_error_free (err);
      return FALSE;
    }

    g_io_channel_set_encoding (enc->multipass_cache_fd, NULL, NULL);
  }

  return TRUE;
}

static gboolean
theora_enc_stop (GstVideoEncoder * benc)
{
  GstTheoraEnc *enc;

  GST_DEBUG_OBJECT (benc, "stop: clearing theora state");
  enc = GST_THEORA_ENC (benc);

  if (enc->encoder) {
    th_encode_free (enc->encoder);
    enc->encoder = NULL;
  }
  th_comment_clear (&enc->comment);
  th_info_clear (&enc->info);

  enc->initialised = FALSE;

  return TRUE;
}

static char *
theora_enc_get_supported_formats (void)
{
  th_enc_ctx *encoder;
  th_info info;
  struct
  {
    th_pixel_fmt pixelformat;
    const char *fourcc;
  } formats[] = {
    {
    TH_PF_420, "I420"}, {
    TH_PF_422, "Y42B"}, {
    TH_PF_444, "Y444"}
  };
  GString *string = NULL;
  guint i;

  th_info_init (&info);
  info.frame_width = 16;
  info.frame_height = 16;
  info.fps_numerator = 25;
  info.fps_denominator = 1;
  for (i = 0; i < G_N_ELEMENTS (formats); i++) {
    info.pixel_fmt = formats[i].pixelformat;

    encoder = th_encode_alloc (&info);
    if (encoder == NULL)
      continue;

    GST_LOG ("format %s is supported", formats[i].fourcc);
    th_encode_free (encoder);

    if (string == NULL) {
      string = g_string_new (formats[i].fourcc);
    } else {
      g_string_append (string, ", ");
      g_string_append (string, formats[i].fourcc);
    }
  }
  th_info_clear (&info);

  return string == NULL ? NULL : g_string_free (string, FALSE);
}

static GstCaps *
theora_enc_getcaps (GstVideoEncoder * encoder, GstCaps * filter)
{
  GstCaps *caps, *ret;
  char *supported_formats, *caps_string;

  supported_formats = theora_enc_get_supported_formats ();
  if (!supported_formats) {
    GST_WARNING ("no supported formats found. Encoder disabled?");
    return gst_caps_new_empty ();
  }

  caps_string = g_strdup_printf ("video/x-raw, "
      "format = (string) { %s }, "
      "framerate = (fraction) [1/MAX, MAX], "
      "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]",
      supported_formats);
  caps = gst_caps_from_string (caps_string);
  g_free (caps_string);
  g_free (supported_formats);
  GST_DEBUG ("Supported caps: %" GST_PTR_FORMAT, caps);

  ret = gst_video_encoder_proxy_getcaps (encoder, caps, filter);
  gst_caps_unref (caps);

  return ret;
}

static gboolean
theora_enc_set_format (GstVideoEncoder * benc, GstVideoCodecState * state)
{
  GstTheoraEnc *enc = GST_THEORA_ENC (benc);
  GstVideoInfo *info = &state->info;

  enc->width = GST_VIDEO_INFO_WIDTH (info);
  enc->height = GST_VIDEO_INFO_HEIGHT (info);

  th_info_clear (&enc->info);
  th_info_init (&enc->info);
  /* Theora has a divisible-by-sixteen restriction for the encoded video size but
   * we can define a picture area using pic_width/pic_height */
  enc->info.frame_width = GST_ROUND_UP_16 (enc->width);
  enc->info.frame_height = GST_ROUND_UP_16 (enc->height);
  enc->info.pic_width = enc->width;
  enc->info.pic_height = enc->height;
  switch (GST_VIDEO_INFO_FORMAT (info)) {
    case GST_VIDEO_FORMAT_I420:
      enc->info.pixel_fmt = TH_PF_420;
      break;
    case GST_VIDEO_FORMAT_Y42B:
      enc->info.pixel_fmt = TH_PF_422;
      break;
    case GST_VIDEO_FORMAT_Y444:
      enc->info.pixel_fmt = TH_PF_444;
      break;
    default:
      g_assert_not_reached ();
  }

  enc->info.fps_numerator = enc->fps_n = GST_VIDEO_INFO_FPS_N (info);
  enc->info.fps_denominator = enc->fps_d = GST_VIDEO_INFO_FPS_D (info);
  enc->info.aspect_numerator = GST_VIDEO_INFO_PAR_N (info);
  enc->info.aspect_denominator = GST_VIDEO_INFO_PAR_D (info);

  enc->info.colorspace = TH_CS_UNSPECIFIED;

  /* Save input state */
  if (enc->input_state)
    gst_video_codec_state_unref (enc->input_state);
  enc->input_state = gst_video_codec_state_ref (state);

  /* as done in theora */
  enc->info.keyframe_granule_shift = _ilog (enc->keyframe_force - 1);
  GST_DEBUG_OBJECT (enc,
      "keyframe_frequency_force is %d, granule shift is %d",
      enc->keyframe_force, enc->info.keyframe_granule_shift);

  theora_enc_reset (enc);
  enc->initialised = TRUE;

  return TRUE;
}

static GstFlowReturn
theora_enc_pre_push (GstVideoEncoder * benc, GstVideoCodecFrame * frame)
{
  GstTheoraEnc *enc = GST_THEORA_ENC (benc);
  guint64 pfn;

  /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
   * time representation */
  /* granulepos from sync frame */
  pfn = frame->presentation_frame_number - frame->distance_from_sync;
  /* correct to correspond to linear running time */
  pfn -= enc->pfn_offset;
  pfn += enc->granulepos_offset + 1;
  /* granulepos */
  GST_BUFFER_OFFSET_END (frame->output_buffer) =
      (pfn << enc->info.keyframe_granule_shift) + frame->distance_from_sync;
  GST_BUFFER_OFFSET (frame->output_buffer) = granulepos_to_timestamp (enc,
      GST_BUFFER_OFFSET_END (frame->output_buffer));

  return GST_FLOW_OK;
}

static GstFlowReturn
theora_push_packet (GstTheoraEnc * enc, ogg_packet * packet)
{
  GstVideoEncoder *benc;
  GstFlowReturn ret;
  GstVideoCodecFrame *frame;

  benc = GST_VIDEO_ENCODER (enc);

  frame = gst_video_encoder_get_oldest_frame (benc);
  if (gst_video_encoder_allocate_output_frame (benc, frame,
          packet->bytes) != GST_FLOW_OK) {
    GST_WARNING_OBJECT (enc, "Could not allocate buffer");
    gst_video_codec_frame_unref (frame);
    ret = GST_FLOW_ERROR;
    goto done;
  }

  if (packet->bytes > 0)
    gst_buffer_fill (frame->output_buffer, 0, packet->packet, packet->bytes);

  /* the second most significant bit of the first data byte is cleared
   * for keyframes */
  if (packet->bytes > 0 && (packet->packet[0] & 0x40) == 0) {
    GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
  } else {
    GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT (frame);
  }
  enc->packetno++;

  ret = gst_video_encoder_finish_frame (benc, frame);

done:
  return ret;
}

static GstCaps *
theora_set_header_on_caps (GstCaps * caps, GList * buffers)
{
  GstStructure *structure;
  GValue array = { 0 };
  GValue value = { 0 };
  GstBuffer *buffer;
  GList *walk;

  caps = gst_caps_make_writable (caps);
  structure = gst_caps_get_structure (caps, 0);

  /* put copies of the buffers in a fixed list */
  g_value_init (&array, GST_TYPE_ARRAY);

  for (walk = buffers; walk; walk = walk->next) {
    buffer = walk->data;

    /* mark buffer */
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);

    /* Copy buffer, because we can't use the original -
     * it creates a circular refcount with the caps<->buffers */
    buffer = gst_buffer_copy (buffer);

    g_value_init (&value, GST_TYPE_BUFFER);
    gst_value_set_buffer (&value, buffer);
    gst_value_array_append_value (&array, &value);
    g_value_unset (&value);

    /* Unref our copy */
    gst_buffer_unref (buffer);
  }

  gst_structure_set_value (structure, "streamheader", &array);
  g_value_unset (&array);

  return caps;
}

static void
theora_enc_init_buffer (th_ycbcr_buffer buf, GstVideoFrame * frame)
{
  GstVideoInfo vinfo;
  guint i;

  /* According to Theora developer Timothy Terriberry, the Theora 
   * encoder will not use memory outside of pic_width/height, even when
   * the frame size is bigger. The values outside this region will be encoded
   * to default values.
   * Due to this, setting the frame's width/height as the buffer width/height
   * is perfectly ok, even though it does not strictly look ok.
   */

  gst_video_info_init (&vinfo);
  gst_video_info_set_format (&vinfo, GST_VIDEO_FRAME_FORMAT (frame),
      GST_ROUND_UP_16 (GST_VIDEO_FRAME_WIDTH (frame)),
      GST_ROUND_UP_16 (GST_VIDEO_FRAME_HEIGHT (frame)));

  for (i = 0; i < 3; i++) {
    buf[i].width = GST_VIDEO_INFO_COMP_WIDTH (&vinfo, i);
    buf[i].height = GST_VIDEO_INFO_COMP_HEIGHT (&vinfo, i);
    buf[i].data = GST_VIDEO_FRAME_COMP_DATA (frame, i);
    buf[i].stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
  }
}

static gboolean
theora_enc_read_multipass_cache (GstTheoraEnc * enc)
{
  GstBuffer *cache_buf;
  const guint8 *cache_data;
  gsize bytes_read = 0;
  gssize bytes_consumed = 0;
  GIOStatus stat = G_IO_STATUS_NORMAL;
  gboolean done = FALSE;

  while (!done) {
    if (gst_adapter_available (enc->multipass_cache_adapter) == 0) {
      GstMapInfo minfo;

      cache_buf = gst_buffer_new_allocate (NULL, 512, NULL);

      gst_buffer_map (cache_buf, &minfo, GST_MAP_WRITE);

      stat = g_io_channel_read_chars (enc->multipass_cache_fd,
          (gchar *) minfo.data, minfo.size, &bytes_read, NULL);

      if (bytes_read <= 0) {
        gst_buffer_unmap (cache_buf, &minfo);
        gst_buffer_unref (cache_buf);
        break;
      } else {
        gst_buffer_unmap (cache_buf, &minfo);
        gst_buffer_resize (cache_buf, 0, bytes_read);

        gst_adapter_push (enc->multipass_cache_adapter, cache_buf);
      }
    }
    if (gst_adapter_available (enc->multipass_cache_adapter) == 0)
      break;

    bytes_read =
        MIN (gst_adapter_available (enc->multipass_cache_adapter), 512);

    cache_data = gst_adapter_map (enc->multipass_cache_adapter, bytes_read);

    bytes_consumed =
        th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_IN, (guint8 *) cache_data,
        bytes_read);
    gst_adapter_unmap (enc->multipass_cache_adapter);

    done = bytes_consumed <= 0;
    if (bytes_consumed > 0)
      gst_adapter_flush (enc->multipass_cache_adapter, bytes_consumed);
  }

  if (stat == G_IO_STATUS_ERROR || (stat == G_IO_STATUS_EOF && bytes_read == 0)
      || bytes_consumed < 0) {
    GST_ELEMENT_ERROR (enc, RESOURCE, READ, (NULL),
        ("Failed to read multipass cache file"));
    return FALSE;
  }
  return TRUE;
}

static gboolean
theora_enc_write_multipass_cache (GstTheoraEnc * enc, gboolean begin,
    gboolean eos)
{
  GError *err = NULL;
  GIOStatus stat = G_IO_STATUS_NORMAL;
  gint bytes_read = 0;
  gsize bytes_written = 0;
  gchar *buf;

  if (begin) {
    stat = g_io_channel_seek_position (enc->multipass_cache_fd, 0, G_SEEK_SET,
        &err);

    if (stat == G_IO_STATUS_ERROR) {
      if (eos)
        GST_ELEMENT_WARNING (enc, RESOURCE, WRITE, (NULL),
            ("Failed to seek to beginning of multipass cache file: %s",
                err->message));
      else
        GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
            ("Failed to seek to beginning of multipass cache file: %s",
                err->message));
      g_error_free (err);
      return FALSE;
    }
  }


  do {
    bytes_read =
        th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_OUT, &buf, sizeof (buf));
    if (bytes_read > 0)
      g_io_channel_write_chars (enc->multipass_cache_fd, buf, bytes_read,
          &bytes_written, &err);
  } while (bytes_read > 0 && bytes_written > 0 && !err);

  if (bytes_read < 0 || err) {
    if (bytes_read < 0) {
      GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
          ("Failed to read multipass cache data: %d", bytes_read));
    } else {
      GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
          ("Failed to write multipass cache file: %s", err->message));
    }
    if (err)
      g_error_free (err);

    return FALSE;
  }

  return TRUE;
}

static void
theora_enc_reset_ts (GstTheoraEnc * enc, GstClockTime running_time, gint pfn)
{
  enc->granulepos_offset =
      gst_util_uint64_scale (running_time, enc->fps_n, GST_SECOND * enc->fps_d);
  enc->timestamp_offset = running_time;
  enc->pfn_offset = pfn;
}

static GstBuffer *
theora_enc_buffer_from_header_packet (GstTheoraEnc * enc, ogg_packet * packet)
{
  GstBuffer *outbuf;

  outbuf =
      gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER (enc),
      packet->bytes);
  gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
  GST_BUFFER_OFFSET (outbuf) = 0;
  GST_BUFFER_OFFSET_END (outbuf) = 0;
  GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
  GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;

  GST_DEBUG ("created header packet buffer, %u bytes",
      (guint) gst_buffer_get_size (outbuf));
  return outbuf;
}

static GstFlowReturn
theora_enc_handle_frame (GstVideoEncoder * benc, GstVideoCodecFrame * frame)
{
  GstTheoraEnc *enc;
  ogg_packet op;
  GstClockTime timestamp, running_time;
  GstFlowReturn ret;
  gboolean force_keyframe;

  enc = GST_THEORA_ENC (benc);

  /* we keep track of two timelines.
   * - The timestamps from the incomming buffers, which we copy to the outgoing
   *   encoded buffers as-is. We need to do this as we simply forward the
   *   newsegment events.
   * - The running_time of the buffers, which we use to construct the granulepos
   *   in the packets.
   */
  timestamp = frame->pts;

  /* incoming buffers are clipped, so this should be positive */
  running_time =
      gst_segment_to_running_time (&GST_VIDEO_ENCODER_INPUT_SEGMENT (enc),
      GST_FORMAT_TIME, timestamp);
  g_return_val_if_fail (running_time >= 0 || timestamp < 0, GST_FLOW_ERROR);

  GST_OBJECT_LOCK (enc);
  if (enc->bitrate_changed) {
    long int bitrate = enc->video_bitrate;

    th_encode_ctl (enc->encoder, TH_ENCCTL_SET_BITRATE, &bitrate,
        sizeof (long int));
    enc->bitrate_changed = FALSE;
  }

  if (enc->quality_changed) {
    long int quality = enc->video_quality;

    th_encode_ctl (enc->encoder, TH_ENCCTL_SET_QUALITY, &quality,
        sizeof (long int));
    enc->quality_changed = FALSE;
  }

  /* see if we need to schedule a keyframe */
  force_keyframe = GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame);
  GST_OBJECT_UNLOCK (enc);

  if (enc->packetno == 0) {
    /* no packets written yet, setup headers */
    GstCaps *caps;
    GstBuffer *buf;
    GList *buffers = NULL;
    int result;
    GstVideoCodecState *state;

    enc->granulepos_offset = 0;
    enc->timestamp_offset = 0;

    GST_DEBUG_OBJECT (enc, "output headers");
    /* Theora streams begin with three headers; the initial header (with
       most of the codec setup parameters) which is mandated by the Ogg
       bitstream spec.  The second header holds any comment fields.  The
       third header holds the bitstream codebook.  We merely need to
       make the headers, then pass them to libtheora one at a time;
       libtheora handles the additional Ogg bitstream constraints */

    /* create the remaining theora headers */
    th_comment_clear (&enc->comment);
    th_comment_init (&enc->comment);

    while ((result =
            th_encode_flushheader (enc->encoder, &enc->comment, &op)) > 0) {
      buf = theora_enc_buffer_from_header_packet (enc, &op);
      buffers = g_list_prepend (buffers, buf);
    }
    if (result < 0) {
      g_list_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
      g_list_free (buffers);
      goto encoder_disabled;
    }

    buffers = g_list_reverse (buffers);

    /* mark buffers and put on caps */
    caps = gst_caps_new_empty_simple ("video/x-theora");
    caps = theora_set_header_on_caps (caps, buffers);
    state = gst_video_encoder_set_output_state (benc, caps, enc->input_state);

    GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, state->caps);

    gst_video_codec_state_unref (state);

    gst_video_encoder_negotiate (GST_VIDEO_ENCODER (enc));

    gst_video_encoder_set_headers (benc, buffers);

    theora_enc_reset_ts (enc, running_time, frame->presentation_frame_number);
  }

  {
    th_ycbcr_buffer ycbcr;
    gint res;
    GstVideoFrame vframe;

    if (force_keyframe) {
      theora_enc_reset (enc);
      theora_enc_reset_ts (enc, running_time, frame->presentation_frame_number);
    }

    if (enc->multipass_cache_fd
        && enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS) {
      if (!theora_enc_read_multipass_cache (enc)) {
        ret = GST_FLOW_ERROR;
        goto multipass_read_failed;
      }
    }

    gst_video_frame_map (&vframe, &enc->input_state->info, frame->input_buffer,
        GST_MAP_READ);
    theora_enc_init_buffer (ycbcr, &vframe);

    res = th_encode_ycbcr_in (enc->encoder, ycbcr);
    gst_video_frame_unmap (&vframe);

    /* none of the failure cases can happen here */
    g_assert (res == 0);

    if (enc->multipass_cache_fd
        && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS) {
      if (!theora_enc_write_multipass_cache (enc, FALSE, FALSE)) {
        ret = GST_FLOW_ERROR;
        goto multipass_write_failed;
      }
    }

    ret = GST_FLOW_OK;
    while (th_encode_packetout (enc->encoder, 0, &op)) {
      ret = theora_push_packet (enc, &op);
      if (ret != GST_FLOW_OK)
        goto beach;
    }
  }

beach:
  gst_video_codec_frame_unref (frame);
  return ret;

  /* ERRORS */
multipass_read_failed:
  {
    gst_video_codec_frame_unref (frame);
    return ret;
  }
multipass_write_failed:
  {
    gst_video_codec_frame_unref (frame);
    return ret;
  }
encoder_disabled:
  {
    gst_video_codec_frame_unref (frame);
    GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
        ("libtheora has been compiled with the encoder disabled"));
    return GST_FLOW_ERROR;
  }
}

static gboolean
theora_enc_finish (GstVideoEncoder * benc)
{
  GstTheoraEnc *enc;
  ogg_packet op;

  enc = GST_THEORA_ENC (benc);

  if (enc->initialised) {
    /* push last packet with eos flag, should not be called */
    while (th_encode_packetout (enc->encoder, 1, &op)) {
      theora_push_packet (enc, &op);
    }
  }
  if (enc->initialised && enc->multipass_cache_fd
      && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS)
    theora_enc_write_multipass_cache (enc, TRUE, TRUE);

  theora_enc_clear_multipass_cache (enc);

  return TRUE;
}

static gboolean
theora_enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
{
  gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);

  return GST_VIDEO_ENCODER_CLASS (parent_class)->propose_allocation (encoder,
      query);
}

static void
theora_enc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstTheoraEnc *enc = GST_THEORA_ENC (object);

  switch (prop_id) {
    case PROP_BITRATE:
      GST_OBJECT_LOCK (enc);
      enc->video_bitrate = g_value_get_int (value) * 1000;
      enc->video_quality = 0;
      enc->bitrate_changed = TRUE;
      GST_OBJECT_UNLOCK (enc);
      break;
    case PROP_QUALITY:
      GST_OBJECT_LOCK (enc);
      if (GST_STATE (enc) >= GST_STATE_PAUSED && enc->video_quality == 0) {
        GST_WARNING_OBJECT (object, "Can't change from bitrate to quality mode"
            " while playing");
      } else {
        enc->video_quality = g_value_get_int (value);
        enc->video_bitrate = 0;
        enc->quality_changed = TRUE;
      }
      GST_OBJECT_UNLOCK (enc);
      break;
    case PROP_KEYFRAME_AUTO:
      enc->keyframe_auto = g_value_get_boolean (value);
      break;
    case PROP_KEYFRAME_FREQ:
      enc->keyframe_freq = g_value_get_int (value);
      break;
    case PROP_KEYFRAME_FREQ_FORCE:
      enc->keyframe_force = g_value_get_int (value);
      break;
    case PROP_SPEEDLEVEL:
      enc->speed_level = g_value_get_int (value);
      break;
    case PROP_VP3_COMPATIBLE:
      enc->vp3_compatible = g_value_get_boolean (value);
      break;
    case PROP_DROP_FRAMES:
      enc->drop_frames = g_value_get_boolean (value);
      break;
    case PROP_CAP_OVERFLOW:
      enc->cap_overflow = g_value_get_boolean (value);
      break;
    case PROP_CAP_UNDERFLOW:
      enc->cap_underflow = g_value_get_boolean (value);
      break;
    case PROP_RATE_BUFFER:
      enc->rate_buffer = g_value_get_int (value);
      break;
    case PROP_MULTIPASS_CACHE_FILE:
      enc->multipass_cache_file = g_value_dup_string (value);
      break;
    case PROP_MULTIPASS_MODE:
      enc->multipass_mode = g_value_get_enum (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
theora_enc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstTheoraEnc *enc = GST_THEORA_ENC (object);

  switch (prop_id) {
    case PROP_BITRATE:
      GST_OBJECT_LOCK (enc);
      g_value_set_int (value, enc->video_bitrate / 1000);
      GST_OBJECT_UNLOCK (enc);
      break;
    case PROP_QUALITY:
      GST_OBJECT_LOCK (enc);
      g_value_set_int (value, enc->video_quality);
      GST_OBJECT_UNLOCK (enc);
      break;
    case PROP_KEYFRAME_AUTO:
      g_value_set_boolean (value, enc->keyframe_auto);
      break;
    case PROP_KEYFRAME_FREQ:
      g_value_set_int (value, enc->keyframe_freq);
      break;
    case PROP_KEYFRAME_FREQ_FORCE:
      g_value_set_int (value, enc->keyframe_force);
      break;
    case PROP_SPEEDLEVEL:
      g_value_set_int (value, enc->speed_level);
      break;
    case PROP_VP3_COMPATIBLE:
      g_value_set_boolean (value, enc->vp3_compatible);
      break;
    case PROP_DROP_FRAMES:
      g_value_set_boolean (value, enc->drop_frames);
      break;
    case PROP_CAP_OVERFLOW:
      g_value_set_boolean (value, enc->cap_overflow);
      break;
    case PROP_CAP_UNDERFLOW:
      g_value_set_boolean (value, enc->cap_underflow);
      break;
    case PROP_RATE_BUFFER:
      g_value_set_int (value, enc->rate_buffer);
      break;
    case PROP_MULTIPASS_CACHE_FILE:
      g_value_set_string (value, enc->multipass_cache_file);
      break;
    case PROP_MULTIPASS_MODE:
      g_value_set_enum (value, enc->multipass_mode);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

gboolean
gst_theora_enc_register (GstPlugin * plugin)
{
  return gst_element_register (plugin, "theoraenc",
      GST_RANK_PRIMARY, GST_TYPE_THEORA_ENC);
}
