summaryrefslogtreecommitdiff
path: root/rotord/src
diff options
context:
space:
mode:
authorComment <tim@gray.(none)>2013-12-05 01:36:58 +0000
committerComment <tim@gray.(none)>2013-12-05 01:36:58 +0000
commit674173fb17ca25b1b35d6482de6f603cc3d8209c (patch)
treefb651966aa14b4acc92d1355938575c10e2090f0 /rotord/src
parent8cfc0a3581cad5da07da69b70c71e67256739166 (diff)
signal output
Diffstat (limited to 'rotord/src')
-rw-r--r--rotord/src/graph.cpp45
-rw-r--r--rotord/src/graph.h2
-rw-r--r--rotord/src/rendercontext.cpp13
-rw-r--r--rotord/src/rotor.h73
4 files changed, 92 insertions, 41 deletions
diff --git a/rotord/src/graph.cpp b/rotord/src/graph.cpp
index 7afb92e..f26db6a 100644
--- a/rotord/src/graph.cpp
+++ b/rotord/src/graph.cpp
@@ -24,23 +24,30 @@ Node* Graph::find_node(const string &type){
}
return nullptr; //can be tested against
};
-bool Graph::signal_render(xmlIO &XML,const float framerate) {
- if (find_node("signal_output")) {
- Signal_output *signal_output=dynamic_cast<Signal_output*>(find_node("signal_output"));
- //return signal_output->render(duration,framerate,signal_xml);
- float sig=0.0f;
- string val="";
- for (float i=0;i<duration;i+=1.0f/framerate){
- float s=(signal_output->get_output(Time_spec(i,framerate,duration))+1.0f)/10.0f;
- if (!fequal(sig,s)){
- val+=toString(i)+":"+toString(s)+" ";
- sig=s;
+bool Graph::signal_render(xmlIO &XML,const string &node,const float framerate) {
+ if (nodes.find(node)!=nodes.end()){
+ Signal_node *signal_output=dynamic_cast<Signal_node*>(nodes[node]);
+ if (signal_output) {
+ //return signal_output->render(duration,framerate,signal_xml);
+ XML.addValue("signal_duration",duration);
+ XML.addValue("signal_framerate",framerate);
+ float sig=0.0f;
+ string val="";
+ for (float i=0;i<duration;i+=1.0f/framerate){
+ float s=(signal_output->get_output(Time_spec(i,framerate,duration))+1.0f)/10.0f;
+ if (!fequal(sig,s)){
+ val+=toString(i)+","+toString(s)+" ";
+ sig=s;
+ }
}
+ XML.addValue("signal",val);
+ return true;
}
- XML.addValue("signal",val);
- return true;
+ cerr<<"Error: /"<<node<<"/ is not a signal node"<<endl;
+
+ return false;
}
- cerr<<"Rotor: signal output node not found"<<endl;
+ cerr<<"Error: signal output node not found"<<endl;
return false;
}
@@ -145,7 +152,7 @@ bool Graph::video_render(const string &output_filename,const float framerate,int
uint16_t *audio=nullptr;
int samples_in_frame;
- for (auto n:nodes) n.second->reset_timer();
+ for (auto n:nodes) n.second->reset();
if (usingaudio){
samples_in_frame=(audioloader.get_sample_rate())/framerate;
@@ -400,10 +407,10 @@ bool Graph::parseJson(string &data,string &media_path){
//handle expandable inputs
- if ((((Image_node*)nodes[nodeID])->image_inputs.size()<=jnodes[i]["image_inputs"].size())&&((Image_node*)nodes[nodeID])->duplicate_inputs){
+ if ((((Image_node*)nodes[nodeID])->image_inputs.size()<jnodes[i]["image_inputs"].size())&&((Image_node*)nodes[nodeID])->duplicate_inputs){
string desc=((Image_node*)nodes[nodeID])->image_inputs[0]->description;
string title=((Image_node*)nodes[nodeID])->image_inputs[0]->title;
- while(((Image_node*)nodes[nodeID])->image_inputs.size()<=jnodes[i]["image_inputs"].size()){
+ while(((Image_node*)nodes[nodeID])->image_inputs.size()<jnodes[i]["image_inputs"].size()){
((Image_node*)nodes[nodeID])->create_image_input(desc,title);
cerr<<"creating an image input"<<endl;
}
@@ -519,10 +526,10 @@ bool Graph::parseXml(string media_path){
uint32_t n3=xml.getNumTags("image_input");
for (uint32_t i3=0;i3<n3;i3++){
//handle expandable inputs
- if ((((Image_node*)nodes[nodeID])->image_inputs.size()<=i3)&&((Image_node*)nodes[nodeID])->duplicate_inputs){
+ if ((((Image_node*)nodes[nodeID])->image_inputs.size()<i3)&&((Image_node*)nodes[nodeID])->duplicate_inputs){
string desc=((Image_node*)nodes[nodeID])->image_inputs[0]->description;
string title=((Image_node*)nodes[nodeID])->image_inputs[0]->title;
- while(((Image_node*)nodes[nodeID])->image_inputs.size()<=i3){
+ while(((Image_node*)nodes[nodeID])->image_inputs.size()<i3){
((Image_node*)nodes[nodeID])->create_image_input(desc,title);
}
}
diff --git a/rotord/src/graph.h b/rotord/src/graph.h
index a231c29..b9647bc 100644
--- a/rotord/src/graph.h
+++ b/rotord/src/graph.h
@@ -51,7 +51,7 @@ namespace Rotor {
std::unordered_map<string,Node*> nodes;
vector<Node*> find_nodes(const string &type); //could be a way of finding a set based on capabilities?
Node* find_node(const string &type);
- bool signal_render(xmlIO &XML,const float framerate);
+ bool signal_render(xmlIO &XML,const string &node,const float framerate);
bool video_render(const string &output_filename,const float framerate,int start, int end);
bool load(string data,string media_path);
bool loadFile(string &filename,string media_path);
diff --git a/rotord/src/rendercontext.cpp b/rotord/src/rendercontext.cpp
index 2f07c89..e73f0d3 100644
--- a/rotord/src/rendercontext.cpp
+++ b/rotord/src/rendercontext.cpp
@@ -296,13 +296,11 @@ void Render_context::session_command(const Session_command& command,xmlIO& XML,H
if (command.commands[1]=="signal") {
if (command.method=="GET") { //generate xml from 1st signal output
if (state==IDLE) {
- //direct call for testing
- float framerate=25.0f;
- //if (command.size()>2) {
- // framerate=toFloat(command.id);
- //}
- //string signal_xml;
- if (graph.signal_render(XML,framerate)){
+ if (command.commands.size()>2) {
+ float framerate;
+ framerate=toFloat(command.body);
+ if (framerate==0.0f) framerate=graph.framerate;
+ if (graph.signal_render(XML,command.commands[2],framerate)){
status=HTTPResponse::HTTP_OK;
logger.information("rendering signal to xml");
//XML.addValue("signal",signal_xml); //this doesn't work >> pseudo xml
@@ -316,6 +314,7 @@ void Render_context::session_command(const Session_command& command,xmlIO& XML,H
// status=HTTPResponse::HTTP_NOT_FOUND;
// XML.addValue("error","Signal output not found in graph");
//}
+ }
}
else {
status=HTTPResponse::HTTP_SERVICE_UNAVAILABLE;
diff --git a/rotord/src/rotor.h b/rotord/src/rotor.h
index 943464d..50fcef7 100644
--- a/rotord/src/rotor.h
+++ b/rotord/src/rotor.h
@@ -373,6 +373,7 @@ namespace Rotor {
};
virtual void init_attribute(const string &attr){
};
+ virtual void init(){}; //initialise any state variables that expect a linear render
string description;
string type;
string ID;
@@ -410,8 +411,9 @@ namespace Rotor {
void set_parameter(const std::string &key,const std::string &value){
if (parameters.find(key)!=parameters.end()) parameters[key]->value=toFloat(value);
};
- void reset_timer(){
+ void reset(){
time_taken=0.0f;
+ int();
}
void time_frame(){
struct timeval end_time;
@@ -508,6 +510,15 @@ namespace Rotor {
#define CYCLER_abs 1
#define CYCLER_rel 2
#define CYCLER_stretch 3
+
+ #define CYCLER_screen 3
+ #define CYCLER_multiply 4
+ #define CYCLER_alpha 5
+ #define CYCLER_wrap 6
+ #define CYCLER_xor 7
+ #define CYCLER_overlay 8
+ #define CYCLER_min 9
+ #define CYCLER_max 10
//new mode that remaps sequence length to segments
//combined with a video mode that maps video length to duration
//time remapper object
@@ -537,25 +548,26 @@ namespace Rotor {
Video_cycler(){
create_image_input("Image input","Image input");
create_signal_input("Selector","Selector input");
- create_attribute("mode","Cycling mode","Mode","cut",{"cut","mix"});
- create_attribute("length_mode","Transition length mode","Length mode","seconds",{"seconds","fraction"});
+ create_attribute("mode","Cycling mode","Mode","cut",{"cut","mix","screen","multiply","alpha","wrap","xor","overlay","min","max"});
+ create_attribute("length_mode","Transition length mode","Length mode","fraction",{"seconds","fraction"});
create_attribute("time_mode","Time mode","time mode","absolute",{"absolute","relative"});
- create_parameter("transition_length","number","transition length","Transition length",-1.0f,0.0f,0.0f);
+ create_parameter("transition_length","number","transition length","Transition length",1.0f,0.0f,0.0f);
title="Video cycler";
description="Cycles through video inputs according to selector signal";
duplicate_inputs=true;
NODEID="93dd9d76-2d09-11e3-9589-5bbbeea1b304";
- segment=0;
- segment_start=segment_end=0.0f;
- prevseg=0;
- prevseg_start=0.0f;
- lastframe=0;
}
Video_cycler(map<string,string> &settings):Video_cycler() {
base_settings(settings);
};
~Video_cycler(){};
bool load(const string &filename);
+ void init(){
+ segment=0;
+ segment_start=0.0f;
+ prevseg_start=0.0f;
+ lastframe=0;
+ }
Image *output(const Frame_spec &frame){
//work out timing
@@ -575,6 +587,7 @@ namespace Rotor {
while ((int)inputs[0]->get(testframe)==seg&&testframe.time<frame.duration){
testframe=testframe.nextframe();
}
+ //nextseg=(int)inputs[0]->get(testframe);
segment_end=((Time_spec)testframe).time;
//cerr<<"Video_cycler: segment "<<seg<<" preroll: "<<prevseg_start<<" start: "<<segment_start<<" end: "<<segment_end<<endl;
}
@@ -643,7 +656,7 @@ namespace Rotor {
//awkward, its getting close to the point where we just need access to all of the segments data everywhere?
//we have 2 times here
- if (attributes["mode"]->intVal==CYCLER_mix&&image_inputs.size()>1){
+ if (attributes["mode"]->intVal>=CYCLER_mix&&image_inputs.size()>1){
int im1=seg%image_inputs.size();
int im2=prevseg%image_inputs.size();
@@ -658,6 +671,8 @@ namespace Rotor {
break;
}
+ //cerr<<f<<" of input "<<(seg%image_inputs.size())<<" & "<<(1.0f-f)<<" of input "<<(prevseg%image_inputs.size())<<endl;
+
Image *in1=image_inputs[im1]->get(attributes["time_mode"]->intVal==CYCLER_abs?frame:inframe);
if (in1){
@@ -668,7 +683,37 @@ namespace Rotor {
image*=f;
Image i2=(*in2);
i2*=(1.0f-f);
- image+=i2;
+ switch(attributes["mode"]->intVal){
+ case CYCLER_screen:
+ image+=i2;
+ break;
+ case CYCLER_multiply:
+ image*=i2;
+ break;
+ case CYCLER_xor:
+ image^=i2;
+ break;
+ case CYCLER_alpha:
+ image=image.alpha_blend(i2);
+ break;
+ case CYCLER_wrap:
+ image=image.add_wrap(i2);
+ break;
+ case CYCLER_overlay:
+ image=image.overlay(i2);
+ break;
+ case CYCLER_min:
+ image=image.min(i2);
+ break;
+ case CYCLER_max:
+ image=image.max(i2);
+ break;
+ case CYCLER_mix: //has to be last because of initialser of *in? go figure
+
+ image+=i2;
+ break;
+ }
+
return &image;
}
}
@@ -678,9 +723,9 @@ namespace Rotor {
}
//cut mode
//for (uint32_t i=0;i<image_inputs.size();i++){ //this skipped a beat for some reason
- int whichinput=(((int)inputs[0]->get((Time_spec)frame)))%image_inputs.size(); //+i
- Image *in=image_inputs[whichinput]->get(inframe);
- if (in) return in;
+ int whichinput=(((int)inputs[0]->get((Time_spec)frame)))%image_inputs.size(); //+i
+ Image *in=image_inputs[whichinput]->get(inframe);
+ if (in) return in;
//}
return nullptr;
}