From fe800af2e903de06eefac64ba0027f8d6ed7a419 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Mon, 2 Dec 2013 16:29:35 +0000 Subject: video bank keep multiple movies open --- rotord/src/rotor.h | 86 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 12 deletions(-) (limited to 'rotord/src/rotor.h') diff --git a/rotord/src/rotor.h b/rotord/src/rotor.h index e3b218d..02303f9 100644 --- a/rotord/src/rotor.h +++ b/rotord/src/rotor.h @@ -88,7 +88,7 @@ map inputs what are the processes needed? -rather than +rather than if (image_inputs[0].connection) @@ -274,7 +274,7 @@ namespace Rotor { if((lyrics_attribute)attributes["lyrics"]) { thislyric=(lyrics_attribute)attributes["lyrics"].findkey(1); } - + 1) generic way to define and use attributes of different types */ @@ -420,7 +420,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: @@ -860,10 +860,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:"<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 { @@ -879,21 +940,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])<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: @@ -925,18 +987,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 &_settings) { return new Video_bank(_settings);}; - ~Video_bank(){}; private: + vector players; int clip_loaded; float segment_start; int segment; -- cgit v1.2.3