Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Schlaile <peter@schlaile.de>2006-02-05 22:39:12 +0300
committerPeter Schlaile <peter@schlaile.de>2006-02-05 22:39:12 +0300
commit4e97a43d56815de982448fc6fb2cf1cc53ec9968 (patch)
tree0fc0d3707ecf57a9cc2b6c3a809445282104927c /release/windows
parent680756393a7be40706826bbbd580269a2a71cc4a (diff)
Adds a VFAPI-Plugin for TMPGenc to connect to the blender frameserver.
Diffstat (limited to 'release/windows')
-rw-r--r--release/windows/contrib/vfapi/README26
-rw-r--r--release/windows/contrib/vfapi/vfapi-plugin.c418
2 files changed, 444 insertions, 0 deletions
diff --git a/release/windows/contrib/vfapi/README b/release/windows/contrib/vfapi/README
new file mode 100644
index 00000000000..f4081bfe02a
--- /dev/null
+++ b/release/windows/contrib/vfapi/README
@@ -0,0 +1,26 @@
+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...
diff --git a/release/windows/contrib/vfapi/vfapi-plugin.c b/release/windows/contrib/vfapi/vfapi-plugin.c
new file mode 100644
index 00000000000..c54f8234d2d
--- /dev/null
+++ b/release/windows/contrib/vfapi/vfapi-plugin.c
@@ -0,0 +1,418 @@
+/*
+ * 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;
+}
+
+
+