/* VPX
 * Copyright (C) 2006 David Schleef <ds@schleef.org>
 * Copyright (C) 2008,2009,2010 Entropy Wave Inc
 * Copyright (C) 2010-2012 Sebastian Dröge <sebastian.droege@collabora.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#if defined(HAVE_VP8_DECODER) || defined(HAVE_VP9_DECODER)

#include <string.h>

#include "gstvpxdec.h"
#include "gstvp8utils.h"

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

GST_DEBUG_CATEGORY_STATIC (gst_vpxdec_debug);
#define GST_CAT_DEFAULT gst_vpxdec_debug

#define DEFAULT_POST_PROCESSING FALSE
#define DEFAULT_POST_PROCESSING_FLAGS (VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE)
#define DEFAULT_DEBLOCKING_LEVEL 4
#define DEFAULT_NOISE_LEVEL 0
#define DEFAULT_THREADS 0
#define DEFAULT_VIDEO_CODEC_TAG NULL
#define DEFAULT_CODEC_ALGO NULL

enum
{
  PROP_0,
  PROP_POST_PROCESSING,
  PROP_POST_PROCESSING_FLAGS,
  PROP_DEBLOCKING_LEVEL,
  PROP_NOISE_LEVEL,
  PROP_THREADS
};

#define C_FLAGS(v) ((guint) v)
#define GST_VPX_DEC_TYPE_POST_PROCESSING_FLAGS (gst_vpx_dec_post_processing_flags_get_type())
static GType
gst_vpx_dec_post_processing_flags_get_type (void)
{
  static const GFlagsValue values[] = {
    {C_FLAGS (VP8_DEBLOCK), "Deblock", "deblock"},
    {C_FLAGS (VP8_DEMACROBLOCK), "Demacroblock", "demacroblock"},
    {C_FLAGS (VP8_ADDNOISE), "Add noise", "addnoise"},
    {C_FLAGS (VP8_MFQE), "Multi-frame quality enhancement", "mfqe"},
    {0, NULL, NULL}
  };
  static volatile GType id = 0;

  if (g_once_init_enter ((gsize *) & id)) {
    GType _id;

    _id = g_flags_register_static ("GstVPXDecPostProcessingFlags", values);

    g_once_init_leave ((gsize *) & id, _id);
  }

  return id;
}

#undef C_FLAGS

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

static gboolean gst_vpx_dec_start (GstVideoDecoder * decoder);
static gboolean gst_vpx_dec_stop (GstVideoDecoder * decoder);
static gboolean gst_vpx_dec_set_format (GstVideoDecoder * decoder,
    GstVideoCodecState * state);
static gboolean gst_vpx_dec_flush (GstVideoDecoder * decoder);
static GstFlowReturn
gst_vpx_dec_handle_frame (GstVideoDecoder * decoder,
    GstVideoCodecFrame * frame);
static gboolean gst_vpx_dec_decide_allocation (GstVideoDecoder * decoder,
    GstQuery * query);

static void gst_vpx_dec_image_to_buffer (GstVPXDec * dec,
    const vpx_image_t * img, GstBuffer * buffer);
static GstFlowReturn gst_vpx_dec_open_codec (GstVPXDec * dec,
    GstVideoCodecFrame * frame);
static void gst_vpx_dec_default_send_tags (GstVPXDec * dec);
static void gst_vpx_dec_set_stream_info (GstVPXDec * dec,
    vpx_codec_stream_info_t * stream_info);
static void gst_vpx_dec_set_default_format (GstVPXDec * dec, GstVideoFormat fmt,
    int width, int height);
static gboolean gst_vpx_dec_default_frame_format (GstVPXDec * dec,
    vpx_image_t * img, GstVideoFormat * fmt);
static void gst_vpx_dec_handle_resolution_change (GstVPXDec * dec,
    vpx_image_t * img, GstVideoFormat fmt);

#define parent_class gst_vpx_dec_parent_class
G_DEFINE_TYPE (GstVPXDec, gst_vpx_dec, GST_TYPE_VIDEO_DECODER);

static void
gst_vpx_dec_class_init (GstVPXDecClass * klass)
{
  GObjectClass *gobject_class;
  GstVideoDecoderClass *base_video_decoder_class;

  gobject_class = G_OBJECT_CLASS (klass);
  base_video_decoder_class = GST_VIDEO_DECODER_CLASS (klass);

  gobject_class->set_property = gst_vpx_dec_set_property;
  gobject_class->get_property = gst_vpx_dec_get_property;

  g_object_class_install_property (gobject_class, PROP_POST_PROCESSING,
      g_param_spec_boolean ("post-processing", "Post Processing",
          "Enable post processing", DEFAULT_POST_PROCESSING,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_POST_PROCESSING_FLAGS,
      g_param_spec_flags ("post-processing-flags", "Post Processing Flags",
          "Flags to control post processing",
          GST_VPX_DEC_TYPE_POST_PROCESSING_FLAGS, DEFAULT_POST_PROCESSING_FLAGS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_DEBLOCKING_LEVEL,
      g_param_spec_uint ("deblocking-level", "Deblocking Level",
          "Deblocking level",
          0, 16, DEFAULT_DEBLOCKING_LEVEL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_NOISE_LEVEL,
      g_param_spec_uint ("noise-level", "Noise Level",
          "Noise level",
          0, 16, DEFAULT_NOISE_LEVEL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_THREADS,
      g_param_spec_uint ("threads", "Max Threads",
          "Maximum number of decoding threads",
          0, 16, DEFAULT_THREADS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  base_video_decoder_class->start = GST_DEBUG_FUNCPTR (gst_vpx_dec_start);
  base_video_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_vpx_dec_stop);
  base_video_decoder_class->flush = GST_DEBUG_FUNCPTR (gst_vpx_dec_flush);
  base_video_decoder_class->set_format =
      GST_DEBUG_FUNCPTR (gst_vpx_dec_set_format);
  base_video_decoder_class->handle_frame =
      GST_DEBUG_FUNCPTR (gst_vpx_dec_handle_frame);;
  base_video_decoder_class->decide_allocation =
      GST_DEBUG_FUNCPTR (gst_vpx_dec_decide_allocation);

  klass->video_codec_tag = DEFAULT_VIDEO_CODEC_TAG;
  klass->codec_algo = DEFAULT_CODEC_ALGO;
  klass->open_codec = GST_DEBUG_FUNCPTR (gst_vpx_dec_open_codec);
  klass->send_tags = GST_DEBUG_FUNCPTR (gst_vpx_dec_default_send_tags);
  klass->set_stream_info = NULL;
  klass->set_default_format = NULL;
  klass->handle_resolution_change = NULL;
  klass->get_frame_format =
      GST_DEBUG_FUNCPTR (gst_vpx_dec_default_frame_format);

  GST_DEBUG_CATEGORY_INIT (gst_vpxdec_debug, "vpxdec", 0, "VPX Decoder");
}

static void
gst_vpx_dec_init (GstVPXDec * gst_vpx_dec)
{
  GstVideoDecoder *decoder = (GstVideoDecoder *) gst_vpx_dec;

  GST_DEBUG_OBJECT (gst_vpx_dec, "gst_vpx_dec_init");
  gst_video_decoder_set_packetized (decoder, TRUE);
  gst_vpx_dec->post_processing = DEFAULT_POST_PROCESSING;
  gst_vpx_dec->post_processing_flags = DEFAULT_POST_PROCESSING_FLAGS;
  gst_vpx_dec->deblocking_level = DEFAULT_DEBLOCKING_LEVEL;
  gst_vpx_dec->noise_level = DEFAULT_NOISE_LEVEL;

  gst_video_decoder_set_needs_format (decoder, TRUE);
  gst_video_decoder_set_use_default_pad_acceptcaps (decoder, TRUE);
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_DECODER_SINK_PAD (decoder));
}

static void
gst_vpx_dec_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstVPXDec *dec;

  g_return_if_fail (GST_IS_VPX_DEC (object));
  dec = GST_VPX_DEC (object);

  GST_DEBUG_OBJECT (object, "gst_vpx_dec_set_property");
  switch (prop_id) {
    case PROP_POST_PROCESSING:
      dec->post_processing = g_value_get_boolean (value);
      break;
    case PROP_POST_PROCESSING_FLAGS:
      dec->post_processing_flags = g_value_get_flags (value);
      break;
    case PROP_DEBLOCKING_LEVEL:
      dec->deblocking_level = g_value_get_uint (value);
      break;
    case PROP_NOISE_LEVEL:
      dec->noise_level = g_value_get_uint (value);
      break;
    case PROP_THREADS:
      dec->threads = g_value_get_uint (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_vpx_dec_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstVPXDec *dec;

  g_return_if_fail (GST_IS_VPX_DEC (object));
  dec = GST_VPX_DEC (object);

  switch (prop_id) {
    case PROP_POST_PROCESSING:
      g_value_set_boolean (value, dec->post_processing);
      break;
    case PROP_POST_PROCESSING_FLAGS:
      g_value_set_flags (value, dec->post_processing_flags);
      break;
    case PROP_DEBLOCKING_LEVEL:
      g_value_set_uint (value, dec->deblocking_level);
      break;
    case PROP_NOISE_LEVEL:
      g_value_set_uint (value, dec->noise_level);
      break;
    case PROP_THREADS:
      g_value_set_uint (value, dec->threads);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_vpx_dec_start (GstVideoDecoder * decoder)
{
  GstVPXDec *gst_vpx_dec = GST_VPX_DEC (decoder);

  GST_DEBUG_OBJECT (gst_vpx_dec, "start");
  gst_vpx_dec->decoder_inited = FALSE;

  return TRUE;
}

static gboolean
gst_vpx_dec_stop (GstVideoDecoder * base_video_decoder)
{
  GstVPXDec *gst_vpx_dec = GST_VPX_DEC (base_video_decoder);

  GST_DEBUG_OBJECT (gst_vpx_dec, "stop");

  if (gst_vpx_dec->output_state) {
    gst_video_codec_state_unref (gst_vpx_dec->output_state);
    gst_vpx_dec->output_state = NULL;
  }

  if (gst_vpx_dec->input_state) {
    gst_video_codec_state_unref (gst_vpx_dec->input_state);
    gst_vpx_dec->input_state = NULL;
  }

  if (gst_vpx_dec->decoder_inited)
    vpx_codec_destroy (&gst_vpx_dec->decoder);
  gst_vpx_dec->decoder_inited = FALSE;

  if (gst_vpx_dec->pool) {
    gst_buffer_pool_set_active (gst_vpx_dec->pool, FALSE);
    gst_object_unref (gst_vpx_dec->pool);
    gst_vpx_dec->pool = NULL;
    gst_vpx_dec->buf_size = 0;
  }

  return TRUE;
}

static gboolean
gst_vpx_dec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
{
  GstVPXDec *gst_vpx_dec = GST_VPX_DEC (decoder);

  GST_DEBUG_OBJECT (gst_vpx_dec, "set_format");

  if (gst_vpx_dec->decoder_inited)
    vpx_codec_destroy (&gst_vpx_dec->decoder);
  gst_vpx_dec->decoder_inited = FALSE;

  if (gst_vpx_dec->output_state) {
    gst_video_codec_state_unref (gst_vpx_dec->output_state);
    gst_vpx_dec->output_state = NULL;
  }

  if (gst_vpx_dec->input_state) {
    gst_video_codec_state_unref (gst_vpx_dec->input_state);
  }

  gst_vpx_dec->input_state = gst_video_codec_state_ref (state);

  return TRUE;
}

static gboolean
gst_vpx_dec_flush (GstVideoDecoder * base_video_decoder)
{
  GstVPXDec *decoder;

  GST_DEBUG_OBJECT (base_video_decoder, "flush");

  decoder = GST_VPX_DEC (base_video_decoder);

  if (decoder->output_state) {
    gst_video_codec_state_unref (decoder->output_state);
    decoder->output_state = NULL;
  }

  if (decoder->decoder_inited)
    vpx_codec_destroy (&decoder->decoder);
  decoder->decoder_inited = FALSE;

  return TRUE;
}

static void
gst_vpx_dec_default_send_tags (GstVPXDec * dec)
{
  GstTagList *list;
  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);

  if (vpxclass->video_codec_tag == NULL)
    return;

  list = gst_tag_list_new_empty ();
  gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
      GST_TAG_VIDEO_CODEC, vpxclass->video_codec_tag, NULL);

  gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (dec),
      gst_event_new_tag (list));
}

#ifdef HAVE_VPX_1_4
struct Frame
{
  GstMapInfo info;
  GstBuffer *buffer;
};

static GstBuffer *
gst_vpx_dec_prepare_image (GstVPXDec * dec, const vpx_image_t * img)
{
  gint comp;
  GstVideoMeta *vmeta;
  GstBuffer *buffer;
  struct Frame *frame = img->fb_priv;
  GstVideoInfo *info = &dec->output_state->info;

  buffer = gst_buffer_ref (frame->buffer);

  vmeta = gst_buffer_get_video_meta (buffer);
  vmeta->format = GST_VIDEO_INFO_FORMAT (info);
  vmeta->width = GST_VIDEO_INFO_WIDTH (info);
  vmeta->height = GST_VIDEO_INFO_HEIGHT (info);
  vmeta->n_planes = GST_VIDEO_INFO_N_PLANES (info);

  for (comp = 0; comp < 4; comp++) {
    vmeta->stride[comp] = img->stride[comp];
    vmeta->offset[comp] =
        img->planes[comp] ? img->planes[comp] - frame->info.data : 0;
  }

  /* FIXME This is a READ/WRITE mapped buffer see bug #754826 */

  return buffer;
}

static int
gst_vpx_dec_get_buffer_cb (gpointer priv, gsize min_size,
    vpx_codec_frame_buffer_t * fb)
{
  GstVPXDec *dec = priv;
  GstBuffer *buffer;
  struct Frame *frame;
  GstFlowReturn ret;

  if (!dec->pool || dec->buf_size != min_size) {
    GstBufferPool *pool;
    GstStructure *config;
    GstCaps *caps;
    GstAllocator *allocator;
    GstAllocationParams params;

    if (dec->pool) {
      gst_buffer_pool_set_active (dec->pool, FALSE);
      gst_object_unref (dec->pool);
      dec->pool = NULL;
      dec->buf_size = 0;
    }

    gst_video_decoder_get_allocator (GST_VIDEO_DECODER (dec), &allocator,
        &params);

    if (allocator &&
        GST_OBJECT_FLAG_IS_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC)) {
      gst_object_unref (allocator);
      allocator = NULL;
    }

    pool = gst_buffer_pool_new ();
    config = gst_buffer_pool_get_config (pool);
    gst_buffer_pool_config_set_allocator (config, allocator, &params);
    caps = gst_caps_from_string ("video/internal");
    gst_buffer_pool_config_set_params (config, caps, min_size, 2, 0);
    gst_caps_unref (caps);
    gst_buffer_pool_set_config (pool, config);

    if (allocator)
      gst_object_unref (allocator);

    if (!gst_buffer_pool_set_active (pool, TRUE)) {
      GST_WARNING ("Failed to create internal pool");
      gst_object_unref (pool);
      return -1;
    }

    dec->pool = pool;
    dec->buf_size = min_size;
  }

  ret = gst_buffer_pool_acquire_buffer (dec->pool, &buffer, NULL);
  if (ret != GST_FLOW_OK) {
    GST_WARNING ("Failed to acquire buffer from internal pool.");
    return -1;
  }

  /* Add it now, while the buffer is writable */
  gst_buffer_add_video_meta (buffer, GST_VIDEO_FRAME_FLAG_NONE,
      GST_VIDEO_FORMAT_ENCODED, 0, 0);

  frame = g_new0 (struct Frame, 1);
  if (!gst_buffer_map (buffer, &frame->info, GST_MAP_READWRITE)) {
    gst_buffer_unref (buffer);
    g_free (frame);
    GST_WARNING ("Failed to map buffer from internal pool.");
    return -1;
  }

  fb->size = frame->info.size;
  fb->data = frame->info.data;
  frame->buffer = buffer;
  fb->priv = frame;

  GST_TRACE_OBJECT (priv, "Allocated buffer %p", frame->buffer);

  return 0;
}

static int
gst_vpx_dec_release_buffer_cb (gpointer priv, vpx_codec_frame_buffer_t * fb)
{
  struct Frame *frame = fb->priv;

  GST_TRACE_OBJECT (priv, "Release buffer %p", frame->buffer);

  g_assert (frame);
  gst_buffer_unmap (frame->buffer, &frame->info);
  gst_buffer_unref (frame->buffer);
  g_free (frame);

  return 0;
}
#endif

static void
gst_vpx_dec_image_to_buffer (GstVPXDec * dec, const vpx_image_t * img,
    GstBuffer * buffer)
{
  int deststride, srcstride, height, width, line, comp;
  guint8 *dest, *src;
  GstVideoFrame frame;
  GstVideoInfo *info = &dec->output_state->info;

  if (!gst_video_frame_map (&frame, info, buffer, GST_MAP_WRITE)) {
    GST_ERROR_OBJECT (dec, "Could not map video buffer");
    return;
  }

  for (comp = 0; comp < 3; comp++) {
    dest = GST_VIDEO_FRAME_COMP_DATA (&frame, comp);
    src = img->planes[comp];
    width = GST_VIDEO_FRAME_COMP_WIDTH (&frame, comp)
        * GST_VIDEO_FRAME_COMP_PSTRIDE (&frame, comp);
    height = GST_VIDEO_FRAME_COMP_HEIGHT (&frame, comp);
    deststride = GST_VIDEO_FRAME_COMP_STRIDE (&frame, comp);
    srcstride = img->stride[comp];

    if (srcstride == deststride) {
      GST_TRACE_OBJECT (dec, "Stride matches. Comp %d: %d, copying full plane",
          comp, srcstride);
      memcpy (dest, src, srcstride * height);
    } else {
      GST_TRACE_OBJECT (dec, "Stride mismatch. Comp %d: %d != %d, copying "
          "line by line.", comp, srcstride, deststride);
      for (line = 0; line < height; line++) {
        memcpy (dest, src, width);
        dest += deststride;
        src += srcstride;
      }
    }
  }

  gst_video_frame_unmap (&frame);
}

static GstFlowReturn
gst_vpx_dec_open_codec (GstVPXDec * dec, GstVideoCodecFrame * frame)
{
  int flags = 0;
  vpx_codec_stream_info_t stream_info;
  vpx_codec_caps_t caps;
  vpx_codec_dec_cfg_t cfg;
  vpx_codec_err_t status;
  GstMapInfo minfo;
  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);

  g_return_val_if_fail (vpxclass->codec_algo != NULL, GST_FLOW_ERROR);

  memset (&stream_info, 0, sizeof (stream_info));
  memset (&cfg, 0, sizeof (cfg));
  stream_info.sz = sizeof (stream_info);

  if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
    GST_ERROR_OBJECT (dec, "Failed to map input buffer");
    return GST_FLOW_ERROR;
  }

  status = vpx_codec_peek_stream_info (vpxclass->codec_algo,
      minfo.data, minfo.size, &stream_info);

  gst_buffer_unmap (frame->input_buffer, &minfo);

  if (status != VPX_CODEC_OK) {
    GST_WARNING_OBJECT (dec, "VPX preprocessing error: %s",
        gst_vpx_error_name (status));
    gst_video_decoder_drop_frame (GST_VIDEO_DECODER (dec), frame);
    return GST_FLOW_CUSTOM_SUCCESS_1;
  }
  if (!stream_info.is_kf) {
    GST_WARNING_OBJECT (dec, "No keyframe, skipping");
    gst_video_decoder_drop_frame (GST_VIDEO_DECODER (dec), frame);
    return GST_FLOW_CUSTOM_SUCCESS_1;
  }

  gst_vpx_dec_set_stream_info (dec, &stream_info);
  gst_vpx_dec_set_default_format (dec, GST_VIDEO_FORMAT_I420, stream_info.w,
      stream_info.h);

  cfg.w = stream_info.w;
  cfg.h = stream_info.h;
  cfg.threads = dec->threads;

  caps = vpx_codec_get_caps (vpxclass->codec_algo);

  if (dec->post_processing) {
    if (!(caps & VPX_CODEC_CAP_POSTPROC)) {
      GST_WARNING_OBJECT (dec, "Decoder does not support post processing");
    } else {
      flags |= VPX_CODEC_USE_POSTPROC;
    }
  }

  status =
      vpx_codec_dec_init (&dec->decoder, vpxclass->codec_algo, &cfg, flags);
  if (status != VPX_CODEC_OK) {
    GST_ELEMENT_ERROR (dec, LIBRARY, INIT,
        ("Failed to initialize VP8 decoder"), ("%s",
            gst_vpx_error_name (status)));
    return GST_FLOW_ERROR;
  }

  if ((caps & VPX_CODEC_CAP_POSTPROC) && dec->post_processing) {
    vp8_postproc_cfg_t pp_cfg = { 0, };

    pp_cfg.post_proc_flag = dec->post_processing_flags;
    pp_cfg.deblocking_level = dec->deblocking_level;
    pp_cfg.noise_level = dec->noise_level;

    status = vpx_codec_control (&dec->decoder, VP8_SET_POSTPROC, &pp_cfg);
    if (status != VPX_CODEC_OK) {
      GST_WARNING_OBJECT (dec, "Couldn't set postprocessing settings: %s",
          gst_vpx_error_name (status));
    }
  }
#ifdef HAVE_VPX_1_4
  vpx_codec_set_frame_buffer_functions (&dec->decoder,
      gst_vpx_dec_get_buffer_cb, gst_vpx_dec_release_buffer_cb, dec);
#endif

  dec->decoder_inited = TRUE;

  return GST_FLOW_OK;
}

static GstFlowReturn
gst_vpx_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
{
  GstVPXDec *dec;
  GstFlowReturn ret = GST_FLOW_OK;
  vpx_codec_err_t status;
  vpx_codec_iter_t iter = NULL;
  vpx_image_t *img;
  long decoder_deadline = 0;
  GstClockTimeDiff deadline;
  GstMapInfo minfo;
  GstVPXDecClass *vpxclass;
  GstVideoFormat fmt;

  GST_LOG_OBJECT (decoder, "handle_frame");

  dec = GST_VPX_DEC (decoder);
  vpxclass = GST_VPX_DEC_GET_CLASS (dec);

  if (!dec->decoder_inited) {
    ret = vpxclass->open_codec (dec, frame);
    if (ret == GST_FLOW_CUSTOM_SUCCESS_1)
      return GST_FLOW_OK;
    else if (ret != GST_FLOW_OK)
      return ret;
  }

  deadline = gst_video_decoder_get_max_decode_time (decoder, frame);
  if (deadline < 0) {
    decoder_deadline = 1;
  } else if (deadline == G_MAXINT64) {
    decoder_deadline = 0;
  } else {
    decoder_deadline = MAX (1, deadline / GST_MSECOND);
  }

  if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
    GST_ERROR_OBJECT (dec, "Failed to map input buffer");
    return GST_FLOW_ERROR;
  }

  status = vpx_codec_decode (&dec->decoder,
      minfo.data, minfo.size, NULL, decoder_deadline);

  gst_buffer_unmap (frame->input_buffer, &minfo);

  if (status) {
    GST_VIDEO_DECODER_ERROR (decoder, 1, LIBRARY, ENCODE,
        ("Failed to decode frame"), ("%s", gst_vpx_error_name (status)), ret);
    return ret;
  }

  img = vpx_codec_get_frame (&dec->decoder, &iter);
  if (img) {
    if (vpxclass->get_frame_format (dec, img, &fmt) == FALSE) {
      vpx_img_free (img);
      GST_ELEMENT_ERROR (decoder, LIBRARY, ENCODE,
          ("Failed to decode frame"), ("Unsupported color format %d",
              img->fmt));
      return GST_FLOW_ERROR;
    }

    if (deadline < 0) {
      GST_LOG_OBJECT (dec, "Skipping late frame (%f s past deadline)",
          (double) -deadline / GST_SECOND);
      gst_video_decoder_drop_frame (decoder, frame);
    } else {
      gst_vpx_dec_handle_resolution_change (dec, img, fmt);
#ifdef HAVE_VPX_1_4
      if (img->fb_priv && dec->have_video_meta) {
        frame->output_buffer = gst_vpx_dec_prepare_image (dec, img);
        ret = gst_video_decoder_finish_frame (decoder, frame);
      } else
#endif
      {
        ret = gst_video_decoder_allocate_output_frame (decoder, frame);

        if (ret == GST_FLOW_OK) {
          gst_vpx_dec_image_to_buffer (dec, img, frame->output_buffer);
          ret = gst_video_decoder_finish_frame (decoder, frame);
        } else {
          gst_video_decoder_drop_frame (decoder, frame);
        }
      }
    }

    vpx_img_free (img);

    while ((img = vpx_codec_get_frame (&dec->decoder, &iter))) {
      GST_WARNING_OBJECT (decoder, "Multiple decoded frames... dropping");
      vpx_img_free (img);
    }
  } else {
    /* Invisible frame */
    GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (frame);
    gst_video_decoder_finish_frame (decoder, frame);
  }

  return ret;
}

static gboolean
gst_vpx_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
{
  GstVPXDec *dec = GST_VPX_DEC (bdec);
  GstBufferPool *pool;
  GstStructure *config;

  if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (bdec, query))
    return FALSE;

  g_assert (gst_query_get_n_allocation_pools (query) > 0);
  gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
  g_assert (pool != NULL);

  config = gst_buffer_pool_get_config (pool);
  if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) {
    gst_buffer_pool_config_add_option (config,
        GST_BUFFER_POOL_OPTION_VIDEO_META);
    dec->have_video_meta = TRUE;
  }
  gst_buffer_pool_set_config (pool, config);
  gst_object_unref (pool);

  return TRUE;
}

static void
gst_vpx_dec_set_stream_info (GstVPXDec * dec,
    vpx_codec_stream_info_t * stream_info)
{
  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);
  if (vpxclass->set_stream_info != NULL) {
    vpxclass->set_stream_info (dec, stream_info);
  }
}

static void
gst_vpx_dec_set_default_format (GstVPXDec * dec, GstVideoFormat fmt, int width,
    int height)
{
  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);
  if (vpxclass->set_default_format != NULL) {
    vpxclass->set_default_format (dec, fmt, width, height);
  }
}

static gboolean
gst_vpx_dec_default_frame_format (GstVPXDec * dec, vpx_image_t * img,
    GstVideoFormat * fmt)
{
  if (img->fmt == VPX_IMG_FMT_I420) {
    *fmt = GST_VIDEO_FORMAT_I420;
    return TRUE;
  } else {
    return FALSE;
  }

}

static void
gst_vpx_dec_handle_resolution_change (GstVPXDec * dec, vpx_image_t * img,
    GstVideoFormat fmt)
{
  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);
  if (vpxclass->handle_resolution_change != NULL) {
    vpxclass->handle_resolution_change (dec, img, fmt);
  }
}

#endif /* HAVE_VP8_DECODER ||  HAVE_VP9_DECODER */
