| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2012-04-30 14:24:11 +00:00
										 |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							| 
									
										
										
										
											2010-03-28 17:01:46 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2012-04-30 14:24:11 +00:00
										 |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2012-04-30 14:24:11 +00:00
										 |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (c) 2006 Peter Schlaile | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 09:38:02 +00:00
										 |  |  | /** \file blender/blenkernel/intern/writeframeserver.c
 | 
					
						
							|  |  |  |  *  \ingroup bke | 
					
						
							| 
									
										
										
										
											2012-04-30 14:24:11 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Frameserver | 
					
						
							|  |  |  |  * Makes Blender accessible from TMPGenc directly using VFAPI (you can | 
					
						
							|  |  |  |  * use firefox too ;-) | 
					
						
							| 
									
										
										
										
											2011-10-10 09:38:02 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-21 23:06:51 +00:00
										 |  |  | #ifdef WITH_FRAMESERVER
 | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | #include <winsock2.h>
 | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | #include <windows.h>
 | 
					
						
							|  |  |  | #include <winbase.h>
 | 
					
						
							|  |  |  | #include <direct.h>
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2006-02-08 23:00:34 +00:00
										 |  |  | #include <sys/time.h>
 | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | #include <sys/socket.h>
 | 
					
						
							| 
									
										
										
										
											2006-06-26 13:22:55 +00:00
										 |  |  | #include <sys/types.h>
 | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | #include <netinet/in.h>
 | 
					
						
							|  |  |  | #include <arpa/inet.h>
 | 
					
						
							|  |  |  | #include <net/if.h>
 | 
					
						
							|  |  |  | #include <netdb.h>
 | 
					
						
							|  |  |  | #include <sys/ioctl.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #include <sys/un.h>
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_userdef_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 18:36:47 +00:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-14 17:55:27 +00:00
										 |  |  | #include "BKE_writeframeserver.h"
 | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | #include "BKE_global.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-22 12:01:32 +00:00
										 |  |  | #include "BKE_report.h"
 | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_scene_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int sock; | 
					
						
							|  |  |  | static int connsock; | 
					
						
							|  |  |  | static int write_ppm; | 
					
						
							|  |  |  | static int render_width; | 
					
						
							|  |  |  | static int render_height; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | #if defined(_WIN32)
 | 
					
						
							| 
									
										
										
										
											2010-12-03 16:45:04 +00:00
										 |  |  | static int startup_socket_system(void) | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	WSADATA wsa; | 
					
						
							| 
									
										
										
										
											2012-04-29 15:47:02 +00:00
										 |  |  | 	return (WSAStartup(MAKEWORD(2, 0), &wsa) == 0); | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 16:45:04 +00:00
										 |  |  | static void shutdown_socket_system(void) | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	WSACleanup(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-12-03 16:45:04 +00:00
										 |  |  | static int select_was_interrupted_by_signal(void) | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return (WSAGetLastError() == WSAEINTR); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | static int startup_socket_system(void) | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | static void shutdown_socket_system(void) | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 12:30:59 +00:00
										 |  |  | static int select_was_interrupted_by_signal(void) | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return (errno == EINTR); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-28 17:01:46 +00:00
										 |  |  | static int closesocket(int fd) | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 	return close(fd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-07 09:30:15 +00:00
										 |  |  | int BKE_frameserver_start(struct Scene *scene, RenderData *UNUSED(rd), int rectx, int recty, ReportList *reports) | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-22 12:01:32 +00:00
										 |  |  | 	struct sockaddr_in addr; | 
					
						
							| 
									
										
										
										
											2006-06-26 13:22:55 +00:00
										 |  |  | 	int arg = 1; | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	(void)scene; /* unused */ | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | 	if (!startup_socket_system()) { | 
					
						
							| 
									
										
										
										
											2012-10-21 14:02:30 +00:00
										 |  |  | 		BKE_report(reports, RPT_ERROR, "Cannot startup socket system"); | 
					
						
							| 
									
										
										
										
											2009-12-22 12:01:32 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | 		shutdown_socket_system(); | 
					
						
							| 
									
										
										
										
											2012-10-21 14:02:30 +00:00
										 |  |  | 		BKE_report(reports, RPT_ERROR, "Cannot open socket"); | 
					
						
							| 
									
										
										
										
											2009-12-22 12:01:32 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  | 	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &arg, sizeof(arg)); | 
					
						
							| 
									
										
										
										
											2006-06-26 13:22:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 	addr.sin_family = AF_INET; | 
					
						
							| 
									
										
										
										
											2009-12-22 12:01:32 +00:00
										 |  |  | 	addr.sin_port = htons(U.frameserverport); | 
					
						
							|  |  |  | 	addr.sin_addr.s_addr = INADDR_ANY; | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | 		shutdown_socket_system(); | 
					
						
							| 
									
										
										
										
											2012-10-21 14:02:30 +00:00
										 |  |  | 		BKE_report(reports, RPT_ERROR, "Cannot bind to socket"); | 
					
						
							| 
									
										
										
										
											2009-12-22 12:01:32 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-22 12:01:32 +00:00
										 |  |  | 	if (listen(sock, SOMAXCONN) < 0) { | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | 		shutdown_socket_system(); | 
					
						
							| 
									
										
										
										
											2012-10-21 14:02:30 +00:00
										 |  |  | 		BKE_report(reports, RPT_ERROR, "Cannot establish listen backlog"); | 
					
						
							| 
									
										
										
										
											2009-12-22 12:01:32 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 	connsock = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	render_width = rectx; | 
					
						
							|  |  |  | 	render_height = recty; | 
					
						
							| 
									
										
										
										
											2009-12-22 12:01:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-28 17:01:46 +00:00
										 |  |  | static char index_page[] = | 
					
						
							|  |  |  | "HTTP/1.1 200 OK\r\n" | 
					
						
							|  |  |  | "Content-Type: text/html\r\n" | 
					
						
							|  |  |  | "\r\n" | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | "<html><head><title>Blender Frameserver</title></head>\n" | 
					
						
							|  |  |  | "<body><pre>\n" | 
					
						
							|  |  |  | "<H2>Blender Frameserver</H2>\n" | 
					
						
							|  |  |  | "<A HREF=info.txt>Render Info</A><br>\n" | 
					
						
							|  |  |  | "<A HREF=close.txt>Stop Rendering</A><br>\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "Images can be found here\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "images/ppm/%d.ppm\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "</pre></body></html>\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-28 17:01:46 +00:00
										 |  |  | static char good_bye[] = | 
					
						
							|  |  |  | "HTTP/1.1 200 OK\r\n" | 
					
						
							|  |  |  | "Content-Type: text/html\r\n" | 
					
						
							|  |  |  | "\r\n" | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | "<html><head><title>Blender Frameserver</title></head>\n" | 
					
						
							|  |  |  | "<body><pre>\n" | 
					
						
							|  |  |  | "Render stopped. Goodbye</pre></body></html>"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  | static int safe_write(char *s, int tosend) | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int total = tosend; | 
					
						
							|  |  |  | 	do { | 
					
						
							|  |  |  | 		int got = send(connsock, s, tosend, 0); | 
					
						
							|  |  |  | 		if (got < 0) { | 
					
						
							|  |  |  | 			return got; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		tosend -= got; | 
					
						
							|  |  |  | 		s += got; | 
					
						
							|  |  |  | 	} while (tosend > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return total; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  | static int safe_puts(char *s) | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return safe_write(s, strlen(s)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  | static int handle_request(RenderData *rd, char *req) | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  | 	char *p; | 
					
						
							|  |  |  | 	char *path; | 
					
						
							| 
									
										
										
										
											2006-03-07 20:01:12 +00:00
										 |  |  | 	int pathlen; | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (memcmp(req, "GET ", 4) != 0) { | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	    | 
					
						
							|  |  |  | 	p = req + 4; | 
					
						
							|  |  |  | 	path = p; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (*p != ' ' && *p) p++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*p = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-21 15:11:03 +00:00
										 |  |  | 	if (strcmp(path, "/index.html") == 0 || strcmp(path, "/") == 0) { | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 		safe_puts(index_page); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	write_ppm = 0; | 
					
						
							| 
									
										
										
										
											2006-03-07 20:01:12 +00:00
										 |  |  | 	pathlen = strlen(path); | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-07 20:01:12 +00:00
										 |  |  | 	if (pathlen > 12 && memcmp(path, "/images/ppm/", 12) == 0) { | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 		write_ppm = 1; | 
					
						
							|  |  |  | 		return atoi(path + 12); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (strcmp(path, "/info.txt") == 0) { | 
					
						
							|  |  |  | 		char buf[4096]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-28 17:01:46 +00:00
										 |  |  | 		sprintf(buf, | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  | 		        "HTTP/1.1 200 OK\r\n" | 
					
						
							|  |  |  | 		        "Content-Type: text/html\r\n" | 
					
						
							|  |  |  | 		        "\r\n" | 
					
						
							|  |  |  | 		        "start %d\n" | 
					
						
							|  |  |  | 		        "end %d\n" | 
					
						
							|  |  |  | 		        "width %d\n" | 
					
						
							|  |  |  | 		        "height %d\n" | 
					
						
							|  |  |  | 		        "rate %d\n" | 
					
						
							|  |  |  | 		        "ratescale %d\n", | 
					
						
							|  |  |  | 		        rd->sfra, | 
					
						
							|  |  |  | 		        rd->efra, | 
					
						
							|  |  |  | 		        render_width, | 
					
						
							|  |  |  | 		        render_height, | 
					
						
							|  |  |  | 		        rd->frs_sec, | 
					
						
							|  |  |  | 		        1 | 
					
						
							|  |  |  | 		        ); | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		safe_puts(buf); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (strcmp(path, "/close.txt") == 0) { | 
					
						
							|  |  |  | 		safe_puts(good_bye); | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  | 		G.is_break = true;  /* Abort render */ | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-07 09:30:15 +00:00
										 |  |  | int BKE_frameserver_loop(RenderData *rd, ReportList *UNUSED(reports)) | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	fd_set readfds; | 
					
						
							|  |  |  | 	struct timeval tv; | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  | 	struct sockaddr_in addr; | 
					
						
							| 
									
										
										
										
											2006-10-26 23:34:44 +00:00
										 |  |  | 	int len, rval; | 
					
						
							| 
									
										
										
										
											2011-09-27 01:32:27 +00:00
										 |  |  | #ifdef FREE_WINDOWS
 | 
					
						
							|  |  |  | 	int socklen; | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2006-10-26 23:34:44 +00:00
										 |  |  | 	unsigned int socklen; | 
					
						
							| 
									
										
										
										
											2011-09-27 01:32:27 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 	char buf[4096]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (connsock != -1) { | 
					
						
							|  |  |  | 		closesocket(connsock); | 
					
						
							|  |  |  | 		connsock = -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tv.tv_sec = 1; | 
					
						
							|  |  |  | 	tv.tv_usec = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	FD_ZERO(&readfds); | 
					
						
							|  |  |  | 	FD_SET(sock, &readfds); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rval = select(sock + 1, &readfds, NULL, NULL, &tv); | 
					
						
							|  |  |  | 	if (rval < 0) { | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (rval == 0) { /* nothing to be done */ | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-26 23:34:44 +00:00
										 |  |  | 	socklen = sizeof(addr); | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-26 23:34:44 +00:00
										 |  |  | 	if ((connsock = accept(sock, (struct sockaddr *)&addr, &socklen)) < 0) { | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	FD_ZERO(&readfds); | 
					
						
							|  |  |  | 	FD_SET(connsock, &readfds); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		/* give 10 seconds for telnet testing... */ | 
					
						
							|  |  |  | 		tv.tv_sec = 10; | 
					
						
							|  |  |  | 		tv.tv_usec = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  | 		rval = select(connsock + 1, &readfds, NULL, NULL, &tv); | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 		if (rval > 0) { | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (rval == 0) { | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (rval < 0) { | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | 			if (!select_was_interrupted_by_signal()) { | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-12 13:16:30 +00:00
										 |  |  | 	len = recv(connsock, buf, sizeof(buf) - 1, 0); | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (len < 0) { | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	buf[len] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-04 14:14:06 +00:00
										 |  |  | 	return handle_request(rd, buf); | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void serve_ppm(int *pixels, int rectx, int recty) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  | 	unsigned char *rendered_frame; | 
					
						
							|  |  |  | 	unsigned char *row = (unsigned char *) malloc(render_width * 3); | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 	int y; | 
					
						
							|  |  |  | 	char header[1024]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-28 17:01:46 +00:00
										 |  |  | 	sprintf(header, | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  | 	        "HTTP/1.1 200 OK\r\n" | 
					
						
							|  |  |  | 	        "Content-Type: image/ppm\r\n" | 
					
						
							|  |  |  | 	        "Connection: close\r\n" | 
					
						
							|  |  |  | 	        "\r\n" | 
					
						
							|  |  |  | 	        "P6\n" | 
					
						
							|  |  |  | 	        "# Creator: blender frameserver v0.0.1\n" | 
					
						
							|  |  |  | 	        "%d %d\n" | 
					
						
							|  |  |  | 	        "255\n", | 
					
						
							|  |  |  | 	        rectx, recty); | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	safe_puts(header); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-14 11:46:45 +00:00
										 |  |  | 	rendered_frame = (unsigned char *)pixels; | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (y = recty - 1; y >= 0; y--) { | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  | 		unsigned char *target = row; | 
					
						
							|  |  |  | 		unsigned char *src = rendered_frame + rectx * 4 * y; | 
					
						
							|  |  |  | 		unsigned char *end = src + rectx * 4; | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 		while (src != end) { | 
					
						
							|  |  |  | 			target[2] = src[2]; | 
					
						
							|  |  |  | 			target[1] = src[1]; | 
					
						
							|  |  |  | 			target[0] = src[0]; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			target += 3; | 
					
						
							|  |  |  | 			src += 4; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  | 		safe_write((char *)row, 3 * rectx); | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	free(row); | 
					
						
							|  |  |  | 	closesocket(connsock); | 
					
						
							|  |  |  | 	connsock = -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-07 09:30:15 +00:00
										 |  |  | int BKE_frameserver_append(RenderData *UNUSED(rd), int UNUSED(start_frame), int frame, int *pixels, | 
					
						
							| 
									
										
										
										
											2012-07-29 00:20:28 +00:00
										 |  |  |                            int rectx, int recty, ReportList *UNUSED(reports)) | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	fprintf(stderr, "Serving frame: %d\n", frame); | 
					
						
							|  |  |  | 	if (write_ppm) { | 
					
						
							|  |  |  | 		serve_ppm(pixels, rectx, recty); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (connsock != -1) { | 
					
						
							|  |  |  | 		closesocket(connsock); | 
					
						
							|  |  |  | 		connsock = -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-12-22 12:01:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-11 21:42:06 +00:00
										 |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-07 09:30:15 +00:00
										 |  |  | void BKE_frameserver_end(void) | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (connsock != -1) { | 
					
						
							|  |  |  | 		closesocket(connsock); | 
					
						
							|  |  |  | 		connsock = -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	closesocket(sock); | 
					
						
							| 
									
										
										
										
											2006-07-14 13:32:29 +00:00
										 |  |  | 	shutdown_socket_system(); | 
					
						
							| 
									
										
										
										
											2006-02-05 19:12:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-21 23:06:51 +00:00
										 |  |  | #endif /* WITH_FRAMESERVER */
 |