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:
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;
}
#define __GST_MATROSKA_IDS_H__
#include <gst/gst.h>
+#include <gst/video/video-info.h>
#include "ebml-ids.h"
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;
GstMatroskaAspectRatioMode asr_mode;
guint32 fourcc;
+ GstVideoMultiviewMode multiview_mode;
+ GstVideoMultiviewFlags multiview_flags;
+
/* QoS */
GstClockTime earliest_time;
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;
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;
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;