]> git.nihav.org Git - nihav-tool.git/commitdiff
switch to nihav_hlblocks demuxer core master
authorKostya Shishkov <kostya.shishkov@gmail.com>
Sat, 31 Jan 2026 14:46:38 +0000 (15:46 +0100)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Sat, 31 Jan 2026 14:46:38 +0000 (15:46 +0100)
Cargo.toml
src/demux.rs [deleted file]
src/main.rs

index 76cc06e8c342e9ec2f0a21a69c6c36d86d7bb51c..5c93afc6e2d30dfcf8f3b835a2f8f45930400d15 100644 (file)
@@ -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"]
diff --git a/src/demux.rs b/src/demux.rs
deleted file mode 100644 (file)
index adfae6f..0000000
+++ /dev/null
@@ -1,404 +0,0 @@
-use std::io::SeekFrom;
-use nihav_core::codecs::*;
-use nihav_core::demuxers::*;
-use nihav_registry::detect;
-use nihav_core::io::byteio::ByteIO;
-use nihav_allstuff::*;
-
-pub struct FullRegister {
-    pub dmx_reg:    RegisteredDemuxers,
-    pub rdmx_reg:   RegisteredRawDemuxers,
-    pub pkt_reg:    RegisteredPacketisers,
-    pub dec_reg:    RegisteredDecoders,
-}
-
-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);
-        Self { dmx_reg, rdmx_reg, pkt_reg, dec_reg }
-    }
-}
-
-pub struct RawStreamCtx<'a> {
-    stream: NAStreamRef,
-    pkt:    Box<dyn NAPacketiser + Send>,
-    br:     &'a mut dyn ByteIO,
-    pts:    u64,
-    seek:   SeekIndex,
-}
-
-impl<'a> RawStreamCtx<'a> {
-    fn new(stream: NAStreamRef, packetiser: Box<dyn NAPacketiser + Send>, br: &'a mut dyn ByteIO) -> Self {
-        let mut seek = SeekIndex::new();
-        seek.add_stream(0);
-        Self { stream, pkt: packetiser, br, pts: 0, seek }
-    }
-    fn account_for_packet(&mut self, packet: &mut NAPacket) {
-        let pos = self.br.tell() - (self.pkt.bytes_left() as u64);
-        if packet.get_pts().is_none() && packet.get_duration().is_some() {
-            packet.ts.pts = Some(self.pts);
-        }
-        if packet.is_keyframe() {
-            let pts = packet.get_pts().unwrap_or(self.pts);
-            let time = NATimeInfo::rescale_ts(pts, self.stream.tb_num, self.stream.tb_den, 1, 1000);
-            let in_range = if let Some(last) = self.seek.seek_info[0].entries.last() {
-                    last.pts >= pts
-                } else {
-                    false
-                };
-            if !in_range {
-                self.seek.add_entry(0, SeekEntry { time, pts, pos });
-            }
-        }
-        self.pts += packet.get_duration().unwrap_or(0);
-    }
-    fn get_frame(&mut self) -> DemuxerResult<NAPacket> {
-        let mut buf = [0; 1048576];
-        loop {
-            match self.pkt.get_packet(self.stream.clone()) {
-                Ok(Some(mut packet)) => {
-                    self.account_for_packet(&mut packet);
-                    return Ok(packet);
-                },
-                Ok(None) => {},
-                Err(DecoderError::ShortData) => {},
-                _ => return Err(DemuxerError::InvalidData),
-            };
-            match self.br.read_buf_some(&mut buf) {
-                Ok(size) => {
-                    self.pkt.add_data(&buf[..size]);
-                },
-                Err(_) => {
-                    match self.pkt.get_packet(self.stream.clone()) {
-                        Ok(Some(mut packet)) => {
-                            self.account_for_packet(&mut packet);
-                            return Ok(packet);
-                        },
-                        Ok(None) | Err(DecoderError::ShortData) => return Err(DemuxerError::EOF),
-                        _ => return Err(DemuxerError::InvalidData),
-                    };
-                },
-            };
-        }
-    }
-}
-
-pub enum DemuxerObject<'a> {
-    None,
-    Normal(Demuxer<'a>),
-    Raw(RawDemuxer<'a>, Vec<Option<Box<dyn NAPacketiser + Send>>>, bool),
-    RawStream(RawStreamCtx<'a>),
-}
-
-impl<'a> DemuxerObject<'a> {
-    pub fn create(br: &'a mut dyn ByteIO, reg: &FullRegister, name: &str, force_dmx: Option<&str>, is_raw: bool, opts: &[NAOption]) -> DemuxerObject<'a> {
-        if !is_raw {
-            let res = detect::detect_format(name, br);
-            if let Some(dmx_name) = force_dmx {
-                println!("forcing demuxer {} on {}", dmx_name, name);
-                if let Some(dmx_fact) = reg.dmx_reg.find_demuxer(dmx_name) {
-                    br.seek(SeekFrom::Start(0)).unwrap();
-                    let dmx = create_demuxer_with_options(dmx_fact, br, opts).unwrap();
-                    return DemuxerObject::Normal(dmx);
-                } else {
-                    return DemuxerObject::None
-                }
-            }
-            let (dmx_name, _) = res.unwrap_or(("", detect::DetectionScore::No));
-            if !dmx_name.is_empty() {
-                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 dmx = create_demuxer_with_options(dmx_fact, br, opts).unwrap();
-                    return DemuxerObject::Normal(dmx);
-                }
-            }
-            if !dmx_name.is_empty() {
-                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 dmx = create_raw_demuxer_with_options(rdmx_fact, br, opts).unwrap();
-                    let mut pkts = Vec::new();
-                    for stream in dmx.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);
-                }
-            }
-            for rdmx in reg.rdmx_reg.iter() {
-                if rdmx.check_format(br) {
-                    println!("detected {} as {}", name, rdmx.get_name());
-                    br.seek(SeekFrom::Start(0)).unwrap();
-                    let dmx = create_raw_demuxer_with_options(*rdmx, br, opts).unwrap();
-                    let mut pkts = Vec::new();
-                    for stream in dmx.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);
-                }
-            }
-        }
-        br.seek(SeekFrom::Start(0)).unwrap();
-        let mut buf = vec![0; 1048576];
-        let size = br.read_buf_some(&mut buf).unwrap();
-        br.seek(SeekFrom::Start(0)).unwrap();
-        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() {
-            println!("found raw stream of type {} for {}", pname, name);
-            let pcreate = reg.pkt_reg.find_packetiser(pname).unwrap();
-            let mut packetiser = (pcreate)();
-            packetiser.add_data(&buf[..size]);
-            let stream = packetiser.parse_stream(0).unwrap();
-            packetiser.reset();
-            DemuxerObject::RawStream(RawStreamCtx::new(stream, packetiser, br))
-        } else {
-            DemuxerObject::None
-        }
-    }
-    pub fn is_none(&self) -> bool {
-        matches!(*self, DemuxerObject::None)
-    }
-    pub fn get_duration(&self) -> u64 {
-        match *self {
-            DemuxerObject::Normal(ref dmx) => dmx.get_duration(),
-            DemuxerObject::Raw(ref dmx, _, _) => dmx.get_duration(),
-            DemuxerObject::RawStream(ref ctx) => {
-                NATimeInfo::rescale_ts(ctx.stream.duration, ctx.stream.tb_num, ctx.stream.tb_den, 1, 1000)
-            },
-            _ => 0,
-        }
-    }
-    pub fn get_num_streams(&self) -> usize {
-        match *self {
-            DemuxerObject::None => 0,
-            DemuxerObject::Normal(ref dmx) => dmx.get_num_streams(),
-            DemuxerObject::Raw(ref dmx, _, _) => dmx.get_num_streams(),
-            DemuxerObject::RawStream(_) => 1,
-        }
-    }
-    pub fn get_stream(&self, idx: usize) -> Option<NAStreamRef> {
-        match *self {
-            DemuxerObject::Normal(ref dmx) => dmx.get_stream(idx),
-            DemuxerObject::Raw(ref dmx, _, _) => dmx.get_stream(idx),
-            DemuxerObject::RawStream(ref ctx) if idx == 0 => Some(ctx.stream.clone()),
-            _ => None,
-        }
-    }
-    pub fn get_frame(&mut self) -> DemuxerResult<NAPacket> {
-        match *self {
-            DemuxerObject::Normal(ref mut dmx) => dmx.get_frame(),
-            DemuxerObject::Raw(ref mut dmx, ref mut packetisers, ref mut eof) => {
-                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) => ctx.get_frame(),
-            _ => unreachable!(),
-        }
-    }
-    pub fn seek(&mut self, seek_time: NATimePoint) -> DemuxerResult<()> {
-        match *self {
-            DemuxerObject::Normal(ref mut dmx) => dmx.seek(seek_time),
-            DemuxerObject::Raw(ref mut dmx, _, _) => dmx.seek(seek_time),
-            DemuxerObject::RawStream(ref mut ctx) => {
-                if seek_time == NATimePoint::None {
-                    return Err(DemuxerError::SeekError);
-                }
-                if let Some(last) = ctx.seek.seek_info[0].entries.last() {
-                    let in_index = match seek_time {
-                            NATimePoint::None => unreachable!(),
-                            NATimePoint::PTS(pts) => last.pts >= pts,
-                            NATimePoint::Milliseconds(ms) => last.time >= ms,
-                        };
-                    if in_index {
-                        if let Some(result) = ctx.seek.find_pos(seek_time) {
-                            ctx.br.seek(SeekFrom::Start(result.pos))?;
-                            ctx.pts = result.pts;
-                            ctx.pkt.reset();
-                            return Ok(());
-                        }
-                    }
-                }
-                if let Some(last) = ctx.seek.seek_info[0].entries.last() {
-                    ctx.br.seek(SeekFrom::Start(last.pos))?;
-                    ctx.pts = last.pts;
-                    ctx.pkt.reset();
-                }
-                let mut key_pts = 0;
-                while let Ok(pkt) = ctx.get_frame() {
-                    if !pkt.ts.less_than(seek_time) && !pkt.ts.equal(seek_time) {
-                        break;
-                    }
-                    if pkt.is_keyframe() {
-                        key_pts = pkt.get_pts().unwrap_or(0);
-                    }
-                }
-                let result = ctx.seek.find_pos(NATimePoint::PTS(key_pts)).unwrap();
-                ctx.br.seek(SeekFrom::Start(result.pos))?;
-                ctx.pts = result.pts;
-                ctx.pkt.reset();
-                Ok(())
-            },
-            _ => Err(DemuxerError::NotImplemented),
-        }
-    }
-}
-
-pub fn detect_tags(br: &mut dyn ByteIO) -> (bool, u64, Option<u64>) {
-    let mut is_raw = false;
-    let mut start = 0;
-    let mut end = None;
-
-    // check for ID3v{2-4}
-    let mut buf = [0; 5];
-    loop {
-        if br.peek_buf(&mut buf).is_err() {
-            break;
-        }
-        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;
-            br.read_skip(size as usize).unwrap();
-            while let Ok(0) = br.read_byte() {
-                start += 1;
-            }
-            br.seek(SeekFrom::Start(start)).unwrap();
-            is_raw = true;
-        } else {
-            break;
-        }
-    }
-    // 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 Lyrics v2
-        let mut sig = [0; 9];
-        br.seek(SeekFrom::End(-128 - 9)).unwrap();
-        br.peek_buf(&mut sig).unwrap();
-        if &sig == b"LYRICS200" {
-            br.seek(SeekFrom::Current(-6)).unwrap();
-            let mut sizestr = [0; 6];
-            br.peek_buf(&mut sizestr).unwrap();
-            if let Ok(sstr) = std::str::from_utf8(&sizestr) {
-                if let Ok(size) = sstr.parse::<u64>() {
-                    end = Some(br.tell() - size);
-                }
-            }
-        }
-    }
-    // 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);
-        }
-    }
-    // check for MusicMatch tag
-    let ret = if let Some(endpos) = end {
-            br.seek(SeekFrom::Start(endpos - 0x30))
-        } else {
-            br.seek(SeekFrom::End(-0x30))
-        };
-    if ret.is_ok() && br.tell() > (0x2000 - 0x30) {
-        let mut buf = [0; 19];
-        br.peek_buf(&mut buf).unwrap();
-        if &buf == b"Brava Software Inc." {
-            br.seek(SeekFrom::Current(-20)).unwrap();
-            let mut mm_start = u64::from(br.read_u32le().unwrap());
-            if mm_start > 4 && mm_start + 0x2000 <= br.tell() {
-                let diff = (br.tell() - mm_start) & 3;
-                if diff != 0 {
-                    mm_start -= 4 - diff;
-                }
-                end = Some(mm_start);
-            }
-        }
-    }
-
-    (is_raw, start, end)
-}
index 71031b66957004d5ef456997a7c7b7087526a29b..c32d7c22a4c0133b3e255972fed2135ec4995a9d 100644 (file)
@@ -11,9 +11,9 @@ use nihav_core::codecs::*;
 use nihav_core::demuxers::*;
 use nihav_codec_support::imgwrite::*;
 use std::env;
+use nihav_hlblocks::demux::*;
+use nihav_allstuff::*;
 
-mod demux;
-use demux::*;
 mod wavwriter;
 use crate::wavwriter::WavWriter;
 
@@ -179,9 +179,9 @@ fn main() {
     let file = File::open(path).unwrap();
     let file = BufReader::new(file);
     let mut fr = FileReader::new_read(file);
-    let (is_raw, start, end) = detect_tags(&mut fr);
+    let (is_raw, start, end) = detect_tags(&mut fr, true);
 
-    let mut br: Box<dyn ByteIO>;
+    let br: Box<dyn ByteIO>;
     if start != 0 || end.is_some() {
         println!(" limiting range to {:X}-{:X}", start, end.unwrap_or(0));
         let file = fr.finish();
@@ -189,8 +189,13 @@ fn main() {
     } else {
         br = Box::new(fr);
     }
-    let full_reg = FullRegister::new();
-    let mut demuxer = DemuxerObject::create(br.as_mut(), &full_reg, name, force_dmx, is_raw, &demux_opts);
+    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);
+
+    let mut demuxer = DemuxerObject::create(br, &full_reg, name, force_dmx, is_raw, &demux_opts, true);
     if demuxer.is_none() {
         println!("No demuxer found!");
         return;