From 7cf41b8709074694a795ecc784a87dc9e9c5589f Mon Sep 17 00:00:00 2001 From: Rafael Caricio Date: Wed, 12 May 2021 21:41:20 +0200 Subject: [PATCH] Fix issue when handling pad creation --- src/imp.rs | 41 +++++++------ tests/flexhlssink.rs | 140 +++++++++++++++++++++++++++++++------------ 2 files changed, 126 insertions(+), 55 deletions(-) diff --git a/src/imp.rs b/src/imp.rs index eefd3ba..fa6d7e0 100644 --- a/src/imp.rs +++ b/src/imp.rs @@ -1,7 +1,7 @@ use glib::subclass::prelude::*; use gst::prelude::*; use gst::subclass::prelude::*; -use gst::{gst_debug, gst_error, gst_info}; +use gst::{gst_debug, gst_error, gst_info, gst_trace}; use crate::playlist::PlaylistRenderState; use m3u8_rs::playlist::{MediaPlaylist, MediaPlaylistType, MediaSegment}; @@ -116,6 +116,11 @@ impl FlexHlsSink { let segment_file_location = settings .location .replace(BACKWARDS_COMPATIBLE_PLACEHOLDER, &seq_num); + gst_trace!( + CAT, + "Segment location formatted: {}", + segment_file_location + ); let segment_file_location_clone = segment_file_location.clone(); let segment_file = File::create(&segment_file_location).map_err(move |err| { @@ -130,7 +135,7 @@ impl FlexHlsSink { *current_segment_location = Some(segment_file_location); *current_segment_file = Some(segment_file); - gst_debug!( + gst_info!( CAT, "New segment location: {}", current_segment_location.as_ref().unwrap() @@ -509,9 +514,12 @@ impl ObjectImpl for FlexHlsSink { .connect("format-location", false, move |args| { let fragment_id = args[1].get::().unwrap(); + gst_info!(CAT, "Got fragment-id: {}", fragment_id); + if let Err(err) = this.on_format_location(fragment_id) { gst_error!(CAT, "on format-location handler: {}", err); } + None }) .unwrap(); @@ -638,11 +646,11 @@ impl ElementImpl for FlexHlsSink { &self, element: &Self::Type, templ: &gst::PadTemplate, - name: Option, + _name: Option, caps: Option<&gst::Caps>, ) -> Option { let mut settings = self.settings.lock().unwrap(); - match name.as_ref().map(|val| val.as_str()) { + match templ.name_template().as_ref().map(|val| val.as_str()) { Some("audio") => { if settings.audio_sink { gst_debug!( @@ -652,17 +660,15 @@ impl ElementImpl for FlexHlsSink { ); return None; } - gst_info!(CAT, "creating the audio pad"); let splitmuxsink = match &mut settings.splitmuxsink { None => return None, Some(sms) => sms, }; let peer_pad = splitmuxsink.request_pad_simple("audio_0").unwrap(); - println!("Peer pad caps: {:?}", peer_pad.allowed_caps()); let sink_pad = gst::GhostPad::from_template_with_target(&templ, Some("audio"), &peer_pad).unwrap(); - sink_pad.set_active(true).unwrap(); element.add_pad(&sink_pad).unwrap(); + sink_pad.set_active(true).unwrap(); settings.audio_sink = true; Some(sink_pad.upcast()) @@ -676,26 +682,27 @@ impl ElementImpl for FlexHlsSink { ); return None; } - let peer_pad_name = "video"; - let pad_name = "video"; - let splitmuxsink = match &mut settings.splitmuxsink { None => return None, Some(sms) => sms, }; - let peer_pad = match splitmuxsink.request_pad_simple(peer_pad_name) { - None => return None, - Some(pad) => pad, - }; - let sink_pad = gst::GhostPad::from_template_with_target(&templ, Some(pad_name), &peer_pad).unwrap(); - sink_pad.set_active(true).unwrap(); + let peer_pad = splitmuxsink.request_pad_simple("video").unwrap(); + let sink_pad = gst::GhostPad::from_template_with_target(&templ, Some("video"), &peer_pad).unwrap(); element.add_pad(&sink_pad).unwrap(); + sink_pad.set_active(true).unwrap(); settings.video_sink = true; Some(sink_pad.upcast()) } - None => None, + None => { + gst_debug!( + CAT, + obj: element, + "template name returned `None`", + ); + None + }, Some(other_name) => { gst_debug!( CAT, diff --git a/tests/flexhlssink.rs b/tests/flexhlssink.rs index 4260ccc..e233c89 100644 --- a/tests/flexhlssink.rs +++ b/tests/flexhlssink.rs @@ -23,6 +23,76 @@ fn init() { }); } +#[test] +fn test_basic_element_with_video_content() { + init(); + + const BUFFER_NB: i32 = 3; + + let pipeline = gst::Pipeline::new(Some("video_pipeline")); + + let video_src = gst::ElementFactory::make("videotestsrc", Some("videotestsrc")).unwrap(); + video_src.set_property("is-live", &true).unwrap(); + video_src.set_property("num-buffers", &BUFFER_NB).unwrap(); + + let x264enc= gst::ElementFactory::make("x264enc", Some("x264enc")).unwrap(); + let h264parse = gst::ElementFactory::make("h264parse", Some("h264parse")).unwrap(); + + let flexhlssink = gst::ElementFactory::make("flexhlssink", Some("flexhlssink")).unwrap(); + flexhlssink.set_property("target-duration", &6u32).unwrap(); + + // let app_sink = gst::ElementFactory::make("appsink", Some("appsink")).unwrap(); + // app_sink.set_property("sync", &false).unwrap(); + // app_sink.set_property("async", &false).unwrap(); + // app_sink.set_property("emit-signals", &true).unwrap(); + + pipeline + .add_many(&[ + &video_src, + &x264enc, + &h264parse, + //&app_sink + &flexhlssink, + ]) + .unwrap(); + + gst::Element::link_many(&[ + &video_src, + &x264enc, + &h264parse, + &flexhlssink, + ]).unwrap(); + + // let appsink = app_sink.dynamic_cast::().unwrap(); + // let (sender, receiver) = mpsc::channel(); + // appsink.connect_new_sample(move |appsink| { + // let _sample = appsink + // .emit_by_name("pull-sample", &[]) + // .unwrap() + // .unwrap() + // .get::() + // .unwrap(); + // + // sender.send(()).unwrap(); + // Ok(gst::FlowSuccess::Ok) + // }); + + pipeline.set_state(gst::State::Playing).unwrap(); + // + // gst_info!( + // CAT, + // "flexhlssink_video_pipeline: waiting for {} buffers", + // BUFFER_NB + // ); + // for idx in 0..BUFFER_NB { + // receiver.recv().unwrap(); + // gst_info!(CAT, "flexhlssink_video_pipeline: received buffer #{}", idx); + // } + + pipeline.set_state(gst::State::Null).unwrap(); +} + + #[test] fn test_basic_element_properties() { init(); @@ -35,18 +105,17 @@ fn test_basic_element_properties() { audio_src.set_property("is-live", &true).unwrap(); audio_src.set_property("num-buffers", &BUFFER_NB).unwrap(); - let decodebin = gst::ElementFactory::make("decodebin", Some("decodebin_base")).unwrap(); - let video_src = gst::ElementFactory::make("videotestsrc", Some("videotestsrc")).unwrap(); - video_src.set_property("is-live", &true).unwrap(); - video_src.set_property("num-buffers", &BUFFER_NB).unwrap(); - - let audio_convert = gst::ElementFactory::make("audioconvert", Some("audioconvert")).unwrap(); + // let video_src = gst::ElementFactory::make("videotestsrc", Some("videotestsrc")).unwrap(); + // video_src.set_property("is-live", &true).unwrap(); + // video_src.set_property("num-buffers", &BUFFER_NB).unwrap(); let tee = gst::ElementFactory::make("tee", Some("tee")).unwrap(); let hls_queue = gst::ElementFactory::make("queue", Some("hls_queue")).unwrap(); - let hls_audio_convert = gst::ElementFactory::make("audioconvert", Some("hls_audioconvert")).unwrap(); + // let decodebin = gst::ElementFactory::make("decodebin", Some("decodebin_base")).unwrap(); + // let audio_convert = gst::ElementFactory::make("audioconvert", Some("audioconvert")).unwrap(); + let hls_avenc_aac = gst::ElementFactory::make("avenc_aac", Some("hls_avenc_aac")).unwrap(); let flexhlssink = gst::ElementFactory::make("flexhlssink", Some("flexhlssink")).unwrap(); flexhlssink.set_property("target-duration", &6u32).unwrap(); @@ -63,19 +132,21 @@ fn test_basic_element_properties() { &app_queue, &app_sink, &hls_queue, - &decodebin, - &audio_convert, - // &hls_audio_convert, + //&decodebin, + //&audio_convert, + &hls_avenc_aac, &flexhlssink, ]) .unwrap(); gst::Element::link_many(&[&audio_src, &tee]).unwrap(); gst::Element::link_many(&[&app_queue, &app_sink]).unwrap(); - gst::Element::link_many(&[&hls_queue, &decodebin]).unwrap(); + gst::Element::link_many(&[&hls_queue, &hls_avenc_aac, &flexhlssink]).unwrap(); + // gst::Element::link_many(&[&audio_convert, &flexhlssink]).unwrap(); + // gst::Element::link_many(&[&hls_queue, &decodebin, &audio_convert, &flexhlssink]).unwrap(); // hls_queue.link_pads(Some("src"), &hls_audio_convert, Some("sink")).unwrap(); - // audio_convert.link_pads(Some("src"), &flexhlssink, Some("audio")).unwrap(); + // audio_convert.link_pads(Some("src"), , Some("audio")).unwrap(); // Link the appsink let tee_app_pad = tee.request_pad_simple("src_%u").unwrap(); @@ -94,32 +165,25 @@ fn test_basic_element_properties() { ); let hls_queue_pad = hls_queue.static_pad("sink").unwrap(); tee_hls_pad.link(&hls_queue_pad).unwrap(); - - // Link the queue to flexhlssink to link on audio - // let audio_convert_pad = audio_convert.static_pad("src").unwrap(); - // println!( - // "Obtained request pad {} for the flex HLS sink", - // audio_convert_pad.name() - // ); - // let hls_audio_pad = flexhlssink.request_pad_simple("audio").unwrap(); - // audio_convert_pad.link(&hls_audio_pad).unwrap(); - - let audio_convert_clone = audio_convert.clone(); - let flexhlssink_clone = flexhlssink.clone(); - decodebin.connect_pad_added(move |_, pad| { - let caps = pad.current_caps().unwrap(); - let s = caps.structure(0).unwrap(); - - let audio_convert_sink_pad = audio_convert_clone.static_pad("sink").unwrap(); - - if s.name() == "audio/x-raw" && !audio_convert_sink_pad.is_linked() { - pad.link(&audio_convert_sink_pad).unwrap(); - - let audio_convert_src_pad = audio_convert_clone.static_pad("src").unwrap(); - let hls_audio_pad = flexhlssink_clone.request_pad_simple("audio").unwrap(); - audio_convert_src_pad.link(&hls_audio_pad).unwrap(); - } - }); + // + // let audio_convert_clone = audio_convert.clone(); + // let flexhlssink_clone = flexhlssink.clone(); + // decodebin.connect_pad_added(move |_, pad| { + // let caps = pad.current_caps().unwrap(); + // let s = caps.structure(0).unwrap(); + // + // let audio_convert_sink_pad = audio_convert_clone.static_pad("sink").unwrap(); + // + // if s.name() == "audio/x-raw" && !audio_convert_sink_pad.is_linked() { + // pad.link(&audio_convert_sink_pad).unwrap(); + // + // let audio_convert_src_pad = audio_convert_clone.static_pad("src").unwrap(); + // let hls_audio_pad = flexhlssink_clone.request_pad_simple("audio").unwrap(); + // println!("Caps for new audio_convert_src_pad: {:?}", audio_convert_src_pad.caps()); + // println!("Caps for new hls_audio_pad: {:?}", hls_audio_pad.caps()); + // audio_convert_src_pad.link(&hls_audio_pad).unwrap(); + // } + // }); // audio_src.connect_pad_added(move |src, src_pad| { // println!(