Remove Frame Server

This feature is limited (only byte PPM output, no multi-view),
only works with specific configurations.

This also causes some maintenance overhead
when testing changes to the render pipeline.
This commit is contained in:
Campbell Barton 2018-05-09 12:43:16 +02:00
parent e53cf14280
commit aab5ac25f2
23 changed files with 3 additions and 987 deletions

@ -319,7 +319,6 @@ option(WITH_IMAGE_TIFF "Enable LibTIFF Support" ON)
option(WITH_IMAGE_DDS "Enable DDS Image Support" ON) option(WITH_IMAGE_DDS "Enable DDS Image Support" ON)
option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON) option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON)
option(WITH_IMAGE_HDR "Enable HDR Image Support" ON) option(WITH_IMAGE_HDR "Enable HDR Image Support" ON)
option(WITH_IMAGE_FRAMESERVER "Enable image FrameServer Support for rendering" ON)
# Audio/Video format support # Audio/Video format support
option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON) option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON)

@ -23,7 +23,6 @@ set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE) set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE) set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE) set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_FRAMESERVER ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE) set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE)

@ -28,7 +28,6 @@ set(WITH_IK_SOLVER OFF CACHE BOOL "" FORCE)
set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE) set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON OFF CACHE BOOL "" FORCE) set(WITH_IMAGE_CINEON OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_DDS OFF CACHE BOOL "" FORCE) set(WITH_IMAGE_DDS OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_FRAMESERVER OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_HDR OFF CACHE BOOL "" FORCE) set(WITH_IMAGE_HDR OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENEXR OFF CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENEXR OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENJPEG OFF CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENJPEG OFF CACHE BOOL "" FORCE)

@ -23,7 +23,6 @@ set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE) set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE) set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE) set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_FRAMESERVER ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE) set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE)

@ -442,7 +442,6 @@ class SpellChecker:
"fedge", "fedges", "fedge", "fedges",
"filmic", "filmic",
"fluidsim", "fluidsim",
"frameserver",
"freestyle", "freestyle",
"enum", "enums", "enum", "enums",
"gpencil", "gpencil",

@ -480,7 +480,6 @@ class USERPREF_PT_system(Panel):
col = colsplit.column() col = colsplit.column()
col.label(text="General:") col.label(text="General:")
col.prop(system, "frame_server_port")
col.prop(system, "scrollback", text="Console Scrollback") col.prop(system, "scrollback", text="Console Scrollback")
col.separator() col.separator()

@ -1,26 +0,0 @@
VFAPI-Plugin
This plugin enables TMPGEnc (or other VFAPI-compliant applications)
to directly connect to the blender frameserver. (Well, this was the
intention of the frameserver... ;-)
Use mingw
i586-mingw32msvc-gcc -shared vfapi-plugin.c -o blenderserver.vfp -lwsock32
i586-mingw32msvc-strip blenderserver.vfp
and copy the resulting plugin into your TMPGenc directory.
Usage:
Create a small file that only contains
host:port
where "host" is running blender frameserver on "port"
and call it something.blu
You can open the blu-file in TMPGenc. That's all. The rest is automagic.
By the way: the whole thing is developed completely under linux and
tested successfully with a vanilla wine-0.9.6...

@ -1,421 +0,0 @@
/*
* VFAPI-Plugin
*
* Copyright (c) 2006 Peter Schlaile
*
* 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.
*
* 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.
*
*/
#include <windows.h>
#include <winbase.h>
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
#define VF_STREAM_VIDEO 0x00000001
#define VF_STREAM_AUDIO 0x00000002
#define VF_OK 0x00000000
#define VF_ERROR 0x80004005
typedef struct {
DWORD dwSize;
DWORD dwAPIVersion;
DWORD dwVersion;
DWORD dwSupportStreamType;
char cPluginInfo[256];
char cFileType[256];
} VF_PluginInfo,*LPVF_PluginInfo;
typedef DWORD VF_FileHandle,*LPVF_FileHandle;
typedef struct {
DWORD dwSize;
DWORD dwHasStreams;
} VF_FileInfo,*LPVF_FileInfo;
typedef struct {
DWORD dwSize;
DWORD dwLengthL;
DWORD dwLengthH;
DWORD dwRate;
DWORD dwScale;
DWORD dwWidth;
DWORD dwHeight;
DWORD dwBitCount;
} VF_StreamInfo_Video,*LPVF_StreamInfo_Video;
typedef struct {
DWORD dwSize;
DWORD dwLengthL;
DWORD dwLengthH;
DWORD dwRate;
DWORD dwScale;
DWORD dwChannels;
DWORD dwBitsPerSample;
DWORD dwBlockAlign;
} VF_StreamInfo_Audio,*LPVF_StreamInfo_Audio;
typedef struct {
DWORD dwSize;
DWORD dwFrameNumberL;
DWORD dwFrameNumberH;
void *lpData;
long lPitch;
} VF_ReadData_Video,*LPVF_ReadData_Video;
typedef struct {
DWORD dwSize;
LONGLONG dwSamplePos;
DWORD dwSampleCount;
DWORD dwReadedSampleCount;
DWORD dwBufSize;
void *lpBuf;
} VF_ReadData_Audio,*LPVF_ReadData_Audio;
typedef struct {
DWORD dwSize;
HRESULT (__stdcall *OpenFile)(
char *lpFileName, LPVF_FileHandle lpFileHandle );
HRESULT (__stdcall *CloseFile)( VF_FileHandle hFileHandle );
HRESULT (__stdcall *GetFileInfo)( VF_FileHandle hFileHandle,
LPVF_FileInfo lpFileInfo );
HRESULT (__stdcall *GetStreamInfo)( VF_FileHandle hFileHandle,
DWORD dwStream,void *lpStreamInfo );
HRESULT (__stdcall *ReadData)( VF_FileHandle hFileHandle,
DWORD dwStream,void *lpData );
} VF_PluginFunc,*LPVF_PluginFunc;
__declspec(dllexport) HRESULT vfGetPluginInfo(
LPVF_PluginInfo lpPluginInfo )
{
if (!lpPluginInfo || lpPluginInfo->dwSize != sizeof(VF_PluginInfo)) {
return VF_ERROR;
}
lpPluginInfo->dwAPIVersion = 1;
lpPluginInfo->dwVersion = 1;
lpPluginInfo->dwSupportStreamType = VF_STREAM_VIDEO;
strcpy(lpPluginInfo->cPluginInfo, "Blender Frameserver");
strcpy(lpPluginInfo->cFileType,
"Blender Frame-URL-File (*.blu)|*.blu");
return VF_OK;
}
static unsigned long getipaddress(const char *ipaddr)
{
struct hostent *host;
unsigned long ip;
if (((ip = inet_addr(ipaddr)) == INADDR_NONE) &&
strcmp(ipaddr, "255.255.255.255") != 0)
{
if ((host = gethostbyname(ipaddr)) != NULL) {
memcpy(&ip, host->h_addr, sizeof(ip));
}
}
return (ip);
}
static void my_send(SOCKET sock, char *str)
{
send(sock, str, strlen(str), 0);
}
static int my_recv(SOCKET sock, char *line, int maxlen)
{
int got = 0;
int toget = maxlen;
while (toget > 0) {
got = recv(sock, line, toget, 0);
if (got <= 0) {
return got;
}
toget -= got;
line += got;
}
return maxlen;
}
static int my_gets(SOCKET sock, char *line, int maxlen)
{
int last_rval = 0;
while (((last_rval = my_recv(sock, line, 1)) == 1) && maxlen > 0) {
if (*line == '\n') {
line++;
*line = 0;
break;
}
else {
line++;
maxlen--;
}
}
return last_rval;
}
typedef struct conndesc_ {
struct sockaddr_in addr;
int width;
int height;
int start;
int end;
int rate;
int ratescale;
} conndesc;
HRESULT __stdcall VF_OpenFileFunc_Blen(
char *lpFileName, LPVF_FileHandle lpFileHandle )
{
conndesc * rval;
char * host;
char * p;
int port;
SOCKET s_in;
char buf[256];
struct sockaddr_in addr;
FILE *fp;
p = lpFileName;
while (*p && *p != '.') p++;
if (*p) p++;
if (strcmp(p, "blu") != 0) {
return VF_ERROR;
}
fp = fopen(lpFileName, "r");
if (!fp) {
return VF_ERROR;
}
fgets(buf, 256, fp);
fclose(fp);
host = buf;
p = host;
while (*p && *p != ':') p++;
if (*p) p++;
p[-1] = 0;
port = atoi(p);
if (!port) {
port = 8080;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = getipaddress(host);
s_in = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s_in < 0) {
return VF_ERROR;
}
if (connect(s_in, (struct sockaddr*) &addr,
sizeof(addr)) < 0) {
closesocket(s_in);
return VF_ERROR;
}
rval = (conndesc *) malloc(sizeof(conndesc));
rval->addr = addr;
my_send(s_in, "GET /info.txt HTTP/1.0\n\n");
for (;;) {
char * key;
char * val;
if (my_gets(s_in, buf, 250) <= 0) {
break;
}
key = buf;
val = buf;
while (*val && *val != ' ') val++;
if (*val) {
*val = 0;
val++;
if (strcmp(key, "width") == 0) {
rval->width = atoi(val);
}
else if (strcmp(key, "height") == 0) {
rval->height = atoi(val);
}
else if (strcmp(key, "start") == 0) {
rval->start = atoi(val);
}
else if (strcmp(key, "end") == 0) {
rval->end = atoi(val);
}
else if (strcmp(key, "rate") == 0) {
rval->rate = atoi(val);
}
else if (strcmp(key, "ratescale") == 0) {
rval->ratescale = atoi(val);
}
}
}
closesocket(s_in);
*lpFileHandle = (VF_FileHandle) rval;
return VF_OK;
}
HRESULT __stdcall VF_CloseFileFunc_Blen(
VF_FileHandle hFileHandle )
{
free((conndesc *) hFileHandle);
return VF_OK;
}
HRESULT __stdcall VF_GetFileInfoFunc_Blen(
VF_FileHandle hFileHandle,
LPVF_FileInfo lpFileInfo )
{
conndesc *c = (conndesc *) hFileHandle;
if (c == 0) {
return VF_ERROR;
}
if (lpFileInfo->dwSize != sizeof(VF_FileInfo)) {
return VF_ERROR;
}
lpFileInfo->dwHasStreams = VF_STREAM_VIDEO;
return VF_OK;
}
HRESULT __stdcall VF_GetStreamInfoFunc_Blen(
VF_FileHandle hFileHandle,
DWORD dwStream,void *lpStreamInfo )
{
conndesc * c = (conndesc*) hFileHandle;
LPVF_StreamInfo_Video v = (LPVF_StreamInfo_Video) lpStreamInfo;
if (c == 0 || dwStream != VF_STREAM_VIDEO || v == 0) {
return VF_ERROR;
}
v->dwLengthL = c->end - c->start;
v->dwLengthH = 0;
v->dwScale = c->ratescale;
v->dwRate = c->rate;
v->dwWidth = c->width;
v->dwHeight = c->height;
v->dwBitCount = 24;
return VF_OK;
}
HRESULT __stdcall VF_ReadDataFunc_Blen(
VF_FileHandle hFileHandle,
DWORD dwStream,void *lpData )
{
char req[256];
char buf[256];
SOCKET s_in;
int width;
int height;
int y;
int rval;
unsigned char * framebuf;
conndesc * c = (conndesc*) hFileHandle;
LPVF_ReadData_Video v = (LPVF_ReadData_Video) lpData;
if (c == 0 || dwStream != VF_STREAM_VIDEO || v == 0) {
return VF_ERROR;
}
s_in = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s_in < 0) {
return VF_ERROR;
}
if (connect(s_in, (struct sockaddr*) &c->addr,
sizeof(c->addr)) < 0) {
goto errout;
}
sprintf(req, "GET /images/ppm/%d.ppm HTTP/1.0\n\n",
(int) (v->dwFrameNumberL) + c->start);
my_send(s_in, req);
do {
if (my_gets(s_in, buf, 256) <= 0) {
goto errout;
}
} while (strcmp(buf, "P6\n") != 0);
do {
rval = my_gets(s_in, buf, 256);
} while ( (buf[0] == '#' || buf[0] == '\n') && rval >= 0);
if (sscanf(buf, "%d %d\n", &width, &height) != 2) {
goto errout;
}
if (width != c->width || height != c->height) {
goto errout;
}
my_gets(s_in, buf, 256); /* 255 */
framebuf = (unsigned char *) v->lpData;
for (y = 0; y < height; y++) {
unsigned char *p = framebuf + v->lPitch * y;
unsigned char *e = p + width * 3;
my_recv(s_in, (char *)p, width * 3);
while (p != e) {
unsigned char tmp = p[2];
p[2] = p[0];
p[0] = tmp;
p += 3;
}
}
closesocket(s_in);
return VF_OK;
errout:
closesocket(s_in);
return VF_ERROR;
}
__declspec(dllexport) HRESULT vfGetPluginFunc(
LPVF_PluginFunc lpPluginFunc )
{
if (!lpPluginFunc || lpPluginFunc->dwSize != sizeof(VF_PluginFunc)) {
return VF_ERROR;
}
lpPluginFunc->OpenFile = VF_OpenFileFunc_Blen;
lpPluginFunc->CloseFile = VF_CloseFileFunc_Blen;
lpPluginFunc->GetFileInfo = VF_GetFileInfoFunc_Blen;
lpPluginFunc->GetStreamInfo = VF_GetStreamInfoFunc_Blen;
lpPluginFunc->ReadData = VF_ReadDataFunc_Blen;
return VF_OK;
}

@ -1,59 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* 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.
*
* 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.
*
* 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.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __BKE_WRITEFRAMESERVER_H__
#define __BKE_WRITEFRAMESERVER_H__
/** \file BKE_writeframeserver.h
* \ingroup bke
*/
#ifdef __cplusplus
extern "C" {
#endif
struct RenderData;
struct ReportList;
struct Scene;
int BKE_frameserver_start(
void *context_v, struct Scene *scene, struct RenderData *rd, int rectx, int recty,
struct ReportList *reports, bool preview, const char *suffix);
void BKE_frameserver_end(void *context_v);
int BKE_frameserver_append(
void *context_v, struct RenderData *rd, int start_frame, int frame, int *pixels,
int rectx, int recty, const char *suffix, struct ReportList *reports);
int BKE_frameserver_loop(void *context_v, struct RenderData *rd, struct ReportList *reports);
void *BKE_frameserver_context_create(void);
void BKE_frameserver_context_free(void *context_v);
#ifdef __cplusplus
}
#endif
#endif

@ -202,7 +202,6 @@ set(SRC
intern/workspace.c intern/workspace.c
intern/world.c intern/world.c
intern/writeavi.c intern/writeavi.c
intern/writeframeserver.c
BKE_DerivedMesh.h BKE_DerivedMesh.h
BKE_action.h BKE_action.h
@ -314,7 +313,6 @@ set(SRC
BKE_workspace.h BKE_workspace.h
BKE_world.h BKE_world.h
BKE_writeavi.h BKE_writeavi.h
BKE_writeframeserver.h
nla_private.h nla_private.h
tracking_private.h tracking_private.h

@ -1206,7 +1206,6 @@ bool BKE_imtype_is_movie(const char imtype)
case R_IMF_IMTYPE_H264: case R_IMF_IMTYPE_H264:
case R_IMF_IMTYPE_THEORA: case R_IMF_IMTYPE_THEORA:
case R_IMF_IMTYPE_XVID: case R_IMF_IMTYPE_XVID:
case R_IMF_IMTYPE_FRAMESERVER:
return true; return true;
} }
return false; return false;
@ -1347,7 +1346,6 @@ char BKE_imtype_from_arg(const char *imtype_arg)
else if (STREQ(imtype_arg, "MULTILAYER")) return R_IMF_IMTYPE_MULTILAYER; else if (STREQ(imtype_arg, "MULTILAYER")) return R_IMF_IMTYPE_MULTILAYER;
#endif #endif
else if (STREQ(imtype_arg, "FFMPEG")) return R_IMF_IMTYPE_FFMPEG; else if (STREQ(imtype_arg, "FFMPEG")) return R_IMF_IMTYPE_FFMPEG;
else if (STREQ(imtype_arg, "FRAMESERVER")) return R_IMF_IMTYPE_FRAMESERVER;
#ifdef WITH_CINEON #ifdef WITH_CINEON
else if (STREQ(imtype_arg, "CINEON")) return R_IMF_IMTYPE_CINEON; else if (STREQ(imtype_arg, "CINEON")) return R_IMF_IMTYPE_CINEON;
else if (STREQ(imtype_arg, "DPX")) return R_IMF_IMTYPE_DPX; else if (STREQ(imtype_arg, "DPX")) return R_IMF_IMTYPE_DPX;

@ -84,10 +84,6 @@ static void context_free_avi(void *context_v);
# include "BKE_writeffmpeg.h" # include "BKE_writeffmpeg.h"
#endif #endif
#ifdef WITH_FRAMESERVER
# include "BKE_writeframeserver.h"
#endif
bMovieHandle *BKE_movie_handle_get(const char imtype) bMovieHandle *BKE_movie_handle_get(const char imtype)
{ {
static bMovieHandle mh = {NULL}; static bMovieHandle mh = {NULL};
@ -121,16 +117,6 @@ bMovieHandle *BKE_movie_handle_get(const char imtype)
mh.context_free = BKE_ffmpeg_context_free; mh.context_free = BKE_ffmpeg_context_free;
} }
#endif #endif
#ifdef WITH_FRAMESERVER
if (imtype == R_IMF_IMTYPE_FRAMESERVER) {
mh.start_movie = BKE_frameserver_start;
mh.append_movie = BKE_frameserver_append;
mh.end_movie = BKE_frameserver_end;
mh.get_next_frame = BKE_frameserver_loop;
mh.context_create = BKE_frameserver_context_create;
mh.context_free = BKE_frameserver_context_free;
}
#endif
/* in case all above are disabled */ /* in case all above are disabled */
(void)imtype; (void)imtype;

@ -1,419 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* 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.
*
* 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.
*
* 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 *****
*/
/** \file blender/blenkernel/intern/writeframeserver.c
* \ingroup bke
*
* Frameserver
* Makes Blender accessible from TMPGenc directly using VFAPI (you can
* use firefox too ;-)
*/
#ifdef WITH_FRAMESERVER
#include <string.h>
#include <stdio.h>
#if defined(_WIN32)
#include <winsock2.h>
#include <windows.h>
#include <winbase.h>
#include <direct.h>
#else
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/types.h>
#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"
#include "BLI_utildefines.h"
#include "BKE_writeframeserver.h"
#include "BKE_global.h"
#include "BKE_report.h"
#include "DNA_scene_types.h"
#include "MEM_guardedalloc.h"
typedef struct FrameserverContext {
int sock;
int connsock;
int write_ppm;
int render_width;
int render_height;
} FrameserverContext;
#if defined(_WIN32)
static int startup_socket_system(void)
{
WSADATA wsa;
return (WSAStartup(MAKEWORD(2, 0), &wsa) == 0);
}
static void shutdown_socket_system(void)
{
WSACleanup();
}
static int select_was_interrupted_by_signal(void)
{
return (WSAGetLastError() == WSAEINTR);
}
#else
static int startup_socket_system(void)
{
return 1;
}
static void shutdown_socket_system(void)
{
}
static int select_was_interrupted_by_signal(void)
{
return (errno == EINTR);
}
static int closesocket(int fd)
{
return close(fd);
}
#endif
int BKE_frameserver_start(void *context_v, struct Scene *scene, RenderData *UNUSED(rd), int rectx, int recty, ReportList *reports, bool UNUSED(preview), const char *UNUSED(suffix))
{
struct sockaddr_in addr;
int arg = 1;
FrameserverContext *context = context_v;
(void)scene; /* unused */
if (!startup_socket_system()) {
BKE_report(reports, RPT_ERROR, "Cannot startup socket system");
return 0;
}
if ((context->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
shutdown_socket_system();
BKE_report(reports, RPT_ERROR, "Cannot open socket");
return 0;
}
setsockopt(context->sock, SOL_SOCKET, SO_REUSEADDR, (char *) &arg, sizeof(arg));
addr.sin_family = AF_INET;
addr.sin_port = htons(U.frameserverport);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(context->sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
shutdown_socket_system();
BKE_report(reports, RPT_ERROR, "Cannot bind to socket");
return 0;
}
if (listen(context->sock, SOMAXCONN) < 0) {
shutdown_socket_system();
BKE_report(reports, RPT_ERROR, "Cannot establish listen backlog");
return 0;
}
context->connsock = -1;
context->render_width = rectx;
context->render_height = recty;
return 1;
}
static char index_page[] =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<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";
static char good_bye[] =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<html><head><title>Blender Frameserver</title></head>\n"
"<body><pre>\n"
"Render stopped. Goodbye</pre></body></html>";
static int safe_write(const int connsock, char *s, int tosend)
{
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;
}
static int safe_puts(const int connsock, char *s)
{
return safe_write(connsock, s, strlen(s));
}
static int handle_request(FrameserverContext *context, RenderData *rd, char *req)
{
char *p;
char *path;
int pathlen;
if (memcmp(req, "GET ", 4) != 0) {
return -1;
}
p = req + 4;
path = p;
while (*p != ' ' && *p) p++;
*p = 0;
if (STREQ(path, "/index.html") || STREQ(path, "/")) {
safe_puts(context->connsock, index_page);
return -1;
}
context->write_ppm = 0;
pathlen = strlen(path);
if (pathlen > 12 && memcmp(path, "/images/ppm/", 12) == 0) {
context->write_ppm = 1;
return atoi(path + 12);
}
if (STREQ(path, "/info.txt")) {
char buf[4096];
sprintf(buf,
"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,
context->render_width,
context->render_height,
rd->frs_sec,
1
);
safe_puts(context->connsock, buf);
return -1;
}
if (STREQ(path, "/close.txt")) {
safe_puts(context->connsock, good_bye);
G.is_break = true; /* Abort render */
return -1;
}
return -1;
}
int BKE_frameserver_loop(void *context_v, RenderData *rd, ReportList *UNUSED(reports))
{
fd_set readfds;
struct timeval tv;
struct sockaddr_in addr;
int len, rval;
unsigned int socklen;
char buf[4096];
FrameserverContext *context = context_v;
if (context->connsock != -1) {
closesocket(context->connsock);
context->connsock = -1;
}
tv.tv_sec = 1;
tv.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(context->sock, &readfds);
rval = select(context->sock + 1, &readfds, NULL, NULL, &tv);
if (rval < 0) {
return -1;
}
if (rval == 0) { /* nothing to be done */
return -1;
}
socklen = sizeof(addr);
if ((context->connsock = accept(context->sock, (struct sockaddr *)&addr, &socklen)) < 0) {
return -1;
}
FD_ZERO(&readfds);
FD_SET(context->connsock, &readfds);
for (;;) {
/* give 10 seconds for telnet testing... */
tv.tv_sec = 10;
tv.tv_usec = 0;
rval = select(context->connsock + 1, &readfds, NULL, NULL, &tv);
if (rval > 0) {
break;
}
else if (rval == 0) {
return -1;
}
else if (rval < 0) {
if (!select_was_interrupted_by_signal()) {
return -1;
}
}
}
len = recv(context->connsock, buf, sizeof(buf) - 1, 0);
if (len < 0) {
return -1;
}
buf[len] = 0;
return handle_request(context, rd, buf);
}
static void serve_ppm(FrameserverContext *context, int *pixels, int rectx, int recty)
{
unsigned char *rendered_frame;
unsigned char *row = (unsigned char *) malloc(context->render_width * 3);
int y;
char header[1024];
sprintf(header,
"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);
safe_puts(context->connsock, header);
rendered_frame = (unsigned char *)pixels;
for (y = recty - 1; y >= 0; y--) {
unsigned char *target = row;
unsigned char *src = rendered_frame + rectx * 4 * y;
unsigned char *end = src + rectx * 4;
while (src != end) {
target[2] = src[2];
target[1] = src[1];
target[0] = src[0];
target += 3;
src += 4;
}
safe_write(context->connsock, (char *)row, 3 * rectx);
}
free(row);
closesocket(context->connsock);
context->connsock = -1;
}
int BKE_frameserver_append(void *context_v, RenderData *UNUSED(rd), int UNUSED(start_frame), int frame, int *pixels,
int rectx, int recty, const char *UNUSED(suffix), ReportList *UNUSED(reports))
{
FrameserverContext *context = context_v;
fprintf(stderr, "Serving frame: %d\n", frame);
if (context->write_ppm) {
serve_ppm(context, pixels, rectx, recty);
}
if (context->connsock != -1) {
closesocket(context->connsock);
context->connsock = -1;
}
return 1;
}
void BKE_frameserver_end(void *context_v)
{
FrameserverContext *context = context_v;
if (context->connsock != -1) {
closesocket(context->connsock);
context->connsock = -1;
}
closesocket(context->sock);
shutdown_socket_system();
}
void *BKE_frameserver_context_create(void)
{
FrameserverContext *context = MEM_mallocN(sizeof(FrameserverContext), "Frameserver Context");
return context;
}
void BKE_frameserver_context_free(void *context_v)
{
FrameserverContext *context = context_v;
if (context) {
MEM_freeN(context);
}
}
#endif /* WITH_FRAMESERVER */

@ -2475,9 +2475,6 @@ void init_userdef_do_versions(void)
if (U.memcachelimit <= 0) { if (U.memcachelimit <= 0) {
U.memcachelimit = 32; U.memcachelimit = 32;
} }
if (U.frameserverport == 0) {
U.frameserverport = 8080;
}
if (U.dbl_click_time == 0) { if (U.dbl_click_time == 0) {
U.dbl_click_time = 350; U.dbl_click_time = 350;
} }

@ -432,7 +432,7 @@ typedef struct ImageFormatData {
#define R_IMF_IMTYPE_TIFF 22 #define R_IMF_IMTYPE_TIFF 22
#define R_IMF_IMTYPE_OPENEXR 23 #define R_IMF_IMTYPE_OPENEXR 23
#define R_IMF_IMTYPE_FFMPEG 24 #define R_IMF_IMTYPE_FFMPEG 24
#define R_IMF_IMTYPE_FRAMESERVER 25 /* #define R_IMF_IMTYPE_FRAMESERVER 25 */ /* frame server is nomore */
#define R_IMF_IMTYPE_CINEON 26 #define R_IMF_IMTYPE_CINEON 26
#define R_IMF_IMTYPE_DPX 27 #define R_IMF_IMTYPE_DPX 27
#define R_IMF_IMTYPE_MULTILAYER 28 #define R_IMF_IMTYPE_MULTILAYER 28

@ -527,7 +527,7 @@ typedef struct UserDef {
int memcachelimit; int memcachelimit;
int prefetchframes; int prefetchframes;
float pad_rot_angle; /* control the rotation step of the view when PAD2, PAD4, PAD6&PAD8 is use */ float pad_rot_angle; /* control the rotation step of the view when PAD2, PAD4, PAD6&PAD8 is use */
short frameserverport; short _pad0;
short obcenter_dia; short obcenter_dia;
short rvisize; /* rotating view icon size */ short rvisize; /* rotating view icon size */
short rvibright; /* rotating view icon brightness */ short rvibright; /* rotating view icon brightness */

@ -218,10 +218,6 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR) add_definitions(-DWITH_HDR)
endif() endif()
if(WITH_IMAGE_FRAMESERVER)
add_definitions(-DWITH_FRAMESERVER)
endif()
if(WITH_AUDASPACE) if(WITH_AUDASPACE)
add_definitions(-DWITH_AUDASPACE) add_definitions(-DWITH_AUDASPACE)

@ -289,9 +289,6 @@ const EnumPropertyItem rna_enum_image_type_items[] = {
{0, "", 0, N_("Movie"), NULL}, {0, "", 0, N_("Movie"), NULL},
{R_IMF_IMTYPE_AVIJPEG, "AVI_JPEG", ICON_FILE_MOVIE, "AVI JPEG", "Output video in AVI JPEG format"}, {R_IMF_IMTYPE_AVIJPEG, "AVI_JPEG", ICON_FILE_MOVIE, "AVI JPEG", "Output video in AVI JPEG format"},
{R_IMF_IMTYPE_AVIRAW, "AVI_RAW", ICON_FILE_MOVIE, "AVI Raw", "Output video in AVI Raw format"}, {R_IMF_IMTYPE_AVIRAW, "AVI_RAW", ICON_FILE_MOVIE, "AVI Raw", "Output video in AVI Raw format"},
#ifdef WITH_FRAMESERVER
{R_IMF_IMTYPE_FRAMESERVER, "FRAMESERVER", ICON_FILE_SCRIPT, "Frame Server", "Output image to a frameserver"},
#endif
#ifdef WITH_FFMPEG #ifdef WITH_FFMPEG
{R_IMF_IMTYPE_FFMPEG, "FFMPEG", ICON_FILE_MOVIE, "FFmpeg video", "The most versatile way to output video files"}, {R_IMF_IMTYPE_FFMPEG, "FFMPEG", ICON_FILE_MOVIE, "FFmpeg video", "The most versatile way to output video files"},
#endif #endif

@ -4069,11 +4069,6 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Memory Cache Limit", "Memory cache limit (in megabytes)"); RNA_def_property_ui_text(prop, "Memory Cache Limit", "Memory cache limit (in megabytes)");
RNA_def_property_update(prop, 0, "rna_Userdef_memcache_update"); RNA_def_property_update(prop, 0, "rna_Userdef_memcache_update");
prop = RNA_def_property(srna, "frame_server_port", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "frameserverport");
RNA_def_property_range(prop, 0, 32727);
RNA_def_property_ui_text(prop, "Frame Server Port", "Frameserver Port for Frameserver Rendering");
prop = RNA_def_property(srna, "gl_clip_alpha", PROP_FLOAT, PROP_NONE); prop = RNA_def_property(srna, "gl_clip_alpha", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "glalphaclip"); RNA_def_property_float_sdna(prop, NULL, "glalphaclip");
RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_range(prop, 0.0f, 1.0f);

@ -190,10 +190,6 @@ if(WITH_IMAGE_DDS)
add_definitions(-DWITH_DDS) add_definitions(-DWITH_DDS)
endif() endif()
if(WITH_IMAGE_FRAMESERVER)
add_definitions(-DWITH_FRAMESERVER)
endif()
if(WITH_IMAGE_HDR) if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR) add_definitions(-DWITH_HDR)
endif() endif()

@ -44,7 +44,6 @@ static PyStructSequence_Field app_builtopts_info_fields[] = {
{(char *)"freestyle", NULL}, {(char *)"freestyle", NULL},
{(char *)"image_cineon", NULL}, {(char *)"image_cineon", NULL},
{(char *)"image_dds", NULL}, {(char *)"image_dds", NULL},
{(char *)"image_frameserver", NULL},
{(char *)"image_hdr", NULL}, {(char *)"image_hdr", NULL},
{(char *)"image_openexr", NULL}, {(char *)"image_openexr", NULL},
{(char *)"image_openjpeg", NULL}, {(char *)"image_openjpeg", NULL},
@ -150,12 +149,6 @@ static PyObject *make_builtopts_info(void)
SetObjIncref(Py_False); SetObjIncref(Py_False);
#endif #endif
#ifdef WITH_FRAMESERVER
SetObjIncref(Py_True);
#else
SetObjIncref(Py_False);
#endif
#ifdef WITH_HDR #ifdef WITH_HDR
SetObjIncref(Py_True); SetObjIncref(Py_True);
#else #else

@ -2540,15 +2540,6 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
if (!render_initialize_from_main(re, &rd, bmain, scene, NULL, camera_override, lay_override, 0, 1)) if (!render_initialize_from_main(re, &rd, bmain, scene, NULL, camera_override, lay_override, 0, 1))
return; return;
/* MULTIVIEW_TODO:
* in case a new video format is added that implements get_next_frame multiview has to be addressed
* or the error throwing for R_IMF_IMTYPE_FRAMESERVER has to be extended for those cases as well
*/
if ((rd.im_format.imtype == R_IMF_IMTYPE_FRAMESERVER) && (totvideos > 1)) {
BKE_report(re->reports, RPT_ERROR, "Frame Server only support stereo output for multiview rendering");
return;
}
if (is_movie) { if (is_movie) {
size_t width, height; size_t width, height;
int i; int i;

@ -1220,7 +1220,7 @@ static const char arg_handle_image_type_set_doc[] =
"\tValid options are 'TGA' 'RAWTGA' 'JPEG' 'IRIS' 'IRIZ' 'AVIRAW' 'AVIJPEG' 'PNG' 'BMP'\n" "\tValid options are 'TGA' 'RAWTGA' 'JPEG' 'IRIS' 'IRIZ' 'AVIRAW' 'AVIJPEG' 'PNG' 'BMP'\n"
"\n" "\n"
"\tFormats that can be compiled into Blender, not available on all systems: 'HDR' 'TIFF' 'EXR' 'MULTILAYER'\n" "\tFormats that can be compiled into Blender, not available on all systems: 'HDR' 'TIFF' 'EXR' 'MULTILAYER'\n"
"\t'MPEG' 'FRAMESERVER' 'CINEON' 'DPX' 'DDS' 'JP2'" "\t'MPEG' 'CINEON' 'DPX' 'DDS' 'JP2'"
; ;
static int arg_handle_image_type_set(int argc, const char **argv, void *data) static int arg_handle_image_type_set(int argc, const char **argv, void *data)
{ {