From 7d78e568bcef0356fa2d4873b2ba6d19b65c4689 Mon Sep 17 00:00:00 2001 From: Comment Date: Sun, 3 Nov 2013 16:00:34 +0000 Subject: making video bank loader --- rotord/rotord.cbp | 1 - rotord/src/graph.cpp | 56 ++++++++++++++++++++++----- rotord/src/libavwrapper.cpp | 3 +- rotord/src/rotor.h | 93 +++++++++++++++++++++++++++++++-------------- 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 @@ - 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 settings; vector attrs; settings["type"]=jnodes[i]["type"].asString(); - if (settings["type"]=="video_cycler"){ - //breakpoint - cerr<<"making video cycler"<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 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 '"<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;i4attributes.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 vals; + for (int i5=0;i5attributes.find(attribute)->second->init(vals); + xml.popTag(); + } + } + } + else cerr << "Rotor: cannot find attribute '" << attribute << "' of "< &_vals){ + vals=_vals; + //string s; + //for (auto v:vals) s=s+v+" "; + //cerr<<"array attribute "< 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 &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 &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 &_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 &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 &_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 -- cgit v1.2.3