X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-core%2Fsrc%2Fscale%2Fmod.rs;h=13762bd01e4d65e16536fa2740004930411fd57f;hb=b914ee01a678df890f66d7e7c63dde8f43ec6a80;hp=c569b2f680f0f84a4f5b80e19c7bafbe967f3bcc;hpb=03accf760cf79bc56d7c6dc6e82cd885fb7e1e13;p=nihav.git diff --git a/nihav-core/src/scale/mod.rs b/nihav-core/src/scale/mod.rs index c569b2f..13762bd 100644 --- a/nihav-core/src/scale/mod.rs +++ b/nihav-core/src/scale/mod.rs @@ -38,11 +38,11 @@ pub type ScaleResult = Result; struct KernelDesc { name: &'static str, - create: fn () -> Box, + create: fn () -> Box, } impl KernelDesc { - fn find(name: &str) -> ScaleResult> { + fn find(name: &str) -> ScaleResult> { for kern in KERNELS.iter() { if kern.name == name { return Ok((kern.create)()); @@ -65,7 +65,7 @@ struct Stage { fmt_out: ScaleInfo, tmp_pic: NABufferType, next: Option>, - worker: Box, + worker: Box, } pub fn get_scale_fmt_from_pic(pic: &NABufferType) -> ScaleInfo { @@ -123,9 +123,38 @@ fn check_format(in_fmt: NAVideoInfo, ref_fmt: &ScaleInfo, just_convert: bool) -> fn copy(pic_in: &NABufferType, pic_out: &mut NABufferType) { if let (Some(ref sbuf), Some(ref mut dbuf)) = (pic_in.get_vbuf(), pic_out.get_vbuf()) { - let sdata = sbuf.get_data(); - let ddata = dbuf.get_data_mut().unwrap(); - ddata.copy_from_slice(&sdata[0..]); + let mut same = true; + let num_components = sbuf.get_info().get_format().get_num_comp(); + for i in 0..num_components { + if sbuf.get_stride(i) != dbuf.get_stride(i) { + same = false; + break; + } + if sbuf.get_offset(i) != dbuf.get_offset(i) { + same = false; + break; + } + } + if same { + let sdata = sbuf.get_data(); + let ddata = dbuf.get_data_mut().unwrap(); + ddata.copy_from_slice(&sdata[0..]); + } else { + let sdata = sbuf.get_data(); + for comp in 0..num_components { + let (_, h) = sbuf.get_dimensions(comp); + let src = &sdata[sbuf.get_offset(comp)..]; + let sstride = sbuf.get_stride(comp); + let doff = dbuf.get_offset(comp); + let dstride = dbuf.get_stride(comp); + let ddata = dbuf.get_data_mut().unwrap(); + let dst = &mut ddata[doff..]; + let copy_size = sstride.min(dstride); + for (dline, sline) in dst.chunks_exact_mut(dstride).take(h).zip(src.chunks_exact(sstride)) { + (&mut dline[..copy_size]).copy_from_slice(&sline[..copy_size]); + } + } + } } else { unimplemented!(); } @@ -157,17 +186,15 @@ fn build_pipeline(ifmt: &ScaleInfo, ofmt: &ScaleInfo, just_convert: bool) -> Sca let outname = ofmt.fmt.get_model().get_short_name(); println!("convert {} -> {}", ifmt, ofmt); - let mut needs_scale = !just_convert; - if (ofmt.fmt.get_max_subsampling() > 0) && + let needs_scale = if (ofmt.fmt.get_max_subsampling() > 0) && (ofmt.fmt.get_max_subsampling() != ifmt.fmt.get_max_subsampling()) { - needs_scale = true; - } - let needs_unpack = needs_scale || !ifmt.fmt.is_unpacked(); + true + } else { + !just_convert + }; + let needs_unpack = !ifmt.fmt.is_unpacked(); let needs_pack = !ofmt.fmt.is_unpacked(); - let mut needs_convert = false; - if inname != outname { - needs_convert = true; - } + let needs_convert = inname != outname; let scale_before_cvt = is_better_fmt(&ifmt, &ofmt) && needs_convert && (ofmt.fmt.get_max_subsampling() == 0); //todo stages for model and gamma conversion @@ -177,12 +204,11 @@ println!("convert {} -> {}", ifmt, ofmt); if needs_unpack { println!("[adding unpack]"); - let new_stage; - if !cur_fmt.fmt.is_paletted() { - new_stage = Stage::new("unpack", &cur_fmt, &ofmt)?; - } else { - new_stage = Stage::new("depal", &cur_fmt, &ofmt)?; - } + let new_stage = if !cur_fmt.fmt.is_paletted() { + Stage::new("unpack", &cur_fmt, &ofmt)? + } else { + Stage::new("depal", &cur_fmt, &ofmt)? + }; cur_fmt = new_stage.fmt_out; add_stage!(stages, new_stage); }