PROP_ASYNC_DEPTH,
PROP_DENOISE,
PROP_ROTATION,
+ PROP_DEINTERLACE_MODE,
+ PROP_DEINTERLACE_METHOD,
PROP_N,
};
#define PROP_ASYNC_DEPTH_DEFAULT 1
#define PROP_DENOISE_DEFAULT 0
#define PROP_ROTATION_DEFAULT MFX_ANGLE_0
+#define PROP_DEINTERLACE_MODE_DEFAULT GST_MSDKVPP_DEINTERLACE_MODE_AUTO
+#define PROP_DEINTERLACE_METHOD_DEFAULT MFX_DEINTERLACING_BOB
#define gst_msdkvpp_parent_class parent_class
G_DEFINE_TYPE (GstMsdkVPP, gst_msdkvpp, GST_TYPE_BASE_TRANSFORM);
gst_object_unref (thiz->srcpad_buffer_pool);
thiz->srcpad_buffer_pool = NULL;
+ thiz->field_duration = GST_CLOCK_TIME_NONE;
gst_video_info_init (&thiz->sinkpad_info);
gst_video_info_init (&thiz->srcpad_info);
}
n_filters++;
}
+ /* Deinterlace */
+ if (thiz->flags & GST_MSDK_FLAG_DEINTERLACE) {
+ mfxExtVPPDeinterlacing *mfx_deinterlace = &thiz->mfx_deinterlace;
+ mfx_deinterlace->Header.BufferId = MFX_EXTBUFF_VPP_DEINTERLACING;
+ mfx_deinterlace->Header.BufferSz = sizeof (mfxExtVPPDeinterlacing);
+ mfx_deinterlace->Mode = thiz->deinterlace_method;
+ gst_msdkvpp_add_extra_param (thiz, (mfxExtBuffer *) mfx_deinterlace);
+ thiz->max_filter_algorithms[n_filters] = MFX_EXTBUFF_VPP_DEINTERLACING;
+ n_filters++;
+ }
+
/* mfxExtVPPDoUse */
if (n_filters) {
mfxExtVPPDoUse *mfx_vpp_douse = &thiz->mfx_vpp_douse;
thiz->param.vpp.Out.FrameRateExtD =
GST_VIDEO_INFO_FPS_D (&thiz->sinkpad_info);
+ /* set vpp out picstruct as progressive if deinterlacing enabled */
+ if (thiz->flags & GST_MSDK_FLAG_DEINTERLACE)
+ thiz->param.vpp.Out.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
+
/* validate parameters and allow the Media SDK to make adjustments */
status = MFXVideoVPP_Query (session, &thiz->param, &thiz->param);
if (status < MFX_ERR_NONE) {
GstVideoInfo in_info, out_info;
gboolean sinkpad_info_changed = FALSE;
gboolean srcpad_info_changed = FALSE;
+ gboolean deinterlace;
gst_video_info_from_caps (&in_info, caps);
gst_video_info_from_caps (&out_info, out_caps);
if (!sinkpad_info_changed && !srcpad_info_changed)
return TRUE;
+ /* check for deinterlace requirement */
+ deinterlace = gst_msdkvpp_is_deinterlace_enabled (thiz, &in_info);
+ if (deinterlace)
+ thiz->flags |= GST_MSDK_FLAG_DEINTERLACE;
+ thiz->field_duration = GST_VIDEO_INFO_FPS_N (&in_info) > 0 ?
+ gst_util_uint64_scale (GST_SECOND, GST_VIDEO_INFO_FPS_D (&in_info),
+ (1 + deinterlace) * GST_VIDEO_INFO_FPS_N (&in_info)) : 0;
+
if (!gst_msdkvpp_initialize (thiz))
return FALSE;
thiz->rotation = g_value_get_enum (value);
thiz->flags |= GST_MSDK_FLAG_ROTATION;
break;
+ case PROP_DEINTERLACE_MODE:
+ thiz->deinterlace_mode = g_value_get_enum (value);
+ break;
+ case PROP_DEINTERLACE_METHOD:
+ thiz->deinterlace_method = g_value_get_enum (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_ROTATION:
g_value_set_enum (value, thiz->rotation);
break;
+ case PROP_DEINTERLACE_MODE:
+ g_value_set_enum (value, thiz->deinterlace_mode);
+ break;
+ case PROP_DEINTERLACE_METHOD:
+ g_value_set_enum (value, thiz->deinterlace_method);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
"Rotation Angle", gst_msdkvpp_rotation_get_type (),
PROP_ROTATION_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_DEINTERLACE_MODE] =
+ g_param_spec_enum ("deinterlace-mode", "Deinterlace Mode",
+ "Deinterlace mode to use", gst_msdkvpp_deinterlace_mode_get_type (),
+ PROP_DEINTERLACE_MODE_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_DEINTERLACE_METHOD] =
+ g_param_spec_enum ("deinterlace-method", "Deinterlace Method",
+ "Deinterlace method to use", gst_msdkvpp_deinterlace_method_get_type (),
+ PROP_DEINTERLACE_METHOD_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (gobject_class, PROP_N, obj_properties);
}
thiz->async_depth = PROP_ASYNC_DEPTH_DEFAULT;
thiz->denoise_factor = PROP_DENOISE_DEFAULT;
thiz->rotation = PROP_ROTATION_DEFAULT;
+ thiz->deinterlace_mode = PROP_DEINTERLACE_MODE_DEFAULT;
+ thiz->deinterlace_method = PROP_DEINTERLACE_METHOD_DEFAULT;
+ thiz->field_duration = GST_CLOCK_TIME_NONE;
gst_video_info_init (&thiz->sinkpad_info);
gst_video_info_init (&thiz->srcpad_info);
}
typedef struct _GstMsdkVPPClass GstMsdkVPPClass;
typedef enum {
- GST_MSDK_FLAG_DENOISE = 1 << 0,
- GST_MSDK_FLAG_ROTATION = 1 << 1,
+ GST_MSDK_FLAG_DENOISE = 1 << 0,
+ GST_MSDK_FLAG_ROTATION = 1 << 1,
+ GST_MSDK_FLAG_DEINTERLACE = 1 << 2,
} GstMsdkVppFlags;
struct _GstMsdkVPP
guint async_depth;
guint denoise_factor;
guint rotation;
+ guint deinterlace_mode;
+ guint deinterlace_method;
+ GstClockTime field_duration;
/* MFX Filters */
mfxExtVPPDoUse mfx_vpp_douse;
mfxU32 max_filter_algorithms [MAX_FILTER_ALGORITHMS];
mfxExtVPPDenoise mfx_denoise;
mfxExtVPPRotation mfx_rotation;
+ mfxExtVPPDeinterlacing mfx_deinterlace;
/* Extended buffers */
mfxExtBuffer *extra_params[MAX_EXTRA_PARAMS];
*/
#include "gstmsdkvpputil.h"
+#include "msdk-enums.h"
+
+gboolean
+gst_msdkvpp_is_deinterlace_enabled (GstMsdkVPP * msdkvpp, GstVideoInfo * vip)
+{
+ gboolean deinterlace;
+
+ switch (msdkvpp->deinterlace_mode) {
+ case GST_MSDKVPP_DEINTERLACE_MODE_AUTO:
+ deinterlace = GST_VIDEO_INFO_IS_INTERLACED (vip);
+ break;
+ case GST_MSDKVPP_DEINTERLACE_MODE_INTERLACED:
+ deinterlace = TRUE;
+ break;
+ default:
+ deinterlace = FALSE;
+ break;
+ }
+ return deinterlace;
+}
static gboolean
fixate_output_frame_size (GstMsdkVPP * thiz, GstVideoInfo * vinfo,
}
static gboolean
+fixate_frame_rate (GstMsdkVPP * thiz, GstVideoInfo * vinfo, GstStructure * outs)
+{
+ gint fps_n, fps_d;
+
+ fps_n = GST_VIDEO_INFO_FPS_N (vinfo);
+ fps_d = GST_VIDEO_INFO_FPS_D (vinfo);
+ if (gst_msdkvpp_is_deinterlace_enabled (thiz, vinfo)) {
+ /* Fixme: set double framerate?:
+ * msdk is not outputting double framerate for bob or adv deinterlace */
+ if (!gst_util_fraction_multiply (fps_n, fps_d, 1, 1, &fps_n, &fps_d))
+ goto overflow_error;
+ }
+ gst_structure_set (outs, "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL);
+ return TRUE;
+
+ /* ERRORS */
+overflow_error:
+ {
+ GST_ELEMENT_ERROR (thiz, CORE, NEGOTIATION, (NULL),
+ ("Error calculating the output framerate - integer overflow"));
+ return FALSE;
+ }
+}
+
+static gboolean
set_multiview_mode (GstMsdkVPP * thiz, GstVideoInfo * vinfo,
GstStructure * outs)
{
return TRUE;
}
+static gboolean
+set_interlace_mode (GstMsdkVPP * thiz, GstVideoInfo * vinfo,
+ GstStructure * outs)
+{
+ const gchar *interlace_mode = NULL;
+
+ if (gst_msdkvpp_is_deinterlace_enabled (thiz, vinfo)) {
+ interlace_mode = "progressive";
+ } else {
+ interlace_mode =
+ gst_video_interlace_mode_to_string (GST_VIDEO_INFO_INTERLACE_MODE
+ (vinfo));
+ }
+
+ if (!interlace_mode)
+ return FALSE;
+
+ gst_structure_set (outs, "interlace-mode", G_TYPE_STRING, interlace_mode,
+ NULL);
+ return TRUE;
+}
+
static GstCaps *
_get_preferred_src_caps (GstMsdkVPP * thiz, GstVideoInfo * vinfo,
GstCaps * srccaps)
goto fixate_failed;
/* Fixate the framerate */
- gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
- GST_VIDEO_INFO_FPS_N (vinfo), GST_VIDEO_INFO_FPS_D (vinfo), NULL);
+ if (!fixate_frame_rate (thiz, vinfo, structure))
+ goto fixate_failed;
/* set multiview mode based on input caps */
if (!set_multiview_mode (thiz, vinfo, structure))
goto fixate_failed;
- /*Fixme: Set colorimetry and interlace mode */
+ /*Fixme: Set colorimetry */
+
+ /* set interlace mode */
+ if (!set_interlace_mode (thiz, vinfo, structure))
+ goto interlace_mode_failed;
outcaps = gst_caps_new_empty ();
gst_caps_append_structure (outcaps, structure);
gst_structure_free (structure);
return NULL;
}
+interlace_mode_failed:
+ {
+ GST_WARNING_OBJECT (thiz, "Invalid sink caps interlace mode");
+ return NULL;
+ }
}
/**
GstCaps *gst_msdkvpp_fixate_srccaps (GstMsdkVPP * msdkvpp,
GstCaps * sinkcaps, GstCaps * srccaps);
+gboolean
+gst_msdkvpp_is_deinterlace_enabled (GstMsdkVPP * msdkvpp,
+ GstVideoInfo * vip);
+
G_END_DECLS
#endif /* GST_MSDKVPPUTIL_H */
}
return type;
}
+
+GType
+gst_msdkvpp_deinterlace_mode_get_type (void)
+{
+ static GType type = 0;
+
+ static const GEnumValue values[] = {
+ {GST_MSDKVPP_DEINTERLACE_MODE_AUTO,
+ "Auto detection", "auto"},
+ {GST_MSDKVPP_DEINTERLACE_MODE_INTERLACED,
+ "Force deinterlacing", "interlaced"},
+ {GST_MSDKVPP_DEINTERLACE_MODE_DISABLED,
+ "Never deinterlace", "disabled"},
+ {0, NULL, NULL},
+ };
+
+ if (!type) {
+ type = g_enum_register_static ("GstMsdkVPPDeinterlaceMode", values);
+ }
+ return type;
+}
+
+GType
+gst_msdkvpp_deinterlace_method_get_type (void)
+{
+ static GType type = 0;
+
+ static const GEnumValue values[] = {
+ {_MFX_DEINTERLACE_METHOD_NONE,
+ "Disable deinterlacing", "none"},
+ {MFX_DEINTERLACING_BOB, "Bob deinterlacing", "bob"},
+ {MFX_DEINTERLACING_ADVANCED, "Advanced deinterlacing (Motion adaptive)",
+ "advanced"},
+#if 0
+ {MFX_DEINTERLACING_AUTO_DOUBLE,
+ "Auto mode with deinterlacing double framerate output",
+ "auto-double"},
+ {MFX_DEINTERLACING_AUTO_SINGLE,
+ "Auto mode with deinterlacing single framerate output",
+ "auto-single"},
+ {MFX_DEINTERLACING_FULL_FR_OUT,
+ "Deinterlace only mode with full framerate output", "full-fr"},
+ {MFX_DEINTERLACING_HALF_FR_OUT,
+ "Deinterlace only Mode with half framerate output", "half-fr"},
+ {MFX_DEINTERLACING_24FPS_OUT, "24 fps fixed output mode", "24-fps"},
+ {MFX_DEINTERLACING_FIXED_TELECINE_PATTERN,
+ "Fixed telecine pattern removal mode", "fixed-telecine-removal"},
+ {MFX_DEINTERLACING_30FPS_OUT, "30 fps fixed output mode", "30-fps"},
+ {MFX_DEINTERLACING_DETECT_INTERLACE, "Only interlace detection",
+ "only-detect"},
+#endif
+ {MFX_DEINTERLACING_ADVANCED_NOREF,
+ "Advanced deinterlacing mode without using of reference frames",
+ "advanced-no-ref"},
+ {MFX_DEINTERLACING_ADVANCED_SCD,
+ "Advanced deinterlacing mode with scene change detection",
+ "advanced-scd"},
+ {MFX_DEINTERLACING_FIELD_WEAVING, "Field weaving", "field-weave"},
+ {0, NULL, NULL},
+ };
+
+ if (!type) {
+ type = g_enum_register_static ("GstMsdkVPPDeinterlaceMethod", values);
+ }
+ return type;
+}
gst_msdkenc_adaptive_b_get_type (void);
/*========= MSDK VPP Enums =========================*/
+
GType
gst_msdkvpp_rotation_get_type (void);
+typedef enum
+{
+ GST_MSDKVPP_DEINTERLACE_MODE_AUTO = 0,
+ GST_MSDKVPP_DEINTERLACE_MODE_INTERLACED,
+ GST_MSDKVPP_DEINTERLACE_MODE_DISABLED,
+} GstMskdVPPDeinterlaceMode;
+
+GType
+gst_msdkvpp_deinterlace_mode_get_type (void);
+
+#define _MFX_DEINTERLACE_METHOD_NONE 0
+GType
+gst_msdkvpp_deinterlace_method_get_type (void);
+
G_END_DECLS
#endif
mfx_info->FrameRateExtD = GST_VIDEO_INFO_FPS_D (info);
mfx_info->AspectRatioW = GST_VIDEO_INFO_PAR_N (info);
mfx_info->AspectRatioH = GST_VIDEO_INFO_PAR_D (info);
- mfx_info->PicStruct = MFX_PICSTRUCT_PROGRESSIVE; /* this is by default */
+ mfx_info->PicStruct =
+ !GST_VIDEO_INFO_IS_INTERLACED (info) ? MFX_PICSTRUCT_PROGRESSIVE :
+ MFX_PICSTRUCT_UNKNOWN;
mfx_info->FourCC =
gst_msdk_get_mfx_fourcc_from_format (GST_VIDEO_INFO_FORMAT (info));
mfx_info->ChromaFormat =