/* GStreamer Wavpack encoder plugin
 * Copyright (c) 2006 Sebastian Dröge <slomo@circular-chaos.org>
 *
 * gstwavpackdec.c: Wavpack audio encoder
 *
 * 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-wavpackenc
 *
 * WavpackEnc encodes raw audio into a framed Wavpack stream.
 * <ulink url="http://www.wavpack.com/">Wavpack</ulink> is an open-source
 * audio codec that features both lossless and lossy encoding.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch audiotestsrc num-buffers=500 ! audioconvert ! wavpackenc ! filesink location=sinewave.wv
 * ]| This pipeline encodes audio from audiotestsrc into a Wavpack file. The audioconvert element is needed
 * as the Wavpack encoder only accepts input with 32 bit width.
 * |[
 * gst-launch cdda://1 ! audioconvert ! wavpackenc ! filesink location=track1.wv
 * ]| This pipeline encodes audio from an audio CD into a Wavpack file using
 * lossless encoding (the file output will be fairly large).
 * |[
 * gst-launch cdda://1 ! audioconvert ! wavpackenc bitrate=128000 ! filesink location=track1.wv
 * ]| This pipeline encodes audio from an audio CD into a Wavpack file using
 * lossy encoding at a certain bitrate (the file will be fairly small).
 * </refsect2>
 */

/*
 * TODO: - add 32 bit float mode. CONFIG_FLOAT_DATA
 */

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

#include <wavpack/wavpack.h>
#include "gstwavpackenc.h"
#include "gstwavpackcommon.h"

static gboolean gst_wavpack_enc_start (GstAudioEncoder * enc);
static gboolean gst_wavpack_enc_stop (GstAudioEncoder * enc);
static gboolean gst_wavpack_enc_set_format (GstAudioEncoder * enc,
    GstAudioInfo * info);
static GstFlowReturn gst_wavpack_enc_handle_frame (GstAudioEncoder * enc,
    GstBuffer * in_buf);
static gboolean gst_wavpack_enc_sink_event (GstAudioEncoder * enc,
    GstEvent * event);

static int gst_wavpack_enc_push_block (void *id, void *data, int32_t count);
static GstFlowReturn gst_wavpack_enc_drain (GstWavpackEnc * enc);

static void gst_wavpack_enc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_wavpack_enc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

enum
{
  ARG_0,
  ARG_MODE,
  ARG_BITRATE,
  ARG_BITSPERSAMPLE,
  ARG_CORRECTION_MODE,
  ARG_MD5,
  ARG_EXTRA_PROCESSING,
  ARG_JOINT_STEREO_MODE
};

GST_DEBUG_CATEGORY_STATIC (gst_wavpack_enc_debug);
#define GST_CAT_DEFAULT gst_wavpack_enc_debug

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) " GST_AUDIO_NE (S32) ", "
        "layout = (string) interleaved, "
        "channels = (int) [ 1, 8 ], " "rate = (int) [ 6000, 192000 ]")
    );

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-wavpack, "
        "depth = (int) [ 1, 32 ], "
        "channels = (int) [ 1, 8 ], "
        "rate = (int) [ 6000, 192000 ], " "framed = (boolean) TRUE")
    );

static GstStaticPadTemplate wvcsrc_factory = GST_STATIC_PAD_TEMPLATE ("wvcsrc",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS ("audio/x-wavpack-correction, " "framed = (boolean) TRUE")
    );

enum
{
  GST_WAVPACK_ENC_MODE_VERY_FAST = 0,
  GST_WAVPACK_ENC_MODE_FAST,
  GST_WAVPACK_ENC_MODE_DEFAULT,
  GST_WAVPACK_ENC_MODE_HIGH,
  GST_WAVPACK_ENC_MODE_VERY_HIGH
};

#define GST_TYPE_WAVPACK_ENC_MODE (gst_wavpack_enc_mode_get_type ())
static GType
gst_wavpack_enc_mode_get_type (void)
{
  static GType qtype = 0;

  if (qtype == 0) {
    static const GEnumValue values[] = {
#if 0
      /* Very Fast Compression is not supported yet, but will be supported
       * in future wavpack versions */
      {GST_WAVPACK_ENC_MODE_VERY_FAST, "Very Fast Compression", "veryfast"},
#endif
      {GST_WAVPACK_ENC_MODE_FAST, "Fast Compression", "fast"},
      {GST_WAVPACK_ENC_MODE_DEFAULT, "Normal Compression", "normal"},
      {GST_WAVPACK_ENC_MODE_HIGH, "High Compression", "high"},
#ifndef WAVPACK_OLD_API
      {GST_WAVPACK_ENC_MODE_VERY_HIGH, "Very High Compression", "veryhigh"},
#endif
      {0, NULL, NULL}
    };

    qtype = g_enum_register_static ("GstWavpackEncMode", values);
  }
  return qtype;
}

enum
{
  GST_WAVPACK_CORRECTION_MODE_OFF = 0,
  GST_WAVPACK_CORRECTION_MODE_ON,
  GST_WAVPACK_CORRECTION_MODE_OPTIMIZED
};

#define GST_TYPE_WAVPACK_ENC_CORRECTION_MODE (gst_wavpack_enc_correction_mode_get_type ())
static GType
gst_wavpack_enc_correction_mode_get_type (void)
{
  static GType qtype = 0;

  if (qtype == 0) {
    static const GEnumValue values[] = {
      {GST_WAVPACK_CORRECTION_MODE_OFF, "Create no correction file", "off"},
      {GST_WAVPACK_CORRECTION_MODE_ON, "Create correction file", "on"},
      {GST_WAVPACK_CORRECTION_MODE_OPTIMIZED,
          "Create optimized correction file", "optimized"},
      {0, NULL, NULL}
    };

    qtype = g_enum_register_static ("GstWavpackEncCorrectionMode", values);
  }
  return qtype;
}

enum
{
  GST_WAVPACK_JS_MODE_AUTO = 0,
  GST_WAVPACK_JS_MODE_LEFT_RIGHT,
  GST_WAVPACK_JS_MODE_MID_SIDE
};

#define GST_TYPE_WAVPACK_ENC_JOINT_STEREO_MODE (gst_wavpack_enc_joint_stereo_mode_get_type ())
static GType
gst_wavpack_enc_joint_stereo_mode_get_type (void)
{
  static GType qtype = 0;

  if (qtype == 0) {
    static const GEnumValue values[] = {
      {GST_WAVPACK_JS_MODE_AUTO, "auto", "auto"},
      {GST_WAVPACK_JS_MODE_LEFT_RIGHT, "left/right", "leftright"},
      {GST_WAVPACK_JS_MODE_MID_SIDE, "mid/side", "midside"},
      {0, NULL, NULL}
    };

    qtype = g_enum_register_static ("GstWavpackEncJSMode", values);
  }
  return qtype;
}

#define gst_wavpack_enc_parent_class parent_class
G_DEFINE_TYPE (GstWavpackEnc, gst_wavpack_enc, GST_TYPE_AUDIO_ENCODER);

static void
gst_wavpack_enc_class_init (GstWavpackEncClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *element_class = (GstElementClass *) (klass);
  GstAudioEncoderClass *base_class = (GstAudioEncoderClass *) (klass);

  /* add pad templates */
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_factory));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_factory));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&wvcsrc_factory));

  /* set element details */
  gst_element_class_set_static_metadata (element_class, "Wavpack audio encoder",
      "Codec/Encoder/Audio",
      "Encodes audio with the Wavpack lossless/lossy audio codec",
      "Sebastian Dröge <slomo@circular-chaos.org>");

  /* set property handlers */
  gobject_class->set_property = gst_wavpack_enc_set_property;
  gobject_class->get_property = gst_wavpack_enc_get_property;

  base_class->start = GST_DEBUG_FUNCPTR (gst_wavpack_enc_start);
  base_class->stop = GST_DEBUG_FUNCPTR (gst_wavpack_enc_stop);
  base_class->set_format = GST_DEBUG_FUNCPTR (gst_wavpack_enc_set_format);
  base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_wavpack_enc_handle_frame);
  base_class->sink_event = GST_DEBUG_FUNCPTR (gst_wavpack_enc_sink_event);

  /* install all properties */
  g_object_class_install_property (gobject_class, ARG_MODE,
      g_param_spec_enum ("mode", "Encoding mode",
          "Speed versus compression tradeoff.",
          GST_TYPE_WAVPACK_ENC_MODE, GST_WAVPACK_ENC_MODE_DEFAULT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, ARG_BITRATE,
      g_param_spec_uint ("bitrate", "Bitrate",
          "Try to encode with this average bitrate (bits/sec). "
          "This enables lossy encoding, values smaller than 24000 disable it again.",
          0, 9600000, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, ARG_BITSPERSAMPLE,
      g_param_spec_double ("bits-per-sample", "Bits per sample",
          "Try to encode with this amount of bits per sample. "
          "This enables lossy encoding, values smaller than 2.0 disable it again.",
          0.0, 24.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, ARG_CORRECTION_MODE,
      g_param_spec_enum ("correction-mode", "Correction stream mode",
          "Use this mode for the correction stream. Only works in lossy mode!",
          GST_TYPE_WAVPACK_ENC_CORRECTION_MODE, GST_WAVPACK_CORRECTION_MODE_OFF,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, ARG_MD5,
      g_param_spec_boolean ("md5", "MD5",
          "Store MD5 hash of raw samples within the file.", FALSE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, ARG_EXTRA_PROCESSING,
      g_param_spec_uint ("extra-processing", "Extra processing",
          "Use better but slower filters for better compression/quality.",
          0, 6, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, ARG_JOINT_STEREO_MODE,
      g_param_spec_enum ("joint-stereo-mode", "Joint-Stereo mode",
          "Use this joint-stereo mode.", GST_TYPE_WAVPACK_ENC_JOINT_STEREO_MODE,
          GST_WAVPACK_JS_MODE_AUTO,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_wavpack_enc_reset (GstWavpackEnc * enc)
{
  /* close and free everything stream related if we already did something */
  if (enc->wp_context) {
    WavpackCloseFile (enc->wp_context);
    enc->wp_context = NULL;
  }
  if (enc->wp_config) {
    g_free (enc->wp_config);
    enc->wp_config = NULL;
  }
  if (enc->first_block) {
    g_free (enc->first_block);
    enc->first_block = NULL;
  }
  enc->first_block_size = 0;
  if (enc->md5_context) {
    g_checksum_free (enc->md5_context);
    enc->md5_context = NULL;
  }
  if (enc->pending_segment)
    gst_event_unref (enc->pending_segment);
  enc->pending_segment = NULL;

  if (enc->pending_buffer) {
    gst_buffer_unref (enc->pending_buffer);
    enc->pending_buffer = NULL;
    enc->pending_offset = 0;
  }

  /* reset the last returns to GST_FLOW_OK. This is only set to something else
   * while WavpackPackSamples() or more specific gst_wavpack_enc_push_block()
   * so not valid anymore */
  enc->srcpad_last_return = enc->wvcsrcpad_last_return = GST_FLOW_OK;

  /* reset stream information */
  enc->samplerate = 0;
  enc->depth = 0;
  enc->channels = 0;
  enc->channel_mask = 0;
  enc->need_channel_remap = FALSE;

  enc->timestamp_offset = GST_CLOCK_TIME_NONE;
  enc->next_ts = GST_CLOCK_TIME_NONE;
}

static void
gst_wavpack_enc_init (GstWavpackEnc * enc)
{
  GstAudioEncoder *benc = GST_AUDIO_ENCODER (enc);

  /* initialize object attributes */
  enc->wp_config = NULL;
  enc->wp_context = NULL;
  enc->first_block = NULL;
  enc->md5_context = NULL;
  gst_wavpack_enc_reset (enc);

  enc->wv_id.correction = FALSE;
  enc->wv_id.wavpack_enc = enc;
  enc->wv_id.passthrough = FALSE;
  enc->wvc_id.correction = TRUE;
  enc->wvc_id.wavpack_enc = enc;
  enc->wvc_id.passthrough = FALSE;

  /* set default values of params */
  enc->mode = GST_WAVPACK_ENC_MODE_DEFAULT;
  enc->bitrate = 0;
  enc->bps = 0.0;
  enc->correction_mode = GST_WAVPACK_CORRECTION_MODE_OFF;
  enc->md5 = FALSE;
  enc->extra_processing = 0;
  enc->joint_stereo_mode = GST_WAVPACK_JS_MODE_AUTO;

  /* require perfect ts */
  gst_audio_encoder_set_perfect_timestamp (benc, TRUE);
}


static gboolean
gst_wavpack_enc_start (GstAudioEncoder * enc)
{
  GST_DEBUG_OBJECT (enc, "start");

  return TRUE;
}

static gboolean
gst_wavpack_enc_stop (GstAudioEncoder * enc)
{
  GstWavpackEnc *wpenc = GST_WAVPACK_ENC (enc);

  GST_DEBUG_OBJECT (enc, "stop");
  gst_wavpack_enc_reset (wpenc);

  return TRUE;
}

static gboolean
gst_wavpack_enc_set_format (GstAudioEncoder * benc, GstAudioInfo * info)
{
  GstWavpackEnc *enc = GST_WAVPACK_ENC (benc);
  GstAudioChannelPosition *pos;
  GstAudioChannelPosition opos[64] = { GST_AUDIO_CHANNEL_POSITION_INVALID, };
  GstCaps *caps;
  guint64 mask = 0;

  /* we may be configured again, but that change should have cleanup context */
  g_assert (enc->wp_context == NULL);

  enc->channels = GST_AUDIO_INFO_CHANNELS (info);
  enc->depth = GST_AUDIO_INFO_DEPTH (info);
  enc->samplerate = GST_AUDIO_INFO_RATE (info);

  pos = info->position;
  g_assert (pos);

  /* If one channel is NONE they'll be all undefined */
  if (pos != NULL && pos[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
    goto invalid_channels;
  }

  enc->channel_mask =
      gst_wavpack_get_channel_mask_from_positions (pos, enc->channels);
  enc->need_channel_remap =
      gst_wavpack_set_channel_mapping (pos, enc->channels,
      enc->channel_mapping);

  /* wavpack caps hold gst mask, not wavpack mask */
  gst_audio_channel_positions_to_mask (opos, enc->channels, FALSE, &mask);

  /* set fixed src pad caps now that we know what we will get */
  caps = gst_caps_new_simple ("audio/x-wavpack",
      "channels", G_TYPE_INT, enc->channels,
      "rate", G_TYPE_INT, enc->samplerate,
      "depth", G_TYPE_INT, enc->depth, "framed", G_TYPE_BOOLEAN, TRUE, NULL);

  if (mask)
    gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, mask, NULL);

  if (!gst_audio_encoder_set_output_format (benc, caps))
    goto setting_src_caps_failed;

  gst_caps_unref (caps);

  /* no special feedback to base class; should provide all available samples */

  return TRUE;

  /* ERRORS */
setting_src_caps_failed:
  {
    GST_DEBUG_OBJECT (enc,
        "Couldn't set caps on source pad: %" GST_PTR_FORMAT, caps);
    gst_caps_unref (caps);
    return FALSE;
  }
invalid_channels:
  {
    GST_DEBUG_OBJECT (enc, "input has invalid channel layout");
    return FALSE;
  }
}

static void
gst_wavpack_enc_set_wp_config (GstWavpackEnc * enc)
{
  enc->wp_config = g_new0 (WavpackConfig, 1);
  /* set general stream informations in the WavpackConfig */
  enc->wp_config->bytes_per_sample = GST_ROUND_UP_8 (enc->depth) / 8;
  enc->wp_config->bits_per_sample = enc->depth;
  enc->wp_config->num_channels = enc->channels;
  enc->wp_config->channel_mask = enc->channel_mask;
  enc->wp_config->sample_rate = enc->samplerate;

  /*
   * Set parameters in WavpackConfig
   */

  /* Encoding mode */
  switch (enc->mode) {
#if 0
    case GST_WAVPACK_ENC_MODE_VERY_FAST:
      enc->wp_config->flags |= CONFIG_VERY_FAST_FLAG;
      enc->wp_config->flags |= CONFIG_FAST_FLAG;
      break;
#endif
    case GST_WAVPACK_ENC_MODE_FAST:
      enc->wp_config->flags |= CONFIG_FAST_FLAG;
      break;
    case GST_WAVPACK_ENC_MODE_DEFAULT:
      break;
    case GST_WAVPACK_ENC_MODE_HIGH:
      enc->wp_config->flags |= CONFIG_HIGH_FLAG;
      break;
#ifndef WAVPACK_OLD_API
    case GST_WAVPACK_ENC_MODE_VERY_HIGH:
      enc->wp_config->flags |= CONFIG_HIGH_FLAG;
      enc->wp_config->flags |= CONFIG_VERY_HIGH_FLAG;
      break;
#endif
  }

  /* Bitrate, enables lossy mode */
  if (enc->bitrate) {
    enc->wp_config->flags |= CONFIG_HYBRID_FLAG;
    enc->wp_config->flags |= CONFIG_BITRATE_KBPS;
    enc->wp_config->bitrate = enc->bitrate / 1000.0;
  } else if (enc->bps) {
    enc->wp_config->flags |= CONFIG_HYBRID_FLAG;
    enc->wp_config->bitrate = enc->bps;
  }

  /* Correction Mode, only in lossy mode */
  if (enc->wp_config->flags & CONFIG_HYBRID_FLAG) {
    if (enc->correction_mode > GST_WAVPACK_CORRECTION_MODE_OFF) {
      GstCaps *caps = gst_caps_new_simple ("audio/x-wavpack-correction",
          "framed", G_TYPE_BOOLEAN, TRUE, NULL);

      enc->wvcsrcpad =
          gst_pad_new_from_static_template (&wvcsrc_factory, "wvcsrc");

      /* try to add correction src pad, don't set correction mode on failure */
      GST_DEBUG_OBJECT (enc, "Adding correction pad with caps %"
          GST_PTR_FORMAT, caps);
      if (!gst_pad_set_caps (enc->wvcsrcpad, caps)) {
        enc->correction_mode = 0;
        GST_WARNING_OBJECT (enc, "setting correction caps failed");
      } else {
        gst_pad_use_fixed_caps (enc->wvcsrcpad);
        gst_pad_set_active (enc->wvcsrcpad, TRUE);
        gst_element_add_pad (GST_ELEMENT (enc), enc->wvcsrcpad);
        enc->wp_config->flags |= CONFIG_CREATE_WVC;
        if (enc->correction_mode == GST_WAVPACK_CORRECTION_MODE_OPTIMIZED) {
          enc->wp_config->flags |= CONFIG_OPTIMIZE_WVC;
        }
      }
      gst_caps_unref (caps);
    }
  } else {
    if (enc->correction_mode > GST_WAVPACK_CORRECTION_MODE_OFF) {
      enc->correction_mode = 0;
      GST_WARNING_OBJECT (enc, "setting correction mode only has "
          "any effect if a bitrate is provided.");
    }
  }
  gst_element_no_more_pads (GST_ELEMENT (enc));

  /* MD5, setup MD5 context */
  if ((enc->md5) && !(enc->md5_context)) {
    enc->wp_config->flags |= CONFIG_MD5_CHECKSUM;
    enc->md5_context = g_checksum_new (G_CHECKSUM_MD5);
  }

  /* Extra encode processing */
  if (enc->extra_processing) {
    enc->wp_config->flags |= CONFIG_EXTRA_MODE;
    enc->wp_config->xmode = enc->extra_processing;
  }

  /* Joint stereo mode */
  switch (enc->joint_stereo_mode) {
    case GST_WAVPACK_JS_MODE_AUTO:
      break;
    case GST_WAVPACK_JS_MODE_LEFT_RIGHT:
      enc->wp_config->flags |= CONFIG_JOINT_OVERRIDE;
      enc->wp_config->flags &= ~CONFIG_JOINT_STEREO;
      break;
    case GST_WAVPACK_JS_MODE_MID_SIDE:
      enc->wp_config->flags |= (CONFIG_JOINT_OVERRIDE | CONFIG_JOINT_STEREO);
      break;
  }
}

static int
gst_wavpack_enc_push_block (void *id, void *data, int32_t count)
{
  GstWavpackEncWriteID *wid = (GstWavpackEncWriteID *) id;
  GstWavpackEnc *enc = GST_WAVPACK_ENC (wid->wavpack_enc);
  GstFlowReturn *flow;
  GstBuffer *buffer;
  GstPad *pad;
  guchar *block = (guchar *) data;
  gint samples = 0;

  pad = (wid->correction) ? enc->wvcsrcpad : GST_AUDIO_ENCODER_SRC_PAD (enc);
  flow =
      (wid->correction) ? &enc->
      wvcsrcpad_last_return : &enc->srcpad_last_return;

  buffer = gst_buffer_new_and_alloc (count);
  gst_buffer_fill (buffer, 0, data, count);

  if (count > sizeof (WavpackHeader) && memcmp (block, "wvpk", 4) == 0) {
    /* if it's a Wavpack block set buffer timestamp and duration, etc */
    WavpackHeader wph;

    GST_LOG_OBJECT (enc, "got %d bytes of encoded wavpack %sdata",
        count, (wid->correction) ? "correction " : "");

    gst_wavpack_read_header (&wph, block);

    /* Only set when pushing the first buffer again, in that case
     * we don't want to delay the buffer or push newsegment events
     */
    if (!wid->passthrough) {
      /* Only push complete blocks */
      if (enc->pending_buffer == NULL) {
        enc->pending_buffer = buffer;
        enc->pending_offset = wph.block_index;
      } else if (enc->pending_offset == wph.block_index) {
        enc->pending_buffer = gst_buffer_append (enc->pending_buffer, buffer);
      } else {
        GST_ERROR ("Got incomplete block, dropping");
        gst_buffer_unref (enc->pending_buffer);
        enc->pending_buffer = buffer;
        enc->pending_offset = wph.block_index;
      }

      if (!(wph.flags & FINAL_BLOCK))
        return TRUE;

      buffer = enc->pending_buffer;
      enc->pending_buffer = NULL;
      enc->pending_offset = 0;

      /* only send segment on correction pad,
       * regular pad is handled normally by baseclass */
      if (wid->correction && enc->pending_segment) {
        gst_pad_push_event (pad, enc->pending_segment);
        enc->pending_segment = NULL;
      }

      if (wph.block_index == 0) {
        /* save header for later reference, so we can re-send it later on
         * EOS with fixed up values for total sample count etc. */
        if (enc->first_block == NULL && !wid->correction) {
          GstMapInfo map;

          gst_buffer_map (buffer, &map, GST_MAP_READ);
          enc->first_block = g_memdup (map.data, map.size);
          enc->first_block_size = map.size;
          gst_buffer_unmap (buffer, &map);
        }
      }
    }
    samples = wph.block_samples;

    /* decorate buffer */
    /* NOTE: this will get overwritten by baseclass, but stay for those
     * that are pushed directly
     * FIXME: add setting to baseclass to avoid overwriting it ?? */
    GST_BUFFER_OFFSET (buffer) = wph.block_index;
    GST_BUFFER_OFFSET_END (buffer) = wph.block_index + wph.block_samples;
  } else {
    /* if it's something else set no timestamp and duration on the buffer */
    GST_DEBUG_OBJECT (enc, "got %d bytes of unknown data", count);
  }

  if (wid->correction || wid->passthrough) {
    /* push the buffer and forward errors */
    GST_DEBUG_OBJECT (enc, "pushing buffer with %d bytes",
        gst_buffer_get_size (buffer));
    *flow = gst_pad_push (pad, buffer);
  } else {
    GST_DEBUG_OBJECT (enc, "handing frame of %d bytes",
        gst_buffer_get_size (buffer));
    *flow = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc), buffer,
        samples);
  }

  if (*flow != GST_FLOW_OK) {
    GST_WARNING_OBJECT (enc, "flow on %s:%s = %s",
        GST_DEBUG_PAD_NAME (pad), gst_flow_get_name (*flow));
    return FALSE;
  }

  return TRUE;
}

static void
gst_wavpack_enc_fix_channel_order (GstWavpackEnc * enc, gint32 * data,
    gint nsamples)
{
  gint i, j;
  gint32 tmp[8];

  for (i = 0; i < nsamples / enc->channels; i++) {
    for (j = 0; j < enc->channels; j++) {
      tmp[enc->channel_mapping[j]] = data[j];
    }
    for (j = 0; j < enc->channels; j++) {
      data[j] = tmp[j];
    }
    data += enc->channels;
  }
}

static GstFlowReturn
gst_wavpack_enc_handle_frame (GstAudioEncoder * benc, GstBuffer * buf)
{
  GstWavpackEnc *enc = GST_WAVPACK_ENC (benc);
  uint32_t sample_count;
  GstFlowReturn ret;
  GstMapInfo map;

  /* base class ensures configuration */
  g_return_val_if_fail (enc->depth != 0, GST_FLOW_NOT_NEGOTIATED);

  /* reset the last returns to GST_FLOW_OK. This is only set to something else
   * while WavpackPackSamples() or more specific gst_wavpack_enc_push_block()
   * so not valid anymore */
  enc->srcpad_last_return = enc->wvcsrcpad_last_return = GST_FLOW_OK;

  if (G_UNLIKELY (!buf))
    return gst_wavpack_enc_drain (enc);

  sample_count = gst_buffer_get_size (buf) / 4;
  GST_DEBUG_OBJECT (enc, "got %u raw samples", sample_count);

  /* check if we already have a valid WavpackContext, otherwise make one */
  if (!enc->wp_context) {
    /* create raw context */
    enc->wp_context =
        WavpackOpenFileOutput (gst_wavpack_enc_push_block, &enc->wv_id,
        (enc->correction_mode > 0) ? &enc->wvc_id : NULL);
    if (!enc->wp_context)
      goto context_failed;

    /* set the WavpackConfig according to our parameters */
    gst_wavpack_enc_set_wp_config (enc);

    /* set the configuration to the context now that we know everything
     * and initialize the encoder */
    if (!WavpackSetConfiguration (enc->wp_context,
            enc->wp_config, (uint32_t) (-1))
        || !WavpackPackInit (enc->wp_context)) {
      WavpackCloseFile (enc->wp_context);
      goto config_failed;
    }
    GST_DEBUG_OBJECT (enc, "setup of encoding context successfull");
  }

  if (enc->need_channel_remap) {
    buf = gst_buffer_make_writable (buf);
    gst_buffer_map (buf, &map, GST_MAP_WRITE);
    gst_wavpack_enc_fix_channel_order (enc, (gint32 *) map.data, sample_count);
    gst_buffer_unmap (buf, &map);
  }

  gst_buffer_map (buf, &map, GST_MAP_READ);

  /* if we want to append the MD5 sum to the stream update it here
   * with the current raw samples */
  if (enc->md5) {
    g_checksum_update (enc->md5_context, map.data, map.size);
  }

  /* encode and handle return values from encoding */
  if (WavpackPackSamples (enc->wp_context, (int32_t *) map.data,
          sample_count / enc->channels)) {
    GST_DEBUG_OBJECT (enc, "encoding samples successful");
    gst_buffer_unmap (buf, &map);
    ret = GST_FLOW_OK;
  } else {
    gst_buffer_unmap (buf, &map);
    if ((enc->srcpad_last_return == GST_FLOW_OK) ||
        (enc->wvcsrcpad_last_return == GST_FLOW_OK)) {
      ret = GST_FLOW_OK;
    } else if ((enc->srcpad_last_return == GST_FLOW_NOT_LINKED) &&
        (enc->wvcsrcpad_last_return == GST_FLOW_NOT_LINKED)) {
      ret = GST_FLOW_NOT_LINKED;
    } else if ((enc->srcpad_last_return == GST_FLOW_FLUSHING) &&
        (enc->wvcsrcpad_last_return == GST_FLOW_FLUSHING)) {
      ret = GST_FLOW_FLUSHING;
    } else {
      goto encoding_failed;
    }
  }

exit:
  return ret;

  /* ERRORS */
encoding_failed:
  {
    GST_ELEMENT_ERROR (enc, LIBRARY, ENCODE, (NULL),
        ("encoding samples failed"));
    ret = GST_FLOW_ERROR;
    goto exit;
  }
config_failed:
  {
    GST_ELEMENT_ERROR (enc, LIBRARY, SETTINGS, (NULL),
        ("error setting up wavpack encoding context"));
    ret = GST_FLOW_ERROR;
    goto exit;
  }
context_failed:
  {
    GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL),
        ("error creating Wavpack context"));
    ret = GST_FLOW_ERROR;
    goto exit;
  }
}

static void
gst_wavpack_enc_rewrite_first_block (GstWavpackEnc * enc)
{
  GstSegment segment;
  gboolean ret;
  GstQuery *query;
  gboolean seekable = FALSE;

  g_return_if_fail (enc);
  g_return_if_fail (enc->first_block);

  /* update the sample count in the first block */
  WavpackUpdateNumSamples (enc->wp_context, enc->first_block);

  /* try to seek to the beginning of the output */
  query = gst_query_new_seeking (GST_FORMAT_BYTES);
  if (gst_pad_peer_query (GST_AUDIO_ENCODER_SRC_PAD (enc), query)) {
    GstFormat format;

    gst_query_parse_seeking (query, &format, &seekable, NULL, NULL);
    if (format != GST_FORMAT_BYTES)
      seekable = FALSE;
  } else {
    GST_LOG_OBJECT (enc, "SEEKING query not handled");
  }
  gst_query_unref (query);

  if (!seekable) {
    GST_DEBUG_OBJECT (enc, "downstream not seekable; not rewriting");
    return;
  }

  gst_segment_init (&segment, GST_FORMAT_BYTES);
  ret = gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (enc),
      gst_event_new_segment (&segment));
  if (ret) {
    /* try to rewrite the first block */
    GST_DEBUG_OBJECT (enc, "rewriting first block ...");
    enc->wv_id.passthrough = TRUE;
    ret = gst_wavpack_enc_push_block (&enc->wv_id,
        enc->first_block, enc->first_block_size);
    enc->wv_id.passthrough = FALSE;
    g_free (enc->first_block);
    enc->first_block = NULL;
  } else {
    GST_WARNING_OBJECT (enc, "rewriting of first block failed. "
        "Seeking to first block failed!");
  }
}

static GstFlowReturn
gst_wavpack_enc_drain (GstWavpackEnc * enc)
{
  if (!enc->wp_context)
    return GST_FLOW_OK;

  GST_DEBUG_OBJECT (enc, "draining");

  /* Encode all remaining samples and flush them to the src pads */
  WavpackFlushSamples (enc->wp_context);

  /* Drop all remaining data, this is no complete block otherwise
   * it would've been pushed already */
  if (enc->pending_buffer) {
    gst_buffer_unref (enc->pending_buffer);
    enc->pending_buffer = NULL;
    enc->pending_offset = 0;
  }

  /* write the MD5 sum if we have to write one */
  if ((enc->md5) && (enc->md5_context)) {
    guint8 md5_digest[16];
    gsize digest_len = sizeof (md5_digest);

    g_checksum_get_digest (enc->md5_context, md5_digest, &digest_len);
    if (digest_len == sizeof (md5_digest)) {
      WavpackStoreMD5Sum (enc->wp_context, md5_digest);
      WavpackFlushSamples (enc->wp_context);
    } else
      GST_WARNING_OBJECT (enc, "Calculating MD5 digest failed");
  }

  /* Try to rewrite the first frame with the correct sample number */
  if (enc->first_block)
    gst_wavpack_enc_rewrite_first_block (enc);

  /* close the context if not already happened */
  if (enc->wp_context) {
    WavpackCloseFile (enc->wp_context);
    enc->wp_context = NULL;
  }

  return GST_FLOW_OK;
}

static gboolean
gst_wavpack_enc_sink_event (GstAudioEncoder * benc, GstEvent * event)
{
  GstWavpackEnc *enc = GST_WAVPACK_ENC (benc);

  GST_DEBUG_OBJECT (enc, "Received %s event on sinkpad",
      GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
      if (enc->wp_context) {
        GST_WARNING_OBJECT (enc, "got NEWSEGMENT after encoding "
            "already started");
      }
      /* peek and hold NEWSEGMENT events for sending on correction pad */
      if (enc->pending_segment)
        gst_event_unref (enc->pending_segment);
      enc->pending_segment = gst_event_ref (event);
      break;
    default:
      break;
  }

  /* baseclass handles rest */
  return GST_AUDIO_ENCODER_CLASS (parent_class)->sink_event (benc, event);
}

static void
gst_wavpack_enc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstWavpackEnc *enc = GST_WAVPACK_ENC (object);

  switch (prop_id) {
    case ARG_MODE:
      enc->mode = g_value_get_enum (value);
      break;
    case ARG_BITRATE:{
      guint val = g_value_get_uint (value);

      if ((val >= 24000) && (val <= 9600000)) {
        enc->bitrate = val;
        enc->bps = 0.0;
      } else {
        enc->bitrate = 0;
        enc->bps = 0.0;
      }
      break;
    }
    case ARG_BITSPERSAMPLE:{
      gdouble val = g_value_get_double (value);

      if ((val >= 2.0) && (val <= 24.0)) {
        enc->bps = val;
        enc->bitrate = 0;
      } else {
        enc->bps = 0.0;
        enc->bitrate = 0;
      }
      break;
    }
    case ARG_CORRECTION_MODE:
      enc->correction_mode = g_value_get_enum (value);
      break;
    case ARG_MD5:
      enc->md5 = g_value_get_boolean (value);
      break;
    case ARG_EXTRA_PROCESSING:
      enc->extra_processing = g_value_get_uint (value);
      break;
    case ARG_JOINT_STEREO_MODE:
      enc->joint_stereo_mode = g_value_get_enum (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_wavpack_enc_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstWavpackEnc *enc = GST_WAVPACK_ENC (object);

  switch (prop_id) {
    case ARG_MODE:
      g_value_set_enum (value, enc->mode);
      break;
    case ARG_BITRATE:
      if (enc->bps == 0.0) {
        g_value_set_uint (value, enc->bitrate);
      } else {
        g_value_set_uint (value, 0);
      }
      break;
    case ARG_BITSPERSAMPLE:
      if (enc->bitrate == 0) {
        g_value_set_double (value, enc->bps);
      } else {
        g_value_set_double (value, 0.0);
      }
      break;
    case ARG_CORRECTION_MODE:
      g_value_set_enum (value, enc->correction_mode);
      break;
    case ARG_MD5:
      g_value_set_boolean (value, enc->md5);
      break;
    case ARG_EXTRA_PROCESSING:
      g_value_set_uint (value, enc->extra_processing);
      break;
    case ARG_JOINT_STEREO_MODE:
      g_value_set_enum (value, enc->joint_stereo_mode);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

gboolean
gst_wavpack_enc_plugin_init (GstPlugin * plugin)
{
  if (!gst_element_register (plugin, "wavpackenc",
          GST_RANK_NONE, GST_TYPE_WAVPACK_ENC))
    return FALSE;

  GST_DEBUG_CATEGORY_INIT (gst_wavpack_enc_debug, "wavpackenc", 0,
      "Wavpack encoder");

  return TRUE;
}
