]> git.nihav.org Git - nihav-encoder.git/blobdiff - src/main.rs
whitespace fix
[nihav-encoder.git] / src / main.rs
index ff19ae151f4eebed8f9bb64f20cf34f2a57aed5c..97be1e2ea36367b6b833a1b61f5134cc5a5619da 100644 (file)
@@ -23,6 +23,10 @@ use crate::demux::*;
 mod null;
 mod acvt;
 use crate::acvt::*;
+mod imgseq;
+use crate::imgseq::*;
+
+const SND_NO_FORMAT: NASoniton = NASoniton { bits: 0, be: false, packed: false, planar: false, float: false, signed: false };
 
 fn format_time(ms: u64) -> String {
     let s = ms / 1000;
@@ -148,7 +152,7 @@ macro_rules! parse_and_apply_options {
                     matches = name == opt_def.name;
                 }
                 if matches {
-                    let arg = if let Some(ref str) = opt.value { Some(str) } else { None };
+                    let arg = if let Some(ref strval) = opt.value { Some(strval) } else { None };
                     let ret = opt_def.parse(&opt.name, arg);
                     if let Ok((val, _)) = ret {
                         opts.push(val);
@@ -174,7 +178,7 @@ impl Transcoder {
         if ret.is_err() { return false; }
         let streamno = ret.unwrap();
 
-        let sidx = if let Some(idx) = self.istr_opts.iter().position(|str| str.id == streamno) {
+        let sidx = if let Some(idx) = self.istr_opts.iter().position(|el| el.id == streamno) {
                 idx
             } else {
                 self.istr_opts.push(InputStreamOptions {id: streamno, drop: false, dec_opts: Vec::new() });
@@ -205,7 +209,7 @@ impl Transcoder {
         if ret.is_err() { return false; }
         let streamno = ret.unwrap();
 
-        let sidx = if let Some(idx) = self.ostr_opts.iter().position(|str| str.id == streamno) {
+        let sidx = if let Some(idx) = self.ostr_opts.iter().position(|el| el.id == streamno) {
                 idx
             } else {
                 self.ostr_opts.push(OutputStreamOptions {id: streamno, enc_name: String::new(), enc_params: EncodeParameters::default(), enc_opts: Vec::new() });
@@ -316,7 +320,7 @@ impl Transcoder {
                     },
                     "srate" => {
                         if ostr.enc_params.format == NACodecTypeInfo::None {
-                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_S16_FORMAT, 0));
+                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_NO_FORMAT, 0));
                         }
                         if let NACodecTypeInfo::Audio(ref mut ainfo) = ostr.enc_params.format {
                             let ret = oval[1].parse::<u32>();
@@ -331,7 +335,7 @@ impl Transcoder {
                     },
                     "channels" => {
                         if ostr.enc_params.format == NACodecTypeInfo::None {
-                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_S16_FORMAT, 0));
+                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_NO_FORMAT, 0));
                         }
                         if let NACodecTypeInfo::Audio(ref mut ainfo) = ostr.enc_params.format {
                             let ret = oval[1].parse::<u8>();
@@ -346,7 +350,7 @@ impl Transcoder {
                     },
                     "block_len" => {
                         if ostr.enc_params.format == NACodecTypeInfo::None {
-                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_S16_FORMAT, 0));
+                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_NO_FORMAT, 0));
                         }
                         if let NACodecTypeInfo::Audio(ref mut ainfo) = ostr.enc_params.format {
                             let ret = oval[1].parse::<usize>();
@@ -361,7 +365,7 @@ impl Transcoder {
                     },
                     "sfmt" => {
                         if ostr.enc_params.format == NACodecTypeInfo::None {
-                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_S16_FORMAT, 0));
+                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_NO_FORMAT, 0));
                         }
                         if let NACodecTypeInfo::Audio(ref mut ainfo) = ostr.enc_params.format {
                             let ret = oval[1].parse::<NASoniton>();
@@ -377,7 +381,7 @@ impl Transcoder {
 // todo channel map negotiation
                     /*"chmap" => {
                         if ostr.enc_params.format == NACodecTypeInfo::None {
-                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_S16_FORMAT, 0));
+                            ostr.enc_params.format = NACodecTypeInfo::Audio(NAAudioInfo::new(0, 0, SND_NO_FORMAT, 0));
                         }
                         if let NACodecTypeInfo::Audio(ref mut ainfo) = ostr.enc_params.format {
                             let ret = oval[1].parse::<NAChannelMap>();
@@ -473,7 +477,7 @@ impl Transcoder {
         true
     }
     fn apply_decoder_options(&self, dec: &mut dyn NADecoder, str_id: u32) {
-        if let Some(str_idx) = self.istr_opts.iter().position(|str| str.id == str_id) {
+        if let Some(str_idx) = self.istr_opts.iter().position(|el| el.id == str_id) {
             let dec_opts = dec.get_supported_options();
             if dec_opts.is_empty() { return; }
             let name = format!("input stream {}", str_id);
@@ -482,14 +486,14 @@ impl Transcoder {
     }
     fn register_output_stream(&mut self, cname: &str, istr: NAStreamRef, out_sm: &mut StreamManager, enc_reg: &RegisteredEncoders) -> bool {
         let out_id = out_sm.get_num_streams() as u32;
-        if let Some(str_idx) = self.istr_opts.iter().position(|str| str.id == (istr.get_num() as u32)) {
+        if let Some(str_idx) = self.istr_opts.iter().position(|el| el.id == (istr.get_num() as u32)) {
             if self.istr_opts[str_idx].drop {
                 self.encoders.push(OutputMode::Drop);
                 return true;
             }
         }
 
-        if let Some(str_idx) = self.ostr_opts.iter().position(|str| str.id == out_id) {
+        if let Some(str_idx) = self.ostr_opts.iter().position(|el| el.id == out_id) {
             let oopts = &mut self.ostr_opts[str_idx];
             if oopts.enc_name.as_str() == "copy" && (cname == "any" || istr.get_info().get_name() == cname) {
                 out_sm.add_stream_ref(istr);
@@ -502,8 +506,35 @@ impl Transcoder {
                 }
                 let mut encoder = (enc_create.unwrap())();
                 let forced_out = oopts.enc_params.format != NACodecTypeInfo::None;
+                let iformat = istr.get_info().get_properties();
                 if oopts.enc_params.format == NACodecTypeInfo::None {
                     oopts.enc_params.format = istr.get_info().get_properties();
+                } else {
+                    match (&iformat, &mut oopts.enc_params.format) {
+                        (NACodecTypeInfo::Video(svinfo), NACodecTypeInfo::Video(ref mut dvinfo)) => {
+                            if dvinfo.width == 0 {
+                                dvinfo.width = svinfo.width;
+                            }
+                            if dvinfo.height == 0 {
+                                dvinfo.height = svinfo.height;
+                            }
+                        },
+                        (NACodecTypeInfo::Audio(sainfo), NACodecTypeInfo::Audio(ref mut dainfo)) => {
+                            if dainfo.sample_rate == 0 {
+                                dainfo.sample_rate = sainfo.sample_rate;
+                            }
+                            if dainfo.format == SND_NO_FORMAT {
+                                dainfo.format = sainfo.format;
+                            }
+                            if dainfo.channels == 0 {
+                                dainfo.channels = sainfo.channels;
+                            }
+                            if dainfo.block_len == 0 {
+                                dainfo.block_len = sainfo.block_len;
+                            }
+                        },
+                        _ => {},
+                    };
                 }
                 if oopts.enc_params.tb_num == 0 {
                     oopts.enc_params.tb_num = istr.tb_num;
@@ -517,7 +548,7 @@ impl Transcoder {
                 let ret_eparams = ret_eparams.unwrap();
 
 //todo check for params mismatch
-                let cvt = match (&oopts.enc_params.format, &ret_eparams.format) {
+                let cvt = match (&iformat, &ret_eparams.format) {
                         (NACodecTypeInfo::Video(svinfo), NACodecTypeInfo::Video(dvinfo)) => {
                             if svinfo == dvinfo && !forced_out {
                                 OutputConvert::None
@@ -743,10 +774,16 @@ fn encode_frame(dst_id: u32, encoder: &mut Box<dyn NAEncoder>, cvt: &mut OutputC
     let buf = frm.get_buffer();
     let cbuf = if let NABufferType::None = buf {
         if (encoder.get_capabilities() & ENC_CAPS_SKIPFRAME) == 0 {
-            println!("encoder does not support skip frames, skipping");
-            return true;
+            match cvt {
+                OutputConvert::Video(_, ref mut dbuf) => dbuf.clone(),
+                _ => {
+                    println!("encoder does not support skip frames, skipping");
+                    return true;
+                },
+            }
+        } else {
+            buf
         }
-        buf
     } else {
         match cvt {
             OutputConvert::None => buf,
@@ -1033,6 +1070,20 @@ fn main() {
         return;
     }
 
+    if let Some("imgseq") = transcoder.input_fmt.as_deref() {
+        let mut isdc = ImgSeqDemuxerCreator::new(transcoder.input_name.as_str());
+        parse_and_apply_options!(isdc, &transcoder.demux_opts, "input");
+        let isd = if let Ok(ctx) = isdc.open() {
+                ctx
+            } else {
+                println!("failed to create image sequence demuxer!");
+                return;
+            };
+        let mut dmx = DemuxerObject::create_imgseq(isd);
+        transcode(transcoder, full_reg, &mut dmx);
+        return;
+    }
+
     let res = File::open(transcoder.input_name.as_str());
     if res.is_err() {
         println!("error opening input");
@@ -1062,10 +1113,14 @@ fn main() {
         println!("cannot find demuxer for '{}'", transcoder.input_name.as_str());
         return;
     }
+    parse_and_apply_options!(dmx, &transcoder.demux_opts, "input");
+    transcode(transcoder, full_reg, &mut dmx);
+}
+
+fn transcode(mut transcoder: Transcoder, full_reg: FullRegister, dmx: &mut DemuxerObject) {
     let duration = dmx.get_duration();
     let duration_string = if duration != 0 { format_time(duration) } else { String::new() };
 
-    parse_and_apply_options!(dmx, &transcoder.demux_opts, "input");
     for i in 0..dmx.get_num_streams() {
         let s = dmx.get_stream(i).unwrap();
         let info = s.get_info();
@@ -1102,10 +1157,12 @@ println!("stream {} - {} {}", i, s, info.get_name());
         }
     }
 
-    let output_fmt = if let Some(ref str) = transcoder.output_fmt {
-            str
-        } else if let Some(str) = detect::detect_format_by_name(transcoder.output_name.as_str()) {
-            str
+    let output_fmt = if let Some(ref fmtname) = transcoder.output_fmt {
+            fmtname
+        } else if transcoder.output_name.as_str() == "/dev/null" {
+            "null"
+        } else if let Some(fmtname) = detect::detect_format_by_name(transcoder.output_name.as_str()) {
+            fmtname
         } else {
             println!("Cannot guess muxer for output");
             return;
@@ -1241,8 +1298,8 @@ println!("stream {} - {} {}", i, s, info.get_name());
             },
         };
     }
-    'reord_flush_loop: for str in dmx.get_streams() {
-        let src_id = str.get_num();
+    'reord_flush_loop: for stream in dmx.get_streams() {
+        let src_id = stream.get_num();
         if let OutputMode::Encode(dst_id, ref mut encoder, ref mut cvt) = transcoder.encoders[src_id] {
             if let Some((_, _, ref mut reorderer)) = transcoder.decoders[src_id] {
                 while let Some(frm) = reorderer.get_last_frames() {