From b772fc6d12321327473fe3effa69902312c31624 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 31 Jan 2026 15:49:07 +0100 Subject: [PATCH] switch to nihav_hlblocks for demuxer and image sequence code --- Cargo.toml | 4 + src/demux.rs | 420 ---------------------------------------------- src/imgseq.rs | 329 ------------------------------------ src/main.rs | 16 +- src/transcoder.rs | 9 +- 5 files changed, 21 insertions(+), 757 deletions(-) delete mode 100644 src/demux.rs delete mode 100644 src/imgseq.rs diff --git a/Cargo.toml b/Cargo.toml index e54f354..1bf45dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,7 @@ nihav_core = { path="../nihav-core" } nihav_codec_support = { path="../nihav-codec-support" } nihav_registry = { path="../nihav-registry" } nihav_allstuff = { path="../nihav-allstuff" } + +[dependencies.nihav_hlblocks] +path = "../nihav-hlblocks" +features = ["demuxer", "imgseq_dec"] diff --git a/src/demux.rs b/src/demux.rs deleted file mode 100644 index ae5058a..0000000 --- a/src/demux.rs +++ /dev/null @@ -1,420 +0,0 @@ -use std::io::SeekFrom; -use nihav_core::codecs::*; -use nihav_core::demuxers::*; -use nihav_core::muxers::*; -use nihav_registry::detect; -use nihav_core::io::byteio::ByteIO; -use nihav_core::sbbox::*; -use nihav_allstuff::*; -use crate::null::*; -use crate::imgseq::*; - -pub struct FullRegister { - pub dmx_reg: RegisteredDemuxers, - pub rdmx_reg: RegisteredRawDemuxers, - pub pkt_reg: RegisteredPacketisers, - pub dec_reg: RegisteredDecoders, - pub enc_reg: RegisteredEncoders, - pub mux_reg: RegisteredMuxers, -} - -impl FullRegister { - pub fn new() -> Self { - let mut dmx_reg = RegisteredDemuxers::new(); - nihav_register_all_demuxers(&mut dmx_reg); - let mut rdmx_reg = RegisteredRawDemuxers::new(); - nihav_register_all_raw_demuxers(&mut rdmx_reg); - let mut dec_reg = RegisteredDecoders::new(); - nihav_register_all_decoders(&mut dec_reg); - let mut pkt_reg = RegisteredPacketisers::new(); - nihav_register_all_packetisers(&mut pkt_reg); - let mut enc_reg = RegisteredEncoders::new(); - nihav_register_all_encoders(&mut enc_reg); - enc_reg.add_encoder(NULL_ENCODER); - let mut mux_reg = RegisteredMuxers::new(); - nihav_register_all_muxers(&mut mux_reg); - mux_reg.add_muxer(NULL_MUXER); - Self { dmx_reg, rdmx_reg, pkt_reg, dec_reg, enc_reg, mux_reg } - } -} - -pub struct RawStreamCtx<'a> { - stream: NAStreamRef, - sm: StreamManager, - packetiser: Box, - br: &'a mut dyn ByteIO, - pts: u64, -} - -impl<'a> RawStreamCtx<'a> { - fn new(stream: NAStreamRef, packetiser: Box, br: &'a mut dyn ByteIO) -> Self { - let mut sm = StreamManager::new(); - sm.add_stream_ref(stream.clone()); - Self { stream, sm, packetiser, br, pts: 0 } - } -} - -type ReaderBox = Box; - -pub enum DemuxerObject<'a> { - None, - Normal(SBBox>), - Raw(SBBox>, Vec>>, bool), - RawStream(SBBox>), - ImageSequence(ImgSeqDemuxer), -} - -impl<'a> DemuxerObject<'a> { - pub fn create(mut br: ReaderBox, reg: &FullRegister, name: &str, ifmt: &Option, is_raw: bool, print_info: bool) -> DemuxerObject<'a> { - if !is_raw { - let dmx_name = if let Some(ref dname) = ifmt { - dname.as_str() - } else if let Some((dname, score)) = detect::detect_format(name, &mut *br) { - if print_info { - println!("detected {} with score {:?}", dname, score); - } - dname - } else { - "" - }; - if !dmx_name.is_empty() { - if print_info { - println!("trying demuxer {} on {}", dmx_name, name); - } - if let Some(dmx_fact) = reg.dmx_reg.find_demuxer(dmx_name) { - br.seek(SeekFrom::Start(0)).unwrap(); - - let ret = SelfBorrow::try_new(br, |br_| { - unsafe { - create_demuxer(dmx_fact, (*br_).as_mut()).ok() - } - }); - if let Ok(dmx) = ret { - return DemuxerObject::Normal(dmx); - } else { - println!("demuxer creation failed!"); - return DemuxerObject::None; - } - } - } - if ifmt.is_some() { - return DemuxerObject::None; - } - if !dmx_name.is_empty() { - if print_info { - println!("trying raw demuxer {} on {}", dmx_name, name); - } - if let Some(rdmx_fact) = reg.rdmx_reg.find_demuxer(dmx_name) { - br.seek(SeekFrom::Start(0)).unwrap(); - let ret = SelfBorrow::try_new(br, |br_| { - unsafe { - create_raw_demuxer(rdmx_fact, (*br_).as_mut()).ok() - } - }); - if let Ok(dmx) = ret { - let mut pkts = Vec::new(); - for stream in dmx.get_object().get_streams() { - if let Some(pcreate) = reg.pkt_reg.find_packetiser(stream.get_info().get_name()) { - let mut packetiser = (pcreate)(); - packetiser.attach_stream(stream); - pkts.push(Some(packetiser)); - } else { - pkts.push(None); - } - } - return DemuxerObject::Raw(dmx, pkts, false); - } else { - println!("raw demuxer creation failed!"); - return DemuxerObject::None; - } - } - } - for rdmx in reg.rdmx_reg.iter() { - if rdmx.check_format(&mut *br) { - if print_info { - println!("detected {} as {}", name, rdmx.get_name()); - } - br.seek(SeekFrom::Start(0)).unwrap(); - let ret = SelfBorrow::try_new(br, |br_| { - unsafe { - create_raw_demuxer(*rdmx, (*br_).as_mut()).ok() - } - }); - if let Ok(dmx) = ret { - let mut pkts = Vec::new(); - for stream in dmx.get_object().get_streams() { - if let Some(pcreate) = reg.pkt_reg.find_packetiser(stream.get_info().get_name()) { - let packetiser = (pcreate)(); - pkts.push(Some(packetiser)); - } else { - pkts.push(None); - } - } - return DemuxerObject::Raw(dmx, pkts, false); - } else { - println!("raw demuxer creation failed!"); - return DemuxerObject::None; - } - } - } - } - br.seek(SeekFrom::Start(0)).unwrap(); - let mut buf = vec![0; 1048576]; - let size = if let Ok(val) = br.peek_buf(&mut buf) { val } else { - println!("cannot read any data"); - return DemuxerObject::None; - }; - let mut pname = ""; - - for pinfo in reg.pkt_reg.iter() { - let mut packetiser = (pinfo.get_packetiser)(); - packetiser.add_data(&buf[..size]); - if packetiser.parse_stream(0).is_ok() { - pname = pinfo.name; - break; - } - } - if !pname.is_empty() { - if print_info { - println!("found raw stream of type {} for {}", pname, name); - } - let pcreate = reg.pkt_reg.find_packetiser(pname).unwrap(); - let rctx = SelfBorrow::new(br, |br_| { - unsafe { - let mut packetiser = (pcreate)(); - packetiser.add_data(&buf[..size]); - let stream = packetiser.parse_stream(0).unwrap(); - packetiser.reset(); - RawStreamCtx::new(stream, packetiser, (*br_).as_mut()) - } - }); - DemuxerObject::RawStream(rctx) - } else { - DemuxerObject::None - } - } - pub fn create_imgseq(isd: ImgSeqDemuxer) -> Self { - DemuxerObject::ImageSequence(isd) - } - pub fn is_none(&self) -> bool { - matches!(*self, DemuxerObject::None) - } - pub fn get_duration(&self) -> u64 { - match *self { - DemuxerObject::Normal(ref dmx) => dmx.get_object().get_duration(), - DemuxerObject::Raw(ref dmx, _, _) => dmx.get_object().get_duration(), - DemuxerObject::RawStream(ref ctx) => { - NATimeInfo::rescale_ts(ctx.get_object().stream.duration, ctx.get_object().stream.tb_num, ctx.get_object().stream.tb_den, 1, 1000) - }, - _ => 0, - } - } - pub fn get_num_streams(&self) -> usize { - match *self { - DemuxerObject::None => 0, - DemuxerObject::Normal(ref dmx) => dmx.get_object().get_num_streams(), - DemuxerObject::Raw(ref dmx, _, _) => dmx.get_object().get_num_streams(), - DemuxerObject::RawStream(_) => 1, - DemuxerObject::ImageSequence(_) => 1, - } - } - pub fn get_stream(&self, idx: usize) -> Option { - match *self { - DemuxerObject::Normal(ref dmx) => dmx.get_object().get_stream(idx), - DemuxerObject::Raw(ref dmx, _, _) => dmx.get_object().get_stream(idx), - DemuxerObject::RawStream(ref ctx) if idx == 0 => Some(ctx.get_object().stream.clone()), - DemuxerObject::ImageSequence(ref ctx) if idx == 0 => Some(ctx.stream.clone()), - _ => None, - } - } - /*pub fn get_streams(&self) -> StreamIter { - match *self { - DemuxerObject::Normal(ref dmx) => dmx.get_object().get_streams(), - DemuxerObject::Raw(ref dmx, _, _) => dmx.get_object().get_streams(), - DemuxerObject::RawStream(ref ctx) => ctx.get_object().sm.iter(), - DemuxerObject::ImageSequence(ref ctx) => ctx.sm.iter(), - _ => unreachable!(), - } - }*/ - pub fn get_stream_manager(&self) -> &StreamManager { - match *self { - DemuxerObject::Normal(ref dmx) => dmx.get_object().get_stream_manager(), - DemuxerObject::Raw(ref dmx, _, _) => dmx.get_object().get_stream_manager(), - DemuxerObject::RawStream(ref ctx) => &ctx.get_object().sm, - DemuxerObject::ImageSequence(ref ctx) => &ctx.sm, - _ => unreachable!(), - } - } - pub fn get_frame(&mut self) -> DemuxerResult { - match *self { - DemuxerObject::Normal(ref mut dmx) => dmx.get_object_mut().get_frame(), - DemuxerObject::Raw(ref mut dmx, ref mut packetisers, ref mut eof) => { - let dmx = dmx.get_object_mut(); - loop { - let mut has_some = false; - for (stream, p) in dmx.get_streams().zip(packetisers.iter_mut()) { - if let Some(ref mut pkts) = p { - match pkts.get_packet(stream.clone()) { - Ok(Some(pkt)) => return Ok(pkt), - Ok(None) | Err(DecoderError::ShortData) => { - if *eof { - *p = None; - } - }, - Err(err) => { - println!("packetisation error {:?}", err); - return Err(DemuxerError::InvalidData); - } - }; - has_some |= p.is_some(); - } - } - if !has_some { - return Err(DemuxerError::EOF); - } - if let Ok(data) = dmx.get_data() { - let id = data.get_stream().get_id(); - for (i, stream) in dmx.get_streams().enumerate() { - if stream.get_id() == id { - if let Some(ref mut pkts) = packetisers[i] { - pkts.add_data(&data.get_buffer()); - } - break; - } - } - } else { - *eof = true; - } - } - }, - DemuxerObject::RawStream(ref mut ctx) => { - let ctx = ctx.get_object_mut(); - let mut buf = [0; 65536]; - loop { - match ctx.packetiser.get_packet(ctx.stream.clone()) { - Ok(Some(mut packet)) => { - if packet.get_pts().is_none() && packet.get_duration().is_some() { - packet.ts.pts = Some(ctx.pts); - } - ctx.pts += packet.get_duration().unwrap_or(0); - return Ok(packet); - }, - Ok(None) => {}, - Err(DecoderError::ShortData) => {}, - _ => return Err(DemuxerError::InvalidData), - }; - match ctx.br.read_buf_some(&mut buf) { - Ok(size) => { - ctx.packetiser.add_data(&buf[..size]); - }, - Err(_) => { - match ctx.packetiser.get_packet(ctx.stream.clone()) { - Ok(Some(mut packet)) => { - if packet.get_pts().is_none() && packet.get_duration().is_some() { - packet.ts.pts = Some(ctx.pts); - } - ctx.pts += packet.get_duration().unwrap_or(0); - return Ok(packet); - }, - Ok(None) | Err(DecoderError::ShortData) => return Err(DemuxerError::EOF), - _ => return Err(DemuxerError::InvalidData), - }; - }, - }; - } - }, - DemuxerObject::ImageSequence(ref mut ctx) => ctx.get_frame(), - _ => unreachable!(), - } - } - pub fn seek(&mut self, seek_time: NATimePoint) -> DemuxerResult<()> { - match *self { - DemuxerObject::Normal(ref mut dmx) => dmx.get_object_mut().seek(seek_time), - DemuxerObject::Raw(ref mut dmx, _, _) => dmx.get_object_mut().seek(seek_time), - DemuxerObject::ImageSequence(ref mut ctx) => ctx.seek(seek_time), - _ => Err(DemuxerError::NotImplemented), - } - } -} - -impl<'a> NAOptionHandler for DemuxerObject<'a> { - fn get_supported_options(&self) -> &[NAOptionDefinition] { - match *self { - DemuxerObject::Normal(ref dmx) => dmx.get_object().get_supported_options(), - DemuxerObject::Raw(ref dmx, _, _) => dmx.get_object().get_supported_options(), - DemuxerObject::ImageSequence(ref ctx) => ctx.get_supported_options(), - _ => &[], - } - } - fn set_options(&mut self, options: &[NAOption]) { - match *self { - DemuxerObject::Normal(ref mut dmx) => dmx.get_object_mut().set_options(options), - DemuxerObject::Raw(ref mut dmx, _, _) => dmx.get_object_mut().set_options(options), - DemuxerObject::ImageSequence(ref mut ctx) => ctx.set_options(options), - _ => {}, - } - } - fn query_option_value(&self, name: &str) -> Option { - match *self { - DemuxerObject::Normal(ref dmx) => dmx.get_object().query_option_value(name), - DemuxerObject::Raw(ref dmx, _, _) => dmx.get_object().query_option_value(name), - DemuxerObject::ImageSequence(ref ctx) => ctx.query_option_value(name), - _ => None, - } - } -} - -pub fn detect_tags(br: &mut dyn ByteIO) -> (bool, u64, Option) { - let mut is_raw = false; - let mut start = 0; - let mut end = None; - - // check for ID3v{2-4} - let mut buf = [0; 5]; - if br.peek_buf(&mut buf).is_err() { - return (false, 0, None); - } - if &buf[0..3] == b"ID3" && buf[3] > 0 && buf[3] < 5 && buf[4] == 0 { //ID3 tag found, must be a raw stream - br.read_skip(6).unwrap(); - let mut size = 0; - for _ in 0..4 { - let b = br.read_byte().unwrap(); - if (b & 0x80) != 0 { - println!("Invalid ID3 size"); - break; - } - size = (size << 7) | u64::from(b); - } - start = size + 10; - is_raw = true; - } - // check for ID3v1 - br.seek(SeekFrom::End(-128)).unwrap(); - let off = br.tell(); - br.peek_buf(&mut buf[..3]).unwrap(); - if &buf[0..3] == b"TAG" { - end = Some(off); - } - // check for APETAG - let mut buf = [0; 8]; - if let Some(off) = end { - br.seek(SeekFrom::Start(off - 32)).unwrap(); - } else { - br.seek(SeekFrom::End(-32)).unwrap(); - } - let off = br.tell(); - br.read_buf(&mut buf).unwrap(); - if &buf == b"APETAGEX" { - let ver = br.read_u32le().unwrap(); - let size = u64::from(br.read_u32le().unwrap()); - let _items = br.read_u32le().unwrap(); - let flags = br.read_u32le().unwrap(); - if ver == 1000 || (flags & 0x80000000) == 0 { - end = Some(off - size + 32); - } else { - end = Some(off - size); - } - } - - (is_raw, start, end) -} diff --git a/src/imgseq.rs b/src/imgseq.rs deleted file mode 100644 index 90fc0e2..0000000 --- a/src/imgseq.rs +++ /dev/null @@ -1,329 +0,0 @@ -use nihav_core::frame::*; -use nihav_core::demuxers::*; -use std::fs::File; -use std::io::BufReader; -use std::io::Read; - -struct TemplateName { - prefix: String, - pad_size: usize, - suffix: String, - single: bool, -} - -trait Deescape { - fn deescape(&mut self); -} - -impl Deescape for String { - fn deescape(&mut self) { - while let Some(idx) = self.find("%%") { - self.remove(idx + 1); - } - } -} - -impl TemplateName { - fn new(name: &str) -> Self { - let mut off = 0; - let mut tmpl_start = 0; - let mut tmpl_end = 0; - let mut pad_size = 0; - 'parse_loop: - while let Some(idx) = name[off..].find('%') { - let idx = idx + off; - if idx + 1 == name.len() { - break; - } - if name[idx + 1..].starts_with('%') { // escape, skip it - off += 1; - } - if name[idx + 1..].starts_with('0') { - if let Some(end_idx) = name[idx + 2..].find('d') { - if let Ok(val) = name[idx + 2..][..end_idx].parse::() { - if val <= 32 { - tmpl_start = idx; - pad_size = val; - tmpl_end = idx + 2 + end_idx + 1; - } - } - break 'parse_loop; - } - } - if name[idx + 1..].starts_with('d') { - tmpl_start = idx; - tmpl_end = idx + 2; - break; - } - off += idx; - } - - if tmpl_end == 0 { - let mut prefix = name.to_owned(); - prefix.deescape(); - Self { - prefix, - pad_size: 0, - suffix: String::new(), - single: true, - } - } else { - let mut prefix = name[..tmpl_start].to_string(); - prefix.deescape(); - let mut suffix = name[tmpl_end..].to_string(); - suffix.deescape(); - Self { - prefix, suffix, pad_size, - single: false, - } - } - } - fn format(&self, id: T) -> String { - let mut number = id.to_string(); - while number.len() < self.pad_size { - number.insert(0, '0'); - } - let mut fname = String::with_capacity(self.prefix.len() + number.len() + self.suffix.len()); - fname.push_str(&self.prefix); - fname.push_str(&number); - fname.push_str(&self.suffix); - fname - } -} - -pub struct ImgSeqDemuxer { - pub stream: NAStreamRef, - pub sm: StreamManager, - cur_frame: u64, - template: TemplateName, - pgmyuv: bool, -} - -impl ImgSeqDemuxer { - fn new(stream: NAStreamRef, cur_frame: u64, template: TemplateName, pgmyuv: bool) -> Self { - let mut sm = StreamManager::new(); - sm.add_stream_ref(stream.clone()); - Self { - stream, sm, cur_frame, template, pgmyuv, - } - } - pub fn seek(&mut self, time: NATimePoint) -> DemuxerResult<()> { - self.cur_frame = match time { - NATimePoint::None => return Ok(()), - NATimePoint::Milliseconds(ms) => NATimeInfo::rescale_ts(ms, 1, 1000, self.stream.tb_num, self.stream.tb_den), - NATimePoint::PTS(pts) => pts, - }; - Ok(()) - } - pub fn get_frame(&mut self) -> DemuxerResult { - if self.cur_frame > 0 && self.template.single { - return Err(DemuxerError::EOF); - } - let fname = self.template.format(self.cur_frame); - if let Ok(file) = File::open(fname.as_str()) { - let mut file = BufReader::new(file); - let vinfo = read_pnm_header(&mut file, self.pgmyuv)?; - let pkt_size = if vinfo.format.model.is_yuv() && vinfo.format.components == 3 { - vinfo.width * (vinfo.height * 3 / 2) * if vinfo.format.get_max_depth() > 8 { 2 } else { 1 } - } else { - vinfo.width * vinfo.height * usize::from(vinfo.format.components) - }; - let mut buf = vec![0; pkt_size]; - file.read_exact(&mut buf).map_err(|_| DemuxerError::IOError)?; - let ts = NATimeInfo::new(Some(self.cur_frame), None, None, self.stream.tb_num, self.stream.tb_den); - let pkt = NAPacket::new(self.stream.clone(), ts, true, buf); - self.cur_frame += 1; - Ok(pkt) - } else { - Err(DemuxerError::EOF) - } - } -} - -impl NAOptionHandler for ImgSeqDemuxer { - fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } - fn set_options(&mut self, _options: &[NAOption]) {} - fn query_option_value(&self, _name: &str) -> Option { None } -} - -pub struct ImgSeqDemuxerCreator<'a> { - name: &'a str, - start: Option, - pgmyuv: bool, - tb_num: u32, - tb_den: u32, -} - -impl<'a> ImgSeqDemuxerCreator<'a> { - pub fn new(name: &'a str) -> Self { - Self { - name, - start: None, - pgmyuv: false, - tb_num: 1, - tb_den: 25, - } - } - pub fn open(&mut self) -> DemuxerResult { - let template = TemplateName::new(self.name); - - let fname = template.format(self.start.unwrap_or(0)); - - if let Ok(file) = File::open(fname.as_str()) { - let mut file = BufReader::new(file); - let vinfo = read_pnm_header(&mut file, self.pgmyuv)?; - let cinfo = NACodecInfo::new("rawvideo", NACodecTypeInfo::Video(vinfo), None); - let stream = NAStream::new(StreamType::Video, 0, cinfo, self.tb_num, self.tb_den, 0).into_ref(); - return Ok(ImgSeqDemuxer::new(stream, self.start.unwrap_or(0), template, self.pgmyuv)); - } - - // if start is not given, try also starting from one - if self.start.is_none() { - let new_start = 1; - let fname = template.format(new_start); - if let Ok(file) = File::open(fname.as_str()) { - let mut file = BufReader::new(file); - let vinfo = read_pnm_header(&mut file, self.pgmyuv)?; - let cinfo = NACodecInfo::new("rawvideo", NACodecTypeInfo::Video(vinfo), None); - let stream = NAStream::new(StreamType::Video, 0, cinfo, self.tb_num, self.tb_den, 0).into_ref(); - return Ok(ImgSeqDemuxer::new(stream, new_start, template, self.pgmyuv)); - } - } - - Err(DemuxerError::NoSuchInput) - } -} - -const IMGSEQ_OPTIONS: &[NAOptionDefinition] = &[ - NAOptionDefinition { - name: "start", description: "start frame number", - opt_type: NAOptionDefinitionType::Int(Some(0), None) }, - NAOptionDefinition { - name: "pgmyuv", description: "Input is in PGMYUV format", - opt_type: NAOptionDefinitionType::Bool }, - NAOptionDefinition { - name: "tb_num", description: "timebase numerator", - opt_type: NAOptionDefinitionType::Int(Some(1), Some(1000000)) }, - NAOptionDefinition { - name: "tb_den", description: "timebase denominator", - opt_type: NAOptionDefinitionType::Int(Some(1), Some(1000000)) }, -]; - -impl<'a> NAOptionHandler for ImgSeqDemuxerCreator<'a> { - fn get_supported_options(&self) -> &[NAOptionDefinition] { IMGSEQ_OPTIONS } - fn set_options(&mut self, options: &[NAOption]) { - for option in options.iter() { - for opt_def in IMGSEQ_OPTIONS.iter() { - if opt_def.check(option).is_ok() { - match (option.name, &option.value) { - ("start", NAValue::Int(intval)) => { - self.start = Some(*intval as u64); - }, - ("pgmyuv", NAValue::Bool(bval)) => { - self.pgmyuv = *bval; - }, - ("tb_num", NAValue::Int(intval)) => { - self.tb_num = *intval as u32; - }, - ("tb_den", NAValue::Int(intval)) => { - self.tb_den = *intval as u32; - }, - _ => {}, - } - } - } - } - } - fn query_option_value(&self, name: &str) -> Option { - match name { - "start" => Some(NAValue::Int(self.start.unwrap_or(0) as i64)), - "pgmyuv" => Some(NAValue::Bool(self.pgmyuv)), - "tb_num" => Some(NAValue::Int(self.tb_num as i64)), - "tb_den" => Some(NAValue::Int(self.tb_den as i64)), - _ => None, - } - } -} - -fn read_pnm_header(file: &mut BufReader, pgmyuv: bool) -> DemuxerResult { - let mut br = FileReader::new_read(file); - - let mut magic = [0; 2]; - br.read_buf(&mut magic)?; - if magic[0] != b'P' { return Err(DemuxerError::InvalidData); } - match magic[1] { - b'4' | // PBM, PBM ASCII - b'1' => return Err(DemuxerError::NotImplemented), - b'5' => { // PGM - }, - b'2' => return Err(DemuxerError::NotImplemented), // PGM ASCII - b'6' => { // PPM - }, - b'3' => return Err(DemuxerError::NotImplemented), // PPM ASCII - _ => return Err(DemuxerError::InvalidData), - }; - if br.read_byte()? != b'\n' { return Err(DemuxerError::InvalidData); } - let w = read_number(&mut br)?; - let h = read_number(&mut br)?; - let maxval = if matches!(magic[1], b'4' | b'1') { 1 } else { read_number(&mut br)? }; - if maxval > 65535 || (maxval & (maxval + 1)) != 0 { return Err(DemuxerError::InvalidData); } - let bits = maxval.count_ones() as u8; - - let mut vinfo = NAVideoInfo::new(w, h, false, RGB24_FORMAT); - match magic[1] { - b'5' | b'2' if !pgmyuv => { - vinfo.format = NAPixelFormaton { - model: ColorModel::YUV(YUVSubmodel::YUVJ), - components: 1, - comp_info: [Some(NAPixelChromaton{h_ss: 0, v_ss: 0, packed: false, depth: 8, shift: 0, comp_offs: 0, next_elem: 1}), None, None, None, None], - elem_size: 1, - be: true, - alpha: false, - palette: false, - }; - vinfo.bits = bits; - }, - b'5' | b'2' => { - if ((w & 1) != 0) || ((h % 3) != 0) { return Err(DemuxerError::InvalidData); } - vinfo.format = YUV420_FORMAT; - vinfo.height = h * 2 / 3; - vinfo.bits = bits * 3 / 2; - }, - b'6' | b'3' => { - vinfo.format = RGB24_FORMAT; - vinfo.bits = bits; - }, - _ => unreachable!(), - }; - if bits != 8 { - for chr in vinfo.format.comp_info.iter_mut().flatten() { - chr.depth = bits; - if bits > 8 { - chr.next_elem = 2; - } - } - if bits > 8 { - vinfo.format.elem_size <<= 1; - } - } - - Ok(vinfo) -} - -fn read_number(br: &mut dyn ByteIO) -> DemuxerResult { - let mut val = 0; - loop { - let c = br.read_byte()?; - match c { - b'0'..=b'9' => { - if val > 1048576 { - return Err(DemuxerError::InvalidData); - } - val = val * 10 + usize::from(c - b'0'); - }, - b' ' | b'\n' => break, - _ => return Err(DemuxerError::InvalidData), - }; - } - Ok(val) -} diff --git a/src/main.rs b/src/main.rs index 1dc85ef..b9bb2a0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,8 @@ use nihav_core::muxers::*; use nihav_core::reorder::*; use nihav_registry::detect; use nihav_registry::register; +use nihav_hlblocks::demux::*; +use nihav_allstuff::*; use std::env; use std::time::{Duration, Instant}; @@ -47,11 +49,9 @@ macro_rules! parse_and_apply_options { } } -mod demux; -use crate::demux::FullRegister; mod null; +use null::*; mod acvt; -mod imgseq; mod transcoder; use crate::transcoder::*; @@ -180,7 +180,15 @@ fn main() { return; } - let full_reg = FullRegister::new(); + let mut full_reg = FullRegister::new(); + nihav_register_all_demuxers(&mut full_reg.dmx_reg); + nihav_register_all_raw_demuxers(&mut full_reg.rdmx_reg); + nihav_register_all_decoders(&mut full_reg.dec_reg); + nihav_register_all_packetisers(&mut full_reg.pkt_reg); + nihav_register_all_muxers(&mut full_reg.mux_reg); + nihav_register_all_encoders(&mut full_reg.enc_reg); + full_reg.enc_reg.add_encoder(NULL_ENCODER); + full_reg.mux_reg.add_muxer(NULL_MUXER); let mut transcoder = Transcoder::new(); diff --git a/src/transcoder.rs b/src/transcoder.rs index e6d09ac..a3e3e7e 100644 --- a/src/transcoder.rs +++ b/src/transcoder.rs @@ -10,8 +10,8 @@ use nihav_core::reorder::*; use nihav_core::scale::*; use crate::acvt::*; -use crate::demux::*; -use crate::imgseq::*; +use nihav_hlblocks::demux::*; +use nihav_hlblocks::imgseqdec::*; #[derive(Clone,Copy,Debug)] pub struct EncodingProfile { @@ -1138,7 +1138,7 @@ println!("encoder {} is not supported by output (expected {})", istr.id, istr.ge let file = BufReader::new(file); let mut fr = FileReader::new_read(file); let (is_raw, start, end) = if ifmt.is_none() { - detect_tags(&mut fr) + detect_tags(&mut fr, false) } else { (false, 0, None) }; @@ -1150,7 +1150,8 @@ println!("encoder {} is not supported by output (expected {})", istr.id, istr.ge Box::new(fr) }; - let mut dmx = DemuxerObject::create(sb, full_reg, name, ifmt, is_raw, print_info); + let fformat = if let Some(ref fname) = ifmt { Some(fname.as_str()) } else { None }; + let mut dmx = DemuxerObject::create(sb, full_reg, name, fformat, is_raw, &[], print_info); if dmx.is_none() { println!("cannot find demuxer for '{}'", name); return false; -- 2.39.5