1use tracing::debug;
2use wedeo_core::error::{Error, Result};
3use wedeo_core::metadata::Metadata;
4use wedeo_core::packet::Packet;
5
6use crate::demuxer::{Demuxer, ProbeData, SeekFlags, Stream};
7use crate::io::{BufferedIo, FileIo};
8use crate::muxer::Muxer;
9use crate::registry;
10
11pub struct InputContext {
13 demuxer: Box<dyn Demuxer>,
14 io: BufferedIo,
15 pub streams: Vec<Stream>,
16 pub metadata: Metadata,
17 pub duration: i64,
18 pub start_time: i64,
19}
20
21impl InputContext {
22 pub fn open(path: &str) -> Result<Self> {
24 let file_io = FileIo::open(path)?;
25 let mut io = BufferedIo::new(Box::new(file_io));
26
27 let file_size = io.size().unwrap_or(4096);
29 let probe_size = file_size.min(4096) as usize;
30 let probe_buf = io.read_bytes(probe_size)?;
31 io.seek(0)?;
32
33 let probe_data = ProbeData {
34 filename: path,
35 buf: &probe_buf,
36 };
37
38 let factory = registry::probe(&probe_data).ok_or(Error::DemuxerNotFound)?;
39
40 let mut demuxer = factory.create()?;
41 let header = demuxer.read_header(&mut io)?;
42
43 let format_name = factory.descriptor().name;
44 debug!(
45 path,
46 format = format_name,
47 streams = header.streams.len(),
48 "InputContext opened"
49 );
50
51 Ok(Self {
52 demuxer,
53 io,
54 streams: header.streams,
55 metadata: header.metadata,
56 duration: header.duration,
57 start_time: header.start_time,
58 })
59 }
60
61 pub fn read_packet(&mut self) -> Result<Packet> {
63 self.demuxer.read_packet(&mut self.io)
64 }
65
66 pub fn seek(&mut self, stream_index: usize, timestamp: i64, flags: SeekFlags) -> Result<()> {
68 self.demuxer
69 .seek(&mut self.io, stream_index, timestamp, flags)
70 }
71
72 pub fn stream(&self, index: usize) -> Option<&Stream> {
74 self.streams.get(index)
75 }
76
77 pub fn nb_streams(&self) -> usize {
79 self.streams.len()
80 }
81}
82
83pub struct OutputContext {
85 muxer: Box<dyn Muxer>,
86 io: BufferedIo,
87}
88
89impl OutputContext {
90 pub fn create(path: &str, format_name: &str, streams: &[Stream]) -> Result<Self> {
92 let factory = registry::find_muxer_by_name(format_name).ok_or(Error::MuxerNotFound)?;
93 let mut muxer = factory.create()?;
94 let file_io = FileIo::create(path)?;
95 let mut io = BufferedIo::new(Box::new(file_io));
96 muxer.write_header(&mut io, streams)?;
97 Ok(Self { muxer, io })
98 }
99
100 pub fn write_packet(&mut self, packet: &Packet) -> Result<()> {
102 self.muxer.write_packet(&mut self.io, packet)
103 }
104
105 pub fn finish(mut self) -> Result<()> {
107 self.muxer.write_trailer(&mut self.io)?;
108 self.io.flush()
109 }
110}