From 019f9f9c8f115c0b7e3a18f1ad81a47546aa0793 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Fri, 9 Jun 2017 14:21:21 +0200 Subject: [PATCH] initial commit --- Cargo.toml | 7 +++ src/main.rs | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..9ffafdd --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "nihav-tool" +version = "0.1.0" +authors = ["Kostya Shishkov "] + +[dependencies] +nihav = { path="/home/kst/devel/nihav" } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..2517b53 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,148 @@ +extern crate nihav; + +use std::io::prelude::*; +use std::io::SeekFrom; +use std::fs::File; +use std::path::Path; +use nihav::io::byteio::{FileReader, ByteReader}; +use nihav::frame::*; +use nihav::codecs::*; +use nihav::demuxers::*; +use nihav::detect; +use std::env; + +fn write_pgmyuv(pfx: &str, strno: usize, num: u64, frmref: NAFrameRef) { + let frm = frmref.borrow(); + if let NABufferType::None = frm.get_buffer() { return; } + let name = format!("{}out{:02}_{:04}.pgm", pfx, strno, num); + let mut ofile = File::create(name).unwrap(); + let buf = frm.get_buffer().get_vbuf().unwrap(); + let (w, h) = buf.get_dimensions(0); + let (w2, h2) = buf.get_dimensions(1); + let tot_h = h + h2; + let hdr = format!("P5\n{} {}\n255\n", w, tot_h); + ofile.write_all(hdr.as_bytes()).unwrap(); + let dta = buf.get_data(); + let ls = buf.get_stride(0); + let mut idx = 0; + 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 { + let line = &dta[idx..idx2]; + ofile.write_all(line).unwrap(); + idx += ls; + idx2 += ls; + } + let mut base1 = buf.get_offset(1); + let stride1 = buf.get_stride(1); + let mut base2 = buf.get_offset(2); + let stride2 = buf.get_stride(2); + for _ in 0..h2 { + let bend1 = base1 + w2; + let line = &dta[base1..bend1]; + ofile.write_all(line).unwrap(); + ofile.write_all(pad.as_slice()).unwrap(); + + let bend2 = base2 + w2; + let line = &dta[base2..bend2]; + ofile.write_all(line).unwrap(); + ofile.write_all(pad.as_slice()).unwrap(); + + base1 += stride1; + base2 += stride2; + } +} + +fn write_palppm(pfx: &str, strno: usize, num: u64, frmref: NAFrameRef) { + let frm = frmref.borrow(); + let name = format!("{}out{:02}_{:04}.ppm", pfx, strno, num); + let mut ofile = File::create(name).unwrap(); + let buf = frm.get_buffer().get_vbuf().unwrap(); + let (w, h) = buf.get_dimensions(0); + let paloff = buf.get_offset(1); + let hdr = format!("P6\n{} {}\n255\n", w, h); + ofile.write_all(hdr.as_bytes()).unwrap(); + let dta = buf.get_data(); + let ls = buf.get_stride(0); + let mut idx = 0; + let mut line: Vec = Vec::with_capacity(w * 3); + line.resize(w * 3, 0); + for _ in 0..h { + let src = &dta[idx..(idx+w)]; + for x in 0..w { + let pix = src[x] as usize; + line[x * 3 + 0] = dta[paloff + pix * 3 + 2]; + line[x * 3 + 1] = dta[paloff + pix * 3 + 1]; + line[x * 3 + 2] = dta[paloff + pix * 3 + 0]; + } + ofile.write_all(line.as_slice()).unwrap(); + idx += ls; + } +} + +fn main() { + let args: Vec<_> = env::args().collect(); + + if args.len() == 1 { return; } + let lastpts = if args.len() > 2 { + Some(u64::from_str_radix(args[2].as_str(), 10).unwrap()) + } else { None }; + + let name = args[1].as_str(); + let path = Path::new(name); + let mut file = File::open(path).unwrap(); + let dmx_fact; + let mut fr = FileReader::new_read(&mut file); + let mut br = ByteReader::new(&mut fr); + let res = detect::detect_format(name, &mut br); + if res.is_none() { + println!("cannot detect format for {}", name); + return; + } + let (dmx_name, _) = res.unwrap(); +println!("trying demuxer {}", dmx_name); + dmx_fact = find_demuxer(dmx_name).unwrap(); + br.seek(SeekFrom::Start(0)).unwrap(); + let mut dmx = dmx_fact.new_demuxer(&mut br); + dmx.open().unwrap(); + + let mut decs: Vec>> = Vec::new(); + for i in 0..dmx.get_num_streams() { + let s = dmx.get_stream(i).unwrap(); + let info = s.get_info(); + let decfunc = find_decoder(info.get_name()); + if !info.is_video() { + decs.push(None); + } else if let Some(df) = decfunc { + let mut dec = (df)(); + dec.init(info).unwrap(); + decs.push(Some(dec)); + } else { +panic!("decoder {} not found", info.get_name()); + } + } + + loop { + let pktres = dmx.get_frame(); + if let Err(e) = pktres { + if e == DemuxerError::EOF { break; } + } + let pkt = pktres.unwrap(); + let streamno = pkt.get_stream().get_id() as usize; + if let Some(ref mut dec) = decs[streamno] { + let frm = dec.decode(&pkt).unwrap(); + if pkt.get_stream().get_info().is_video() { + if frm.borrow().get_frame_type() != FrameType::Skip { + if frm.borrow().get_buffer().get_vbuf().unwrap().get_info().get_format().is_paletted() { + write_palppm("", streamno, pkt.get_pts().unwrap(), frm); + } else { + write_pgmyuv("", streamno, pkt.get_pts().unwrap(), frm); + } + } + } + } + if pkt.get_pts() != None && pkt.get_pts() == lastpts { break; } + } +//panic!("end"); +} -- 2.30.2