Commit ec5bc9dc authored by Jan Schmidt's avatar Jan Schmidt

matroska: Implement basic stereoscopic video support

Implement support for the packed video formats WebM
uses, not all the values that Matroska might use.

In practice, it's really hard to find any samples in the
wild of any.

Supported in both the muxer and demuxer.
parent fff76157
......@@ -731,12 +731,61 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
g_free (data);
break;
}
case GST_MATROSKA_ID_VIDEOSTEREOMODE:
{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
break;
GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
switch (num) {
case GST_MATROSKA_STEREO_MODE_SBS_RL:
videocontext->multiview_flags =
GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
/* fall through */
case GST_MATROSKA_STEREO_MODE_SBS_LR:
videocontext->multiview_mode =
GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
break;
case GST_MATROSKA_STEREO_MODE_TB_RL:
videocontext->multiview_flags =
GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
/* fall through */
case GST_MATROSKA_STEREO_MODE_TB_LR:
videocontext->multiview_mode =
GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
break;
case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
videocontext->multiview_flags =
GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
/* fall through */
case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
videocontext->multiview_mode =
GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
break;
case GST_MATROSKA_STEREO_MODE_FBF_RL:
videocontext->multiview_flags =
GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
/* fall through */
case GST_MATROSKA_STEREO_MODE_FBF_LR:
videocontext->multiview_mode =
GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
/* FIXME: In frame-by-frame mode, left/right frame buffers are
* laced within one block, and we'll need to apply FIRST_IN_BUNDLE
* accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
GST_FIXME_OBJECT (demux,
"Frame-by-frame stereoscopic mode not fully implemented");
break;
}
break;
}
default:
GST_WARNING_OBJECT (demux,
"Unknown TrackVideo subelement 0x%x - ignoring", id);
/* fall through */
case GST_MATROSKA_ID_VIDEOSTEREOMODE:
case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
......
......@@ -59,6 +59,9 @@ gst_matroska_track_init_video_context (GstMatroskaTrackContext ** p_context)
video_context->fourcc = 0;
video_context->default_fps = 0.0;
video_context->earliest_time = GST_CLOCK_TIME_NONE;
video_context->multiview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE;
video_context->multiview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
return TRUE;
}
......
......@@ -23,6 +23,7 @@
#define __GST_MATROSKA_IDS_H__
#include <gst/gst.h>
#include <gst/video/video-info.h>
#include "ebml-ids.h"
......@@ -489,6 +490,16 @@ typedef enum {
GST_MATROSKA_VIDEOTRACK_INTERLACED = (GST_MATROSKA_TRACK_SHIFT<<0)
} GstMatroskaVideoTrackFlags;
typedef enum {
GST_MATROSKA_STEREO_MODE_SBS_LR = 0x1,
GST_MATROSKA_STEREO_MODE_TB_RL = 0x2,
GST_MATROSKA_STEREO_MODE_TB_LR = 0x3,
GST_MATROSKA_STEREO_MODE_CHECKER_RL = 0x4,
GST_MATROSKA_STEREO_MODE_CHECKER_LR = 0x5,
GST_MATROSKA_STEREO_MODE_SBS_RL = 0x9,
GST_MATROSKA_STEREO_MODE_FBF_LR = 0xD,
GST_MATROSKA_STEREO_MODE_FBF_RL = 0xE
} GstMatroskaStereoMode;
typedef struct _GstMatroskaTrackContext GstMatroskaTrackContext;
......@@ -571,6 +582,9 @@ typedef struct _GstMatroskaTrackVideoContext {
GstMatroskaAspectRatioMode asr_mode;
guint32 fourcc;
GstVideoMultiviewMode multiview_mode;
GstVideoMultiviewFlags multiview_flags;
/* QoS */
GstClockTime earliest_time;
......
......@@ -929,7 +929,7 @@ gst_matroska_mux_video_pad_setcaps (GstPad * pad, GstCaps * caps)
GstMatroskaPad *collect_pad;
GstStructure *structure;
const gchar *mimetype;
const gchar *interlace_mode;
const gchar *interlace_mode, *s;
const GValue *value = NULL;
GstBuffer *codec_buf = NULL;
gint width, height, pixel_width, pixel_height;
......@@ -1002,6 +1002,14 @@ gst_matroska_mux_video_pad_setcaps (GstPad * pad, GstCaps * caps)
videocontext->display_height = 0;
}
/* Collect stereoscopic info, if any */
if ((s = gst_structure_get_string (structure, "multiview-mode")))
videocontext->multiview_mode =
gst_video_multiview_mode_from_caps_string (s);
gst_structure_get_flagset (structure, "multiview-flags",
&videocontext->multiview_flags, NULL);
skip_details:
videocontext->asr_mode = GST_MATROSKA_ASPECT_RATIO_MODE_FREE;
......@@ -2432,6 +2440,53 @@ gst_matroska_mux_track_header (GstMatroskaMux * mux,
gst_ebml_write_binary (ebml, GST_MATROSKA_ID_VIDEOCOLOURSPACE,
(gpointer) & fcc_le, 4);
}
if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
guint64 stereo_mode = 0;
switch (videocontext->multiview_mode) {
case GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE:
if (videocontext->multiview_flags &
GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST)
stereo_mode = GST_MATROSKA_STEREO_MODE_SBS_RL;
else
stereo_mode = GST_MATROSKA_STEREO_MODE_SBS_LR;
break;
case GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM:
if (videocontext->multiview_flags &
GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST)
stereo_mode = GST_MATROSKA_STEREO_MODE_TB_RL;
else
stereo_mode = GST_MATROSKA_STEREO_MODE_TB_LR;
break;
case GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD:
if (videocontext->multiview_flags &
GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST)
stereo_mode = GST_MATROSKA_STEREO_MODE_CHECKER_RL;
else
stereo_mode = GST_MATROSKA_STEREO_MODE_CHECKER_LR;
break;
case GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME:
if (videocontext->multiview_flags &
GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST)
stereo_mode = GST_MATROSKA_STEREO_MODE_FBF_RL;
else
stereo_mode = GST_MATROSKA_STEREO_MODE_FBF_LR;
/* FIXME: In frame-by-frame mode, left/right frame buffers need to be
* laced within one block. See http://www.matroska.org/technical/specs/index.html#StereoMode */
GST_FIXME_OBJECT (mux,
"Frame-by-frame stereoscopic mode not fully implemented");
break;
default:
GST_WARNING_OBJECT (mux,
"Multiview mode %d not supported in Matroska/WebM",
videocontext->multiview_mode);
break;
}
if (stereo_mode != 0)
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOSTEREOMODE,
stereo_mode);
}
gst_ebml_write_master_finish (ebml, master);
break;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment