summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-08-30 23:24:46 +0200
committerwm4 <wm4@nowhere>2014-08-30 23:24:46 +0200
commit8599c959fe9334bc4d226faf813166ef8bc8efd5 (patch)
tree433530a09dd4b22173092b10452d7a35325de570 /video
parentc80adac07772f5b3c7a6c31e3e05480252f84171 (diff)
downloadmpv-8599c959fe9334bc4d226faf813166ef8bc8efd5.tar.bz2
mpv-8599c959fe9334bc4d226faf813166ef8bc8efd5.tar.xz
video: initial Matroska 3D support
This inserts an automatic conversion filter if a Matroska file is marked as 3D (StereoMode element). The basic idea is similar to video rotation and colorspace handling: the 3D mode is added as a property to the video params. Depending on this property, a video filter can be inserted. As of this commit, extending mp_image_params is actually completely unnecessary - but the idea is that it will make it easier to integrate with VOs supporting stereo 3D mogrification. Although vo_opengl does support some stereo rendering, it didn't support the mode my sample file used, so I'll leave that part for later. Not that most mappings from Matroska mode to vf_stereo3d mode are probably wrong, and some are missing. Assuming that Matroska modes, and vf_stereo3d in modes, and out modes are all the same might be an oversimplification - we'll see. See issue #1045.
Diffstat (limited to 'video')
-rw-r--r--video/csputils.c22
-rw-r--r--video/csputils.h11
-rw-r--r--video/decode/vd_lavc.c2
-rw-r--r--video/filter/vf_stereo3d.c2
-rw-r--r--video/mp_image.c6
-rw-r--r--video/mp_image.h2
6 files changed, 44 insertions, 1 deletions
diff --git a/video/csputils.c b/video/csputils.c
index 1cbaf47de9..d07b3a096e 100644
--- a/video/csputils.c
+++ b/video/csputils.c
@@ -77,6 +77,28 @@ const char *const mp_chroma_names[MP_CHROMA_COUNT] = {
"mpeg1/jpeg",
};
+// The short name _must_ match with what vf_stereo3d accepts (if supported).
+// The long name is closer to the Matroska spec (StereoMode element).
+// If you add entries that don't match Matroska, make sure demux_mkv.c rejects
+// them properly.
+// The long name is unused.
+#define E(index, short, long) [index] = short
+const char *const mp_stereo3d_names[MP_STEREO3D_COUNT] = {
+ E(0, "mono", "mono"), // unsupported by vf_stereo3d
+ E(1, "sbs2l", "side_by_side_left"),
+ E(2, "abr", "top_bottom_right"),
+ E(3, "abl", "top_bottom_left"),
+ E(4, "checkr", "checkboard_right"), // unsupported by vf_stereo3d
+ E(5, "checkl", "checkboard_left"),
+ E(6, "irr", "row_interleaved_right"),
+ E(7, "irl", "row_interleaved_left"),
+ E(8, "icr", "column_interleaved_right"),// unsupported by vf_stereo3d
+ E(9, "icl", "column_interleaved_left"), // unsupported by vf_stereo3d
+ E(10, "arcc", "anaglyph_cyan_red"), // Matroska: unclear which mode
+ E(11, "sbs2r", "side_by_side_right"),
+ E(12, "agmc", "anaglyph_green_magenta"), // Matroska: unclear which mode
+};
+
enum mp_csp avcol_spc_to_mp_csp(int avcolorspace)
{
switch (avcolorspace) {
diff --git a/video/csputils.h b/video/csputils.h
index 757ac72cdc..1a559ebfd2 100644
--- a/video/csputils.h
+++ b/video/csputils.h
@@ -79,6 +79,17 @@ enum mp_render_intent {
MP_INTENT_ABSOLUTE_COLORIMETRIC = 3
};
+enum mp_stereo3d_mode {
+ MP_STEREO3D_INVALID = -1,
+ MP_STEREO3D_MONO = 0,
+ MP_STEREO3D_COUNT = 13, // 12 is last valid mode
+};
+
+extern const char *const mp_stereo3d_names[MP_STEREO3D_COUNT];
+
+#define MP_STEREO3D_NAME(x) \
+ ((x) >= 0 && (x) < MP_STEREO3D_COUNT ? (char *)mp_stereo3d_names[(x)] : NULL)
+
struct mp_csp_details {
enum mp_csp format;
enum mp_csp_levels levels_in; // encoded video
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 1d33742bc5..45ae9fce94 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -485,6 +485,7 @@ static void update_image_params(struct dec_video *vd, AVFrame *frame,
.chroma_location =
avchroma_location_to_mp(ctx->avctx->chroma_sample_location),
.rotate = vd->header->video->rotate,
+ .stereo_in = vd->header->video->stereo_mode,
};
if (opts->video_rotate < 0) {
@@ -492,6 +493,7 @@ static void update_image_params(struct dec_video *vd, AVFrame *frame,
} else {
out_params->rotate = (out_params->rotate + opts->video_rotate) % 360;
}
+ out_params->stereo_out = opts->video_stereo_mode;
}
static enum AVPixelFormat get_format_hwdec(struct AVCodecContext *avctx,
diff --git a/video/filter/vf_stereo3d.c b/video/filter/vf_stereo3d.c
index 15d2095f5d..fcf583eef4 100644
--- a/video/filter/vf_stereo3d.c
+++ b/video/filter/vf_stereo3d.c
@@ -445,6 +445,8 @@ const struct m_opt_choice_alternatives stereo_code_names[] = {
{"interleave_rows_left_first", INTERLEAVE_ROWS_LR},
{"irr", INTERLEAVE_ROWS_RL},
{"interleave_rows_right_first", INTERLEAVE_ROWS_RL},
+ // convenience alias for MP_STEREO3D_MONO
+ {"mono", MONO_L},
{ NULL, 0}
};
diff --git a/video/mp_image.c b/video/mp_image.c
index d83a9ae3c1..7b430dfaf6 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -364,6 +364,8 @@ void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
dst->fields = src->fields;
dst->qscale_type = src->qscale_type;
dst->pts = src->pts;
+ dst->params.stereo_in = src->params.stereo_in;
+ dst->params.stereo_out = src->params.stereo_out;
if (dst->w == src->w && dst->h == src->h) {
dst->params.d_w = src->params.d_w;
dst->params.d_h = src->params.d_h;
@@ -489,7 +491,9 @@ bool mp_image_params_equal(const struct mp_image_params *p1,
p1->outputlevels == p2->outputlevels &&
p1->primaries == p2->primaries &&
p1->chroma_location == p2->chroma_location &&
- p1->rotate == p2->rotate;
+ p1->rotate == p2->rotate &&
+ p1->stereo_in == p2->stereo_in &&
+ p1->stereo_out == p2->stereo_out;
}
// Set most image parameters, but not image format or size.
diff --git a/video/mp_image.h b/video/mp_image.h
index 5ab12ae3d8..9cdc7fdf77 100644
--- a/video/mp_image.h
+++ b/video/mp_image.h
@@ -55,6 +55,8 @@ struct mp_image_params {
enum mp_csp_levels outputlevels;
// The image should be rotated clockwise (0-359 degrees).
int rotate;
+ enum mp_stereo3d_mode stereo_in; // image is encoded with this mode
+ enum mp_stereo3d_mode stereo_out; // should be displayed with this mode
};
/* Memory management: