diff options
| author | Tim Redfern <tim@eclectronics.org> | 2013-09-11 16:11:47 +0100 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2013-09-11 16:11:47 +0100 |
| commit | f9694b7d4f1648a0fa984e7cc428bbc9eea86ca0 (patch) | |
| tree | 59e14e57c52e82927963ef71bf83de0f665c42cb /rotord/src/rotor.h | |
| parent | 1f52520db005e056e131f511418e4b71bc9e89fd (diff) | |
ffms2 library for video loader
Diffstat (limited to 'rotord/src/rotor.h')
| -rw-r--r-- | rotord/src/rotor.h | 71 |
1 files changed, 67 insertions, 4 deletions
diff --git a/rotord/src/rotor.h b/rotord/src/rotor.h index eba5be1..ff8675a 100644 --- a/rotord/src/rotor.h +++ b/rotord/src/rotor.h @@ -29,7 +29,6 @@ Definitions of base classes and types for rotor rendering graph #include "utils.h" #include "cvimage.h" #include "libavwrapper.h" -#include "ffmpeg-fas_wrapper.h" //using namespace cv; namespace Rotor { @@ -879,6 +878,33 @@ namespace Rotor { }; #define VIDEOFRAMES_frame 1 #define VIDEOFRAMES_blend 2 + class _Video_loader: public Image_node { + public: + _Video_loader(){ + 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("mode","frame mode","Mode","frame",{"frame","blend"}); + title="Video loader"; + description="Loads a video file"; + }; + _Video_loader(map<string,string> &settings): _Video_loader() { + base_settings(settings); + isLoaded=false; + if (attributes["filename"]->value!="") { + load(find_setting(settings,"media_path","")+attributes["filename"]->value); + } + lastframe=0; + }; + ~_Video_loader(){}; + bool load(const string &filename); + Image *output(const Frame_spec &frame); + _Video_loader* clone(map<string,string> &_settings) { return new _Video_loader(_settings);}; + bool isLoaded; + private: + libav::decoder player; + int lastframe; + }; class Video_loader: public Image_node { public: Video_loader(){ @@ -898,12 +924,49 @@ namespace Rotor { lastframe=0; }; ~Video_loader(){}; - bool load(const string &filename); - Image *output(const Frame_spec &frame); + 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+": "\ + +toString(player.getNumberOfFrames())+" frames, "\ + +toString(player.getFrameRate())+" fps, "\ + +toString(player.getWidth())+"x"+toString(player.getHeight())\ + +", channels:"+toString(player.getNumberOfChannels())); + return true; + } + logger.error("Video_loader failed to load "+filename); + return false; + } + Image *output(const Frame_spec &frame){ + if (isLoaded){ + float clipframerate=(parameters["framerate"]->value==0.0f?player.getFrameRate():parameters["framerate"]->value); + float clipspeed=(clipframerate/frame.framerate)*parameters["speed"]->value; + int wanted=(((int) ((frame.time*frame.framerate)+0.5))%max(1,player.getNumberOfFrames()-1)); + if (wanted!=lastframe){ + if (!player.fetchFrame(frame.w,frame.h,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,player.frame->Data[0],player.frame->Linesize[0]-(frame.w*3)); + lastframe=wanted; + } + return ℑ + } + return nullptr; + }; Video_loader* clone(map<string,string> &_settings) { return new Video_loader(_settings);}; bool isLoaded; private: - libav::decoder player; + //ffmpegsource::decoder player; + libav::ffms2_decoder player; int lastframe; }; class Video_output: public Image_node { |
