summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorComment <tim@gray.(none)>2013-11-03 16:00:34 +0000
committerComment <tim@gray.(none)>2013-11-03 16:00:34 +0000
commit7d78e568bcef0356fa2d4873b2ba6d19b65c4689 (patch)
tree37597ee4e74513f54ddfa72511803faba43bdfe7
parent510a5218d5e981db3dde9ed31ddc6f732ed6a22a (diff)
making video bank loader
-rw-r--r--rotord/rotord.cbp1
-rw-r--r--rotord/src/graph.cpp56
-rw-r--r--rotord/src/libavwrapper.cpp3
-rw-r--r--rotord/src/rotor.h93
4 files changed, 113 insertions, 40 deletions
diff --git a/rotord/rotord.cbp b/rotord/rotord.cbp
index a3258c2..9a1918b 100644
--- a/rotord/rotord.cbp
+++ b/rotord/rotord.cbp
@@ -65,7 +65,6 @@
<Unit filename="src/nodes_filters.h" />
<Unit filename="src/nodes_maths.h" />
<Unit filename="src/nodes_transform.h" />
- <Unit filename="src/ofUtils.cpp" />
<Unit filename="src/params.h" />
<Unit filename="src/rendercontext.cpp" />
<Unit filename="src/rendercontext.h" />
diff --git a/rotord/src/graph.cpp b/rotord/src/graph.cpp
index 3f1d02b..e323b87 100644
--- a/rotord/src/graph.cpp
+++ b/rotord/src/graph.cpp
@@ -322,19 +322,35 @@ bool Graph::parseJson(string &data,string &media_path){
map<string,string> settings;
vector<string> attrs;
settings["type"]=jnodes[i]["type"].asString();
- if (settings["type"]=="video_cycler"){
- //breakpoint
- cerr<<"making video cycler"<<endl;
- }
- //attributes
+ //attributes
settings["media_path"]=media_path;
- for (int m=0;m<jnodes[i]["attributes"].size();m++){
+ Node* node=factory.create(settings);
+ for (int m=0;m<jnodes[i]["attributes"].size();m++){
string attribute=jnodes[i]["attributes"][m]["name"].asString();
- string val=jnodes[i]["attributes"][m]["value"].asString();
- settings[attribute]=val;
+ if (node->attributes.find(attribute)!=node->attributes.end()){
+ Attribute *attr=node->attributes.find(attribute)->second;
+ if (attr->type=="enum"){
+ string val=jnodes[i]["attributes"][m]["value"].asString();
+ attr->init(val);
+ }
+ else if (attr->type=="array"){
+ std::vector<std::string> vals;
+
+ for (int i5 = 0; i5 < jnodes[i]["attributes"][m]["value"].size(); i5++ )
+ {
+ vals.push_back(jnodes[i]["attributes"][m]["value"][i5].asString());
+ }
+ attr->init(vals);
+
+ }
+ else {
+ string val=jnodes[i]["attributes"][m]["value"].asString();
+ attr->value=val;
+ }
+ }
+ //settings[attribute]=val;
//cerr << "Rotor: setting attribute '"<<attribute<<"' of "<<nodeID<<" to "<<val<<endl;
}
- Node* node=factory.create(settings);
if (node) {
if (nodes.find(nodeID)==nodes.end()){
cerr << "Rotor: creating node '"<<nodeID<<"': '"<< settings["type"] << "'" << endl;
@@ -545,6 +561,28 @@ 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;
+ //support attributes in tags
+ n4=xml.getNumTags("attribute");
+ for (int i4=0;i4<n4;i4++){
+ string attribute=xml.getAttribute("attribute","name","",i4);
+ if (nodes[nodeID]->attributes.find(attribute)!=nodes[nodeID]->attributes.end()) {
+ string val=xml.getAttribute("attribute","value","",i4);
+ if (val!="") nodes[nodeID]->attributes.find(attribute)->second->value=val;
+ string type=xml.getAttribute("attribute","type","",i4);
+ if (nodes[nodeID]->attributes.find(attribute)->second->type=="array"){
+ if(xml.pushTag("attribute",i4)) {
+ int n5=xml.getNumTags("value");
+ std::vector<std::string> vals;
+ for (int i5=0;i5<n5;i5++){
+ vals.push_back(xml.getValue("value","",i5));
+ }
+ nodes[nodeID]->attributes.find(attribute)->second->init(vals);
+ xml.popTag();
+ }
+ }
+ }
+ else cerr << "Rotor: cannot find attribute '" << attribute << "' of "<<nodetype<<" "<< nodeID << endl;
+ }
xml.popTag();
}
diff --git a/rotord/src/libavwrapper.cpp b/rotord/src/libavwrapper.cpp
index 2ee9985..3276b16 100644
--- a/rotord/src/libavwrapper.cpp
+++ b/rotord/src/libavwrapper.cpp
@@ -30,9 +30,8 @@ void libav::maybeInitFFMpegLib()
}
bool libav::video_decoder::open(const std::string& filename){
+ cleanup();
Mutex::ScopedLock lock(mutex);
- loaded=false;
-
Poco::File f=Poco::File(filename);
if (!f.exists()) {
cerr<<"ERROR: "<<filename<<" does not exist"<<endl;
diff --git a/rotord/src/rotor.h b/rotord/src/rotor.h
index 94ec643..a3e65ae 100644
--- a/rotord/src/rotor.h
+++ b/rotord/src/rotor.h
@@ -218,6 +218,12 @@ namespace Rotor {
}
else intVal=0;
}
+ void init(const std::vector<std::string> &_vals){
+ vals=_vals;
+ //string s;
+ //for (auto v:vals) s=s+v+" ";
+ //cerr<<"array attribute "<<title<<": "<<s<<endl;
+ }
string value,description,title,type;
std::vector<std::string> vals;
int intVal;
@@ -435,44 +441,26 @@ namespace Rotor {
#define VIDEOFRAMES_blend 2
#define VIDEOTIME_play 1
#define VIDEOTIME_stretch 2
- //relative timelines used to stretch video
- //1. make a video position input for video node - seconds and stretch modes
- //2. video mode that maps to duration- timeline remapping from cycler and others
- class Video_loader: public Image_node {
+ class Base_video: public Image_node {
public:
- Video_loader(){
+ Base_video(){
create_signal_input("playhead","Playhead");
//floating point control of playback time
//if signal is connected it overrides normal playback
//time_mode dictates whether control is seconds, or duration
create_parameter("speed","number","video playback speed","Speed",1.0f,0.0f,0.0f);
create_parameter("framerate","number","framerate override","Frame rate",0.0f,0.0f,0.0f);
- create_attribute("filename","name of video file to load","File name","");
create_attribute("frame_mode","frame mode","Frame mode","frame",{"frame","blend"});
create_attribute("time_mode","time mode","Time mode","play",{"play","stretch"});
create_attribute("media_id","media_id","media_id","media_id"); //for rotorW
- title="Video loader";
- description="Loads a video file";
- UID="5b64b8ca-2d0a-11e3-92ed-4b7420b40040";
- };
- Video_loader(map<string,string> &settings): Video_loader() {
- base_settings(settings);
+ UID="e92255a0-447a-11e3-b0ce-3fc7ff4bdac9";
isLoaded=false;
- if (attributes["filename"]->value!="") {
- load(find_setting(settings,"media_path","")+attributes["filename"]->value);
- }
-
};
- ~Video_loader(){};
bool load(const string &filename){
Poco::Logger& logger = Poco::Logger::get("Rotor");
- if (isLoaded) {
- player.cleanup(); ///should be in decoder class?
- isLoaded=false;
- }
isLoaded=player.open(filename);
if (isLoaded){
- logger.information("Video_loader loaded "+filename+": "\
+ logger.information("libav::decoder loaded "+filename+": "\
+toString(player.get_number_frames())+" frames, "\
+toString(player.get_framerate())+" fps, "\
+toString(player.get_width())+"x"+toString(player.get_height())\
@@ -480,9 +468,34 @@ namespace Rotor {
lastframe=-2;
return true;
}
- logger.error("Video_loader failed to load "+filename);
+ logger.error("libav::decoder failed to load "+filename);
return false;
}
+ protected:
+ libav::video_decoder player;
+ int lastframe;
+ bool isLoaded;
+ };
+ //relative timelines used to stretch video
+ //1. make a video position input for video node - seconds and stretch modes
+ //2. video mode that maps to duration- timeline remapping from cycler and others
+ class Video_loader: public Base_video {
+ public:
+ Video_loader(){
+ create_attribute("filename","name of video file to load","File name","");
+ create_attribute("media_id","media_id","media_id","media_id"); //for rotorW
+ title="Video loader";
+ description="Loads a video file";
+ UID="5b64b8ca-2d0a-11e3-92ed-4b7420b40040";
+ };
+ Video_loader(map<string,string> &settings): Video_loader() {
+ base_settings(settings);
+ if (attributes["filename"]->value!="") {
+ isLoaded=load(find_setting(settings,"media_path","")+attributes["filename"]->value);
+ }
+
+ };
+ ~Video_loader(){};
void init_attribute(const string &attr){
if (attr=="filename") {
load(attributes["media_path"]->value+attributes[attr]->value);
@@ -562,29 +575,53 @@ namespace Rotor {
Video_loader* clone(map<string,string> &_settings) { return new Video_loader(_settings);};
bool isLoaded;
private:
- //ffmpegsource::decoder player;
- libav::video_decoder player;
- int lastframe;
Image in1,in2,in2t,temp; //for blend frames;
string *filename;
};
- class Video_bank: public Image_node {
+ class Video_bank: public Base_video {
public:
+ //manage a bank of video inclusing transitions
+ //blend mode etc
+ //there may be a total of 4 frames required
+ //and 2 videos open
Video_bank(){
create_attribute("filenames","names of video files to load","File names","",{},"array");
UID="73616e66-4306-11e3-981e-74d02b29f6a6";
title="Video bank";
description="Loads a banks of video files";
+ video_loaded=0;
};
Video_bank(map<string,string> &settings): Video_bank() {
base_settings(settings);
+ media_path=find_setting(settings,"media_path","");
};
Image *output(const Frame_spec &frame){
+ if (attributes["filenames"]->vals.size()){
+ float ph=inputs[0]->get((Time_spec)frame);
+ int wv=((int)ph)%attributes["filenames"]->vals.size();
+ ph=fmod(ph,wv);
+ if (video_loaded!=wv+1){
+ if (load(media_path+attributes["filenames"]->vals[wv]){
+ video_loaded=wv+1;
+ }
+ else video_loaded=0;
+ }
+ if (video_loaded){
+
+ }
+
+ }
return nullptr;
}
Video_bank* clone(map<string,string> &_settings) { return new Video_bank(_settings);};
- ~Video_bank(){};
+ ~Video_bank(){
+
+ };
private:
+ int video_loaded;
+ int last_frame;
+ float segment_duration; //to allow play within a segment at original speed
+ string media_path;
};
class Video_output: public Image_node {
//Video_output 'presents' the output movie. Aspect ratio, bars, fadein/fadeout would happen here