diff options
Diffstat (limited to 'rotord')
| -rwxr-xr-x[-rw-r--r--] | rotord/ofxMovieExporter.cpp | 35 | ||||
| -rwxr-xr-x[-rw-r--r--] | rotord/ofxMovieExporter.h | 5 | ||||
| -rwxr-xr-x | rotord/rotor.cpp | 10 | ||||
| -rwxr-xr-x | rotord/rotor.h | 40 | ||||
| -rw-r--r-- | rotord/rotord.cbp | 4 |
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" /> |
