All pastes #1616104 Raw Edit

gst-kaps

public c v1 · immutable
#1616104 ·published 2009-10-12 18:24 UTC
rendered paste body
/** * SECTION:element myaudiosrc * *  * <refsect2> * <title>Example launch line</title> * |[ * gst-launch -v -m myaudiosrc ! queue ! alsasink  * ]| * </refsect2> */#ifdef HAVE_CONFIG_H#  include <config.h>#endif#include <gst/controller/gstcontroller.h>#include "gstmyaudiosrc.h"GST_DEBUG_CATEGORY_STATIC (gst_myaudiosrc_debug);#define GST_CAT_DEFAULT gst_myaudiosrc_debug/* Element Properties */enum{  PROP_0,  PROP_MY_API};static voidgst_myaudiosrc_finalize (GObject * object){  Gstmyaudiosrc *src;  src = GST_MYAUDIOSRC (object);}/* the capabilities of the inputs and outputs. * * describe the real formats here. */static GstStaticPadTemplate src_factory =  GST_STATIC_PAD_TEMPLATE ("src",    GST_PAD_SRC,    GST_PAD_SOMETIMES,    GST_STATIC_CAPS ("audio/x-raw-int, "        "width = (int) {16, 32}, "        "depth = (int) {16, 32}, "        "signed = (boolean) true, "        "channels = (int) {1, 2}, "        "endianness = (int) LITTLE_ENDIAN,"        "rate = (int) [ 8000, 48000 ] "    ));GST_BOILERPLATE (Gstmyaudiosrc, gst_myaudiosrc, GstBaseSrc,    GST_TYPE_BASE_SRC);static void gst_myaudiosrc_set_property (GObject * object, guint prop_id,    const GValue * value, GParamSpec * pspec);static void gst_myaudiosrc_get_property (GObject * object, guint prop_id,    GValue * value, GParamSpec * pspec);static GstStateChangeReturn gst_myaudiosrc_change_state     (GstElement * element, GstStateChange transition);static gboolean gst_myaudiosrc_start (GstBaseSrc * basesrc);static gboolean gst_myaudiosrc_check_get_range (GstBaseSrc * basesrc);static gbooleangst_myaudiosrc_is_seekable (GstBaseSrc * psrc){  /* we're not seekable... */  return FALSE;}static voidgst_myaudiosrc_get_times (GstBaseSrc * basesrc, GstBuffer * buffer,    GstClockTime * start, GstClockTime * end){  /* for live sources, sync on the timestamp of the buffer */  if (gst_base_src_is_live (basesrc)) {    GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);    if (GST_CLOCK_TIME_IS_VALID (timestamp)) {      /* get duration to calculate end time */      GstClockTime duration = GST_BUFFER_DURATION (buffer);      if (GST_CLOCK_TIME_IS_VALID (duration)) {        *end = timestamp + duration;      }      *start = timestamp;    }  } else {    *start = -1;    *end = -1;  }}/*Query handling*/static gbooleangst_myaudiosrc_query (GstBaseSrc * bsrc, GstQuery * query){//  Gstmyaudiosrc *src = GST_MYAUDIOSRC (bsrc);  gboolean res = TRUE;  switch (GST_QUERY_TYPE (query)) {    case GST_QUERY_LATENCY: {      GstClockTime min, max;      min = gst_util_uint64_scale_int (GST_SECOND, 1, 30);      max = GST_CLOCK_TIME_NONE;      GST_ERROR ("report latency: live 1, min %" GST_TIME_FORMAT          ", max %" GST_TIME_FORMAT, GST_TIME_ARGS (min),          GST_TIME_ARGS (max));      gst_query_set_latency (query, TRUE, min, max);      break;    }    default:      res = FALSE;  }  return res;}GstFlowReturngst_myaudiosrc_create (GstBaseSrc * psrc, guint64 offset,    guint length, GstBuffer ** buffer){  Gstmyaudiosrc *src = GST_MYAUDIOSRC (psrc);  GstBuffer *buf = NULL;  guint64 ts, duration;  guint32 samples;  GstClockTime next_time;  gint64 next_sample, next_bytes;/*  if (G_UNLIKELY (src->fourcc == NULL))    goto not_negotiated;*/    while (buf == NULL) {      buf = myapi_get_frame (src->myapi, 0, &ts, &duration);    }       /* Audio Packet */    GST_LOG ("Got Audio Packet of lenght %d, with timestamp %d",         GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));    samples = length / (2 * 2);     if (offset == -1)    offset = src->offset;    /* now see if we are at the byteoffset we think we are */  if (offset != src->offset) {    GST_DEBUG_OBJECT (src, "seek to new offset %" G_GUINT64_FORMAT, offset);    /* we have a discont in the expected sample offset, do a 'seek' */    src->next_sample = offset / (2 * 2);    src->next_time =        gst_util_uint64_scale_int (src->next_sample, GST_SECOND,        48000);    src->offset = offset;  }  next_sample = src->next_sample + samples;  next_bytes = src->offset + length;  next_time = gst_util_uint64_scale_int (next_sample, GST_SECOND,      48000);   GST_BUFFER_TIMESTAMP (buf) = 0 + src->next_time;  GST_BUFFER_OFFSET (buf) = src->next_sample;  GST_BUFFER_OFFSET_END (buf) = next_sample;  GST_BUFFER_DURATION (buf) = next_time - src->next_time;  gst_object_sync_values (G_OBJECT (src), src->next_time);  src->next_time = next_time;  src->next_sample = next_sample;  src->offset = next_bytes;        GST_DEBUG ("Pushing buffer of size-%d, timestamp-%" GST_TIME_FORMAT \        " duration-%"GST_TIME_FORMAT,  GST_BUFFER_SIZE (buf),         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),         GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));   *buffer = buf;   return GST_FLOW_OK;/*not_negotiated:  {    GST_ELEMENT_ERROR (src, CORE, NEGOTIATION, (NULL),        ("format wasn't negotiated before get function"));    return GST_FLOW_NOT_NEGOTIATED;  }*/}static GstCaps *gst_myaudiosrc_getcaps (GstBaseSrc * psrc){  Gstmyaudiosrc *src = GST_MYAUDIOSRC (psrc);    src->caps = gst_caps_new_simple ("audio/x-raw-int",      "width", G_TYPE_INT, 16,      "depth", G_TYPE_INT, 16,      "channels", G_TYPE_INT, 2,      "rate", G_TYPE_INT, 48000,      "signed", G_TYPE_BOOLEAN, TRUE,      "endianness", G_TYPE_INT, 1234,      NULL);  if (G_UNLIKELY (!src->caps)) {    GST_ERROR ("Unable to generate caps");  }    return src->caps;}gbooleangst_myaudiosrc_open_device (Gstmyaudiosrc *src) {  GST_INFO_OBJECT (src, "opening Device ");  if (src->myapi == NULL) {    src->myapi = myapi_new ();  }  else {    GST_DEBUG ("Myapi already initialized, using same initialized value");    src->setup = TRUE;  }  return TRUE;}gbooleangst_myaudiosrc_setup (Gstmyaudiosrc *src){  gboolean ret = FALSE;  if (myapi_init (src->myapi)) {    if (myapi_start (src->myapi)) {      src->setup = TRUE;      ret = TRUE;    }  }  return ret;}/* GObject vmethod implementations */static voidgst_myaudiosrc_base_init (gpointer gclass){  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);  gst_element_class_set_details_simple(element_class,    "My Audio Source",    "Source/MyAudio",    "Reads Audio Streams ",    " ");  gst_element_class_add_pad_template (element_class,      gst_static_pad_template_get (&src_factory));}/* initialize the myaudiosrc's class */static voidgst_myaudiosrc_class_init (GstmyaudiosrcClass * klass){  GObjectClass *gobject_class;  GstElementClass *gstelement_class;  GstBaseSrcClass *gstbasesrc_class;  gobject_class = (GObjectClass *) klass;  gstbasesrc_class = (GstBaseSrcClass *) klass;  gstelement_class = (GstElementClass *) klass;  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_myaudiosrc_finalize);  gobject_class->set_property =       GST_DEBUG_FUNCPTR (gst_myaudiosrc_set_property);  gobject_class->get_property =       GST_DEBUG_FUNCPTR (gst_myaudiosrc_get_property);  gstelement_class->change_state =      GST_DEBUG_FUNCPTR (gst_myaudiosrc_change_state);  gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_myaudiosrc_getcaps);  gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_myaudiosrc_is_seekable);  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_myaudiosrc_start);//  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_myaudiosrc_stop);  gstbasesrc_class->check_get_range = GST_DEBUG_FUNCPTR (gst_myaudiosrc_check_get_range);  gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_myaudiosrc_create);  gstbasesrc_class->get_times =      GST_DEBUG_FUNCPTR (gst_myaudiosrc_get_times);  gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_myaudiosrc_query);    /* debug category for fltering log messages */    GST_DEBUG_CATEGORY_INIT (gst_myaudiosrc_debug, "myaudiosrc",      0, "My src Plugin");}/* initialize the new element * instantiate pads and add them to element * set pad calback functions * initialize instance structure */static voidgst_myaudiosrc_init (Gstmyaudiosrc * src,    GstmyaudiosrcClass * gclass){  /* protects our state changes from multiple invocations */  src->state_rec_lock = g_new (GStaticRecMutex, 1);  g_static_rec_mutex_init (src->state_rec_lock);  src->stream_rec_lock = g_new (GStaticRecMutex, 1);  g_static_rec_mutex_init (src->stream_rec_lock);  gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);  gst_base_src_set_live (GST_BASE_SRC (src), TRUE);  src->offset = 0;    src->is_paused = FALSE;  src->setup = FALSE;  src->myapi = NULL;}static voidgst_myaudiosrc_set_property (GObject * object, guint prop_id,    const GValue * value, GParamSpec * pspec){  Gstmyaudiosrc *src = GST_MYAUDIOSRC (object);  switch (prop_id) {    case PROP_DECKLINK_API:      src->myapi = g_value_get_pointer (value);            break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);      break;  }}static voidgst_myaudiosrc_get_property (GObject * object, guint prop_id,    GValue * value, GParamSpec * pspec){//  Gstmyaudiosrc *src = GST_MYAUDIOSRC (object);  switch (prop_id) {    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);      break;  }}static GstStateChangeReturngst_myaudiosrc_change_state (GstElement * element,     GstStateChange transition){  Gstmyaudiosrc *src;  GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;  gboolean no_preroll = FALSE;     src = GST_MYAUDIOSRC (element);  switch (transition) {    case GST_STATE_CHANGE_NULL_TO_READY:      if (!gst_myaudiosrc_open_device (src)) {        goto failure;      }      break;    case GST_STATE_CHANGE_READY_TO_PAUSED:      no_preroll = TRUE;      break;    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:      if (!src->setup) {        if (!gst_myaudiosrc_setup (src)) {          goto failure;        }      }      GST_ERROR_OBJECT (src, "PAUSED->PLAYING");      /* now we can start playback */      if (src->is_paused) {        GST_ERROR_OBJECT (src, "Resuming Device");        src->is_paused = FALSE;      }      break;    default:      break;  }  if ((result =          GST_ELEMENT_CLASS (parent_class)->change_state (element,              transition)) == GST_STATE_CHANGE_FAILURE)    goto failure;  switch (transition) {    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:      break;    case GST_STATE_CHANGE_PAUSED_TO_READY:      GST_DEBUG ("Stopping the device........");      if (!myapi_stop (src->myapi)) {        GST_ERROR ("Unable to Stop, device ");        return GST_STATE_CHANGE_FAILURE;      }      break;    case GST_STATE_CHANGE_READY_TO_NULL:      src->myapi = NULL;       break;    default:      break;  }  if (no_preroll && result == GST_STATE_CHANGE_SUCCESS)    result = GST_STATE_CHANGE_NO_PREROLL;  return result;  /* ERRORS */failure:  {    GST_DEBUG_OBJECT (src, "parent failed state change");    return result;  }}static gbooleangst_myaudiosrc_start (GstBaseSrc * basesrc){  Gstmyaudiosrc *src = GST_MYAUDIOSRC (basesrc);  src->next_sample = 0;  src->offset = 0;  src->next_time = 0;  src->running_time = 0;  return TRUE;}static gbooleangst_myaudiosrc_check_get_range (GstBaseSrc * basesrc){  Gstmyaudiosrc *src;  src = GST_MYAUDIOSRC (basesrc);  src->can_activate_pull = FALSE;  /* if we can operate in pull mode */  return src->can_activate_pull;}