Index: roard/streams.c
===================================================================
--- roard/streams.c	(revision 4290)
+++ roard/streams.c	(revision 4336)
@@ -32,4 +32,22 @@
 int streams_recsource_id = -1;
 
+static void _streams_change_state(struct roar_stream_server * s, const int new, const char * func) {
+ register int id  = ROAR_STREAM(s)->id;
+ register int old = s->state;
+
+ s->state = new;
+
+ if ( func == NULL ) {
+  func = "(unknown)";
+ }
+
+ ROAR_INFO("_streams_change_state[by %s](id=%i): stream state: %s->%s", ROAR_DBG_INFO_VERBOSE,
+            func,
+            ROAR_STREAM(s)->id,
+            roar_streamstate2str(old), roar_streamstate2str(new));
+
+ roar_notify_core_emit_simple(ROAR_OE_BASICS_CHANGE_STATE, -1, id, ROAR_OT_STREAM, old, new, NULL, 0);
+}
+
 int streams_init (void) {
  int i;
@@ -165,6 +183,5 @@
   return 0;
 
- ROAR_INFO("streams_delete(id=%i): stream state: %s->closing", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(s->state));
- s->state = ROAR_STREAMSTATE_CLOSING;
+ _streams_change_state(s, ROAR_STREAMSTATE_CLOSING, "streams_delete");
 
  counters_inc(streams, -1);
@@ -596,6 +613,6 @@
  if ( fh == -1 || fh == -2 ) { // yes, this is valid, indecats full vio!
   ss->ready = 1;
-  ROAR_INFO("streams_set_fh(id=%i, fh=%i): stream state: %s->new", ROAR_DBG_INFO_VERBOSE, id, fh, roar_streamstate2str(ss->state));
-  ss->state = ROAR_STREAMSTATE_NEW;
+  //ROAR_INFO("streams_set_fh(id=%i, fh=%i): stream state: %s->new", ROAR_DBG_INFO_VERBOSE, id, fh, roar_streamstate2str(ss->state));
+  _streams_change_state(ss, ROAR_STREAMSTATE_NEW, "streams_set_fh");
   return 0;
  }
@@ -633,6 +650,6 @@
  if ( !nonblock ) {
   ss->ready = 1;
-  ROAR_INFO("streams_set_fh(id=%i, fh=%i): stream state: %s->new", ROAR_DBG_INFO_VERBOSE, id, fh, roar_streamstate2str(ss->state));
-  ss->state = ROAR_STREAMSTATE_NEW;
+  //ROAR_INFO("streams_set_fh(id=%i, fh=%i): stream state: %s->new", ROAR_DBG_INFO_VERBOSE, id, fh, roar_streamstate2str(ss->state));
+  _streams_change_state(ss, ROAR_STREAMSTATE_NEW, "streams_set_fh");
 
   ROAR_DBG("streams_set_fh(id=%i, fh=%i) = 0", id, fh);
@@ -645,6 +662,6 @@
 
   ss->ready = 1;
-  ROAR_INFO("streams_set_fh(id=%i, fh=%i): stream state: %s->new", ROAR_DBG_INFO_VERBOSE, id, fh, roar_streamstate2str(ss->state));
-  ss->state = ROAR_STREAMSTATE_NEW;
+  //ROAR_INFO("streams_set_fh(id=%i, fh=%i): stream state: %s->new", ROAR_DBG_INFO_VERBOSE, id, fh, roar_streamstate2str(ss->state));
+  _streams_change_state(ss, ROAR_STREAMSTATE_NEW, "streams_set_fh");
 
   ROAR_DBG("streams_set_fh(id=%i, fh=%i) = 0", id, fh);
@@ -1314,6 +1331,6 @@
 
  if ( ss->is_new ) {
-  ss->state = ROAR_STREAMSTATE_OLD;
-  ROAR_INFO("streams_fill_mixbuffer2(id=%i, info=...): stream state: new->old", ROAR_DBG_INFO_VERBOSE, id);
+  //ROAR_INFO("streams_fill_mixbuffer2(id=%i, info=...): stream state: new->old", ROAR_DBG_INFO_VERBOSE, id);
+  _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_fill_mixbuffer2");
  }
 
@@ -1878,7 +1895,7 @@
      if ( codecfilter_write(ss->codecfilter_inst, ss->codecfilter, NULL, 0) == 0 )
       if ( ss->state != ROAR_STREAMSTATE_OLD ) {
-       ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
+       //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
+       _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon");
       }
-      ss->state = ROAR_STREAMSTATE_OLD;
     }
     return 0;
@@ -1973,7 +1990,7 @@
    s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, ROAR_OUTPUT_CALC_OUTBUFSAMP(&(s->info), olen)*s->info.channels);
    if ( ss->state != ROAR_STREAMSTATE_OLD ) {
-    ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
+    //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
+    _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon");
    }
-   ss->state = ROAR_STREAMSTATE_OLD;
    ROAR_DBG("streams_send_mon(id=%i) = 0", id);
    _return(0);
@@ -1986,7 +2003,7 @@
    s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, ROAR_OUTPUT_CALC_OUTBUFSAMP(&(s->info), ret)*s->info.channels);
    if ( ss->state != ROAR_STREAMSTATE_OLD ) {
-    ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
+    //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
+    _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon");
    }
-   ss->state = ROAR_STREAMSTATE_OLD;
    _return(0);
   }
@@ -1997,7 +2014,7 @@
    s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, ROAR_OUTPUT_CALC_OUTBUFSAMP(&(s->info), olen)*s->info.channels);
    if ( ss->state != ROAR_STREAMSTATE_OLD ) {
-    ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
+    //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
+    _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon");
    }
-   ss->state = ROAR_STREAMSTATE_OLD;
    _return(0);
   } else { // we cann't retry on codec filetered streams
@@ -2020,7 +2037,7 @@
    s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, ROAR_OUTPUT_CALC_OUTBUFSAMP(&(s->info), olen)*s->info.channels);
    if ( ss->state != ROAR_STREAMSTATE_OLD ) {
-    ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
+    //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
+    _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon");
    }
-   ss->state = ROAR_STREAMSTATE_OLD;
    _return(0);
   } else if ( errno == EAGAIN ) {
@@ -2134,7 +2151,7 @@
       if ( g_streams[i] != NULL ) {
        if ( g_streams[i]->state != ROAR_STREAMSTATE_OLD ) {
-        ROAR_INFO("stream_vio_s_read(*): (stream: %i) stream state: %s->old", ROAR_DBG_INFO_VERBOSE, i, roar_streamstate2str(g_streams[i]->state));
+        //ROAR_INFO("stream_vio_s_read(*): (stream: %i) stream state: %s->old", ROAR_DBG_INFO_VERBOSE, i, roar_streamstate2str(g_streams[i]->state));
+        _streams_change_state(g_streams[i], ROAR_STREAMSTATE_OLD, "stream_vio_s_read");
        }
-       g_streams[i]->state = ROAR_STREAMSTATE_OLD;
       }
      }
@@ -2181,7 +2198,7 @@
       if ( g_streams[i] != NULL ) {
        if ( g_streams[i]->state != ROAR_STREAMSTATE_OLD ) {
-        ROAR_INFO("stream_vio_s_write(*): (stream: %i) stream state: %s->old", ROAR_DBG_INFO_VERBOSE, i, roar_streamstate2str(g_streams[i]->state));
+        //ROAR_INFO("stream_vio_s_write(*): (stream: %i) stream state: %s->old", ROAR_DBG_INFO_VERBOSE, i, roar_streamstate2str(g_streams[i]->state));
+        _streams_change_state(g_streams[i], ROAR_STREAMSTATE_OLD, "stream_vio_s_write");
        }
-       g_streams[i]->state = ROAR_STREAMSTATE_OLD;
       }
      }
