summaryrefslogtreecommitdiff
path: root/rotord
diff options
context:
space:
mode:
Diffstat (limited to 'rotord')
-rwxr-xr-x[-rw-r--r--]rotord/ofxMovieExporter.cpp35
-rwxr-xr-x[-rw-r--r--]rotord/ofxMovieExporter.h5
-rwxr-xr-xrotord/rotor.cpp10
-rwxr-xr-xrotord/rotor.h40
-rw-r--r--rotord/rotord.cbp4
5 files changed, 61 insertions, 33 deletions
diff --git a/rotord/ofxMovieExporter.cpp b/rotord/ofxMovieExporter.cpp
index eae289c..e8a53e6 100644..100755
--- a/rotord/ofxMovieExporter.cpp
+++ b/rotord/ofxMovieExporter.cpp
@@ -88,7 +88,7 @@
inW=outW;
inH=outH;
-
+
convertCtx = sws_getContext(inW, inH, PIX_FMT_RGB24, outW, outH, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
allocateMemory();
@@ -134,7 +134,7 @@ inH=outH;
lastFrameTime = 0;
frameNum = 0;
recording = true;
-
+
return true;
}
@@ -158,7 +158,7 @@ inH=outH;
inW = w;
inH = h;
usePixelSource = true;
-
+
// resetup encoder etc
setup(outW, outH, bitRate, frameRate, codecId, container);
}
@@ -168,7 +168,7 @@ inH=outH;
{
return numCaptures;
}
-
+
void ofxMovieExporter::resetNumCaptures()
{
numCaptures = 0;
@@ -194,10 +194,10 @@ inH=outH;
void ofxMovieExporter::encodeFrame()
{
-
+
avpicture_fill((AVPicture*)inFrame, inPixels, PIX_FMT_RGB24, inW, inH);
avpicture_fill((AVPicture*)outFrame, outPixels, PIX_FMT_YUV420P, outW, outH);
-
+
//perform the conversion for RGB to YUV and size
sws_scale(convertCtx, inFrame->data, inFrame->linesize, 0, inH, outFrame->data, outFrame->linesize);
@@ -208,7 +208,7 @@ inH=outH;
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.pts = frameNum;//ofGetFrameNum();//codecCtx->coded_frame->pts;
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.dts = pkt.pts;
pkt.stream_index = videoStream->index;
@@ -219,15 +219,20 @@ inH=outH;
frameNum++;
}
- void ofxMovieExporter::encodeFrame(char *pixels)
+ bool ofxMovieExporter::encodeFrame(unsigned char *pixels)
{
-
+
+ if (pixels==nullptr) return false;
+
+ //is it possible to skip the first avpicture_fill?
+
avpicture_fill((AVPicture*)inFrame, pixels, PIX_FMT_RGB24, inW, inH);
avpicture_fill((AVPicture*)outFrame, outPixels, PIX_FMT_YUV420P, outW, outH);
-
+
//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)
{
@@ -235,7 +240,9 @@ inH=outH;
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;
+ int num=videoStream->time_base.num;
+ int den=videoStream->time_base.den;
+ pkt.pts = (int64_t)frameNum*(frameInterval*(((float)videoStream->time_base.den)/videoStream->time_base.num));//ofGetFrameNum();//codecCtx->coded_frame->pts;
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.dts = pkt.pts;
pkt.stream_index = videoStream->index;
@@ -244,6 +251,8 @@ inH=outH;
av_write_frame(formatCtx, &pkt);
}
frameNum++;
+
+ return true;
}
void ofxMovieExporter::allocateMemory()
@@ -268,7 +277,7 @@ inH=outH;
delete[] inPixels;
inPixels = NULL;
-
+
av_free(inFrame);
av_free(outFrame);
av_free(encodedBuf);
@@ -350,7 +359,7 @@ inH=outH;
options=NULL;
// open codec
//if (
- avcodec_open2(codecCtx, codec,&options);
+ 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
index ebd794c..507751e 100644..100755
--- a/rotord/ofxMovieExporter.h
+++ b/rotord/ofxMovieExporter.h
@@ -133,7 +133,7 @@ class ofxMovieExporter
inline int getRecordingWidth() {return outW;}
inline int getRecordingHeight() {return outH;}
- void encodeFrame(unsigned char *pixels,int w,int h);
+ bool encodeFrame(unsigned char *pixels);
private:
//#ifdef _THREAD_CAPTURE
@@ -165,6 +165,7 @@ class ofxMovieExporter
AVOutputFormat* outputFormat;
AVFormatContext* formatCtx;
AVStream* videoStream;
+ AVStream* audioStream;
AVCodec* codec;
AVCodecContext* codecCtx;
@@ -184,5 +185,7 @@ class ofxMovieExporter
bool usePixelSource;
unsigned char* pixelSource;
+
+ int frame_ticks;
};
diff --git a/rotord/rotor.cpp b/rotord/rotor.cpp
index 7ad1488..975ec85 100755
--- a/rotord/rotor.cpp
+++ b/rotord/rotor.cpp
@@ -500,9 +500,9 @@ bool Graph::load(string &filename){
cerr << "Rotor: graph loader cannot connect image input " << i3 << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
return false;
}
- else cerr << "Rotor: linked input " << i3 << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
+ else cerr << "Rotor: linked image input " << i3 << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
}
- else cerr << "Rotor: linking input " << i3 << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl;
+ else cerr << "Rotor: linking image input " << i3 << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl;
}
xml.popTag();
}
@@ -778,9 +778,13 @@ bool Video_output::render(const float duration, const float framerate,const stri
float step=1.0f/framerate;
float v=0.0f;
for (float f=0.0f;f<duration;f+=step) {
- exporter->encodeFrame(get_output(Frame_spec(f,framerate,outW,outH))->RGBdata,outW,outH);
+ if (!exporter->encodeFrame(get_output(Frame_spec(f,framerate,outW,outH))->RGBdata)){
+ cerr << "Rotor: video output failed"<<endl;
+ break;
+ }
}
exporter->finishRecord();
+ cerr << "Rotor: Video_output finished "<< endl;
return true;
}
}
diff --git a/rotord/rotor.h b/rotord/rotor.h
index e5b4085..af1bb72 100755
--- a/rotord/rotor.h
+++ b/rotord/rotor.h
@@ -98,7 +98,7 @@ extern "C" {
#include "vampHost.h"
#include "xmlIO.h"
//#include "avCodec.h"
-
+
namespace Rotor {
#define IDLE 0
#define ANALYSING_AUDIO 1
@@ -116,7 +116,7 @@ namespace Rotor {
class Node;
class Signal_node;
class Image_node;
-
+
//http://blog.tomaka17.com/2012/03/libavcodeclibavformat-tutorial/
struct Packet {
explicit Packet(AVFormatContext* ctxt = nullptr) {
@@ -182,7 +182,7 @@ namespace Rotor {
};
class Input{
public:
- Input(const string &_desc): description(_desc){};
+ Input(const string &_desc): description(_desc),connection(nullptr){};
Node* connection;
string description;
};
@@ -195,9 +195,9 @@ namespace Rotor {
public:
bool connect(Signal_node *source);
Signal_input(const string &_desc): Input(_desc){};
-
+
};
- class Node{
+ class Node{
public:
virtual Node* clone(map<string,string> &_settings)=0;
UUID uid; //every usable node has a UUID
@@ -222,6 +222,7 @@ namespace Rotor {
zero();
};
Image(int _w,int _h){
+ zero();
setup(_w,_h);
};
~Image() {
@@ -266,11 +267,14 @@ namespace Rotor {
public:
vector<Image_input*> image_inputs; //image node also has image inputs and outputs
void create_image_input(const string &description) {image_inputs.push_back(new Image_input(description));};
- Image *get_output(const Frame_spec &frame){ //sample implementation
+ virtual Image *get_output(const Frame_spec &frame)=0;
+
+ /*{ //sample implementation
//do something with the inputs
//and then
return ((Image_node*)(image_inputs[0]->connection))->get_output(frame);
}
+ */
Image *get_preview(const Frame_spec &frame);
Image *image; //this can be privately allocated or just passed on as the node see fit
private:
@@ -309,7 +313,7 @@ namespace Rotor {
}
else return (float)ln;
}
- }
+ }
return 0.0f;
}
void print_features();
@@ -372,18 +376,20 @@ namespace Rotor {
Testcard(){};
Testcard(map<string,string> &settings) {
base_settings(settings);
+ image=new Image();
};
+ ~Testcard(){ delete image;};
Testcard* clone(map<string,string> &_settings) { return new Testcard(_settings);};
- Image *get_output(const Frame_spec &frame){
+ Image *get_output(const Frame_spec &frame){
if (image->setup(frame.w,frame.h)) {
//create testcard
float ws=(255.0f/frame.w);
float hs=(255.0f/frame.h);
for (int i=0;i<frame.h;i++){
for (int j=0;j<frame.w;j++){
- image->RGBdata[i*frame.w+j]=(uint8_t)(i*hs);
- image->RGBdata[i*frame.w+j+1]=(uint8_t)(j*ws);
- image->RGBdata[i*frame.w+j+2]=(uint8_t)(0);
+ image->RGBdata[(i*frame.w+j)*3]=(uint8_t)(i*hs);
+ image->RGBdata[((i*frame.w+j)*3)+1]=(uint8_t)(j*ws);
+ image->RGBdata[((i*frame.w+j)*3)+2]=(uint8_t)(0);
image->Adata[i*frame.w+j]=(uint8_t)255;
image->Zdata[i*frame.w+j]=(uint16_t)512; //1.0 in fixed point 8.8 bits
}
@@ -401,11 +407,17 @@ namespace Rotor {
base_settings(settings);
exporter=new ofxMovieExporter();
};
+ Image *get_output(const Frame_spec &frame){
+ if (image_inputs[0]->connection) {
+ return ((Image_node*)(image_inputs[0]->connection))->get_output(frame);
+ }
+ else return nullptr;
+ };
Video_output* clone(map<string,string> &_settings) { return new Video_output(_settings);};
bool render(const float duration, const float framerate,const string &output_filename,const string &audio_filename);
private:
- ofxMovieExporter *exporter;
+ ofxMovieExporter *exporter;
};
//-------------------------------------------------------------------
class Node_factory{
@@ -462,7 +474,7 @@ namespace Rotor {
else return false;
}
int load(Poco::UUID uid);
- bool load(string &graph_filename);
+ bool load(string &graph_filename);
UUID save(); //save to DB, returns UUID of saved graph
bool loaded;
float duration;
@@ -475,7 +487,7 @@ namespace Rotor {
public:
Audio_thumbnailer(){
height=32;
- width=64; //fit
+ width=64; //fit
data=new uint8_t[height*width];
memset(data,0,height*width);
};
diff --git a/rotord/rotord.cbp b/rotord/rotord.cbp
index f4eafc3..6bae8c7 100644
--- a/rotord/rotord.cbp
+++ b/rotord/rotord.cbp
@@ -49,10 +49,10 @@
<Add option="-Wall" />
</Compiler>
<Unit filename="Makefile" />
- <Unit filename="avCodec.cpp" />
- <Unit filename="avCodec.h" />
<Unit filename="ofUtils.cpp" />
<Unit filename="ofUtils.h" />
+ <Unit filename="ofxMovieExporter.cpp" />
+ <Unit filename="ofxMovieExporter.h" />
<Unit filename="rotor.cpp" />
<Unit filename="rotor.h" />
<Unit filename="rotord.cpp" />