summaryrefslogtreecommitdiff
path: root/rotord/src/graph.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rotord/src/graph.cpp')
-rw-r--r--rotord/src/graph.cpp221
1 files changed, 19 insertions, 202 deletions
diff --git a/rotord/src/graph.cpp b/rotord/src/graph.cpp
index 81f3275..74a569b 100644
--- a/rotord/src/graph.cpp
+++ b/rotord/src/graph.cpp
@@ -74,12 +74,16 @@ bool Graph::preview(xmlIO &XML,string &node,string &_format,int frame,int w,int
}
}
XML.popTag();
- return true;
+ return true;
}
return false;
}
bool Graph::video_render(const string &output_filename,const float framerate) {
+
+ //https://www.adobe.com/devnet/video/articles/mp4_movie_atom.html
+ //https://www.google.ie/search?q=ffmbc&aq=f&oq=ffmbc&aqs=chrome.0.57j0l2j60j0j60.4360j0&sourceid=chrome&ie=UTF-8#q=ffmbc+git
+
//vector<Node*> loaders=find_nodes("video_loader");
//for (auto i:loaders){
// if (!dynamic_cast<Video_loader*>(i)->isLoaded) {
@@ -96,7 +100,12 @@ bool Graph::video_render(const string &output_filename,const float framerate) {
//setup defaults
int bitRate=5000000;
AVCodecID codecId=AV_CODEC_ID_H264; //MPEG4;
- std::string container ="mp4";
+ std::string container;
+ Poco::StringTokenizer t(output_filename,".");
+ if (t.count()>1){
+ container="."+t[t.count()-1];
+ }
+ else container=".mp4";
//at the moment it crashes if you render before audio is loaded and also on 2nd render
libav::exporter exporter;
@@ -141,7 +150,7 @@ bool Graph::video_render(const string &output_filename,const float framerate) {
Audio_frame *a;
int64_t sample_start=0;
while (vf<duration&&!cancelled){ //-vstep) {
-
+
if (usingaudio) {
if (audioloader.get_samples(audio,sample_start,samples_in_frame)) {
if (aoffs>0){
@@ -174,7 +183,7 @@ bool Graph::video_render(const string &output_filename,const float framerate) {
sample_start+=samples_in_frame;
}
else usingaudio=false;
-
+
}
@@ -223,151 +232,7 @@ bool Graph::video_render(const string &output_filename,const float framerate) {
return false;
}
-
- cerr<<"Rotor: video output node not found"<<endl;
- return false;
-}
-
-bool Graph::_video_render(const string &output_filename,const float framerate) {
- //vector<Node*> loaders=find_nodes("video_loader");
- //for (auto i:loaders){
- // if (!dynamic_cast<Video_loader*>(i)->isLoaded) {
- // cerr<<"Rotor: all loaders must be populated before rendering"<<endl;
- // return false;
- // }
- //}
- if (find_node("video_output")) {
- Video_output *video_output=dynamic_cast<Video_output*>(find_node("video_output"));
- for (auto f: find_nodes("video_feedback")){
- (dynamic_cast<Video_feedback*>(f))->set_feedback(&(video_output->image));
- }
- //
- //setup defaults
- int bitRate=5000000;
- AVCodecID codecId=AV_CODEC_ID_H264; //MPEG4;
- std::string container ="mp4";
-
- //at the moment it crashes if you render before audio is loaded and also on 2nd render
- libav::exporter exporter;
-
- float spct=100.0f/duration;
-
- if (exporter.setup(outW,outH,bitRate,framerate,container)) { //codecId,
- if (exporter.record(output_filename)) {
-
- libav::audioloader audioloader;
-
- bool usingaudio=audioloader.setup(audio_filename);
- float *avframe=nullptr;
-
- Logger& logger = Logger::get("Rotor");
- logger.information("Video_output rendering "+output_filename+": "+toString(duration)+" seconds at "+toString(framerate)+" fps, audio frame size: "+toString(exporter.get_audio_framesize()));
- //25fps video and 43.06640625fps audio? hmm
- //how to get the timecodes correct for the interleaved files
-
- struct timeval start, end;
-
- gettimeofday(&start, NULL);
-
- uint16_t *audioframe;
- int samples_in_frame;
-
- if (usingaudio){
- //does audioloader output interleaved samples?
- samples_in_frame=(audioloader.codecContext->sample_rate)/framerate;
- string whether=usingaudio?"Loading":"Cannot load";
- logger.information(whether+" audio file: "+audio_filename+", each frame contains "+toString(samples_in_frame)+" samples at "+toString(audioloader.codecContext->sample_rate)+" hz");
- audioframe=new uint16_t[(samples_in_frame+exporter.get_audio_framesize())*audioloader.codecContext->channels];
- }
-
- float vstep=1.0f/framerate;
- float v=0.0f;
- float vf=0.0f;
- float af=0.0f;
- int aoffs=0;
- int audioend=0;
- Audio_frame *a;
- while (vf<duration&&!cancelled){ //-vstep) {
- uint16_t *audio=nullptr;
- if (usingaudio) {
- uint16_t *audio=audioloader.get_samples(samples_in_frame);
- if (aoffs>0){
- //shift down samples
- int s=0;
- while ((s+aoffs)<audioend) {
- for (int j=0;j<audioloader.codecContext->channels;j++){
- audioframe[s*audioloader.codecContext->channels+j]=audioframe[(s+aoffs)*audioloader.codecContext->channels+j];
- }
- s++;
- }
- aoffs=s;
- }
- for (int i=0;i<samples_in_frame;i++){
- for (int j=0;j<audioloader.codecContext->channels;j++){
- audioframe[(aoffs+i)*audioloader.codecContext->channels+j]=audio[i*audioloader.codecContext->channels+j];
- }
- }
- audioend=aoffs+samples_in_frame;
- aoffs=0;
- //while (fless(vf+vstep,af+exporter.get_audio_step())) {
- while (aoffs+exporter.get_audio_framesize()<audioend) {
- //insert audio frames until we are only 1 audio frame behind the next video frame
- //send audio_framesize() of them through until buffer is used
- //pass full buffer within frame_spec for av nodes
- exporter.encodeFrame(audioframe+(aoffs*audioloader.codecContext->channels));
- af+=exporter.get_audio_step();
- aoffs+=exporter.get_audio_framesize();
- }
- a=new Audio_frame(audio,audioloader.codecContext->channels,samples_in_frame);
- }
-
-
- //[mp3 @ 0x7fffe40330e0] max_analyze_duration 5000000 reached at 5015510 microseconds
- //[mp3 @ 0x7fffe4033ec0] Insufficient thread locking around avcodec_open/close()
- //[mp3 @ 0x7fffe40330e0] Estimating duration from bitrate, this may be inaccurate
- //[libx264 @ 0x7fffe8003940] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle SSE4.2
- //[libx264 @ 0x7fffe8003940] profile High, level 3.0
- //[libx264 @ 0x7fffe8003940] 264 - core 123 r2189 35cf912 - H.264/MPEG-4 AVC codec - Copyleft 2003-2012 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=10 keyint_min=1 scenecut=40 intra_refresh=0 rc_lookahead=10 rc=abr mbtree=1 bitrate=400 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
- //Assertion ff_avcodec_locked failed at libavcodec/utils.c:2967
-
- //cerr<<"videoloader: "<<vf<<" seconds, vstep "<<vstep<<" ,asking for frame "<<((int)((vf*framerate)+0.5))<<endl
-
- Image* i;
- if (usingaudio) {
- i=video_output->get_output(Frame_spec(vf,framerate,duration,outW,outH,a));
- }
- else i=video_output->get_output(Frame_spec(vf,framerate,duration,outW,outH));
- if (i) {
- exporter.encodeFrame(i->RGBdata);
- }
- vf+=vstep;
- progress=vf/duration;
- if (usingaudio) {delete a;};
- }
-
- exporter.finishRecord();
-
- gettimeofday(&end, NULL);
-
- float mtime = ((end.tv_sec-start.tv_sec) + (end.tv_usec-start.tv_usec)/1000000.0) + 0.5;
-
- logger.information("Video_output: rendered "+output_filename+": in "+toString(mtime)+" seconds");
-
- if (usingaudio) {
- audioloader.close();
- delete[] audioframe;
- }
-
-
-
- return true;
- }
- }
-
- return false;
- }
-
cerr<<"Rotor: video output node not found"<<endl;
return false;
}
@@ -388,7 +253,7 @@ bool Graph::load(string data,string media_path){
return false;
}
bool Graph::loadFile(string &filename,string media_path){
- //if (loaded)
+ //if (loaded)
printf("loading graph: %s\n",(filename).c_str());
if (xml.loadFile(filename)){
return parseXml(media_path);
@@ -494,9 +359,9 @@ bool Graph::parseJson(string &data,string &media_path){
}
//parameters
for (int l=0;l<jnodes[i]["parameters"].size();l++){
-
+
string parameter=jnodes[i]["parameters"][l]["name"].asString();
-
+
if (nodes[nodeID]->parameters.find(parameter)!=nodes[nodeID]->parameters.end()) {
float val=jnodes[i]["parameters"][l]["value"].asFloat();
if (val!=nodes[nodeID]->parameters.find(parameter)->second->value){
@@ -514,7 +379,7 @@ bool Graph::parseJson(string &data,string &media_path){
else if (fromID!="") cerr << "Rotor: linking parameter " << parameter << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl;
}
else cerr << "Rotor: cannot find parameter '" << parameter << "' of "<<settings["type"]<<" "<< nodeID << endl;
-
+
}
//attributes
for (int m=0;m<jnodes[i]["attributes"].size();m++){
@@ -582,7 +447,7 @@ bool Graph::parseXml(string media_path){
else cerr << "Rotor: linking input " << i2 << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl;
}
else cerr << "Rotor: input " << i2 << " of node: '" << nodeID << "' does not exist" << endl;
-
+
}
int n3=xml.getNumTags("image_input");
for (int i3=0;i3<n3;i3++){
@@ -651,7 +516,7 @@ bool Graph::parseXml(string media_path){
// nodes[nodeID]->set_parameter(xml.getAttribute("parameter","name","",i5),xml.getAttribute("parameter","value","",i5));
//}
//if (n5>0) cerr << "Rotor: found " << n5 << " extra parameters for node '" << nodeID << "'" << endl;
-
+
xml.popTag();
}
}
@@ -667,54 +532,6 @@ bool Graph::parseXml(string media_path){
loaded=true;
return true;
}
-bool Graph::_load_audio(const string &filename,vector<Audio_processor*> processors){
- Logger& logger = Logger::get("Rotor");
- logger.information("Analysing "+filename);
-
- libav::audioloader loader;
- loader.setup(filename);
-
- duration=((float)loader.formatContext->duration)/AV_TIME_BASE;
-
- int rate = loader.codecContext->sample_rate;
- int samples = ((loader.formatContext->duration + 5000)*rate)/AV_TIME_BASE; //why 5000 more?
- int channels= loader.codecContext->channels;
- int bits = 16; //???why can't we read this loader.codecContext->bits_per_raw_sample;
-
- for (auto p: processors) {
- if(!p->init(channels,bits,samples,rate) ){
- logger.error("ERROR: Audio plugin failed to initialse");
- return false;
- }
- }
-
- AVFrame* frame=loader.get_frame();
- int sample_processed=0;
-
- while (frame&&!cancelled)
- {
- //now we can pass the data to the processor(s)
- for (auto p: processors) {
- p->process_frame(frame->data[0],frame->nb_samples);
- }
- sample_processed+=frame->nb_samples;
- //mutex.lock();
- progress=((float)sample_processed)/samples; //atomic on 64 bit?
- //mutex.unlock();
-
- frame=loader.get_frame();
- }
-
- loader.close();
-
- for (auto p: processors) {
- p->cleanup();
- p->print_summary();
- }
-
- logger.information("Finished audio analysis");
- return true;
-}
bool Graph::load_audio(const string &filename,vector<Audio_processor*> processors){
Logger& logger = Logger::get("Rotor");
logger.information("Analysing "+filename);