+ fn create_demuxers(&mut self, demuxers: &mut Vec<(DemuxerObject, bool)>, full_reg: &FullRegister, print_info: bool) -> bool {
+ let mut isn_start = 0;
+ for (i, (iname, ifmt)) in self.input_name.iter().zip(
+ self.input_fmt.iter()).enumerate() {
+ match (iname, ifmt.as_ref().map(|s| s.as_str())) {
+ (Some(name), Some("imgseq")) => {
+ println!("trying image sequence {}", name);
+ let mut isdc = ImgSeqDemuxerCreator::new(name.as_str());
+ parse_and_apply_options!(isdc, &self.demux_opts[i], "input");
+ let isd = if let Ok(ctx) = isdc.open() {
+ ctx
+ } else {
+ println!("failed to create image sequence demuxer!");
+ return false;
+ };
+ let dmx = DemuxerObject::create_imgseq(isd);
+ if print_info {
+ for i in 0..dmx.get_num_streams() {
+ let s = dmx.get_stream(i).unwrap();
+ let info = s.get_info();
+ println!(" stream {}({}) - {} {}", i, i + isn_start, s, info.get_name());
+ }
+ }
+ isn_start += dmx.get_num_streams();
+ demuxers.push((dmx, false))
+ },
+ (Some(name), _) => {
+ let res = File::open(name);
+ if res.is_err() {
+ println!("error opening input");
+ return false;
+ }
+ let file = res.unwrap();
+ let file = BufReader::new(file);
+ let mut fr = FileReader::new_read(file);
+ let mut br = ByteReader::new(&mut fr);
+ let (is_raw, start, end) = if ifmt.is_none() {
+ detect_tags(&mut br)
+ } else {
+ (false, 0, None)
+ };
+
+ let nfr: Box<dyn ByteIO> = if start != 0 || end.is_some() {
+ let file = fr.finish();
+ Box::new(BoundedFileReader::new_read(file, start, end).unwrap())
+ } else {
+ Box::new(fr)
+ };
+ let sb = SelfBorrow::new(nfr, |rd| {
+ unsafe {
+ ByteReader::new(rd.as_mut().unwrap().as_mut())
+ }
+ });
+
+ let mut dmx = DemuxerObject::create(sb, full_reg, name, ifmt, is_raw, print_info);
+ if dmx.is_none() {
+ println!("cannot find demuxer for '{}'", name);
+ return false;
+ }
+ parse_and_apply_options!(dmx, &self.demux_opts[i], "input");
+ if print_info {
+ for i in 0..dmx.get_num_streams() {
+ let s = dmx.get_stream(i).unwrap();
+ let info = s.get_info();
+ println!(" stream {}({}) - {} {}", i, i + isn_start, s, info.get_name());
+ }
+ }
+ isn_start += dmx.get_num_streams();
+ demuxers.push((dmx, false));
+ },
+ _ => {},
+ };
+ }
+ true
+ }
+}
+
+fn encode_frame(dst_id: u32, encoder: &mut Box<dyn NAEncoder>, cvt: &mut OutputConvert, frm: NAFrameRef, scale_opts: &[(String, String)]) -> bool {
+ let buf = frm.get_buffer();
+ let cbuf = if let NABufferType::None = buf {
+ if (encoder.get_capabilities() & ENC_CAPS_SKIPFRAME) == 0 {
+ match cvt {
+ OutputConvert::Video(_, ref mut dbuf) => dbuf.clone(),
+ _ => {
+ println!("encoder does not support skip frames, skipping");
+ return true;
+ },
+ }
+ } else {
+ buf
+ }
+ } else {
+ match cvt {
+ OutputConvert::None => buf,
+ OutputConvert::Video(ref mut scaler, ref mut dbuf) => {
+ let cur_ifmt = get_scale_fmt_from_pic(&buf);
+ let last_ifmt = scaler.get_in_fmt();
+ if cur_ifmt != last_ifmt {
+ let ofmt = scaler.get_out_fmt();
+ let ret = NAScale::new_with_options(cur_ifmt, ofmt, scale_opts);
+ if ret.is_err() {
+ println!("error re-initialising scaler for {} -> {}", cur_ifmt, ofmt);
+ return false;
+ }
+ *scaler = ret.unwrap();
+ }
+ let ret = scaler.convert(&buf, dbuf);
+ if ret.is_err() {
+ println!("error converting frame for encoding");
+ return false;
+ }
+ dbuf.clone()
+ },
+ OutputConvert::Audio(ref mut acvt) => {
+ if !acvt.queue_frame(buf, frm.get_time_information()) {
+ println!("error converting audio for stream {}", dst_id);
+ return false;
+ }
+ return true;
+ },
+ }
+ };
+ let cfrm = NAFrame::new(frm.get_time_information(), frm.frame_type, frm.key, frm.get_info(), cbuf);
+ encoder.encode(&cfrm).unwrap();
+ true