this repo has no description
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

๐Ÿ› Fix odd dimensions making encoder crash and RAM hogging because of pixmap-to-hwc parallelization

its serial again, we'll have to see what we have to do about it

+40 -64
+6 -2
src/graphics/canvas.rs
··· 7 7 8 8 use crate::{ 9 9 fonts::{load_fonts, FontOptions}, 10 - Color, ColorMapping, Fill, Filter, Layer, Object, ObjectSizes, Point, 11 - Region, 10 + Color, ColorMapping, Fill, Filter, Layer, Object, ObjectSizes, Point, Region, 12 11 }; 13 12 14 13 use super::ColoredObject; ··· 245 244 pub fn clear(&mut self) { 246 245 self.layers.clear(); 247 246 self.remove_background() 247 + } 248 + 249 + pub fn resolution_to_size_even(&self, resolution: u32) -> (u32, u32) { 250 + let (width, height) = self.resolution_to_size(resolution); 251 + (width + width % 2, height + height % 2) 248 252 } 249 253 250 254 pub fn resolution_to_size(&self, resolution: u32) -> (u32, u32) {
+34 -62
src/video/encoding.rs
··· 4 4 use crate::{ui::Log, Canvas, SVGRenderable}; 5 5 use anyhow::Result; 6 6 use indicatif::ProgressIterator; 7 - use itertools::Itertools; 8 7 use measure_time::debug_time; 9 - use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; 8 + use rayon::iter::ParallelIterator; 10 9 use rayon::{iter::IndexedParallelIterator, slice::ParallelSliceMut}; 10 + use std::sync::MutexGuard; 11 11 use std::{ 12 12 fs::create_dir_all, 13 13 path::{Path, PathBuf}, ··· 19 19 impl Canvas { 20 20 pub fn render_to_hwc_frame( 21 21 &mut self, 22 - resolution: u32, 22 + size: (usize, usize), 23 23 ) -> anyhow::Result<video_rs::Frame> { 24 - let (width, height) = self.resolution_to_size(resolution); 25 - let pixmap = self.render_to_pixmap(width, height)?; 26 - self.pixmap_to_hwc_frame(resolution, &pixmap) 24 + let (width, height) = size; 25 + let pixmap = self.render_to_pixmap(width as u32, height as u32)?; 26 + self.pixmap_to_hwc_frame(size, &pixmap) 27 27 } 28 28 29 29 pub fn pixmap_to_hwc_frame( 30 30 &self, 31 - resolution: u32, 31 + size: (usize, usize), 32 32 pixmap: &tiny_skia::Pixmap, 33 33 ) -> anyhow::Result<video_rs::Frame> { 34 34 debug_time!("pixmap_to_hwc_frame"); 35 - let (width, height) = self.resolution_to_size(resolution); 36 - let (width, height) = (width as usize, height as usize); 35 + let (width, height) = size; 37 36 let mut data = vec![0u8; height * width * 3]; 38 37 39 38 data.par_chunks_exact_mut(3) ··· 60 59 fn setup_encoder(&mut self, output_path: &str) -> anyhow::Result<()> { 61 60 debug_time!("setup_encoder"); 62 61 let (width, height) = 63 - self.initial_canvas.resolution_to_size(self.resolution); 62 + self.initial_canvas.resolution_to_size_even(self.resolution); 64 63 65 64 self.encoder = Some(Arc::new(Mutex::new( 66 65 video_rs::Encoder::new( ··· 110 109 .progress_with(self.progress_bar.clone()) 111 110 { 112 111 context.ms += 1_usize; 113 - context.timestamp = 114 - milliseconds_to_timestamp(context.ms).to_string(); 112 + context.timestamp = milliseconds_to_timestamp(context.ms).to_string(); 115 113 context.beat_fractional = 116 114 (context.bpm * context.ms) as f32 / (1000.0 * 60.0); 117 115 context.beat = context.beat_fractional as usize; ··· 129 127 130 128 if context.marker().starts_with(':') { 131 129 let marker_text = context.marker(); 132 - let commandline = 133 - marker_text.trim_start_matches(':').to_string(); 130 + let commandline = marker_text.trim_start_matches(':').to_string(); 134 131 135 132 for command in &self.commands { 136 133 if commandline.starts_with(&command.name) { ··· 198 195 199 196 self.progress_bar.set_position(0); 200 197 self.progress_bar.set_length(frames_to_encode.len() as u64); 201 - self.progress_bar.set_message("Rasterizing"); 202 - 203 - let (hwc_frames_send, hwc_frames_receive) = 204 - std::sync::mpsc::channel::<(Time, video_rs::Frame)>(); 205 - 206 - let resolution = self.resolution; 207 - let pb = self.progress_bar.clone(); 208 - let canvas = self.initial_canvas.clone(); 209 - frames_to_encode.par_iter().for_each(|(time, svg)| { 210 - encode_frame(&hwc_frames_send, resolution, &canvas, time, svg); 211 - 212 - pb.inc(1); 213 - }); 214 - 215 - drop(hwc_frames_send); 216 - 217 - self.progress_bar.set_position(0); 218 - self.progress_bar.set_length(frames_to_encode.len() as u64); 219 198 self.progress_bar.set_message("Encoding"); 220 199 221 - for (time, frame) in 222 - hwc_frames_receive.iter().sorted_by(|(a, _), (b, _)| { 223 - a.as_secs_f64().total_cmp(&b.as_secs_f64()) 224 - }) 200 + for (time, svg) in frames_to_encode 201 + .into_iter() 202 + .progress_with(self.progress_bar.clone()) 225 203 { 226 - self.encoder 227 - .as_mut() 228 - .expect("Encoder was not initialized") 229 - .lock() 230 - .unwrap() 231 - .encode(&frame, time) 232 - .expect("Failed to encode frame"); 233 - 234 - self.progress_bar.inc(1); 204 + encode_frame( 205 + self.encoder 206 + .as_mut() 207 + .expect("Encoder was not initalized") 208 + .lock() 209 + .unwrap(), 210 + self.resolution, 211 + time, 212 + &canvas, 213 + &svg, 214 + )?; 235 215 } 236 216 237 217 self.progress_bar.finish(); ··· 281 261 } 282 262 283 263 fn encode_frame( 284 - hwc_frames_send: &std::sync::mpsc::Sender<( 285 - Time, 286 - ndarray::ArrayBase<ndarray::OwnedRepr<u8>, ndarray::Dim<[usize; 3]>>, 287 - )>, 264 + mut encoder: MutexGuard<video_rs::Encoder>, 288 265 resolution: u32, 266 + timestamp: Time, 289 267 canvas: &Canvas, 290 - time: &Time, 291 268 svg: &String, 292 - ) { 269 + ) -> anyhow::Result<()> { 293 270 debug_time!("encode_frame"); 294 - let (width, height) = canvas.resolution_to_size(resolution); 295 - let pixmap = canvas 296 - .svg_to_pixmap(width, height, svg) 297 - .expect("Failed to render frame"); 271 + // Make sure that width and height are divisible by 2, as the encoder requires it 272 + let (width, height) = canvas.resolution_to_size_even(resolution); 298 273 299 - let frame = canvas 300 - .pixmap_to_hwc_frame(resolution, &pixmap) 301 - .expect("Failed to convert pixmap to frame"); 302 - 303 - hwc_frames_send 304 - .send((*time, frame)) 305 - .expect("Failed to send frame"); 274 + let pixmap = canvas.svg_to_pixmap(width, height, svg)?; 275 + let frame = 276 + canvas.pixmap_to_hwc_frame((width as usize, height as usize), &pixmap)?; 277 + Ok(encoder.encode(&frame, timestamp)?) 306 278 }