/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 *
 * 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-jpegenc
 *
 * Encodes jpeg images.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch videotestsrc num-buffers=50 ! video/x-raw-yuv, framerate='(fraction)'5/1 ! jpegenc ! avimux ! filesink location=mjpeg.avi
 * ]| a pipeline to mux 5 JPEG frames per second into a 10 sec. long motion jpeg
 * avi.
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>

#include "gstjpegenc.h"
#include "gstjpeg.h"
#include <gst/video/video.h>

/* experimental */
/* setting smoothig seems to have no effect in libjepeg
#define ENABLE_SMOOTHING 1
*/

GST_DEBUG_CATEGORY_STATIC (jpegenc_debug);
#define GST_CAT_DEFAULT jpegenc_debug

#define JPEG_DEFAULT_QUALITY 85
#define JPEG_DEFAULT_SMOOTHING 0
#define JPEG_DEFAULT_IDCT_METHOD	JDCT_FASTEST

/* JpegEnc signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_QUALITY,
  PROP_SMOOTHING,
  PROP_IDCT_METHOD
};

static void gst_jpegenc_reset (GstJpegEnc * enc);
static void gst_jpegenc_finalize (GObject * object);

static GstFlowReturn gst_jpegenc_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buf);
static gboolean gst_jpegenc_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static GstCaps *gst_jpegenc_getcaps (GstPad * pad, GstCaps * filter);
static gboolean gst_jpegenc_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query);

static void gst_jpegenc_resync (GstJpegEnc * jpegenc);
static void gst_jpegenc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_jpegenc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static GstStateChangeReturn gst_jpegenc_change_state (GstElement * element,
    GstStateChange transition);

#define gst_jpegenc_parent_class parent_class
G_DEFINE_TYPE (GstJpegEnc, gst_jpegenc, GST_TYPE_ELEMENT);

/* *INDENT-OFF* */
static GstStaticPadTemplate gst_jpegenc_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
        ("{ I420, YV12, YUY2, UYVY, Y41B, Y42B, YVYU, Y444, "
         "RGB, BGR, RGBx, xRGB, BGRx, xBGR, GRAY8 }"))
    );
/* *INDENT-ON* */

static GstStaticPadTemplate gst_jpegenc_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("image/jpeg, "
        "width = (int) [ 16, 65535 ], "
        "height = (int) [ 16, 65535 ], " "framerate = (fraction) [ 0/1, MAX ]")
    );


static void
gst_jpegenc_class_init (GstJpegEncClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;

  gobject_class->finalize = gst_jpegenc_finalize;
  gobject_class->set_property = gst_jpegenc_set_property;
  gobject_class->get_property = gst_jpegenc_get_property;

  g_object_class_install_property (gobject_class, PROP_QUALITY,
      g_param_spec_int ("quality", "Quality", "Quality of encoding",
          0, 100, JPEG_DEFAULT_QUALITY,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

#ifdef ENABLE_SMOOTHING
  /* disabled, since it doesn't seem to work */
  g_object_class_install_property (gobject_class, PROP_SMOOTHING,
      g_param_spec_int ("smoothing", "Smoothing", "Smoothing factor",
          0, 100, JPEG_DEFAULT_SMOOTHING,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
#endif

  g_object_class_install_property (gobject_class, PROP_IDCT_METHOD,
      g_param_spec_enum ("idct-method", "IDCT Method",
          "The IDCT algorithm to use", GST_TYPE_IDCT_METHOD,
          JPEG_DEFAULT_IDCT_METHOD,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state = gst_jpegenc_change_state;

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_jpegenc_sink_pad_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_jpegenc_src_pad_template));
  gst_element_class_set_static_metadata (gstelement_class, "JPEG image encoder",
      "Codec/Encoder/Image",
      "Encode images in JPEG format", "Wim Taymans <wim.taymans@tvd.be>");

  GST_DEBUG_CATEGORY_INIT (jpegenc_debug, "jpegenc", 0,
      "JPEG encoding element");
}

static void
ensure_memory (GstJpegEnc * jpegenc)
{
  GstMemory *new_memory;
  GstMapInfo map;
  gsize old_size, desired_size, new_size;
  guint8 *new_data;
  static GstAllocationParams params = { 0, 0, 0, 3, };

  old_size = jpegenc->output_map.size;
  if (old_size == 0)
    desired_size = jpegenc->bufsize;
  else
    desired_size = old_size * 2;

  /* Our output memory wasn't big enough.
   * Make a new memory that's twice the size, */
  new_memory = gst_allocator_alloc (NULL, desired_size, &params);
  gst_memory_map (new_memory, &map, GST_MAP_READWRITE);
  new_data = map.data;
  new_size = map.size;

  /* copy previous data if any */
  if (jpegenc->output_mem) {
    memcpy (new_data, jpegenc->output_map.data, old_size);
    gst_memory_unmap (jpegenc->output_mem, &jpegenc->output_map);
    gst_memory_unref (jpegenc->output_mem);
  }

  /* drop it into place, */
  jpegenc->output_mem = new_memory;
  jpegenc->output_map = map;

  /* and last, update libjpeg on where to work. */
  jpegenc->jdest.next_output_byte = new_data + old_size;
  jpegenc->jdest.free_in_buffer = new_size - old_size;
}

static void
gst_jpegenc_init_destination (j_compress_ptr cinfo)
{
  GST_DEBUG ("gst_jpegenc_chain: init_destination");
}

static boolean
gst_jpegenc_flush_destination (j_compress_ptr cinfo)
{
  GstJpegEnc *jpegenc = (GstJpegEnc *) (cinfo->client_data);

  GST_DEBUG_OBJECT (jpegenc,
      "gst_jpegenc_chain: flush_destination: buffer too small");

  ensure_memory (jpegenc);

  return TRUE;
}

static void
gst_jpegenc_term_destination (j_compress_ptr cinfo)
{
  GstJpegEnc *jpegenc = (GstJpegEnc *) (cinfo->client_data);
  GST_DEBUG_OBJECT (jpegenc, "gst_jpegenc_chain: term_source");

  gst_memory_unmap (jpegenc->output_mem, &jpegenc->output_map);
  /* Trim the buffer size. we will push it in the chain function */
  gst_memory_resize (jpegenc->output_mem, 0,
      jpegenc->output_map.size - jpegenc->jdest.free_in_buffer);
  jpegenc->output_map.data = NULL;
  jpegenc->output_map.size = 0;
}

static void
gst_jpegenc_init (GstJpegEnc * jpegenc)
{
  /* create the sink and src pads */
  jpegenc->sinkpad =
      gst_pad_new_from_static_template (&gst_jpegenc_sink_pad_template, "sink");
  gst_pad_set_chain_function (jpegenc->sinkpad,
      GST_DEBUG_FUNCPTR (gst_jpegenc_chain));
  gst_pad_set_query_function (jpegenc->sinkpad,
      GST_DEBUG_FUNCPTR (gst_jpegenc_sink_query));
  gst_pad_set_event_function (jpegenc->sinkpad,
      GST_DEBUG_FUNCPTR (gst_jpegenc_sink_event));
  gst_element_add_pad (GST_ELEMENT (jpegenc), jpegenc->sinkpad);

  jpegenc->srcpad =
      gst_pad_new_from_static_template (&gst_jpegenc_src_pad_template, "src");
  gst_pad_use_fixed_caps (jpegenc->srcpad);
  gst_element_add_pad (GST_ELEMENT (jpegenc), jpegenc->srcpad);

  /* reset the initial video state */
  gst_video_info_init (&jpegenc->info);

  /* setup jpeglib */
  memset (&jpegenc->cinfo, 0, sizeof (jpegenc->cinfo));
  memset (&jpegenc->jerr, 0, sizeof (jpegenc->jerr));
  jpegenc->cinfo.err = jpeg_std_error (&jpegenc->jerr);
  jpeg_create_compress (&jpegenc->cinfo);

  jpegenc->jdest.init_destination = gst_jpegenc_init_destination;
  jpegenc->jdest.empty_output_buffer = gst_jpegenc_flush_destination;
  jpegenc->jdest.term_destination = gst_jpegenc_term_destination;
  jpegenc->cinfo.dest = &jpegenc->jdest;
  jpegenc->cinfo.client_data = jpegenc;

  /* init properties */
  jpegenc->quality = JPEG_DEFAULT_QUALITY;
  jpegenc->smoothing = JPEG_DEFAULT_SMOOTHING;
  jpegenc->idct_method = JPEG_DEFAULT_IDCT_METHOD;

  gst_jpegenc_reset (jpegenc);
}

static void
gst_jpegenc_reset (GstJpegEnc * enc)
{
  gint i, j;

  g_free (enc->line[0]);
  g_free (enc->line[1]);
  g_free (enc->line[2]);
  enc->line[0] = NULL;
  enc->line[1] = NULL;
  enc->line[2] = NULL;
  for (i = 0; i < 3; i++) {
    for (j = 0; j < 4 * DCTSIZE; j++) {
      g_free (enc->row[i][j]);
      enc->row[i][j] = NULL;
    }
  }

  gst_video_info_init (&enc->info);
}

static void
gst_jpegenc_finalize (GObject * object)
{
  GstJpegEnc *filter = GST_JPEGENC (object);

  jpeg_destroy_compress (&filter->cinfo);

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

static GstCaps *
gst_jpegenc_getcaps (GstPad * pad, GstCaps * filter)
{
  GstJpegEnc *jpegenc = GST_JPEGENC (gst_pad_get_parent (pad));
  GstCaps *caps, *othercaps;
  GstCaps *templ;
  gint i, j;
  GstStructure *structure = NULL;

  /* we want to proxy properties like width, height and framerate from the
     other end of the element */

  othercaps = gst_pad_peer_query_caps (jpegenc->srcpad, filter);
  templ = gst_pad_get_pad_template_caps (pad);
  if (othercaps == NULL ||
      gst_caps_is_empty (othercaps) || gst_caps_is_any (othercaps)) {
    caps = templ;
    goto done;
  }

  caps = gst_caps_new_empty ();

  for (i = 0; i < gst_caps_get_size (templ); i++) {
    /* pick fields from peer caps */
    for (j = 0; j < gst_caps_get_size (othercaps); j++) {
      GstStructure *s = gst_caps_get_structure (othercaps, j);
      const GValue *val;

      structure = gst_structure_copy (gst_caps_get_structure (templ, i));
      if ((val = gst_structure_get_value (s, "width")))
        gst_structure_set_value (structure, "width", val);
      if ((val = gst_structure_get_value (s, "height")))
        gst_structure_set_value (structure, "height", val);
      if ((val = gst_structure_get_value (s, "framerate")))
        gst_structure_set_value (structure, "framerate", val);

      caps = gst_caps_merge_structure (caps, structure);
    }
  }

  gst_caps_unref (templ);

done:

  gst_caps_replace (&othercaps, NULL);
  gst_object_unref (jpegenc);

  return caps;
}

static gboolean
gst_jpegenc_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  gboolean res;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:
    {
      GstCaps *filter, *caps;

      gst_query_parse_caps (query, &filter);
      caps = gst_jpegenc_getcaps (pad, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      res = TRUE;
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }
  return res;
}

static gboolean
gst_jpegenc_setcaps (GstJpegEnc * enc, GstCaps * caps)
{
  GstVideoInfo info;
  gint i;
  GstCaps *othercaps;
  gboolean ret;
  const GstVideoFormatInfo *vinfo;

  /* get info from caps */
  if (!gst_video_info_from_caps (&info, caps))
    goto refuse_caps;

  /* store input description */
  enc->info = info;

  vinfo = info.finfo;

  /* prepare a cached image description  */
  enc->channels = 3 + (GST_VIDEO_FORMAT_INFO_HAS_ALPHA (vinfo) ? 1 : 0);
  /* ... but any alpha is disregarded in encoding */
  if (GST_VIDEO_FORMAT_INFO_IS_GRAY (vinfo))
    enc->channels = 1;
  else
    enc->channels = 3;

  enc->h_max_samp = 0;
  enc->v_max_samp = 0;
  for (i = 0; i < enc->channels; ++i) {
    enc->cwidth[i] = GST_VIDEO_INFO_COMP_WIDTH (&info, i);
    enc->cheight[i] = GST_VIDEO_INFO_COMP_HEIGHT (&info, i);
    enc->inc[i] = GST_VIDEO_INFO_COMP_PSTRIDE (&info, i);

    enc->h_samp[i] = GST_ROUND_UP_4 (info.width) / enc->cwidth[i];
    enc->h_max_samp = MAX (enc->h_max_samp, enc->h_samp[i]);
    enc->v_samp[i] = GST_ROUND_UP_4 (info.height) / enc->cheight[i];
    enc->v_max_samp = MAX (enc->v_max_samp, enc->v_samp[i]);
  }
  /* samp should only be 1, 2 or 4 */
  g_assert (enc->h_max_samp <= 4);
  g_assert (enc->v_max_samp <= 4);
  /* now invert */
  /* maximum is invariant, as one of the components should have samp 1 */
  for (i = 0; i < enc->channels; ++i) {
    enc->h_samp[i] = enc->h_max_samp / enc->h_samp[i];
    enc->v_samp[i] = enc->v_max_samp / enc->v_samp[i];
  }
  enc->planar = (enc->inc[0] == 1 && enc->inc[1] == 1 && enc->inc[2] == 1);

  othercaps = gst_caps_copy (gst_pad_get_pad_template_caps (enc->srcpad));
  gst_caps_set_simple (othercaps,
      "width", G_TYPE_INT, info.width, "height", G_TYPE_INT, info.height, NULL);
  if (info.fps_d > 0)
    gst_caps_set_simple (othercaps,
        "framerate", GST_TYPE_FRACTION, info.fps_n, info.fps_d, NULL);
  if (info.par_d > 0)
    gst_caps_set_simple (othercaps,
        "pixel-aspect-ratio", GST_TYPE_FRACTION, info.par_n, info.par_d, NULL);

  ret = gst_pad_set_caps (enc->srcpad, othercaps);
  gst_caps_unref (othercaps);

  if (ret)
    gst_jpegenc_resync (enc);

  return ret;

  /* ERRORS */
refuse_caps:
  {
    GST_WARNING_OBJECT (enc, "refused caps %" GST_PTR_FORMAT, caps);
    return FALSE;
  }
}

static gboolean
gst_jpegenc_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res;
  GstJpegEnc *enc = GST_JPEGENC (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      res = gst_jpegenc_setcaps (enc, caps);
      gst_event_unref (event);
      break;
    }
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }

  return res;
}

static void
gst_jpegenc_resync (GstJpegEnc * jpegenc)
{
  gint width, height;
  gint i, j;
  const GstVideoFormatInfo *finfo;

  GST_DEBUG_OBJECT (jpegenc, "resync");

  finfo = jpegenc->info.finfo;

  jpegenc->cinfo.image_width = width = GST_VIDEO_INFO_WIDTH (&jpegenc->info);
  jpegenc->cinfo.image_height = height = GST_VIDEO_INFO_HEIGHT (&jpegenc->info);
  jpegenc->cinfo.input_components = jpegenc->channels;

  GST_DEBUG_OBJECT (jpegenc, "width %d, height %d", width, height);
  GST_DEBUG_OBJECT (jpegenc, "format %d",
      GST_VIDEO_INFO_FORMAT (&jpegenc->info));

  if (GST_VIDEO_FORMAT_INFO_IS_RGB (finfo)) {
    GST_DEBUG_OBJECT (jpegenc, "RGB");
    jpegenc->cinfo.in_color_space = JCS_RGB;
  } else if (GST_VIDEO_FORMAT_INFO_IS_GRAY (finfo)) {
    GST_DEBUG_OBJECT (jpegenc, "gray");
    jpegenc->cinfo.in_color_space = JCS_GRAYSCALE;
  } else {
    GST_DEBUG_OBJECT (jpegenc, "YUV");
    jpegenc->cinfo.in_color_space = JCS_YCbCr;
  }

  /* input buffer size as max output */
  jpegenc->bufsize = GST_VIDEO_INFO_SIZE (&jpegenc->info);
  jpeg_set_defaults (&jpegenc->cinfo);
  jpegenc->cinfo.raw_data_in = TRUE;
  /* duh, libjpeg maps RGB to YUV ... and don't expect some conversion */
  if (jpegenc->cinfo.in_color_space == JCS_RGB)
    jpeg_set_colorspace (&jpegenc->cinfo, JCS_RGB);

  GST_DEBUG_OBJECT (jpegenc, "h_max_samp=%d, v_max_samp=%d",
      jpegenc->h_max_samp, jpegenc->v_max_samp);
  /* image dimension info */
  for (i = 0; i < jpegenc->channels; i++) {
    GST_DEBUG_OBJECT (jpegenc, "comp %i: h_samp=%d, v_samp=%d", i,
        jpegenc->h_samp[i], jpegenc->v_samp[i]);
    jpegenc->cinfo.comp_info[i].h_samp_factor = jpegenc->h_samp[i];
    jpegenc->cinfo.comp_info[i].v_samp_factor = jpegenc->v_samp[i];
    g_free (jpegenc->line[i]);
    jpegenc->line[i] = g_new (guchar *, jpegenc->v_max_samp * DCTSIZE);
    if (!jpegenc->planar) {
      for (j = 0; j < jpegenc->v_max_samp * DCTSIZE; j++) {
        g_free (jpegenc->row[i][j]);
        jpegenc->row[i][j] = g_malloc (width);
        jpegenc->line[i][j] = jpegenc->row[i][j];
      }
    }
  }

  /* guard against a potential error in gst_jpegenc_term_destination
     which occurs iff bufsize % 4 < free_space_remaining */
  jpegenc->bufsize = GST_ROUND_UP_4 (jpegenc->bufsize);

  jpeg_suppress_tables (&jpegenc->cinfo, TRUE);

  GST_DEBUG_OBJECT (jpegenc, "resync done");
}

static GstFlowReturn
gst_jpegenc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstFlowReturn ret;
  GstJpegEnc *jpegenc;
  guint height;
  guchar *base[3], *end[3];
  guint stride[3];
  gint i, j, k;
  GstBuffer *outbuf;
  GstVideoFrame frame;
  static GstAllocationParams params = { 0, 0, 0, 3, };

  jpegenc = GST_JPEGENC (parent);

  if (G_UNLIKELY (GST_VIDEO_INFO_FORMAT (&jpegenc->info) ==
          GST_VIDEO_FORMAT_UNKNOWN))
    goto not_negotiated;

  if (!gst_video_frame_map (&frame, &jpegenc->info, buf, GST_MAP_READ))
    goto invalid_frame;

  height = GST_VIDEO_FRAME_HEIGHT (&frame);

  GST_LOG_OBJECT (jpegenc, "got buffer of %" G_GSIZE_FORMAT " bytes",
      gst_buffer_get_size (buf));

  for (i = 0; i < jpegenc->channels; i++) {
    base[i] = GST_VIDEO_FRAME_COMP_DATA (&frame, i);
    stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (&frame, i);
    end[i] = base[i] + GST_VIDEO_FRAME_COMP_HEIGHT (&frame, i) * stride[i];
  }

  jpegenc->output_mem = gst_allocator_alloc (NULL, jpegenc->bufsize, &params);
  gst_memory_map (jpegenc->output_mem, &jpegenc->output_map, GST_MAP_READWRITE);

  jpegenc->jdest.next_output_byte = jpegenc->output_map.data;
  jpegenc->jdest.free_in_buffer = jpegenc->output_map.size;

  /* prepare for raw input */
#if JPEG_LIB_VERSION >= 70
  jpegenc->cinfo.do_fancy_downsampling = FALSE;
#endif
  jpegenc->cinfo.smoothing_factor = jpegenc->smoothing;
  jpegenc->cinfo.dct_method = jpegenc->idct_method;
  jpeg_set_quality (&jpegenc->cinfo, jpegenc->quality, TRUE);
  jpeg_start_compress (&jpegenc->cinfo, TRUE);

  GST_LOG_OBJECT (jpegenc, "compressing");

  if (jpegenc->planar) {
    for (i = 0; i < height; i += jpegenc->v_max_samp * DCTSIZE) {
      for (k = 0; k < jpegenc->channels; k++) {
        for (j = 0; j < jpegenc->v_samp[k] * DCTSIZE; j++) {
          jpegenc->line[k][j] = base[k];
          if (base[k] + stride[k] < end[k])
            base[k] += stride[k];
        }
      }
      jpeg_write_raw_data (&jpegenc->cinfo, jpegenc->line,
          jpegenc->v_max_samp * DCTSIZE);
    }
  } else {
    for (i = 0; i < height; i += jpegenc->v_max_samp * DCTSIZE) {
      for (k = 0; k < jpegenc->channels; k++) {
        for (j = 0; j < jpegenc->v_samp[k] * DCTSIZE; j++) {
          guchar *src, *dst;
          gint l;

          /* ouch, copy line */
          src = base[k];
          dst = jpegenc->line[k][j];
          for (l = jpegenc->cwidth[k]; l > 0; l--) {
            *dst = *src;
            src += jpegenc->inc[k];
            dst++;
          }
          if (base[k] + stride[k] < end[k])
            base[k] += stride[k];
        }
      }
      jpeg_write_raw_data (&jpegenc->cinfo, jpegenc->line,
          jpegenc->v_max_samp * DCTSIZE);
    }
  }

  /* This will ensure that gst_jpegenc_term_destination is called */
  jpeg_finish_compress (&jpegenc->cinfo);
  GST_LOG_OBJECT (jpegenc, "compressing done");

  outbuf = gst_buffer_new ();
  gst_buffer_copy_into (outbuf, buf, GST_BUFFER_COPY_METADATA, 0, -1);
  gst_buffer_append_memory (outbuf, jpegenc->output_mem);
  jpegenc->output_mem = NULL;

  ret = gst_pad_push (jpegenc->srcpad, outbuf);

  gst_video_frame_unmap (&frame);
  gst_buffer_unref (buf);

  return ret;

  /* ERRORS */
not_negotiated:
  {
    GST_WARNING_OBJECT (jpegenc, "no input format set (no caps on buffer)");
    gst_buffer_unref (buf);
    return GST_FLOW_NOT_NEGOTIATED;
  }
invalid_frame:
  {
    GST_WARNING_OBJECT (jpegenc, "invalid frame received");
    gst_buffer_unref (buf);
    return GST_FLOW_OK;
  }
}

static void
gst_jpegenc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstJpegEnc *jpegenc = GST_JPEGENC (object);

  GST_OBJECT_LOCK (jpegenc);

  switch (prop_id) {
    case PROP_QUALITY:
      jpegenc->quality = g_value_get_int (value);
      break;
#ifdef ENABLE_SMOOTHING
    case PROP_SMOOTHING:
      jpegenc->smoothing = g_value_get_int (value);
      break;
#endif
    case PROP_IDCT_METHOD:
      jpegenc->idct_method = g_value_get_enum (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_OBJECT_UNLOCK (jpegenc);
}

static void
gst_jpegenc_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstJpegEnc *jpegenc = GST_JPEGENC (object);

  GST_OBJECT_LOCK (jpegenc);

  switch (prop_id) {
    case PROP_QUALITY:
      g_value_set_int (value, jpegenc->quality);
      break;
#ifdef ENABLE_SMOOTHING
    case PROP_SMOOTHING:
      g_value_set_int (value, jpegenc->smoothing);
      break;
#endif
    case PROP_IDCT_METHOD:
      g_value_set_enum (value, jpegenc->idct_method);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_OBJECT_UNLOCK (jpegenc);
}

static GstStateChangeReturn
gst_jpegenc_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstJpegEnc *filter = GST_JPEGENC (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      GST_DEBUG_OBJECT (element, "setting line buffers");
      filter->line[0] = NULL;
      filter->line[1] = NULL;
      filter->line[2] = NULL;
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_jpegenc_reset (filter);
      break;
    default:
      break;
  }

  return ret;
}
