From 12ad37fdb364b20cf0d93a37d3c9c74a6b50d48c Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Sun, 8 Jan 2017 01:13:32 +1100 Subject: [PATCH] qtmux: Write tfdt atom into fragmented files. The DASH spec requires that tfdt atoms be present, so write one out. ISO/IEC 23009-1:2014 6.3.4.2 https://bugzilla.gnome.org/show_bug.cgi?id=708221 --- gst/isomp4/atoms.c | 42 ++++++++++++++++++++++++++++++++++++++++++ gst/isomp4/atoms.h | 10 ++++++++++ gst/isomp4/gstqtmux.c | 1 + 3 files changed, 53 insertions(+) diff --git a/gst/isomp4/atoms.c b/gst/isomp4/atoms.c index d110333..3bc6be9 100644 --- a/gst/isomp4/atoms.c +++ b/gst/isomp4/atoms.c @@ -4302,6 +4302,26 @@ atom_tfhd_copy_data (AtomTFHD * tfhd, guint8 ** buffer, guint64 * size, } static guint64 +atom_tfdt_copy_data (AtomTFDT * tfdt, guint8 ** buffer, guint64 * size, + guint64 * offset) +{ + guint64 original_offset = *offset; + + if (!atom_full_copy_data (&tfdt->header, buffer, size, offset)) { + return 0; + } + + /* 32-bit time if version == 0 else 64-bit: */ + if (tfdt->header.version == 0) + prop_copy_uint32 (tfdt->base_media_decode_time, buffer, size, offset); + else + prop_copy_uint64 (tfdt->base_media_decode_time, buffer, size, offset); + + atom_write_size (buffer, size, offset, original_offset); + return *offset - original_offset; +} + +static guint64 atom_trun_copy_data (AtomTRUN * trun, guint8 ** buffer, guint64 * size, guint64 * offset, guint32 * data_offset) { @@ -4382,6 +4402,9 @@ atom_traf_copy_data (AtomTRAF * traf, guint8 ** buffer, guint64 * size, if (!atom_tfhd_copy_data (&traf->tfhd, buffer, size, offset)) { return 0; } + if (!atom_tfdt_copy_data (&traf->tfdt, buffer, size, offset)) { + return 0; + } walker = g_list_first (traf->truns); while (walker != NULL) { @@ -4455,6 +4478,15 @@ atom_tfhd_init (AtomTFHD * tfhd, guint32 track_ID) } static void +atom_tfdt_init (AtomTFDT * tfdt) +{ + guint8 flags[3] = { 0, 0, 0 }; + atom_full_init (&tfdt->header, FOURCC_tfdt, 0, 0, 0, flags); + + tfdt->base_media_decode_time = 0; +} + +static void atom_trun_init (AtomTRUN * trun) { guint8 flags[3] = { 0, 0, 0 }; @@ -4528,6 +4560,7 @@ static void atom_traf_init (AtomTRAF * traf, AtomsContext * context, guint32 track_ID) { atom_header_set (&traf->header, FOURCC_traf, 0, 0); + atom_tfdt_init (&traf->tfdt); atom_tfhd_init (&traf->tfhd, track_ID); traf->truns = NULL; @@ -4544,6 +4577,15 @@ atom_traf_new (AtomsContext * context, guint32 track_ID) return traf; } +void +atom_traf_set_base_decode_time (AtomTRAF * traf, guint64 base_decode_time) +{ + traf->tfdt.base_media_decode_time = base_decode_time; + /* If we need to write a 64-bit tfdt, set the atom version */ + if (base_decode_time > G_MAXUINT32) + traf->tfdt.header.version = 1; +} + static void atom_traf_add_trun (AtomTRAF * traf, AtomTRUN * trun) { diff --git a/gst/isomp4/atoms.h b/gst/isomp4/atoms.h index b563116..8f2ea1e 100644 --- a/gst/isomp4/atoms.h +++ b/gst/isomp4/atoms.h @@ -761,6 +761,13 @@ typedef struct _AtomTFHD guint32 default_sample_flags; } AtomTFHD; +typedef struct _AtomTFDT +{ + AtomFull header; + + guint64 base_media_decode_time; +} AtomTFDT; + typedef struct _TRUNSampleEntry { guint32 sample_duration; @@ -798,6 +805,8 @@ typedef struct _AtomTRAF AtomTFHD tfhd; + AtomTFDT tfdt; + /* list of AtomTRUN */ GList *truns; /* list of AtomSDTP */ @@ -948,6 +957,7 @@ void atom_moof_free (AtomMOOF *moof); guint64 atom_moof_copy_data (AtomMOOF *moof, guint8 **buffer, guint64 *size, guint64* offset); AtomTRAF * atom_traf_new (AtomsContext * context, guint32 track_ID); void atom_traf_free (AtomTRAF * traf); +void atom_traf_set_base_decode_time (AtomTRAF * traf, guint64 base_decode_time); void atom_traf_add_samples (AtomTRAF * traf, guint32 delta, guint32 size, gboolean sync, gint64 pts_offset, gboolean sdtp_sync); diff --git a/gst/isomp4/gstqtmux.c b/gst/isomp4/gstqtmux.c index 810c1dd..b8fdf17 100644 --- a/gst/isomp4/gstqtmux.c +++ b/gst/isomp4/gstqtmux.c @@ -2848,6 +2848,7 @@ init: pad->tfra = atom_tfra_new (qtmux->context, atom_trak_get_id (pad->trak)); atom_mfra_add_tfra (qtmux->mfra, pad->tfra); } + atom_traf_set_base_decode_time (pad->traf, dts); } /* add buffer and metadata */ -- 2.7.4