mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-13 23:22:54 +00:00
msdk: vpp: Add deinterlacing support
https://bugzilla.gnome.org/show_bug.cgi?id=793705
This commit is contained in:
parent
36e81744d1
commit
f5a3d3d799
7 changed files with 230 additions and 6 deletions
|
@ -69,6 +69,8 @@ enum
|
|||
PROP_ASYNC_DEPTH,
|
||||
PROP_DENOISE,
|
||||
PROP_ROTATION,
|
||||
PROP_DEINTERLACE_MODE,
|
||||
PROP_DEINTERLACE_METHOD,
|
||||
PROP_N,
|
||||
};
|
||||
|
||||
|
@ -76,6 +78,8 @@ enum
|
|||
#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);
|
||||
|
@ -581,6 +585,7 @@ gst_msdkvpp_close (GstMsdkVPP * thiz)
|
|||
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);
|
||||
}
|
||||
|
@ -612,6 +617,17 @@ ensure_filters (GstMsdkVPP * thiz)
|
|||
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;
|
||||
|
@ -682,6 +698,10 @@ gst_msdkvpp_initialize (GstMsdkVPP * thiz)
|
|||
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) {
|
||||
|
@ -753,6 +773,7 @@ gst_msdkvpp_set_caps (GstBaseTransform * trans, GstCaps * caps,
|
|||
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);
|
||||
|
@ -773,6 +794,14 @@ gst_msdkvpp_set_caps (GstBaseTransform * trans, GstCaps * 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;
|
||||
|
||||
|
@ -880,6 +909,12 @@ gst_msdkvpp_set_property (GObject * object, guint prop_id,
|
|||
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;
|
||||
|
@ -905,6 +940,12 @@ gst_msdkvpp_get_property (GObject * object, guint prop_id,
|
|||
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;
|
||||
|
@ -995,6 +1036,18 @@ gst_msdkvpp_class_init (GstMsdkVPPClass * klass)
|
|||
"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);
|
||||
}
|
||||
|
||||
|
@ -1005,6 +1058,9 @@ gst_msdkvpp_init (GstMsdkVPP * thiz)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -61,8 +61,9 @@ typedef struct _GstMsdkVPP GstMsdkVPP;
|
|||
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
|
||||
|
@ -99,12 +100,16 @@ 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];
|
||||
|
|
|
@ -26,6 +26,26 @@
|
|||
*/
|
||||
|
||||
#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,
|
||||
|
@ -406,6 +426,31 @@ overflow_error:
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -429,6 +474,28 @@ set_multiview_mode (GstMsdkVPP * thiz, GstVideoInfo * vinfo,
|
|||
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)
|
||||
|
@ -450,14 +517,18 @@ _get_preferred_src_caps (GstMsdkVPP * thiz, GstVideoInfo * vinfo,
|
|||
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);
|
||||
|
@ -471,6 +542,11 @@ fixate_failed:
|
|||
gst_structure_free (structure);
|
||||
return NULL;
|
||||
}
|
||||
interlace_mode_failed:
|
||||
{
|
||||
GST_WARNING_OBJECT (thiz, "Invalid sink caps interlace mode");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,6 +33,10 @@ G_BEGIN_DECLS
|
|||
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 */
|
||||
|
|
|
@ -176,3 +176,69 @@ gst_msdkvpp_rotation_get_type (void)
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -60,8 +60,23 @@ GType
|
|||
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
|
||||
|
|
|
@ -265,7 +265,9 @@ gst_msdk_set_mfx_frame_info_from_video_info (mfxFrameInfo * mfx_info,
|
|||
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 =
|
||||
|
|
Loading…
Reference in a new issue