00001 /*************************************************************************** 00002 * Copyright (C) 2005 by Robot Group Leipzig * 00003 * martius@informatik.uni-leipzig.de * 00004 * fhesse@informatik.uni-leipzig.de * 00005 * der@informatik.uni-leipzig.de * 00006 * * 00007 * This program is free software; you can redistribute it and/or modify * 00008 * it under the terms of the GNU General Public License as published by * 00009 * the Free Software Foundation; either version 2 of the License, or * 00010 * (at your option) any later version. * 00011 * * 00012 * This program is distributed in the hope that it will be useful, * 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00015 * GNU General Public License for more details. * 00016 * * 00017 * You should have received a copy of the GNU General Public License * 00018 * along with this program; if not, write to the * 00019 * Free Software Foundation, Inc., * 00020 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00021 * * 00022 * $Log: grabframe.cpp,v $ 00023 * Revision 1.3.4.1 2006/02/22 15:27:22 martius 00024 * class-ified and osg-ified 00025 * 00026 * Revision 1.3 2005/11/09 13:31:51 martius 00027 * GPL'ised 00028 * 00029 ***************************************************************************/ 00030 #include <assert.h> 00031 #include <string.h> 00032 #include <osgDB/WriteFile> 00033 #include "grabframe.h" 00034 00035 namespace lpzrobots { 00036 00037 // bool getGLFrameBuffer( unsigned char *buf, int w, int h); 00038 00039 void VideoStream::open(const char* _filename){ 00040 assert (_filename); 00041 filename = new char[strlen(_filename) + 1]; 00042 strcpy(filename, _filename); 00043 counter = 0; 00044 opened = true; 00045 } 00046 00047 void VideoStream::close(){ 00048 if(filename) delete[] filename; 00049 filename = 0; 00050 opened = false; 00051 } 00052 00053 bool VideoStream::grabAndWriteFrame(const Producer::Camera& camera){ 00054 if(!opened) return false; 00055 char name[128]; 00056 osg::ref_ptr<osg::Image>image = new osg::Image; 00057 int x, y; 00058 camera.getProjectionRectangle(x, y, w, h); 00059 image->allocateImage( w, h, 1, GL_RGB, GL_UNSIGNED_BYTE); 00060 00061 image->readPixels( 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE); 00062 sprintf(name,"%s_%06ld.bmp", filename, counter); 00063 if(!osgDB::writeImageFile( *(image.get()), name )){ 00064 fprintf(stderr, "VideoStream: Cannot write to file %s\n", name); 00065 return false; 00066 } 00067 counter++; 00068 return true; 00069 } 00070 00071 } 00072 00073 // bool getGLFrameBuffer( unsigned char *buf, int w, int h){ 00074 // if (!buf) 00075 // return false; 00076 // glReadPixels(0,0,w,h,GL_RGB,GL_UNSIGNED_BYTE,(GLvoid*)buf); 00077 // return true; 00078 // } 00079 00080 // > the best way to capture frames within OSG is to use osg::Image. One 00081 // > suggestion is to use a Producer::Camera postDrawCallback. Each frame, 00082 // > then, (to quote a current project): 00083 // > 00084 // > osg::ref_ptr<osg::Image>image = new osg::Image; 00085 // > int x, y; 00086 // > unsigned int w, h; 00087 // > camera.getProjectionRectangle(x,y,w,h); 00088 // > image->allocateImage( w, h, 1, GL_RGB, GL_UNSIGNED_BYTE); 00089 00090 // > image->readPixels( 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE); 00091 // > 00092 // > 00093 // > char filename[128]; 00094 // > sprintf( filename, "ScreenCapture/%04d.bmp", _screenCaptureSequence); 00095 // > osgDB::writeImageFile( *(image.get()), filename ); 00096 // > _screenCaptureSequence++; 00097 00098 00099 00100 // And finally, to create mpegs, (I made mpeg1), you simply 00101 // use the mpeg_encode with this cfg file encode.stats: 00102 00103 // PATTERN ibbpbbpbbpbbpbb 00104 00105 // SLICES_PER_FRAME 1 00106 00107 // OUTPUT nb.mpg 00108 00109 // GOP_SIZE 50 00110 00111 // INPUT_DIR . 00112 00113 00114 // INPUT_CONVERT * 00115 00116 // INPUT 00117 // nb*.ppm [0000-3181] 00118 // END_INPUT 00119 00120 // BASE_FILE_FORMAT PPM 00121 00122 // ERROR MAD 00123 00124 00125 // PIXEL HALF 00126 00127 // # means +/- this many pixels 00128 // RANGE 10 00129 00130 // PSEARCH_ALG EXHAUSTIVE 00131 // BSEARCH_ALG CROSS2 00132 // #IQSCALE 8 00133 // #PQSCALE 10 00134 // #BQSCALE 25 00135 00136 // IQSCALE 26 00137 // PQSCALE 26 00138 // BQSCALE 26 00139 00140 // REFERENCE_FRAME ORIGINAL 00141