$ git clone http://tcclient.ion.nu/tc_client.git
commit 38fc8d1990a2c5405f75c16f7be3e1c2b77ff9e9
Author: Alicia <...>
Date: Wed May 24 14:21:35 2017 +0200
tc_client-gtk: use pulseaudio for incoming audio if it's available (preferred over libao) and display the volume indicator even if no audio playback library is available.
diff --git a/ChangeLog b/ChangeLog
index e9e0343..ca0a5ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -20,6 +20,7 @@ tc_client-gtk: fixed some memory leaks.
tc_client-gtk: use /quit to guarantee a clean exit.
tc_client-gtk: fixed segfault at exit by doing camera cleanup earlier.
tc_client-gtk: made the automatic brightness postprocessing adjustment gradual.
+tc_client-gtk: use pulseaudio for incoming audio if it's available (preferred over libao) and display the volume indicator even if no audio playback library is available.
irchack: don't rely on connection ID.
0.41.1:
Use tinychat.com instead of apl.tinychat.com (works around SSL/TLS issues on windows)
diff --git a/Makefile b/Makefile
index 8e5979f..91131be 100644
--- a/Makefile
+++ b/Makefile
@@ -28,28 +28,34 @@ ifdef SWSCALE_LIBS
UTILS+=camviewer tc_client-gtk
CFLAGS+=$(GTK_CFLAGS) $(AVCODEC_CFLAGS) $(AVUTIL_CFLAGS) $(SWSCALE_CFLAGS)
INSTALLDEPS+=tc_client-gtk gtkgui.glade
- ifdef AO_LIBS
- ifdef AVRESAMPLE_LIBS
- CONFINFO+=| Will enable incoming mic support
- CFLAGS+=-DHAVE_LIBAO=1 -DHAVE_AVRESAMPLE=1 $(AVRESAMPLE_CFLAGS) $(AO_CFLAGS)
- endif
- ifdef SWRESAMPLE_LIBS
- CONFINFO+=| Will enable incoming mic support
- CFLAGS+=-DHAVE_LIBAO=1 -DHAVE_SWRESAMPLE=1 $(SWRESAMPLE_CFLAGS) $(AO_CFLAGS)
- endif
- ifndef AVRESAMPLE_LIBS
- ifndef SWRESAMPLE_LIBS
- CONFINFO+=| Incoming mic support will not be enabled
- endif
+ ifdef HAVE_PULSE
+ AUDIO_CFLAGS=-DHAVE_PULSEAUDIO=1 $(PULSE_CFLAGS)
+ HAVE_AUDIOLIB=1
+ else
+ ifdef HAVE_AO
+ AUDIO_CFLAGS=-DHAVE_LIBAO=1 $(AO_CFLAGS)
+ HAVE_AUDIOLIB=1
endif
endif
+ ifdef AVRESAMPLE_LIBS
+ HAVE_RESAMPLELIB=1
+ CFLAGS+=-DHAVE_AVRESAMPLE=1 $(AVRESAMPLE_CFLAGS) $(AUDIO_CFLAGS)
+ endif
+ ifdef SWRESAMPLE_LIBS
+ HAVE_RESAMPLELIB=1
+ CFLAGS+=-DHAVE_SWRESAMPLE=1 $(SWRESAMPLE_CFLAGS) $(AUDIO_CFLAGS)
+ endif
+ ifeq ($(HAVE_RESAMPLELIB)$(HAVE_AUDIOLIB),11)
+ CONFINFO+=| Will enable incoming mic support
+ else
+ CONFINFO+=| Incoming mic support will not be enabled
+ endif
ifdef AVFORMAT_LIBS
CFLAGS+=-DHAVE_AVFORMAT=1
CONFINFO+=| Will enable integrated youtube videos
endif
- ifdef PULSE_LIBS
+ ifeq ($(HAVE_RESAMPLELIB)$(HAVE_PULSE),11)
CONFINFO+=| Will enable outgoing mic support
- CFLAGS+=-DHAVE_PULSEAUDIO=1 $(PULSE_CFLAGS)
else
CONFINFO+=| Outgoing mic support will not be enabled
endif
diff --git a/configure b/configure
index e47dc2d..8ddf184 100755
--- a/configure
+++ b/configure
@@ -3,6 +3,7 @@
host=''
prefix=''
+args="$@"
while [ "$#" -gt 0 ]; do
case "$1" in
--host=*) host="`echo "$1" | sed -e 's/--host=//'`";;
@@ -17,6 +18,7 @@ while [ "$#" -gt 0 ]; do
done
rm -f config.mk
true > config.h
+echo "# Generated with: $0 $args" > config.mk
if [ -n "$prefix" ]; then echo "PREFIX=${prefix}" >> config.mk; fi
printf 'Checking for a C compiler... '
@@ -78,6 +80,7 @@ testpkgconfig()
if [ "x$testlibs" != "x" ]; then
echo "${varprefix}_LIBS=${testlibs}" >> config.mk
echo "${varprefix}_CFLAGS=`pkg-config --cflags "$pkgname"`" >> config.mk
+ echo "HAVE_${varprefix}=1" >> config.mk
echo yes
return 0
else
diff --git a/testbuilds.sh b/testbuilds.sh
index b6d473d..b26d118 100755
--- a/testbuilds.sh
+++ b/testbuilds.sh
@@ -16,6 +16,9 @@ while true; do
if ! grep -q '^SWSCALE_LIBS' config.mk; then res="libswscale not found, can't test"; break; fi
if ! grep -q '^GLIB_LIBS' config.mk; then res="glib not found, can't test"; break; fi
sed -i -e '/^AO_LIBS/d' config.mk
+ sed -i -e '/^PULSE_LIBS/d' config.mk
+ sed -i -e '/^HAVE_AO/d' config.mk
+ sed -i -e '/^HAVE_PULSE/d' config.mk
sed -i -e '/^AVFORMAT_LIBS/d' config.mk
echo 'CFLAGS+=-Werror' >> config.mk
if ! make utils > /dev/null 2> /dev/null; then
diff --git a/utilities/gtk/camviewer.c b/utilities/gtk/camviewer.c
index aa9250b..635b3c4 100644
--- a/utilities/gtk/camviewer.c
+++ b/utilities/gtk/camviewer.c
@@ -38,10 +38,15 @@
#ifdef HAVE_AVRESAMPLE
#include <libavutil/opt.h>
#include <libavresample/avresample.h>
- #include <ao/ao.h>
#elif defined(HAVE_SWRESAMPLE)
#include <libswresample/swresample.h>
- #include <ao/ao.h>
+#endif
+#if defined(HAVE_AVRESAMPLE) || defined(HAVE_SWRESAMPLE)
+ #ifdef HAVE_PULSEAUDIO
+ #include <pulse/simple.h>
+ #elif defined(HAVE_LIBAO)
+ #include <ao/ao.h>
+ #endif
#endif
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
@@ -67,7 +72,6 @@ struct viddata
{
AVCodec* vdecoder;
AVCodec* vencoder;
- int audiopipe;
};
struct viddata* data;
@@ -209,7 +213,7 @@ gboolean handledata(GIOChannel* iochannel, GIOCondition condition, gpointer x)
g_io_channel_read_chars(iochannel, (gchar*)pkt.data+pos, size-pos, &r, 0);
pos+=r;
}
-#ifdef HAVE_LIBAO
+#if defined(HAVE_AVRESAMPLE) || defined(HAVE_SWRESAMPLE)
// Find the camera representation for the given ID (for decoder context)
struct camera* cam=camera_find(&buf[7]);
if(!cam){printf("No cam found with ID '%s'\n", &buf[7]); return 1;}
@@ -584,10 +588,30 @@ gboolean handledata(GIOChannel* iochannel, GIOCondition condition, gpointer x)
return 1;
}
-#ifdef HAVE_LIBAO
+#if (defined(HAVE_AVRESAMPLE) || defined(HAVE_SWRESAMPLE)) && (defined(HAVE_PULSEAUDIO) || defined(HAVE_LIBAO))
+extern void justwait(int);
void* audiothread(void* fdp)
{
int fd=*(int*)fdp;
+ char buf[2048];
+ size_t len;
+ #ifdef HAVE_PULSEAUDIO
+ pa_simple* pulse;
+ pa_sample_spec pulsespec;
+ pulsespec.format=PA_SAMPLE_S16NE;
+ pulsespec.channels=1;
+ pulsespec.rate=SAMPLERATE_OUT;
+ signal(SIGCHLD, SIG_DFL); // Briefly revert to the default handler to not break pulseaudio's autospawn feature
+ pulse=pa_simple_new(0, "tc_client-gtk", PA_STREAM_PLAYBACK, 0, channel, &pulsespec, 0, 0, 0);
+ signal(SIGCHLD, justwait);
+ if(!pulse){return 0;}
+ while((len=read(fd, buf, 2048))>0)
+ {
+ if(pa_simple_write(pulse, buf, len, 0)<0){break;}
+ }
+ pa_simple_free(pulse);
+ close(fd);
+ #else
ao_initialize();
ao_sample_format samplefmt;
samplefmt.bits=16;
@@ -597,13 +621,12 @@ void* audiothread(void* fdp)
samplefmt.matrix=0;
ao_option clientname={.key="client_name", .value="tc_client-gtk", .next=0};
ao_device* dev=ao_open_live(ao_default_driver_id(), &samplefmt, &clientname);
- char buf[2048];
- size_t len;
while((len=read(fd, buf, 2048))>0)
{
ao_play(dev, buf, len);
}
ao_close(dev);
+ #endif
return 0;
}
#endif
@@ -971,6 +994,15 @@ void startsession(GtkButton* button, void* x)
GIOChannel* tcchannel=g_io_channel_unix_new(tc_client[0]);
g_io_channel_set_encoding(tcchannel, 0, 0);
g_io_add_watch(tcchannel, G_IO_IN, handledata, data);
+#if (defined(HAVE_PULSEAUDIO) || defined(HAVE_LIBAO)) && (defined(HAVE_AVRESAMPLE) || defined(HAVE_SWRESAMPLE))
+ static int audiopipe[2]={-1,-1};
+ if(audiopipe[0]==-1)
+ {
+ pipe(audiopipe);
+ g_thread_new("audio", audiothread, audiopipe);
+ g_timeout_add(40, audiomixer, &audiopipe[1]);
+ }
+#endif
}
void captcha_done(GtkWidget* button, void* x)
@@ -988,7 +1020,7 @@ void justwait(int x){waitpid(-1, 0, WNOHANG);}
int main(int argc, char** argv)
{
if(!strncmp(argv[0], "./", 2)){frombuild=1;}
- struct viddata datax={0,0,0};
+ struct viddata datax={0,0};
data=&datax;
avcodec_register_all();
data->vdecoder=avcodec_find_decoder(AV_CODEC_ID_FLV1);
@@ -1000,20 +1032,10 @@ int main(int argc, char** argv)
#endif
config_load();
-#ifdef HAVE_LIBAO
- int audiopipe[2];
- pipe(audiopipe);
- data->audiopipe=audiopipe[1];
- g_thread_new("audio", audiothread, audiopipe);
-#endif
-
gtk_init(&argc, &argv);
gui_init(frombuild);
campreview.frame=av_frame_alloc();
campreview.frame->data[0]=0;
-#ifdef HAVE_LIBAO
- g_timeout_add(40, audiomixer, &audiopipe[1]);
-#endif
gtk_main();
camera_cleanup();
write(tc_client_in[1], "/quit\n", 6);
diff --git a/utilities/gtk/media.c b/utilities/gtk/media.c
index eb9a7fe..d87932b 100644
--- a/utilities/gtk/media.c
+++ b/utilities/gtk/media.c
@@ -64,11 +64,14 @@ unsigned int camout_delay;
#if defined(HAVE_AVRESAMPLE) || defined(HAVE_SWRESAMPLE)
void camera_playsnd(struct camera* cam, int16_t* samples, unsigned int samplecount)
{
+#if defined(HAVE_PULSEAUDIO) || defined(HAVE_LIBAO)
cam->samples=realloc(cam->samples, sizeof(int16_t)*(cam->samplecount+samplecount));
memcpy(&cam->samples[cam->samplecount], samples, samplecount*sizeof(short));
cam->samplecount+=samplecount;
+#endif
}
+#if defined(HAVE_PULSEAUDIO) || defined(HAVE_LIBAO)
gboolean audiomixer(void* p)
{
int audiopipe=*(int*)p;
@@ -103,6 +106,7 @@ gboolean audiomixer(void* p)
return G_SOURCE_CONTINUE;
}
#endif
+#endif
void camera_free(struct camera* cam)
{
@@ -213,7 +217,7 @@ struct camera* camera_new(const char* nick, const char* id, unsigned char flags)
return cam;
}
-#ifdef HAVE_LIBAO
+#if defined(HAVE_AVRESAMPLE) || defined(HAVE_SWRESAMPLE)
char camera_init_audio(struct camera* cam, uint8_t frameinfo)
{
switch((frameinfo&0xc)/0x4)
@@ -797,7 +801,7 @@ void camera_decode(struct camera* cam, AVPacket* pkt, unsigned int width, unsign
if(oldpixbuf){g_object_unref(oldpixbuf);}
}
-#ifdef HAVE_LIBAO
+#if defined(HAVE_AVRESAMPLE) || defined(HAVE_SWRESAMPLE)
void mic_decode(struct camera* cam, AVPacket* pkt)
{
int gotframe;
diff --git a/utilities/gtk/media.h b/utilities/gtk/media.h
index b7e45a7..cea12d7 100644
--- a/utilities/gtk/media.h
+++ b/utilities/gtk/media.h
@@ -78,7 +78,9 @@ extern void camera_remove(const char* id, char isnick);
extern struct camera* camera_find(const char* id);
extern struct camera* camera_findbynick(const char* nick);
extern struct camera* camera_new(const char* nick, const char* id, unsigned char flags);
+#if defined(HAVE_AVRESAMPLE) || defined(HAVE_SWRESAMPLE)
extern char camera_init_audio(struct camera* cam, uint8_t frameinfo);
+#endif
extern void camera_cleanup(void);
extern void freebuffer(guchar* pixels, gpointer data);
extern void startcamout(CAM* cam);
@@ -97,7 +99,7 @@ extern gboolean mic_encode(GIOChannel* iochannel, GIOCondition condition, gpoint
extern void camera_calcvolume(struct camera* cam, float* samples, unsigned int samplecount);
extern void volume_indicator(GdkPixbuf* frame, struct camera* cam);
extern void camera_decode(struct camera* cam, AVPacket* pkt, unsigned int width, unsigned int height);
-#ifdef HAVE_LIBAO
+#if defined(HAVE_AVRESAMPLE) || defined(HAVE_SWRESAMPLE)
extern void mic_decode(struct camera* cam, AVPacket* pkt);
#endif
#endif