From 6241ff63f8b7e3b1aeceb461dc13ee22d152a0c2 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 19 Dec 2011 18:03:45 +0100 Subject: [PATCH] video: update interlace caps and docs Remove interlaced boolean from caps and replace with an interlace-mode enum. document this new property in the video caps document. With the enum we can put fields into separate video meta. Add enum for this interlace-mode in the VideoInfo. Update the buffer flags. --- docs/design/draft-media-types.txt | 39 ++++++++++++++++++++++++++++++++---- gst-libs/gst/video/video.c | 40 +++++++++++++++++++++++++++++-------- gst-libs/gst/video/video.h | 42 ++++++++++++++++++++++++++++----------- 3 files changed, 97 insertions(+), 24 deletions(-) diff --git a/docs/design/draft-media-types.txt b/docs/design/draft-media-types.txt index 42cab2c..f50e838 100644 --- a/docs/design/draft-media-types.txt +++ b/docs/design/draft-media-types.txt @@ -16,12 +16,43 @@ Media Types For variable framerates this would be the maximum framerate that is expected. This value is only valid when the framerate is 0/1 - pixel-aspect-ratio, GST_TYPE_FRACTION, default 1/1 - The pixel aspect ration of the video - views, G_TYPE_INT, default 1 The number of views for multiview video. Each buffer contains - multiple GstMetaVideo buffers that describe each view. + multiple GstMetaVideo buffers that describe each view. use the frame id to + get access to the different views. + + interlace-mode, G_TYPE_STRING, default progressive + The interlace mode. The following values are possible: + + "progressive" : all frames are progressive + "interleaved" : 2 fields are interleaved in one video frame. Extra buffer + flags describe the field order. + "mixed" : progressive and interleaved frames, extra buffer flags describe + the frame and fields. + "fields" : 2 fields are stored in one buffer, use the frame ID + to get access to the required field. For multiview (the + views property > 1) the second field of view N is at N * 2. + Each view has only half the amount of lines as noted in the + height property, pads specifying the "fields" property + must be prepared for this. + + chroma-site, G_TYPE_STRING, default UNKNOWN + The chroma siting of the video frames. + + "jpeg" : GST_VIDEO_CHROMA_SITE_JPEG + "mpeg2": GST_VIDEO_CHROMA_SITE_MPEG2 + "dv" : GST_VIDEO_CHROMA_SITE_DV + + colorimetry, G_TYPE_STRING, default UNKNOWN + The colorimetry of the video frames predefined colorimetry is given with + the following values: + + "bt601" + "bt709" + "smpte240m" + + pixel-aspect-ratio, GST_TYPE_FRACTION, default 1/1 + The pixel aspect ration of the video format, G_TYPE_STRING, mandatory The format of the video diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c index 48be215..f00ebd6 100644 --- a/gst-libs/gst/video/video.c +++ b/gst-libs/gst/video/video.c @@ -647,6 +647,33 @@ gst_video_info_set_format (GstVideoInfo * info, GstVideoFormat format, fill_planes (info); } +static const gchar *interlace_mode[] = { + "progressive", + "interleaved", + "mixed", + "fields" +}; + +static const gchar * +gst_interlace_mode_to_string (GstVideoInterlaceMode mode) +{ + if (mode < 0 || mode >= G_N_ELEMENTS (interlace_mode)) + return NULL; + + return interlace_mode[mode]; +} + +static GstVideoInterlaceMode +gst_interlace_mode_from_string (const gchar * mode) +{ + gint i; + for (i = 0; i < G_N_ELEMENTS (interlace_mode); i++) { + if (g_str_equal (interlace_mode[i], mode)) + return i; + } + return GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; +} + typedef struct { const gchar *name; @@ -797,7 +824,6 @@ gst_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps) GstVideoFormat format; gint width, height, views; gint fps_n, fps_d; - gboolean interlaced; gint par_n, par_d; g_return_val_if_fail (info != NULL, FALSE); @@ -840,12 +866,10 @@ gst_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps) info->fps_d = 1; } - if (!gst_structure_get_boolean (structure, "interlaced", &interlaced)) - interlaced = FALSE; - if (interlaced) - info->flags |= GST_VIDEO_FLAG_INTERLACED; + if ((s = gst_structure_get_string (structure, "interlace-mode"))) + info->interlace_mode = gst_interlace_mode_from_string (s); else - info->flags &= ~GST_VIDEO_FLAG_INTERLACED; + info->interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; if (gst_structure_get_int (structure, "views", &views)) info->views = views; @@ -928,8 +952,8 @@ gst_video_info_to_caps (GstVideoInfo * info) "height", G_TYPE_INT, info->height, "pixel-aspect-ratio", GST_TYPE_FRACTION, info->par_n, info->par_d, NULL); - if (info->flags & GST_VIDEO_FLAG_INTERLACED) - gst_caps_set_simple (caps, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL); + gst_caps_set_simple (caps, "interlace-mode", G_TYPE_STRING, + gst_interlace_mode_to_string (info->interlace_mode), NULL); if (info->chroma_site != GST_VIDEO_CHROMA_SITE_UNKNOWN) gst_caps_set_simple (caps, "chroma-site", G_TYPE_STRING, diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h index 60b50cf..dce7cf7 100644 --- a/gst-libs/gst/video/video.h +++ b/gst-libs/gst/video/video.h @@ -304,14 +304,32 @@ typedef struct _GstVideoInfo GstVideoInfo; typedef struct _GstVideoFrame GstVideoFrame; /** + * GstVideoInterlaceMode: + * GST_VIDEO_INTERLACE_MODE_PROGRESSIVE: all frames are progressive + * GST_VIDEO_INTERLACE_MODE_INTERLEAVED: video is interlaced and all fields + * are interlaced in one frame. + * @GST_VIDEO_INTERLACE_MODE_MIXED: video contains both interlaced and + * progressive frames, the buffer flags describe the frame and fields. + * @GST_VIDEO_INTERLACE_MODE_FIELDS: video is interlaced and fields are stored + * separately. Use the id property to get access to the required field. + * + * The possible values of the #GstVideoInterlaceMode describing the interlace + * mode of the stream. + */ +typedef enum { + GST_VIDEO_INTERLACE_MODE_PROGRESSIVE = 0, + GST_VIDEO_INTERLACE_MODE_INTERLEAVED, + GST_VIDEO_INTERLACE_MODE_MIXED, + GST_VIDEO_INTERLACE_MODE_FIELDS +} GstVideoInterlaceMode; + +/** * GstVideoFlags: * @GST_VIDEO_FLAG_NONE: no flags * @GST_VIDEO_FLAG_INTERLACED: The video is interlaced * @GST_VIDEO_FLAG_TFF: The video has the top field first * @GST_VIDEO_FLAG_RFF: The video has the repeat flag * @GST_VIDEO_FLAG_ONEFIELD: one field - * @GST_VIDEO_FLAG_TELECINE: telecine - * @GST_VIDEO_FLAG_PROGRESSIVE: video is progressive * @GST_VIDEO_FLAG_VARIABLE_FPS: a variable fps is selected, fps_n and fps_d * denote the maximum fps of the video * @@ -323,9 +341,7 @@ typedef enum { GST_VIDEO_FLAG_TFF = (1 << 1), GST_VIDEO_FLAG_RFF = (1 << 2), GST_VIDEO_FLAG_ONEFIELD = (1 << 3), - GST_VIDEO_FLAG_TELECINE = (1 << 4), - GST_VIDEO_FLAG_PROGRESSIVE = (1 << 5), - GST_VIDEO_FLAG_VARIABLE_FPS = (1 << 6) + GST_VIDEO_FLAG_VARIABLE_FPS = (1 << 4) } GstVideoFlags; /** @@ -479,6 +495,7 @@ gchar * gst_video_colorimetry_to_string (GstVideoColorimetry *cinfo); /** * GstVideoInfo: * @finfo: the format info of the video + * @interlace_mode: the interlace mode * @flags: additional video flags * @width: the width of the video * @height: the height of the video @@ -503,6 +520,8 @@ gchar * gst_video_colorimetry_to_string (GstVideoColorimetry *cinfo); */ struct _GstVideoInfo { const GstVideoFormatInfo *finfo; + + GstVideoInterlaceMode interlace_mode; GstVideoFlags flags; gint width; gint height; @@ -531,6 +550,7 @@ struct _GstVideoInfo { #define GST_VIDEO_INFO_IS_GRAY(i) (GST_VIDEO_FORMAT_INFO_IS_GRAY((i)->finfo)) #define GST_VIDEO_INFO_HAS_ALPHA(i) (GST_VIDEO_FORMAT_INFO_HAS_ALPHA((i)->finfo)) +#define GST_VIDEO_INFO_INTERLACE_MODE(i) ((i)->interlace_mode) #define GST_VIDEO_INFO_FLAGS(i) ((i)->flags) #define GST_VIDEO_INFO_WIDTH(i) ((i)->width) #define GST_VIDEO_INFO_HEIGHT(i) ((i)->height) @@ -662,6 +682,7 @@ gboolean gst_video_frame_copy (GstVideoFrame *dest, const GstVideoFr /** * GstVideoBufferFlags: + * @GST_VIDEO_BUFFER_FLAG_INTERLACED: Mark #GstBuffer as interlaced * @GST_VIDEO_BUFFER_FLAG_TFF: If the #GstBuffer is interlaced, then the first field * in the video frame is the top field. If unset, the * bottom field is first. @@ -671,17 +692,14 @@ gboolean gst_video_frame_copy (GstVideoFrame *dest, const GstVideoFr * @GST_VIDEO_BUFFER_FLAG_ONEFIELD: If the #GstBuffer is interlaced, then only the * first field (as defined by the %GST_VIDEO_BUFFER_TFF * flag setting) is to be displayed. - * @GST_VIDEO_BUFFER_FLAG_PROGRESSIVE: If the #GstBuffer is telecined, then the - * buffer is progressive if the %GST_VIDEO_BUFFER_PROGRESSIVE - * flag is set, else it is telecine mixed. * * Additional video buffer flags. */ typedef enum { - GST_VIDEO_BUFFER_FLAG_TFF = (GST_BUFFER_FLAG_LAST << 0), - GST_VIDEO_BUFFER_FLAG_RFF = (GST_BUFFER_FLAG_LAST << 1), - GST_VIDEO_BUFFER_FLAG_ONEFIELD = (GST_BUFFER_FLAG_LAST << 2), - GST_VIDEO_BUFFER_FLAG_PROGRESSIVE = (GST_BUFFER_FLAG_LAST << 3), + GST_VIDEO_BUFFER_FLAG_INTERLACED = (GST_BUFFER_FLAG_LAST << 0), + GST_VIDEO_BUFFER_FLAG_TFF = (GST_BUFFER_FLAG_LAST << 1), + GST_VIDEO_BUFFER_FLAG_RFF = (GST_BUFFER_FLAG_LAST << 2), + GST_VIDEO_BUFFER_FLAG_ONEFIELD = (GST_BUFFER_FLAG_LAST << 3), GST_VIDEO_BUFFER_FLAG_LAST = (GST_BUFFER_FLAG_LAST << 8) } GstVideoBufferFlags; -- 2.7.4