try to apply default encoder if possible
authorKostya Shishkov <kostya.shishkov@gmail.com>
Wed, 17 Nov 2021 16:51:16 +0000 (17:51 +0100)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Wed, 17 Nov 2021 17:18:38 +0000 (18:18 +0100)
src/main.rs

index fd1fdaefbc5cb5dabcb3eaa9edb76700b8d7d460..d0b8d4b117a9fe7eb26ee9632820a4fc81beb12e 100644 (file)
@@ -524,9 +524,72 @@ println!("encoder {} is not supported by output (expected {})", istr.id, istr.ge
             out_sm.add_stream_ref(istr);
             self.encoders.push(OutputMode::Copy(out_id));
         } else {
-println!("stream {} ({}) can't be handled", istr.id, istr.get_info().get_name());
-// todo autoselect encoder?
-            return false;
+            let mut oopts = OutputStreamOptions {id: out_id, enc_name: cname.to_owned(), enc_params: EncodeParameters::default(), enc_opts: Vec::new() };
+
+            let enc_create = enc_reg.find_encoder(cname);
+            if enc_create.is_none() {
+                println!("encoder '{}' not found", oopts.enc_name.as_str());
+                return false;
+            }
+            let mut encoder = (enc_create.unwrap())();
+            oopts.enc_params.format = istr.get_info().get_properties();
+            oopts.enc_params.tb_num = istr.tb_num;
+            oopts.enc_params.tb_den = istr.tb_den;
+            let ret_eparams = encoder.negotiate_format(&oopts.enc_params);
+            if ret_eparams.is_err() {
+                println!("cannot negotiate encoding parameters");
+                return false;
+            }
+            let ret_eparams = ret_eparams.unwrap();
+
+//todo check for params mismatch
+            let cvt = match (&oopts.enc_params.format, &ret_eparams.format) {
+                    (NACodecTypeInfo::Video(svinfo), NACodecTypeInfo::Video(dvinfo)) => {
+                        if svinfo == dvinfo {
+                            OutputConvert::None
+                        } else {
+                            let ofmt = ScaleInfo { fmt: dvinfo.format, width: dvinfo.width, height: dvinfo.height };
+                            let ret = NAScale::new_with_options(ofmt, ofmt, &self.scale_opts);
+                            if ret.is_err() {
+                                println!("cannot create scaler");
+                                return false;
+                            }
+                            let scaler = ret.unwrap();
+                            let ret = alloc_video_buffer(*dvinfo, 4);
+                            if ret.is_err() {
+                                println!("cannot create scaler buffer");
+                                return false;
+                            }
+                            let cvt_buf = ret.unwrap();
+                            OutputConvert::Video(scaler, cvt_buf)
+                        }
+                    },
+                    (NACodecTypeInfo::Audio(sainfo), NACodecTypeInfo::Audio(dainfo)) => {
+                        if sainfo == dainfo {
+                            OutputConvert::None
+                        } else {
+                            let dchmap = match dainfo.channels {
+                                    1 => NAChannelMap::from_ms_mapping(0x4),
+                                    2 => NAChannelMap::from_ms_mapping(0x3),
+                                    _ => {
+println!("can't generate default channel map for {} channels", dainfo.channels);
+                                        return false;
+                                    },
+                                };
+//todo channelmap
+                            OutputConvert::Audio(*dainfo, dchmap)
+                        }
+                    },
+                    _ => OutputConvert::None,
+                };
+            let ret = encoder.init(out_id, ret_eparams);
+            if ret.is_err() {
+                println!("error initialising encoder");
+                return false;
+            }
+            out_sm.add_stream_ref(ret.unwrap());
+            self.encoders.push(OutputMode::Encode(out_id, encoder, cvt));
+            self.ostr_opts.push(oopts);
         }
         true
     }