diff --git a/generic/fmp4/Cargo.toml b/generic/fmp4/Cargo.toml index 135f7f9d..242ef00b 100644 --- a/generic/fmp4/Cargo.toml +++ b/generic/fmp4/Cargo.toml @@ -15,6 +15,7 @@ gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/g gst-audio = { package = "gstreamer-audio", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" } gst-video = { package = "gstreamer-video", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" } once_cell = "1.0" +uuid = { version = "1", features = ["v4"] } [lib] name = "gstfmp4" diff --git a/generic/fmp4/src/fmp4mux/boxes.rs b/generic/fmp4/src/fmp4mux/boxes.rs index ccd09b41..5c93ed6b 100644 --- a/generic/fmp4/src/fmp4mux/boxes.rs +++ b/generic/fmp4/src/fmp4mux/boxes.rs @@ -355,8 +355,7 @@ fn brands_from_variant_and_caps<'a>( pub(super) fn create_fmp4_header(cfg: super::HeaderConfiguration) -> Result { let mut v = vec![]; - let (brand, compatible_brands) = - brands_from_variant_and_caps(cfg.variant, cfg.streams.iter().map(|s| &s.1)); + let (brand, compatible_brands) = brands_from_variant_and_caps(cfg.variant, cfg.streams.iter()); write_box(&mut v, b"ftyp", |v| { // major brand @@ -371,6 +370,42 @@ pub(super) fn create_fmp4_header(cfg: super::HeaderConfiguration) -> Result, cfg: &super::HeaderConfiguration) -> Result<(), E write_full_box(v, b"mvhd", FULL_BOX_VERSION_1, FULL_BOX_FLAGS_NONE, |v| { write_mvhd(v, cfg, creation_time) })?; - for (idx, (pad, caps)) in cfg.streams.iter().enumerate() { + for (idx, caps) in cfg.streams.iter().enumerate() { write_box(v, b"trak", |v| { let mut references = vec![]; @@ -394,7 +429,7 @@ fn write_moov(v: &mut Vec, cfg: &super::HeaderConfiguration) -> Result<(), E && caps.structure(0).unwrap().name() == "application/x-onvif-metadata" { // Find the first video track - for (idx, (_pad, caps)) in cfg.streams.iter().enumerate() { + for (idx, caps) in cfg.streams.iter().enumerate() { let s = caps.structure(0).unwrap(); if matches!(s.name(), "video/x-h264" | "video/x-h265" | "image/jpeg") { @@ -407,7 +442,7 @@ fn write_moov(v: &mut Vec, cfg: &super::HeaderConfiguration) -> Result<(), E } } - write_trak(v, cfg, idx, pad, caps, creation_time, &references) + write_trak(v, cfg, idx, caps, creation_time, &references) })?; } write_box(v, b"mvex", |v| write_mvex(v, cfg))?; @@ -454,7 +489,7 @@ fn write_mvhd( // Modification time v.extend(creation_time.to_be_bytes()); // Timescale: uses the reference track timescale - v.extend(caps_to_timescale(&cfg.streams[0].1).to_be_bytes()); + v.extend(caps_to_timescale(&cfg.streams[0]).to_be_bytes()); // Duration v.extend(0u64.to_be_bytes()); @@ -504,7 +539,6 @@ fn write_trak( v: &mut Vec, cfg: &super::HeaderConfiguration, idx: usize, - _pad: &gst_base::AggregatorPad, caps: &gst::CapsRef, creation_time: u64, references: &[TrackReference], @@ -1389,7 +1423,7 @@ fn write_mvex(v: &mut Vec, cfg: &super::HeaderConfiguration) -> Result<(), E } } - for (idx, (_pad, _caps)) in cfg.streams.iter().enumerate() { + for (idx, _caps) in cfg.streams.iter().enumerate() { write_full_box(v, b"trex", FULL_BOX_VERSION_0, FULL_BOX_FLAGS_NONE, |v| { write_trex(v, cfg, idx) })?; @@ -1400,7 +1434,7 @@ fn write_mvex(v: &mut Vec, cfg: &super::HeaderConfiguration) -> Result<(), E fn write_mehd(v: &mut Vec, cfg: &super::HeaderConfiguration) -> Result<(), Error> { // Use the reference track timescale - let timescale = caps_to_timescale(&cfg.streams[0].1); + let timescale = caps_to_timescale(&cfg.streams[0]); let duration = cfg .duration @@ -1443,7 +1477,7 @@ pub(super) fn create_fmp4_fragment_header( let mut v = vec![]; let (brand, compatible_brands) = - brands_from_variant_and_caps(cfg.variant, cfg.streams.iter().map(|s| &s.1)); + brands_from_variant_and_caps(cfg.variant, cfg.streams.iter().map(|s| &s.0)); write_box(&mut v, b"styp", |v| { // major brand @@ -1494,7 +1528,7 @@ fn write_moof( })?; let mut data_offset_offsets = vec![]; - for (idx, (_pad, caps, timing_info)) in cfg.streams.iter().enumerate() { + for (idx, (caps, timing_info)) in cfg.streams.iter().enumerate() { // Skip tracks without any buffers for this fragment. let timing_info = match timing_info { None => continue, diff --git a/generic/fmp4/src/fmp4mux/imp.rs b/generic/fmp4/src/fmp4mux/imp.rs index f1ba3c12..60d8b919 100644 --- a/generic/fmp4/src/fmp4mux/imp.rs +++ b/generic/fmp4/src/fmp4mux/imp.rs @@ -607,7 +607,7 @@ impl FMP4Mux { "Draining no buffers", ); - streams.push((stream.sinkpad.clone(), stream.caps.clone(), None)); + streams.push((stream.caps.clone(), None)); drain_buffers.push(VecDeque::new()); } else { let first_gop = gops.first().unwrap(); @@ -678,7 +678,6 @@ impl FMP4Mux { }; streams.push(( - stream.sinkpad.clone(), stream.caps.clone(), Some(super::FragmentTimingInfo { start_time, @@ -928,7 +927,7 @@ impl FMP4Mux { // Write mfra only for the main stream, and if there are no buffers for the main stream // in this segment then don't write anything. - if let Some((_pad, _caps, Some(ref timing_info))) = streams.get(0) { + if let Some((_caps, Some(ref timing_info))) = streams.get(0) { state.fragment_offsets.push(super::FragmentOffset { time: timing_info.start_time, offset: moof_offset, @@ -952,7 +951,7 @@ impl FMP4Mux { } if settings.write_mfra && at_eos { - match boxes::create_mfra(&streams[0].1, &state.fragment_offsets) { + match boxes::create_mfra(&streams[0].0, &state.fragment_offsets) { Ok(mut mfra) => { { let mfra = mfra.get_mut().unwrap(); @@ -1100,11 +1099,10 @@ impl FMP4Mux { let streams = state .streams .iter() - .map(|s| (s.sinkpad.clone(), s.caps.clone())) + .map(|s| s.caps.clone()) .collect::>(); let mut buffer = boxes::create_fmp4_header(super::HeaderConfiguration { - element, variant, update: at_eos, streams: streams.as_slice(), diff --git a/generic/fmp4/src/fmp4mux/mod.rs b/generic/fmp4/src/fmp4mux/mod.rs index a9b649a6..2d0ba10e 100644 --- a/generic/fmp4/src/fmp4mux/mod.rs +++ b/generic/fmp4/src/fmp4mux/mod.rs @@ -64,12 +64,10 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { #[derive(Debug)] pub(crate) struct HeaderConfiguration<'a> { variant: Variant, - #[allow(dead_code)] - element: &'a FMP4Mux, update: bool, /// First caps must be the video/reference stream. Must be in the order the tracks are going to /// be used later for the fragments too. - streams: &'a [(gst_base::AggregatorPad, gst::Caps)], + streams: &'a [gst::Caps], write_mehd: bool, duration: Option, } @@ -78,11 +76,7 @@ pub(crate) struct HeaderConfiguration<'a> { pub(crate) struct FragmentHeaderConfiguration<'a> { variant: Variant, sequence_number: u32, - streams: &'a [( - gst_base::AggregatorPad, - gst::Caps, - Option, - )], + streams: &'a [(gst::Caps, Option)], buffers: &'a [Buffer], }