$ git clone http://tcclient.ion.nu/tc_client.git
commit c04f3c83debaaba57b49c64b5bdcfb84e737254e
Author: Alicia <...>
Date:   Sat May 23 21:46:24 2015 +0200

    tc_client-gtk: send the cam stream to tc_client from the main process instead of from the cam child process to avoid potential overlap of writes.

diff --git a/ChangeLog b/ChangeLog
index de2a525..6893997 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,7 @@ Added an 'install' make target, adjusted utilities to run tc_client from PATH un
 irchack: send passwords by pipe, not argument.
 tc_client-gtk: ignore anything after the offset in /mbs commands.
 tc_client-gtk: when camming down, remove the glib event source for our cam stream.
+tc_client-gtk: send the cam stream to tc_client from the main process instead of from the cam child process to avoid potential overlap of writes.
 0.31:
 Fixed the issue where messages would show up on kanji on some platforms (a proper fix instead of the earlier android & apple workaround)
 When a message is sent with a privacy field, send it once with 'b' (broadcasting) and once with 'n' (not-broadcasting)
diff --git a/utilities/gtk/camviewer.c b/utilities/gtk/camviewer.c
index 8a1c45d..9522c9c 100644
--- a/utilities/gtk/camviewer.c
+++ b/utilities/gtk/camviewer.c
@@ -454,6 +454,12 @@ gboolean handledata(GIOChannel* iochannel, GIOCondition condition, gpointer data
   {
     pos+=read(fd, pkt.data+pos, size-pos);
   }
+  if(!strcmp(&buf[7], "out"))
+  {
+    dprintf(tc_client_in[1], "/video %i\n", size+1);
+    write(tc_client_in[1], &frameinfo, 1);
+    write(tc_client_in[1], pkt.data, size);
+  }
   if((frameinfo&0xf)!=2){return 1;} // Not FLV1, get data but discard it
   if(!cam){printf("No cam found with ID '%s'\n", &buf[7]); return 1;}
   pkt.size=size;
@@ -576,10 +582,7 @@ void togglecam(GtkCheckMenuItem* item, struct viddata* data)
 packet.size=0;
       avcodec_encode_video2(ctx, &packet, dstframe, &gotpacket);
       unsigned char frameinfo=0x22; // Note: differentiating between keyframes and non-keyframes seems to break stuff, so let's just go with all being interframes (1=keyframe, 2=interframe, 3=disposable interframe)
-      dprintf(tc_client_in[1], "/video %i\n", packet.size+1);
-      write(tc_client_in[1], &frameinfo, 1);
-      write(tc_client_in[1], packet.data, packet.size);
-      // Also send the packet to our main thread so we can see ourselves
+      // Send the packet to our main thread so we can see ourselves (the main thread also sends it to the server)
       dprintf(campipe[1], "Video: out %i\n", packet.size+1);
       write(campipe[1], &frameinfo, 1);
       write(campipe[1], packet.data, packet.size);