diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2018-02-02 13:51:49 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2018-02-09 11:05:02 +0200 |
commit | e7177059e91ec5c2b9f1b67e0ed2ed09493ffb83 (patch) | |
tree | eabd04affb5a20acf6cb5c667956f364945890e3 | |
parent | 4fd8635983f1f9c6124ed148a5e145fc966b4584 (diff) |
qtmux: Add support for muxing svmi atom for stereoscopic video information
https://bugzilla.gnome.org/show_bug.cgi?id=793120
-rw-r--r-- | gst/isomp4/atoms.c | 55 | ||||
-rw-r--r-- | gst/isomp4/atoms.h | 13 | ||||
-rw-r--r-- | gst/isomp4/gstqtmux.c | 31 |
3 files changed, 99 insertions, 0 deletions
diff --git a/gst/isomp4/atoms.c b/gst/isomp4/atoms.c index eb90b7929..4ca69274b 100644 --- a/gst/isomp4/atoms.c +++ b/gst/isomp4/atoms.c @@ -729,6 +729,33 @@ atom_ctts_free (AtomCTTS * ctts) } static void +atom_svmi_init (AtomSVMI * svmi) +{ + guint8 flags[3] = { 0, 0, 0 }; + + atom_full_init (&svmi->header, FOURCC_svmi, 0, 0, 0, flags); + svmi->stereoscopic_composition_type = 0x00; + svmi->is_left_first = FALSE; +} + +AtomSVMI * +atom_svmi_new (guint8 stereoscopic_composition_type, gboolean is_left_first) +{ + AtomSVMI *svmi = g_new0 (AtomSVMI, 1); + + atom_svmi_init (svmi); + svmi->stereoscopic_composition_type = stereoscopic_composition_type; + svmi->is_left_first = is_left_first; + return svmi; +} + +static void +atom_svmi_free (AtomSVMI * svmi) +{ + g_free (svmi); +} + +static void atom_stts_init (AtomSTTS * stts) { guint8 flags[3] = { 0, 0, 0 }; @@ -822,6 +849,7 @@ atom_stbl_init (AtomSTBL * stbl) atom_stsz_init (&stbl->stsz); atom_stsc_init (&stbl->stsc); stbl->ctts = NULL; + stbl->svmi = NULL; atom_co64_init (&stbl->stco64); } @@ -838,6 +866,9 @@ atom_stbl_clear (AtomSTBL * stbl) if (stbl->ctts) { atom_ctts_free (stbl->ctts); } + if (stbl->svmi) { + atom_svmi_free (stbl->svmi); + } atom_stco64_clear (&stbl->stco64); } @@ -2293,6 +2324,25 @@ atom_ctts_copy_data (AtomCTTS * ctts, guint8 ** buffer, guint64 * size, } guint64 +atom_svmi_copy_data (AtomSVMI * svmi, guint8 ** buffer, guint64 * size, + guint64 * offset) +{ + guint64 original_offset = *offset; + + if (!atom_full_copy_data (&svmi->header, buffer, size, offset)) { + return 0; + } + + prop_copy_uint8 (svmi->stereoscopic_composition_type, buffer, size, offset); + prop_copy_uint8 (svmi->is_left_first ? 1 : 0, buffer, size, offset); + /* stereo-mono change count */ + prop_copy_uint32 (0, buffer, size, offset); + + atom_write_size (buffer, size, offset, original_offset); + return *offset - original_offset; +} + +guint64 atom_stco64_copy_data (AtomSTCO64 * stco64, guint8 ** buffer, guint64 * size, guint64 * offset) { @@ -2454,6 +2504,11 @@ atom_stbl_copy_data (AtomSTBL * stbl, guint8 ** buffer, guint64 * size, return 0; } } + if (stbl->svmi) { + if (!atom_svmi_copy_data (stbl->svmi, buffer, size, offset)) { + return 0; + } + } if (!atom_stco64_copy_data (&stbl->stco64, buffer, size, offset)) { return 0; } diff --git a/gst/isomp4/atoms.h b/gst/isomp4/atoms.h index f73cb9f05..27d249431 100644 --- a/gst/isomp4/atoms.h +++ b/gst/isomp4/atoms.h @@ -563,6 +563,14 @@ typedef struct _AtomCTTS gboolean do_pts; } AtomCTTS; +typedef struct _AtomSVMI +{ + AtomFull header; + + guint8 stereoscopic_composition_type; + gboolean is_left_first; +} AtomSVMI; + typedef struct _AtomSTBL { Atom header; @@ -574,6 +582,8 @@ typedef struct _AtomSTBL AtomSTSZ stsz; /* NULL if not present */ AtomCTTS *ctts; + /* NULL if not present */ + AtomSVMI *svmi; AtomSTCO64 stco64; } AtomSTBL; @@ -960,6 +970,9 @@ guint64 atom_stsz_copy_data (AtomSTSZ *atom, guint8 **buffer, guint64 *size, guint64* offset); guint64 atom_ctts_copy_data (AtomCTTS *atom, guint8 **buffer, guint64 *size, guint64* offset); +guint64 atom_svmi_copy_data (AtomSVMI *atom, guint8 **buffer, + guint64 *size, guint64* offset); +AtomSVMI * atom_svmi_new (guint8 stereoscopic_composition_type, gboolean is_left_first); guint64 atom_stco64_copy_data (AtomSTCO64 *atom, guint8 **buffer, guint64 *size, guint64* offset); AtomMOOF* atom_moof_new (AtomsContext *context, guint32 sequence_number); diff --git a/gst/isomp4/gstqtmux.c b/gst/isomp4/gstqtmux.c index 09357be1b..74e177c3d 100644 --- a/gst/isomp4/gstqtmux.c +++ b/gst/isomp4/gstqtmux.c @@ -5189,6 +5189,7 @@ gst_qt_mux_video_sink_set_caps (GstQTPad * qtpad, GstCaps * caps) GList *ext_atom_list = NULL; gboolean sync = FALSE; int par_num, par_den; + const gchar *multiview_mode; /* does not go well to renegotiate stream mid-way, unless * the old caps are a subset of the new one (this means upstream @@ -5258,6 +5259,36 @@ gst_qt_mux_video_sink_set_caps (GstQTPad * qtpad, GstCaps * caps) GST_DEBUG_OBJECT (qtmux, "Rate of video track selected: %" G_GUINT32_FORMAT, rate); + multiview_mode = gst_structure_get_string (structure, "multiview-mode"); + if (multiview_mode && !qtpad->trak->mdia.minf.stbl.svmi) { + GstVideoMultiviewMode mode; + GstVideoMultiviewFlags flags = 0; + + mode = gst_video_multiview_mode_from_caps_string (multiview_mode); + gst_structure_get_flagset (structure, "multiview-flags", &flags, NULL); + switch (mode) { + case GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE: + qtpad->trak->mdia.minf.stbl.svmi = + atom_svmi_new (0, + flags & GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST); + break; + case GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED: + qtpad->trak->mdia.minf.stbl.svmi = + atom_svmi_new (1, + flags & GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST); + break; + case GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME: + qtpad->trak->mdia.minf.stbl.svmi = + atom_svmi_new (2, + flags & GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST); + break; + default: + GST_DEBUG_OBJECT (qtmux, "Unsupported multiview-mode %s", + multiview_mode); + break; + } + } + /* set common properties */ entry.width = width; entry.height = height; |