1 // MEncoderCaptureOperation.hxx -- capture video stream into mencoder
3 // Copyright (C) 2009 - 2012 Mathias Froehlich
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #ifndef MEncoderCaptureOperation_HXX
20 #define MEncoderCaptureOperation_HXX
26 #include <osgViewer/ViewerEventHandlers>
28 /// Class to capture into a pipe driven mencoder.
29 /// To integrate this into a viewer:
30 /// MEncoderCaptureOperation* mencoderCaptureOperation = new MEncoderCaptureOperation("/tmp/fgviewer.avi", 60);
31 /// osgViewer::ScreenCaptureHandler* c = new osgViewer::ScreenCaptureHandler(mencoderCaptureOperation, -1);
32 /// viewer.addEventHandler(c);
33 /// c->startCapture();
37 class MEncoderCaptureOperation : public osgViewer::ScreenCaptureHandler::CaptureOperation {
39 MEncoderCaptureOperation(const std::string& fileName = "video.avi", unsigned fps = 30) :
42 _options("-ovc lavc"),
47 virtual ~MEncoderCaptureOperation()
50 const std::string& getFileName() const
52 void setFileName(const std::string& fileName)
53 { _fileName = fileName; }
55 unsigned getFramesPerSecond() const
57 void setFramesPerSecond(unsigned fps)
60 const std::string& getOptions() const
62 void setOptions(const std::string& options)
63 { _options = options; }
65 virtual void operator()(const osg::Image& image, const unsigned int)
67 // Delay any action until we have a valid image
71 // Ensure an open file
73 // If the video was already opened and we got any error,
74 // do not reopen with the same name.
82 // Ensure we did not change dimensions
83 if (image.s() != _width)
85 if (image.t() != _height)
88 // Write upside down flipped image
89 for (int row = _height - 1; 0 <= row; --row) {
90 size_t ret = fwrite(image.data(0, row), 1, image.getRowSizeInBytes(), _file);
91 if (ret != image.getRowSizeInBytes())
101 /// FIXME improve: adapt format to the format we get from the image
102 std::stringstream ss;
103 ss << "mencoder - -demuxer rawvideo -rawvideo fps="
104 << _fps << ":w=" << _width << ":h=" << _height
105 << ":format=rgb24 -o " << _fileName << " " << _options;
107 _file = _popen(ss.str().c_str(), "wb");
109 _file = popen(ss.str().c_str(), "w");
125 /// Externally given:
127 std::string _fileName;
128 std::string _options;
130 /// Internal determined