コード例 #1
0
ファイル: xineinput.c プロジェクト: JJCG/gst-plugins-bad
/** GstXineInput ***********************************************************/

enum
{
  ARG_0,
  ARG_LOCATION
};

GST_BOILERPLATE (GstXineInput, gst_xine_input, GstXine, GST_TYPE_XINE);

static void gst_xine_input_dispose (GObject * object);
static void gst_xine_input_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_xine_input_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static GstStateChangeReturn
gst_xine_input_change_state (GstElement * element, GstStateChange transition);

static void
gst_xine_input_base_init (gpointer g_class)
{
}

static void
gst_xine_input_class_init (GstXineInputClass * klass)
{
  GstElementClass *element = GST_ELEMENT_CLASS (klass);
  GObjectClass *object = G_OBJECT_CLASS (klass);

  element->change_state = gst_xine_input_change_state;

  object->set_property = gst_xine_input_set_property;
  object->get_property = gst_xine_input_get_property;
  object->dispose = gst_xine_input_dispose;

  g_object_class_install_property (object, ARG_LOCATION,
      g_param_spec_string ("location", "location", "location",
          NULL, G_PARAM_READWRITE));
}

static void
gst_xine_input_init (GstXineInput * xine, GstXineInputClass * g_class)
{
}

static void
gst_xine_input_dispose (GObject * object)
{
  GstXineInput *xine = GST_XINE_INPUT (object);

  g_free (xine->location);
  xine->location = NULL;

  GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
}

static void
gst_xine_input_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstXineInput *xine = GST_XINE_INPUT (object);

  switch (prop_id) {
    case ARG_LOCATION:
      if (gst_element_get_state (GST_ELEMENT (xine)) != GST_STATE_NULL)
        return;
      if (xine->location)
        g_free (xine->location);
      xine->location = g_strdup (g_value_get_string (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      return;
  }
}

static void
gst_xine_input_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstXineInput *xine = GST_XINE_INPUT (object);

  switch (prop_id) {
    case ARG_LOCATION:
      g_value_set_string (value, xine->location);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      return;
  }
}

#define BUFFER_SIZE 4096        /* FIXME: what size? */
static GstData *
gst_xine_input_get (GstPad * pad)
{
  GstXineInput *xine =
      GST_XINE_INPUT (gst_object_get_parent (GST_OBJECT (pad)));
  GstBuffer *buf;
  gint real_size, position;

  /* FIXME: how does xine figure out EOS? */
  position = xine->input->get_current_pos (xine->input);
  if (position > 0 && position == xine->input->get_length (xine->input)) {
    gst_element_set_eos (GST_ELEMENT (xine));
    return GST_DATA (gst_event_new (GST_EVENT_EOS));
  }

  buf =
      gst_pad_alloc_buffer_and_set_caps (xine->srcpad, GST_BUFFER_OFFSET_NONE,
      xine->blocksize);
  GST_BUFFER_OFFSET (buf) = position;
  real_size =
      xine->input->read (xine->input, GST_BUFFER_DATA (buf),
      GST_BUFFER_MAXSIZE (buf));
  GST_BUFFER_SIZE (buf) = real_size;
  if (real_size < 0) {
    GST_ELEMENT_ERROR (xine, RESOURCE, READ, (NULL), ("error %d reading data",
            real_size));
    gst_data_unref (GST_DATA (buf));
    return NULL;
  } else if (real_size == 0) {
    buf_element_t *element;

    if (xine->input->get_capabilities (xine->input) & INPUT_CAP_BLOCK)
      element =
          xine->input->read_block (xine->input,
          gst_xine_get_stream (GST_XINE (xine))->audio_fifo, xine->blocksize);
    if (element == NULL) {
      /* FIXME: is this EOS? */
      gst_element_set_eos (GST_ELEMENT (xine));
      return GST_DATA (gst_event_new (GST_EVENT_EOS));
    } else {
      GST_BUFFER_SIZE (buf) = element->size;
      /* FIXME: put buf_element_t data in buffer */
      memcpy (GST_BUFFER_DATA (buf), element->mem, element->size);
      element->free_buffer (element);
    }
  }
  GST_BUFFER_OFFSET_END (buf) = xine->input->get_current_pos (xine->input);

  return GST_DATA (buf);
}
コード例 #2
0
ファイル: gstmikmod.c プロジェクト: an146/gst-plugins-good
static void
gst_mikmod_loop (GstElement * element)
{
  GstMikMod *mikmod;
  GstBuffer *buffer_in;

  g_return_if_fail (element != NULL);
  g_return_if_fail (GST_IS_MIKMOD (element));

  mikmod = GST_MIKMOD (element);
  srcpad = mikmod->srcpad;
  mikmod->Buffer = NULL;

  if (!mikmod->initialized) {
    while ((buffer_in = GST_BUFFER (gst_pad_pull (mikmod->sinkpad)))) {
      if (GST_IS_EVENT (buffer_in)) {
        GstEvent *event = GST_EVENT (buffer_in);

        if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
          break;
      } else {
        if (mikmod->Buffer) {
          mikmod->Buffer = gst_buffer_append (mikmod->Buffer, buffer_in);
        } else {
          mikmod->Buffer = buffer_in;
        }
      }
    }

    if (!GST_PAD_CAPS (mikmod->srcpad)) {
      if (GST_PAD_LINK_SUCCESSFUL (gst_pad_renegotiate (mikmod->srcpad))) {
        GST_ELEMENT_ERROR (mikmod, CORE, NEGOTIATION, (NULL), (NULL));
        return;
      }
    }

    MikMod_RegisterDriver (&drv_gst);
    MikMod_RegisterAllLoaders ();

    MikMod_Init ("");
    reader = GST_READER_new (mikmod);
    module = Player_LoadGeneric (reader, 64, 0);

    gst_buffer_unref (mikmod->Buffer);

    if (!Player_Active ())
      Player_Start (module);

    mikmod->initialized = TRUE;
  }

  if (Player_Active ()) {
    timestamp = (module->sngtime / 1024.0) * GST_SECOND;
    drv_gst.Update ();
  } else {
    gst_element_set_eos (GST_ELEMENT (mikmod));
    gst_pad_push (mikmod->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
  }
}
コード例 #3
0
ファイル: gstevent.c プロジェクト: JERUKA9/gstreamer
/**
 * gst_event_new_custom:
 * @type: The type of the new event
 * @structure: (transfer full): the structure for the event. The event will
 *     take ownership of the structure.
 *
 * Create a new custom-typed event. This can be used for anything not
 * handled by other event-specific functions to pass an event to another
 * element.
 *
 * Make sure to allocate an event type with the #GST_EVENT_MAKE_TYPE macro,
 * assigning a free number and filling in the correct direction and
 * serialization flags.
 *
 * New custom events can also be created by subclassing the event type if
 * needed.
 *
 * Returns: (transfer full): the new custom event.
 */
GstEvent *
gst_event_new_custom (GstEventType type, GstStructure * structure)
{
  GstEvent *event;

  /* structure must not have a parent */
  if (structure)
    g_return_val_if_fail (structure->parent_refcount == NULL, NULL);

  event = gst_event_new (type);
  if (structure) {
    gst_structure_set_parent_refcount (structure, &event->mini_object.refcount);
    event->structure = structure;
  }
  return event;
}
コード例 #4
0
ファイル: gstevent.c プロジェクト: JERUKA9/gstreamer
/**
 * gst_event_new_eos:
 *
 * Create a new EOS event. The eos event can only travel downstream
 * synchronized with the buffer flow. Elements that receive the EOS
 * event on a pad can return #GST_FLOW_UNEXPECTED as a #GstFlowReturn
 * when data after the EOS event arrives.
 *
 * The EOS event will travel down to the sink elements in the pipeline
 * which will then post the #GST_MESSAGE_EOS on the bus after they have
 * finished playing any buffered data.
 *
 * When all sinks have posted an EOS message, an EOS message is
 * forwarded to the application.
 *
 * The EOS event itself will not cause any state transitions of the pipeline.
 *
 * Returns: (transfer full): the new EOS event.
 */
GstEvent *
gst_event_new_eos (void)
{
  return gst_event_new (GST_EVENT_EOS);
}
コード例 #5
0
ファイル: gstevent.c プロジェクト: JERUKA9/gstreamer
/**
 * gst_event_new_flush_stop:
 *
 * Allocate a new flush stop event. The flush stop event can be sent
 * upstream and downstream and travels serialized with the dataflow.
 * It is typically sent after sending a FLUSH_START event to make the
 * pads accept data again.
 *
 * Elements can process this event synchronized with the dataflow since
 * the preceeding FLUSH_START event stopped the dataflow.
 *
 * This event is typically generated to complete a seek and to resume
 * dataflow.
 *
 * Returns: (transfer full): a new flush stop event.
 */
GstEvent *
gst_event_new_flush_stop (void)
{
  return gst_event_new (GST_EVENT_FLUSH_STOP);
}
コード例 #6
0
ファイル: gstevent.c プロジェクト: JERUKA9/gstreamer
/**
 * gst_event_new_flush_start:
 *
 * Allocate a new flush start event. The flush start event can be sent
 * upstream and downstream and travels out-of-bounds with the dataflow.
 *
 * It marks pads as being flushing and will make them return
 * #GST_FLOW_WRONG_STATE when used for data flow with gst_pad_push(),
 * gst_pad_chain(), gst_pad_alloc_buffer(), gst_pad_get_range() and
 * gst_pad_pull_range(). Any event (except a #GST_EVENT_FLUSH_STOP) received
 * on a flushing pad will return %FALSE immediately.
 *
 * Elements should unlock any blocking functions and exit their streaming
 * functions as fast as possible when this event is received.
 *
 * This event is typically generated after a seek to flush out all queued data
 * in the pipeline so that the new media is played as soon as possible.
 *
 * Returns: (transfer full): a new flush start event.
 */
GstEvent *
gst_event_new_flush_start (void)
{
  return gst_event_new (GST_EVENT_FLUSH_START);
}