From: Matthew Waters Date: Wed, 16 Sep 2020 02:15:09 +0000 (+1000) Subject: qtmux: make documentation happy X-Git-Tag: 1.19.3~509^2~404 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e64227f585589174e8099b2b58372e8cceaffb5b;p=platform%2Fupstream%2Fgstreamer.git qtmux: make documentation happy introduce a base qtmux class that we can install documentation snippets on instead of duplicating across alll the isomp4 elements Part-of: --- diff --git a/docs/gst_plugins_cache.json b/docs/gst_plugins_cache.json index 8407983..73a9bb3 100644 --- a/docs/gst_plugins_cache.json +++ b/docs/gst_plugins_cache.json @@ -7491,6 +7491,7 @@ "description": "Multiplex audio and video into a 3GPP file", "hierarchy": [ "Gst3GPPMux", + "GstQTMux", "GstAggregator", "GstElement", "GstObject", @@ -7531,242 +7532,6 @@ } }, "properties": { - "dts-method": { - "blurb": "Method to determine DTS time (DEPRECATED)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "reorder (1)", - "mutable": "null", - "readable": true, - "type": "GstQTMuxDtsMethods", - "writable": true - }, - "faststart": { - "blurb": "If the file should be formatted for faststart (headers first)", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "faststart-file": { - "blurb": "File that will be used temporarily to store data from the stream when creating a faststart file. If null a filepath will be created automatically", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "NULL", - "mutable": "null", - "readable": true, - "type": "gchararray", - "writable": true - }, - "force-chunks": { - "blurb": "Force multiple chunks to be created even for single-stream files", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "force-create-timecode-trak": { - "blurb": "Create a timecode trak even in unsupported flavors", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "fragment-duration": { - "blurb": "Fragment durations in ms (produce a fragmented file if > 0)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, - "interleave-bytes": { - "blurb": "Interleave between streams in bytes", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "interleave-time": { - "blurb": "Interleave between streams in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "250000000", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "max-raw-audio-drift": { - "blurb": "Maximum allowed drift of raw audio samples vs. timestamps in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "40000000", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "moov-recovery-file": { - "blurb": "File to be used to store data for moov atom making movie file recovery possible in case of a crash during muxing. Null for disabled. (Experimental)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "NULL", - "mutable": "null", - "readable": true, - "type": "gchararray", - "writable": true - }, - "movie-timescale": { - "blurb": "Timescale to use in the movie (units per second, 0 == default)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, - "presentation-time": { - "blurb": "Calculate and include presentation/composition time (in addition to decoding time)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "reserved-bytes-per-sec": { - "blurb": "Multiplier for converting reserved-max-duration into bytes of header to reserve, per second, per track", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "550", - "max": "10000", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, - "reserved-duration-remaining": { - "blurb": "Reports the approximate amount of remaining moov header space reserved using reserved-max-duration", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "18446744073709551615", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": false - }, - "reserved-max-duration": { - "blurb": "When set to a value > 0, reserves space for index tables at the beginning of the file.", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "18446744073709551615", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "reserved-moov-update-period": { - "blurb": "When used with reserved-max-duration, periodically updates the index tables with information muxed so far.", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "18446744073709551615", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "reserved-prefill": { - "blurb": "Prefill samples table of reserved duration", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "start-gap-threshold": { - "blurb": "Threshold for creating an edit list for gaps at the start in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, "streamable": { "blurb": "If set to true, the output should be as if it is to be streamed and hence no indexes written or duration written. (DEPRECATED, only valid for fragmented MP4)", "conditionally-available": false, @@ -7778,20 +7543,6 @@ "readable": true, "type": "gboolean", "writable": true - }, - "trak-timescale": { - "blurb": "Timescale to use for the tracks (units per second, 0 is automatic)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true } }, "rank": "primary" @@ -7801,6 +7552,7 @@ "description": "Multiplex audio and video into a ISML file", "hierarchy": [ "GstISMLMux", + "GstQTMux", "GstAggregator", "GstElement", "GstObject", @@ -7815,876 +7567,81 @@ "klass": "Codec/Muxer", "long-name": "ISML Muxer", "pad-templates": { - "audio_%%u": { - "caps": "audio/mpeg:\n mpegversion: 1\n layer: 3\n channels: [ 1, 2 ]\n rate: [ 1, 2147483647 ]\naudio/mpeg:\n mpegversion: 4\n stream-format: raw\n channels: [ 1, 8 ]\n rate: [ 1, 2147483647 ]\n", - "direction": "sink", - "presence": "request", - "type": "GstQTMuxPad" - }, - "src": { - "caps": "video/quicktime:\n variant: iso-fragmented\n", - "direction": "src", - "presence": "always", - "type": "GstAggregatorPad" - }, - "video_%%u": { - "caps": "video/mpeg:\n mpegversion: 4\n systemstream: false\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-divx:\n divxversion: 5\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-h264:\n stream-format: avc\n alignment: au\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\n", - "direction": "sink", - "presence": "request", - "type": "GstQTMuxPad" - } - }, - "properties": { - "dts-method": { - "blurb": "Method to determine DTS time (DEPRECATED)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "reorder (1)", - "mutable": "null", - "readable": true, - "type": "GstQTMuxDtsMethods", - "writable": true - }, - "faststart": { - "blurb": "If the file should be formatted for faststart (headers first)", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "faststart-file": { - "blurb": "File that will be used temporarily to store data from the stream when creating a faststart file. If null a filepath will be created automatically", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "NULL", - "mutable": "null", - "readable": true, - "type": "gchararray", - "writable": true - }, - "force-chunks": { - "blurb": "Force multiple chunks to be created even for single-stream files", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "force-create-timecode-trak": { - "blurb": "Create a timecode trak even in unsupported flavors", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "fragment-duration": { - "blurb": "Fragment durations in ms (produce a fragmented file if > 0)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "2000", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, - "interleave-bytes": { - "blurb": "Interleave between streams in bytes", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "interleave-time": { - "blurb": "Interleave between streams in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "250000000", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "max-raw-audio-drift": { - "blurb": "Maximum allowed drift of raw audio samples vs. timestamps in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "40000000", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "moov-recovery-file": { - "blurb": "File to be used to store data for moov atom making movie file recovery possible in case of a crash during muxing. Null for disabled. (Experimental)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "NULL", - "mutable": "null", - "readable": true, - "type": "gchararray", - "writable": true - }, - "movie-timescale": { - "blurb": "Timescale to use in the movie (units per second, 0 == default)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, - "presentation-time": { - "blurb": "Calculate and include presentation/composition time (in addition to decoding time)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "reserved-bytes-per-sec": { - "blurb": "Multiplier for converting reserved-max-duration into bytes of header to reserve, per second, per track", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "550", - "max": "10000", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, - "reserved-duration-remaining": { - "blurb": "Reports the approximate amount of remaining moov header space reserved using reserved-max-duration", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "18446744073709551615", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": false - }, - "reserved-max-duration": { - "blurb": "When set to a value > 0, reserves space for index tables at the beginning of the file.", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "18446744073709551615", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "reserved-moov-update-period": { - "blurb": "When used with reserved-max-duration, periodically updates the index tables with information muxed so far.", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "18446744073709551615", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "reserved-prefill": { - "blurb": "Prefill samples table of reserved duration", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "start-gap-threshold": { - "blurb": "Threshold for creating an edit list for gaps at the start in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "streamable": { - "blurb": "If set to true, the output should be as if it is to be streamed and hence no indexes written or duration written.", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "trak-timescale": { - "blurb": "Timescale to use for the tracks (units per second, 0 is automatic)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - } - }, - "rank": "primary" - }, - "mj2mux": { - "author": "Thiago Sousa Santos ", - "description": "Multiplex audio and video into a MJ2 file", - "hierarchy": [ - "GstMJ2Mux", - "GstAggregator", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "interfaces": [ - "GstTagSetter", - "GstTagXmpWriter", - "GstPreset" - ], - "klass": "Codec/Muxer", - "long-name": "MJ2 Muxer", - "pad-templates": { - "audio_%%u": { - "caps": "audio/x-raw:\n format: { S16LE, S16BE, S8, U8 }\n layout: interleaved\n channels: [ 1, 2 ]\n rate: [ 1, 2147483647 ]\n", - "direction": "sink", - "presence": "request", - "type": "GstQTMuxPad" - }, - "src": { - "caps": "video/mj2:\n", - "direction": "src", - "presence": "always", - "type": "GstAggregatorPad" - }, - "video_%%u": { - "caps": "image/x-j2c:\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nimage/x-jpc:\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\n", - "direction": "sink", - "presence": "request", - "type": "GstQTMuxPad" - } - }, - "properties": { - "dts-method": { - "blurb": "Method to determine DTS time (DEPRECATED)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "reorder (1)", - "mutable": "null", - "readable": true, - "type": "GstQTMuxDtsMethods", - "writable": true - }, - "faststart": { - "blurb": "If the file should be formatted for faststart (headers first)", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "faststart-file": { - "blurb": "File that will be used temporarily to store data from the stream when creating a faststart file. If null a filepath will be created automatically", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "NULL", - "mutable": "null", - "readable": true, - "type": "gchararray", - "writable": true - }, - "force-chunks": { - "blurb": "Force multiple chunks to be created even for single-stream files", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "force-create-timecode-trak": { - "blurb": "Create a timecode trak even in unsupported flavors", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "fragment-duration": { - "blurb": "Fragment durations in ms (produce a fragmented file if > 0)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, - "interleave-bytes": { - "blurb": "Interleave between streams in bytes", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "interleave-time": { - "blurb": "Interleave between streams in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "250000000", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "max-raw-audio-drift": { - "blurb": "Maximum allowed drift of raw audio samples vs. timestamps in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "40000000", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "moov-recovery-file": { - "blurb": "File to be used to store data for moov atom making movie file recovery possible in case of a crash during muxing. Null for disabled. (Experimental)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "NULL", - "mutable": "null", - "readable": true, - "type": "gchararray", - "writable": true - }, - "movie-timescale": { - "blurb": "Timescale to use in the movie (units per second, 0 == default)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, - "presentation-time": { - "blurb": "Calculate and include presentation/composition time (in addition to decoding time)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "reserved-bytes-per-sec": { - "blurb": "Multiplier for converting reserved-max-duration into bytes of header to reserve, per second, per track", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "550", - "max": "10000", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, - "reserved-duration-remaining": { - "blurb": "Reports the approximate amount of remaining moov header space reserved using reserved-max-duration", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "18446744073709551615", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": false - }, - "reserved-max-duration": { - "blurb": "When set to a value > 0, reserves space for index tables at the beginning of the file.", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "18446744073709551615", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "reserved-moov-update-period": { - "blurb": "When used with reserved-max-duration, periodically updates the index tables with information muxed so far.", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "18446744073709551615", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "reserved-prefill": { - "blurb": "Prefill samples table of reserved duration", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "start-gap-threshold": { - "blurb": "Threshold for creating an edit list for gaps at the start in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "streamable": { - "blurb": "If set to true, the output should be as if it is to be streamed and hence no indexes written or duration written. (DEPRECATED, only valid for fragmented MP4)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "trak-timescale": { - "blurb": "Timescale to use for the tracks (units per second, 0 is automatic)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - } - }, - "rank": "primary" - }, - "mp4mux": { - "author": "Thiago Sousa Santos ", - "description": "Multiplex audio and video into a MP4 file", - "hierarchy": [ - "GstMP4Mux", - "GstAggregator", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "interfaces": [ - "GstTagSetter", - "GstTagXmpWriter", - "GstPreset" - ], - "klass": "Codec/Muxer", - "long-name": "MP4 Muxer", - "pad-templates": { - "audio_%%u": { - "caps": "audio/mpeg:\n mpegversion: 1\n layer: [ 1, 3 ]\n channels: [ 1, 2 ]\n rate: [ 1, 2147483647 ]\naudio/mpeg:\n mpegversion: 4\n stream-format: raw\n channels: [ 1, 8 ]\n rate: [ 1, 2147483647 ]\naudio/x-ac3:\n channels: [ 1, 6 ]\n rate: [ 1, 2147483647 ]\naudio/x-alac:\n channels: [ 1, 2 ]\n rate: [ 1, 2147483647 ]\naudio/x-opus:\nchannel-mapping-family: [ 0, 255 ]\n channels: [ 1, 8 ]\n rate: [ 1, 2147483647 ]\n", - "direction": "sink", - "presence": "request", - "type": "GstQTMuxPad" - }, - "src": { - "caps": "video/quicktime:\n variant: iso\n", - "direction": "src", - "presence": "always", - "type": "GstAggregatorPad" - }, - "subtitle_%%u": { - "caps": "text/x-raw:\n format: utf8\n", - "direction": "sink", - "presence": "request", - "type": "GstQTMuxPad" - }, - "video_%%u": { - "caps": "video/mpeg:\n mpegversion: 4\n systemstream: false\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-divx:\n divxversion: 5\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-h264:\n stream-format: avc\n alignment: au\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-h265:\n stream-format: { (string)hvc1, (string)hev1 }\n alignment: au\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-mp4-part:\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-av1:\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\n", - "direction": "sink", - "presence": "request", - "type": "GstQTMuxPad" - } - }, - "properties": { - "dts-method": { - "blurb": "Method to determine DTS time (DEPRECATED)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "reorder (1)", - "mutable": "null", - "readable": true, - "type": "GstQTMuxDtsMethods", - "writable": true - }, - "faststart": { - "blurb": "If the file should be formatted for faststart (headers first)", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "faststart-file": { - "blurb": "File that will be used temporarily to store data from the stream when creating a faststart file. If null a filepath will be created automatically", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "NULL", - "mutable": "null", - "readable": true, - "type": "gchararray", - "writable": true - }, - "force-chunks": { - "blurb": "Force multiple chunks to be created even for single-stream files", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "force-create-timecode-trak": { - "blurb": "Create a timecode trak even in unsupported flavors", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "fragment-duration": { - "blurb": "Fragment durations in ms (produce a fragmented file if > 0)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, - "interleave-bytes": { - "blurb": "Interleave between streams in bytes", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "interleave-time": { - "blurb": "Interleave between streams in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "250000000", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "max-raw-audio-drift": { - "blurb": "Maximum allowed drift of raw audio samples vs. timestamps in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "40000000", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "moov-recovery-file": { - "blurb": "File to be used to store data for moov atom making movie file recovery possible in case of a crash during muxing. Null for disabled. (Experimental)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "NULL", - "mutable": "null", - "readable": true, - "type": "gchararray", - "writable": true - }, - "movie-timescale": { - "blurb": "Timescale to use in the movie (units per second, 0 == default)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, - "presentation-time": { - "blurb": "Calculate and include presentation/composition time (in addition to decoding time)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "reserved-bytes-per-sec": { - "blurb": "Multiplier for converting reserved-max-duration into bytes of header to reserve, per second, per track", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "550", - "max": "10000", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, - "reserved-duration-remaining": { - "blurb": "Reports the approximate amount of remaining moov header space reserved using reserved-max-duration", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "18446744073709551615", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": false - }, - "reserved-max-duration": { - "blurb": "When set to a value > 0, reserves space for index tables at the beginning of the file.", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "18446744073709551615", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "reserved-moov-update-period": { - "blurb": "When used with reserved-max-duration, periodically updates the index tables with information muxed so far.", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "18446744073709551615", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true + "audio_%%u": { + "caps": "audio/mpeg:\n mpegversion: 1\n layer: 3\n channels: [ 1, 2 ]\n rate: [ 1, 2147483647 ]\naudio/mpeg:\n mpegversion: 4\n stream-format: raw\n channels: [ 1, 8 ]\n rate: [ 1, 2147483647 ]\n", + "direction": "sink", + "presence": "request", + "type": "GstQTMuxPad" }, - "reserved-prefill": { - "blurb": "Prefill samples table of reserved duration", + "src": { + "caps": "video/quicktime:\n variant: iso-fragmented\n", + "direction": "src", + "presence": "always", + "type": "GstAggregatorPad" + }, + "video_%%u": { + "caps": "video/mpeg:\n mpegversion: 4\n systemstream: false\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-divx:\n divxversion: 5\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-h264:\n stream-format: avc\n alignment: au\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\n", + "direction": "sink", + "presence": "request", + "type": "GstQTMuxPad" + } + }, + "properties": { + "streamable": { + "blurb": "If set to true, the output should be as if it is to be streamed and hence no indexes written or duration written.", "conditionally-available": false, "construct": true, "construct-only": false, "controllable": false, - "default": "false", + "default": "true", "mutable": "null", "readable": true, "type": "gboolean", "writable": true + } + }, + "rank": "primary" + }, + "mj2mux": { + "author": "Thiago Sousa Santos ", + "description": "Multiplex audio and video into a MJ2 file", + "hierarchy": [ + "GstMJ2Mux", + "GstQTMux", + "GstAggregator", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "interfaces": [ + "GstTagSetter", + "GstTagXmpWriter", + "GstPreset" + ], + "klass": "Codec/Muxer", + "long-name": "MJ2 Muxer", + "pad-templates": { + "audio_%%u": { + "caps": "audio/x-raw:\n format: { S16LE, S16BE, S8, U8 }\n layout: interleaved\n channels: [ 1, 2 ]\n rate: [ 1, 2147483647 ]\n", + "direction": "sink", + "presence": "request", + "type": "GstQTMuxPad" }, - "start-gap-threshold": { - "blurb": "Threshold for creating an edit list for gaps at the start in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true + "src": { + "caps": "video/mj2:\n", + "direction": "src", + "presence": "always", + "type": "GstAggregatorPad" }, + "video_%%u": { + "caps": "image/x-j2c:\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nimage/x-jpc:\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\n", + "direction": "sink", + "presence": "request", + "type": "GstQTMuxPad" + } + }, + "properties": { "streamable": { "blurb": "If set to true, the output should be as if it is to be streamed and hence no indexes written or duration written. (DEPRECATED, only valid for fragmented MP4)", "conditionally-available": false, @@ -8696,19 +7653,66 @@ "readable": true, "type": "gboolean", "writable": true + } + }, + "rank": "primary" + }, + "mp4mux": { + "author": "Thiago Sousa Santos ", + "description": "Multiplex audio and video into a MP4 file", + "hierarchy": [ + "GstMP4Mux", + "GstQTMux", + "GstAggregator", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "interfaces": [ + "GstTagSetter", + "GstTagXmpWriter", + "GstPreset" + ], + "klass": "Codec/Muxer", + "long-name": "MP4 Muxer", + "pad-templates": { + "audio_%%u": { + "caps": "audio/mpeg:\n mpegversion: 1\n layer: [ 1, 3 ]\n channels: [ 1, 2 ]\n rate: [ 1, 2147483647 ]\naudio/mpeg:\n mpegversion: 4\n stream-format: raw\n channels: [ 1, 8 ]\n rate: [ 1, 2147483647 ]\naudio/x-ac3:\n channels: [ 1, 6 ]\n rate: [ 1, 2147483647 ]\naudio/x-alac:\n channels: [ 1, 2 ]\n rate: [ 1, 2147483647 ]\naudio/x-opus:\nchannel-mapping-family: [ 0, 255 ]\n channels: [ 1, 8 ]\n rate: [ 1, 2147483647 ]\n", + "direction": "sink", + "presence": "request", + "type": "GstQTMuxPad" }, - "trak-timescale": { - "blurb": "Timescale to use for the tracks (units per second, 0 is automatic)", + "src": { + "caps": "video/quicktime:\n variant: iso\n", + "direction": "src", + "presence": "always", + "type": "GstAggregatorPad" + }, + "subtitle_%%u": { + "caps": "text/x-raw:\n format: utf8\n", + "direction": "sink", + "presence": "request", + "type": "GstQTMuxPad" + }, + "video_%%u": { + "caps": "video/mpeg:\n mpegversion: 4\n systemstream: false\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-divx:\n divxversion: 5\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-h264:\n stream-format: avc\n alignment: au\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-h265:\n stream-format: { (string)hvc1, (string)hev1 }\n alignment: au\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-mp4-part:\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\nvideo/x-av1:\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\n", + "direction": "sink", + "presence": "request", + "type": "GstQTMuxPad" + } + }, + "properties": { + "streamable": { + "blurb": "If set to true, the output should be as if it is to be streamed and hence no indexes written or duration written. (DEPRECATED, only valid for fragmented MP4)", "conditionally-available": false, "construct": true, "construct-only": false, "controllable": false, - "default": "0", - "max": "-1", - "min": "0", + "default": "false", "mutable": "null", "readable": true, - "type": "guint", + "type": "gboolean", "writable": true } }, @@ -8824,6 +7828,7 @@ "author": "Thiago Sousa Santos ", "description": "Multiplex audio and video into a QuickTime file", "hierarchy": [ + "GstQTMuxElement", "GstQTMux", "GstAggregator", "GstElement", @@ -8871,6 +7876,69 @@ } }, "properties": { + "streamable": { + "blurb": "If set to true, the output should be as if it is to be streamed and hence no indexes written or duration written. (DEPRECATED, only valid for fragmented MP4)", + "conditionally-available": false, + "construct": true, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": true + } + }, + "rank": "primary" + }, + "rtpxqtdepay": { + "author": "Wim Taymans ", + "description": "Extracts Quicktime audio/video from RTP packets", + "hierarchy": [ + "GstRtpXQTDepay", + "GstRTPBaseDepayload", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Depayloader/Network", + "long-name": "RTP packet depayloader", + "pad-templates": { + "sink": { + "caps": "application/x-rtp:\n payload: [ 96, 127 ]\n media: { (string)audio, (string)video }\n clock-rate: [ 1, 2147483647 ]\n encoding-name: { (string)X-QT, (string)X-QUICKTIME }\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "ANY", + "direction": "src", + "presence": "always" + } + }, + "properties": {}, + "rank": "marginal" + } + }, + "filename": "gstisomp4", + "license": "LGPL", + "other-types": { + "GstQTMux": { + "hierarchy": [ + "GstQTMux", + "GstAggregator", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "interfaces": [ + "GstTagSetter", + "GstTagXmpWriter", + "GstPreset" + ], + "kind": "object", + "properties": { "dts-method": { "blurb": "Method to determine DTS time (DEPRECATED)", "conditionally-available": false, @@ -8945,6 +8013,18 @@ "type": "guint", "writable": true }, + "fragment-mode": { + "blurb": "How to to write fragments to the file. Only used when 'fragment-duration' is greather than 0", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "dash-or-mss (0)", + "mutable": "null", + "readable": true, + "type": "GstQTMuxFragmentMode", + "writable": true + }, "interleave-bytes": { "blurb": "Interleave between streams in bytes", "conditionally-available": false, @@ -9107,18 +8187,6 @@ "type": "guint64", "writable": true }, - "streamable": { - "blurb": "If set to true, the output should be as if it is to be streamed and hence no indexes written or duration written. (DEPRECATED, only valid for fragmented MP4)", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, "trak-timescale": { "blurb": "Timescale to use for the tracks (units per second, 0 is automatic)", "conditionally-available": false, @@ -9133,41 +8201,8 @@ "type": "guint", "writable": true } - }, - "rank": "primary" + } }, - "rtpxqtdepay": { - "author": "Wim Taymans ", - "description": "Extracts Quicktime audio/video from RTP packets", - "hierarchy": [ - "GstRtpXQTDepay", - "GstRTPBaseDepayload", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "klass": "Codec/Depayloader/Network", - "long-name": "RTP packet depayloader", - "pad-templates": { - "sink": { - "caps": "application/x-rtp:\n payload: [ 96, 127 ]\n media: { (string)audio, (string)video }\n clock-rate: [ 1, 2147483647 ]\n encoding-name: { (string)X-QT, (string)X-QUICKTIME }\n", - "direction": "sink", - "presence": "always" - }, - "src": { - "caps": "ANY", - "direction": "src", - "presence": "always" - } - }, - "properties": {}, - "rank": "marginal" - } - }, - "filename": "gstisomp4", - "license": "LGPL", - "other-types": { "GstQTMuxDtsMethods": { "kind": "enum", "values": [ @@ -9192,13 +8227,13 @@ "kind": "enum", "values": [ { - "desc": "dash-or-mss", - "name": "Dash or Smoothstreaming", + "desc": "Dash or Smoothstreaming", + "name": "dash-or-mss", "value": "0" }, { - "desc": "first-moov-then-finalise", - "name": "First MOOV Fragment Then Finalise", + "desc": "First MOOV Fragment Then Finalise", + "name": "first-moov-then-finalise", "value": "1" } ] diff --git a/gst/isomp4/gstqtmux-doc.c b/gst/isomp4/gstqtmux-doc.c index c290981..a3906c4 100644 --- a/gst/isomp4/gstqtmux-doc.c +++ b/gst/isomp4/gstqtmux-doc.c @@ -43,6 +43,81 @@ * SOFTWARE. */ +/* ============================= qtmux ==================================== */ + +/** + * SECTION:element-qtmux + * @title: qtmux + * @short_description: Muxer for quicktime(.mov) files + * + * This element merges streams (audio and video) into QuickTime(.mov) files. + * + * The following background intends to explain why various similar muxers + * are present in this plugin. + * + * The [QuickTime file format specification](http://www.apple.com/quicktime/resources/qtfileformat.pdf) + * served as basis for the MP4 file format specification (mp4mux), and as such + * the QuickTime file structure is nearly identical to the so-called ISO Base + * Media file format defined in ISO 14496-12 (except for some media specific + * parts). + * + * In turn, the latter ISO Base Media format was further specialized as a + * Motion JPEG-2000 file format in ISO 15444-3 (mj2mux) + * and in various 3GPP(2) specs (gppmux). + * The fragmented file features defined (only) in ISO Base Media are used by + * ISMV files making up (a.o.) Smooth Streaming (ismlmux). + * + * A few properties (#GstQTMux:movie-timescale, #GstQTMux:trak-timescale, + * #GstQTMuxPad:trak-timescale) allow adjusting some technical parameters, + * which might be useful in (rare) cases to resolve compatibility issues in + * some situations. + * + * Some other properties influence the result more fundamentally. + * A typical mov/mp4 file's metadata (aka moov) is located at the end of the + * file, somewhat contrary to this usually being called "the header". + * However, a #GstQTMux:faststart file will (with some effort) arrange this to + * be located near start of the file, which then allows it e.g. to be played + * while downloading. Alternatively, rather than having one chunk of metadata at + * start (or end), there can be some metadata at start and most of the other + * data can be spread out into fragments of #GstQTMux:fragment-duration. + * If such fragmented layout is intended for streaming purposes, then + * #GstQTMuxElement:streamable allows foregoing to add index metadata (at the end of + * file). + * + * When the maximum duration to be recorded can be known in advance, #GstQTMuxElement + * also supports a 'Robust Muxing' mode. In robust muxing mode, space for the + * headers are reserved at the start of muxing, and rewritten at a configurable + * interval, so that the output file is always playable, even if the recording + * is interrupted uncleanly by a crash. Robust muxing mode requires a seekable + * output, such as filesink, because it needs to rewrite the start of the file. + * + * To enable robust muxing mode, set the #GstQTMux:reserved-moov-update-period + * and #GstQTMux:reserved-max-duration property. Also present is the + * #GstQTMux:reserved-bytes-per-sec property, which can be increased if + * for some reason the default is not large enough and the initial reserved + * space for headers is too small. Applications can monitor the + * #GstQTMux:reserved-duration-remaining property to see how close to full + * the reserved space is becoming. + * + * Applications that wish to be able to use/edit a file while it is being + * written to by live content, can use the "Robust Prefill Muxing" mode. That + * mode is a variant of the "Robust Muxing" mode in that it will pre-allocate a + * completely valid header from the start for all tracks (i.e. it appears as + * though the file is "reserved-max-duration" long with all samples + * present). This mode can be enabled by setting the + * #GstQTMux:reserved-moov-update-period and #GstQTMux:reserved-prefill + * properties. Note that this mode is only possible with input streams that have + * a fixed sample size (such as raw audio and Prores Video) and that don't + * have reordered samples. + * + * ## Example pipelines + * |[ + * gst-launch-1.0 v4l2src num-buffers=500 ! video/x-raw,width=320,height=240 ! videoconvert ! qtmux ! filesink location=video.mov + * ]| + * Records a video stream captured from a v4l2 device and muxes it into a qt file. + * + */ + /* ============================= mp4mux ==================================== */ /** @@ -67,18 +142,18 @@ * The fragmented file features defined (only) in ISO Base Media are used by * ISMV files making up (a.o.) Smooth Streaming (ismlmux). * - * A few properties (#GstMP4Mux:movie-timescale, #GstMP4Mux:trak-timescale) + * A few properties (#GstQTMux:movie-timescale, #GstQTMux:trak-timescale) * allow adjusting some technical parameters, which might be useful in (rare) * cases to resolve compatibility issues in some situations. * * Some other properties influence the result more fundamentally. * A typical mov/mp4 file's metadata (aka moov) is located at the end of the * file, somewhat contrary to this usually being called "the header". - * However, a #GstMP4Mux:faststart file will (with some effort) arrange this to + * However, a #GstQTMux:faststart file will (with some effort) arrange this to * be located near start of the file, which then allows it e.g. to be played * while downloading. Alternatively, rather than having one chunk of metadata at * start (or end), there can be some metadata at start and most of the other - * data can be spread out into fragments of #GstMP4Mux:fragment-duration. + * data can be spread out into fragments of #GstQTMux:fragment-duration. * If such fragmented layout is intended for streaming purposes, then * #GstMP4Mux:streamable allows foregoing to add index metadata (at the end of * file). @@ -116,18 +191,18 @@ * The fragmented file features defined (only) in ISO Base Media are used by * ISMV files making up (a.o.) Smooth Streaming (ismlmux). * - * A few properties (#Gst3GPPMux:movie-timescale, #Gst3GPPMux:trak-timescale) + * A few properties (#GstQTMux:movie-timescale, #GstQTMux:trak-timescale) * allow adjusting some technical parameters, which might be useful in (rare) * cases to resolve compatibility issues in some situations. * * Some other properties influence the result more fundamentally. * A typical mov/mp4 file's metadata (aka moov) is located at the end of the file, * somewhat contrary to this usually being called "the header". However, a - * #Gst3GPPMux:faststart file will (with some effort) arrange this to be located + * #GstQTMux:faststart file will (with some effort) arrange this to be located * near start of the file, which then allows it e.g. to be played while * downloading. Alternatively, rather than having one chunk of metadata at start * (or end), there can be some metadata at start and most of the other data can - * be spread out into fragments of #Gst3GPPMux:fragment-duration. If such + * be spread out into fragments of #GstQTMux:fragment-duration. If such * fragmented layout is intended for streaming purposes, then * #Gst3GPPMux:streamable allows foregoing to add index metadata (at the end of * file). @@ -166,18 +241,18 @@ * The fragmented file features defined (only) in ISO Base Media are used by * ISMV files making up (a.o.) Smooth Streaming (ismlmux). * - * A few properties (#GstMJ2Mux:movie-timescale, #GstMJ2Mux:trak-timescale) + * A few properties (#GstQTMux:movie-timescale, #GstQTMux:trak-timescale) * allow adjusting some technical parameters, which might be useful in (rare) * cases to resolve compatibility issues in some situations. * * Some other properties influence the result more fundamentally. * A typical mov/mp4 file's metadata (aka moov) is located at the end of the file, * somewhat contrary to this usually being called "the header". However, a - * #GstMJ2Mux:faststart file will (with some effort) arrange this to be located + * #GstQTMux:faststart file will (with some effort) arrange this to be located * near start of the file, which then allows it e.g. to be played while * downloading. Alternatively, rather than having one chunk of metadata at start * (or end), there can be some metadata at start and most of the other data can - * be spread out into fragments of #GstMJ2Mux:fragment-duration. If such + * be spread out into fragments of #GstQTMux:fragment-duration. If such * fragmented layout is intended for streaming purposes, then * #GstMJ2Mux:streamable allows foregoing to add index metadata (at the end of * file). @@ -216,18 +291,18 @@ * The fragmented file features defined (only) in ISO Base Media are used by * ISMV files making up (a.o.) Smooth Streaming (ismlmux). * - * A few properties (#GstISMLMux:movie-timescale, #GstISMLMux:trak-timescale) + * A few properties (#GstQTMux:movie-timescale, #GstQTMux:trak-timescale) * allow adjusting some technical parameters, which might be useful in (rare) * cases to resolve compatibility issues in some situations. * * Some other properties influence the result more fundamentally. * A typical mov/mp4 file's metadata (aka moov) is located at the end of the file, * somewhat contrary to this usually being called "the header". However, a - * #GstISMLMux:faststart file will (with some effort) arrange this to be located + * #GstQTMux:faststart file will (with some effort) arrange this to be located * near start of the file, which then allows it e.g. to be played while * downloading. Alternatively, rather than having one chunk of metadata at start * (or end), there can be some metadata at start and most of the other data can - * be spread out into fragments of #GstISMLMux:fragment-duration. If such + * be spread out into fragments of #GstQTMux:fragment-duration. If such * fragmented layout is intended for streaming purposes, then * #GstISMLMux:streamable allows foregoing to add index metadata (at the end of * file). diff --git a/gst/isomp4/gstqtmux-doc.h b/gst/isomp4/gstqtmux-doc.h index 9d12164..c6f8baa 100644 --- a/gst/isomp4/gstqtmux-doc.h +++ b/gst/isomp4/gstqtmux-doc.h @@ -45,6 +45,7 @@ #error "This header is for gtk-doc only and not supposed to be included" +typedef struct _GstQTMuxElement GstQTMuxElement; typedef struct _GstMP4Mux GstMP4Mux; typedef struct _Gst3GPPMux Gst3GPPMux; typedef struct _GstISMLMux GstISMLMux; diff --git a/gst/isomp4/gstqtmux.c b/gst/isomp4/gstqtmux.c index beecacf..f8ef037 100644 --- a/gst/isomp4/gstqtmux.c +++ b/gst/isomp4/gstqtmux.c @@ -46,76 +46,9 @@ /** - * SECTION:element-qtmux - * @title: qtmux - * @short_description: Muxer for quicktime(.mov) files - * - * This element merges streams (audio and video) into QuickTime(.mov) files. - * - * The following background intends to explain why various similar muxers - * are present in this plugin. - * - * The [QuickTime file format specification](http://www.apple.com/quicktime/resources/qtfileformat.pdf) - * served as basis for the MP4 file format specification (mp4mux), and as such - * the QuickTime file structure is nearly identical to the so-called ISO Base - * Media file format defined in ISO 14496-12 (except for some media specific - * parts). - * - * In turn, the latter ISO Base Media format was further specialized as a - * Motion JPEG-2000 file format in ISO 15444-3 (mj2mux) - * and in various 3GPP(2) specs (gppmux). - * The fragmented file features defined (only) in ISO Base Media are used by - * ISMV files making up (a.o.) Smooth Streaming (ismlmux). - * - * A few properties (#GstQTMux:movie-timescale, #GstQTMux:trak-timescale, - * #GstQTMuxPad:trak-timescale) allow adjusting some technical parameters, - * which might be useful in (rare) cases to resolve compatibility issues in - * some situations. - * - * Some other properties influence the result more fundamentally. - * A typical mov/mp4 file's metadata (aka moov) is located at the end of the - * file, somewhat contrary to this usually being called "the header". - * However, a #GstQTMux:faststart file will (with some effort) arrange this to - * be located near start of the file, which then allows it e.g. to be played - * while downloading. Alternatively, rather than having one chunk of metadata at - * start (or end), there can be some metadata at start and most of the other - * data can be spread out into fragments of #GstQTMux:fragment-duration. - * If such fragmented layout is intended for streaming purposes, then - * #GstQTMux:streamable allows foregoing to add index metadata (at the end of - * file). - * - * When the maximum duration to be recorded can be known in advance, #GstQTMux - * also supports a 'Robust Muxing' mode. In robust muxing mode, space for the - * headers are reserved at the start of muxing, and rewritten at a configurable - * interval, so that the output file is always playable, even if the recording - * is interrupted uncleanly by a crash. Robust muxing mode requires a seekable - * output, such as filesink, because it needs to rewrite the start of the file. - * - * To enable robust muxing mode, set the #GstQTMux:reserved-moov-update-period - * and #GstQTMux:reserved-max-duration property. Also present is the - * #GstQTMux:reserved-bytes-per-sec property, which can be increased if - * for some reason the default is not large enough and the initial reserved - * space for headers is too small. Applications can monitor the - * #GstQTMux:reserved-duration-remaining property to see how close to full - * the reserved space is becoming. - * - * Applications that wish to be able to use/edit a file while it is being - * written to by live content, can use the "Robust Prefill Muxing" mode. That - * mode is a variant of the "Robust Muxing" mode in that it will pre-allocate a - * completely valid header from the start for all tracks (i.e. it appears as - * though the file is "reserved-max-duration" long with all samples - * present). This mode can be enabled by setting the - * #GstQTMux:reserved-moov-update-period and #GstQTMux:reserved-prefill - * properties. Note that this mode is only possible with input streams that have - * a fixed sample size (such as raw audio and Prores Video) and that don't - * have reordered samples. - * - * ## Example pipelines - * |[ - * gst-launch-1.0 v4l2src num-buffers=500 ! video/x-raw,width=320,height=240 ! videoconvert ! qtmux ! filesink location=video.mov - * ]| - * Records a video stream captured from a v4l2 device and muxes it into a qt file. - * + * SECTION:GstQTMux + * @title: GstQTMux + * @short_description: Muxer for ISO MP4-based files */ /* @@ -381,7 +314,6 @@ enum PROP_FAST_START_TEMP_FILE, PROP_MOOV_RECOV_FILE, PROP_FRAGMENT_DURATION, - PROP_STREAMABLE, PROP_RESERVED_MAX_DURATION, PROP_RESERVED_DURATION_REMAINING, PROP_RESERVED_MOOV_UPDATE_PERIOD, @@ -469,7 +401,7 @@ static void gst_qt_mux_update_edit_lists (GstQTMux * qtmux); static GstElementClass *parent_class = NULL; static void -gst_qt_mux_subclass_base_init (gpointer g_class) +gst_qt_mux_base_init (gpointer g_class) { GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); GstQTMuxClass *klass = (GstQTMuxClass *) g_class; @@ -482,7 +414,8 @@ gst_qt_mux_subclass_base_init (gpointer g_class) params = (GstQTMuxClassParams *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), GST_QT_MUX_PARAMS_QDATA); - g_assert (params != NULL); + if (!params) + return; /* construct the element details struct */ longname = g_strdup_printf ("%s Muxer", params->prop->long_name); @@ -531,16 +464,11 @@ gst_qt_mux_subclass_base_init (gpointer g_class) } static void -gst_qt_mux_subclass_class_init (GstQTMuxClass * klass) +gst_qt_mux_class_init (GstQTMuxClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; GstAggregatorClass *gstagg_class = GST_AGGREGATOR_CLASS (klass); - GParamFlags streamable_flags; - const gchar *streamable_desc; - gboolean streamable; -#define STREAMABLE_DESC "If set to true, the output should be as if it is to "\ - "be streamed and hence no indexes written or duration written." gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; @@ -551,17 +479,6 @@ gst_qt_mux_subclass_class_init (GstQTMuxClass * klass) gobject_class->get_property = gst_qt_mux_get_property; gobject_class->set_property = gst_qt_mux_set_property; - streamable_flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT; - if (klass->format == GST_QT_MUX_FORMAT_ISML) { - streamable_desc = STREAMABLE_DESC; - streamable = DEFAULT_STREAMABLE; - } else { - streamable_desc = - STREAMABLE_DESC " (DEPRECATED, only valid for fragmented MP4)"; - streamable_flags |= G_PARAM_DEPRECATED; - streamable = FALSE; - } - g_object_class_install_property (gobject_class, PROP_MOVIE_TIMESCALE, g_param_spec_uint ("movie-timescale", "Movie timescale", "Timescale to use in the movie (units per second, 0 == default)", @@ -611,9 +528,6 @@ gst_qt_mux_subclass_class_init (GstQTMuxClass * klass) 0, G_MAXUINT32, klass->format == GST_QT_MUX_FORMAT_ISML ? 2000 : DEFAULT_FRAGMENT_DURATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_STREAMABLE, - g_param_spec_boolean ("streamable", "Streamable", streamable_desc, - streamable, streamable_flags | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_RESERVED_MAX_DURATION, g_param_spec_uint64 ("reserved-max-duration", "Reserved maximum file duration (ns)", @@ -914,7 +828,7 @@ gst_qt_mux_clip_running_time (GstAggregator * agg, } static void -gst_qt_mux_subclass_init (GstQTMux * qtmux, GstQTMuxClass * qtmux_klass) +gst_qt_mux_init (GstQTMux * qtmux, GstQTMuxClass * qtmux_klass) { /* properties set to default upon construction */ @@ -7013,9 +6927,6 @@ gst_qt_mux_get_property (GObject * object, case PROP_FRAGMENT_DURATION: g_value_set_uint (value, qtmux->fragment_duration); break; - case PROP_STREAMABLE: - g_value_set_boolean (value, qtmux->streamable); - break; case PROP_RESERVED_MAX_DURATION: g_value_set_uint64 (value, qtmux->reserved_max_duration); break; @@ -7132,14 +7043,6 @@ gst_qt_mux_set_property (GObject * object, case PROP_FRAGMENT_DURATION: qtmux->fragment_duration = g_value_get_uint (value); break; - case PROP_STREAMABLE:{ - GstQTMuxClass *qtmux_klass = - (GstQTMuxClass *) (G_OBJECT_GET_CLASS (qtmux)); - if (qtmux_klass->format == GST_QT_MUX_FORMAT_ISML) { - qtmux->streamable = g_value_get_boolean (value); - } - break; - } case PROP_RESERVED_MAX_DURATION: qtmux->reserved_max_duration = g_value_get_uint64 (value); break; @@ -7212,31 +7115,99 @@ gst_qt_mux_stop (GstAggregator * agg) return TRUE; } -G_DEFINE_TYPE (GstQTMux, gst_qt_mux, GST_TYPE_AGGREGATOR); +enum +{ + PROP_SUBCLASS_STREAMABLE = 1, +}; static void -gst_qt_mux_class_init (GstQTMuxClass * klass) +gst_qt_mux_subclass_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) { + GstQTMux *qtmux = GST_QT_MUX_CAST (object); + + GST_OBJECT_LOCK (qtmux); + switch (prop_id) { + case PROP_SUBCLASS_STREAMABLE:{ + GstQTMuxClass *qtmux_klass = + (GstQTMuxClass *) (G_OBJECT_GET_CLASS (qtmux)); + if (qtmux_klass->format == GST_QT_MUX_FORMAT_ISML) { + qtmux->streamable = g_value_get_boolean (value); + } + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + GST_OBJECT_UNLOCK (qtmux); } static void -gst_qt_mux_init (GstQTMux * qtmux) +gst_qt_mux_subclass_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstQTMux *qtmux = GST_QT_MUX_CAST (object); + + GST_OBJECT_LOCK (qtmux); + switch (prop_id) { + case PROP_SUBCLASS_STREAMABLE: + g_value_set_boolean (value, qtmux->streamable); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + GST_OBJECT_UNLOCK (qtmux); +} + +static void +gst_qt_mux_subclass_class_init (GstQTMuxClass * klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + GParamFlags streamable_flags; + const gchar *streamable_desc; + gboolean streamable; +#define STREAMABLE_DESC "If set to true, the output should be as if it is to "\ + "be streamed and hence no indexes written or duration written." + + gobject_class->set_property = gst_qt_mux_subclass_set_property; + gobject_class->get_property = gst_qt_mux_subclass_get_property; + + streamable_flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT; + if (klass->format == GST_QT_MUX_FORMAT_ISML) { + streamable_desc = STREAMABLE_DESC; + streamable = DEFAULT_STREAMABLE; + } else { + streamable_desc = + STREAMABLE_DESC " (DEPRECATED, only valid for fragmented MP4)"; + streamable_flags |= G_PARAM_DEPRECATED; + streamable = FALSE; + } + + g_object_class_install_property (gobject_class, PROP_SUBCLASS_STREAMABLE, + g_param_spec_boolean ("streamable", "Streamable", streamable_desc, + streamable, streamable_flags | G_PARAM_STATIC_STRINGS)); +} + +static void +gst_qt_mux_subclass_init (GstQTMux * qtmux) { } gboolean gst_qt_mux_register (GstPlugin * plugin) { - GTypeInfo typeinfo = { + GTypeInfo parent_typeinfo = { sizeof (GstQTMuxClass), - (GBaseInitFunc) gst_qt_mux_subclass_base_init, + (GBaseInitFunc) gst_qt_mux_base_init, NULL, - (GClassInitFunc) gst_qt_mux_subclass_class_init, + (GClassInitFunc) gst_qt_mux_class_init, NULL, NULL, sizeof (GstQTMux), 0, - (GInstanceInitFunc) gst_qt_mux_subclass_init, + (GInstanceInitFunc) gst_qt_mux_init, }; static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL @@ -7247,7 +7218,7 @@ gst_qt_mux_register (GstPlugin * plugin) static const GInterfaceInfo preset_info = { NULL, NULL, NULL }; - GType type; + GType parent_type; GstQTMuxFormat format; GstQTMuxClassParams *params; guint i = 0; @@ -7256,7 +7227,30 @@ gst_qt_mux_register (GstPlugin * plugin) GST_LOG ("Registering muxers"); + parent_type = + g_type_register_static (GST_TYPE_AGGREGATOR, "GstQTMux", + &parent_typeinfo, 0); + g_type_add_interface_static (parent_type, GST_TYPE_TAG_SETTER, + &tag_setter_info); + g_type_add_interface_static (parent_type, GST_TYPE_TAG_XMP_WRITER, + &tag_xmp_writer_info); + g_type_add_interface_static (parent_type, GST_TYPE_PRESET, &preset_info); + + gst_type_mark_as_plugin_api (parent_type, 0); + while (TRUE) { + GType type; + GTypeInfo subclass_typeinfo = { + sizeof (GstQTMuxClass), + NULL, + NULL, + (GClassInitFunc) gst_qt_mux_subclass_class_init, + NULL, + NULL, + sizeof (GstQTMux), + 0, + (GInstanceInitFunc) gst_qt_mux_subclass_init, + }; GstQTMuxFormatProp *prop; GstCaps *subtitle_caps, *caption_caps; @@ -7286,13 +7280,9 @@ gst_qt_mux_register (GstPlugin * plugin) /* create the type now */ type = - g_type_register_static (gst_qt_mux_get_type (), prop->type_name, - &typeinfo, 0); + g_type_register_static (parent_type, prop->type_name, + &subclass_typeinfo, 0); g_type_set_qdata (type, GST_QT_MUX_PARAMS_QDATA, (gpointer) params); - g_type_add_interface_static (type, GST_TYPE_TAG_SETTER, &tag_setter_info); - g_type_add_interface_static (type, GST_TYPE_TAG_XMP_WRITER, - &tag_xmp_writer_info); - g_type_add_interface_static (type, GST_TYPE_PRESET, &preset_info); if (!gst_element_register (plugin, prop->name, prop->rank, type)) return FALSE; diff --git a/gst/isomp4/gstqtmux.h b/gst/isomp4/gstqtmux.h index a90b8b8..ca6c027 100644 --- a/gst/isomp4/gstqtmux.h +++ b/gst/isomp4/gstqtmux.h @@ -204,9 +204,9 @@ typedef enum _GstQtMuxMode { /** * GstQTMuxFragmentMode: - * GST_QT_MUX_FRAGMENT_DASH_OR_MSS: dash-or-mss - * GST_QT_MUX_FRAGMENT_FIRST_MOOV_THEN_FINALISE: first-moov-then-finalise - * GST_QT_MUX_FRAGMENT_STREAMABLE: streamable (private value) + * @GST_QT_MUX_FRAGMENT_DASH_OR_MSS: dash-or-mss + * @GST_QT_MUX_FRAGMENT_FIRST_MOOV_THEN_FINALISE: first-moov-then-finalise + * @GST_QT_MUX_FRAGMENT_STREAMABLE: streamable (private value) * * Since: 1.20 */