Sophie

Sophie

distrib > Mandriva > 10.0-com > i586 > by-pkgid > f0a9f2b9c81d34eadc43f527947c0b70 > files > 248

libgstreamer0.7-devel-0.7.4-2mdk.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML
><HEAD
><TITLE
>The Bytestream Object</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="GStreamer Plugin Writer's Guide"
HREF="index.html"><LINK
REL="UP"
TITLE="How a loopfunc works"
HREF="chapter-loopbased-loopfn.html"><LINK
REL="PREVIOUS"
TITLE="How a loopfunc works"
HREF="chapter-loopbased-loopfn.html"><LINK
REL="NEXT"
TITLE="Adding a second output"
HREF="section-loopbased-secnd.html"></HEAD
><BODY
CLASS="sect1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
><SPAN
CLASS="application"
>GStreamer</SPAN
> Plugin Writer's Guide</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="chapter-loopbased-loopfn.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Chapter 12. How a loopfunc works</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="section-loopbased-secnd.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="sect1"
><H1
CLASS="sect1"
><A
NAME="section-loopfn-bytestream"
>12.2. The Bytestream Object</A
></H1
><P
>&#13;      A second type of elements that wants to be loop-based, are the so-called
      bytestream-elements. Until now, we've only dealt with elements that
      receive of pull full buffers of a random size from other elements. Often,
      however, it is wanted to have control over the stream at a byte-level,
      such as in stream parsers or demuxers. It is possible to manually pull
      buffers and merge them until a certain size; it is easier, however, to
      use bytestream, which wraps this behaviour.
    </P
><P
>&#13;      Bytestream-using elements are ususally stream parsers or demuxers. For
      now, we will take a parser as an example. Demuxers require some more
      magic that will be dealt with later in this guide:
      <A
HREF="chapter-advanced-request.html"
>Chapter 14</A
>. The goal of this parser will be
      to parse a text-file and to push each line of text as a separate buffer
      over its source pad.
    </P
><PRE
CLASS="programlisting"
>&#13;
static void
gst_my_filter_loopfunc (GstElement *element)
{
  GstMyFilter *filter = GST_MY_FILTER (element);
  gint n, num;
  guint8 *data;

  for (n = 0; ; n++) {
    num = gst_bytestream_peek_bytes (filter-&#62;bs, &#38;data, n + 1);
    if (num != n + 1) {
      GstEvent *event = NULL;
      guint remaining;

      gst_bytestream_get_status (filter-&#62;bs, &#38;remaining, &#38;event);
      if (event) {
        if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)) {
          /* end-of-file */
          gst_pad_push (filter-&#62;srcpad, GST_DATA (event));
          gst_element_set_eos (element);

          return;
        }
        gst_event_unref (event);
      }

      /* failed to read - throw error and bail out */
      gst_element_error (element, STREAM, READ, (NULL), (NULL));

      return;
    }

    /* check if the last character is a newline */
    if (data[n] == '\n') {
      GstBuffer *buf = gst_buffer_new_and_alloc (n + 1);

      /* read the line of text without newline - then flush the newline */
      gst_bytestream_peek_data (filter-&#62;bs, &#38;data, n);
      memcpy (GST_BUFFER_DATA (buf), data, n);
      GST_BUFFER_DATA (buf)[n] = '\0';
      gst_bytestream_flush_fast (filter-&#62;bs, n + 1);
      g_print ("Pushing '%s'\n", GST_BUFFER_DATA (buf));
      gst_pad_push (filter-&#62;srcpad, GST_DATA (buf));

      return;
    }
  }
}

static void
gst_my_filter_change_state (GstElement *element)
{
  GstMyFilter *filter = GST_MY_FILTER (element);

  switch (GST_STATE_TRANSITION (element)) {
    case GST_STATE_READY_TO_PAUSED:
      filter-&#62;bs = gst_bytestream_new (filter-&#62;sinkpad);
      break;
    case GST_STATE_PAUSED_TO_READY:
      gst_bytestream_destroy (filter-&#62;bs);
      break;
    default:
      break;
  }

  if (GST_ELEMENT_CLASS (parent_class)-&#62;change_state)
    return GST_ELEMENT_CLASS (parent_class)-&#62;change_state (element);

  return GST_STATE_SUCCESS;
}

    </PRE
><P
>&#13;      In the above example, you'll notice how bytestream handles buffering of
      data for you. The result is that you can handle the same data multiple
      times. Event handling in bytestream is currently sort of
      <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>wacky</I
></SPAN
>, but it works quite well. The one big
      disadvantage of bytestream is that it <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>requires</I
></SPAN
>
      the element to be loop-based. Long-term, we hope to have a chain-based
      usable version of bytestream, too.
    </P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="chapter-loopbased-loopfn.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="section-loopbased-secnd.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>How a loopfunc works</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="chapter-loopbased-loopfn.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Adding a second output</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>