<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
    <title></title>
  </head>
  <body bgcolor="#ffffff" text="#000000">
    Re-hi,<br>
    <br>
    Ok, I found a solution by studying the source of
    gnome-media-2.30.0/grecord. <br>
    <br>
    My code now calls rec_set_state_to_null() function that sets the
    pipeline to GST_STATE_NULL state.&nbsp; Rec_state_changed_cb(...)
    function receives now messages so the state goes from PLAYING -&gt;
    PAUSED -&gt; READY/NULL. And the GUI is updated appropriately.<br>
    <br>
    Very good. I can now bake the code to my recorder.<br>
    <br>
    void rec_set_state_to_null() {<br>
    &nbsp;&nbsp;&nbsp; // Copyright notice:<br>
    &nbsp;&nbsp;&nbsp; // Copied from gnome-media-2.30.0/grecord.<br>
    <br>
    &nbsp;&nbsp;&nbsp; // Set state of pipeline to GST_STATE_NULL.<br>
    &nbsp;&nbsp;&nbsp; GstMessage *msg;<br>
    &nbsp;&nbsp;&nbsp; GstState cur_state, pending;<br>
    &nbsp;&nbsp;&nbsp; GstBus *bus;<br>
    <br>
    &nbsp;&nbsp;&nbsp; if (!GST_IS_PIPELINE(g_rec.pipeline)) return;<br>
    <br>
    &nbsp;&nbsp;&nbsp; gst_element_get_state(g_rec.pipeline, &amp;cur_state,
    &amp;pending, 0);<br>
    <br>
    &nbsp;&nbsp;&nbsp; if (cur_state == GST_STATE_NULL &amp;&amp; pending ==
    GST_STATE_VOID_PENDING)<br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;<br>
    <br>
    &nbsp;&nbsp;&nbsp; if (cur_state == GST_STATE_NULL &amp;&amp; pending !=
    GST_STATE_VOID_PENDING) {<br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gst_element_set_state (g_rec.pipeline, GST_STATE_NULL);<br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;<br>
    &nbsp;&nbsp;&nbsp; }<br>
    <br>
    &nbsp;&nbsp;&nbsp; gst_element_set_state(g_rec.pipeline, GST_STATE_READY);<br>
    &nbsp;&nbsp;&nbsp; gst_element_get_state(g_rec.pipeline, NULL, NULL, -1);<br>
    <br>
    &nbsp;&nbsp;&nbsp; bus = gst_element_get_bus(g_rec.pipeline);<br>
    &nbsp;&nbsp;&nbsp; if (GST_IS_BUS(bus)) {<br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while ((msg = gst_bus_pop(bus))) {<br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gst_bus_async_signal_func(bus, msg, NULL);<br>
    <br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gst_message_unref(msg); <br>
    <br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gst_object_unref(bus);<br>
    &nbsp;&nbsp;&nbsp; }<br>
    <br>
    &nbsp;&nbsp;&nbsp; gst_element_set_state(g_rec.pipeline, GST_STATE_NULL);<br>
    }<br>
    <br>
    Thanks.<br>
    &nbsp; Osmo Antero (Moma)<br>
    &nbsp; <a moz-do-not-send="true" class="moz-txt-link-freetext"
      href="http://www.futuredesktop.org">http://www.futuredesktop.org</a><br>
    <br>
    <br>
    On 12/20/2010 11:43 AM, Osmo Antero Maatta wrote:
    <blockquote cite="mid:4D0F3344.6090706@gmail.com" type="cite">
      <meta http-equiv="content-type" content="text/html;
        charset=ISO-8859-1">
      Hello,<br>
      I have created an audio-recorder application using the GStreamer
      framework. My question is:<br>
      How to catch and react to the EOS (end of stream, end of
      recording) message? <br>
      <br>
      When starting a recording the state change from NULL -&gt; PLAYING
      works fine.<br>
      My program now updates the GUI (buttons, icons in the GUI) when
      the recording changes state from NULL -&gt; READY -&gt; PLAYING.
      This works OK.&nbsp; <br>
      <br>
      Also state change from PLAYING -&gt; PAUSED works fine. My program
      captures the PAUSED message and updates the GUI. This is OK.<br>
      <br>
      But how to catch the STOP message (when the recording stops/ends)
      ?&nbsp; Obviously Gstreamer has no STOP/STREAM END message.&nbsp; Are there
      event-chain for PLAYING -&gt; PAUSED -&gt; STOP/NULL?<br>
      <br>
      <b>I want to update the GUI solely via the Gstreamer's
        state-change messages/events. </b><br>
      Why? Because the recording can be controlled from various places;
      directly from the GUI using buttons, it can be controlled from
      DBus by Media Players (like Amarok/RhythmBox/Banshee and there are
      threads involved etc.). So I want to update the GUI solely via
      (event's) state changes.<br>
      <br>
      Here is how I setup the callback functions to receive
      events/messages from the bus.<br>
      See:&nbsp; rec_state_changed_cb(...) function in <br>
      <a moz-do-not-send="true" class="moz-txt-link-freetext"
        href="http://www.futuredesktop.com/tmp/gst-recorder.c">http://www.futuredesktop.com/tmp/gst-recorder.c</a>
      <br>
      <br>
      The message/event handlers are set up like this (in the
      rec_create_pipeline(...) function) :<br>
      <br>
      // Add a message handlers<br>
      GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));<br>
      gst_bus_add_signal_watch(bus);<br>
      <br>
      // Detect state changes<br>
      g_signal_connect(bus, "message::state-changed",
      G_CALLBACK(rec_state_changed_cb), NULL);<br>
      <br>
      // Monitor sound level/amplitude<br>
      g_signal_connect(bus, "message::element",
      G_CALLBACK(rec_level_message_cb), NULL);<br>
      <br>
      // Catch error messages<br>
      g_signal_connect(bus, "message::error",
      G_CALLBACK(rec_pipeline_error_cb), NULL);<br>
      <br>
      // EOS<br>
      g_signal_connect(bus, "message::eos", G_CALLBACK(rec_eos_msg_cb),
      NULL);<br>
      <br>
      gst_object_unref(bus);<br>
      ----<br>
      <br>
      Thanks,<br>
      &nbsp; Osmo Antero (Moma)<br>
      &nbsp; <a moz-do-not-send="true" class="moz-txt-link-freetext"
        href="http://www.futuredesktop.org">http://www.futuredesktop.org</a><br>
      <br>
      <br>
      <br>
      <br>
      <br>
      <br>
    </blockquote>
    <br>
    <br>
  </body>
</html>