diff options
| author | Tim Redfern <tim@eclectronics.org> | 2013-12-02 16:44:08 +0000 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2013-12-02 16:44:08 +0000 |
| commit | 991ea189e8c8ea54dfd9c579e59dfef3a25db0c7 (patch) | |
| tree | 4dc8e22953d8ab760ef7830043408e0bd89f3187 /rotord/src/rotor.h | |
| parent | 09631556970633c022ba58519ff83b7beeb5aa9f (diff) | |
| parent | fe800af2e903de06eefac64ba0027f8d6ed7a419 (diff) | |
Merge branch 'master' into experimental
Diffstat (limited to 'rotord/src/rotor.h')
| -rw-r--r-- | rotord/src/rotor.h | 86 |
1 files changed, 74 insertions, 12 deletions
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 ℑ //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 ℑ + if (get_frame(wanted,frame)) return ℑ } } 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; |
