/* VP9
 * Copyright (C) 2006 David Schleef <ds@schleef.org>
 * Copyright (C) 2008,2009,2010 Entropy Wave Inc
 * Copyright (C) 2010-2013 Sebastian Dröge <slomo@circular-chaos.org>
 *
 * 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.
 *
 */
/**
 * SECTION:element-vp9dec
 * @see_also: vp9enc, matroskademux
 *
 * This element decodes VP9 streams into raw video.
 * <ulink url="http://www.webmproject.org">VP9</ulink> is a royalty-free
 * video codec maintained by <ulink url="http://www.google.com/">Google
 * </ulink>. It's the successor of On2 VP3, which was the base of the
 * Theora video codec.
 *
 * <refsect2>
 * <title>Example pipeline</title>
 * |[
 * gst-launch-1.0 -v filesrc location=videotestsrc.webm ! matroskademux ! vp9dec ! videoconvert ! videoscale ! autovideosink
 * ]| This example pipeline will decode a WebM stream and decodes the VP9 video.
 * </refsect2>
 */

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

#ifdef HAVE_VP9_DECODER

#include <string.h>

#include "gstvp8utils.h"
#include "gstvp9dec.h"

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

GST_DEBUG_CATEGORY_STATIC (gst_vp9dec_debug);
#define GST_CAT_DEFAULT gst_vp9dec_debug

#define VP9_DECODER_VIDEO_TAG "VP9 video"

static void gst_vp9_dec_set_stream_info (GstVPXDec * dec,
    vpx_codec_stream_info_t * stream_info);
static gboolean gst_vp9_dec_get_valid_format (GstVPXDec * dec,
    vpx_image_t * img, GstVideoFormat * fmt);
static void gst_vp9_dec_handle_resolution_change (GstVPXDec * dec,
    vpx_image_t * img, GstVideoFormat fmt);

static GstStaticPadTemplate gst_vp9_dec_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-vp9")
    );

static GstStaticPadTemplate gst_vp9_dec_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ I420, YV12, Y42B, Y444 }"))
    );

#define parent_class gst_vp9_dec_parent_class
G_DEFINE_TYPE (GstVP9Dec, gst_vp9_dec, GST_TYPE_VPX_DEC);

static void
gst_vp9_dec_class_init (GstVP9DecClass * klass)
{
  GstElementClass *element_class;
  GstVPXDecClass *vpx_class;

  element_class = GST_ELEMENT_CLASS (klass);
  vpx_class = GST_VPX_DEC_CLASS (klass);

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_vp9_dec_src_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_vp9_dec_sink_template));

  gst_element_class_set_static_metadata (element_class,
      "On2 VP9 Decoder",
      "Codec/Decoder/Video",
      "Decode VP9 video streams", "David Schleef <ds@entropywave.com>, "
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  vpx_class->video_codec_tag = VP9_DECODER_VIDEO_TAG;
  vpx_class->codec_algo = &vpx_codec_vp9_dx_algo;
  vpx_class->set_stream_info = GST_DEBUG_FUNCPTR (gst_vp9_dec_set_stream_info);
  vpx_class->get_frame_format =
      GST_DEBUG_FUNCPTR (gst_vp9_dec_get_valid_format);
  vpx_class->handle_resolution_change =
      GST_DEBUG_FUNCPTR (gst_vp9_dec_handle_resolution_change);

  GST_DEBUG_CATEGORY_INIT (gst_vp9dec_debug, "vp9dec", 0, "VP9 Decoder");
}

static void
gst_vp9_dec_init (GstVP9Dec * gst_vp9_dec)
{
  GST_DEBUG_OBJECT (gst_vp9_dec, "gst_vp9_dec_init");
}

static void
gst_vp9_dec_set_stream_info (GstVPXDec * dec,
    vpx_codec_stream_info_t * stream_info)
{
  /* FIXME: peek_stream_info() does not return valid values, take input caps */
  stream_info->w = dec->input_state->info.width;
  stream_info->h = dec->input_state->info.height;
  return;
}

static gboolean
gst_vp9_dec_get_valid_format (GstVPXDec * dec, vpx_image_t * img,
    GstVideoFormat * fmt)
{
  switch (img->fmt) {
    case VPX_IMG_FMT_I420:
      *fmt = GST_VIDEO_FORMAT_I420;
      return TRUE;

    case VPX_IMG_FMT_YV12:
      *fmt = GST_VIDEO_FORMAT_YV12;
      return TRUE;

    case VPX_IMG_FMT_I422:
      *fmt = GST_VIDEO_FORMAT_Y42B;
      return TRUE;

    case VPX_IMG_FMT_I444:
      *fmt = GST_VIDEO_FORMAT_Y444;
      return TRUE;

    default:
      return FALSE;
  }
}

static void
gst_vp9_dec_handle_resolution_change (GstVPXDec * dec, vpx_image_t * img,
    GstVideoFormat fmt)
{
  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);

  if (!dec->output_state || dec->output_state->info.finfo->format != fmt ||
      dec->output_state->info.width != img->d_w ||
      dec->output_state->info.height != img->d_h) {
    gboolean send_tags = !dec->output_state;

    if (dec->output_state)
      gst_video_codec_state_unref (dec->output_state);

    dec->output_state =
        gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec),
        fmt, img->d_w, img->d_h, dec->input_state);
    gst_video_decoder_negotiate (GST_VIDEO_DECODER (dec));

    if (send_tags)
      vpxclass->send_tags (dec);
  }
}

#endif /* HAVE_VP9_DECODER */
