/*
 *  gstvaapifilter.h - Video processing abstraction
 *
 *  Copyright (C) 2013 Intel Corporation
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1
 *  of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301 USA
 */

#ifndef GST_VAAPI_FILTER_H
#define GST_VAAPI_FILTER_H

G_BEGIN_DECLS

typedef struct _GstVaapiFilter                  GstVaapiFilter;
typedef struct _GstVaapiFilterOperationInfo     GstVaapiFilterOperationInfo;

/**
 * @GST_VAAPI_FILTER_OP_FORMAT: Force output pixel format (#GstVideoFormat).
 * @GST_VAAPI_FILTER_OP_CROP: Crop source surface (#GstVaapiRectangle).
 * @GST_VAAPI_FILTER_OP_DENOISE: Noise reduction (float).
 * @GST_VAAPI_FILTER_OP_SHARPEN: Sharpening (float).
 * @GST_VAAPI_FILTER_OP_DEINTERLACE: Deinterlace (#GstVaapiDeinterlaceMethod).
 * @GST_VAAPI_FILTER_OP_HUE: Change color hue. Value: float.
 * @GST_VAAPI_FILTER_OP_SATURATION: Change saturation (float).
 * @GST_VAAPI_FILTER_OP_BRIGHTNESS: Change brightness (float).
 * @GST_VAAPI_FILTER_OP_CONTRAST: Change contrast (float).
 *
 * The set of operations that could be applied to the filter.
 */
typedef enum {
    GST_VAAPI_FILTER_OP_FORMAT = 1,
    GST_VAAPI_FILTER_OP_CROP,
    GST_VAAPI_FILTER_OP_DENOISE,
    GST_VAAPI_FILTER_OP_SHARPEN,
    GST_VAAPI_FILTER_OP_DEINTERLACE,
    GST_VAAPI_FILTER_OP_HUE,
    GST_VAAPI_FILTER_OP_SATURATION,
    GST_VAAPI_FILTER_OP_BRIGHTNESS,
    GST_VAAPI_FILTER_OP_CONTRAST,
} GstVaapiFilterOperation;

/**
 * GstVaapiFilterOperationInfo:
 * @operation: the #GstVaapiFilterOperation
 * @pspec: the #GParamSpec describing the associated configurable value
 *
 * A #GstVaapiFilterOperation descriptor.
 */
struct _GstVaapiFilterOperationInfo {
    GstVaapiFilterOperation operation;
    const GParamSpec *pspec;
};

/**
 * GstVaapiFilterStatus:
 * @GST_VAAPI_FILTER_STATUS_SUCCESS: Success.
 * @GST_VAAPI_FILTER_STATUS_UNSUPPORTED_FORMAT: Unsupported target format.
 *
 * Video processing status for gst_vaapi_filter_process().
 */
typedef enum {
    GST_VAAPI_FILTER_STATUS_SUCCESS = 0,
    GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_FORMAT,
} GstVaapiFilterStatus;

/**
 * gst_vaapi_filter_new:
 * @display: a #GstVaapiDisplay
 *
 * Creates a new #GstVaapiFilter set up to operate in "identity"
 * mode. This means that no other operation than scaling is performed.
 *
 * Return value: the newly created #GstVaapiFilter object
 */
GstVaapiFilter *
gst_vaapi_filter_new(GstVaapiDisplay *display);

/**
 * gst_vaapi_filter_ref:
 * @filter: a #GstVaapiFilter
 *
 * Atomically increases the reference count of the given @filter by one.
 *
 * Returns: The same @filter argument
 */
GstVaapiFilter *
gst_vaapi_filter_ref(GstVaapiFilter *filter);

/**
 * gst_vaapi_filter_unref:
 * @filter: a #GstVaapiFilter
 *
 * Atomically decreases the reference count of the @filter by one. If
 * the reference count reaches zero, the filter will be free'd.
 */
void
gst_vaapi_filter_unref(GstVaapiFilter *filter);

/**
 * gst_vaapi_filter_replace:
 * @old_filter_ptr: a pointer to a #GstVaapiFilter
 * @new_filter: a #GstVaapiFilter
 *
 * Atomically replaces the filter held in @old_filter_ptr with
 * @new_filter. This means that @old_filter_ptr shall reference a
 * valid filter. However, @new_filter can be NULL.
 */
void
gst_vaapi_filter_replace(GstVaapiFilter **old_filter_ptr,
    GstVaapiFilter *new_filter);

/**
 * gst_vaapi_filter_get_operations:
 * @filter: a #GstVaapiFilter
 *
 * Determines the set of supported operations for video processing.
 * The @filter owns the resulting array of #GstVaapiFilterOperationInfo
 * elements, so it shall not be destroyed. Use g_array_ref(), if needed
 *
 * Return value: the set of supported operations
 */
GArray *
gst_vaapi_filter_get_operations(GstVaapiFilter *filter);

/**
 * gst_vaapi_filter_set_operation:
 * @filter: a #GstVaapiFilter
 * @operation: a #GstVaapiFilterOperation
 * @value: the @operation settings
 *
 * Enable the specified @operation to be performed during video
 * processing, i.e. in gst_vaapi_filter_process(). The @value argument
 * specifies the operation settings. e.g. deinterlacing method for
 * deinterlacing, denoising level for noise reduction, etc.
 *
 * Return value: %TRUE if the specified operation may be supported,
 *   %FALSE otherwise
 */
gboolean
gst_vaapi_filter_set_operation(GstVaapiFilter *filter,
    GstVaapiFilterOperation operation, const GValue *value);

/**
 * gst_vaapi_filter_process:
 * @filter: a #GstVaapiFilter
 * @src_surface: the source @GstVaapiSurface
 * @dst_surface: the destination @GstVaapiSurface
 * @flags: #GstVaapiSurfaceRenderFlags that apply to @src_surface
 *
 * Applies the operations currently defined in the @filter to
 * @src_surface and return the output in @dst_surface. The order of
 * operations is determined in a way that suits best the underlying
 * hardware. i.e. the only guarantee held is the generated outcome,
 * not any specific order of operations.
 *
 * Return value: a #GstVaapiFilterStatus
 */
GstVaapiFilterStatus
gst_vaapi_filter_process(GstVaapiFilter *filter, GstVaapiSurface *src_surface,
    GstVaapiSurface *dst_surface, guint flags);

/**
 * gst_vaapi_filter_set_format:
 * @filter: a #GstVaapiFilter
 * @format: the target surface format
 *
 * Sets the desired pixel format of the resulting video processing
 * operations.
 *
 * If @format is #GST_VIDEO_FORMAT_UNKNOWN, the filter will assume iso
 * format conversion, i.e. no color conversion at all and the target
 * surface format shall match the source surface format.
 *
 * If @format is #GST_VIDEO_FORMAT_ENCODED, the filter will use the pixel
 * format of the target surface passed to gst_vaapi_filter_process().
 *
 * Return value: %TRUE if the color conversion to the specified @format
 *   may be supported, %FALSE otherwise.
 */
gboolean
gst_vaapi_filter_set_format(GstVaapiFilter *filter, GstVideoFormat format);

/**
 * gst_vaapi_filter_set_cropping_rectangle:
 * @filter: a #GstVaapiFilter
 * @rect: the cropping region
 *
 * Sets the source surface cropping rectangle to use during the video
 * processing. If @rect is %NULL, the whole source surface will be used.
 *
 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
 */
gboolean
gst_vaapi_filter_set_cropping_rectangle(GstVaapiFilter *filter,
    const GstVaapiRectangle *rect);

/**
 * gst_vaapi_filter_set_denoising_level:
 * @filter: a #GstVaapiFilter
 * @level: the denoising factor
 *
 * Enables noise reduction with the specified factor.
 *
 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
 */
gboolean
gst_vaapi_filter_set_denoising_level(GstVaapiFilter *filter, gfloat level);

/**
 * gst_vaapi_filter_set_sharpening_level:
 * @filter: a #GstVaapiFilter
 * @level: the sharpening factor
 *
 * Enables noise reduction with the specified factor.
 *
 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
 */
gboolean
gst_vaapi_filter_set_sharpening_level(GstVaapiFilter *filter, gfloat level);

/**
 * gst_vaapi_filter_set_deinterlacing_method:
 * @filter: a #GstVaapiFilter
 * @method: the #GstVaapiDeinterlaceMethod to use
 *
 * Sets the specified deinterlacing @method to perform during video
 * processing, i.e. gst_vaapi_filter_process(). This function actually
 * disables deinterlacing if @method is set to
 * %GST_VAAPI_DEINTERLACE_METHOD_NONE.
 *
 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
 */
gboolean
gst_vaapi_filter_set_deinterlacing_method(GstVaapiFilter *filter,
    GstVaapiDeinterlaceMethod method);

/**
 * 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.
 */
void
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 */
