From 79809633de398d5495dbe2e3fa3c1bc6bd9f780d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 29 Sep 2016 14:36:42 +0300 Subject: [PATCH] video-info: Add optional field-order caps field for interlaced-mode=interleaved Usually this information is static for the whole stream, and various container formats store this information inside the headers for the whole stream. Having it inside the caps for these cases simplifies code and makes it possible to express these requirements more explicitly with the caps. https://bugzilla.gnome.org/show_bug.cgi?id=771376 --- docs/libs/gst-plugins-base-libs-sections.txt | 4 ++ gst-libs/gst/video/video-info.c | 62 ++++++++++++++++++++ gst-libs/gst/video/video-info.h | 25 ++++++++ gst-libs/gst/video/videoorientation.c | 4 +- win32/common/libgstvideo.def | 3 + 5 files changed, 96 insertions(+), 2 deletions(-) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 33e64f832b..33617be7bc 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -2479,6 +2479,7 @@ GST_TYPE_VIDEO_COLOR_PRIMARIES GstVideoInfo GstVideoInterlaceMode +GstVideoFieldOrder GstVideoMultiviewMode GstVideoMultiviewFramePacking GstVideoMultiviewFlags @@ -2491,6 +2492,7 @@ GST_VIDEO_INFO_IS_GRAY GST_VIDEO_INFO_HAS_ALPHA GST_VIDEO_INFO_INTERLACE_MODE GST_VIDEO_INFO_IS_INTERLACED +GST_VIDEO_INFO_FIELD_ORDER GST_VIDEO_INFO_FLAGS GST_VIDEO_INFO_WIDTH GST_VIDEO_INFO_HEIGHT @@ -2533,6 +2535,8 @@ gst_video_info_align gst_video_interlace_mode_get_type GST_TYPE_VIDEO_INTERLACE_MODE +gst_video_field_order_get_type +GST_TYPE_VIDEO_FIELD_ORDER gst_video_flags_get_type GST_TYPE_VIDEO_FLAGS GST_TYPE_VIDEO_MULTIVIEW_FLAGS diff --git a/gst-libs/gst/video/video-info.c b/gst-libs/gst/video/video-info.c index f42b8c9619..0c4edab0b3 100644 --- a/gst-libs/gst/video/video-info.c +++ b/gst-libs/gst/video/video-info.c @@ -274,6 +274,54 @@ gst_video_interlace_mode_from_string (const gchar * mode) return GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; } +static const gchar *field_order[] = { + "unknown", + "top-field-first", + "bottom-field-first" +}; + +/** + * gst_video_field_order_to_string: + * @order: a #GstVideoFieldOrder + * + * Convert @order to its string representation. + * + * Returns: @order as a string or NULL if @order in invalid. + * + * Since: 1.12 + */ +const gchar * +gst_video_field_order_to_string (GstVideoFieldOrder order) +{ + if (((guint) order) >= G_N_ELEMENTS (field_order)) + return NULL; + + return field_order[order]; +} + +/** + * gst_video_field_order_from_string: + * @order: a field order + * + * Convert @order to a #GstVideoFieldOrder + * + * Returns: the #GstVideoFieldOrder of @order or + * #GST_VIDEO_FIELD_ORDER_UNKNOWN when @order is not a valid + * string representation for a #GstVideoFieldOrder. + * + * Since: 1.12 + */ +GstVideoFieldOrder +gst_video_field_order_from_string (const gchar * order) +{ + gint i; + for (i = 0; i < G_N_ELEMENTS (field_order); i++) { + if (g_str_equal (field_order[i], order)) + return i; + } + return GST_VIDEO_FIELD_ORDER_UNKNOWN; +} + /** * gst_video_info_from_caps: * @info: a #GstVideoInfo @@ -359,6 +407,13 @@ gst_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps) else info->interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; + if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED && + (s = gst_structure_get_string (structure, "field-order"))) { + GST_VIDEO_INFO_FIELD_ORDER (info) = gst_video_field_order_from_string (s); + } else { + GST_VIDEO_INFO_FIELD_ORDER (info) = GST_VIDEO_FIELD_ORDER_UNKNOWN; + } + { if ((s = gst_structure_get_string (structure, "multiview-mode"))) GST_VIDEO_INFO_MULTIVIEW_MODE (info) = @@ -531,6 +586,13 @@ gst_video_info_to_caps (GstVideoInfo * info) gst_caps_set_simple (caps, "interlace-mode", G_TYPE_STRING, gst_video_interlace_mode_to_string (info->interlace_mode), NULL); + if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED && + GST_VIDEO_INFO_FIELD_ORDER (info) != GST_VIDEO_FIELD_ORDER_UNKNOWN) { + gst_caps_set_simple (caps, "field-order", G_TYPE_STRING, + gst_video_field_order_to_string (GST_VIDEO_INFO_FIELD_ORDER (info)), + NULL); + } + if (GST_VIDEO_INFO_MULTIVIEW_MODE (info) != GST_VIDEO_MULTIVIEW_MODE_NONE) { const gchar *caps_str = NULL; diff --git a/gst-libs/gst/video/video-info.h b/gst-libs/gst/video/video-info.h index aaddea7902..35101218e3 100644 --- a/gst-libs/gst/video/video-info.h +++ b/gst-libs/gst/video/video-info.h @@ -227,6 +227,29 @@ typedef enum { GST_VIDEO_FLAG_PREMULTIPLIED_ALPHA = (1 << 1) } GstVideoFlags; +/** + * GstVideoFieldOrder: + * @GST_VIDEO_FIELD_ORDER_UNKNOWN: unknown field order for interlaced content. + * The actual field order is signalled via buffer flags. + * @GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST: top field is first + * @GST_VIDEO_FIELD_ORDER_BOTTOM_FIELD_FIRST: bottom field is first + * + * Field order of interlaced content. This is only valid for + * interlaced-mode=interleaved and not interlaced-mode=mixed. In the case of + * mixed or GST_VIDEO_FIELD_ORDER_UNKOWN, the field order is signalled via + * buffer flags. + * + * Since: 1.12 + */ +typedef enum { + GST_VIDEO_FIELD_ORDER_UNKNOWN = 0, + GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST = 1, + GST_VIDEO_FIELD_ORDER_BOTTOM_FIELD_FIRST = 2, +} GstVideoFieldOrder; + +const gchar * gst_video_field_order_to_string (GstVideoFieldOrder order); +GstVideoFieldOrder gst_video_field_order_from_string (const gchar * order); + /** * GstVideoInfo: * @finfo: the format info of the video @@ -281,6 +304,7 @@ struct _GstVideoInfo { struct { GstVideoMultiviewMode multiview_mode; GstVideoMultiviewFlags multiview_flags; + GstVideoFieldOrder field_order; } abi; /*< private >*/ gpointer _gst_reserved[GST_PADDING]; @@ -300,6 +324,7 @@ GType gst_video_info_get_type (void); #define GST_VIDEO_INFO_INTERLACE_MODE(i) ((i)->interlace_mode) #define GST_VIDEO_INFO_IS_INTERLACED(i) ((i)->interlace_mode != GST_VIDEO_INTERLACE_MODE_PROGRESSIVE) +#define GST_VIDEO_INFO_FIELD_ORDER(i) ((i)->ABI.abi.field_order) #define GST_VIDEO_INFO_FLAGS(i) ((i)->flags) #define GST_VIDEO_INFO_WIDTH(i) ((i)->width) #define GST_VIDEO_INFO_HEIGHT(i) ((i)->height) diff --git a/gst-libs/gst/video/videoorientation.c b/gst-libs/gst/video/videoorientation.c index 9e2149be33..0f714fe028 100644 --- a/gst-libs/gst/video/videoorientation.c +++ b/gst-libs/gst/video/videoorientation.c @@ -41,8 +41,8 @@ G_DEFINE_INTERFACE (GstVideoOrientation, gst_video_orientation, 0) -static void -gst_video_orientation_default_init (GstVideoOrientationInterface * + static void + gst_video_orientation_default_init (GstVideoOrientationInterface * iface) { /* default virtual functions */ diff --git a/win32/common/libgstvideo.def b/win32/common/libgstvideo.def index cff46517bc..67a079d0a1 100644 --- a/win32/common/libgstvideo.def +++ b/win32/common/libgstvideo.def @@ -166,6 +166,9 @@ EXPORTS gst_video_event_parse_downstream_force_key_unit gst_video_event_parse_still_frame gst_video_event_parse_upstream_force_key_unit + gst_video_field_order_from_string + gst_video_field_order_get_type + gst_video_field_order_to_string gst_video_filter_get_type gst_video_flags_get_type gst_video_format_flags_get_type