"progressive",
"interleaved",
"mixed",
- "fields"
+ "fields",
+ "alternate"
};
/**
NULL);
}
+ if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE) {
+ /* 'alternate' mode must always be accompanied by interlaced caps feature.
+ */
+ GstCapsFeatures *features;
+
+ features = gst_caps_features_new (GST_CAPS_FEATURE_FORMAT_INTERLACED, NULL);
+ gst_caps_set_features (caps, 0, features);
+ }
+
if (GST_VIDEO_INFO_MULTIVIEW_MODE (info) != GST_VIDEO_MULTIVIEW_MODE_NONE) {
const gchar *caps_str = NULL;
gint bpp = 0, i;
width = (gsize) info->width;
- height = (gsize) info->height;
+ if (GST_VIDEO_INFO_INTERLACE_MODE (info) ==
+ GST_VIDEO_INTERLACE_MODE_ALTERNATE)
+ height = (gsize) info->height / 2;
+ else
+ height = (gsize) info->height;
/* Sanity check the resulting frame size for overflows */
for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (info); i++)
typedef struct _GstVideoInfo GstVideoInfo;
+/**
+ * GST_CAPS_FEATURE_FORMAT_INTERLACED:
+ *
+ * Name of the caps feature indicating that the stream is interlaced. Currently
+ * it is only used for video.
+ *
+ * Since: 1.16.
+ */
+#define GST_CAPS_FEATURE_FORMAT_INTERLACED "format:Interlaced"
+
/**
* GstVideoInterlaceMode:
* @GST_VIDEO_INTERLACE_MODE_PROGRESSIVE: all frames are progressive
* Each field has only half the amount of lines as noted in the
* height property. This mode requires multiple GstVideoMeta metadata
* to describe the fields.
+ * @GST_VIDEO_INTERLACE_MODE_ALTERNATE: 1 field is stored in one buffer,
+ * @GST_VIDEO_BUFFER_FLAG_TF or @GST_VIDEO_BUFFER_FLAG_BF indicates if
+ * the buffer is carrying the top or bottom field, respectively. The top and
+ * bottom buffers are expected to alternate in the pipeline, with this mode
+ * (Since: 1.16).
*
* The possible values of the #GstVideoInterlaceMode describing the interlace
* mode of the stream.
GST_VIDEO_INTERLACE_MODE_PROGRESSIVE = 0,
GST_VIDEO_INTERLACE_MODE_INTERLEAVED,
GST_VIDEO_INTERLACE_MODE_MIXED,
- GST_VIDEO_INTERLACE_MODE_FIELDS
+ GST_VIDEO_INTERLACE_MODE_FIELDS,
+ GST_VIDEO_INTERLACE_MODE_ALTERNATE,
} GstVideoInterlaceMode;
GST_VIDEO_API
GST_END_TEST;
+GST_START_TEST (test_interlace_mode)
+{
+ GstVideoInfo vinfo;
+ GstCaps *caps;
+ GstStructure *structure;
+ GstCapsFeatures *features;
+ const char *mode_str;
+ int mode;
+
+ gst_video_info_init (&vinfo);
+
+ /* Progressive */
+ gst_video_info_set_format (&vinfo, GST_VIDEO_FORMAT_YV12, 320, 240);
+ GST_VIDEO_INFO_INTERLACE_MODE (&vinfo) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
+
+ caps = gst_video_info_to_caps (&vinfo);
+ fail_unless (caps != NULL);
+ structure = gst_caps_get_structure (caps, 0);
+ fail_unless (structure != NULL);
+ mode_str = gst_structure_get_string (structure, "interlace-mode");
+ mode = gst_video_interlace_mode_from_string (mode_str);
+ fail_unless (mode == GST_VIDEO_INTERLACE_MODE_PROGRESSIVE);
+
+ /* Converting back to video info */
+ fail_unless (gst_video_info_from_caps (&vinfo, caps));
+ fail_unless (GST_VIDEO_INFO_INTERLACE_MODE (&vinfo) ==
+ GST_VIDEO_INTERLACE_MODE_PROGRESSIVE);
+
+ gst_caps_unref (caps);
+
+ /* Interlaced with alternate frame on buffers */
+ gst_video_info_set_format (&vinfo, GST_VIDEO_FORMAT_YV12, 320, 240);
+ GST_VIDEO_INFO_INTERLACE_MODE (&vinfo) = GST_VIDEO_INTERLACE_MODE_ALTERNATE;
+
+ caps = gst_video_info_to_caps (&vinfo);
+ fail_unless (caps != NULL);
+ structure = gst_caps_get_structure (caps, 0);
+ fail_unless (structure != NULL);
+ mode_str = gst_structure_get_string (structure, "interlace-mode");
+ mode = gst_video_interlace_mode_from_string (mode_str);
+ fail_unless (mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE);
+ /* 'alternate' mode must always be accompanied by interlaced caps feature. */
+ features = gst_caps_get_features (caps, 0);
+ fail_unless (gst_caps_features_contains (features,
+ GST_CAPS_FEATURE_FORMAT_INTERLACED));
+
+ /* Converting back to video info */
+ fail_unless (gst_video_info_from_caps (&vinfo, caps));
+ fail_unless (GST_VIDEO_INFO_INTERLACE_MODE (&vinfo) ==
+ GST_VIDEO_INTERLACE_MODE_ALTERNATE);
+
+ gst_caps_unref (caps);
+}
+
+GST_END_TEST;
+
GST_START_TEST (test_overlay_composition)
{
GstVideoOverlayComposition *comp1, *comp2;
tcase_add_test (tc_chain, test_convert_frame);
tcase_add_test (tc_chain, test_convert_frame_async);
tcase_add_test (tc_chain, test_video_size_from_caps);
+ tcase_add_test (tc_chain, test_interlace_mode);
tcase_add_test (tc_chain, test_overlay_composition);
tcase_add_test (tc_chain, test_overlay_composition_premultiplied_alpha);
tcase_add_test (tc_chain, test_overlay_composition_global_alpha);