Ignore:
Timestamp:
Mar 22, 2013, 7:45:30 PM (12 years ago)
Author:
gah
Message:
  • Clean up unused variable warnings.
  • Remove use of ffmpeg libraries from nanovis. This should make it easier to maintain (don't have to keep up with all the backward incompatible changes to the ffmpeg library).
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/packages/vizservers/nanovis/FlowCmd.cpp

    r3502 r3559  
    55 */
    66#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>
    712#include <stdlib.h>
    813#include <stddef.h>
    914#include <limits.h>
    1015#include <stdint.h>
     16#include <unistd.h>
    1117#include <poll.h>
    12 
    1318#include <tcl.h>
    1419
     
    2328
    2429#include "nvconf.h"
    25 
    26 #if defined(HAVE_LIBAVCODEC) || defined(HAVE_LIBAVFORMAT)
    27 #define HAVE_FFMPEG 1
    28 #endif
    29 
    30 #ifdef HAVE_FFMPEG
    31 #include "RpAVTranslate.h"
    32 #endif
    3330
    3431#include "nanovis.h"
     
    163160FlowParticles::render()
    164161{
    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 
    171162    _rendererPtr->setPos(FlowCmd::GetRelativePosition(&_sv.position));
    172163    _rendererPtr->setAxis(_sv.position.axis);
     
    243234    }
    244235
    245     TRACE("Box model bounds: (%g,%g,%g) - (%g,%g,%g)", x0, y0, z0, x1, y1, z1);
    246 
    247236    Vector3f modelMin(x0, y0, z0);
    248237    Vector3f modelMax(x1, y1, z1);
     
    267256        if (worldVert.z > bboxMax.z) bboxMax.z = worldVert.z;
    268257    }
    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);
    273258}
    274259
     
    276261FlowBox::Render(Volume *vol)
    277262{
    278     TRACE("Rendering box %s", _name);
    279 
    280263    glPushAttrib(GL_ENABLE_BIT);
    281264
     
    301284    max.z = vol->zAxis.max();
    302285
    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 
    310286    float x0, y0, z0, x1, y1, z1;
    311287    x0 = y0 = z0 = 0.0f;
     
    323299        z1 = (_sv.corner2.z - min.z) / (max.z - min.z);
    324300    }
    325     TRACE("rendering box %g,%g %g,%g %g,%g", x0, x1, y0, y1, z0, z1);
    326 
    327301    glColor4d(_sv.color.r, _sv.color.g, _sv.color.b, _sv.color.a);
    328302    glLineWidth(_sv.lineWidth);
     
    462436        }
    463437    }
    464     TRACE("in Render before boxes %s", _name);
    465438    RenderBoxes();
    466439}
     
    612585{
    613586    if (_volPtr != NULL) {
    614         TRACE("from ScaleVectorField volId=%s", _volPtr->name());
    615587        NanoVis::removeVolume(_volPtr);
    616588        _volPtr = NULL;
     
    694666    FlowBox *boxPtr;
    695667    for (boxPtr = FirstBox(&iter); boxPtr != NULL; boxPtr = NextBox(&iter)) {
    696         TRACE("found box %s", boxPtr->name());
    697668        if (boxPtr->visible()) {
    698669            boxPtr->Render(_volPtr);
     
    748719    volPtr->zAxis.setRange(_dataPtr->zMin(), _dataPtr->zMax());
    749720
    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 
    755721    volPtr->disableCutplane(0);
    756722    volPtr->disableCutplane(1);
     
    786752    const char *fileName;
    787753    fileName = Tcl_GetString(objv[3]);
    788     TRACE("Flow loading data from file %s", fileName);
    789754
    790755    int nComponents;
     
    830795        delete u2dPtr;
    831796    } else {
    832         TRACE("header is %.14s", buf.bytes());
    833797        if (!dataPtr->importDx(result, nComponents, length, bytes)) {
    834798            Tcl_AppendResult(interp, result.remark(), (char *)NULL);
     
    857821    Rappture::Outcome result;
    858822
    859     TRACE("Flow Data Loading");
    860 
    861823    int nBytes;
    862824    if (Tcl_GetIntFromObj(interp, objv[3], &nBytes) != TCL_OK) {
     
    882844    }
    883845    Rappture::Buffer buf;
    884     TRACE("Flow Data Loading %d %d", nBytes, nComponents);
    885846    if (GetDataStream(interp, buf, nBytes) != TCL_OK) {
    886847        return TCL_ERROR;
     
    913874        delete u2dPtr;
    914875    } else {
    915         TRACE("header is %.14s", buf.bytes());
    916876        if (!dataPtr->importDx(result, nComponents, length, bytes)) {
    917877            Tcl_AppendResult(interp, result.remark(), (char *)NULL);
     
    925885        return TCL_ERROR;
    926886    }
    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());
    939887    flowPtr->data(dataPtr);
    940888    {
     
    10931041{
    10941042    flags &= ~MAP_FLOWS;
    1095     TRACE("Enter");
    10961043
    10971044    /*
     
    11381085    }
    11391086
    1140     TRACE("MapFlows magMin=%g magMax=%g", NanoVis::magMin, NanoVis::magMax);
    1141 
    11421087    /*
    11431088     * Step 2. Generate the vector field from each data set.
     
    11671112                       bool onlyVisible)
    11681113{
    1169     TRACE("Enter");
    1170 
    11711114    min.set(FLT_MAX, FLT_MAX, FLT_MAX);
    11721115    max.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);
     
    12071150        for (box = flow->FirstBox(&iter); box != NULL;
    12081151             box = flow->NextBox(&iter)) {
    1209             TRACE("found box %s", box->name());
    12101152            if (!onlyVisible || box->visible()) {
    12111153                Vector3f fbmin, fbmax;
     
    19541896}
    19551897
    1956 #ifdef HAVE_FFMPEG
    1957 
    19581898/**
    19591899 * \brief Convert a Tcl_Obj representing the video format into its
     
    19751915                      char *record, int offset, int flags)
    19761916{
    1977     Rappture::AVTranslate::VideoFormats *formatPtr =
    1978         (Rappture::AVTranslate::VideoFormats *)(record + offset);
     1917    Tcl_Obj **formatObjPtr = (Tcl_Obj **)(record + offset);
     1918    Tcl_Obj *fmtObjPtr;
    19791919    const char *string;
    19801920    char c;
    1981 
    1982     string = Tcl_GetString(objPtr);
     1921    int length;
     1922
     1923    string = Tcl_GetStringFromObj(objPtr, &length);
    19831924    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);
    19901933    } else {
    19911934        Tcl_AppendResult(interp, "bad video format \"", string,
    19921935                         "\": 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
     1946struct FlowVideoSwitches {
    19981947    float frameRate;         /**< Frame rate */
    19991948    int bitRate;             /**< Video bitrate */
    20001949    int width, height;       /**< Dimensions of video frame. */
    2001     int nFrames;
    2002     Rappture::AVTranslate::VideoFormats format;
     1950    int numFrames;
     1951    Tcl_Obj *formatObjPtr;
    20031952};
    20041953
     
    20101959Rappture::SwitchSpec FlowCmd::videoSwitches[] = {
    20111960    {Rappture::SWITCH_INT, "-bitrate", "value",
    2012      offsetof(FlowVideoValues, bitRate), 0},
     1961     offsetof(FlowVideoSwitches, bitRate), 0},
    20131962    {Rappture::SWITCH_CUSTOM, "-format", "string",
    2014      offsetof(FlowVideoValues, format), 0, 0, &videoFormatSwitch},
     1963     offsetof(FlowVideoSwitches, formatObjPtr), 0, 0, &videoFormatSwitch},
    20151964    {Rappture::SWITCH_FLOAT, "-framerate", "value",
    2016      offsetof(FlowVideoValues, frameRate), 0},
     1965     offsetof(FlowVideoSwitches, frameRate), 0},
    20171966    {Rappture::SWITCH_INT, "-height", "integer",
    2018      offsetof(FlowVideoValues, height), 0},
     1967     offsetof(FlowVideoSwitches, height), 0},
    20191968    {Rappture::SWITCH_INT, "-numframes", "count",
    2020      offsetof(FlowVideoValues, nFrames), 0},
     1969     offsetof(FlowVideoSwitches, numFrames), 0},
    20211970    {Rappture::SWITCH_INT, "-width", "integer",
    2022      offsetof(FlowVideoValues, width), 0},
     1971     offsetof(FlowVideoSwitches, width), 0},
    20231972    {Rappture::SWITCH_END}
    20241973};
    20251974
    2026 static int
    2027 FlowVideoOp(ClientData clientData, Tcl_Interp *interp, int objc,
    2028             Tcl_Obj *const *objv)
     1975#ifdef HAVE_FFMPEG
     1976
     1977static int
     1978ppmWriteToFile(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
     2029static int
     2030MakeImageFiles(Tcl_Interp *interp, char *tmpFileName,
     2031               FlowVideoSwitches *switchesPtr, bool *cancelPtr)
    20292032{
    20302033    struct pollfd pollResults;
    2031     int timeout;
    2032 
    20332034    pollResults.fd = fileno(NanoVis::stdin);
    20342035    pollResults.events = POLLIN;
    2035 
    20362036#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
    20712039    int oldWidth, oldHeight;
    20722040    oldWidth = NanoVis::winWidth;
    20732041    oldHeight = NanoVis::winHeight;
    20742042
    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)) {
    20902045        // 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);
    20972047    }
    20982048    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)) {
    21022054            /* If there's another command on stdin, that means the client is
    21032055             * trying to cancel this operation. */
    2104             canceled = true;
     2056            *cancelPtr = true;
    21052057            break;
    21062058        }
     
    21192071        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboOrig);
    21202072
    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
     2088static int
     2089MakeMovie(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);
    21332128            return TCL_ERROR;
    21342129        }
    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
     2144static int
     2145FlowVideoOp(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;
    21512207}
    21522208#else
Note: See TracChangeset for help on using the changeset viewer.