$ git clone http://tcclient.ion.nu/tc_client.git
commit 3bf6dc5ca287b43b5c85746611e75f64c05ec561
Author: Alicia <...>
Date: Wed Dec 21 23:52:03 2016 +0100
tc_client-gtk: made camera scaling keep the aspect ratio.
diff --git a/ChangeLog b/ChangeLog
index 364f0c3..0fc408d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -29,6 +29,7 @@ tc_client-gtk: made the user list sorted.
tc_client-gtk: added support for viewing and approving greenroom cameras.
tc_client-gtk: added an option to show the greenroom menu even when you're not a moderator.
tc_client-gtk: implemented broadcasting to greenroom while awaiting approval.
+tc_client-gtk: made camera scaling keep the aspect ratio.
dist/appimage.sh: fix audio in appimages by building ffmpeg with support for nellymoser and speex, and depending on the system's libao and libpulse instead of including it in the appimage.
libcamera(escapi): handle failure to open camera more gracefully.
irchack: pass along "<user> cammed up" notifications.
diff --git a/utilities/gtk/media.c b/utilities/gtk/media.c
index 37b69f2..cca7b8f 100644
--- a/utilities/gtk/media.c
+++ b/utilities/gtk/media.c
@@ -276,6 +276,34 @@ void startcamout(CAM* cam)
g_timeout_add(camout_delay, cam_encode, cam);
}
+GdkPixbuf* scaleframe(void* data, unsigned int width, unsigned int height, unsigned int linesize, unsigned int towidth, unsigned int toheight)
+{
+ GdkPixbuf* gdkframe=gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, 0, 8, width, height, linesize, 0, 0);
+ // Scale to fit
+ GdkPixbuf* scaled=gdk_pixbuf_new(GDK_COLORSPACE_RGB, 0, 8, towidth, toheight);
+ double scalex=(double)towidth/(double)width;
+ double scaley=(double)toheight/(double)height;
+ unsigned int offsetx=0;
+ unsigned int offsety=0;
+ if(height*4/3>width)
+ {
+ scalex=scaley;
+ offsetx=(towidth-width*toheight/height)/2;
+ towidth=width*toheight/height;
+ gdk_pixbuf_fill(scaled, 0);
+ }
+ else if(width*3/4>height)
+ {
+ scaley=scalex;
+ offsety=(toheight-height*towidth/width)/2;
+ toheight=height*towidth/width;
+ gdk_pixbuf_fill(scaled, 0);
+ }
+ gdk_pixbuf_scale(gdkframe, scaled, offsetx, offsety, towidth, toheight, offsetx, offsety, scalex, scaley, GDK_INTERP_BILINEAR);
+ g_object_unref(gdkframe);
+ return scaled;
+}
+
gboolean cam_encode(void* camera_)
{
CAM* camera=camera_;
@@ -309,9 +337,7 @@ gboolean cam_encode(void* camera_)
postprocess(&cam->postproc, cam->frame->data[0], cam->frame->width, cam->frame->height);
// Update our local display
GdkPixbuf* oldpixbuf=gtk_image_get_pixbuf(GTK_IMAGE(cam->cam));
- GdkPixbuf* gdkframe=gdk_pixbuf_new_from_data(cam->frame->data[0], GDK_COLORSPACE_RGB, 0, 8, cam->frame->width, cam->frame->height, cam->frame->linesize[0], 0, 0);
- // Scale to fit
- gdkframe=gdk_pixbuf_scale_simple(gdkframe, camsize_scale.width, camsize_scale.height, GDK_INTERP_BILINEAR);
+ GdkPixbuf* gdkframe=scaleframe(cam->frame->data[0], cam->frame->width, cam->frame->height, cam->frame->linesize[0], camsize_scale.width, camsize_scale.height);
volume_indicator(gdkframe, cam); // Add volume indicator
int fd;
if(hasgreenroom && !greenroom_gotpass)
@@ -750,17 +776,17 @@ void camera_decode(struct camera* cam, AVPacket* pkt, unsigned int width, unsign
cam->placeholder=0;
}
// Scale and convert to RGB24 format
- unsigned int bufsize=av_image_get_buffer_size(AV_PIX_FMT_RGB24, width, height, 1);
- unsigned char* buf=malloc(bufsize);
+ unsigned int bufsize=av_image_get_buffer_size(AV_PIX_FMT_RGB24, cam->frame->width, cam->frame->height, 1);
+ unsigned char buf[bufsize];
cam->dstframe->data[0]=buf;
- cam->dstframe->linesize[0]=width*3;
- struct SwsContext* swsctx=sws_getContext(cam->frame->width, cam->frame->height, cam->frame->format, width, height, AV_PIX_FMT_RGB24, SWS_BICUBIC, 0, 0, 0);
+ cam->dstframe->linesize[0]=cam->frame->width*3;
+ struct SwsContext* swsctx=sws_getContext(cam->frame->width, cam->frame->height, cam->frame->format, cam->frame->width, cam->frame->height, AV_PIX_FMT_RGB24, SWS_BICUBIC, 0, 0, 0);
sws_scale(swsctx, (const uint8_t*const*)cam->frame->data, cam->frame->linesize, 0, cam->frame->height, cam->dstframe->data, cam->dstframe->linesize);
sws_freeContext(swsctx);
- postprocess(&cam->postproc, cam->dstframe->data[0], width, height);
+ postprocess(&cam->postproc, cam->dstframe->data[0], cam->frame->width, cam->frame->height);
GdkPixbuf* oldpixbuf=gtk_image_get_pixbuf(GTK_IMAGE(cam->cam));
- GdkPixbuf* gdkframe=gdk_pixbuf_new_from_data(cam->dstframe->data[0], GDK_COLORSPACE_RGB, 0, 8, width, height, cam->dstframe->linesize[0], freebuffer, 0);
+ GdkPixbuf* gdkframe=scaleframe(cam->dstframe->data[0], cam->frame->width, cam->frame->height, cam->dstframe->linesize[0], width, height);
volume_indicator(gdkframe, cam);
gtk_image_set_from_pixbuf(GTK_IMAGE(cam->cam), gdkframe);
if(oldpixbuf){g_object_unref(oldpixbuf);}