Functional multithreading etching
This commit is contained in:
parent
c8b8a23bff
commit
66ca666b47
119
src/etcher.rs
119
src/etcher.rs
@ -1,7 +1,9 @@
|
|||||||
use std::{fs, vec};
|
use std::{fs, vec, thread};
|
||||||
|
use std::thread::JoinHandle;
|
||||||
|
|
||||||
use anyhow;
|
use anyhow;
|
||||||
use anyhow::Error; //anyhow::Error::msg("My err");
|
use anyhow::Error; //anyhow::Error::msg("My err");
|
||||||
|
|
||||||
use opencv::prelude::*;
|
use opencv::prelude::*;
|
||||||
use opencv::highgui::{self, WINDOW_FULLSCREEN};
|
use opencv::highgui::{self, WINDOW_FULLSCREEN};
|
||||||
use opencv::core::{Mat, Vector, VecN, Size, CV_8UC3,};
|
use opencv::core::{Mat, Vector, VecN, Size, CV_8UC3,};
|
||||||
@ -150,7 +152,8 @@ fn etch_pixel(frame: &mut EmbedSource, rgb: Vec<u8>, x: i32, y: i32) -> anyhow::
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn etch_bw(source: &mut EmbedSource, data: &[bool], global_index: &mut usize) {
|
fn etch_bw(source: &mut EmbedSource, data: &Vec<bool>, global_index: &mut usize)
|
||||||
|
-> anyhow::Result<()> {
|
||||||
let width = source.actual_size.width;
|
let width = source.actual_size.width;
|
||||||
let height = source.actual_size.height;
|
let height = source.actual_size.height;
|
||||||
let size = source.size as usize;
|
let size = source.size as usize;
|
||||||
@ -173,12 +176,19 @@ fn etch_bw(source: &mut EmbedSource, data: &[bool], global_index: &mut usize) {
|
|||||||
//Increment index so we move along the data
|
//Increment index so we move along the data
|
||||||
*global_index += 1;
|
*global_index += 1;
|
||||||
|
|
||||||
|
if *global_index >= data.len() - 1 {
|
||||||
|
return Err(Error::msg("Index beyond data"));
|
||||||
|
}
|
||||||
|
|
||||||
etch_pixel(source, rgb, x, y).unwrap();
|
etch_pixel(source, rgb, x, y).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn etch_color(source: &mut EmbedSource, data: &[u8], global_index: &mut usize) {
|
fn etch_color(source: &mut EmbedSource, data: &Vec<u8>, global_index: &mut usize)
|
||||||
|
-> anyhow::Result<()>{
|
||||||
let width = source.actual_size.width;
|
let width = source.actual_size.width;
|
||||||
let height = source.actual_size.height;
|
let height = source.actual_size.height;
|
||||||
let size = source.size as usize;
|
let size = source.size as usize;
|
||||||
@ -196,9 +206,15 @@ fn etch_color(source: &mut EmbedSource, data: &[u8], global_index: &mut usize) {
|
|||||||
//Increment index so we move along the data
|
//Increment index so we move along the data
|
||||||
*global_index += 3;
|
*global_index += 3;
|
||||||
|
|
||||||
|
if *global_index+2 >= data.len() - 1 {
|
||||||
|
return Err(Error::msg("Index beyond data"));
|
||||||
|
}
|
||||||
|
|
||||||
etch_pixel(source, rgb, x, y).unwrap();
|
etch_pixel(source, rgb, x, y).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn etch_frame(source: &mut EmbedSource, data: &Data, global_index: &mut usize)
|
fn etch_frame(source: &mut EmbedSource, data: &Data, global_index: &mut usize)
|
||||||
@ -407,43 +423,84 @@ fn read_instructions(source: &EmbedSource, threads: usize) -> anyhow::Result<(Ou
|
|||||||
return Ok((out_mode, settings));
|
return Ok((out_mode, settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn summon_etch_thread() -> anyhow::Result<()> {
|
|
||||||
|
|
||||||
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn etch(path: &str, data: Data, settings: Settings) -> anyhow::Result<()> {
|
pub fn etch(path: &str, data: Data, settings: Settings) -> anyhow::Result<()> {
|
||||||
let mut frames = Vec::new();
|
let mut spool = Vec::new();
|
||||||
let mut index: usize = 0;
|
|
||||||
|
|
||||||
match data.out_mode {
|
match data.out_mode {
|
||||||
OutputMode::Color => {
|
OutputMode::Color => {
|
||||||
let length = data.bytes.len();
|
let length = data.bytes.len();
|
||||||
let chunk_size = (length / settings.threads) + 1;
|
let chunk_size = (length / settings.threads) + 1;
|
||||||
|
|
||||||
for chunk in data.bytes.chunks(chunk_size) {
|
//UGLY DUPING
|
||||||
dbg!(chunk.len());
|
let chunks = data.bytes.chunks(chunk_size);
|
||||||
|
for chunk in chunks {
|
||||||
|
//source of perf loss ?
|
||||||
|
let mut chunk_copy = Vec::new();
|
||||||
|
chunk_copy.copy_from_slice(chunk);
|
||||||
|
|
||||||
|
let thread = thread::spawn(move || {
|
||||||
|
let mut frames = Vec::new();
|
||||||
|
let mut index: usize = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// let _timer = Timer::new("Etching frame");
|
||||||
|
let mut source = EmbedSource::new(settings.size, settings.width, settings.height);
|
||||||
|
match etch_color(&mut source, &chunk_copy, &mut index) {
|
||||||
|
Ok(_) => frames.push(source),
|
||||||
|
Err(v) => {
|
||||||
|
frames.push(source);
|
||||||
|
println!("Reached the end of data");
|
||||||
|
break;},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames;
|
||||||
|
});
|
||||||
|
|
||||||
|
spool.push(thread);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OutputMode::Binary => {
|
||||||
|
let length = data.binary.len();
|
||||||
|
let chunk_size = (length / settings.threads) + 1;
|
||||||
|
|
||||||
|
//UGLY DUPING
|
||||||
|
let chunks = data.binary.chunks(chunk_size);
|
||||||
|
for chunk in chunks {
|
||||||
|
//source of perf loss ?
|
||||||
|
let chunk_copy = chunk.to_vec();
|
||||||
|
|
||||||
|
let thread = thread::spawn(move || {
|
||||||
|
let mut frames = Vec::new();
|
||||||
|
let mut index: usize = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// let _timer = Timer::new("Etching frame");
|
||||||
|
let mut source = EmbedSource::new(settings.size, settings.width, settings.height);
|
||||||
|
match etch_bw(&mut source, &chunk_copy, &mut index) {
|
||||||
|
Ok(_) => frames.push(source),
|
||||||
|
Err(v) => {
|
||||||
|
frames.push(source);
|
||||||
|
println!("Reached the end of data");
|
||||||
|
break;},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames;
|
||||||
|
});
|
||||||
|
|
||||||
|
spool.push(thread);
|
||||||
}
|
}
|
||||||
return Ok(());
|
|
||||||
},
|
},
|
||||||
OutputMode::Binary => {},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let instructional_frame = etch_instructions(&settings, &data)?;
|
let mut complete_frames = Vec::new();
|
||||||
frames.push(instructional_frame);
|
|
||||||
|
|
||||||
loop {
|
let instructional_frame = etch_instructions(&settings, &data)?;
|
||||||
// dbg!("Looped!");
|
complete_frames.push(instructional_frame);
|
||||||
// let _timer = Timer::new("Etching frame");
|
|
||||||
let mut source = EmbedSource::new(settings.size, settings.width, settings.height);
|
for thread in spool {
|
||||||
match etch_frame(&mut source, &data, &mut index) {
|
let frame_chunk = thread.join().unwrap();
|
||||||
Ok(_) => frames.push(source),
|
complete_frames.extend(frame_chunk);
|
||||||
Err(v) => {
|
|
||||||
frames.push(source);
|
|
||||||
println!("Reached the end of data");
|
|
||||||
break;},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Mess around with lossless codecs, png seems fine
|
//Mess around with lossless codecs, png seems fine
|
||||||
@ -451,11 +508,11 @@ pub fn etch(path: &str, data: Data, settings: Settings) -> anyhow::Result<()> {
|
|||||||
let fourcc = VideoWriter::fourcc('p', 'n', 'g', ' ')?;
|
let fourcc = VideoWriter::fourcc('p', 'n', 'g', ' ')?;
|
||||||
|
|
||||||
//Check if frame_size is flipped
|
//Check if frame_size is flipped
|
||||||
let frame_size = frames[1].frame_size;
|
let frame_size = complete_frames[1].frame_size;
|
||||||
let mut video = VideoWriter::new(path, fourcc, settings.fps, frame_size, true)?;
|
let mut video = VideoWriter::new(path, fourcc, settings.fps, frame_size, true)?;
|
||||||
|
|
||||||
//Putting them in vector might be slower
|
//Putting them in vector might be slower
|
||||||
for frame in frames {
|
for frame in complete_frames {
|
||||||
let image = frame.image;
|
let image = frame.image;
|
||||||
video.write(&image)?;
|
video.write(&image)?;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user