mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
filter: add helper to specify references for deinterlacing.
Add gst_vaapi_fitler_set_deinterlacing_references() API to submit the list of surfaces used for forward or backward reference in advanced deinterlacing mode, e.g. Motion-Adaptive, Motion-Compensated. The list of surfaces used as deinterlacing references shall be live until the next call to gst_vaapi_filter_process(). Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
parent
06c7fde8e0
commit
5a9e169504
3 changed files with 142 additions and 0 deletions
|
@ -397,6 +397,7 @@ gst_vaapi_filter_set_saturation
|
||||||
gst_vaapi_filter_set_brightness
|
gst_vaapi_filter_set_brightness
|
||||||
gst_vaapi_filter_set_saturation
|
gst_vaapi_filter_set_saturation
|
||||||
gst_vaapi_filter_set_deinterlacing
|
gst_vaapi_filter_set_deinterlacing
|
||||||
|
gst_vaapi_filter_set_deinterlacing_references
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
GST_VAAPI_FILTER
|
GST_VAAPI_FILTER
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
|
@ -63,6 +63,8 @@ struct _GstVaapiFilter {
|
||||||
GPtrArray *operations;
|
GPtrArray *operations;
|
||||||
GstVideoFormat format;
|
GstVideoFormat format;
|
||||||
GArray *formats;
|
GArray *formats;
|
||||||
|
GArray *forward_references;
|
||||||
|
GArray *backward_references;
|
||||||
GstVaapiRectangle crop_rect;
|
GstVaapiRectangle crop_rect;
|
||||||
GstVaapiRectangle target_rect;
|
GstVaapiRectangle target_rect;
|
||||||
guint use_crop_rect : 1;
|
guint use_crop_rect : 1;
|
||||||
|
@ -851,6 +853,33 @@ op_set_deinterlace(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data,
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
deint_refs_set(GArray *refs, GstVaapiSurface **surfaces, guint num_surfaces)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (num_surfaces > 0 && !surfaces)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < num_surfaces; i++)
|
||||||
|
g_array_append_val(refs, GST_VAAPI_OBJECT_ID(surfaces[i]));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
deint_refs_clear(GArray *refs)
|
||||||
|
{
|
||||||
|
if (refs->len > 0)
|
||||||
|
g_array_remove_range(refs, 0, refs->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
deint_refs_clear_all(GstVaapiFilter *filter)
|
||||||
|
{
|
||||||
|
deint_refs_clear(filter->forward_references);
|
||||||
|
deint_refs_clear(filter->backward_references);
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
/* --- Surface Formats --- */
|
/* --- Surface Formats --- */
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
@ -952,6 +981,16 @@ gst_vaapi_filter_init(GstVaapiFilter *filter, GstVaapiDisplay *display)
|
||||||
filter->va_context = VA_INVALID_ID;
|
filter->va_context = VA_INVALID_ID;
|
||||||
filter->format = DEFAULT_FORMAT;
|
filter->format = DEFAULT_FORMAT;
|
||||||
|
|
||||||
|
filter->forward_references =
|
||||||
|
g_array_sized_new(FALSE, FALSE, sizeof(VASurfaceID), 4);
|
||||||
|
if (!filter->forward_references)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
filter->backward_references =
|
||||||
|
g_array_sized_new(FALSE, FALSE, sizeof(VASurfaceID), 4);
|
||||||
|
if (!filter->backward_references)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (!GST_VAAPI_DISPLAY_HAS_VPP(display))
|
if (!GST_VAAPI_DISPLAY_HAS_VPP(display))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -995,6 +1034,16 @@ gst_vaapi_filter_finalize(GstVaapiFilter *filter)
|
||||||
GST_VAAPI_DISPLAY_UNLOCK(filter->display);
|
GST_VAAPI_DISPLAY_UNLOCK(filter->display);
|
||||||
gst_vaapi_display_replace(&filter->display, NULL);
|
gst_vaapi_display_replace(&filter->display, NULL);
|
||||||
|
|
||||||
|
if (filter->forward_references) {
|
||||||
|
g_array_unref(filter->forward_references);
|
||||||
|
filter->backward_references = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter->backward_references) {
|
||||||
|
g_array_unref(filter->backward_references);
|
||||||
|
filter->backward_references = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter->formats) {
|
if (filter->formats) {
|
||||||
g_array_unref(filter->formats);
|
g_array_unref(filter->formats);
|
||||||
filter->formats = NULL;
|
filter->formats = NULL;
|
||||||
|
@ -1252,6 +1301,7 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter,
|
||||||
VAProcPipelineParameterBuffer *pipeline_param = NULL;
|
VAProcPipelineParameterBuffer *pipeline_param = NULL;
|
||||||
VABufferID pipeline_param_buf_id;
|
VABufferID pipeline_param_buf_id;
|
||||||
VABufferID filters[N_PROPERTIES];
|
VABufferID filters[N_PROPERTIES];
|
||||||
|
VAProcPipelineCaps pipeline_caps;
|
||||||
guint i, num_filters = 0;
|
guint i, num_filters = 0;
|
||||||
VAStatus va_status;
|
VAStatus va_status;
|
||||||
VARectangle src_rect, dst_rect;
|
VARectangle src_rect, dst_rect;
|
||||||
|
@ -1316,6 +1366,12 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter,
|
||||||
filters[num_filters++] = op_data->va_buffer;
|
filters[num_filters++] = op_data->va_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Validate pipeline caps */
|
||||||
|
va_status = vaQueryVideoProcPipelineCaps(filter->va_display,
|
||||||
|
filter->va_context, filters, num_filters, &pipeline_caps);
|
||||||
|
if (!vaapi_check_status(va_status, "vaQueryVideoProcPipelineCaps()"))
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (!vaapi_create_buffer(filter->va_display, filter->va_context,
|
if (!vaapi_create_buffer(filter->va_display, filter->va_context,
|
||||||
VAProcPipelineParameterBufferType, sizeof(*pipeline_param),
|
VAProcPipelineParameterBufferType, sizeof(*pipeline_param),
|
||||||
NULL, &pipeline_param_buf_id, (gpointer *)&pipeline_param))
|
NULL, &pipeline_param_buf_id, (gpointer *)&pipeline_param))
|
||||||
|
@ -1332,6 +1388,31 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter,
|
||||||
pipeline_param->filters = filters;
|
pipeline_param->filters = filters;
|
||||||
pipeline_param->num_filters = num_filters;
|
pipeline_param->num_filters = num_filters;
|
||||||
|
|
||||||
|
// Reference frames for advanced deinterlacing
|
||||||
|
if (filter->forward_references->len > 0) {
|
||||||
|
pipeline_param->forward_references = (VASurfaceID *)
|
||||||
|
filter->forward_references->data;
|
||||||
|
pipeline_param->num_forward_references =
|
||||||
|
MIN(filter->forward_references->len,
|
||||||
|
pipeline_caps.num_forward_references);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pipeline_param->forward_references = NULL;
|
||||||
|
pipeline_param->num_forward_references = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter->backward_references->len > 0) {
|
||||||
|
pipeline_param->backward_references = (VASurfaceID *)
|
||||||
|
filter->backward_references->data;
|
||||||
|
pipeline_param->num_backward_references =
|
||||||
|
MIN(filter->backward_references->len,
|
||||||
|
pipeline_caps.num_backward_references);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pipeline_param->backward_references = NULL;
|
||||||
|
pipeline_param->num_backward_references = 0;
|
||||||
|
}
|
||||||
|
|
||||||
vaapi_unmap_buffer(filter->va_display, pipeline_param_buf_id, NULL);
|
vaapi_unmap_buffer(filter->va_display, pipeline_param_buf_id, NULL);
|
||||||
|
|
||||||
va_status = vaBeginPicture(filter->va_display, filter->va_context,
|
va_status = vaBeginPicture(filter->va_display, filter->va_context,
|
||||||
|
@ -1347,10 +1428,13 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter,
|
||||||
va_status = vaEndPicture(filter->va_display, filter->va_context);
|
va_status = vaEndPicture(filter->va_display, filter->va_context);
|
||||||
if (!vaapi_check_status(va_status, "vaEndPicture()"))
|
if (!vaapi_check_status(va_status, "vaEndPicture()"))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
deint_refs_clear_all(filter);
|
||||||
return GST_VAAPI_FILTER_STATUS_SUCCESS;
|
return GST_VAAPI_FILTER_STATUS_SUCCESS;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
vaDestroyBuffer(filter->va_display, pipeline_param_buf_id);
|
vaDestroyBuffer(filter->va_display, pipeline_param_buf_id);
|
||||||
|
deint_refs_clear_all(filter);
|
||||||
return GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED;
|
return GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED;
|
||||||
#endif
|
#endif
|
||||||
return GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_OPERATION;
|
return GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_OPERATION;
|
||||||
|
@ -1605,3 +1689,55 @@ gst_vaapi_filter_set_deinterlacing(GstVaapiFilter *filter,
|
||||||
find_operation(filter, GST_VAAPI_FILTER_OP_DEINTERLACING), method,
|
find_operation(filter, GST_VAAPI_FILTER_OP_DEINTERLACING), method,
|
||||||
flags);
|
flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vaapi_filter_set_deinterlacing_references:
|
||||||
|
* @filter: a #GstVaapiFilter
|
||||||
|
* @forward_references: the set of #GstVaapiSurface objects used as
|
||||||
|
* forward references
|
||||||
|
* @num_forward_references: the number of elements in the
|
||||||
|
* @forward_references array
|
||||||
|
* @backward_references: the set of #GstVaapiSurface objects used as
|
||||||
|
* backward references
|
||||||
|
* @num_backward_references: the number of elements in the
|
||||||
|
* @backward_references array
|
||||||
|
*
|
||||||
|
* Specifies the list of surfaces used for forward or backward reference in
|
||||||
|
* advanced deinterlacing mode. The caller is responsible for maintaining
|
||||||
|
* the associated surfaces live until gst_vaapi_filter_process() completes.
|
||||||
|
* e.g. by holding an extra reference to the associated #GstVaapiSurfaceProxy.
|
||||||
|
*
|
||||||
|
* Temporal ordering is maintained as follows: the shorter index in
|
||||||
|
* either array is, the closest the matching surface is relatively to
|
||||||
|
* the current source surface to process. e.g. surface in
|
||||||
|
* @forward_references array index 0 represents the immediately
|
||||||
|
* preceding surface in display order, surface at index 1 is the one
|
||||||
|
* preceding surface at index 0, etc.
|
||||||
|
*
|
||||||
|
* The video processing filter will only use the recommended number of
|
||||||
|
* surfaces for backward and forward references.
|
||||||
|
*
|
||||||
|
* Note: the supplied lists of reference surfaces are not sticky. This
|
||||||
|
* means that they are only valid for the next gst_vaapi_filter_process()
|
||||||
|
* call, and thus needs to be submitted again for subsequent calls.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the operation is supported, %FALSE otherwise.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_filter_set_deinterlacing_references(GstVaapiFilter *filter,
|
||||||
|
GstVaapiSurface **forward_references, guint num_forward_references,
|
||||||
|
GstVaapiSurface **backward_references, guint num_backward_references)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(filter != NULL, FALSE);
|
||||||
|
|
||||||
|
deint_refs_clear_all(filter);
|
||||||
|
|
||||||
|
if (!deint_refs_set(filter->forward_references, forward_references,
|
||||||
|
num_forward_references))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!deint_refs_set(filter->backward_references, backward_references,
|
||||||
|
num_backward_references))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -206,4 +206,9 @@ gboolean
|
||||||
gst_vaapi_filter_set_deinterlacing(GstVaapiFilter *filter,
|
gst_vaapi_filter_set_deinterlacing(GstVaapiFilter *filter,
|
||||||
GstVaapiDeinterlaceMethod method, guint flags);
|
GstVaapiDeinterlaceMethod method, guint flags);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_filter_set_deinterlacing_references(GstVaapiFilter *filter,
|
||||||
|
GstVaapiSurface **forward_references, guint num_forward_references,
|
||||||
|
GstVaapiSurface **backward_references, guint num_backward_references);
|
||||||
|
|
||||||
#endif /* GST_VAAPI_FILTER_H */
|
#endif /* GST_VAAPI_FILTER_H */
|
||||||
|
|
Loading…
Reference in a new issue