summaryrefslogtreecommitdiff
path: root/rotord/src/rotor.h
diff options
context:
space:
mode:
Diffstat (limited to 'rotord/src/rotor.h')
-rw-r--r--rotord/src/rotor.h71
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 &image; //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 &image;
+ }
+ 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 {