/*
 * Copyright (c) 2013-2015, Freescale Semiconductor, Inc. All rights reserved.
 * Copyright 2017-2018 NXP
 *
 * 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-vpudec
 *
 * VPU based video decoder.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v filesrc location=test.avi ! avidemux !  queue ! vpudec ! videoconvert ! videoscale ! autovideosink
 * ]| The above pipeline decode the test.avi and renders it to the screen.
 * </refsect2>
 */

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

#include <gst/video/video.h>
#include <gst/video/gstvideometa.h>
#include <gst/video/gstvideopool.h>
#include <gst/allocators/gstphysmemory.h>
#include <gst/allocators/gstdmabufmeta.h>
#ifdef USE_ION
#include <gst/allocators/gstionmemory.h>
#endif
#include <drm_fourcc_imx.h>
#include "gstimxcommon.h"
#include "gstvpuallocator.h"
#include "gstvpudec.h"

enum
{
  PROP_0,
  PROP_OUTPUT_FORMAT,
  PROP_ADAPTIVE_FRAME_DROP,
  PROP_FRAMES_PLUS,
  PROP_USE_VPU_MEMORY
};

#define DEFAULT_LOW_LATENCY FALSE
#define DEFAULT_OUTPUT_FORMAT 0
#define DEFAULT_ADAPTIVE_FRAME_DROP TRUE
#define DEFAULT_FRAMES_PLUS 3
/* Default to use VPU memory for video frame buffer as all video frame buffer
 * must registe to VPU. Change video frame buffer will cause close VPU which
 * will cause video stream lost.
 */
#define DEFAULT_USE_VPU_MEMORY TRUE

GST_DEBUG_CATEGORY_STATIC (vpu_dec_debug);
#define GST_CAT_DEFAULT vpu_dec_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);

static void gst_vpu_dec_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_vpu_dec_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static gboolean gst_vpu_dec_open (GstVideoDecoder * bdec);
static gboolean gst_vpu_dec_close (GstVideoDecoder * bdec);
static gboolean gst_vpu_dec_start (GstVideoDecoder * bdec);
static gboolean gst_vpu_dec_stop (GstVideoDecoder * bdec);
static gboolean gst_vpu_dec_set_format (GstVideoDecoder * bdec,
    GstVideoCodecState * state);
static GstFlowReturn gst_vpu_dec_handle_frame (GstVideoDecoder * bdec,
    GstVideoCodecFrame * frame);
static GstFlowReturn gst_vpu_dec_finish (GstVideoDecoder * bdec);
static gboolean gst_vpu_dec_decide_allocation (GstVideoDecoder * bdec,
    GstQuery * query);
static gboolean gst_vpu_dec_reset (GstVideoDecoder * bdec, gboolean hard);

#define gst_vpu_dec_parent_class parent_class
G_DEFINE_TYPE (GstVpuDec, gst_vpu_dec, GST_TYPE_VIDEO_DECODER);

static void
gst_vpu_dec_finalize (GObject * object)
{
  GstVpuDec *dec;
  GST_DEBUG ("finalizing");

  g_return_if_fail (GST_IS_VPU_DEC (object));

  dec = GST_VPU_DEC (object);

  gst_vpu_dec_object_destroy (dec->vpu_dec_object);

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

static void
gst_vpu_dec_class_init (GstVpuDecClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstVideoDecoderClass *vdec_class;

  gobject_class = (GObjectClass *) klass;
  element_class = (GstElementClass *) klass;
  vdec_class = (GstVideoDecoderClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_vpu_dec_finalize);
  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_vpu_dec_set_property);
  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_vpu_dec_get_property);

  g_object_class_install_property (gobject_class, PROP_OUTPUT_FORMAT,
      g_param_spec_enum ("output-format", "output format",
        "set raw video format for output (Y42B NV16 Y444 NV24 only for MJPEG)", \
        GST_TYPE_VPU_DEC_OUTPUT_FORMAT, \
        DEFAULT_OUTPUT_FORMAT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_ADAPTIVE_FRAME_DROP,
      g_param_spec_boolean ("frame-drop", "frame drop",
        "enable adaptive frame drop for smoothly playback", 
          DEFAULT_ADAPTIVE_FRAME_DROP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_FRAMES_PLUS,
      g_param_spec_uint ("frame-plus", "addtionlal frames",
        "set number of addtional frames for smoothly playback", 
          0, 16, DEFAULT_FRAMES_PLUS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_USE_VPU_MEMORY,
      g_param_spec_boolean ("use-vpu-memory", "use vpu memory",
        "use vpu allocate video frame buffer", 
          DEFAULT_USE_VPU_MEMORY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
  gst_element_class_add_pad_template (element_class,
          gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
          gst_vpu_dec_object_get_sink_caps ()));
  gst_element_class_add_pad_template (element_class,
          gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
          gst_vpu_dec_object_get_src_caps ()));
  gst_element_class_set_static_metadata (element_class,
      "IMX VPU-based video decoder", "Codec/Decoder/Video",
      "Decode compressed video to raw data",
      IMX_GST_PLUGIN_AUTHOR);

  vdec_class->open = GST_DEBUG_FUNCPTR (gst_vpu_dec_open);
  vdec_class->close = GST_DEBUG_FUNCPTR (gst_vpu_dec_close);
  vdec_class->start = GST_DEBUG_FUNCPTR (gst_vpu_dec_start);
  vdec_class->stop = GST_DEBUG_FUNCPTR (gst_vpu_dec_stop);
  vdec_class->set_format = GST_DEBUG_FUNCPTR (gst_vpu_dec_set_format);
  vdec_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vpu_dec_handle_frame);
  vdec_class->finish = GST_DEBUG_FUNCPTR (gst_vpu_dec_finish);
  vdec_class->decide_allocation = GST_DEBUG_FUNCPTR (gst_vpu_dec_decide_allocation);
  vdec_class->reset = GST_DEBUG_FUNCPTR (gst_vpu_dec_reset);

  GST_DEBUG_CATEGORY_INIT (vpu_dec_debug, "vpudec", 0, "VPU decoder");
  GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
}

static void
gst_vpu_dec_init (GstVpuDec * dec)
{
  GST_DEBUG ("initializing");

  dec->vpu_dec_object = gst_vpu_dec_object_new ();

  GST_VPU_DEC_LOW_LATENCY (dec->vpu_dec_object) = DEFAULT_LOW_LATENCY;
  GST_VPU_DEC_OUTPUT_FORMAT (dec->vpu_dec_object) = DEFAULT_OUTPUT_FORMAT;
  GST_VPU_DEC_FRAME_DROP (dec->vpu_dec_object) = DEFAULT_ADAPTIVE_FRAME_DROP;
  GST_VPU_DEC_FRAMES_PLUS (dec->vpu_dec_object) = DEFAULT_FRAMES_PLUS;
  GST_VPU_DEC_USE_VPU_MEMORY (dec->vpu_dec_object) = DEFAULT_USE_VPU_MEMORY;
  GST_VPU_DEC_MIN_BUF_CNT (dec->vpu_dec_object) = 0;

  /* As VPU can support stream mode. need call parser before decode */
  gst_video_decoder_set_packetized (GST_VIDEO_DECODER (dec), TRUE);
}

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

  g_return_if_fail (GST_IS_VPU_DEC (object));
  dec = GST_VPU_DEC (object);

  switch (prop_id) {
    case PROP_OUTPUT_FORMAT:
      g_value_set_enum (value, GST_VPU_DEC_OUTPUT_FORMAT (dec->vpu_dec_object));
      break;
    case PROP_ADAPTIVE_FRAME_DROP:
      g_value_set_boolean (value, GST_VPU_DEC_FRAME_DROP (dec->vpu_dec_object));
      break;
    case PROP_FRAMES_PLUS:
      g_value_set_uint (value, GST_VPU_DEC_FRAMES_PLUS (dec->vpu_dec_object));
      break;
    case PROP_USE_VPU_MEMORY:
      g_value_set_boolean (value, GST_VPU_DEC_USE_VPU_MEMORY (dec->vpu_dec_object));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

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

  g_return_if_fail (GST_IS_VPU_DEC (object));
  dec = GST_VPU_DEC (object);

  switch (prop_id) {
    case PROP_OUTPUT_FORMAT:
      GST_VPU_DEC_OUTPUT_FORMAT (dec->vpu_dec_object) = g_value_get_enum (value);
      break;
    case PROP_ADAPTIVE_FRAME_DROP:
      GST_VPU_DEC_FRAME_DROP (dec->vpu_dec_object) = g_value_get_boolean (value);
      break;
    case PROP_FRAMES_PLUS:
      GST_VPU_DEC_FRAMES_PLUS (dec->vpu_dec_object) = g_value_get_uint (value);
      break;
    case PROP_USE_VPU_MEMORY:
      GST_VPU_DEC_USE_VPU_MEMORY (dec->vpu_dec_object) = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_vpu_dec_open (GstVideoDecoder * bdec)
{
  GstVpuDec *dec = (GstVpuDec *) bdec;

  dec->vpu_dec_object->use_my_pool = FALSE;
  dec->vpu_dec_object->use_my_allocator = FALSE;
  dec->vpu_dec_object->drm_modifier = 0;
  dec->vpu_dec_object->drm_modifier_pre = 0;

  return gst_vpu_dec_object_open (dec->vpu_dec_object);
}

static gboolean
gst_vpu_dec_close (GstVideoDecoder * bdec)
{
  GstVpuDec *dec = (GstVpuDec *) bdec;

  return gst_vpu_dec_object_close (dec->vpu_dec_object);
}

static gboolean
gst_vpu_dec_start (GstVideoDecoder * bdec)
{
  GstVpuDec *dec = (GstVpuDec *) bdec;

  return gst_vpu_dec_object_start (dec->vpu_dec_object);
}

static gboolean
gst_vpu_dec_stop (GstVideoDecoder * bdec)
{
  GstVpuDec *dec = (GstVpuDec *) bdec;

  return gst_vpu_dec_object_stop (dec->vpu_dec_object);
}

static gboolean
gst_vpu_dec_set_format (GstVideoDecoder * bdec, GstVideoCodecState * state)
{
  GstVpuDec *dec = (GstVpuDec *) bdec;
  GstQuery *query;
  gboolean is_live;

  query = gst_query_new_latency ();
  is_live = FALSE;
  if (gst_pad_peer_query (GST_VIDEO_DECODER_SINK_PAD (bdec), query)) {
    gst_query_parse_latency (query, &is_live, NULL, NULL);
  }
  gst_query_unref (query);

  // Hantro VPU can get best performance with low lantency.
  if (is_live || IS_HANTRO()) {
    GST_INFO_OBJECT (dec, "Pipeline is live, set VPU to low latency mode.\n");
    GST_VPU_DEC_LOW_LATENCY (dec->vpu_dec_object) = TRUE;
  } else {
    GST_INFO_OBJECT (dec, "Pipeline isn't live, set VPU to non-latency mode.\n");
    GST_VPU_DEC_LOW_LATENCY (dec->vpu_dec_object) = FALSE;
  }

  return gst_vpu_dec_object_config (dec->vpu_dec_object, bdec, state);
}

static GstFlowReturn
gst_vpu_dec_handle_frame (GstVideoDecoder * bdec, GstVideoCodecFrame * frame)
{
  GstVpuDec *dec = (GstVpuDec *) bdec;

  return gst_vpu_dec_object_decode (dec->vpu_dec_object, bdec, frame);
}

static GstFlowReturn
gst_vpu_dec_finish (GstVideoDecoder * bdec)
{
  GstVpuDec *dec = (GstVpuDec *) bdec;

  return gst_vpu_dec_object_decode (dec->vpu_dec_object, bdec, NULL);
}

static gboolean
gst_vpu_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
{
  GstVpuDec *dec = (GstVpuDec *) bdec;
  GstCaps *outcaps;
  GstBufferPool *pool = NULL;
  guint size, min, max;
  GstAllocator *allocator = NULL;
  GstAllocationParams params;
  GstStructure *config;
  gboolean update_pool, update_allocator;
  GstVideoInfo vinfo;
  gboolean alloc_has_meta = FALSE;
  guint alloc_index;

  gst_query_parse_allocation (query, &outcaps, NULL);
  gst_video_info_init (&vinfo);
  gst_video_info_from_caps (&vinfo, outcaps);

  GST_DEBUG_OBJECT (dec, "gst_vpu_dec_decide_allocation");

  /* we got configuration from our peer or the decide_allocation method,
   * parse them */
  if (gst_query_get_n_allocation_params (query) > 0) {
    /* try the allocator */
    gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
    update_allocator = TRUE;
  } else {
    allocator = NULL;
    gst_allocation_params_init (&params);
    update_allocator = FALSE;
  }

  if (gst_query_get_n_allocation_pools (query) > 0) {
    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
    size = MAX (size, vinfo.size);
    if (min < 3) min = 3;
    update_pool = TRUE;
  } else {
    pool = NULL;
    size = vinfo.size;
    /* Allocate 3 more buffer as video sink will hold buffer after reuse the
     * buffer pool */
    max = 0;
    min = 3;

    update_pool = FALSE;
  }

  alloc_has_meta = gst_query_find_allocation_meta (query,
      GST_DMABUF_META_API_TYPE, &alloc_index);

  GST_DEBUG_OBJECT (dec, "vpudec query has dmabuf meta %d", alloc_has_meta);

  if (IS_HANTRO() || IS_AMPHION()) {
    if (alloc_has_meta) {
      const GstStructure *params;
      gchar *meta;
      gint j, len;

      gst_query_parse_nth_allocation_meta (query, alloc_index, &params);
      GST_DEBUG_OBJECT (dec, "Expected field 'GstDmabufMeta' in structure: %" GST_PTR_FORMAT,
          params);
      if (params) {
        const GValue *vdrm_modifier = gst_structure_get_value (params, "dmabuf.drm_modifier");
        if (GST_VALUE_HOLDS_LIST (vdrm_modifier)) {
          len = gst_value_list_get_size (vdrm_modifier);
          for (j = 0; j < len; j++) {
            const GValue *val;
            val = gst_value_list_get_value (vdrm_modifier, j);
            guint64 drm_modifier = g_value_get_uint64 (val);
            GST_DEBUG_OBJECT (dec, "dmabuf meta has modifier: %lld", drm_modifier);
            if (IS_AMPHION() && drm_modifier == DRM_FORMAT_MOD_AMPHION_TILED)
              dec->vpu_dec_object->drm_modifier = drm_modifier;
            else if (IS_HANTRO() && drm_modifier == DRM_FORMAT_MOD_VSI_G2_TILED_COMPRESSED
                && dec->vpu_dec_object->is_g2 == TRUE)
              dec->vpu_dec_object->drm_modifier = drm_modifier;
            else if (IS_HANTRO() && drm_modifier == DRM_FORMAT_MOD_VSI_G1_TILED
                && dec->vpu_dec_object->is_g2 == FALSE)
              dec->vpu_dec_object->drm_modifier = drm_modifier;
            else {
              GST_WARNING_OBJECT (dec, "video sink can't support modifier: %lld",
                  DRM_FORMAT_MOD_AMPHION_TILED);
            }
          }
        } else if (meta = gst_structure_to_string (params)) {
          guint64 drm_modifier;
          GST_DEBUG_OBJECT (dec, "dmabuf meta has modifier: %s", meta);
          sscanf (meta, "GstDmabufMeta, dmabuf.drm_modifier=(guint64){ %lld };", &drm_modifier);
          GST_DEBUG_OBJECT (dec, "dmabuf meta has modifier: %lld", drm_modifier);
          if (drm_modifier == DRM_FORMAT_MOD_AMPHION_TILED) {
            GST_DEBUG_OBJECT (dec, "video sink support modifier: %lld", drm_modifier);
            dec->vpu_dec_object->drm_modifier = drm_modifier;
          } else {
            GST_WARNING_OBJECT (dec, "video sink can't support modifier: %lld",
                DRM_FORMAT_MOD_AMPHION_TILED);
          }
        }
      }
    }
  }

  if (IS_HANTRO() && (!dec->vpu_dec_object->implement_config
        || dec->vpu_dec_object->force_linear))
    dec->vpu_dec_object->drm_modifier = 0;
  //FIXME: handle video track selection.
  if (IS_HANTRO() && dec->vpu_dec_object->drm_modifier_pre != dec->vpu_dec_object->drm_modifier) {
    int config_param = 0;
    GstVpuDecObject * vpu_dec_object = dec->vpu_dec_object;
    gint height_align;
    gint width_align;
    guint i;

    VPU_DecConfig(dec->vpu_dec_object->handle, VPU_DEC_CONF_ENABLE_TILED, &config_param);

    VPU_DecGetInitialInfo(dec->vpu_dec_object->handle, &(dec->vpu_dec_object->init_info));
    dec->vpu_dec_object->frame_size = dec->vpu_dec_object->init_info.nFrameSize;

    width_align = DEFAULT_FRAME_BUFFER_ALIGNMENT_H;
    if (vpu_dec_object->init_info.nPicWidth % width_align)
      vpu_dec_object->video_align.padding_right = width_align \
        - vpu_dec_object->init_info.nPicWidth % width_align;

    for (i = 0; i < GST_VIDEO_MAX_PLANES; i++)
      vpu_dec_object->video_align.stride_align[i] = width_align - 1;

    vpu_dec_object->width_paded = vpu_dec_object->init_info.nPicWidth \
                                  + vpu_dec_object->video_align.padding_right;

    GST_DEBUG_OBJECT (dec, "width: %d height: %d paded width: %d paded height: %d\n", \
        vpu_dec_object->init_info.nPicWidth, vpu_dec_object->init_info.nPicHeight, \
        vpu_dec_object->width_paded, vpu_dec_object->height_paded);

    dec->vpu_dec_object->drm_modifier_pre = dec->vpu_dec_object->drm_modifier;
  }
  GST_DEBUG_OBJECT (dec, "used modifier: %lld", dec->vpu_dec_object->drm_modifier);

  if (dec->vpu_dec_object->vpu_need_reconfig == FALSE
    && dec->vpu_dec_object->use_my_pool
    && dec->vpu_dec_object->use_my_allocator) {
    /* video track selection case. don't change pool for smoothly video track
     * selection */
    GstStructure *config;
    GstCaps *caps;
    guint size_pre, min_buffers, max_buffers;
    GstBufferPool *pool_pre = gst_video_decoder_get_buffer_pool (bdec);

    config = gst_buffer_pool_get_config (pool_pre);
    gst_buffer_pool_config_get_params (config, &caps, &size_pre, &min_buffers,
                  &max_buffers);

    GST_DEBUG_OBJECT (dec, "outcaps caps %" GST_PTR_FORMAT, outcaps);
    GST_DEBUG_OBJECT (dec, "VPU output caps %" GST_PTR_FORMAT, caps);
    if (gst_caps_is_equal (outcaps, caps)) {
      GST_DEBUG_OBJECT (dec, "using previous buffer pool.\n");

      if (update_pool)
        gst_query_set_nth_allocation_pool (query, 0, pool_pre, size_pre, \
            min_buffers, max_buffers);
      else
        gst_query_add_allocation_pool (query, pool_pre, size_pre, min_buffers, \
            max_buffers);

      gst_structure_free (config);
      gst_object_unref (pool_pre);
      if (allocator)
        gst_object_unref (allocator);
      if (pool)
        gst_object_unref (pool);

      return TRUE;
    }

    gst_structure_free (config);
    gst_object_unref (pool_pre);
  }

  if (GST_VPU_DEC_USE_VPU_MEMORY (dec->vpu_dec_object)) {
    if (allocator)
      gst_object_unref (allocator);
    allocator = NULL;
    if (pool)
      gst_object_unref (pool);
    pool = NULL;
  }

  if (allocator == NULL
      || !(GST_IS_ALLOCATOR_PHYMEM (allocator)
        || GST_IS_PHYS_MEMORY_ALLOCATOR (allocator))) {
    /* no allocator or isn't physical memory allocator. VPU need continus
     * physical memory. use VPU memory allocator. */
    if (allocator) {
      gst_object_unref (allocator);
    }
    GST_DEBUG_OBJECT (dec, "using vpu allocator.\n");
#ifdef USE_ION
    allocator = gst_ion_allocator_obtain ();
#endif
    if (!allocator) {
      allocator = gst_vpu_allocator_obtain();
    }
    dec->vpu_dec_object->use_my_allocator = TRUE;
  } else {
    dec->vpu_dec_object->use_my_allocator = FALSE;
  }

  if (pool) {
    /* need set video alignment. */
    if (!gst_buffer_pool_has_option (pool, \
          GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) {
      GST_DEBUG_OBJECT (dec, "buffer pool hasn't video alignment option, unref it.\n");
      gst_object_unref (pool);
      pool = NULL;
    }
  }

  dec->vpu_dec_object->pool_alignment_checked = FALSE;
  if (pool == NULL) {
    /* no pool, we can make our own */
    GST_DEBUG_OBJECT (dec, "no pool, making new pool");
    pool = gst_video_buffer_pool_new ();
    dec->vpu_dec_object->use_my_pool = TRUE;
  } else {
    dec->vpu_dec_object->use_my_pool = FALSE;
  }

  max = min += GST_VPU_DEC_MIN_BUF_CNT (dec->vpu_dec_object) \
        + GST_VPU_DEC_FRAMES_PLUS (dec->vpu_dec_object);
  GST_VPU_DEC_ACTUAL_BUF_CNT (dec->vpu_dec_object) = min;
  params.align = GST_VPU_DEC_BUF_ALIGNMENT (dec->vpu_dec_object);
  params.flags |= GST_MEMORY_FLAG_READONLY;
  GST_INFO_OBJECT (dec, "vpudec frame buffer count: %d.\n", \
      GST_VPU_DEC_ACTUAL_BUF_CNT (dec->vpu_dec_object));

  size = MAX (size, dec->vpu_dec_object->frame_size);
  GST_DEBUG_OBJECT (dec, "video frame size %d", size);

  /* now configure */
  config = gst_buffer_pool_get_config (pool);

  if (!gst_buffer_pool_config_has_option (config, \
        GST_BUFFER_POOL_OPTION_VIDEO_META)) {
    gst_buffer_pool_config_add_option (config,
        GST_BUFFER_POOL_OPTION_VIDEO_META);
  }
  if (!gst_buffer_pool_config_has_option (config, \
        GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) {
    gst_buffer_pool_config_add_option (config, \
        GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
  }

  gst_buffer_pool_config_set_video_alignment (config, \
      &GST_VPU_DEC_VIDEO_ALIGNMENT (dec->vpu_dec_object));
  gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
  gst_buffer_pool_config_set_allocator (config, allocator, &params);
  gst_buffer_pool_set_config (pool, config);

  if (update_allocator)
    gst_query_set_nth_allocation_param (query, 0, allocator, &params);
  else
    gst_query_add_allocation_param (query, allocator, &params);
  if (allocator)
    gst_object_unref (allocator);

  if (update_pool)
    gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
  else
    gst_query_add_allocation_pool (query, pool, size, min, max);

  if (pool)
    gst_object_unref (pool);

  if (!gst_vpu_dec_object_config (dec->vpu_dec_object, bdec, NULL)) {
    GST_DEBUG ("gst_vpu_dec_object_reopen fail.");
    return FALSE;
  }

  return TRUE;
}

static gboolean
gst_vpu_dec_reset (GstVideoDecoder * bdec, gboolean hard)
{
  GstVpuDec *dec = (GstVpuDec *) bdec;

  if (hard) {
    return gst_vpu_dec_object_flush (bdec, dec->vpu_dec_object);
  } else {
    return TRUE;
  }
}

