Old 03-24-2022, 10:35 PM   #1
ashcat_lt
Human being with feelings
 
Join Date: Dec 2012
Posts: 7,271
Default 7 Channel Video Blender

"Mixer" to combine up to 7 videos at a time with different blend modes for each. I used NSFW images to test it, so I'm not going to upload a video. You can figure it out! Or ask questions if you need help.


Code:
// ashcat_lt 7 Channel Video Blender
//@param1:blend1 'blend 1' 0.5 0 1 0.5 0.01
//@param2:blend2 'blend 2' 0.5 0 1 0.5 0.01
//@param3:blend3 'blend 3' 0.5 0 1 0.5 0.01
//@param4:blend4 'blend 4' 0.5 0 1 0.5 0.01
//@param5:blend5 'blend 5' 0.5 0 1 0.5 0.01
//@param6:blend6 'blend 6' 0.5 0 1 0.5 0.01
//@param7:blend7 'blend 7' 0.5 0 1 0.5 0.01
//@param8:mode1 'blend mode 1 (normal, add, multiply, subtract, add inverse, average a, average b, difference, chroma green, chroma blue' 0 0 9 5 1
//@param9:mode2 'blend mode 2 (normal, add, multiply, subtract, add inverse, average a, average b, difference, chroma green, chroma blue' 0 0 9 5 1
//@param10:mode3 'blend mode 3 (normal, add, multiply, subtract, add inverse, average a, average b, difference, chroma green, chroma blue' 0 0 9 5 1
//@param11:mode4 'blend mode 4 (normal, add, multiply, subtract, add inverse, average a, average b, difference, chroma green, chroma blue' 0 0 9 5 1
//@param12:mode5 'blend mode 5 (normal, add, multiply, subtract, add inverse, average a, average b, difference, chroma green, chroma blue' 0 0 9 5 1
//@param13:mode6 'blend mode 6 (normal, add, multiply, subtract, add inverse, average a, average b, difference, chroma green, chroma blue' 0 0 9 5 1
//@param14:mode7 'blend mode 7 (normal, add, multiply, subtract, add inverse, average a, average b, difference, chroma green, chroma blue' 0 0 9 5 1
//@param15:in1 'in 1' 1 1 72 36 1
//@param16:in2 'in 2' 2 1 72 36 1
//@param17:in3 'in 3' 3 1 72 36 1
//@param18:in4 'in 4' 4 1 72 36 1
//@param19:in5 'in 5' 5 1 72 36 1
//@param20:in6 'in 6' 6 1 72 36 1
//@param21:in7 'in 7' 7 1 72 36 1


! inited ?
(
oldCS=colorspace;
colorspace='YV12';
green = -136 * $pi/180;
blue = 0;
g_cos = cos (green);
g_sin = sin (green);
b_cos = 1;
b_sin = 0;
inited = 1;
);

gfx_set (0,0,0,1,0,-1);
gfx_fillrect (0,0,project_w,project_h);
temp = gfx_img_resize (temp,project_w,project_h);
gfx_dest = -1;
gfx_a = 1;
gfx_fillrect (0,0,project_w,project_h);

function blend (in, mode, blend)
(in -=1;
mode <= 1 ? //normal, add
 (gfx_mode = mode;
  gfx_a = blend*1;
  gfx_blit (in););
mode == 2 ? //multiply
  (//gfx_blit (in);
   gfx_mode = 3;
   gfx_a = blend;
   gfx_blit (in););
mode == 3 ? //subtract
  (//gfx_blit (in);
   gfx_mode = 1;
   gfx_a = -1 * blend;
   gfx_blit (in););
mode == 4 ? //add inverse
 (gfx_dest = temp;
  gfx_mode = 0;
  gfx_set (1);  
  gfx_fillrect (0,0,project_w,project_h);
  gfx_mode = 1;
  gfx_a = -1;
  gfx_blit (in);
  gfx_a = blend;
  gfx_dest = -1;
  gfx_blit(temp)); 
mode == 5 ? //average a
 (//gfx_blit (in);
  gfx_mode = 17;
  gfx_a = blend;
  gfx_blit (in););
mode == 6 ? //average b
 (//gfx_blit (in);
  gfx_mode = 18;
  gfx_a = blend;
  gfx_blit (in););
mode == 7 ? //difference
 (//gfx_blit (in);
  gfx_mode = 19;
  gfx_a = blend;
  gfx_blit (in););
//  gfx_dest = -1;
//  gfx_blit(temp);
mode == 8 || mode == 9 ? //chroma green/blue
  (x;
   gfx_mode = 0;
   gfx_a = blend;
   mode == 8 ? (h_cos = g_cos; h_sin = g_sin;);
   mode == 9 ? (h_cos = b_cos; h_sin = b_sin;);
   mag =  0.7;  //mag saturation .7 0 1.0 0.5 .01
   thresh = 0.41;  //thresh threshold .41 0 1 .5 .01
   gain = 1.8;  //gain gain 1.8 0 8 4 .1
   gfx_keyedblit(in,0,0,project_w,project_h,0,0,h_cos*mag,h_sin*mag,thresh,gain);
  );
);

blend (in7, mode7, blend7);
blend (in6, mode6, blend6);
blend (in5, mode5, blend5);
blend (in4, mode4, blend4);
blend (in3, mode3, blend3);
blend (in2, mode2, blend2);
blend (in1, mode1, blend1);


colorspace=oldCS;
Edit - Was originally 8 channels, but that's too many parameters for the VP, so... If you need to mix more than 7 tracks, chain them!

Last edited by ashcat_lt; 03-30-2022 at 10:45 AM. Reason: 3/30/22 - add chroma modes
ashcat_lt is offline   Reply With Quote
Old 03-25-2022, 06:32 AM   #2
papagirafe
Human being with feelings
 
papagirafe's Avatar
 
Join Date: Aug 2020
Location: Brasil
Posts: 679
Default

The concept of a decent video mixer is really missing in the video processor module. Often do we end up "mixing mixes" with unpredictable transparency results. Thanks for sharing!

BTW I am also working on a general video mixer concept with no predefined limits on the number of inputs, sort of an "image overlay" on steroids. But you're definitely the expert on blending effects!
papagirafe is offline   Reply With Quote
Old 03-27-2022, 01:08 PM   #3
ashcat_lt
Human being with feelings
 
Join Date: Dec 2012
Posts: 7,271
Default

Here's a take on this where the blend is controlled by audio/CV via the video peeker. If you want more than 2 audio channels to choose from, you need to use my 64 channel video peeker (link in code) and remember to match the gmem names.

It is rectified and there's a crude global smoothing. If you want more control, it's probably best to condition the audio signal before it hits the video peeker.

Code:
// ashcat_lt Audio/CV controlled 7 Channel Video Blender

//@gmem=jsfx_to_video
  // for more than 2 channels, use 64 channel video peeker and match gmem names
  // https://forums.cockos.com/showthread.php?t=247691

//@param1:ch1 'channel 1' 1 1 64 32 1
//@param2:ch2 'channel 2' 2 1 64 32 1
//@param3:ch3 'channel 3' 3 1 64 32 1
//@param4:ch4 'channel 4' 4 1 64 32 1
//@param5:ch5 'channel 5' 5 1 64 32 1
//@param6:ch6 'channel 6' 6 1 64 32 1
//@param7:ch7 'channel 7' 7 1 64 32 1
//@param8:smooth 'smoothing' 0 0 1 0.5 0.01

//@param10:mode1 'blend mode 1 (normal, add, multiply, subtract, add inverse, average a, average b, difference' 0 0 7 4 1
//@param11:mode2 'blend mode 2 (normal, add, multiply, subtract, add inverse, average a, average b, difference' 0 0 7 4 1
//@param12:mode3 'blend mode 3 (normal, add, multiply, subtract, add inverse, average a, average b, difference' 0 0 7 4 1
//@param13:mode4 'blend mode 4 (normal, add, multiply, subtract, add inverse, average a, average b, difference' 0 0 7 4 1
//@param14:mode5 'blend mode 5 (normal, add, multiply, subtract, add inverse, average a, average b, difference' 0 0 7 4 1
//@param15:mode6 'blend mode 6 (normal, add, multiply, subtract, add inverse, average a, average b, difference' 0 0 7 4 1
//@param16:mode7 'blend mode 7 (normal, add, multiply, subtract, add inverse, average a, average b, difference' 0 0 7 4 1

//@param18:in1 'in 1' 1 1 72 36 1
//@param19:in2 'in 2' 2 1 72 36 1
//@param20:in3 'in 3' 3 1 72 36 1
//@param21:in4 'in 4' 4 1 72 36 1
//@param22:in5 'in 5' 5 1 72 36 1
//@param23:in6 'in 6' 6 1 72 36 1
//@param24:in7 'in 7' 7 1 72 36 1


bufplaypos = gmem[0];
bufwritecursor = gmem[1];
bufsrate = gmem[2];
bufstart = gmem[3];
bufend = gmem[4];
nch = gmem[5];

dt=max(bufplaypos - project_time,0);
dt*bufsrate < dotcount ? underrun_cnt+=1;
rdpos = bufwritecursor - ((dt*bufsrate - dotcount)|0)*nch;
rdpos < bufstart ? rdpos += bufend-bufstart;

i_smooth = 1 - smooth;

function getpt(channel, rect_)
  local (return)
  (channel > 0 && channel <= nch ?
    (return = gmem[rdpos + channel - 1];
     rect_ == -1 ? return = -abs(return);
     rect_ == 1 ? return = abs(return);
     rect_ == 2 ? return = 0.5 * (return + 1);
    );
   (rdpos += nch)>=bufend ? rdpos=bufstart;
   return;
);

function smooth (input)
  instance (last)
  (this.last = i_smooth * input + smooth * this.last;
  );
i=0;

oldCS=colorspace;
colorspace='YV12';
gfx_set (0,0,0,1,0,-1);
gfx_fillrect (0,0,project_w,project_h);
temp = gfx_img_resize (temp,project_w,project_h);
gfx_dest = -1;
gfx_a = 1;
gfx_fillrect (0,0,project_w,project_h);

function blend (in, mode, blend)
(in -=1;
mode <= 1 ? //normal, add
 (gfx_mode = mode;
  gfx_a = blend*1;
  gfx_blit (in););
mode == 2 ? //multiply
  (//gfx_blit (in);
   gfx_mode = 3;
   gfx_a = blend;
   gfx_blit (in););
mode == 3 ? //subtract
  (//gfx_blit (in);
   gfx_mode = 1;
   gfx_a = -1 * blend;
   gfx_blit (in););
mode == 4 ? //add inverse
 (gfx_dest = temp;
  gfx_mode = 0;
  gfx_set (1);  
  gfx_fillrect (0,0,project_w,project_h);
  gfx_mode = 1;
  gfx_a = -1;
  gfx_blit (in);
  gfx_a = blend;
  gfx_dest = -1;
  gfx_blit(temp)); 
mode == 5 ? //average a
 (//gfx_blit (in);
  gfx_mode = 17;
  gfx_a = blend;
  gfx_blit (in););
mode == 6 ? //average b
 (//gfx_blit (in);
  gfx_mode = 18;
  gfx_a = blend;
  gfx_blit (in););
mode == 7 ? //difference
 (//gfx_blit (in);
  gfx_mode = 19;
  gfx_a = blend;
  gfx_blit (in););
//  gfx_dest = -1;
//  gfx_blit(temp);
mode == 8 || mode == 9 ? //chroma green/blue
  (x;
   gfx_mode = 0;
   gfx_a = blend;
   mode == 8 ? (h_cos = g_cos; h_sin = g_sin;);
   mode == 9 ? (h_cos = b_cos; h_sin = b_sin;);
   mag =  0.7;  //mag saturation .7 0 1.0 0.5 .01
   thresh = 0.41;  //thresh threshold .41 0 1 .5 .01
   gain = 1.8;  //gain gain 1.8 0 8 4 .1
   gfx_keyedblit(in,0,0,project_w,project_h,0,0,h_cos*mag,h_sin*mag,thresh,gain);
  );
);

blend (in7, mode7, c7.smooth(getpt(ch7, 1)));
blend (in6, mode6, c6.smooth(getpt(ch6, 1)));
blend (in5, mode5, c5.smooth(getpt(ch5, 1)));
blend (in4, mode4, c4.smooth(getpt(ch4, 1)));
blend (in3, mode3, c3.smooth(getpt(ch3, 1)));
blend (in2, mode2, c2.smooth(getpt(ch2, 1)));
blend (in1, mode1, c1.smooth(getpt(ch1, 1)));


colorspace=oldCS;

Last edited by ashcat_lt; 03-30-2022 at 10:44 AM. Reason: 3/30/33 - add chroma modes
ashcat_lt is offline   Reply With Quote
Old 03-30-2022, 10:46 AM   #4
ashcat_lt
Human being with feelings
 
Join Date: Dec 2012
Posts: 7,271
Default

I had always intended to have chroma key modes for this, and I've now updated both versions to include them. 8 is for green screens and 9 is for blue.
ashcat_lt is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 06:50 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.