diff options
| -rwxr-xr-x | rotord/rotor.cpp | 3 | ||||
| -rwxr-xr-x | rotord/rotor.h | 61 |
2 files changed, 60 insertions, 4 deletions
diff --git a/rotord/rotor.cpp b/rotord/rotor.cpp index 33cd3f5..4ed8de4 100755 --- a/rotord/rotor.cpp +++ b/rotord/rotor.cpp @@ -17,6 +17,7 @@ Node_factory::Node_factory(){ add_type("invert",new Invert()); add_type("video_cycler",new Video_cycler()); add_type("luma_levels",new Luma_levels()); + add_type("echo_trails",new Echo_trails()); } bool Signal_input::connect(Signal_node* source) { @@ -77,7 +78,7 @@ int Audio_thumbnailer::process_frame(uint8_t *_data,int samples_in_frame){ for (int i=0;i<channels;i++) { unsigned int this_val=0; for (int j=0;j<bytes;j++) { -// this_val+=_data[(in_sample*stride)+(i*bytes)+j]<<(j*8); + this_val+=_data[(in_sample*stride)+(i*bytes)+j]<<(j*8); } //convert from integer data format - i.e s16p - to audio signal in -1..1 range //presume 16 bits for now... diff --git a/rotord/rotor.h b/rotord/rotor.h index 839ac32..66ad804 100755 --- a/rotord/rotor.h +++ b/rotord/rotor.h @@ -183,6 +183,17 @@ namespace Rotor { } return false; } + Image & operator+=(const Image &other) { + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot add images with different sizes!"<<endl; + } + else { + for (int i=0;i<w*h*3;i++){ + RGBdata[i]+=other.RGBdata[i]; + } + } + return *this; + } uint8_t *RGBdata; uint8_t *Adata; uint16_t *Zdata; @@ -455,6 +466,9 @@ namespace Rotor { libav::Audioloader audioloader; }; class Video_input: public Image_node { + //video input using gstreamer + //seems slow + //TODO: scaling public: Video_input(){}; Video_input(map<string,string> &settings) { @@ -496,9 +510,9 @@ namespace Rotor { private: }; class Luma_levels: public Image_node { - //cycles through video inputs in order + //applies LUT To RGB channels equally public: - Luma_levels(){LUT=nullptr;}; + Luma_levels(){LUT=nullptr;image=nullptr;}; Luma_levels(map<string,string> &settings) { base_settings(settings); black_in=find_setting(settings,"black_in",0.0f); @@ -519,7 +533,6 @@ namespace Rotor { LUT[i]=(unsigned char)(((pow(min(fltmax,max(0.0f,(((((float)i)/256.0f)-black_in)/(white_in-black_in)))),(1.0/gamma))*(white_out-black_out))+black_out)*256.0f); } } - bool load(const string &filename); Image *get_output(const Frame_spec &frame){ image->setup(frame.w,frame.h); if (image_inputs.size()) { @@ -541,6 +554,48 @@ namespace Rotor { Image *image; float black_in,white_in,gamma,black_out,white_out; }; + class Echo_trails: public Image_node { + //draw trail frames additively that fade off over time + //the hard thing here is how to cache frames, if its done cleverly it could have no impact when + //used linearly + //Image needs to overload operator+ + //need a clever data structure to cache frames - maybe a map of Image pointers + + //we know the frames we want to overlay as offsets ie -25,-20,-15,-10,-5 + //do we keep 25 frames loaded in order to benefit? 25 PAL frames is 60MB so probably so + //OK so: + //make a new set of pointers + //identify if any of the new pointers can inherit old frames + //delete unneeded old frames + //load new frames + //do the calculations + + //2 inputs - "This frame" and "keyed" + //hmm, that is clumsy, could it inherit from luma_levels + public: + Echo_trails(){}; + Echo_trails(map<string,string> &settings) { + base_settings(settings); + duration=find_setting(settings,"duration",1.0f); + number=find_setting(settings,"number",1); + image=new Image(); + }; + ~Echo_trails(){if (image) {delete image;} }; + Image *get_output(const Frame_spec &frame){ + image->setup(frame.w,frame.h); + if (image_inputs.size()) { + if (image_inputs[0]->connection){ + return image; + } + } + return nullptr; + } + Echo_trails* clone(map<string,string> &_settings) { return new Echo_trails(_settings);}; + private: + Image *image; + float duration; + int number; + }; //------------------------------------------------------------------- class Node_factory{ public: |
