mirror of
https://github.com/Akascape/Datamosher-Pro.git
synced 2025-12-05 15:59:59 +01:00
76 lines
2.5 KiB
JavaScript
76 lines
2.5 KiB
JavaScript
// dd_ring_buffer.js
|
|
// works kinda like an audio delay
|
|
// stacks the previous n frames into a buffer
|
|
|
|
// global variable holding forward motion vectors from previous frames
|
|
var prev_fwd_mvs = [ ];
|
|
|
|
// change these values to use a smaller or greater number of frames to
|
|
// perform the average of motion vectors
|
|
|
|
// try making the delay long enough to overlap an edit in the content ...
|
|
var delay = 10;
|
|
// divisor controls "feedback" ... or "feedforward" which ever is a better description ...
|
|
var feedback = 0.5; // a number between 0.000001 and .... yeah - controls how much of the buffered mv gets into the next pass
|
|
|
|
var divisor = 1.0/feedback;
|
|
|
|
function glitch_frame(frame)
|
|
{
|
|
// bail out if we have no motion vectors
|
|
let mvs = frame["mv"];
|
|
if ( !mvs )
|
|
return;
|
|
// bail out if we have no forward motion vectors
|
|
let fwd_mvs = mvs["forward"];
|
|
if ( !fwd_mvs )
|
|
return;
|
|
|
|
// update variable holding forward motion vectors from previous
|
|
// frames. note that we perform a deep copy of the clean motion
|
|
// vector values before modifying them.
|
|
let json_str = JSON.stringify(fwd_mvs);
|
|
let deep_copy = JSON.parse(json_str);
|
|
// push to the end of array
|
|
prev_fwd_mvs.push(deep_copy);
|
|
// drop values from earliest frames to always keep the same tail
|
|
// length
|
|
if ( prev_fwd_mvs.length > delay )
|
|
prev_fwd_mvs = prev_fwd_mvs.slice(1);
|
|
|
|
// bail out if we still don't have enough frames
|
|
if ( prev_fwd_mvs.length != delay )
|
|
return;
|
|
|
|
// replace all motion vectors of current frame with an average
|
|
// of the motion vectors from the previous 10 frames
|
|
for ( let i = 0; i < fwd_mvs.length; i++ )
|
|
{
|
|
// loop through all rows
|
|
let row = fwd_mvs[i];
|
|
let delay_row = prev_fwd_mvs[0][i];
|
|
let insert_row = prev_fwd_mvs[delay-1][i];
|
|
|
|
for ( let j = 0; j < row.length; j++ )
|
|
{
|
|
// loop through all macroblocks
|
|
let mv = row[j];
|
|
let dmv = delay_row[j];
|
|
let imv = insert_row[j];
|
|
// THIS IS WHERE THE MAGIC HAPPENS
|
|
|
|
// temp copy of the incoming vectors
|
|
let x = mv[0];
|
|
let y = mv[1];
|
|
// pull their replacements out of the buffer
|
|
mv[0] = dmv[0];
|
|
mv[1] = dmv[1];
|
|
// feedback the 'old' with the 'new' for next time
|
|
imv[0] = (dmv[0] / divisor) + x;
|
|
imv[1] = (dmv[1] / divisor) + y;
|
|
// rinse and repeat
|
|
|
|
}
|
|
}
|
|
}
|