/* GStreamer
 *
 * Copyright (C) 2014 Samsung Electronics. All rights reserved.
 *   Author: Thiago Santos <ts.santos@sisa.samsung.com>
 *
 * gstflowcombiner.c: utility to combine multiple flow returns into a single one
 *
 * 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:gstflowcombiner
 * @title: GstFlowCombiner
 * @short_description: Utility to combine multiple flow returns into one
 *
 * Utility struct to help handling #GstFlowReturn combination. Useful for
 * #GstElement<!-- -->s that have multiple source pads and need to combine
 * the different #GstFlowReturn for those pads.
 *
 * #GstFlowCombiner works by using the last #GstFlowReturn for all #GstPad
 * it has in its list and computes the combined return value and provides
 * it to the caller.
 *
 * To add a new pad to the #GstFlowCombiner use gst_flow_combiner_add_pad().
 * The new #GstPad is stored with a default value of %GST_FLOW_OK.
 *
 * In case you want a #GstPad to be removed, use gst_flow_combiner_remove_pad().
 *
 * Please be aware that this struct isn't thread safe as its designed to be
 *  used by demuxers, those usually will have a single thread operating it.
 *
 * These functions will take refs on the passed #GstPad<!-- -->s.
 *
 * Aside from reducing the user's code size, the main advantage of using this
 * helper struct is to follow the standard rules for #GstFlowReturn combination.
 * These rules are:
 *
 * * %GST_FLOW_EOS: only if all returns are EOS too
 * * %GST_FLOW_NOT_LINKED: only if all returns are NOT_LINKED too
 * * %GST_FLOW_ERROR or below: if at least one returns an error return
 * * %GST_FLOW_NOT_NEGOTIATED: if at least one returns a not-negotiated return
 * * %GST_FLOW_FLUSHING: if at least one returns flushing
 * * %GST_FLOW_OK: otherwise
 *
 * %GST_FLOW_ERROR or below, GST_FLOW_NOT_NEGOTIATED and GST_FLOW_FLUSHING are
 * returned immediatelly from the gst_flow_combiner_update_flow() function.
 *
 * Since: 1.4
 */

#include <gst/gst.h>
#include "gstflowcombiner.h"

struct _GstFlowCombiner
{
  GQueue pads;

  GstFlowReturn last_ret;
  volatile gint ref_count;
};

GST_DEBUG_CATEGORY_STATIC (flowcombiner_dbg);
#define GST_CAT_DEFAULT flowcombiner_dbg

G_DEFINE_BOXED_TYPE_WITH_CODE (GstFlowCombiner, gst_flow_combiner,
    (GBoxedCopyFunc) gst_flow_combiner_ref,
    (GBoxedFreeFunc) gst_flow_combiner_unref,
    GST_DEBUG_CATEGORY_INIT (flowcombiner_dbg, "flowcombiner", 0,
        "Flow Combiner"));

/**
 * gst_flow_combiner_new:
 *
 * Creates a new #GstFlowCombiner, use gst_flow_combiner_free() to free it.
 *
 * Returns: A new #GstFlowCombiner
 * Since: 1.4
 */
GstFlowCombiner *
gst_flow_combiner_new (void)
{
  GstFlowCombiner *combiner = g_slice_new (GstFlowCombiner);

  g_queue_init (&combiner->pads);
  combiner->last_ret = GST_FLOW_OK;
  combiner->ref_count = 1;

  /* Make sure debug category is initialised */
  gst_flow_combiner_get_type ();

  return combiner;
}

/**
 * gst_flow_combiner_free:
 * @combiner: the #GstFlowCombiner to free
 *
 * Frees a #GstFlowCombiner struct and all its internal data.
 *
 * Since: 1.4
 */
void
gst_flow_combiner_free (GstFlowCombiner * combiner)
{
  gst_flow_combiner_unref (combiner);
}

/**
 * gst_flow_combiner_ref:
 * @combiner: the #GstFlowCombiner to add a reference to.
 *
 * Increments the reference count on the #GstFlowCombiner.
 *
 * Returns: the #GstFlowCombiner.
 *
 * Since: 1.12.1
 */
GstFlowCombiner *
gst_flow_combiner_ref (GstFlowCombiner * combiner)
{
  g_return_val_if_fail (combiner != NULL, NULL);

  g_atomic_int_inc (&combiner->ref_count);

  return combiner;
}

/**
 * gst_flow_combiner_unref:
 * @combiner: the #GstFlowCombiner to unreference.
 *
 * Decrements the reference count on the #GstFlowCombiner.
 *
 * Since: 1.12.1
 */
void
gst_flow_combiner_unref (GstFlowCombiner * combiner)
{
  g_return_if_fail (combiner != NULL);
  g_return_if_fail (combiner->ref_count > 0);

  if (g_atomic_int_dec_and_test (&combiner->ref_count)) {
    GstPad *pad;

    while ((pad = g_queue_pop_head (&combiner->pads)))
      gst_object_unref (pad);

    g_slice_free (GstFlowCombiner, combiner);
  }
}

/**
 * gst_flow_combiner_clear:
 * @combiner: the #GstFlowCombiner to clear
 *
 * Removes all pads from a #GstFlowCombiner and resets it to its initial state.
 *
 * Since: 1.6
 */
void
gst_flow_combiner_clear (GstFlowCombiner * combiner)
{
  GstPad *pad;

  g_return_if_fail (combiner != NULL);

  while ((pad = g_queue_pop_head (&combiner->pads)))
    gst_object_unref (pad);
  combiner->last_ret = GST_FLOW_OK;
}

/**
 * gst_flow_combiner_reset:
 * @combiner: the #GstFlowCombiner to clear
 *
 * Reset flow combiner and all pads to their initial state without removing pads.
 *
 * Since: 1.6
 */
void
gst_flow_combiner_reset (GstFlowCombiner * combiner)
{
  GList *iter;

  g_return_if_fail (combiner != NULL);

  GST_DEBUG ("Reset flow returns");

  for (iter = combiner->pads.head; iter; iter = iter->next) {
    GST_PAD_LAST_FLOW_RETURN (iter->data) = GST_FLOW_OK;
  }

  combiner->last_ret = GST_FLOW_OK;
}

static GstFlowReturn
gst_flow_combiner_get_flow (GstFlowCombiner * combiner)
{
  GstFlowReturn cret = GST_FLOW_OK;
  gboolean all_eos = TRUE;
  gboolean all_notlinked = TRUE;
  GList *iter;

  GST_DEBUG ("Combining flow returns");

  for (iter = combiner->pads.head; iter; iter = iter->next) {
    GstFlowReturn fret = GST_PAD_LAST_FLOW_RETURN (iter->data);

    if (fret <= GST_FLOW_NOT_NEGOTIATED || fret == GST_FLOW_FLUSHING) {
      GST_DEBUG ("Error flow return found, returning");
      cret = fret;
      goto done;
    }

    if (fret != GST_FLOW_NOT_LINKED) {
      all_notlinked = FALSE;
      if (fret != GST_FLOW_EOS)
        all_eos = FALSE;
    }
  }
  if (all_notlinked)
    cret = GST_FLOW_NOT_LINKED;
  else if (all_eos)
    cret = GST_FLOW_EOS;

done:
  GST_DEBUG ("Combined flow return: %s (%d)", gst_flow_get_name (cret), cret);
  return cret;
}

/**
 * gst_flow_combiner_update_flow:
 * @combiner: the #GstFlowCombiner
 * @fret: the latest #GstFlowReturn received for a pad in this #GstFlowCombiner
 *
 * Computes the combined flow return for the pads in it.
 *
 * The #GstFlowReturn parameter should be the last flow return update for a pad
 * in this #GstFlowCombiner. It will use this value to be able to shortcut some
 * combinations and avoid looking over all pads again. e.g. The last combined
 * return is the same as the latest obtained #GstFlowReturn.
 *
 * Returns: The combined #GstFlowReturn
 * Since: 1.4
 */
GstFlowReturn
gst_flow_combiner_update_flow (GstFlowCombiner * combiner, GstFlowReturn fret)
{
  GstFlowReturn ret;

  g_return_val_if_fail (combiner != NULL, GST_FLOW_ERROR);

  if (combiner->last_ret == fret) {
    return fret;
  }

  if (fret <= GST_FLOW_NOT_NEGOTIATED || fret == GST_FLOW_FLUSHING) {
    ret = fret;
  } else {
    ret = gst_flow_combiner_get_flow (combiner);
  }
  combiner->last_ret = ret;
  return ret;
}

/**
 * gst_flow_combiner_update_pad_flow:
 * @combiner: the #GstFlowCombiner
 * @pad: the #GstPad whose #GstFlowReturn to update
 * @fret: the latest #GstFlowReturn received for a pad in this #GstFlowCombiner
 *
 * Sets the provided pad's last flow return to provided value and computes
 * the combined flow return for the pads in it.
 *
 * The #GstFlowReturn parameter should be the last flow return update for a pad
 * in this #GstFlowCombiner. It will use this value to be able to shortcut some
 * combinations and avoid looking over all pads again. e.g. The last combined
 * return is the same as the latest obtained #GstFlowReturn.
 *
 * Returns: The combined #GstFlowReturn
 * Since: 1.6
 */
GstFlowReturn
gst_flow_combiner_update_pad_flow (GstFlowCombiner * combiner, GstPad * pad,
    GstFlowReturn fret)
{
  g_return_val_if_fail (pad != NULL, GST_FLOW_ERROR);

  GST_PAD_LAST_FLOW_RETURN (pad) = fret;

  return gst_flow_combiner_update_flow (combiner, fret);
}

/**
 * gst_flow_combiner_add_pad:
 * @combiner: the #GstFlowCombiner
 * @pad: (transfer none): the #GstPad that is being added
 *
 * Adds a new #GstPad to the #GstFlowCombiner.
 *
 * Since: 1.4
 */
void
gst_flow_combiner_add_pad (GstFlowCombiner * combiner, GstPad * pad)
{
  g_return_if_fail (combiner != NULL);
  g_return_if_fail (pad != NULL);

  g_queue_push_head (&combiner->pads, gst_object_ref (pad));
}

/**
 * gst_flow_combiner_remove_pad:
 * @combiner: the #GstFlowCombiner
 * @pad: (transfer none): the #GstPad to remove
 *
 * Removes a #GstPad from the #GstFlowCombiner.
 *
 * Since: 1.4
 */
void
gst_flow_combiner_remove_pad (GstFlowCombiner * combiner, GstPad * pad)
{
  g_return_if_fail (combiner != NULL);
  g_return_if_fail (pad != NULL);

  if (g_queue_remove (&combiner->pads, pad))
    gst_object_unref (pad);
}
