summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorComment <tim@gray.(none)>2013-04-15 03:15:33 +0100
committerComment <tim@gray.(none)>2013-04-15 03:15:33 +0100
commit25b336a2b34d7a9bcf9e52a16ae962a1e261ae13 (patch)
treeb5426cdcad9dd90d28650bcc97b7ac42f04b2f44
parent4c99697c528e11a4195b572bf9f72f80c2fe3ea6 (diff)
ofxMovieExporter ideas
-rw-r--r--rotord/ofxMovieExporter.cpp494
-rw-r--r--rotord/ofxMovieExporter.h209
-rwxr-xr-xrotord/renderContext.h0
-rwxr-xr-xrotord/rotor.h5
4 files changed, 707 insertions, 1 deletions
diff --git a/rotord/ofxMovieExporter.cpp b/rotord/ofxMovieExporter.cpp
new file mode 100644
index 0000000..f7c47de
--- /dev/null
+++ b/rotord/ofxMovieExporter.cpp
@@ -0,0 +1,494 @@
+/*
+ * ofxMovieExporter.cpp
+ *
+ * Copyright (c) 2011, Neil Mendoza, http://www.neilmendoza.com
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of 16b.it nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "ofxMovieExporter.h"
+//#include "ofThread.h"
+
+namespace itg
+{
+ const std::string ofxMovieExporter::FILENAME_PREFIX = "capture";
+ const std::string ofxMovieExporter::CONTAINER = "mp4";
+
+ ofxMovieExporter::ofxMovieExporter() {
+ outputFormat = NULL;
+ formatCtx = NULL;
+ videoStream = NULL;
+
+ codec = NULL;
+ codecCtx = NULL;
+ convertCtx = NULL;
+
+ inPixels = NULL;
+ outPixels = NULL;
+ encodedBuf = NULL;
+
+ inFrame = NULL;
+ outFrame = NULL;
+
+ posX = 0;
+ posY = 0;
+ //inW = ofGetWidth();
+ //inH = ofGetHeight();
+ //outW = ofGetWidth();
+ //outH = ofGetHeight();
+
+ bool usePixelSource = false;
+ pixelSource = NULL;
+ }
+
+ void ofxMovieExporter::setup(
+ int outW,
+ int outH,
+ int bitRate,
+ int frameRate,
+ AVCodecID codecId,
+ std::string container)
+ {
+ if (outW % 2 == 1 || outH % 2 == 1) //ofLog(OF_LOG_ERROR, "ofxMovieExporter: Resolution must be a multiple of 2");
+
+ this->outW = outW;
+ this->outH = outH;
+ this->frameRate = frameRate;
+ this->bitRate = bitRate;
+ this->codecId = codecId;
+ this->container = container;
+
+ frameInterval = 1.f / (float)frameRate;
+
+ // HACK HACK HACK
+ // Time not syncing
+ // probably related to codec ticks_per_frame
+ frameInterval /= 3.f;
+ recording = false;
+ numCaptures = 0;
+
+ // do one time encoder set up
+ av_register_all();
+ convertCtx = sws_getContext(inW, inH, PIX_FMT_RGB24, outW, outH, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
+
+ allocateMemory();
+ }
+
+ ofxMovieExporter::~ofxMovieExporter()
+ {
+ if (recording) finishRecord();
+
+ //stopThread(true);
+ clearMemory();
+ }
+
+ void ofxMovieExporter::record(std::string filePrefix, std::string folderPath)
+ {
+ initEncoder();
+
+ std::ostringstream oss;
+ oss << folderPath;
+ if (folderPath != "" && (folderPath[folderPath.size()-1] != '/' && folderPath[folderPath.size()-1] != '\\'))
+ oss << "/";
+ oss << filePrefix << numCaptures << "." << container;
+ outFileName = oss.str();
+
+ // open the output file
+ //if (url_fopen(&formatCtx->pb, outFileName.c_str(), 'wb' ) < 0) //url_fopen URL_WRONLY
+ // ofLog(OF_LOG_ERROR, "ofxMovieExporter: Could not open file %s", outFileName.c_str());
+ if (avio_open(&formatCtx->pb, outFileName.c_str(), AVIO_FLAG_WRITE) < 0) {
+
+ cerr << "ofxMovieExporter: Could not open file "<< outFileName<<endl;
+ }
+
+
+ //ofAddListener(ofEvents.draw, this, &ofxMovieExporter::checkFrame);
+
+ AVDictionary *options; //= NULL; causes a forward declaration error!?
+ options=NULL;
+ // write the stream header, if any
+ avformat_write_header(formatCtx,&options);
+
+ lastFrameTime = 0;
+ frameNum = 0;
+ recording = true;
+//#ifdef _THREAD_CAPTURE
+// startThread(true, false);
+//#endif
+ }
+
+ void ofxMovieExporter::stop()
+ {
+ //ofRemoveListener(ofEvents.draw, this, &ofxMovieExporter::checkFrame);
+ recording = false;
+ numCaptures++;
+//#ifndef _THREAD_CAPTURE
+// finishRecord();
+//#endif
+ }
+
+ void ofxMovieExporter::setRecordingArea(int x, int y, int w, int h)
+ {
+ posX = x;
+ posY = y;
+ inW = w;
+ inH = h;
+ }
+
+ void ofxMovieExporter::setRecordingArea(int rect)
+ {
+ /*
+ posX = rect.x;
+ posY = rect.y;
+ inW = rect.width;
+ inH = rect.height;
+ */
+ }
+
+ void ofxMovieExporter::resetRecordingArea()
+ {
+ posX = 0;
+ posY = 0;
+ //inW = ofGetViewportWidth();
+ //inH = ofGetViewportHeight();
+ }
+
+ int ofxMovieExporter::getRecordingArea()
+ {
+ return 0; //ofRectangle(posX, posY, inW, inH);
+ }
+
+ void ofxMovieExporter::setPixelSource(unsigned char* pixels, int w, int h)
+ {
+ if (isRecording())
+ stop();
+
+ if (pixels == NULL)
+ {
+ //ofLog(OF_LOG_ERROR, "ofxMovieExporter: Could not set NULL pixel source");
+ return;
+ }
+ pixelSource = pixels;
+ inW = w;
+ inH = h;
+ usePixelSource = true;
+
+ // resetup encoder etc
+ setup(outW, outH, bitRate, frameRate, codecId, container);
+ }
+
+ void ofxMovieExporter::resetPixelSource()
+ {
+ usePixelSource = false;
+ pixelSource = NULL;
+ //inW = ofGetViewportWidth();
+ //inH = ofGetViewportHeight();
+
+ // resetup encoder etc
+ setup(outW, outH, bitRate, frameRate, codecId, container);
+ }
+
+ int ofxMovieExporter::getNumCaptures()
+ {
+ return numCaptures;
+ }
+
+ void ofxMovieExporter::resetNumCaptures()
+ {
+ numCaptures = 0;
+ }
+
+// PRIVATE
+
+ void ofxMovieExporter::finishRecord()
+ {
+ av_write_trailer(formatCtx);
+
+ // free the encoder
+ avcodec_close(codecCtx);
+ for(int i = 0; i < formatCtx->nb_streams; i++)
+ {
+ av_freep(&formatCtx->streams[i]->codec);
+ av_freep(&formatCtx->streams[i]);
+ }
+ av_free(formatCtx);
+ formatCtx = NULL;
+ //url_fclose(formatCtx->pb);
+ }
+
+/*
+#ifdef _THREAD_CAPTURE
+ void ofxMovieExporter::threadedFunction()
+ {
+ while (isThreadRunning())
+ {
+ if (!frameQueue.empty())
+ {
+ float start = ofGetElapsedTimef();
+ frameQueueMutex.lock();
+ inPixels = frameQueue.front();
+ frameQueue.pop_front();
+ frameQueueMutex.unlock();
+
+ encodeFrame();
+
+ frameMemMutex.lock();
+ frameMem.push_back(inPixels);
+ frameMemMutex.unlock();
+ if (ofGetElapsedTimef() - start < frameInterval) ofSleepMillis(1000.f * (frameInterval - (ofGetElapsedTimef() - start)));
+ }
+ else if (!recording)
+ {
+ finishRecord();
+ stopThread(true);
+ }
+ }
+ }
+#endif
+*/
+
+ void ofxMovieExporter::checkFrame() //ofEventArgs& args)
+ {
+ if (1) //ofGetElapsedTimef() - lastFrameTime >= frameInterval)
+ {
+/*
+#ifdef _THREAD_CAPTURE
+ unsigned char* pixels;
+ if (!frameMem.empty())
+ {
+ frameMemMutex.lock();
+ pixels = frameMem.back();
+ frameMem.pop_back();
+ frameMemMutex.unlock();
+ }
+ else
+ {
+ pixels = new unsigned char[inW * inH * 3];
+ }
+
+ if (!usePixelSource)
+ {
+ // this part from ofImage::saveScreen
+ int screenHeight = ofGetViewportHeight(); // if we are in a FBO or other viewport, this fails: ofGetHeight();
+ int screenY = screenHeight - posY;
+ screenY -= inH; // top, bottom issues
+
+ glReadPixels(posX, screenY, inW, inH, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+ }
+ else
+ {
+ memcpy(pixels, pixelSource, inW * inH * 3);
+ }
+
+ frameQueueMutex.lock();
+ frameQueue.push_back(pixels);
+ frameQueueMutex.unlock();
+#else
+*/
+ if (!usePixelSource) {
+ // this part from ofImage::saveScreen
+ //int screenHeight = ofGetViewportHeight(); // if we are in a FBO or other viewport, this fails: ofGetHeight();
+ //int screenY = screenHeight - posY;
+ //screenY -= inH; // top, bottom issues
+
+ //glReadPixels(posX, screenY, inW, inH, GL_RGB, GL_UNSIGNED_BYTE, inPixels);
+ }
+ else
+ {
+ memcpy(inPixels, pixelSource, inW * inH * 3);
+ }
+ encodeFrame();
+//#endif
+ //lastFrameTime = ofGetElapsedTimef();
+ }
+ }
+
+ void ofxMovieExporter::encodeFrame()
+ {
+
+ avpicture_fill((AVPicture*)inFrame, inPixels, PIX_FMT_RGB24, inW, inH);
+ avpicture_fill((AVPicture*)outFrame, outPixels, PIX_FMT_YUV420P, outW, outH);
+
+ // intentionally flip the image to compensate for OF flipping if reading from the screen
+ if (!usePixelSource)
+ {
+ inFrame->data[0] += inFrame->linesize[0] * (inH - 1);
+ inFrame->linesize[0] = -inFrame->linesize[0];
+ }
+
+ //perform the conversion for RGB to YUV and size
+ sws_scale(convertCtx, inFrame->data, inFrame->linesize, 0, inH, outFrame->data, outFrame->linesize);
+
+ int outSize = avcodec_encode_video(codecCtx, encodedBuf, ENCODED_FRAME_BUFFER_SIZE, outFrame);
+ if (outSize > 0)
+ {
+ AVPacket pkt;
+ av_init_packet(&pkt);
+ //pkt.pts = av_rescale_q(codecCtx->coded_frame->pts, codecCtx->time_base, videoStream->time_base);
+ //if(codecCtx->coded_frame->key_frame) pkt.flags |= AV_PKT_FLAG_KEY;
+ pkt.pts = frameNum;//ofGetFrameNum();//codecCtx->coded_frame->pts;
+ pkt.flags |= AV_PKT_FLAG_KEY;
+ pkt.dts = pkt.pts;
+ pkt.stream_index = videoStream->index;
+ pkt.data = encodedBuf;
+ pkt.size = outSize;
+ av_write_frame(formatCtx, &pkt);
+ }
+ frameNum++;
+ }
+
+ void ofxMovieExporter::allocateMemory()
+ {
+ // clear if we need to reallocate
+ if(inPixels)
+ clearMemory();
+/*
+ // allocate input stuff
+#ifdef _THREAD_CAPTURE
+ //unsigned char* initFrameMem = new unsigned char[inW * inH * 3 * INIT_QUEUE_SIZE];
+ for (int i = 0; i < INIT_QUEUE_SIZE; i++)
+ {
+ //frameMem.push_back(initFrameMem + inW * inH * 3 * i);
+ frameMem.push_back(new unsigned char[inW * inH * 3]);
+ }
+#else
+*/
+ inPixels = new unsigned char[inW * inH * 3];
+//#endif
+ inFrame = avcodec_alloc_frame();
+
+ // allocate output stuff
+ int outSize = avpicture_get_size(PIX_FMT_YUV420P, outW, outH);
+ outPixels = (unsigned char*)av_malloc(outSize);
+ outFrame = avcodec_alloc_frame();
+
+ encodedBuf = (unsigned char*)av_malloc(ENCODED_FRAME_BUFFER_SIZE);
+ }
+
+ void ofxMovieExporter::clearMemory() {
+/*
+ // clear input stuff
+#ifdef _THREAD_CAPTURE
+ for (int i = 0; i < frameMem.size(); i++)
+ {
+ delete[] frameMem[i];
+ }
+ for (int i = 0; i < frameQueue.size(); i++)
+ {
+ delete[] frameQueue[i];
+ }
+#else
+*/
+ delete[] inPixels;
+//#endif
+
+ inPixels = NULL;
+
+ av_free(inFrame);
+ av_free(outFrame);
+ av_free(encodedBuf);
+ av_free(outPixels);
+
+ inFrame = NULL;
+ outFrame = NULL;
+ encodedBuf = NULL;
+ outPixels = NULL;
+ }
+
+ void ofxMovieExporter::initEncoder()
+ {
+ /////////////////////////////////////////////////////////////
+ // find codec
+ codec = avcodec_find_encoder(codecId);
+ //if (!codec) ofLog(OF_LOG_ERROR, "ofxMovieExporter: Codec not found");
+
+ ////////////////////////////////////////////////////////////
+ // auto detect the output format from the name. default is mpeg.
+ ostringstream oss;
+ oss << "amovie." << container;
+ outputFormat = av_guess_format(NULL, oss.str().c_str(), NULL);
+ //if (!outputFormat) ofLog(OF_LOG_ERROR, "ofxMovieExporter: Could not guess output container for an %s file (ueuur!!)", container.c_str());
+ // set the format codec (the format also has a default codec that can be read from it)
+ outputFormat->video_codec = codec->id;
+
+ /////////////////////////////////////////////////////////////
+ // allocate the format context
+ formatCtx = avformat_alloc_context();
+ //if (!formatCtx) ofLog(OF_LOG_ERROR, "ofxMovieExporter: Could not allocate format context");
+ formatCtx->oformat = outputFormat;
+
+ /////////////////////////////////////////////////////////////
+ // set up the video stream
+ videoStream = av_new_stream(formatCtx, 0);
+
+ /////////////////////////////////////////////////////////////
+ // init codec context
+ codecCtx = videoStream->codec;
+ codecCtx->bit_rate = bitRate;
+ codecCtx->width = outW;
+ codecCtx->height = outH;
+
+ codecCtx->time_base.num = 1;//codecCtx->ticks_per_frame;
+ codecCtx->time_base.den = frameRate;
+ videoStream->time_base = codecCtx->time_base;
+
+
+ codecCtx->gop_size = 10; /* emit one intra frame every ten frames */
+ codecCtx->pix_fmt = PIX_FMT_YUV420P;
+
+ if (codecCtx->codec_id == CODEC_ID_MPEG1VIDEO)
+ {
+ /* needed to avoid using macroblocks in which some coeffs overflow
+ this doesnt happen with normal video, it just happens here as the
+ motion of the chroma plane doesnt match the luma plane */
+ codecCtx->mb_decision=2;
+ }
+ // some formats want stream headers to be seperate
+ if(!strcmp(formatCtx->oformat->name, "mp4") || !strcmp(formatCtx->oformat->name, "mov") || !strcmp(formatCtx->oformat->name, "3gp"))
+ codecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+ // set the output parameters (must be done even if no parameters).
+ //if (
+ //
+ //
+ // ???????
+
+ //av_set_parameters(formatCtx, NULL);
+ //
+ //
+ //
+ //
+
+ // < 0) ofLog(OF_LOG_ERROR, "ofxMovieExproter: Could not set format parameters");
+
+ AVDictionary *options; //= NULL; causes a forward declaration error!?
+ options=NULL;
+ // open codec
+ //if (
+ avcodec_open2(codecCtx, codec,&options);
+ // < 0) ofLog(OF_LOG_ERROR, "ofxMovieExproter: Could not open codec");
+ }
+}
diff --git a/rotord/ofxMovieExporter.h b/rotord/ofxMovieExporter.h
new file mode 100644
index 0000000..ae6b306
--- /dev/null
+++ b/rotord/ofxMovieExporter.h
@@ -0,0 +1,209 @@
+/*
+ * ofxMovieExporter.h
+ *
+ * Copyright (c) 2011, Neil Mendoza, http://www.neilmendoza.com
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of 16b.it nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+//#pragma once
+
+#include <unordered_map>
+#include <deque>
+#include <math.h>
+#include <memory>
+
+#include "Poco/Net/HTTPServer.h"
+#include "Poco/Net/HTTPResponse.h"
+#include "Poco/UUID.h"
+#include "Poco/UUIDGenerator.h"
+#include "Poco/Notification.h"
+#include "Poco/NotificationCenter.h"
+#include "Poco/Observer.h"
+#include "Poco/ThreadPool.h"
+#include "Poco/Thread.h"
+#include "Poco/Task.h"
+#include "Poco/Runnable.h"
+#include "Poco/Mutex.h"
+#include "Poco/Random.h"
+#include "Poco/AutoPtr.h"
+#include "Poco/File.h"
+#include "xmlIO.h"
+//#define _THREAD_CAPTURE
+#include <string>
+#include <iostream>
+/*
+#include "ofMain.h"
+
+// needed for gcc on win
+#ifdef TARGET_WIN32
+ #ifndef INT64_C
+ #define INT64_C(c) (c ## LL)
+ #define UINT64_C(c) (c ## ULL)
+ #endif
+#endif
+*/
+//#define UINT64_C(c) (c ## ULL)
+
+
+extern "C"
+{
+ //needed both
+ #include <libavcodec/avcodec.h>
+ #include <libavformat/avformat.h>
+ #include <libavutil/mathematics.h>
+ //needed ofxMovieExporter
+ #include <libswscale/swscale.h>
+ //rest needed audio loader
+ #include <libavutil/opt.h>
+ #include <libavutil/channel_layout.h>
+ #include <libavutil/common.h>
+ #include <libavutil/imgutils.h>
+
+ #include <libavutil/samplefmt.h>
+
+ #include <libavutil/dict.h>
+ //#include <libavutil/dict.c> stops the compiler error but causes a linker error. does libavcodec need to be statically linked?
+ //#include <libavutil/imgutils.h>
+ //#include <libavutil/samplefmt.h>
+ //#include <libavutil/timestamp.h>
+}
+
+namespace itg
+{
+ class ofxMovieExporter
+//#ifdef _THREAD_CAPTURE
+// : public ofThread
+//#endif
+ {
+ public:
+ static const int ENCODED_FRAME_BUFFER_SIZE = 500000;
+ // defaults
+ static const int BIT_RATE = 4000000;
+ static const int FRAME_RATE = 25;
+ static const int OUT_W = 640;
+ static const int OUT_H = 480;
+ static const int INIT_QUEUE_SIZE = 50;
+ static const AVCodecID CODEC_ID = CODEC_ID_MPEG4;
+ static const std::string FILENAME_PREFIX;
+ static const std::string CONTAINER;
+
+ ofxMovieExporter();
+ ~ofxMovieExporter();
+ // tested so far with...
+ // codecId = CODEC_ID_MPEG4, container = "mp4"
+ // codecId = CODEC_ID_MPEG2VIDEO, container = "mov"
+ void setup(int outW = OUT_W, int outH = OUT_H, int bitRate = BIT_RATE, int frameRate = FRAME_RATE, AVCodecID codecId = CODEC_ID, std::string container = CONTAINER);
+ void record(std::string filePrefix=FILENAME_PREFIX, std::string folderPath="");
+ void stop();
+ bool isRecording() const;
+
+ // set the recording area
+ // x, y is the upper left corner of the recording area, default: 0, 0
+ // w x h is the area size, default: viewport width x height
+ void setRecordingArea(int x, int y, int w, int h);
+ void setRecordingArea(int rect);
+
+ // reset the recording area to the size of the current viewport (screen, FBO, etc)
+ void resetRecordingArea();
+
+ // get the recording area as a rectangle
+ int getRecordingArea();
+
+ // set an external pixel source, assumes 3 Byte RGB
+ // also sets the recording size but does not crop to the recording area
+ void setPixelSource(unsigned char* pixels, int w, int h);
+
+ // reset the pixel source and record from the screen
+ // also resets the recording size to the viewport width
+ void resetPixelSource();
+
+ // get the number files that have been captured so far
+ int getNumCaptures();
+
+ // reset the filename counter back to 0
+ void resetNumCaptures();
+
+ // get the recording size
+ inline int getRecordingWidth() {return outW;}
+ inline int getRecordingHeight() {return outH;}
+
+ private:
+//#ifdef _THREAD_CAPTURE
+// void threadedFunction();
+// deque<unsigned char*> frameQueue;
+// deque<unsigned char*> frameMem;
+// ofMutex frameQueueMutex;
+// ofMutex frameMemMutex;
+//#endif
+ void initEncoder();
+ void allocateMemory();
+ void clearMemory();
+
+ void checkFrame();//ofEventArgs& args);
+ void encodeFrame();
+ void finishRecord();
+
+ std::string container;
+ AVCodecID codecId;
+
+ bool recording;
+ int numCaptures;
+ int frameRate;
+ int bitRate;
+ float frameInterval;
+ float lastFrameTime;
+ int frameNum;
+ std::string outFileName;
+
+ AVOutputFormat* outputFormat;
+ AVFormatContext* formatCtx;
+ AVStream* videoStream;
+
+ AVCodec* codec;
+ AVCodecContext* codecCtx;
+
+ SwsContext* convertCtx;
+
+ unsigned char* inPixels;
+ unsigned char* outPixels;
+ unsigned char* encodedBuf;
+
+ AVFrame* inFrame;
+ AVFrame* outFrame;
+
+ int posX, posY;
+ int inW, inH;
+ int outW, outH;
+
+ bool usePixelSource;
+ unsigned char* pixelSource;
+ };
+
+ inline bool ofxMovieExporter::isRecording() const { return recording; }
+}
+
+namespace Apex = itg;
diff --git a/rotord/renderContext.h b/rotord/renderContext.h
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/rotord/renderContext.h
diff --git a/rotord/rotor.h b/rotord/rotor.h
index 9f0c2e3..9728909 100755
--- a/rotord/rotor.h
+++ b/rotord/rotor.h
@@ -71,7 +71,7 @@ using Poco::UUID;
using Poco::UUIDGenerator;
using Poco::Net::HTTPResponse;
-
+/*
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
@@ -88,6 +88,9 @@ extern "C" {
#include <libavutil/samplefmt.h>
//#include <libavutil/timestamp.h>
}
+*/
+
+#include "ofxMovieExporter.h"
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096