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
This commit is contained in:
Sebastian Dröge 2016-09-29 14:36:42 +03:00
parent 46b0b8edff
commit 79809633de
5 changed files with 96 additions and 2 deletions

View file

@ -2479,6 +2479,7 @@ GST_TYPE_VIDEO_COLOR_PRIMARIES
<SUBSECTION>
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
<SUBSECTION Standard>
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

View file

@ -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;

View file

@ -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)

View file

@ -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 */

View file

@ -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