#endif
#endif
+#if (MFX_VERSION >= 1028)
+#define EXT_SINK_FORMATS ", RGB16, Y410, Y210"
+#define EXT_SRC_FORMATS ", Y410, Y210"
+#elif (MFX_VERSION >= 1027)
+#define EXT_SINK_FORMATS ", Y410, Y210"
+#define EXT_SRC_FORMATS ", Y410, Y210"
+#else
+#define EXT_SINK_FORMATS ""
+#define EXT_SRC_FORMATS ""
+#endif
+
GST_DEBUG_CATEGORY_EXTERN (gst_msdkvpp_debug);
#define GST_CAT_DEFAULT gst_msdkvpp_debug
-#if (MFX_VERSION >= 1028)
-#define SUPPORTED_SYSTEM_FORMAT \
- "{ NV12, YV12, I420, YUY2, UYVY, VUYA, BGRA, BGRx, RGB16, P010_10LE }"
-#define SUPPORTED_DMABUF_FORMAT \
- "{ NV12, BGRA, YUY2, UYVY, VUYA, RGB16, P010_10LE}"
-#else
#define SUPPORTED_SYSTEM_FORMAT \
- "{ NV12, YV12, I420, YUY2, UYVY, VUYA, BGRA, BGRx, P010_10LE }"
+ "{ NV12, YV12, I420, YUY2, UYVY, VUYA, BGRA, BGRx, P010_10LE" EXT_SINK_FORMATS "}"
#define SUPPORTED_DMABUF_FORMAT \
- "{ NV12, BGRA, YUY2, UYVY, VUYA, P010_10LE}"
-#endif
+ "{ NV12, BGRA, YUY2, UYVY, VUYA, P010_10LE" EXT_SINK_FORMATS "}"
+#define SRC_SYSTEM_FORMAT \
+ "{ BGRA, NV12, YUY2, UYVY, VUYA, BGRx, P010_10LE" EXT_FORMATS EXT_SRC_FORMATS "}"
+#define SRC_DMABUF_FORMAT \
+ "{ BGRA, YUY2, UYVY, NV12, VUYA, BGRx, P010_10LE" EXT_FORMATS EXT_SRC_FORMATS "}"
#ifndef _WIN32
#define DMABUF_SINK_CAPS_STR \
#ifndef _WIN32
#define DMABUF_SRC_CAPS_STR \
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_DMABUF, \
- "{ BGRA, YUY2, UYVY, NV12, VUYA, BGRx, P010_10LE" EXT_FORMATS "}") ";"
+ SRC_DMABUF_FORMAT) ";"
#else
#define DMABUF_SRC_CAPS_STR ""
#endif
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (DMABUF_SRC_CAPS_STR
- GST_VIDEO_CAPS_MAKE ("{ BGRA, NV12, YUY2, UYVY, VUYA, BGRx, P010_10LE"
- EXT_FORMATS "}") ", "
+ GST_VIDEO_CAPS_MAKE (SRC_SYSTEM_FORMAT) ", "
"interlace-mode = (string){ progressive, interleaved, mixed }" ";"));
enum
PROP_HARDWARE,
PROP_ASYNC_DEPTH,
PROP_DENOISE,
+#ifndef GST_REMOVE_DEPRECATED
PROP_ROTATION,
+#endif
PROP_DEINTERLACE_MODE,
PROP_DEINTERLACE_METHOD,
PROP_HUE,
PROP_BRIGHTNESS,
PROP_CONTRAST,
PROP_DETAIL,
+#ifndef GST_REMOVE_DEPRECATED
PROP_MIRRORING,
+#endif
PROP_SCALING_MODE,
PROP_FORCE_ASPECT_RATIO,
PROP_FRC_ALGORITHM,
+ PROP_VIDEO_DIRECTION,
+ PROP_CROP_LEFT,
+ PROP_CROP_RIGHT,
+ PROP_CROP_TOP,
+ PROP_CROP_BOTTOM,
PROP_N,
};
#define PROP_HARDWARE_DEFAULT TRUE
#define PROP_ASYNC_DEPTH_DEFAULT 1
#define PROP_DENOISE_DEFAULT 0
+#ifndef GST_REMOVE_DEPRECATED
#define PROP_ROTATION_DEFAULT MFX_ANGLE_0
+#define PROP_MIRRORING_DEFAULT MFX_MIRRORING_DISABLED
+#endif
#define PROP_DEINTERLACE_MODE_DEFAULT GST_MSDKVPP_DEINTERLACE_MODE_AUTO
#define PROP_DEINTERLACE_METHOD_DEFAULT MFX_DEINTERLACING_BOB
#define PROP_HUE_DEFAULT 0
#define PROP_BRIGHTNESS_DEFAULT 0
#define PROP_CONTRAST_DEFAULT 1
#define PROP_DETAIL_DEFAULT 0
-#define PROP_MIRRORING_DEFAULT MFX_MIRRORING_DISABLED
#define PROP_SCALING_MODE_DEFAULT MFX_SCALING_MODE_DEFAULT
#define PROP_FORCE_ASPECT_RATIO_DEFAULT TRUE
#define PROP_FRC_ALGORITHM_DEFAULT _MFX_FRC_ALGORITHM_NONE
+#define PROP_VIDEO_DIRECTION_DEFAULT GST_VIDEO_ORIENTATION_IDENTITY
+#define PROP_CROP_LEFT_DEFAULT 0
+#define PROP_CROP_RIGHT_DEFAULT 0
+#define PROP_CROP_TOP_DEFAULT 0
+#define PROP_CROP_BOTTOM_DEFAULT 0
#define gst_msdkvpp_parent_class parent_class
G_DEFINE_TYPE (GstMsdkVPP, gst_msdkvpp, GST_TYPE_BASE_TRANSFORM);
if (!gst_video_info_from_caps (&info, caps))
goto error_no_video_info;
- gst_msdk_set_video_alignment (&info, &align);
+ gst_msdk_set_video_alignment (&info, 0, 0, &align);
gst_video_info_align (&info, &align);
if (use_dmabuf)
if (!gst_buffer_pool_set_config (pool, config))
goto error_pool_config;
- /* Updating pool_info with algined info of allocator */
+ /* Updating pool_info with aligned info of allocator */
*pool_info = info;
return pool;
gst_object_unref (thiz->srcpad_buffer_pool);
/* Always create a pool for vpp out buffers. Each of the msdk element
- * has to create it's own mfxsurfacepool which is an msdk contraint.
+ * has to create it's own mfxsurfacepool which is an msdk constraint.
* For eg: Each Msdk component (vpp, dec and enc) will invoke the external
* Frame allocator for video-memory usage.So sharing the pool between
* gst-msdk elements might not be a good idea, rather each element
gst_query_add_allocation_param (query, allocator, ¶ms);
gst_structure_free (config);
- /* if upstream does't have a pool requirement, set only
+ /* if upstream doesn't have a pool requirement, set only
* size, min_buffers and max_buffers in query */
gst_query_add_allocation_pool (query, need_pool ? pool : NULL, size,
min_buffers, 0);
mfxSession session;
mfxSyncPoint sync_point = NULL;
mfxStatus status;
+ mfxFrameInfo *in_info = NULL;
MsdkSurface *in_surface = NULL;
MsdkSurface *out_surface = NULL;
out_surface->surface = gst_msdk_get_surface_from_buffer (outbuf);
} else {
GST_ERROR ("Failed to get msdk outsurface!");
+ free_msdk_surface (in_surface);
return GST_FLOW_ERROR;
}
+ /* update surface crop info (NOTE: msdk min frame size is 2x2) */
+ in_info = &in_surface->surface->Info;
+ if ((thiz->crop_left + thiz->crop_right >= in_info->CropW - 1)
+ || (thiz->crop_top + thiz->crop_bottom >= in_info->CropH - 1)) {
+ GST_WARNING_OBJECT (thiz, "ignoring crop... cropping too much!");
+ } else {
+ in_info->CropX = thiz->crop_left;
+ in_info->CropY = thiz->crop_top;
+ in_info->CropW -= thiz->crop_left + thiz->crop_right;
+ in_info->CropH -= thiz->crop_top + thiz->crop_bottom;
+ }
+
session = gst_msdk_context_get_session (thiz->context);
/* outer loop is for handling FrameRate Control and deinterlace use cases */
g_usleep (1000);
};
- if (status != MFX_ERR_NONE && status != MFX_ERR_MORE_DATA
+ if (status == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM)
+ GST_WARNING_OBJECT (thiz, "VPP returned: %s",
+ msdk_status_to_string (status));
+ else if (status != MFX_ERR_NONE && status != MFX_ERR_MORE_DATA
&& status != MFX_ERR_MORE_SURFACE)
goto vpp_error;
}
} while (status == MFX_ERR_MORE_SURFACE);
- free_msdk_surface (in_surface);
- return ret;
+ goto transform_end;
vpp_error:
GST_ERROR_OBJECT (thiz, "MSDK Failed to do VPP");
- free_msdk_surface (in_surface);
- free_msdk_surface (out_surface);
- return GST_FLOW_ERROR;
+ ret = GST_FLOW_ERROR;
+ goto transform_end;
error_more_data:
GST_WARNING_OBJECT (thiz,
- "MSDK Requries additional input for processing, "
+ "MSDK Requires additional input for processing, "
"Retruning FLOW_DROPPED since no output buffer was generated");
- free_msdk_surface (in_surface);
- return GST_BASE_TRANSFORM_FLOW_DROPPED;
+ ret = GST_BASE_TRANSFORM_FLOW_DROPPED;
+ goto transform_end;
error_push_buffer:
- {
- free_msdk_surface (in_surface);
- free_msdk_surface (out_surface);
- GST_DEBUG_OBJECT (thiz, "failed to push output buffer: %s",
- gst_flow_get_name (ret));
- return ret;
- }
+ GST_DEBUG_OBJECT (thiz, "failed to push output buffer: %s",
+ gst_flow_get_name (ret));
+
+transform_end:
+ free_msdk_surface (in_surface);
+ free_msdk_surface (out_surface);
+
+ return ret;
}
static void
if (!thiz->context)
return;
+ if (thiz->use_video_memory) {
+ gst_msdk_frame_free (thiz->context, &thiz->in_alloc_resp);
+ gst_msdk_frame_free (thiz->context, &thiz->out_alloc_resp);
+ }
+
GST_DEBUG_OBJECT (thiz, "Closing VPP 0x%p", thiz->context);
status = MFXVideoVPP_Close (gst_msdk_context_get_session (thiz->context));
if (status != MFX_ERR_NONE && status != MFX_ERR_NOT_INITIALIZED) {
static void
ensure_filters (GstMsdkVPP * thiz)
{
-
/* Denoise */
if (thiz->flags & GST_MSDK_FLAG_DENOISE) {
mfxExtVPPDenoise *mfx_denoise = &thiz->mfx_denoise;
}
/* Rotation */
- if (thiz->flags & GST_MSDK_FLAG_ROTATION) {
+ if (thiz->rotation != MFX_ANGLE_0) {
mfxExtVPPRotation *mfx_rotation = &thiz->mfx_rotation;
mfx_rotation->Header.BufferId = MFX_EXTBUFF_VPP_ROTATION;
mfx_rotation->Header.BufferSz = sizeof (mfxExtVPPRotation);
}
/* Mirroring */
- if (thiz->flags & GST_MSDK_FLAG_MIRRORING) {
+ if (thiz->mirroring != MFX_MIRRORING_DISABLED) {
mfxExtVPPMirroring *mfx_mirroring = &thiz->mfx_mirroring;
mfx_mirroring->Header.BufferId = MFX_EXTBUFF_VPP_MIRRORING;
mfx_mirroring->Header.BufferSz = sizeof (mfxExtVPPMirroring);
* otherwise the subsequent function call of MFXVideoVPP_Init() will
* fail
*/
- if (thiz->initialized)
+ if (thiz->initialized) {
+ if (thiz->use_video_memory) {
+ gst_msdk_frame_free (thiz->context, &thiz->in_alloc_resp);
+ gst_msdk_frame_free (thiz->context, &thiz->out_alloc_resp);
+ }
+
MFXVideoVPP_Close (session);
+ }
if (thiz->use_video_memory) {
gst_msdk_set_frame_allocator (thiz->context);
/* Enable the required filters */
ensure_filters (thiz);
- /* Add exteneded buffers */
+ /* Add extended buffers */
if (thiz->num_extra_params) {
thiz->param.NumExtParam = thiz->num_extra_params;
thiz->param.ExtParam = thiz->extra_params;
gst_msdkvpp_set_passthrough (thiz);
/* Ensure sinkpad buffer pool */
+ if (thiz->sinkpad_buffer_pool)
+ gst_object_unref (thiz->sinkpad_buffer_pool);
+
thiz->sinkpad_buffer_pool =
gst_msdkvpp_create_buffer_pool (thiz, GST_PAD_SINK, caps,
thiz->in_num_surfaces);
return FALSE;
}
/* Ensure a srcpad buffer pool */
+ if (thiz->srcpad_buffer_pool)
+ gst_object_unref (thiz->srcpad_buffer_pool);
+
thiz->srcpad_buffer_pool =
gst_msdkvpp_create_buffer_pool (thiz, GST_PAD_SRC, out_caps,
thiz->out_num_surfaces);
result = gst_caps_fixate (result);
use_dmabuf = &thiz->use_sinkpad_dmabuf;
} else {
+ /*
+ * Override mirroring & rotation properties once video-direction
+ * is set explicitly
+ */
+ if (thiz->flags & GST_MSDK_FLAG_VIDEO_DIRECTION)
+ gst_msdk_get_mfx_video_orientation_from_video_direction
+ (thiz->video_direction, &thiz->mirroring, &thiz->rotation);
+
result = gst_msdkvpp_fixate_srccaps (thiz, caps, othercaps);
use_dmabuf = &thiz->use_srcpad_dmabuf;
}
thiz->denoise_factor = g_value_get_uint (value);
thiz->flags |= GST_MSDK_FLAG_DENOISE;
break;
+#ifndef GST_REMOVE_DEPRECATED
case PROP_ROTATION:
thiz->rotation = g_value_get_enum (value);
thiz->flags |= GST_MSDK_FLAG_ROTATION;
break;
+ case PROP_MIRRORING:
+ thiz->mirroring = g_value_get_enum (value);
+ thiz->flags |= GST_MSDK_FLAG_MIRRORING;
+ break;
+#endif
case PROP_DEINTERLACE_MODE:
thiz->deinterlace_mode = g_value_get_enum (value);
break;
thiz->detail = g_value_get_uint (value);
thiz->flags |= GST_MSDK_FLAG_DETAIL;
break;
- case PROP_MIRRORING:
- thiz->mirroring = g_value_get_enum (value);
- thiz->flags |= GST_MSDK_FLAG_MIRRORING;
- break;
case PROP_SCALING_MODE:
thiz->scaling_mode = g_value_get_enum (value);
thiz->flags |= GST_MSDK_FLAG_SCALING_MODE;
case PROP_FRC_ALGORITHM:
thiz->frc_algm = g_value_get_enum (value);
break;
+ case PROP_VIDEO_DIRECTION:
+ thiz->video_direction = g_value_get_enum (value);
+ thiz->flags |= GST_MSDK_FLAG_VIDEO_DIRECTION;
+ break;
+ case PROP_CROP_LEFT:
+ thiz->crop_left = g_value_get_uint (value);
+ break;
+ case PROP_CROP_RIGHT:
+ thiz->crop_right = g_value_get_uint (value);
+ break;
+ case PROP_CROP_TOP:
+ thiz->crop_top = g_value_get_uint (value);
+ break;
+ case PROP_CROP_BOTTOM:
+ thiz->crop_bottom = g_value_get_uint (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_DENOISE:
g_value_set_uint (value, thiz->denoise_factor);
break;
+#ifndef GST_REMOVE_DEPRECATED
case PROP_ROTATION:
g_value_set_enum (value, thiz->rotation);
break;
+ case PROP_MIRRORING:
+ g_value_set_enum (value, thiz->mirroring);
+ break;
+#endif
case PROP_DEINTERLACE_MODE:
g_value_set_enum (value, thiz->deinterlace_mode);
break;
case PROP_DETAIL:
g_value_set_uint (value, thiz->detail);
break;
- case PROP_MIRRORING:
- g_value_set_enum (value, thiz->mirroring);
- break;
case PROP_SCALING_MODE:
g_value_set_enum (value, thiz->scaling_mode);
break;
case PROP_FRC_ALGORITHM:
g_value_set_enum (value, thiz->frc_algm);
break;
+ case PROP_VIDEO_DIRECTION:
+ g_value_set_enum (value, thiz->video_direction);
+ break;
+ case PROP_CROP_LEFT:
+ g_value_set_uint (value, thiz->crop_left);
+ break;
+ case PROP_CROP_RIGHT:
+ g_value_set_uint (value, thiz->crop_right);
+ break;
+ case PROP_CROP_TOP:
+ g_value_set_uint (value, thiz->crop_top);
+ break;
+ case PROP_CROP_BOTTOM:
+ g_value_set_uint (value, thiz->crop_bottom);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
"Denoising Factor",
0, 100, PROP_DENOISE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+#ifndef GST_REMOVE_DEPRECATED
obj_properties[PROP_ROTATION] =
g_param_spec_enum ("rotation", "Rotation",
- "Rotation Angle", gst_msdkvpp_rotation_get_type (),
- PROP_ROTATION_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ "Rotation Angle (DEPRECATED, use video-direction instead)",
+ gst_msdkvpp_rotation_get_type (), PROP_ROTATION_DEFAULT,
+ G_PARAM_DEPRECATED | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_MIRRORING] =
+ g_param_spec_enum ("mirroring", "Mirroring",
+ "The Mirroring type (DEPRECATED, use video-direction instead)",
+ gst_msdkvpp_mirroring_get_type (), PROP_MIRRORING_DEFAULT,
+ G_PARAM_DEPRECATED | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+#endif
obj_properties[PROP_DEINTERLACE_MODE] =
g_param_spec_enum ("deinterlace-mode", "Deinterlace Mode",
"The factor of detail/edge enhancement filter algorithm",
0, 100, PROP_DETAIL_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_MIRRORING] =
- g_param_spec_enum ("mirroring", "Mirroring",
- "The Mirroring type", gst_msdkvpp_mirroring_get_type (),
- PROP_MIRRORING_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
obj_properties[PROP_SCALING_MODE] =
g_param_spec_enum ("scaling-mode", "Scaling Mode",
"The Scaling mode to use", gst_msdkvpp_scaling_mode_get_type (),
gst_msdkvpp_frc_algorithm_get_type (), PROP_FRC_ALGORITHM_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ /*
+ * The video-direction to use, expressed as an enum value. See
+ * #GstVideoOrientationMethod.
+ */
+ obj_properties[PROP_VIDEO_DIRECTION] = g_param_spec_enum ("video-direction",
+ "Video Direction", "Video direction: rotation and flipping"
+#ifndef GST_REMOVE_DEPRECATED
+ ", it will override both mirroring & rotation properties if set explicitly"
+#endif
+ ,
+ GST_TYPE_VIDEO_ORIENTATION_METHOD,
+ PROP_VIDEO_DIRECTION_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_CROP_LEFT] = g_param_spec_uint ("crop-left",
+ "Crop Left", "Pixels to crop at left",
+ 0, G_MAXUINT16, PROP_CROP_LEFT_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_CROP_RIGHT] = g_param_spec_uint ("crop-right",
+ "Crop Right", "Pixels to crop at right",
+ 0, G_MAXUINT16, PROP_CROP_RIGHT_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_CROP_TOP] = g_param_spec_uint ("crop-top",
+ "Crop Top", "Pixels to crop at top",
+ 0, G_MAXUINT16, PROP_CROP_TOP_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_CROP_BOTTOM] = g_param_spec_uint ("crop-bottom",
+ "Crop Bottom", "Pixels to crop at bottom",
+ 0, G_MAXUINT16, PROP_CROP_BOTTOM_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (gobject_class, PROP_N, obj_properties);
}
thiz->hardware = PROP_HARDWARE_DEFAULT;
thiz->async_depth = PROP_ASYNC_DEPTH_DEFAULT;
thiz->denoise_factor = PROP_DENOISE_DEFAULT;
+#ifndef GST_REMOVE_DEPRECATED
thiz->rotation = PROP_ROTATION_DEFAULT;
+ thiz->mirroring = PROP_MIRRORING_DEFAULT;
+#else
+ thiz->rotation = MFX_ANGLE_0;
+ thiz->mirroring = MFX_MIRRORING_DISABLED;
+#endif
thiz->deinterlace_mode = PROP_DEINTERLACE_MODE_DEFAULT;
thiz->deinterlace_method = PROP_DEINTERLACE_METHOD_DEFAULT;
thiz->buffer_duration = GST_CLOCK_TIME_NONE;
thiz->brightness = PROP_BRIGHTNESS_DEFAULT;
thiz->contrast = PROP_CONTRAST_DEFAULT;
thiz->detail = PROP_DETAIL_DEFAULT;
- thiz->mirroring = PROP_MIRRORING_DEFAULT;
thiz->scaling_mode = PROP_SCALING_MODE_DEFAULT;
thiz->keep_aspect = PROP_FORCE_ASPECT_RATIO_DEFAULT;
thiz->frc_algm = PROP_FRC_ALGORITHM_DEFAULT;
+ thiz->video_direction = PROP_VIDEO_DIRECTION_DEFAULT;
+ thiz->crop_left = PROP_CROP_LEFT_DEFAULT;
+ thiz->crop_right = PROP_CROP_RIGHT_DEFAULT;
+ thiz->crop_top = PROP_CROP_TOP_DEFAULT;
+ thiz->crop_bottom = PROP_CROP_BOTTOM_DEFAULT;
+
gst_video_info_init (&thiz->sinkpad_info);
gst_video_info_init (&thiz->srcpad_info);
}