Fix issue when handling pad creation
This commit is contained in:
parent
84f3c3c840
commit
7cf41b8709
2 changed files with 126 additions and 55 deletions
41
src/imp.rs
41
src/imp.rs
|
@ -1,7 +1,7 @@
|
||||||
use glib::subclass::prelude::*;
|
use glib::subclass::prelude::*;
|
||||||
use gst::prelude::*;
|
use gst::prelude::*;
|
||||||
use gst::subclass::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 crate::playlist::PlaylistRenderState;
|
||||||
use m3u8_rs::playlist::{MediaPlaylist, MediaPlaylistType, MediaSegment};
|
use m3u8_rs::playlist::{MediaPlaylist, MediaPlaylistType, MediaSegment};
|
||||||
|
@ -116,6 +116,11 @@ impl FlexHlsSink {
|
||||||
let segment_file_location = settings
|
let segment_file_location = settings
|
||||||
.location
|
.location
|
||||||
.replace(BACKWARDS_COMPATIBLE_PLACEHOLDER, &seq_num);
|
.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_location_clone = segment_file_location.clone();
|
||||||
let segment_file = File::create(&segment_file_location).map_err(move |err| {
|
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_location = Some(segment_file_location);
|
||||||
*current_segment_file = Some(segment_file);
|
*current_segment_file = Some(segment_file);
|
||||||
|
|
||||||
gst_debug!(
|
gst_info!(
|
||||||
CAT,
|
CAT,
|
||||||
"New segment location: {}",
|
"New segment location: {}",
|
||||||
current_segment_location.as_ref().unwrap()
|
current_segment_location.as_ref().unwrap()
|
||||||
|
@ -509,9 +514,12 @@ impl ObjectImpl for FlexHlsSink {
|
||||||
.connect("format-location", false, move |args| {
|
.connect("format-location", false, move |args| {
|
||||||
let fragment_id = args[1].get::<u32>().unwrap();
|
let fragment_id = args[1].get::<u32>().unwrap();
|
||||||
|
|
||||||
|
gst_info!(CAT, "Got fragment-id: {}", fragment_id);
|
||||||
|
|
||||||
if let Err(err) = this.on_format_location(fragment_id) {
|
if let Err(err) = this.on_format_location(fragment_id) {
|
||||||
gst_error!(CAT, "on format-location handler: {}", err);
|
gst_error!(CAT, "on format-location handler: {}", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -638,11 +646,11 @@ impl ElementImpl for FlexHlsSink {
|
||||||
&self,
|
&self,
|
||||||
element: &Self::Type,
|
element: &Self::Type,
|
||||||
templ: &gst::PadTemplate,
|
templ: &gst::PadTemplate,
|
||||||
name: Option<String>,
|
_name: Option<String>,
|
||||||
caps: Option<&gst::Caps>,
|
caps: Option<&gst::Caps>,
|
||||||
) -> Option<gst::Pad> {
|
) -> Option<gst::Pad> {
|
||||||
let mut settings = self.settings.lock().unwrap();
|
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") => {
|
Some("audio") => {
|
||||||
if settings.audio_sink {
|
if settings.audio_sink {
|
||||||
gst_debug!(
|
gst_debug!(
|
||||||
|
@ -652,17 +660,15 @@ impl ElementImpl for FlexHlsSink {
|
||||||
);
|
);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
gst_info!(CAT, "creating the audio pad");
|
|
||||||
|
|
||||||
let splitmuxsink = match &mut settings.splitmuxsink {
|
let splitmuxsink = match &mut settings.splitmuxsink {
|
||||||
None => return None,
|
None => return None,
|
||||||
Some(sms) => sms,
|
Some(sms) => sms,
|
||||||
};
|
};
|
||||||
let peer_pad = splitmuxsink.request_pad_simple("audio_0").unwrap();
|
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();
|
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();
|
element.add_pad(&sink_pad).unwrap();
|
||||||
|
sink_pad.set_active(true).unwrap();
|
||||||
settings.audio_sink = true;
|
settings.audio_sink = true;
|
||||||
|
|
||||||
Some(sink_pad.upcast())
|
Some(sink_pad.upcast())
|
||||||
|
@ -676,26 +682,27 @@ impl ElementImpl for FlexHlsSink {
|
||||||
);
|
);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let peer_pad_name = "video";
|
|
||||||
let pad_name = "video";
|
|
||||||
|
|
||||||
let splitmuxsink = match &mut settings.splitmuxsink {
|
let splitmuxsink = match &mut settings.splitmuxsink {
|
||||||
None => return None,
|
None => return None,
|
||||||
Some(sms) => sms,
|
Some(sms) => sms,
|
||||||
};
|
};
|
||||||
let peer_pad = match splitmuxsink.request_pad_simple(peer_pad_name) {
|
let peer_pad = splitmuxsink.request_pad_simple("video").unwrap();
|
||||||
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 sink_pad = gst::GhostPad::from_template_with_target(&templ, Some("video"), &peer_pad).unwrap();
|
||||||
element.add_pad(&sink_pad).unwrap();
|
element.add_pad(&sink_pad).unwrap();
|
||||||
|
sink_pad.set_active(true).unwrap();
|
||||||
settings.video_sink = true;
|
settings.video_sink = true;
|
||||||
|
|
||||||
Some(sink_pad.upcast())
|
Some(sink_pad.upcast())
|
||||||
}
|
}
|
||||||
None => None,
|
None => {
|
||||||
|
gst_debug!(
|
||||||
|
CAT,
|
||||||
|
obj: element,
|
||||||
|
"template name returned `None`",
|
||||||
|
);
|
||||||
|
None
|
||||||
|
},
|
||||||
Some(other_name) => {
|
Some(other_name) => {
|
||||||
gst_debug!(
|
gst_debug!(
|
||||||
CAT,
|
CAT,
|
||||||
|
|
|
@ -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::<gst_app::AppSink>().unwrap();
|
||||||
|
// let (sender, receiver) = mpsc::channel();
|
||||||
|
// appsink.connect_new_sample(move |appsink| {
|
||||||
|
// let _sample = appsink
|
||||||
|
// .emit_by_name("pull-sample", &[])
|
||||||
|
// .unwrap()
|
||||||
|
// .unwrap()
|
||||||
|
// .get::<gst::Sample>()
|
||||||
|
// .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]
|
#[test]
|
||||||
fn test_basic_element_properties() {
|
fn test_basic_element_properties() {
|
||||||
init();
|
init();
|
||||||
|
@ -35,18 +105,17 @@ fn test_basic_element_properties() {
|
||||||
audio_src.set_property("is-live", &true).unwrap();
|
audio_src.set_property("is-live", &true).unwrap();
|
||||||
audio_src.set_property("num-buffers", &BUFFER_NB).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();
|
// let video_src = gst::ElementFactory::make("videotestsrc", Some("videotestsrc")).unwrap();
|
||||||
video_src.set_property("is-live", &true).unwrap();
|
// video_src.set_property("is-live", &true).unwrap();
|
||||||
video_src.set_property("num-buffers", &BUFFER_NB).unwrap();
|
// video_src.set_property("num-buffers", &BUFFER_NB).unwrap();
|
||||||
|
|
||||||
let audio_convert = gst::ElementFactory::make("audioconvert", Some("audioconvert")).unwrap();
|
|
||||||
|
|
||||||
let tee = gst::ElementFactory::make("tee", Some("tee")).unwrap();
|
let tee = gst::ElementFactory::make("tee", Some("tee")).unwrap();
|
||||||
|
|
||||||
let hls_queue = gst::ElementFactory::make("queue", Some("hls_queue")).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();
|
let flexhlssink = gst::ElementFactory::make("flexhlssink", Some("flexhlssink")).unwrap();
|
||||||
flexhlssink.set_property("target-duration", &6u32).unwrap();
|
flexhlssink.set_property("target-duration", &6u32).unwrap();
|
||||||
|
|
||||||
|
@ -63,19 +132,21 @@ fn test_basic_element_properties() {
|
||||||
&app_queue,
|
&app_queue,
|
||||||
&app_sink,
|
&app_sink,
|
||||||
&hls_queue,
|
&hls_queue,
|
||||||
&decodebin,
|
//&decodebin,
|
||||||
&audio_convert,
|
//&audio_convert,
|
||||||
// &hls_audio_convert,
|
&hls_avenc_aac,
|
||||||
&flexhlssink,
|
&flexhlssink,
|
||||||
])
|
])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
gst::Element::link_many(&[&audio_src, &tee]).unwrap();
|
gst::Element::link_many(&[&audio_src, &tee]).unwrap();
|
||||||
gst::Element::link_many(&[&app_queue, &app_sink]).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();
|
// 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
|
// Link the appsink
|
||||||
let tee_app_pad = tee.request_pad_simple("src_%u").unwrap();
|
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();
|
let hls_queue_pad = hls_queue.static_pad("sink").unwrap();
|
||||||
tee_hls_pad.link(&hls_queue_pad).unwrap();
|
tee_hls_pad.link(&hls_queue_pad).unwrap();
|
||||||
|
//
|
||||||
// Link the queue to flexhlssink to link on audio
|
// let audio_convert_clone = audio_convert.clone();
|
||||||
// let audio_convert_pad = audio_convert.static_pad("src").unwrap();
|
// let flexhlssink_clone = flexhlssink.clone();
|
||||||
// println!(
|
// decodebin.connect_pad_added(move |_, pad| {
|
||||||
// "Obtained request pad {} for the flex HLS sink",
|
// let caps = pad.current_caps().unwrap();
|
||||||
// audio_convert_pad.name()
|
// let s = caps.structure(0).unwrap();
|
||||||
// );
|
//
|
||||||
// let hls_audio_pad = flexhlssink.request_pad_simple("audio").unwrap();
|
// let audio_convert_sink_pad = audio_convert_clone.static_pad("sink").unwrap();
|
||||||
// audio_convert_pad.link(&hls_audio_pad).unwrap();
|
//
|
||||||
|
// if s.name() == "audio/x-raw" && !audio_convert_sink_pad.is_linked() {
|
||||||
let audio_convert_clone = audio_convert.clone();
|
// pad.link(&audio_convert_sink_pad).unwrap();
|
||||||
let flexhlssink_clone = flexhlssink.clone();
|
//
|
||||||
decodebin.connect_pad_added(move |_, pad| {
|
// let audio_convert_src_pad = audio_convert_clone.static_pad("src").unwrap();
|
||||||
let caps = pad.current_caps().unwrap();
|
// let hls_audio_pad = flexhlssink_clone.request_pad_simple("audio").unwrap();
|
||||||
let s = caps.structure(0).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());
|
||||||
let audio_convert_sink_pad = audio_convert_clone.static_pad("sink").unwrap();
|
// audio_convert_src_pad.link(&hls_audio_pad).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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// audio_src.connect_pad_added(move |src, src_pad| {
|
// audio_src.connect_pad_added(move |src, src_pad| {
|
||||||
// println!(
|
// println!(
|
||||||
|
|
Loading…
Reference in a new issue