<commit_before>/*
 *  Copyright (C) 2013 Intel Corporation
 *    Author: <NAME> <<EMAIL>>
 *  Copyright (C) 2016 Intel Corporation
 *    Author: <NAME> <<EMAIL>>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1
 *  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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301 USA
 */

#include "gstmfxvideobufferpool.h"
#include "gstmfxvideomemory.h"

#include <gst-libs/mfx/gstmfxdisplay.h>

GST_DEBUG_CATEGORY_STATIC (gst_debug_mfxvideopool);
#define GST_CAT_DEFAULT gst_debug_mfxvideopool

G_DEFINE_TYPE (GstMfxVideoBufferPool,
    gst_mfx_video_buffer_pool, GST_TYPE_BUFFER_POOL);

struct _GstMfxVideoBufferPoolPrivate
{
  GstVideoInfo video_info[2];
  guint video_info_index;
  GstAllocator *allocator;
  GstVideoInfo alloc_info;
  GstMfxDisplay *display;
  guint has_video_meta:1;
  guint use_dmabuf_memory:1;
  gboolean memtype_is_system;
};

#define GST_MFX_VIDEO_BUFFER_POOL_GET_PRIVATE(obj) \
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_MFX_TYPE_VIDEO_BUFFER_POOL, \
    GstMfxVideoBufferPoolPrivate))

static void
gst_mfx_video_buffer_pool_finalize (GObject * object)
{
  GstMfxVideoBufferPoolPrivate *const priv =
      GST_MFX_VIDEO_BUFFER_POOL (object)->priv;

  gst_mfx_display_unref (priv->display);
  g_clear_object (&priv->allocator);

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

static const gchar **
gst_mfx_video_buffer_pool_get_options (GstBufferPool * pool)
{
  static const gchar *g_options[] = {
    GST_BUFFER_POOL_OPTION_VIDEO_META,
    GST_BUFFER_POOL_OPTION_MFX_VIDEO_META,
    GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT,
    NULL,
  };

  return g_options;
}

static gboolean
gst_mfx_video_buffer_pool_set_config (GstBufferPool * pool,
    GstStructure * config)
{
  GstMfxVideoBufferPoolPrivate *const priv =
      GST_MFX_VIDEO_BUFFER_POOL (pool)->priv;
  GstCaps *caps = NULL;
  GstVideoInfo *const cur_vip = &priv->video_info[priv->video_info_index];
  GstVideoInfo *const new_vip = &priv->video_info[!priv->video_info_index];
  GstAllocator *allocator;
  gboolean changed_caps, use_dmabuf_memory;

  if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
    goto error_invalid_config;
  if (!caps || !gst_video_info_from_caps (new_vip, caps))
    goto error_no_caps;

  use_dmabuf_memory = gst_buffer_pool_config_has_option (config,
      GST_BUFFER_POOL_OPTION_DMABUF_MEMORY);
  if (priv->use_dmabuf_memory != use_dmabuf_memory) {
    priv->use_dmabuf_memory = use_dmabuf_memory;
    g_clear_object (&priv->allocator);
  }

  changed_caps = !priv->allocator ||
      GST_VIDEO_INFO_FORMAT (cur_vip) != GST_VIDEO_INFO_FORMAT (new_vip) ||
      GST_VIDEO_INFO_WIDTH (cur_vip) != GST_VIDEO_INFO_WIDTH (new_vip) ||
      GST_VIDEO_INFO_HEIGHT (cur_vip) != GST_VIDEO_INFO_HEIGHT (new_vip);

  if (changed_caps) {
    if (use_dmabuf_memory)
      allocator = gst_dmabuf_allocator_new ();
    else
      allocator = gst_mfx_video_allocator_new (priv->display, new_vip,
          priv->memtype_is_system);

    if (!allocator)
      goto error_create_allocator;
    gst_object_replace ((GstObject **) & priv->allocator,
        GST_OBJECT_CAST (allocator));
    gst_object_unref (allocator);
    priv->video_info_index ^= 1;

    priv->alloc_info = *new_vip;
  }

  if (!gst_buffer_pool_config_has_option (config,
          GST_BUFFER_POOL_OPTION_MFX_VIDEO_META))
    goto error_no_mfx_video_meta_option;

  priv->has_video_meta = gst_buffer_pool_config_has_option (config,
      GST_BUFFER_POOL_OPTION_VIDEO_META);

  return
      GST_BUFFER_POOL_CLASS
      (gst_mfx_video_buffer_pool_parent_class)->set_config (pool, config);

  /* ERRORS */
error_invalid_config:
  {
    GST_ERROR ("invalid config");
    return FALSE;
  }
error_no_caps:
  {
    GST_ERROR ("no valid caps in config");
    return FALSE;
  }
error_create_allocator:
  {
    GST_ERROR ("failed to create GstMfxVideoAllocator object");
    return FALSE;
  }
error_no_mfx_video_meta_option:
  {
    GST_ERROR ("no GstMfxVideoMeta option");
    return FALSE;
  }
}

static GstFlowReturn
gst_mfx_video_buffer_pool_alloc_buffer (GstBufferPool * pool,
    GstBuffer ** out_buffer_ptr, GstBufferPoolAcquireParams * params)
{
  GstMfxVideoBufferPoolPrivate *const priv =
      GST_MFX_VIDEO_BUFFER_POOL (pool)->priv;
  GstMfxVideoMeta *meta;
  GstMemory *mem;
  GstBuffer *buffer;

  if (!priv->allocator)
    goto error_no_allocator;

  meta = gst_mfx_video_meta_new ();
  if (!meta)
    goto error_create_meta;

  buffer = gst_buffer_new ();
  if (buffer)
    gst_buffer_set_mfx_video_meta (buffer, meta);

  if (!buffer)
    goto error_create_buffer;

  if (priv->use_dmabuf_memory)
    mem = gst_mfx_dmabuf_memory_new (priv->allocator, priv->display,
        &priv->alloc_info, meta);
  else
    mem = gst_mfx_video_memory_new (priv->allocator, meta);

  if (!mem)<commit_msg>VideoBufferPool: Fixed the wrong order checking statement.<commit_after>/*
 *  Copyright (C) 2013 Intel Corporation
 *    Author: <NAME> <<EMAIL>>
 *  Copyright (C) 2016 Intel Corporation
 *    Author: <NAME> <<EMAIL>>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1
 *  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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301 USA
 */

#include "gstmfxvideobufferpool.h"
#include "gstmfxvideomemory.h"

#include <gst-libs/mfx/gstmfxdisplay.h>

GST_DEBUG_CATEGORY_STATIC (gst_debug_mfxvideopool);
#define GST_CAT_DEFAULT gst_debug_mfxvideopool

G_DEFINE_TYPE (GstMfxVideoBufferPool,
    gst_mfx_video_buffer_pool, GST_TYPE_BUFFER_POOL);

struct _GstMfxVideoBufferPoolPrivate
{
  GstVideoInfo video_info[2];
  guint video_info_index;
  GstAllocator *allocator;
  GstVideoInfo alloc_info;
  GstMfxDisplay *display;
  guint has_video_meta:1;
  guint use_dmabuf_memory:1;
  gboolean memtype_is_system;
};

#define GST_MFX_VIDEO_BUFFER_POOL_GET_PRIVATE(obj) \
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_MFX_TYPE_VIDEO_BUFFER_POOL, \
    GstMfxVideoBufferPoolPrivate))

static void
gst_mfx_video_buffer_pool_finalize (GObject * object)
{
  GstMfxVideoBufferPoolPrivate *const priv =
      GST_MFX_VIDEO_BUFFER_POOL (object)->priv;

  gst_mfx_display_unref (priv->display);
  g_clear_object (&priv->allocator);

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

static const gchar **
gst_mfx_video_buffer_pool_get_options (GstBufferPool * pool)
{
  static const gchar *g_options[] = {
    GST_BUFFER_POOL_OPTION_VIDEO_META,
    GST_BUFFER_POOL_OPTION_MFX_VIDEO_META,
    GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT,
    NULL,
  };

  return g_options;
}

static gboolean
gst_mfx_video_buffer_pool_set_config (GstBufferPool * pool,
    GstStructure * config)
{
  GstMfxVideoBufferPoolPrivate *const priv =
      GST_MFX_VIDEO_BUFFER_POOL (pool)->priv;
  GstCaps *caps = NULL;
  GstVideoInfo *const cur_vip = &priv->video_info[priv->video_info_index];
  GstVideoInfo *const new_vip = &priv->video_info[!priv->video_info_index];
  GstAllocator *allocator;
  gboolean changed_caps, use_dmabuf_memory;

  if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
    goto error_invalid_config;
  if (!caps || !gst_video_info_from_caps (new_vip, caps))
    goto error_no_caps;

  use_dmabuf_memory = gst_buffer_pool_config_has_option (config,
      GST_BUFFER_POOL_OPTION_DMABUF_MEMORY);
  if (priv->use_dmabuf_memory != use_dmabuf_memory) {
    priv->use_dmabuf_memory = use_dmabuf_memory;
    g_clear_object (&priv->allocator);
  }

  changed_caps = !priv->allocator ||
      GST_VIDEO_INFO_FORMAT (cur_vip) != GST_VIDEO_INFO_FORMAT (new_vip) ||
      GST_VIDEO_INFO_WIDTH (cur_vip) != GST_VIDEO_INFO_WIDTH (new_vip) ||
      GST_VIDEO_INFO_HEIGHT (cur_vip) != GST_VIDEO_INFO_HEIGHT (new_vip);

  if (changed_caps) {
    if (use_dmabuf_memory)
      allocator = gst_dmabuf_allocator_new ();
    else
      allocator = gst_mfx_video_allocator_new (priv->display, new_vip,
          priv->memtype_is_system);

    if (!allocator)
      goto error_create_allocator;
    gst_object_replace ((GstObject **) & priv->allocator,
        GST_OBJECT_CAST (allocator));
    gst_object_unref (allocator);
    priv->video_info_index ^= 1;

    priv->alloc_info = *new_vip;
  }

  if (!gst_buffer_pool_config_has_option (config,
          GST_BUFFER_POOL_OPTION_MFX_VIDEO_META))
    goto error_no_mfx_video_meta_option;

  priv->has_video_meta = gst_buffer_pool_config_has_option (config,
      GST_BUFFER_POOL_OPTION_VIDEO_META);

  return
      GST_BUFFER_POOL_CLASS
      (gst_mfx_video_buffer_pool_parent_class)->set_config (pool, config);

  /* ERRORS */
error_invalid_config:
  {
    GST_ERROR ("invalid config");
    return FALSE;
  }
error_no_caps:
  {
    GST_ERROR ("no valid caps in config");
    return FALSE;
  }
error_create_allocator:
  {
    GST_ERROR ("failed to create GstMfxVideoAllocator object");
    return FALSE;
  }
error_no_mfx_video_meta_option:
  {
    GST_ERROR ("no GstMfxVideoMeta option");
    return FALSE;
  }
}

static GstFlowReturn
gst_mfx_video_buffer_pool_alloc_buffer (GstBufferPool * pool,
    GstBuffer ** out_buffer_ptr, GstBufferPoolAcquireParams * params)
{
  GstMfxVideoBufferPoolPrivate *const priv =
      GST_MFX_VIDEO_BUFFER_POOL (pool)->priv;
  GstMfxVideoMeta *meta;
  GstMemory *mem;
  GstBuffer *buffer;

  if (!priv->allocator)
    goto error_no_allocator;

  meta = gst_mfx_video_meta_new ();
  if (!meta)
    goto error_create_meta;

  buffer = gst_buffer_new ();
  if (!buffer)
    goto error_create_buffer;

  gst_buffer_set_mfx_video_meta (buffer, meta);

  if (priv->use_dmabuf_memory)
    mem = gst_mfx_dmabuf_memory_new (priv->allocator, priv->display,
        &priv->alloc_info, meta);
  else
    mem = gst_mfx_video_memory_new (priv->allocator, meta);

  if (!mem)
{'fraction_non_alphanumeric': 0.08638480504063556, 'fraction_numerical': 0.004565793078257693, 'mean_word_length': 4.651186790505676, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3689793', 'n_tokens_mistral': 4073, 'n_tokens_neox': 4030, 'n_words': 811}