/* GStreamer
 * unit test for the videobox element
 *
 * Copyright (C) 2006 Ravi Kiran K N <ravi.kiran@samsung.com>
 *
 * 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.
 */

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

#include <unistd.h>

#include <gst/check/gstcheck.h>

typedef struct _GstVideoBoxTestContext
{
  GstElement *pipeline;
  GstElement *src;
  GstElement *filter;
  GstElement *box;
  GstElement *filter2;
  GstElement *sink;
} GstVideoBoxTestContext;

typedef struct _FormatConversion
{
  const gchar *in_caps;
  const gchar *out_caps;
  gboolean expected_result;
} FormatConversion;


/*
 * Update this table as and when the conversion is supported(or unsupported) in videobox
 */
static const FormatConversion conversion_table[] = {
  {"video/x-raw,format={RGBA}", "video/x-raw,format={AYUV}", TRUE},
  {"video/x-raw,format={AYUV}", "video/x-raw,format={RGBA}", TRUE},
  {"video/x-raw,format={I420}", "video/x-raw,format={AYUV}", TRUE},
  {"video/x-raw,format={AYUV}", "video/x-raw,format={I420}", TRUE},
  {"video/x-raw,format={I420}", "video/x-raw,format={YV12}", TRUE},
  {"video/x-raw,format={YV12}", "video/x-raw,format={AYUV}", TRUE},
  {"video/x-raw,format={YV12}", "video/x-raw,format={I420}", TRUE},
  {"video/x-raw,format={AYUV}", "video/x-raw,format={YV12}", TRUE},
  {"video/x-raw,format={AYUV}", "video/x-raw,format={xRGB}", TRUE},
  {"video/x-raw,format={xRGB}", "video/x-raw,format={xRGB}", TRUE},
  {"video/x-raw,format={xRGB}", "video/x-raw,format={AYUV}", TRUE},
  {"video/x-raw,format={GRAY8}", "video/x-raw,format={GRAY16_LE}", FALSE},
  {"video/x-raw,format={GRAY8}", "video/x-raw,format={GRAY16_BE}", FALSE},
  {"video/x-raw,format={Y444}", "video/x-raw,format={Y42B}", FALSE},
  {"video/x-raw,format={Y444}", "video/x-raw,format={Y41B}", FALSE},
  {"video/x-raw,format={Y42B}", "video/x-raw,format={Y41B}", FALSE}
};


static gboolean
bus_handler (GstBus * bus, GstMessage * message, gpointer data)
{
  GMainLoop *loop = (GMainLoop *) data;

  switch (message->type) {
    case GST_MESSAGE_EOS:{
      GST_LOG ("EOS event received");
      g_main_loop_quit (loop);
      break;
    }
    case GST_MESSAGE_ERROR:{
      GError *gerror;
      gchar *debug;
      gst_message_parse_error (message, &gerror, &debug);
      g_error ("Error from %s: %s (%s)\n",
          GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)), gerror->message,
          GST_STR_NULL (debug));
      g_error_free (gerror);
      g_free (debug);
      g_main_loop_quit (loop);
      break;
    }
    case GST_MESSAGE_WARNING:{
      g_main_loop_quit (loop);
      break;
    }
    default:
      break;
  }

  return TRUE;
}

static void
videobox_test_init_context (GstVideoBoxTestContext * ctx)
{
  fail_unless (ctx != NULL);

  ctx->pipeline = gst_pipeline_new ("pipeline");
  fail_unless (ctx->pipeline != NULL);
  ctx->src = gst_element_factory_make ("videotestsrc", "src");
  fail_unless (ctx->src != NULL, "Failed to create videotestsrc element");
  ctx->filter = gst_element_factory_make ("capsfilter", "filter");
  fail_unless (ctx->filter != NULL, "Failed to create capsfilter element");
  ctx->box = gst_element_factory_make ("videobox", "box");
  fail_unless (ctx->box != NULL, "Failed to create videobox element");
  ctx->filter2 = gst_element_factory_make ("capsfilter", "filter2");
  fail_unless (ctx->filter2 != NULL,
      "Failed to create second capsfilter element");
  ctx->sink = gst_element_factory_make ("fakesink", "sink");
  fail_unless (ctx->sink != NULL, "Failed to create fakesink element");

  gst_bin_add_many (GST_BIN (ctx->pipeline), ctx->src, ctx->filter,
      ctx->box, ctx->filter2, ctx->sink, NULL);
  fail_unless (gst_element_link_many (ctx->src, ctx->filter, ctx->box,
          ctx->filter2, ctx->sink, NULL) == TRUE, "Can not link elements");

  fail_unless (gst_element_set_state (ctx->pipeline,
          GST_STATE_READY) != GST_STATE_CHANGE_FAILURE,
      "couldn't set pipeline to READY state");

  GST_LOG ("videobox context inited");
}

static void
videobox_test_deinit_context (GstVideoBoxTestContext * ctx)
{
  GST_LOG ("deiniting videobox context");

  gst_element_set_state (ctx->pipeline, GST_STATE_NULL);
  gst_object_unref (ctx->pipeline);
  memset (ctx, 0x00, sizeof (GstVideoBoxTestContext));
}

GST_START_TEST (test_caps_transform)
{
  GstStateChangeReturn state_ret;
  GstVideoBoxTestContext ctx;
  guint conversions_test_size;
  guint itr;
  gboolean link_res;
  GMainLoop *loop;
  GstBus *bus;

  videobox_test_init_context (&ctx);
  gst_util_set_object_arg (G_OBJECT (ctx.src), "num-buffers", "1");

  loop = g_main_loop_new (NULL, TRUE);
  fail_unless (loop != NULL);

  bus = gst_element_get_bus (ctx.pipeline);
  fail_unless (bus != NULL);

  gst_bus_add_watch (bus, bus_handler, loop);
  gst_object_unref (bus);

  conversions_test_size = G_N_ELEMENTS (conversion_table);
  for (itr = 0; itr < conversions_test_size; itr++) {
    gst_element_unlink_many (ctx.src, ctx.filter, ctx.box, ctx.filter2,
        ctx.sink, NULL);
    gst_util_set_object_arg (G_OBJECT (ctx.filter), "caps",
        conversion_table[itr].in_caps);
    gst_util_set_object_arg (G_OBJECT (ctx.filter2), "caps",
        conversion_table[itr].out_caps);

    /* Link with new input and output format from conversion table */
    link_res =
        gst_element_link_many (ctx.src, ctx.filter, ctx.box, ctx.filter2,
        ctx.sink, NULL);

    /* Check if the specified format conversion is supported or not by videobox */
    fail_unless (link_res == conversion_table[itr].expected_result,
        "videobox can not convert from '%s'' to '%s'",
        conversion_table[itr].in_caps, conversion_table[itr].out_caps);

    if (link_res == FALSE) {
      GST_LOG ("elements linking failed");
      continue;
    }

    state_ret = gst_element_set_state (ctx.pipeline, GST_STATE_PLAYING);
    fail_unless (state_ret != GST_STATE_CHANGE_FAILURE,
        "couldn't set pipeline to PLAYING state");

    g_main_loop_run (loop);

    state_ret = gst_element_set_state (ctx.pipeline, GST_STATE_READY);
    fail_unless (state_ret != GST_STATE_CHANGE_FAILURE,
        "couldn't set pipeline to READY state");
  }

  g_main_loop_unref (loop);

  videobox_test_deinit_context (&ctx);
}

GST_END_TEST;


static Suite *
videobox_suite (void)
{
  Suite *s = suite_create ("videobox");
  TCase *tc_chain = tcase_create ("general");

  suite_add_tcase (s, tc_chain);
  tcase_add_test (tc_chain, test_caps_transform);

  return s;
}

GST_CHECK_MAIN (videobox);
