/* GStreamer
 * Copyright (C) <2016> Carlos Rafael Giani <dv at pseudoterminal dot 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-rawvideoparse
 *
 * This element parses incoming data as raw video frames and timestamps these.
 * It also handles seek queries in said raw video data, and ensures that output
 * buffers contain exactly one frame, even if the input buffers contain only
 * partial frames or multiple frames. In the former case, it will continue to
 * receive buffers until there is enough input data to output one frame. In the
 * latter case, it will extract the first frame in the buffer and output it, then
 * the second one etc. until the remaining unparsed bytes aren't enough to form
 * a complete frame, and it will then continue as described in the earlier case.
 *
 * The element implements the properties and sink caps configuration as specified
 * in the #GstRawBaseParse documentation. The properties configuration can be
 * modified by using the width, height, pixel-aspect-ratio, framerate, interlaced,
 * top-field-first, plane-strides, plane-offsets, and frame-stride properties.
 *
 * If the properties configuration is used, plane strides and offsets will be
 * computed by using gst_video_info_set_format(). This can be overridden by passing
 * GValueArrays to the plane-offsets and plane-strides properties. When this is
 * done, these custom offsets and strides are used later even if new width,
 * height, format etc. property values might be set. To switch back to computed
 * plane strides & offsets, pass NULL to one or both of the plane-offset and
 * plane-array properties.
 *
 * The frame stride property is useful in cases where there is extra data between
 * the frames (for example, trailing metadata, or headers). The parser calculates 
 * the actual frame size out of the other properties and compares it with this
 * frame-stride value. If the frame stride is larger than the calculated size,
 * then the extra bytes after the end of the frame are skipped. For example, with
 * 8-bit grayscale frames and a frame size of 100x10 pixels and a frame stride of
 * 1500 bytes, there are 500 excess bytes at the end of the actual frame which
 * are then skipped. It is safe to set the frame stride to a value that is smaller
 * than the actual frame size (in fact, its default value is 0); if it is smaller,
 * then no trailing data will be skipped.
 *
 * If a framerate of 0 Hz is set (for example, 0/1), then output buffers will have
 * no duration set. The first output buffer will have a PTS 0, all subsequent ones
 * an unset PTS.
 *
 * <refsect2>
 * <title>Example pipelines</title>
 * |[
 * gst-launch-1.0 filesrc location=video.raw ! rawvideoparse use-sink-caps=false \
 *         width=500 height=400 format=y444 ! autovideosink
 * ]| Read raw data from a local file and parse it as video data with 500x400 pixels
 * and Y444 video format.
 * |[
 * gst-launch-1.0 filesrc location=video.raw ! queue ! "video/x-raw, width=320, \
 *         height=240, format=I420, framerate=1/1" ! rawvideoparse \
 *         use-sink-caps=true ! autovideosink
 * ]| Read raw data from a local file and parse it as video data with 320x240 pixels
 * and I420 video format. The queue element here is to force push based scheduling.
 * See the documentation in #GstRawBaseParse for the reason why.
 * </refsect2>
 */

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

/* FIXME: GValueArray is deprecated, but there is currently no viabla alternative
 * See https://bugzilla.gnome.org/show_bug.cgi?id=667228 */
#define GLIB_DISABLE_DEPRECATION_WARNINGS

#include <string.h>
#include "gstrawvideoparse.h"
#include "unalignedvideo.h"


GST_DEBUG_CATEGORY_STATIC (raw_video_parse_debug);
#define GST_CAT_DEFAULT raw_video_parse_debug


enum
{
  PROP_0,
  PROP_WIDTH,
  PROP_HEIGHT,
  PROP_FORMAT,
  PROP_PIXEL_ASPECT_RATIO,
  PROP_FRAMERATE,
  PROP_INTERLACED,
  PROP_TOP_FIELD_FIRST,
  PROP_PLANE_STRIDES,
  PROP_PLANE_OFFSETS,
  PROP_FRAME_STRIDE
};


#define DEFAULT_WIDTH                 320
#define DEFAULT_HEIGHT                240
#define DEFAULT_FORMAT                GST_VIDEO_FORMAT_I420
#define DEFAULT_PIXEL_ASPECT_RATIO_N  1
#define DEFAULT_PIXEL_ASPECT_RATIO_D  1
#define DEFAULT_FRAMERATE_N           25
#define DEFAULT_FRAMERATE_D           1
#define DEFAULT_INTERLACED            FALSE
#define DEFAULT_TOP_FIELD_FIRST       FALSE
#define DEFAULT_FRAME_STRIDE          0


#define GST_RAW_VIDEO_PARSE_CAPS \
        GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) "; "


static GstStaticPadTemplate static_sink_template =
    GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_UNALIGNED_RAW_VIDEO_CAPS "; " GST_RAW_VIDEO_PARSE_CAPS)
    );


static GstStaticPadTemplate static_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_RAW_VIDEO_PARSE_CAPS)
    );


#define gst_raw_video_parse_parent_class parent_class
G_DEFINE_TYPE (GstRawVideoParse, gst_raw_video_parse, GST_TYPE_RAW_BASE_PARSE);


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

static gboolean gst_raw_video_parse_stop (GstBaseParse * parse);

static gboolean gst_raw_video_parse_set_current_config (GstRawBaseParse *
    raw_base_parse, GstRawBaseParseConfig config);
static GstRawBaseParseConfig
gst_raw_video_parse_get_current_config (GstRawBaseParse * raw_base_parse);
static gboolean gst_raw_video_parse_set_config_from_caps (GstRawBaseParse *
    raw_base_parse, GstRawBaseParseConfig config, GstCaps * caps);
static gboolean gst_raw_video_parse_get_caps_from_config (GstRawBaseParse *
    raw_base_parse, GstRawBaseParseConfig config, GstCaps ** caps);
static gsize gst_raw_video_parse_get_config_frame_size (GstRawBaseParse *
    raw_base_parse, GstRawBaseParseConfig config);
static guint gst_raw_video_parse_get_max_frames_per_buffer (GstRawBaseParse *
    raw_base_parse, GstRawBaseParseConfig config);
static gboolean gst_raw_video_parse_is_config_ready (GstRawBaseParse *
    raw_base_parse, GstRawBaseParseConfig config);
static gboolean gst_raw_video_parse_process (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config, GstBuffer * in_data, gsize total_num_in_bytes,
    gsize num_valid_in_bytes, GstBuffer ** processed_data);
static gboolean gst_raw_video_parse_is_unit_format_supported (GstRawBaseParse *
    raw_base_parse, GstFormat format);
static void gst_raw_video_parse_get_units_per_second (GstRawBaseParse *
    raw_base_parse, GstFormat format, GstRawBaseParseConfig config,
    gsize * units_per_sec_n, gsize * units_per_sec_d);

static gint gst_raw_video_parse_get_overhead_size (GstRawBaseParse *
    raw_base_parse, GstRawBaseParseConfig config);

static gboolean gst_raw_video_parse_is_using_sink_caps (GstRawVideoParse *
    raw_video_parse);
static GstRawVideoParseConfig
    * gst_raw_video_parse_get_config_ptr (GstRawVideoParse * raw_video_parse,
    GstRawBaseParseConfig config);

static void gst_raw_video_parse_init_config (GstRawVideoParseConfig * config);
static void gst_raw_video_parse_update_info (GstRawVideoParseConfig * config);



static void
gst_raw_video_parse_class_init (GstRawVideoParseClass * klass)
{
  GObjectClass *object_class;
  GstElementClass *element_class;
  GstBaseParseClass *baseparse_class;
  GstRawBaseParseClass *rawbaseparse_class;

  GST_DEBUG_CATEGORY_INIT (raw_video_parse_debug, "rawvideoparse", 0,
      "rawvideoparse element");

  object_class = G_OBJECT_CLASS (klass);
  element_class = GST_ELEMENT_CLASS (klass);
  baseparse_class = GST_BASE_PARSE_CLASS (klass);
  rawbaseparse_class = GST_RAW_BASE_PARSE_CLASS (klass);

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&static_sink_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&static_src_template));

  object_class->set_property =
      GST_DEBUG_FUNCPTR (gst_raw_video_parse_set_property);
  object_class->get_property =
      GST_DEBUG_FUNCPTR (gst_raw_video_parse_get_property);

  baseparse_class->stop = GST_DEBUG_FUNCPTR (gst_raw_video_parse_stop);

  rawbaseparse_class->set_current_config =
      GST_DEBUG_FUNCPTR (gst_raw_video_parse_set_current_config);
  rawbaseparse_class->get_current_config =
      GST_DEBUG_FUNCPTR (gst_raw_video_parse_get_current_config);
  rawbaseparse_class->set_config_from_caps =
      GST_DEBUG_FUNCPTR (gst_raw_video_parse_set_config_from_caps);
  rawbaseparse_class->get_caps_from_config =
      GST_DEBUG_FUNCPTR (gst_raw_video_parse_get_caps_from_config);
  rawbaseparse_class->get_config_frame_size =
      GST_DEBUG_FUNCPTR (gst_raw_video_parse_get_config_frame_size);
  rawbaseparse_class->get_max_frames_per_buffer =
      GST_DEBUG_FUNCPTR (gst_raw_video_parse_get_max_frames_per_buffer);
  rawbaseparse_class->is_config_ready =
      GST_DEBUG_FUNCPTR (gst_raw_video_parse_is_config_ready);
  rawbaseparse_class->process = GST_DEBUG_FUNCPTR (gst_raw_video_parse_process);
  rawbaseparse_class->is_unit_format_supported =
      GST_DEBUG_FUNCPTR (gst_raw_video_parse_is_unit_format_supported);
  rawbaseparse_class->get_units_per_second =
      GST_DEBUG_FUNCPTR (gst_raw_video_parse_get_units_per_second);
  rawbaseparse_class->get_overhead_size =
      GST_DEBUG_FUNCPTR (gst_raw_video_parse_get_overhead_size);

  g_object_class_install_property (object_class,
      PROP_WIDTH,
      g_param_spec_int ("width",
          "Width",
          "Width of frames in raw stream",
          0, G_MAXINT, DEFAULT_WIDTH,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_HEIGHT,
      g_param_spec_int ("height",
          "Height",
          "Height of frames in raw stream",
          0, G_MAXINT,
          DEFAULT_HEIGHT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_FORMAT,
      g_param_spec_enum ("format",
          "Format",
          "Format of frames in raw stream",
          GST_TYPE_VIDEO_FORMAT,
          DEFAULT_FORMAT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_FRAMERATE,
      gst_param_spec_fraction ("framerate",
          "Frame rate",
          "Rate of frames in raw stream",
          0, 1, G_MAXINT, 1,
          DEFAULT_FRAMERATE_N, DEFAULT_FRAMERATE_D,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_PIXEL_ASPECT_RATIO,
      gst_param_spec_fraction ("pixel-aspect-ratio",
          "Pixel aspect ratio",
          "Pixel aspect ratio of frames in raw stream",
          1, 100, 100, 1,
          DEFAULT_PIXEL_ASPECT_RATIO_N, DEFAULT_PIXEL_ASPECT_RATIO_D,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_INTERLACED,
      g_param_spec_boolean ("interlaced",
          "Interlaced flag",
          "True if frames in raw stream are interlaced",
          DEFAULT_INTERLACED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_TOP_FIELD_FIRST,
      g_param_spec_boolean ("top-field-first",
          "Top field first",
          "True if top field in frames in raw stream come first (not used if frames aren't interlaced)",
          DEFAULT_INTERLACED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_PLANE_STRIDES,
      g_param_spec_value_array ("plane-strides",
          "Plane strides",
          "Strides of the planets in bytes",
          g_param_spec_uint ("plane-stride",
              "Plane stride",
              "Stride of the n-th plane in bytes (0 = stride equals width*bytes-per-pixel)",
              0, G_MAXUINT,
              0,
              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_PLANE_OFFSETS,
      g_param_spec_value_array ("plane-offsets",
          "Plane offsets",
          "Offsets of the planets in bytes",
          g_param_spec_uint ("plane-offset",
              "Plane offset",
              "Offset of the n-th plane in bytes",
              0, G_MAXUINT,
              0,
              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_FRAME_STRIDE,
      g_param_spec_uint ("frame-stride",
          "Frame stride",
          "Stride between whole frames (0 = frames are tightly packed together)",
          0, G_MAXUINT,
          DEFAULT_FRAME_STRIDE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );

  gst_element_class_set_static_metadata (element_class,
      "rawvideoparse",
      "Codec/Parser/Video",
      "Converts unformatted data streams into timestamped raw video frames",
      "Carlos Rafael Giani <dv@pseudoterminal.org>");
}


static void
gst_raw_video_parse_init (GstRawVideoParse * raw_video_parse)
{
  gst_raw_video_parse_init_config (&(raw_video_parse->properties_config));
  gst_raw_video_parse_init_config (&(raw_video_parse->sink_caps_config));

  /* As required by GstRawBaseParse, ensure that the current configuration
   * is initially set to be the properties config */
  raw_video_parse->current_config = &(raw_video_parse->properties_config);

  /* Properties config must be valid from the start, so set its ready value
   * to TRUE, and make sure its bpf value is valid. */
  raw_video_parse->properties_config.ready = TRUE;
  raw_video_parse->properties_config.top_field_first = DEFAULT_TOP_FIELD_FIRST;
  raw_video_parse->properties_config.frame_stride = DEFAULT_FRAME_STRIDE;
}


static void
gst_raw_video_parse_set_property (GObject * object, guint prop_id,
    GValue const *value, GParamSpec * pspec)
{
  GstBaseParse *base_parse = GST_BASE_PARSE (object);
  GstRawBaseParse *raw_base_parse = GST_RAW_BASE_PARSE (object);
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (object);
  GstRawVideoParseConfig *props_cfg = &(raw_video_parse->properties_config);

  /* All properties are handled similarly:
   * - if the new value is the same as the current value, nothing is done
   * - the parser lock is held while the new value is set
   * - if the properties config is the current config, the source caps are
   *   invalidated to ensure that the code in handle_frame pushes a new CAPS
   *   event out
   * - properties that affect the video frame size call the function to update
   *   the info and also call gst_base_parse_set_min_frame_size() to ensure
   *   that the minimum frame size can hold 1 frame (= one sample for each
   *   channel); to ensure that the min frame size includes any extra padding,
   *   it is set to the result of gst_raw_video_parse_get_config_frame_size()
   * - property configuration values that require video info updates aren't
   *   written directory into the video info structure, but in the extra
   *   fields instead (gst_raw_video_parse_update_info() then copies the values
   *   from these fields into the video info); see the documentation inside
   *   gst_raw_video_parse_update_info() for the reason why
   */

  switch (prop_id) {
    case PROP_WIDTH:
    {
      gint new_width = g_value_get_int (value);

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      if (new_width != props_cfg->width) {
        props_cfg->width = new_width;
        gst_raw_video_parse_update_info (props_cfg);

        if (!gst_raw_video_parse_is_using_sink_caps (raw_video_parse)) {
          gst_raw_base_parse_invalidate_src_caps (raw_base_parse);
          gst_base_parse_set_min_frame_size (base_parse,
              gst_raw_video_parse_get_config_frame_size (raw_base_parse,
                  GST_RAW_BASE_PARSE_CONFIG_PROPERTIES));
        }
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_HEIGHT:
    {
      gint new_height = g_value_get_int (value);

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      if (new_height != props_cfg->height) {
        props_cfg->height = new_height;
        gst_raw_video_parse_update_info (props_cfg);

        if (!gst_raw_video_parse_is_using_sink_caps (raw_video_parse)) {
          gst_raw_base_parse_invalidate_src_caps (raw_base_parse);
          gst_base_parse_set_min_frame_size (base_parse,
              gst_raw_video_parse_get_config_frame_size (raw_base_parse,
                  GST_RAW_BASE_PARSE_CONFIG_PROPERTIES));
        }
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_FORMAT:
    {
      GstVideoFormat new_format = g_value_get_enum (value);

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      if (new_format != props_cfg->format) {
        props_cfg->format = new_format;
        gst_raw_video_parse_update_info (props_cfg);

        if (!gst_raw_video_parse_is_using_sink_caps (raw_video_parse)) {
          gst_raw_base_parse_invalidate_src_caps (raw_base_parse);
          gst_base_parse_set_min_frame_size (base_parse,
              gst_raw_video_parse_get_config_frame_size (raw_base_parse,
                  GST_RAW_BASE_PARSE_CONFIG_PROPERTIES));
        }
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_PIXEL_ASPECT_RATIO:
    {
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      /* The pixel aspect ratio does not affect the video frame size,
       * so it is just set directly without any updates */
      props_cfg->pixel_aspect_ratio_n =
          GST_VIDEO_INFO_PAR_N (&(props_cfg->info)) =
          gst_value_get_fraction_numerator (value);
      props_cfg->pixel_aspect_ratio_d =
          GST_VIDEO_INFO_PAR_D (&(props_cfg->info)) =
          gst_value_get_fraction_denominator (value);
      GST_DEBUG_OBJECT (raw_video_parse, "setting pixel aspect ratio to %u/%u",
          props_cfg->pixel_aspect_ratio_n, props_cfg->pixel_aspect_ratio_d);

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_FRAMERATE:
    {
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      /* The framerate does not affect the video frame size,
       * so it is just set directly without any updates */
      props_cfg->framerate_n = GST_VIDEO_INFO_FPS_N (&(props_cfg->info)) =
          gst_value_get_fraction_numerator (value);
      props_cfg->framerate_d = GST_VIDEO_INFO_FPS_D (&(props_cfg->info)) =
          gst_value_get_fraction_denominator (value);
      GST_DEBUG_OBJECT (raw_video_parse, "setting framerate to %u/%u",
          props_cfg->framerate_n, props_cfg->framerate_d);

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_INTERLACED:
    {
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      /* Interlacing does not affect the video frame size,
       * so it is just set directly without any updates */
      props_cfg->interlaced = g_value_get_boolean (value);
      GST_VIDEO_INFO_INTERLACE_MODE (&(props_cfg->info)) =
          props_cfg->interlaced ? GST_VIDEO_INTERLACE_MODE_INTERLEAVED :
          GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);

      break;
    }

    case PROP_TOP_FIELD_FIRST:
    {
      /* The top-field-first flag is a detail related to
       * interlacing, so no video info update is needed */

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      props_cfg->top_field_first = g_value_get_boolean (value);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_PLANE_STRIDES:
    {
      GValueArray *valarray = g_value_get_boxed (value);
      guint n_planes;
      guint i;

      /* If no valarray is given, then disable custom
       * plane strides & offsets and stick to the
       * standard computed ones */
      if (valarray == NULL) {
        GST_DEBUG_OBJECT (raw_video_parse,
            "custom plane strides & offsets disabled");
        props_cfg->custom_plane_strides = FALSE;
        gst_raw_video_parse_update_info (props_cfg);
        break;
      }

      /* Sanity check - reject empty arrays */
      if ((valarray != NULL) && (valarray->n_values == 0)) {
        GST_ELEMENT_ERROR (raw_video_parse, LIBRARY, SETTINGS,
            ("plane strides property holds an empty array"), (NULL));
        break;
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      n_planes = GST_VIDEO_INFO_N_PLANES (&(props_cfg->info));

      /* Check that the valarray holds the right number of values */
      if (valarray->n_values != n_planes) {
        GST_ELEMENT_ERROR (raw_video_parse, LIBRARY, SETTINGS,
            ("incorrect number of elements in plane strides property"),
            ("expected: %u, got: %u", n_planes, valarray->n_values));
        GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
        break;
      }

      /* Copy the values to the stride array */
      for (i = 0; i < n_planes; ++i) {
        GValue *val = g_value_array_get_nth (valarray, i);
        props_cfg->plane_strides[i] = g_value_get_uint (val);
        GST_DEBUG_OBJECT (raw_video_parse, "plane #%u stride: %d", i,
            props_cfg->plane_strides[i]);
      }

      props_cfg->custom_plane_strides = TRUE;

      gst_raw_video_parse_update_info (props_cfg);

      if (!gst_raw_video_parse_is_using_sink_caps (raw_video_parse))
        gst_base_parse_set_min_frame_size (base_parse,
            gst_raw_video_parse_get_config_frame_size (raw_base_parse,
                GST_RAW_BASE_PARSE_CONFIG_PROPERTIES));

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_PLANE_OFFSETS:
    {
      GValueArray *valarray = g_value_get_boxed (value);
      guint n_planes;
      guint i;

      /* If no valarray is given, then disable custom
       * plane strides & offsets and stick to the
       * standard computed ones */
      if (valarray == NULL) {
        GST_DEBUG_OBJECT (raw_video_parse,
            "custom plane strides & offsets disabled");
        props_cfg->custom_plane_strides = FALSE;
        gst_raw_video_parse_update_info (props_cfg);
        break;
      }

      /* Sanity check - reject empty arrays */
      if ((valarray != NULL) && (valarray->n_values == 0)) {
        GST_ELEMENT_ERROR (raw_video_parse, LIBRARY, SETTINGS,
            ("plane offsets property holds an empty array"), (NULL));
        break;
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      n_planes = GST_VIDEO_INFO_N_PLANES (&(props_cfg->info));

      /* Check that the valarray holds the right number of values */
      if (valarray->n_values != n_planes) {
        GST_ELEMENT_ERROR (raw_video_parse, LIBRARY, SETTINGS,
            ("incorrect number of elements in plane offsets property"),
            ("expected: %u, got: %u", n_planes, valarray->n_values));
        GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
        break;
      }

      /* Copy the values to the offset array */
      for (i = 0; i < n_planes; ++i) {
        GValue *val = g_value_array_get_nth (valarray, i);
        props_cfg->plane_offsets[i] = g_value_get_uint (val);
        GST_DEBUG_OBJECT (raw_video_parse, "plane #%u offset: %" G_GSIZE_FORMAT,
            i, props_cfg->plane_offsets[i]);
      }

      props_cfg->custom_plane_strides = TRUE;

      gst_raw_video_parse_update_info (props_cfg);

      if (!gst_raw_video_parse_is_using_sink_caps (raw_video_parse))
        gst_base_parse_set_min_frame_size (base_parse,
            gst_raw_video_parse_get_config_frame_size (raw_base_parse,
                GST_RAW_BASE_PARSE_CONFIG_PROPERTIES));

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_FRAME_STRIDE:
    {
      /* The frame stride does not affect the video frame size,
       * so it is just set directly without any updates */

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      props_cfg->frame_stride = g_value_get_uint (value);
      gst_raw_video_parse_update_info (props_cfg);
      if (!gst_raw_video_parse_is_using_sink_caps (raw_video_parse))
        gst_base_parse_set_min_frame_size (base_parse,
            gst_raw_video_parse_get_config_frame_size (raw_base_parse,
                GST_RAW_BASE_PARSE_CONFIG_PROPERTIES));
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);

      break;
    }

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


static void
gst_raw_video_parse_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (object);
  GstRawVideoParseConfig *props_cfg = &(raw_video_parse->properties_config);

  switch (prop_id) {
    case PROP_WIDTH:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      g_value_set_int (value, props_cfg->width);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;

    case PROP_HEIGHT:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      g_value_set_int (value, props_cfg->height);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;

    case PROP_FORMAT:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      g_value_set_enum (value, props_cfg->format);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;

    case PROP_PIXEL_ASPECT_RATIO:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      gst_value_set_fraction (value, props_cfg->pixel_aspect_ratio_n,
          props_cfg->pixel_aspect_ratio_d);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);

      break;

    case PROP_FRAMERATE:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      gst_value_set_fraction (value, props_cfg->framerate_n,
          props_cfg->framerate_d);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;

    case PROP_INTERLACED:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      g_value_set_boolean (value, props_cfg->interlaced);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;

    case PROP_TOP_FIELD_FIRST:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      g_value_set_boolean (value, props_cfg->top_field_first);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;

    case PROP_PLANE_STRIDES:
    {
      guint i, n_planes;
      GValue val = G_VALUE_INIT;
      GValueArray *valarray;

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      n_planes = GST_VIDEO_INFO_N_PLANES (&(props_cfg->info));
      valarray = g_value_array_new (n_planes);
      g_value_init (&val, G_TYPE_UINT);

      for (i = 0; i < n_planes; ++i) {
        g_value_set_uint (&val, props_cfg->plane_strides[i]);
        g_value_array_insert (valarray, i, &val);
      }

      g_value_unset (&val);

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);

      /* Pass on ownership to the value array,
       * since we don't need it anymore */
      g_value_take_boxed (value, valarray);
      break;
    }

    case PROP_PLANE_OFFSETS:
    {
      guint i, n_planes;
      GValue val = G_VALUE_INIT;
      GValueArray *valarray;

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      n_planes = GST_VIDEO_INFO_N_PLANES (&(props_cfg->info));
      valarray = g_value_array_new (n_planes);
      g_value_init (&val, G_TYPE_UINT);

      for (i = 0; i < n_planes; ++i) {
        g_value_set_uint (&val, props_cfg->plane_offsets[i]);
        g_value_array_insert (valarray, i, &val);
      }

      g_value_unset (&val);

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);

      /* Pass on ownership to the value array,
       * since we don't need it anymore */
      g_value_take_boxed (value, valarray);
      break;
    }

    case PROP_FRAME_STRIDE:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      g_value_set_uint (value, raw_video_parse->properties_config.frame_stride);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


static gboolean
gst_raw_video_parse_stop (GstBaseParse * parse)
{
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (parse);

  /* Sink caps config is not ready until caps come in.
   * We are stopping processing, the element is being reset,
   * so the config has to be un-readied.
   * (Since the properties config is not depending on caps,
   * its ready status is always TRUE.) */
  raw_video_parse->sink_caps_config.ready = FALSE;

  return GST_BASE_PARSE_CLASS (parent_class)->stop (parse);
}


static gboolean
gst_raw_video_parse_set_current_config (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config)
{
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (raw_base_parse);

  switch (config) {
    case GST_RAW_BASE_PARSE_CONFIG_PROPERTIES:
      raw_video_parse->current_config = &(raw_video_parse->properties_config);
      break;

    case GST_RAW_BASE_PARSE_CONFIG_SINKCAPS:
      raw_video_parse->current_config = &(raw_video_parse->sink_caps_config);
      break;

    default:
      g_assert_not_reached ();
  }

  return TRUE;
}


static GstRawBaseParseConfig
gst_raw_video_parse_get_current_config (GstRawBaseParse * raw_base_parse)
{
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (raw_base_parse);
  return gst_raw_video_parse_is_using_sink_caps (raw_video_parse) ?
      GST_RAW_BASE_PARSE_CONFIG_SINKCAPS : GST_RAW_BASE_PARSE_CONFIG_PROPERTIES;
}


static gboolean
gst_raw_video_parse_set_config_from_caps (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config, GstCaps * caps)
{
  int i;
  GstStructure *structure;
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (raw_base_parse);
  GstRawVideoParseConfig *config_ptr =
      gst_raw_video_parse_get_config_ptr (raw_video_parse, config);

  g_assert (caps != NULL);

  /* Caps might get copied, and the copy needs to be unref'd.
   * Also, the caller retains ownership over the original caps.
   * So, to make this mechanism also work with cases where the
   * caps are *not* copied, ref the original caps here first. */
  gst_caps_ref (caps);

  structure = gst_caps_get_structure (caps, 0);

  /* For unaligned raw data, the output caps stay the same,
   * except that video/x-unaligned-raw becomes video/x-raw,
   * since the parser aligns the frame data */
  if (gst_structure_has_name (structure, "video/x-unaligned-raw")) {
    /* Copy the caps to be able to modify them */
    GstCaps *new_caps = gst_caps_copy (caps);
    gst_caps_unref (caps);
    caps = new_caps;

    /* Change the media type to video/x-raw , otherwise
     * gst_video_info_from_caps() won't work */
    structure = gst_caps_get_structure (caps, 0);
    gst_structure_set_name (structure, "video/x-raw");
  }

  config_ptr->ready = gst_video_info_from_caps (&(config_ptr->info), caps);

  if (config_ptr->ready) {
    config_ptr->width = GST_VIDEO_INFO_WIDTH (&(config_ptr->info));
    config_ptr->height = GST_VIDEO_INFO_HEIGHT (&(config_ptr->info));
    config_ptr->pixel_aspect_ratio_n =
        GST_VIDEO_INFO_PAR_N (&(config_ptr->info));
    config_ptr->pixel_aspect_ratio_d =
        GST_VIDEO_INFO_PAR_D (&(config_ptr->info));
    config_ptr->framerate_n = GST_VIDEO_INFO_FPS_N (&(config_ptr->info));
    config_ptr->framerate_d = GST_VIDEO_INFO_FPS_D (&(config_ptr->info));
    config_ptr->interlaced = GST_VIDEO_INFO_IS_INTERLACED (&(config_ptr->info));
    config_ptr->height = GST_VIDEO_INFO_HEIGHT (&(config_ptr->info));
    config_ptr->top_field_first = 0;
    config_ptr->frame_stride = 0;

    for (i = 0; i < GST_VIDEO_MAX_PLANES; ++i) {
      config_ptr->plane_offsets[i] =
          GST_VIDEO_INFO_PLANE_OFFSET (&(config_ptr->info), i);
      config_ptr->plane_strides[i] =
          GST_VIDEO_INFO_PLANE_STRIDE (&(config_ptr->info), i);
    }
  }

  gst_caps_unref (caps);

  return config_ptr->ready;
}


static gboolean
gst_raw_video_parse_get_caps_from_config (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config, GstCaps ** caps)
{
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (raw_base_parse);
  GstRawVideoParseConfig *config_ptr =
      gst_raw_video_parse_get_config_ptr (raw_video_parse, config);

  g_assert (caps != NULL);

  *caps = gst_video_info_to_caps (&(config_ptr->info));

  return *caps != NULL;
}


static gsize
gst_raw_video_parse_get_config_frame_size (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config)
{
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (raw_base_parse);
  GstRawVideoParseConfig *config_ptr =
      gst_raw_video_parse_get_config_ptr (raw_video_parse, config);
  return MAX (GST_VIDEO_INFO_SIZE (&(config_ptr->info)),
      (gsize) (config_ptr->frame_stride));
}


static guint
gst_raw_video_parse_get_max_frames_per_buffer (G_GNUC_UNUSED GstRawBaseParse *
    raw_base_parse, G_GNUC_UNUSED GstRawBaseParseConfig config)
{
  /* We want exactly one frame per buffer */
  return 1;
}


static gboolean
gst_raw_video_parse_is_config_ready (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config)
{
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (raw_base_parse);
  return gst_raw_video_parse_get_config_ptr (raw_video_parse, config)->ready;
}


static gboolean
gst_raw_video_parse_process (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config, GstBuffer * in_data,
    G_GNUC_UNUSED gsize total_num_in_bytes,
    G_GNUC_UNUSED gsize num_valid_in_bytes, GstBuffer ** processed_data)
{
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (raw_base_parse);
  GstRawVideoParseConfig *config_ptr =
      gst_raw_video_parse_get_config_ptr (raw_video_parse, config);
  guint frame_flags = 0;
  GstVideoInfo *video_info = &(config_ptr->info);
  GstVideoMeta *videometa;
  GstBuffer *out_data;

  /* In case of extra padding bytes, get a subbuffer without the padding bytes.
   * Otherwise, just add the video meta. */
  if (GST_VIDEO_INFO_SIZE (video_info) < config_ptr->frame_stride) {
    *processed_data = out_data =
        gst_buffer_copy_region (in_data,
        GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS |
        GST_BUFFER_COPY_MEMORY, 0, GST_VIDEO_INFO_SIZE (video_info));
  } else {
    out_data = in_data;
    *processed_data = NULL;
  }

  if (config_ptr->interlaced) {
    GST_BUFFER_FLAG_SET (out_data, GST_VIDEO_BUFFER_FLAG_INTERLACED);
    frame_flags |= GST_VIDEO_FRAME_FLAG_INTERLACED;

    if (config_ptr->top_field_first) {
      GST_BUFFER_FLAG_SET (out_data, GST_VIDEO_BUFFER_FLAG_TFF);
      frame_flags |= GST_VIDEO_FRAME_FLAG_TFF;
    } else
      GST_BUFFER_FLAG_UNSET (out_data, GST_VIDEO_BUFFER_FLAG_TFF);
  }

  /* Remove any existing videometa - it will be replaced by the new videometa
   * from here */
  while ((videometa = gst_buffer_get_video_meta (out_data))) {
    GST_LOG_OBJECT (raw_base_parse, "removing existing videometa from buffer");
    gst_buffer_remove_meta (out_data, (GstMeta *) videometa);
  }

  gst_buffer_add_video_meta_full (out_data,
      frame_flags,
      config_ptr->format,
      config_ptr->width,
      config_ptr->height,
      GST_VIDEO_INFO_N_PLANES (video_info),
      config_ptr->plane_offsets, config_ptr->plane_strides);


  return TRUE;
}


static gboolean
gst_raw_video_parse_is_unit_format_supported (G_GNUC_UNUSED GstRawBaseParse *
    raw_base_parse, GstFormat format)
{
  switch (format) {
    case GST_FORMAT_BYTES:
    case GST_FORMAT_DEFAULT:
      return TRUE;
    default:
      return FALSE;
  }
}


static void
gst_raw_video_parse_get_units_per_second (GstRawBaseParse * raw_base_parse,
    GstFormat format, GstRawBaseParseConfig config, gsize * units_per_sec_n,
    gsize * units_per_sec_d)
{
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (raw_base_parse);
  GstRawVideoParseConfig *config_ptr =
      gst_raw_video_parse_get_config_ptr (raw_video_parse, config);

  switch (format) {
    case GST_FORMAT_BYTES:
    {
      gsize framesize = GST_VIDEO_INFO_SIZE (&(config_ptr->info));
      gint64 n = framesize * config_ptr->framerate_n;
      gint64 d = config_ptr->framerate_d;
      gint64 common_div = gst_util_greatest_common_divisor_int64 (n, d);
      GST_DEBUG_OBJECT (raw_video_parse,
          "n: %" G_GINT64_FORMAT " d: %" G_GINT64_FORMAT " common divisor: %"
          G_GINT64_FORMAT, n, d, common_div);

      /* Divide numerator and denominator by greatest common divisor.
       * This minimizes the risk of integer overflows in the baseparse class. */
      *units_per_sec_n = n / common_div;
      *units_per_sec_d = d / common_div;

      break;
    }

    case GST_FORMAT_DEFAULT:
    {
      *units_per_sec_n = config_ptr->framerate_n;
      *units_per_sec_d = config_ptr->framerate_d;
      break;
    }

    default:
      g_assert_not_reached ();
  }
}


static gint
gst_raw_video_parse_get_overhead_size (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config)
{
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (raw_base_parse);
  GstRawVideoParseConfig *config_ptr =
      gst_raw_video_parse_get_config_ptr (raw_video_parse, config);
  gint64 frame_size = GST_VIDEO_INFO_SIZE (&(config_ptr->info));
  gint64 frame_stride = config_ptr->frame_stride;

  /* In the video parser, the overhead is defined by the difference between
   * the frame stride and the actual frame size. If the former is larger,
   * then the additional bytes are considered padding bytes and get ignored
   * by the base class. */

  GST_LOG_OBJECT (raw_video_parse,
      "frame size: %" G_GINT64_FORMAT "  frame stride: %" G_GINT64_FORMAT,
      frame_size, frame_stride);

  return (frame_size < frame_stride) ? (gint) (frame_stride - frame_size) : 0;
}


static gboolean
gst_raw_video_parse_is_using_sink_caps (GstRawVideoParse * raw_video_parse)
{
  return raw_video_parse->current_config ==
      &(raw_video_parse->sink_caps_config);
}


static GstRawVideoParseConfig *
gst_raw_video_parse_get_config_ptr (GstRawVideoParse * raw_video_parse,
    GstRawBaseParseConfig config)
{
  g_assert (raw_video_parse->current_config != NULL);

  switch (config) {
    case GST_RAW_BASE_PARSE_CONFIG_PROPERTIES:
      return &(raw_video_parse->properties_config);

    case GST_RAW_BASE_PARSE_CONFIG_SINKCAPS:
      return &(raw_video_parse->sink_caps_config);

    default:
      g_assert (raw_video_parse->current_config != NULL);
      return raw_video_parse->current_config;
  }
}


static void
gst_raw_video_parse_init_config (GstRawVideoParseConfig * config)
{
  int i;

  config->ready = FALSE;
  config->width = DEFAULT_WIDTH;
  config->height = DEFAULT_HEIGHT;
  config->format = DEFAULT_FORMAT;
  config->pixel_aspect_ratio_n = DEFAULT_PIXEL_ASPECT_RATIO_N;
  config->pixel_aspect_ratio_d = DEFAULT_PIXEL_ASPECT_RATIO_D;
  config->framerate_n = DEFAULT_FRAMERATE_N;
  config->framerate_d = DEFAULT_FRAMERATE_D;
  config->interlaced = DEFAULT_INTERLACED;

  config->top_field_first = DEFAULT_TOP_FIELD_FIRST;
  config->frame_stride = DEFAULT_FRAME_STRIDE;

  gst_video_info_set_format (&(config->info), DEFAULT_FORMAT, DEFAULT_WIDTH,
      DEFAULT_HEIGHT);
  for (i = 0; i < GST_VIDEO_MAX_PLANES; ++i) {
    config->plane_offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (&(config->info), i);
    config->plane_strides[i] = GST_VIDEO_INFO_PLANE_STRIDE (&(config->info), i);
  }
}


static void
gst_raw_video_parse_update_info (GstRawVideoParseConfig * config)
{
  guint i;
  guint n_planes;
  guint last_plane;
  gsize last_plane_offset, last_plane_size;
  GstVideoInfo *info = &(config->info);

  GST_DEBUG ("updating info with width %u height %u format %s "
      " custom plane strides&offsets %d", config->width, config->height,
      gst_video_format_to_string (config->format),
      config->custom_plane_strides);

  gst_video_info_set_format (info, config->format, config->width,
      config->height);

  GST_VIDEO_INFO_PAR_N (info) = config->pixel_aspect_ratio_n;
  GST_VIDEO_INFO_PAR_D (info) = config->pixel_aspect_ratio_d;
  GST_VIDEO_INFO_FPS_N (info) = config->framerate_n;
  GST_VIDEO_INFO_FPS_D (info) = config->framerate_d;
  GST_VIDEO_INFO_INTERLACE_MODE (info) =
      config->interlaced ? GST_VIDEO_INTERLACE_MODE_INTERLEAVED :
      GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;

  /* Check if there are custom plane strides & offsets that need to be preserved */
  if (config->custom_plane_strides) {
    /* In case there are, overwrite the offsets&strides computed by
     * gst_video_info_set_format with the custom ones */
    for (i = 0; i < GST_VIDEO_MAX_PLANES; ++i) {
      GST_VIDEO_INFO_PLANE_OFFSET (info, i) = config->plane_offsets[i];
      GST_VIDEO_INFO_PLANE_STRIDE (info, i) = config->plane_strides[i];
    }
  } else {
    /* No custom planes&offsets; copy the computed ones into
     * the plane_offsets & plane_strides arrays to ensure they
     * are equal to the ones in the videoinfo */
    for (i = 0; i < GST_VIDEO_MAX_PLANES; ++i) {
      config->plane_offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (info, i);
      config->plane_strides[i] = GST_VIDEO_INFO_PLANE_STRIDE (info, i);
    }
  }

  n_planes = GST_VIDEO_INFO_N_PLANES (info);
  if (n_planes < 1)
    n_planes = 1;

  /* Figure out what plane is the physically last one. Typically
   * this is the last plane in the list (= at index n_planes-1).
   * However, this is not guaranteed, so we have to scan the offsets
   * to find the last plane. */
  last_plane_offset = 0;
  last_plane = 0;
  for (i = 0; i < n_planes; ++i) {
    gsize plane_offset = GST_VIDEO_INFO_PLANE_OFFSET (info, i);
    if (plane_offset >= last_plane_offset) {
      last_plane = i;
      last_plane_offset = plane_offset;
    }
  }

  last_plane_size =
      GST_VIDEO_INFO_PLANE_STRIDE (info,
      last_plane) * GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo,
      last_plane, config->height);

  GST_VIDEO_INFO_SIZE (info) = last_plane_offset + last_plane_size;

  GST_DEBUG ("last plane #%u:  offset: %" G_GSIZE_FORMAT " size: %"
      G_GSIZE_FORMAT " => frame size minus extra padding: %" G_GSIZE_FORMAT,
      last_plane, last_plane_offset, last_plane_size,
      GST_VIDEO_INFO_SIZE (info));
}
