mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 12:32:29 +00:00
qtdemux: Factor out svmi parsing. Fix bounds checking.
Move the SVMI stereoscopic atom parsing out to a helper function to shrink qtdemux_parse_trak a bit. Add a bounds check that the received atom is large enough before parsing it. Add a note to the atom parser that svmi comes from the MPEG-A spec 23000-11. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/634>
This commit is contained in:
parent
27ced4c8e6
commit
e2d75939bb
2 changed files with 74 additions and 45 deletions
|
@ -764,6 +764,8 @@ atom_ctts_free (AtomCTTS * ctts)
|
||||||
g_free (ctts);
|
g_free (ctts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* svmi is specified in ISO 23000-11 (Stereoscopic video application format)
|
||||||
|
* MPEG-A */
|
||||||
static void
|
static void
|
||||||
atom_svmi_init (AtomSVMI * svmi)
|
atom_svmi_init (AtomSVMI * svmi)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10725,6 +10725,75 @@ qtdemux_track_id_compare_func (QtDemuxStream ** stream1,
|
||||||
return (gint) (*stream1)->track_id - (gint) (*stream2)->track_id;
|
return (gint) (*stream1)->track_id - (gint) (*stream2)->track_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
qtdemux_parse_stereo_svmi_atom (GstQTDemux * qtdemux, QtDemuxStream * stream,
|
||||||
|
GNode * stbl)
|
||||||
|
{
|
||||||
|
GNode *svmi;
|
||||||
|
|
||||||
|
/*parse svmi header if existing */
|
||||||
|
svmi = qtdemux_tree_get_child_by_type (stbl, FOURCC_svmi);
|
||||||
|
if (svmi) {
|
||||||
|
guint len = QT_UINT32 ((guint8 *) svmi->data);
|
||||||
|
guint32 version = QT_UINT32 ((guint8 *) svmi->data + 8);
|
||||||
|
if (!version) {
|
||||||
|
GstVideoMultiviewMode mode = GST_VIDEO_MULTIVIEW_MODE_NONE;
|
||||||
|
GstVideoMultiviewFlags flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
|
||||||
|
guint8 frame_type, frame_layout;
|
||||||
|
guint32 stereo_mono_change_count;
|
||||||
|
|
||||||
|
if (len < 18)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* MPEG-A stereo video */
|
||||||
|
if (qtdemux->major_brand == FOURCC_ss02)
|
||||||
|
flags |= GST_VIDEO_MULTIVIEW_FLAGS_MIXED_MONO;
|
||||||
|
|
||||||
|
frame_type = QT_UINT8 ((guint8 *) svmi->data + 12);
|
||||||
|
frame_layout = QT_UINT8 ((guint8 *) svmi->data + 13) & 0x01;
|
||||||
|
stereo_mono_change_count = QT_UINT32 ((guint8 *) svmi->data + 14);
|
||||||
|
|
||||||
|
switch (frame_type) {
|
||||||
|
case 0:
|
||||||
|
mode = GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mode = GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mode = GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
/* mode 3 is primary/secondary view sequence, ie
|
||||||
|
* left/right views in separate tracks. See section 7.2
|
||||||
|
* of ISO/IEC 23000-11:2009 */
|
||||||
|
/* In the future this might be supported using related
|
||||||
|
* streams, like an enhancement track - if files like this
|
||||||
|
* ever exist */
|
||||||
|
GST_FIXME_OBJECT (qtdemux,
|
||||||
|
"Implement stereo video in separate streams");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((frame_layout & 0x1) == 0)
|
||||||
|
flags |= GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (qtdemux,
|
||||||
|
"StereoVideo: composition type: %u, is_left_first: %u",
|
||||||
|
frame_type, frame_layout);
|
||||||
|
|
||||||
|
if (stereo_mono_change_count > 1) {
|
||||||
|
GST_FIXME_OBJECT (qtdemux,
|
||||||
|
"Mixed-mono flags are not yet supported in qtdemux.");
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->multiview_mode = mode;
|
||||||
|
stream->multiview_flags = flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* parse the traks.
|
/* parse the traks.
|
||||||
* With each track we associate a new QtDemuxStream that contains all the info
|
* With each track we associate a new QtDemuxStream that contains all the info
|
||||||
* about the trak.
|
* about the trak.
|
||||||
|
@ -10746,7 +10815,6 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
|
||||||
GNode *esds;
|
GNode *esds;
|
||||||
GNode *tref;
|
GNode *tref;
|
||||||
GNode *udta;
|
GNode *udta;
|
||||||
GNode *svmi;
|
|
||||||
|
|
||||||
QtDemuxStream *stream = NULL;
|
QtDemuxStream *stream = NULL;
|
||||||
const guint8 *stsd_data;
|
const guint8 *stsd_data;
|
||||||
|
@ -10898,50 +10966,9 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
|
||||||
if (!(stbl = qtdemux_tree_get_child_by_type (minf, FOURCC_stbl)))
|
if (!(stbl = qtdemux_tree_get_child_by_type (minf, FOURCC_stbl)))
|
||||||
goto corrupt_file;
|
goto corrupt_file;
|
||||||
|
|
||||||
/*parse svmi header if existing */
|
/* Parse out svmi (and later st3d/sv3d) atoms */
|
||||||
svmi = qtdemux_tree_get_child_by_type (stbl, FOURCC_svmi);
|
if (!qtdemux_parse_stereo_svmi_atom (qtdemux, stream, stbl))
|
||||||
if (svmi) {
|
goto corrupt_file;
|
||||||
len = QT_UINT32 ((guint8 *) svmi->data);
|
|
||||||
version = QT_UINT32 ((guint8 *) svmi->data + 8);
|
|
||||||
if (!version) {
|
|
||||||
GstVideoMultiviewMode mode = GST_VIDEO_MULTIVIEW_MODE_NONE;
|
|
||||||
GstVideoMultiviewFlags flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
|
|
||||||
guint8 frame_type, frame_layout;
|
|
||||||
|
|
||||||
/* MPEG-A stereo video */
|
|
||||||
if (qtdemux->major_brand == FOURCC_ss02)
|
|
||||||
flags |= GST_VIDEO_MULTIVIEW_FLAGS_MIXED_MONO;
|
|
||||||
|
|
||||||
frame_type = QT_UINT8 ((guint8 *) svmi->data + 12);
|
|
||||||
frame_layout = QT_UINT8 ((guint8 *) svmi->data + 13) & 0x01;
|
|
||||||
switch (frame_type) {
|
|
||||||
case 0:
|
|
||||||
mode = GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
mode = GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
mode = GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
/* mode 3 is primary/secondary view sequence, ie
|
|
||||||
* left/right views in separate tracks. See section 7.2
|
|
||||||
* of ISO/IEC 23000-11:2009 */
|
|
||||||
GST_FIXME_OBJECT (qtdemux,
|
|
||||||
"Implement stereo video in separate streams");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((frame_layout & 0x1) == 0)
|
|
||||||
flags |= GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (qtdemux,
|
|
||||||
"StereoVideo: composition type: %u, is_left_first: %u",
|
|
||||||
frame_type, frame_layout);
|
|
||||||
stream->multiview_mode = mode;
|
|
||||||
stream->multiview_flags = flags;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* parse rest of tkhd */
|
/* parse rest of tkhd */
|
||||||
if (stream->subtype == FOURCC_vide) {
|
if (stream->subtype == FOURCC_vide) {
|
||||||
|
|
Loading…
Reference in a new issue