/* GStreamer Cpu Report Element
 * Copyright (C) <2010> Zaheer Abbas Merali <zaheerabbas merali 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.
 */

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

#include <gst/gst.h>
#include <string.h>
#include <math.h>
#include <time.h>

#include "cpureport.h"


enum
{
  ARG_0,
};

GstStaticPadTemplate cpu_report_src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

GstStaticPadTemplate cpu_report_sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstFlowReturn gst_cpu_report_transform_ip (GstBaseTransform * trans,
    GstBuffer * buf);

static gboolean gst_cpu_report_start (GstBaseTransform * trans);
static gboolean gst_cpu_report_stop (GstBaseTransform * trans);

#define gst_cpu_report_parent_class parent_class
G_DEFINE_TYPE (GstCpuReport, gst_cpu_report, GST_TYPE_BASE_TRANSFORM);

static void
gst_cpu_report_finalize (GObject * obj)
{
  G_OBJECT_CLASS (parent_class)->finalize (obj);
}

static void
gst_cpu_report_class_init (GstCpuReportClass * g_class)
{
  GstBaseTransformClass *gstbasetrans_class;
  GstElementClass *element_class;
  GObjectClass *gobject_class;

  gobject_class = G_OBJECT_CLASS (g_class);
  element_class = GST_ELEMENT_CLASS (g_class);
  gstbasetrans_class = GST_BASE_TRANSFORM_CLASS (g_class);

  gobject_class->finalize = gst_cpu_report_finalize;

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&cpu_report_sink_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&cpu_report_src_template));

  gst_element_class_set_static_metadata (element_class, "CPU report",
      "Testing",
      "Post cpu usage information every buffer",
      "Zaheer Abbas Merali <zaheerabbas at merali dot org>");

  gstbasetrans_class->transform_ip =
      GST_DEBUG_FUNCPTR (gst_cpu_report_transform_ip);
  gstbasetrans_class->start = GST_DEBUG_FUNCPTR (gst_cpu_report_start);
  gstbasetrans_class->stop = GST_DEBUG_FUNCPTR (gst_cpu_report_stop);
}

static void
gst_cpu_report_init (GstCpuReport * report)
{
  gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (report), TRUE);

}

static GstFlowReturn
gst_cpu_report_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
{
  GstCpuReport *filter;
  GTimeVal cur_time;
  clock_t cur_cpu_time;
  GstMessage *msg;
  GstStructure *s;
  gint64 time_taken;


  g_get_current_time (&cur_time);
  cur_cpu_time = clock ();

  filter = GST_CPU_REPORT (trans);


  time_taken = GST_TIMEVAL_TO_TIME (cur_time) -
      GST_TIMEVAL_TO_TIME (filter->last_time);

  s = gst_structure_new ("cpu-report", "cpu-time", G_TYPE_DOUBLE,
      ((gdouble) (cur_cpu_time - filter->last_cpu_time)),
      "actual-time", G_TYPE_INT64, time_taken, "buffer-time", G_TYPE_INT64,
      GST_BUFFER_TIMESTAMP (buf), NULL);
  msg = gst_message_new_element (GST_OBJECT_CAST (filter), s);
  gst_element_post_message (GST_ELEMENT_CAST (filter), msg);
  filter->last_time = cur_time;
  filter->last_cpu_time = cur_cpu_time;


  return GST_FLOW_OK;
}

static gboolean
gst_cpu_report_start (GstBaseTransform * trans)
{
  GstCpuReport *filter;

  filter = GST_CPU_REPORT (trans);

  g_get_current_time (&filter->last_time);
  filter->start_time = filter->last_time;
  filter->last_cpu_time = clock ();
  return TRUE;
}

static gboolean
gst_cpu_report_stop (GstBaseTransform * trans)
{
  /* anything we should be doing here? */
  return TRUE;
}
