summaryrefslogtreecommitdiff
path: root/rotord/src
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2013-12-02 16:44:08 +0000
committerTim Redfern <tim@eclectronics.org>2013-12-02 16:44:08 +0000
commit991ea189e8c8ea54dfd9c579e59dfef3a25db0c7 (patch)
tree4dc8e22953d8ab760ef7830043408e0bd89f3187 /rotord/src
parent09631556970633c022ba58519ff83b7beeb5aa9f (diff)
parentfe800af2e903de06eefac64ba0027f8d6ed7a419 (diff)
Merge branch 'master' into experimental
Diffstat (limited to 'rotord/src')
-rw-r--r--rotord/src/graph.cpp26
-rw-r--r--rotord/src/rotor.h86
2 files changed, 87 insertions, 25 deletions
diff --git a/rotord/src/graph.cpp b/rotord/src/graph.cpp
index 5a6c564..7afb92e 100644
--- a/rotord/src/graph.cpp
+++ b/rotord/src/graph.cpp
@@ -50,10 +50,10 @@ bool Graph::print_features(xmlIO &XML,string &node){
XML.addValue("features",dynamic_cast<Audio_processor*>(nodes[node])->get_features());
return true;
}
- XML.addValue("error","node /"+node+"/ is not an Audio processor");
+ XML.addValue("ERROR","node /"+node+"/ is not an Audio processor");
return false;
}
- XML.addValue("error","could not find node /"+node+"/");
+ XML.addValue("ERROR","could not find node /"+node+"/");
return false;
}
bool Graph::preview(xmlIO &XML,string &node,string &_format,int frame,int w,int h){
@@ -383,15 +383,15 @@ bool Graph::parseJson(string &data,string &media_path){
if (fromID!=""){
if (nodes.find(fromID)!=nodes.end()) {
if (!nodes[nodeID]->inputs[j]->connect((Signal_node*)nodes[fromID])){
- cerr << "Rotor: graph loader cannot connect input " << j << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
+ cerr << "ERROR: graph loader cannot connect input " << j << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
return false;
}
else cerr << "Rotor: linked input " << j << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
}
- else cerr << "Rotor: linking input " << j << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl;
+ else cerr << "ERROR: linking input " << j << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl;
}
}
- else cerr << "Rotor: input " << j << " of node: '" << nodeID << "' does not exist" << endl;
+ else cerr << "ERROR: input " << j << " of node: '" << nodeID << "' does not exist" << endl;
}
@@ -424,17 +424,17 @@ bool Graph::parseJson(string &data,string &media_path){
if (nodes.find(fromID)!=nodes.end()) {
if (dynamic_cast<Image_node*>(nodes[fromID])!=nullptr) {
if (!dynamic_cast<Image_node*>(nodes[nodeID])->image_inputs[k]->connect((Image_node*)nodes[fromID])){
- cerr << "Rotor: graph loader cannot connect image input " << k << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
+ cerr << "ERROR: graph loader cannot connect image input " << k << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
return false;
}
else cerr << "Rotor: linked image input " << k << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
}
- else cerr << "Rotor: cannot link image input "<< k << " of node '" << nodeID << "' to node '" << fromID << "' : not an image node" << endl;
+ else cerr << "ERROR: cannot link image input "<< k << " of node '" << nodeID << "' to node '" << fromID << "' : not an image node" << endl;
}
- else cerr << "Rotor: linking image input " << k << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl;
+ else cerr << "ERROR: linking image input " << k << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl;
}
}
- else cerr << "Rotor: image input number " << k << " of node: '" << nodeID << "' does not exist" << endl;
+ else cerr << "ERROR: image input number " << k << " of node: '" << nodeID << "' does not exist" << endl;
}
}
//parameters
@@ -451,21 +451,21 @@ bool Graph::parseJson(string &data,string &media_path){
string fromID=jnodes[i]["parameters"][l]["from"].asString();
if (nodes.find(fromID)!=nodes.end()) {
if (!nodes[nodeID]->parameters[parameter]->connect(nodes[fromID])){
- cerr << "Rotor: graph loader cannot connect parameter " << parameter << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
+ cerr << "ERROR: graph loader cannot connect parameter " << parameter << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
return false;
}
else cerr << "Rotor: linked parameter " << parameter << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
}
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;
+ else cerr << "ERROR: cannot find parameter '" << parameter << "' of "<<settings["type"]<<" "<< nodeID << endl;
}
}
- else cerr << "Rotor: duplicate node '"<<nodeID<<"' "<< endl;
+ else cerr << "ERROR: duplicate node '"<<nodeID<<"' "<< endl;
}
else {
- cerr << "Rotor: graph loader cannot find node '" << settings["type"] << "'" << endl;
+ cerr << "ERROR: graph loader cannot find node '" << settings["type"] << "'" << endl;
return false;
}
diff --git a/rotord/src/rotor.h b/rotord/src/rotor.h
index 5278896..2e74e23 100644
--- a/rotord/src/rotor.h
+++ b/rotord/src/rotor.h
@@ -88,7 +88,7 @@ map<string,Input*> inputs
what are the processes needed?
-rather than
+rather than
if (image_inputs[0].connection)
@@ -277,7 +277,7 @@ namespace Rotor {
if(<dynamic_cast>(lyrics_attribute)attributes["lyrics"]) {
thislyric=(lyrics_attribute)attributes["lyrics"].findkey(1);
}
-
+
1) generic way to define and use attributes of different types
*/
@@ -423,7 +423,7 @@ namespace Rotor {
virtual float get_time_used()=0;
float time_taken;
protected:
- struct timeval frame_time;
+ struct timeval frame_time;
};
class Signal_node: public Node{
public:
@@ -863,10 +863,71 @@ namespace Rotor {
base_settings(settings);
media_path=find_setting(settings,"media_path","");
};
+ ~Video_bank(){};
+ bool load(int v){
+ if (players[v].loaded) return true;
+ Poco::Logger& logger = Poco::Logger::get("Rotor");
+ players[v]=libav::video_decoder();
+ string filename=media_path+attributes["filenames"]->vals[v];
+ isLoaded=players[v].open(filename);
+ if (isLoaded){
+ logger.information("libav::decoder loaded "+filename+": "\
+ +toString(players[v].get_number_frames())+" frames, "\
+ +toString(players[v].get_framerate())+" fps, "\
+ +toString(players[v].get_width())+"x"+toString(players[v].get_height())\
+ +", channels:"+toString(players[v].get_number_channels()));
+ lastframe=-2;
+ return true;
+ }
+ logger.error("libav::decoder failed to load "+filename);
+ return false;
+ }
+ bool get_frame(float wanted,const Frame_spec &frame){
+ if (attributes["frame_mode"]->intVal==VIDEOFRAMES_blend){
+ if (((int)wanted)!=Base_video::lastframe){
+ //get a new pair of frames possibly by switching the next one
+ //darn peculiar, as if copying wasn't actually copying
+ if ((Base_video::lastframe==(((int)wanted)-1))&&(in2.w>0)) {
+ in1=in2;
+ }
+ else {
+ players[clip_loaded].fetch_frame(frame.w,frame.h,(int)wanted);
+ //use a temp image because setup_fromRGB just copies pointer
+ temp.setup_fromRGB(frame.w,frame.h,players[clip_loaded].frame->Data[0],players[clip_loaded].frame->Linesize[0]-(frame.w*3));
+ in1=temp;
+ }
+ players[clip_loaded].fetch_frame(frame.w,frame.h,((int)wanted+1)%max(1,players[clip_loaded].get_number_frames()));
+ temp.setup_fromRGB(frame.w,frame.h,players[clip_loaded].frame->Data[0],players[clip_loaded].frame->Linesize[0]-(frame.w*3));
+ in2=temp;
+ lastframe=wanted;
+ }
+ float amt=1.0f-(wanted-((int)wanted));
+ //cout<<"video loader time:"<<frame.time<<" frames "<<((int)wanted)<<" (x"<<amt<<"),"<<(((int)wanted+1)%max(1,player.get_number_frames()))<<endl;
+ image=in1;
+ image*=amt;
+ //Image in2t=in2; //DOES NOT WORK, copies pointer by assignation
+ in2t=in2;
+ in2t*=(1.0f-amt);
+ image+=in2t;
+ }
+ else {
+ if (((int)wanted)!=Base_video::lastframe){
+ if (!players[clip_loaded].fetch_frame(frame.w,frame.h,((int)wanted))) { //seek fail
+ Poco::Logger& logger = Poco::Logger::get("Rotor");
+ logger.error("Video_loader failed to seek frame "+toString(wanted)+" of "+attributes["filename"]->value);
+
+ if (image.w>0) return &image; //just return the previous frame if possible
+ else return nullptr;
+ }
+ image.setup_fromRGB(frame.w,frame.h,players[clip_loaded].frame->Data[0],players[clip_loaded].frame->Linesize[0]-(frame.w*3));
+ }
+ }
+ return true;
+ }
Image *output(const Frame_spec &frame){
if (!inputs[0]->connection){ //default to single loader
if (!isLoaded){
- if (load(media_path+attributes["filenames"]->vals[0] )) {
+ if (Base_video::load(media_path+attributes["filenames"]->vals[0] )) {
isLoaded=true;
}
else {
@@ -882,21 +943,22 @@ namespace Rotor {
float ph=inputs[0]->get((Time_spec)frame);
int seg=((int)ph);
int wv=seg%attributes["filenames"]->vals.size();
+ players.resize(attributes["filenames"]->vals.size());
ph=seg==0?ph:fmod(ph,seg);
if (clip_loaded!=wv){
- if (load(media_path+attributes["filenames"]->vals[wv] )) {
+ if (load(wv)) {
clip_loaded=wv;
isLoaded=true;
}
- else {
+ //else {
//cerr<<"Video bank could not load "<<(media_path+attributes["filenames"]->vals[wv])<<endl;
- clip_loaded=-1;
- }
+ // clip_loaded=-1;
+ //}
}
if (isLoaded){
int wanted=0.0f;
int thisframe=((Time_spec)frame).frame();
- float clipframerate=(parameters["framerate"]->value==0.0f?player.get_framerate():parameters["framerate"]->value);
+ float clipframerate=(parameters["framerate"]->value==0.0f?players[clip_loaded].get_framerate():parameters["framerate"]->value);
float clipspeed=(clipframerate/frame.framerate)*parameters["speed"]->value;
switch (attributes["time_mode"]->intVal){
case VIDEOTIME_play:
@@ -928,18 +990,18 @@ namespace Rotor {
lastframe=thisframe;
break;
case VIDEOTIME_stretch:
- wanted=ph*player.get_number_frames();
+ wanted=ph*players[clip_loaded].get_number_frames();
break;
}
- if (Base_video::get_frame(wanted,frame)) return &image;
+ if (get_frame(wanted,frame)) return &image;
}
}
return nullptr;
}
Video_bank* clone(map<string,string> &_settings) { return new Video_bank(_settings);};
- ~Video_bank(){};
private:
+ vector<libav::video_decoder> players;
int clip_loaded;
float segment_start;
int segment;