2021-10-18 06:42:42 +00:00
|
|
|
// Copyright (C) 2021 Sebastian Dröge <sebastian@centricular.com>
|
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
|
|
|
|
// If a copy of the MPL was not distributed with this file, You can obtain one at
|
|
|
|
// <https://mozilla.org/MPL/2.0/>.
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
|
|
|
use gst::glib;
|
|
|
|
use gst::prelude::*;
|
|
|
|
|
|
|
|
mod boxes;
|
|
|
|
mod imp;
|
|
|
|
|
|
|
|
glib::wrapper! {
|
2022-05-05 12:09:19 +00:00
|
|
|
pub(crate) struct FMP4Mux(ObjectSubclass<imp::FMP4Mux>) @extends gst_base::Aggregator, gst::Element, gst::Object;
|
2021-10-18 06:42:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
glib::wrapper! {
|
2022-05-05 12:09:19 +00:00
|
|
|
pub(crate) struct ISOFMP4Mux(ObjectSubclass<imp::ISOFMP4Mux>) @extends FMP4Mux, gst_base::Aggregator, gst::Element, gst::Object;
|
2021-10-18 06:42:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
glib::wrapper! {
|
2022-05-05 12:09:19 +00:00
|
|
|
pub(crate) struct CMAFMux(ObjectSubclass<imp::CMAFMux>) @extends FMP4Mux, gst_base::Aggregator, gst::Element, gst::Object;
|
2021-10-18 06:42:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
glib::wrapper! {
|
2022-05-05 12:09:19 +00:00
|
|
|
pub(crate) struct DASHMP4Mux(ObjectSubclass<imp::DASHMP4Mux>) @extends FMP4Mux, gst_base::Aggregator, gst::Element, gst::Object;
|
2021-10-18 06:42:42 +00:00
|
|
|
}
|
|
|
|
|
2022-05-13 08:45:01 +00:00
|
|
|
glib::wrapper! {
|
|
|
|
pub(crate) struct ONVIFFMP4Mux(ObjectSubclass<imp::ONVIFFMP4Mux>) @extends FMP4Mux, gst_base::Aggregator, gst::Element, gst::Object;
|
|
|
|
}
|
|
|
|
|
2021-10-18 06:42:42 +00:00
|
|
|
pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
|
|
|
|
gst::Element::register(
|
|
|
|
Some(plugin),
|
|
|
|
"isofmp4mux",
|
|
|
|
gst::Rank::Primary,
|
|
|
|
ISOFMP4Mux::static_type(),
|
|
|
|
)?;
|
|
|
|
gst::Element::register(
|
|
|
|
Some(plugin),
|
|
|
|
"cmafmux",
|
|
|
|
gst::Rank::Primary,
|
|
|
|
CMAFMux::static_type(),
|
|
|
|
)?;
|
|
|
|
gst::Element::register(
|
|
|
|
Some(plugin),
|
|
|
|
"dashmp4mux",
|
|
|
|
gst::Rank::Primary,
|
|
|
|
DASHMP4Mux::static_type(),
|
|
|
|
)?;
|
2022-05-13 08:45:01 +00:00
|
|
|
gst::Element::register(
|
|
|
|
Some(plugin),
|
|
|
|
"onviffmp4mux",
|
|
|
|
gst::Rank::Primary,
|
|
|
|
ONVIFFMP4Mux::static_type(),
|
|
|
|
)?;
|
2021-10-18 06:42:42 +00:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub(crate) struct HeaderConfiguration<'a> {
|
|
|
|
variant: Variant,
|
|
|
|
update: bool,
|
2022-05-09 12:32:10 +00:00
|
|
|
/// 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.
|
2022-05-24 11:04:11 +00:00
|
|
|
streams: &'a [gst::Caps],
|
2021-10-18 06:42:42 +00:00
|
|
|
write_mehd: bool,
|
|
|
|
duration: Option<gst::ClockTime>,
|
2022-05-27 10:27:10 +00:00
|
|
|
/// Start UTC time in ONVIF mode.
|
|
|
|
/// Since Jan 1 1601 in 100ns units.
|
|
|
|
start_utc_time: Option<u64>,
|
2021-10-18 06:42:42 +00:00
|
|
|
}
|
|
|
|
|
2022-05-09 12:32:10 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub(crate) struct FragmentHeaderConfiguration<'a> {
|
|
|
|
variant: Variant,
|
|
|
|
sequence_number: u32,
|
2022-05-24 11:04:11 +00:00
|
|
|
streams: &'a [(gst::Caps, Option<FragmentTimingInfo>)],
|
2022-05-09 12:32:10 +00:00
|
|
|
buffers: &'a [Buffer],
|
|
|
|
}
|
|
|
|
|
2022-06-30 13:29:09 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub(crate) struct FragmentTimingInfo {
|
|
|
|
/// Start time of this fragment
|
|
|
|
start_time: gst::ClockTime,
|
|
|
|
/// Set if this is an intra-only stream
|
|
|
|
intra_only: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub(crate) struct Buffer {
|
|
|
|
/// Track index
|
|
|
|
idx: usize,
|
|
|
|
|
|
|
|
/// Actual buffer
|
|
|
|
buffer: gst::Buffer,
|
|
|
|
|
|
|
|
/// Timestamp
|
|
|
|
timestamp: gst::ClockTime,
|
|
|
|
|
|
|
|
/// Sample duration
|
|
|
|
duration: gst::ClockTime,
|
|
|
|
|
|
|
|
/// Composition time offset
|
|
|
|
composition_time_offset: Option<i64>,
|
|
|
|
}
|
|
|
|
|
2021-10-18 06:42:42 +00:00
|
|
|
#[allow(clippy::upper_case_acronyms)]
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
|
|
pub(crate) enum Variant {
|
|
|
|
ISO,
|
|
|
|
CMAF,
|
|
|
|
DASH,
|
2022-05-13 08:45:01 +00:00
|
|
|
ONVIF,
|
2021-10-18 06:42:42 +00:00
|
|
|
}
|
|
|
|
|
2022-05-12 10:44:20 +00:00
|
|
|
impl Variant {
|
|
|
|
pub(crate) fn is_single_stream(self) -> bool {
|
|
|
|
match self {
|
2022-05-13 08:45:01 +00:00
|
|
|
Variant::ISO | Variant::ONVIF => false,
|
2022-05-12 10:44:20 +00:00
|
|
|
Variant::CMAF | Variant::DASH => true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-18 06:42:42 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub(crate) struct FragmentOffset {
|
|
|
|
time: gst::ClockTime,
|
|
|
|
offset: u64,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(clippy::upper_case_acronyms)]
|
2021-11-22 09:04:26 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, glib::Enum)]
|
2021-10-18 06:42:42 +00:00
|
|
|
#[repr(i32)]
|
2021-11-22 09:04:26 +00:00
|
|
|
#[enum_type(name = "GstFMP4MuxHeaderUpdateMode")]
|
2021-10-18 06:42:42 +00:00
|
|
|
pub(crate) enum HeaderUpdateMode {
|
|
|
|
None,
|
|
|
|
Rewrite,
|
|
|
|
Update,
|
|
|
|
}
|