From 6c8e5c40938d4e34f062b53e9ad0d4bd6b147b26 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sun, 4 Jun 2017 11:28:08 +0200 Subject: [PATCH] proper support for linesizes --- src/codecs/mod.rs | 2 +- src/formats.rs | 6 +++++- src/frame.rs | 46 +++++++++++++++++++++++++++++----------------- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/codecs/mod.rs b/src/codecs/mod.rs index dd72aeb..625485e 100644 --- a/src/codecs/mod.rs +++ b/src/codecs/mod.rs @@ -158,7 +158,7 @@ fn write_pgmyuv(pfx: &str, strno: usize, num: u64, frmref: NAFrameRef) { let dta = buf.get_data(); let ls = buf.get_stride(0); let mut idx = 0; - let mut idx2 = ls; + let mut idx2 = w; let mut pad: Vec = Vec::with_capacity((w - w2 * 2) / 2); pad.resize((w - w2 * 2) / 2, 0xFF); for _ in 0..h { diff --git a/src/formats.rs b/src/formats.rs index aa053b2..180e980 100644 --- a/src/formats.rs +++ b/src/formats.rs @@ -330,7 +330,11 @@ impl NAPixelChromaton { } pub fn get_linesize(&self, width: usize) -> usize { let d = self.depth as usize; - (self.get_width(width) * d + d - 1) >> 3 + if self.packed { + (self.get_width(width) * d + d - 1) >> 3 + } else { + self.get_width(width) + } } pub fn get_data_size(&self, width: usize, height: usize) -> usize { let nh = (height + ((1 << self.v_ss) - 1)) >> self.v_ss; diff --git a/src/frame.rs b/src/frame.rs index 02bdf33..e739559 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -92,9 +92,10 @@ pub type NABufferRefT = Rc>>; #[derive(Clone)] pub struct NAVideoBuffer { - info: NAVideoInfo, - data: NABufferRefT, - offs: Vec, + info: NAVideoInfo, + data: NABufferRefT, + offs: Vec, + strides: Vec, } impl NAVideoBuffer { @@ -110,11 +111,13 @@ impl NAVideoBuffer { data.clone_from(self.data.borrow().as_ref()); let mut offs: Vec = Vec::with_capacity(self.offs.len()); offs.clone_from(&self.offs); - NAVideoBuffer { info: self.info, data: Rc::new(RefCell::new(data)), offs: offs } + let mut strides: Vec = Vec::with_capacity(self.strides.len()); + strides.clone_from(&self.strides); + NAVideoBuffer { info: self.info, data: Rc::new(RefCell::new(data)), offs: offs, strides: strides } } pub fn get_stride(&self, idx: usize) -> usize { - if idx >= self.info.get_format().get_num_comp() { return 0; } - self.info.get_format().get_chromaton(idx).unwrap().get_linesize(self.info.get_width()) + if idx >= self.strides.len() { return 0; } + self.strides[idx] } pub fn get_dimensions(&self, idx: usize) -> (usize, usize) { get_plane_size(&self.info, idx) @@ -229,7 +232,8 @@ pub enum AllocatorError { pub fn alloc_video_buffer(vinfo: NAVideoInfo, align: u8) -> Result { let fmt = &vinfo.format; let mut new_size: usize = 0; - let mut offs: Vec = Vec::new(); + let mut offs: Vec = Vec::new(); + let mut strides: Vec = Vec::new(); for i in 0..fmt.get_num_comp() { if fmt.get_chromaton(i) == None { return Err(AllocatorError::FormatError); } @@ -241,7 +245,9 @@ pub fn alloc_video_buffer(vinfo: NAVideoInfo, align: u8) -> Result Result = Vec::with_capacity(new_size.unwrap()); data.resize(new_size.unwrap(), 0); - let buf: NAVideoBuffer = NAVideoBuffer { data: Rc::new(RefCell::new(data)), info: vinfo, offs: offs }; + let buf: NAVideoBuffer = NAVideoBuffer { data: Rc::new(RefCell::new(data)), info: vinfo, offs: offs, strides: strides }; Ok(NABufferType::Video(buf)) } else if !all_packed { for i in 0..fmt.get_num_comp() { - let chr = fmt.get_chromaton(i).unwrap(); + let ochr = fmt.get_chromaton(i); + if let None = ochr { continue; } + let chr = ochr.unwrap(); if !vinfo.is_flipped() { offs.push(new_size as usize); } - let cur_w = chr.get_width(width); + let stride = chr.get_linesize(width); let cur_h = chr.get_height(height); - let cur_sz = cur_w.checked_mul(cur_h); + let cur_sz = stride.checked_mul(cur_h); if cur_sz == None { return Err(AllocatorError::TooLargeDimensions); } let new_sz = new_size.checked_add(cur_sz.unwrap()); if new_sz == None { return Err(AllocatorError::TooLargeDimensions); } @@ -279,16 +289,17 @@ pub fn alloc_video_buffer(vinfo: NAVideoInfo, align: u8) -> Result = Vec::with_capacity(new_size); data.resize(new_size, 0); - let buf: NAVideoBuffer = NAVideoBuffer { data: Rc::new(RefCell::new(data)), info: vinfo, offs: offs }; + let buf: NAVideoBuffer = NAVideoBuffer { data: Rc::new(RefCell::new(data)), info: vinfo, offs: offs, strides: strides }; Ok(NABufferType::Video(buf)) } else { let mut data: Vec = Vec::with_capacity(new_size); data.resize(new_size, 0); - let buf: NAVideoBuffer = NAVideoBuffer { data: Rc::new(RefCell::new(data)), info: vinfo, offs: offs }; + let buf: NAVideoBuffer = NAVideoBuffer { data: Rc::new(RefCell::new(data)), info: vinfo, offs: offs, strides: strides }; Ok(NABufferType::Video16(buf)) } } else { @@ -300,7 +311,8 @@ pub fn alloc_video_buffer(vinfo: NAVideoInfo, align: u8) -> Result = Vec::with_capacity(new_size); data.resize(new_size, 0); - let buf: NAVideoBuffer = NAVideoBuffer { data: Rc::new(RefCell::new(data)), info: vinfo, offs: offs }; + strides.push(line_sz.unwrap()); + let buf: NAVideoBuffer = NAVideoBuffer { data: Rc::new(RefCell::new(data)), info: vinfo, offs: offs, strides: strides }; Ok(NABufferType::VideoPacked(buf)) } } -- 2.30.2