Changeset 3559 for trunk/packages/vizservers/nanovis/FlowCmd.cpp
- Timestamp:
- Mar 22, 2013, 7:45:30 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/packages/vizservers/nanovis/FlowCmd.cpp
r3502 r3559 5 5 */ 6 6 #include <assert.h> 7 #define _OPEN_SYS 8 #include <fcntl.h> 9 #define _XOPEN_SOURCE_EXTENDED 1 10 #include <sys/uio.h> 11 #include <sys/stat.h> 7 12 #include <stdlib.h> 8 13 #include <stddef.h> 9 14 #include <limits.h> 10 15 #include <stdint.h> 16 #include <unistd.h> 11 17 #include <poll.h> 12 13 18 #include <tcl.h> 14 19 … … 23 28 24 29 #include "nvconf.h" 25 26 #if defined(HAVE_LIBAVCODEC) || defined(HAVE_LIBAVFORMAT)27 #define HAVE_FFMPEG 128 #endif29 30 #ifdef HAVE_FFMPEG31 #include "RpAVTranslate.h"32 #endif33 30 34 31 #include "nanovis.h" … … 163 160 FlowParticles::render() 164 161 { 165 TRACE("rendering particles %s", _name);166 TRACE("rendering particles %s axis=%d", _name, _sv.position.axis);167 TRACE("rendering particles %s position=%g", _name, _sv.position.value);168 TRACE("rendering particles %s position=%g", _name,169 FlowCmd::GetRelativePosition(&_sv.position));170 171 162 _rendererPtr->setPos(FlowCmd::GetRelativePosition(&_sv.position)); 172 163 _rendererPtr->setAxis(_sv.position.axis); … … 243 234 } 244 235 245 TRACE("Box model bounds: (%g,%g,%g) - (%g,%g,%g)", x0, y0, z0, x1, y1, z1);246 247 236 Vector3f modelMin(x0, y0, z0); 248 237 Vector3f modelMax(x1, y1, z1); … … 267 256 if (worldVert.z > bboxMax.z) bboxMax.z = worldVert.z; 268 257 } 269 270 TRACE("Box world bounds: (%g,%g,%g) - (%g,%g,%g)",271 bboxMin.x, bboxMin.y, bboxMin.z,272 bboxMax.x, bboxMax.y, bboxMax.z);273 258 } 274 259 … … 276 261 FlowBox::Render(Volume *vol) 277 262 { 278 TRACE("Rendering box %s", _name);279 280 263 glPushAttrib(GL_ENABLE_BIT); 281 264 … … 301 284 max.z = vol->zAxis.max(); 302 285 303 TRACE("box is %g,%g %g,%g %g,%g",304 _sv.corner1.x, _sv.corner2.x,305 _sv.corner1.y, _sv.corner2.y,306 _sv.corner1.z, _sv.corner2.z);307 TRACE("world is %g,%g %g,%g %g,%g",308 min.x, max.x, min.y, max.y, min.z, max.z);309 310 286 float x0, y0, z0, x1, y1, z1; 311 287 x0 = y0 = z0 = 0.0f; … … 323 299 z1 = (_sv.corner2.z - min.z) / (max.z - min.z); 324 300 } 325 TRACE("rendering box %g,%g %g,%g %g,%g", x0, x1, y0, y1, z0, z1);326 327 301 glColor4d(_sv.color.r, _sv.color.g, _sv.color.b, _sv.color.a); 328 302 glLineWidth(_sv.lineWidth); … … 462 436 } 463 437 } 464 TRACE("in Render before boxes %s", _name);465 438 RenderBoxes(); 466 439 } … … 612 585 { 613 586 if (_volPtr != NULL) { 614 TRACE("from ScaleVectorField volId=%s", _volPtr->name());615 587 NanoVis::removeVolume(_volPtr); 616 588 _volPtr = NULL; … … 694 666 FlowBox *boxPtr; 695 667 for (boxPtr = FirstBox(&iter); boxPtr != NULL; boxPtr = NextBox(&iter)) { 696 TRACE("found box %s", boxPtr->name());697 668 if (boxPtr->visible()) { 698 669 boxPtr->Render(_volPtr); … … 748 719 volPtr->zAxis.setRange(_dataPtr->zMin(), _dataPtr->zMax()); 749 720 750 TRACE("min=%g %g %g max=%g %g %g mag=%g %g",751 NanoVis::xMin, NanoVis::yMin, NanoVis::zMin,752 NanoVis::xMax, NanoVis::yMax, NanoVis::zMax,753 NanoVis::magMin, NanoVis::magMax);754 755 721 volPtr->disableCutplane(0); 756 722 volPtr->disableCutplane(1); … … 786 752 const char *fileName; 787 753 fileName = Tcl_GetString(objv[3]); 788 TRACE("Flow loading data from file %s", fileName);789 754 790 755 int nComponents; … … 830 795 delete u2dPtr; 831 796 } else { 832 TRACE("header is %.14s", buf.bytes());833 797 if (!dataPtr->importDx(result, nComponents, length, bytes)) { 834 798 Tcl_AppendResult(interp, result.remark(), (char *)NULL); … … 857 821 Rappture::Outcome result; 858 822 859 TRACE("Flow Data Loading");860 861 823 int nBytes; 862 824 if (Tcl_GetIntFromObj(interp, objv[3], &nBytes) != TCL_OK) { … … 882 844 } 883 845 Rappture::Buffer buf; 884 TRACE("Flow Data Loading %d %d", nBytes, nComponents);885 846 if (GetDataStream(interp, buf, nBytes) != TCL_OK) { 886 847 return TCL_ERROR; … … 913 874 delete u2dPtr; 914 875 } else { 915 TRACE("header is %.14s", buf.bytes());916 876 if (!dataPtr->importDx(result, nComponents, length, bytes)) { 917 877 Tcl_AppendResult(interp, result.remark(), (char *)NULL); … … 925 885 return TCL_ERROR; 926 886 } 927 TRACE("nx = %d ny = %d nz = %d", dataPtr->xNum(), dataPtr->yNum(), dataPtr->zNum());928 TRACE("x0 = %lg y0 = %lg z0 = %lg", dataPtr->xMin(), dataPtr->yMin(), dataPtr->zMin());929 TRACE("lx = %lg ly = %lg lz = %lg",930 dataPtr->xMax() - dataPtr->xMin(),931 dataPtr->yMax() - dataPtr->yMin(),932 dataPtr->zMax() - dataPtr->zMin());933 TRACE("dx = %lg dy = %lg dz = %lg",934 dataPtr->xNum() > 1 ? (dataPtr->xMax() - dataPtr->xMin())/(dataPtr->xNum()-1) : 0,935 dataPtr->yNum() > 1 ? (dataPtr->yMax() - dataPtr->yMin())/(dataPtr->yNum()-1) : 0,936 dataPtr->zNum() > 1 ? (dataPtr->zMax() - dataPtr->zMin())/(dataPtr->zNum()-1) : 0);937 TRACE("magMin = %lg magMax = %lg",938 dataPtr->magMin(), dataPtr->magMax());939 887 flowPtr->data(dataPtr); 940 888 { … … 1093 1041 { 1094 1042 flags &= ~MAP_FLOWS; 1095 TRACE("Enter");1096 1043 1097 1044 /* … … 1138 1085 } 1139 1086 1140 TRACE("MapFlows magMin=%g magMax=%g", NanoVis::magMin, NanoVis::magMax);1141 1142 1087 /* 1143 1088 * Step 2. Generate the vector field from each data set. … … 1167 1112 bool onlyVisible) 1168 1113 { 1169 TRACE("Enter");1170 1171 1114 min.set(FLT_MAX, FLT_MAX, FLT_MAX); 1172 1115 max.set(-FLT_MAX, -FLT_MAX, -FLT_MAX); … … 1207 1150 for (box = flow->FirstBox(&iter); box != NULL; 1208 1151 box = flow->NextBox(&iter)) { 1209 TRACE("found box %s", box->name());1210 1152 if (!onlyVisible || box->visible()) { 1211 1153 Vector3f fbmin, fbmax; … … 1954 1896 } 1955 1897 1956 #ifdef HAVE_FFMPEG1957 1958 1898 /** 1959 1899 * \brief Convert a Tcl_Obj representing the video format into its … … 1975 1915 char *record, int offset, int flags) 1976 1916 { 1977 Rappture::AVTranslate::VideoFormats *formatPtr =1978 (Rappture::AVTranslate::VideoFormats *)(record + offset);1917 Tcl_Obj **formatObjPtr = (Tcl_Obj **)(record + offset); 1918 Tcl_Obj *fmtObjPtr; 1979 1919 const char *string; 1980 1920 char c; 1981 1982 string = Tcl_GetString(objPtr); 1921 int length; 1922 1923 string = Tcl_GetStringFromObj(objPtr, &length); 1983 1924 c = string[0]; 1984 if ((c == 'm') && (strcmp(string, "mpeg") == 0)) { 1985 *formatPtr = Rappture::AVTranslate::MPEG1; 1986 } else if ((c == 't') && (strcmp(string, "theora") == 0)) { 1987 *formatPtr = Rappture::AVTranslate::THEORA; 1988 } else if ((c == 'm') && (strcmp(string, "mov") == 0)) { 1989 *formatPtr = Rappture::AVTranslate::QUICKTIME; 1925 if ((c == 'm') && (length > 1) && 1926 (strncmp(string, "mpeg", length) == 0)) { 1927 fmtObjPtr = Tcl_NewStringObj("mpeg1video", 10); 1928 } else if ((c == 't') && (strncmp(string, "theora", length) == 0)) { 1929 fmtObjPtr = Tcl_NewStringObj("theora", 6); 1930 } else if ((c == 'm') && (length > 1) && 1931 (strncmp(string, "mov", length) == 0)) { 1932 fmtObjPtr = Tcl_NewStringObj("mov", 3); 1990 1933 } else { 1991 1934 Tcl_AppendResult(interp, "bad video format \"", string, 1992 1935 "\": should be mpeg, theora, or mov", (char*)NULL); 1993 } 1994 return TCL_ERROR; 1995 } 1996 1997 struct FlowVideoValues { 1936 return TCL_ERROR; 1937 } 1938 if (*formatObjPtr != NULL) { 1939 Tcl_DecrRefCount(*formatObjPtr); 1940 } 1941 Tcl_IncrRefCount(fmtObjPtr); 1942 *formatObjPtr = fmtObjPtr; 1943 return TCL_OK; 1944 } 1945 1946 struct FlowVideoSwitches { 1998 1947 float frameRate; /**< Frame rate */ 1999 1948 int bitRate; /**< Video bitrate */ 2000 1949 int width, height; /**< Dimensions of video frame. */ 2001 int n Frames;2002 Rappture::AVTranslate::VideoFormats format;1950 int numFrames; 1951 Tcl_Obj *formatObjPtr; 2003 1952 }; 2004 1953 … … 2010 1959 Rappture::SwitchSpec FlowCmd::videoSwitches[] = { 2011 1960 {Rappture::SWITCH_INT, "-bitrate", "value", 2012 offsetof(FlowVideo Values, bitRate), 0},1961 offsetof(FlowVideoSwitches, bitRate), 0}, 2013 1962 {Rappture::SWITCH_CUSTOM, "-format", "string", 2014 offsetof(FlowVideo Values, format), 0, 0, &videoFormatSwitch},1963 offsetof(FlowVideoSwitches, formatObjPtr), 0, 0, &videoFormatSwitch}, 2015 1964 {Rappture::SWITCH_FLOAT, "-framerate", "value", 2016 offsetof(FlowVideo Values, frameRate), 0},1965 offsetof(FlowVideoSwitches, frameRate), 0}, 2017 1966 {Rappture::SWITCH_INT, "-height", "integer", 2018 offsetof(FlowVideo Values, height), 0},1967 offsetof(FlowVideoSwitches, height), 0}, 2019 1968 {Rappture::SWITCH_INT, "-numframes", "count", 2020 offsetof(FlowVideo Values, nFrames), 0},1969 offsetof(FlowVideoSwitches, numFrames), 0}, 2021 1970 {Rappture::SWITCH_INT, "-width", "integer", 2022 offsetof(FlowVideo Values, width), 0},1971 offsetof(FlowVideoSwitches, width), 0}, 2023 1972 {Rappture::SWITCH_END} 2024 1973 }; 2025 1974 2026 static int 2027 FlowVideoOp(ClientData clientData, Tcl_Interp *interp, int objc, 2028 Tcl_Obj *const *objv) 1975 #ifdef HAVE_FFMPEG 1976 1977 static int 1978 ppmWriteToFile(Tcl_Interp *interp, const char *path, FlowVideoSwitches *switchesPtr) 1979 { 1980 int f; 1981 1982 /* Open the named file for writing. */ 1983 f = creat(path, 0600); 1984 if (f < 0) { 1985 Tcl_AppendResult(interp, "can't open temporary image file \"", path, 1986 "\": ", Tcl_PosixError(interp), (char *)NULL); 1987 return TCL_ERROR; 1988 } 1989 // Generate the PPM binary file header 1990 char header[200]; 1991 #define PPM_MAXVAL 255 1992 sprintf(header, "P6 %d %d %d\n", switchesPtr->width, switchesPtr->height, 1993 PPM_MAXVAL); 1994 1995 size_t header_length = strlen(header); 1996 size_t wordsPerRow = (switchesPtr->width * 24 + 31) / 32; 1997 size_t bytesPerRow = wordsPerRow * 4; 1998 size_t rowLength = switchesPtr->width * 3; 1999 size_t numRecords = switchesPtr->height + 1; 2000 2001 struct iovec *iov; 2002 iov = (struct iovec *)malloc(sizeof(struct iovec) * numRecords); 2003 2004 // Add the PPM image header. 2005 iov[0].iov_base = header; 2006 iov[0].iov_len = header_length; 2007 2008 // Now add the image data, reversing the order of the rows. 2009 int y; 2010 unsigned char *srcRowPtr = NanoVis::screenBuffer; 2011 /* Reversing the pointers for the image rows. PPM is top-to-bottom. */ 2012 for (y = switchesPtr->height; y >= 1; y--) { 2013 iov[y].iov_base = srcRowPtr; 2014 iov[y].iov_len = rowLength; 2015 srcRowPtr += bytesPerRow; 2016 } 2017 if (writev(f, iov, numRecords) < 0) { 2018 Tcl_AppendResult(interp, "writing image to \"", path, "\" failed: ", 2019 Tcl_PosixError(interp), (char *)NULL); 2020 free(iov); 2021 close(f); 2022 return TCL_ERROR; 2023 } 2024 close(f); 2025 free(iov); 2026 return TCL_OK; 2027 } 2028 2029 static int 2030 MakeImageFiles(Tcl_Interp *interp, char *tmpFileName, 2031 FlowVideoSwitches *switchesPtr, bool *cancelPtr) 2029 2032 { 2030 2033 struct pollfd pollResults; 2031 int timeout;2032 2033 2034 pollResults.fd = fileno(NanoVis::stdin); 2034 2035 pollResults.events = POLLIN; 2035 2036 2036 #define PENDING_TIMEOUT 10 /* milliseconds. */ 2037 timeout = PENDING_TIMEOUT; 2038 2039 FlowVideoValues values; 2040 const char *token; 2041 2042 token = Tcl_GetString(objv[2]); 2043 values.frameRate = 25.0f; // Default frame rate 25 fps 2044 values.bitRate = 6000000; // Default video bit rate. 2045 values.width = NanoVis::winWidth; 2046 values.height = NanoVis::winHeight; 2047 values.nFrames = 100; 2048 values.format = Rappture::AVTranslate::MPEG1; 2049 if (Rappture::ParseSwitches(interp, FlowCmd::videoSwitches, 2050 objc - 3, objv + 3, &values, SWITCH_DEFAULTS) < 0) { 2051 return TCL_ERROR; 2052 } 2053 if ((values.width < 0) || (values.width > SHRT_MAX) || 2054 (values.height < 0) || (values.height > SHRT_MAX)) { 2055 Tcl_AppendResult(interp, "bad dimensions for video", (char *)NULL); 2056 return TCL_ERROR; 2057 } 2058 if ((values.frameRate < 0.0f) || (values.frameRate > 30.0f)) { 2059 Tcl_AppendResult(interp, "bad frame rate.", (char *)NULL); 2060 return TCL_ERROR; 2061 } 2062 if (values.bitRate < 0) { 2063 Tcl_AppendResult(interp, "bad bit rate.", (char *)NULL); 2064 return TCL_ERROR; 2065 } 2066 if (NanoVis::licRenderer == NULL) { 2067 Tcl_AppendResult(interp, "no lic renderer.", (char *)NULL); 2068 return TCL_ERROR; 2069 } 2070 // Save the old dimensions of the offscreen buffer. 2037 int timeout = PENDING_TIMEOUT; 2038 2071 2039 int oldWidth, oldHeight; 2072 2040 oldWidth = NanoVis::winWidth; 2073 2041 oldHeight = NanoVis::winHeight; 2074 2042 2075 TRACE("FLOW started"); 2076 2077 Rappture::Outcome context; 2078 2079 Rappture::AVTranslate movie(values.width, values.height, 2080 values.bitRate, 2081 values.frameRate); 2082 char tmpFileName[200]; 2083 sprintf(tmpFileName,"/tmp/flow%d.mpeg", getpid()); 2084 if (!movie.init(context, tmpFileName)) { 2085 Tcl_AppendResult(interp, "can't initialized movie \"", tmpFileName, 2086 "\": ", context.remark(), (char *)NULL); 2087 return TCL_ERROR; 2088 } 2089 if ((values.width != oldWidth) || (values.height != oldHeight)) { 2043 if ((switchesPtr->width != oldWidth) || 2044 (switchesPtr->height != oldHeight)) { 2090 2045 // Resize to the requested size. 2091 NanoVis::resizeOffscreenBuffer(values.width, values.height); 2092 } 2093 // Now compute the line padding for the offscreen buffer. 2094 int pad = 0; 2095 if (( 3 * values.width) % 4 > 0) { 2096 pad = 4 - ((3* values.width) % 4); 2046 NanoVis::resizeOffscreenBuffer(switchesPtr->width, switchesPtr->height); 2097 2047 } 2098 2048 NanoVis::ResetFlows(); 2099 bool canceled = false; 2100 for (int i = 1; i <= values.nFrames; i++) { 2101 if (((i & 0xF) == 0) && (poll(&pollResults, 1, 0) > 0)) { 2049 *cancelPtr = false; 2050 int result = TCL_OK; 2051 size_t length = strlen(tmpFileName); 2052 for (int i = 1; i <= switchesPtr->numFrames; i++) { 2053 if (((i & 0xF) == 0) && (poll(&pollResults, 1, timeout) > 0)) { 2102 2054 /* If there's another command on stdin, that means the client is 2103 2055 * trying to cancel this operation. */ 2104 canceled= true;2056 *cancelPtr = true; 2105 2057 break; 2106 2058 } … … 2119 2071 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboOrig); 2120 2072 2121 movie.append(context, NanoVis::screenBuffer, pad); 2122 } 2123 movie.done(context); 2124 TRACE("FLOW end"); 2125 if (!canceled) { 2126 Rappture::Buffer data; 2127 2128 /* FIXME: find a way to get the data from the movie object as a 2129 * void* */ 2130 if (!data.load(context, tmpFileName)) { 2131 Tcl_AppendResult(interp, "can't load data from temporary file \"", 2132 tmpFileName, "\": ", context.remark(), (char *)NULL); 2073 sprintf(tmpFileName + length, "/image%d.ppm", i); 2074 result = ppmWriteToFile(interp, tmpFileName, switchesPtr); 2075 if (result != TCL_OK) { 2076 break; 2077 } 2078 } 2079 if ((switchesPtr->width != oldWidth) || 2080 (switchesPtr->height != oldHeight)) { 2081 NanoVis::resizeOffscreenBuffer(oldWidth, oldHeight); 2082 } 2083 tmpFileName[length] = '\0'; 2084 NanoVis::ResetFlows(); 2085 return result; 2086 } 2087 2088 static int 2089 MakeMovie(Tcl_Interp *interp, char *tmpFileName, const char *token, 2090 FlowVideoSwitches *switchesPtr) 2091 { 2092 #ifndef FFMPEG 2093 # define FFMPEG "/usr/bin/ffmpeg" 2094 #endif 2095 /* Generate the movie from the frame images by exec-ing ffmpeg */ 2096 /* The ffmpeg command is 2097 * ffmpeg -f image2 -i /var/tmp/xxxxx/image%d.ppm \ 2098 * -b bitrate -f framerate /var/tmp/xxxxx/movie.mpeg 2099 */ 2100 char cmd[BUFSIZ]; 2101 sprintf(cmd, "%s -f image2 -i %s/image%%d.ppm -f %s -b:v %d -r %f -", 2102 FFMPEG, tmpFileName, Tcl_GetString(switchesPtr->formatObjPtr), 2103 switchesPtr->bitRate, switchesPtr->frameRate); 2104 TRACE("MakeMovie %s", cmd); 2105 FILE *f; 2106 f = popen(cmd, "r"); 2107 if (f == NULL) { 2108 Tcl_AppendResult(interp, "can't run ffmpeg: ", 2109 Tcl_PosixError(interp), (char *)NULL); 2110 return TCL_ERROR; 2111 } 2112 Rappture::Buffer data; 2113 size_t total = 0; 2114 for (;;) { 2115 ssize_t numRead; 2116 char buffer[BUFSIZ]; 2117 2118 numRead = fread(buffer, sizeof(unsigned char), BUFSIZ, f); 2119 total += numRead; 2120 if (numRead == 0) { // EOF 2121 break; 2122 } 2123 if (numRead < 0) { // Error 2124 ERROR("MakeMovie: can't read movie data: %s", 2125 Tcl_PosixError(interp)); 2126 Tcl_AppendResult(interp, "can't read movie data: ", 2127 Tcl_PosixError(interp), (char *)NULL); 2133 2128 return TCL_ERROR; 2134 2129 } 2135 2136 char command[200]; 2137 sprintf(command,"nv>image -type movie -token \"%s\" -bytes %lu\n", 2138 token, (unsigned long)data.size()); 2139 NanoVis::sendDataToClient(command, data.bytes(), data.size()); 2140 } 2141 if ((values.width != oldWidth) || (values.height != oldHeight)) { 2142 NanoVis::resizeOffscreenBuffer(oldWidth, oldHeight); 2143 } 2144 NanoVis::ResetFlows(); 2145 if (unlink(tmpFileName) != 0) { 2146 Tcl_AppendResult(interp, "can't unlink temporary movie file \"", 2147 tmpFileName, "\": ", Tcl_PosixError(interp), (char *)NULL); 2148 return TCL_ERROR; 2149 } 2150 return TCL_OK; 2130 if (!data.append(buffer, numRead)) { 2131 ERROR("MakeMovie: can't append movie data to buffer %d bytes", 2132 numRead); 2133 Tcl_AppendResult(interp, "can't append movie data to buffer", 2134 (char *)NULL); 2135 return TCL_ERROR; 2136 } 2137 } 2138 sprintf(cmd,"nv>image -type movie -token \"%s\" -bytes %lu\n", 2139 token, (unsigned long)data.size()); 2140 NanoVis::sendDataToClient(cmd, data.bytes(), data.size()); 2141 return TCL_OK; 2142 } 2143 2144 static int 2145 FlowVideoOp(ClientData clientData, Tcl_Interp *interp, int objc, 2146 Tcl_Obj *const *objv) 2147 { 2148 FlowVideoSwitches switches; 2149 const char *token; 2150 2151 token = Tcl_GetString(objv[2]); 2152 switches.frameRate = 25.0f; // Default frame rate 25 fps 2153 switches.bitRate = 6000000; // Default video bit rate. 2154 switches.width = NanoVis::winWidth; 2155 switches.height = NanoVis::winHeight; 2156 switches.numFrames = 100; 2157 switches.formatObjPtr = Tcl_NewStringObj("mpeg1video", 10); 2158 Tcl_IncrRefCount(switches.formatObjPtr); 2159 if (Rappture::ParseSwitches(interp, FlowCmd::videoSwitches, 2160 objc - 3, objv + 3, &switches, SWITCH_DEFAULTS) < 0) { 2161 return TCL_ERROR; 2162 } 2163 if ((switches.width < 0) || (switches.width > SHRT_MAX) || 2164 (switches.height < 0) || (switches.height > SHRT_MAX)) { 2165 Tcl_AppendResult(interp, "bad dimensions for video", (char *)NULL); 2166 return TCL_ERROR; 2167 } 2168 if ((switches.frameRate < 0.0f) || (switches.frameRate > 30.0f)) { 2169 Tcl_AppendResult(interp, "bad frame rate.", (char *)NULL); 2170 return TCL_ERROR; 2171 } 2172 if (switches.bitRate < 0) { 2173 Tcl_AppendResult(interp, "bad bit rate.", (char *)NULL); 2174 return TCL_ERROR; 2175 } 2176 if (NanoVis::licRenderer == NULL) { 2177 Tcl_AppendResult(interp, "no lic renderer.", (char *)NULL); 2178 return TCL_ERROR; 2179 } 2180 TRACE("FLOW started"); 2181 2182 char *tmpFileName; 2183 char nameTemplate[200]; 2184 strcpy(nameTemplate,"/var/tmp/flowXXXXXX"); 2185 tmpFileName = mkdtemp(nameTemplate); 2186 int result = TCL_OK; 2187 if (tmpFileName == NULL) { 2188 Tcl_AppendResult(interp, "can't create temporary directory \"", 2189 nameTemplate, "\" for frame image files: ", 2190 Tcl_PosixError(interp), (char *)NULL); 2191 return TCL_ERROR; 2192 } 2193 size_t length = strlen(tmpFileName); 2194 bool canceled = false; 2195 result = MakeImageFiles(interp, tmpFileName, &switches, &canceled); 2196 if ((result == TCL_OK) && (!canceled)) { 2197 result = MakeMovie(interp, tmpFileName, token, &switches); 2198 } 2199 for (int i = 1; i <= switches.numFrames; i++) { 2200 sprintf(tmpFileName + length, "/image%d.ppm", i); 2201 unlink(tmpFileName); 2202 } 2203 tmpFileName[length] = '\0'; 2204 rmdir(tmpFileName); 2205 Rappture::FreeSwitches(FlowCmd::videoSwitches, &switches, 0); 2206 return result; 2151 2207 } 2152 2208 #else
Note: See TracChangeset
for help on using the changeset viewer.