mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 04:56:24 +00:00
qtmux: Add support for muxing svmi atom for stereoscopic video information
https://bugzilla.gnome.org/show_bug.cgi?id=793120
This commit is contained in:
parent
4fd8635983
commit
e7177059e9
3 changed files with 99 additions and 0 deletions
|
@ -728,6 +728,33 @@ atom_ctts_free (AtomCTTS * ctts)
|
||||||
g_free (ctts);
|
g_free (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
|
static void
|
||||||
atom_stts_init (AtomSTTS * stts)
|
atom_stts_init (AtomSTTS * stts)
|
||||||
{
|
{
|
||||||
|
@ -822,6 +849,7 @@ atom_stbl_init (AtomSTBL * stbl)
|
||||||
atom_stsz_init (&stbl->stsz);
|
atom_stsz_init (&stbl->stsz);
|
||||||
atom_stsc_init (&stbl->stsc);
|
atom_stsc_init (&stbl->stsc);
|
||||||
stbl->ctts = NULL;
|
stbl->ctts = NULL;
|
||||||
|
stbl->svmi = NULL;
|
||||||
|
|
||||||
atom_co64_init (&stbl->stco64);
|
atom_co64_init (&stbl->stco64);
|
||||||
}
|
}
|
||||||
|
@ -838,6 +866,9 @@ atom_stbl_clear (AtomSTBL * stbl)
|
||||||
if (stbl->ctts) {
|
if (stbl->ctts) {
|
||||||
atom_ctts_free (stbl->ctts);
|
atom_ctts_free (stbl->ctts);
|
||||||
}
|
}
|
||||||
|
if (stbl->svmi) {
|
||||||
|
atom_svmi_free (stbl->svmi);
|
||||||
|
}
|
||||||
atom_stco64_clear (&stbl->stco64);
|
atom_stco64_clear (&stbl->stco64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2292,6 +2323,25 @@ atom_ctts_copy_data (AtomCTTS * ctts, guint8 ** buffer, guint64 * size,
|
||||||
return *offset - original_offset;
|
return *offset - original_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
guint64
|
||||||
atom_stco64_copy_data (AtomSTCO64 * stco64, guint8 ** buffer, guint64 * size,
|
atom_stco64_copy_data (AtomSTCO64 * stco64, guint8 ** buffer, guint64 * size,
|
||||||
guint64 * offset)
|
guint64 * offset)
|
||||||
|
@ -2454,6 +2504,11 @@ atom_stbl_copy_data (AtomSTBL * stbl, guint8 ** buffer, guint64 * size,
|
||||||
return 0;
|
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)) {
|
if (!atom_stco64_copy_data (&stbl->stco64, buffer, size, offset)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -563,6 +563,14 @@ typedef struct _AtomCTTS
|
||||||
gboolean do_pts;
|
gboolean do_pts;
|
||||||
} AtomCTTS;
|
} AtomCTTS;
|
||||||
|
|
||||||
|
typedef struct _AtomSVMI
|
||||||
|
{
|
||||||
|
AtomFull header;
|
||||||
|
|
||||||
|
guint8 stereoscopic_composition_type;
|
||||||
|
gboolean is_left_first;
|
||||||
|
} AtomSVMI;
|
||||||
|
|
||||||
typedef struct _AtomSTBL
|
typedef struct _AtomSTBL
|
||||||
{
|
{
|
||||||
Atom header;
|
Atom header;
|
||||||
|
@ -574,6 +582,8 @@ typedef struct _AtomSTBL
|
||||||
AtomSTSZ stsz;
|
AtomSTSZ stsz;
|
||||||
/* NULL if not present */
|
/* NULL if not present */
|
||||||
AtomCTTS *ctts;
|
AtomCTTS *ctts;
|
||||||
|
/* NULL if not present */
|
||||||
|
AtomSVMI *svmi;
|
||||||
|
|
||||||
AtomSTCO64 stco64;
|
AtomSTCO64 stco64;
|
||||||
} AtomSTBL;
|
} AtomSTBL;
|
||||||
|
@ -960,6 +970,9 @@ guint64 atom_stsz_copy_data (AtomSTSZ *atom, guint8 **buffer,
|
||||||
guint64 *size, guint64* offset);
|
guint64 *size, guint64* offset);
|
||||||
guint64 atom_ctts_copy_data (AtomCTTS *atom, guint8 **buffer,
|
guint64 atom_ctts_copy_data (AtomCTTS *atom, guint8 **buffer,
|
||||||
guint64 *size, guint64* offset);
|
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 atom_stco64_copy_data (AtomSTCO64 *atom, guint8 **buffer,
|
||||||
guint64 *size, guint64* offset);
|
guint64 *size, guint64* offset);
|
||||||
AtomMOOF* atom_moof_new (AtomsContext *context, guint32 sequence_number);
|
AtomMOOF* atom_moof_new (AtomsContext *context, guint32 sequence_number);
|
||||||
|
|
|
@ -5189,6 +5189,7 @@ gst_qt_mux_video_sink_set_caps (GstQTPad * qtpad, GstCaps * caps)
|
||||||
GList *ext_atom_list = NULL;
|
GList *ext_atom_list = NULL;
|
||||||
gboolean sync = FALSE;
|
gboolean sync = FALSE;
|
||||||
int par_num, par_den;
|
int par_num, par_den;
|
||||||
|
const gchar *multiview_mode;
|
||||||
|
|
||||||
/* does not go well to renegotiate stream mid-way, unless
|
/* does not go well to renegotiate stream mid-way, unless
|
||||||
* the old caps are a subset of the new one (this means upstream
|
* 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,
|
GST_DEBUG_OBJECT (qtmux, "Rate of video track selected: %" G_GUINT32_FORMAT,
|
||||||
rate);
|
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 */
|
/* set common properties */
|
||||||
entry.width = width;
|
entry.width = width;
|
||||||
entry.height = height;
|
entry.height = height;
|
||||||
|
|
Loading…
Reference in a new issue