/* 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 = NULL;
  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;

  /* We're sometimes called without a frame */
  if (!frame)
    return 0;

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

  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));
    return GST_FLOW_CUSTOM_SUCCESS_1;
  }
  if (!stream_info.is_kf) {
    GST_WARNING_OBJECT (dec, "No keyframe, skipping");
    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;

  if (dec->threads > 0)
    cfg.threads = dec->threads;
  else
    cfg.threads = g_get_num_processors ();

  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) {
      gst_video_decoder_drop_frame (decoder, frame);
      return GST_FLOW_OK;
    } else if (ret != GST_FLOW_OK) {
      gst_video_codec_frame_unref (frame);
      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");
    gst_video_codec_frame_unref (frame);
    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);
    gst_video_codec_frame_unref (frame);
    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));
      gst_video_codec_frame_unref (frame);
      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 */
