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
