Author: eudoxos
Date: 2009-07-29 11:17:45 +0200 (Wed, 29 Jul 2009)
New Revision: 1901

Modified:
   trunk/SConstruct
   trunk/gui/qt3/GLViewer.cpp
   trunk/gui/qt3/GLViewer.hpp
   trunk/gui/qt3/SnapshotEngine.cpp
   trunk/gui/qt3/qt.py
   trunk/py/utils.py
Log:
1. Add GLViewer::nextFrameSnapshotFilename to save frame in postDraw
2. Adjust SnapshotEngine to take advantage of that. This should solve 
https://bugs.launchpad.net/yade/+bug/396023
3. utils.encodeVideoFromFrames can take list of files (instead of just 
wildcard). Backwards-compatible.
4. scons doc skips debian/ directory (would mess up if deb package was build)



Modified: trunk/SConstruct
===================================================================
--- trunk/SConstruct    2009-07-29 08:23:29 UTC (rev 1900)
+++ trunk/SConstruct    2009-07-29 09:17:45 UTC (rev 1901)
@@ -210,7 +210,7 @@
                else: print "Nothing to clean: %s."%buildDir
                sys.argv.remove('clean')
        if 'tags' in sys.argv:
-               cmd="ctags -R --extra=+q --fields=+n --exclude='.*' 
--exclude=doc --exclude=scons-local --exclude=include --exclude='*.so' 
--langmap=c++:+.inl,c++:+.tpp,c++:+.ipp"
+               cmd="ctags -R --extra=+q --fields=+n --exclude='.*' 
--exclude=doc --exclude=scons-local --exclude=include --exclude=debian 
--exclude='*.so' --langmap=c++:+.inl,c++:+.tpp,c++:+.ipp"
                print cmd; os.system(cmd)
                sys.argv.remove('tags')
        if 'doc' in sys.argv:

Modified: trunk/gui/qt3/GLViewer.cpp
===================================================================
--- trunk/gui/qt3/GLViewer.cpp  2009-07-29 08:23:29 UTC (rev 1900)
+++ trunk/gui/qt3/GLViewer.cpp  2009-07-29 09:17:45 UTC (rev 1901)
@@ -606,6 +606,12 @@
                }
        }
        QGLViewer::postDraw();
+       if(!nextFrameSnapshotFilename.empty()){
+               // save the snapshot
+               saveSnapshot(QString(nextFrameSnapshotFilename),/*overwrite*/ 
true);
+               // notify the caller that it is done already (probably not an 
atomic op :-|, though)
+               nextFrameSnapshotFilename.clear();
+       }
 }
 
 string GLViewer::getRealTimeString(){

Modified: trunk/gui/qt3/GLViewer.hpp
===================================================================
--- trunk/gui/qt3/GLViewer.hpp  2009-07-29 08:23:29 UTC (rev 1900)
+++ trunk/gui/qt3/GLViewer.hpp  2009-07-29 09:17:45 UTC (rev 1901)
@@ -89,6 +89,10 @@
                void initFromDOMElement(const QDomElement& element);
                int viewId;
 
+               // if defined, snapshot will be saved to this file right after 
being drawn and the string will be reset.
+               // this way the caller will be notified of the frame being 
saved successfully.
+               string nextFrameSnapshotFilename;
+
                boost::posix_time::ptime getLastUserEvent();
 
 

Modified: trunk/gui/qt3/SnapshotEngine.cpp
===================================================================
--- trunk/gui/qt3/SnapshotEngine.cpp    2009-07-29 08:23:29 UTC (rev 1900)
+++ trunk/gui/qt3/SnapshotEngine.cpp    2009-07-29 09:17:45 UTC (rev 1901)
@@ -12,7 +12,14 @@
        ostringstream fss; 
fss<<fileBase<<setw(4)<<setfill('0')<<counter++<<".png";
        LOG_DEBUG("GL view #"<<viewNo<<" → "<<fss.str())
        glv->setSnapshotFormat("PNG");
-       glv->saveSnapshot(QString(fss.str()),/*overwrite*/ true);
+       glv->nextFrameSnapshotFilename=fss.str();
+       // wait for the renderer to save the frame (will happen at next 
postDraw)
+       timespec t1,t2; t1.tv_sec=0; t1.tv_nsec=10000000; /* 10 ms */
+       long waiting=0;
+       while(!glv->nextFrameSnapshotFilename.empty()){
+               nanosleep(&t1,&t2);
+               if(((++waiting) % 1000)==0) LOG_WARN("Already waiting 
"<<waiting/100<<"s for snapshot to be saved. Something went wrong?");
+       }
        savedSnapshots.push_back(fss.str());
        usleep((long)(msecSleep*1000));
 }

Modified: trunk/gui/qt3/qt.py
===================================================================
--- trunk/gui/qt3/qt.py 2009-07-29 08:23:29 UTC (rev 1900)
+++ trunk/gui/qt3/qt.py 2009-07-29 09:17:45 UTC (rev 1901)
@@ -22,6 +22,7 @@
        See makePlayerVideo for more documentation.
        """
        import os
+       from yade import utils
        # create primary view if none
        if len(views())==0: View()
        # remove existing SnaphotEngines

Modified: trunk/py/utils.py
===================================================================
--- trunk/py/utils.py   2009-07-29 08:23:29 UTC (rev 1900)
+++ trunk/py/utils.py   2009-07-29 09:17:45 UTC (rev 1901)
@@ -331,14 +331,29 @@
                o.bodies[i].shape['diffuseColor']=color
        return imported
 
-def encodeVideoFromFrames(wildcard,out,renameNotOverwrite=True,fps=24):
-       import pygst,sys,gobject,os
+def encodeVideoFromFrames(frameSpec,out,renameNotOverwrite=True,fps=24):
+       """Create .ogg video from external image files.
+       
+       @param frameSpec If string, wildcard in format understood by 
GStreamer's multifilesrc plugin (e.g. '/tmp/frame-%04d.png'). If list or tuple, 
filenames to be encoded in given order.
+       @param out file to save video into
+       @param renameNotOverwrite if True, existing same-named video file will 
have ~[number] appended; will be overwritten otherwise.
+       @param fps Frames per second.
+       """
+       import pygst,sys,gobject,os,tempfile,shutil
        pygst.require("0.10")
        import gst
        if renameNotOverwrite and os.path.exists(out):
                i=0;
                while(os.path.exists(out+"~%d"%i)): i+=1
                os.rename(out,out+"~%d"%i); print "Output file `%s' already 
existed, old file renamed to `%s'"%(out,out+"~%d"%i)
+       if frameSpec.__class__==list or frameSpec.__class__==tuple:
+               # create a new common prefix, symlink given files to 
prefix-%05d.png in their order, adjust wildcard, go ahead.
+               tmpDir=tempfile.mkdtemp()
+               for no,frame in enumerate(frameSpec):
+                       os.symlink(frame,os.path.join(tmpDir,'%07d'%no))
+               wildcard=os.path.join(tmpDir,'%07d')
+       else:
+               tmpDir=None; wildcard=frameSpec
        print "Encoding video from %s to %s"%(wildcard,out)
        pipeline=gst.parse_launch('multifilesrc location="%s" index=0 
caps="image/png,framerate=\(fraction\)%d/1" ! pngdec ! ffmpegcolorspace ! 
theoraenc sharpness=2 quality=63 ! oggmux ! filesink 
location="%s"'%(wildcard,fps,out))
        bus=pipeline.get_bus()
@@ -348,7 +363,10 @@
        pipeline.set_state(gst.STATE_PLAYING)
        mainloop.run()
        pipeline.set_state(gst.STATE_NULL); pipeline.get_state()
+       # remove symlinked frames, if any
+       if tmpDir: shutil.rmtree(tmpDir)
 
+
 def 
readParamsFromTable(tableFileLine=None,noTableOk=False,unknownOk=False,**kw):
        """
        Read parameters from a file and assign them to __builtin__ variables.


_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~yade-dev
More help   : https://help.launchpad.net/ListHelp
_______________________________________________
yade-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/yade-dev

Reply via email to