From c9c910184562ca3166fd53e174c4082eea9ae395 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Fri, 3 Feb 2023 18:43:23 +0900 Subject: [PATCH] videoconvertscale: Support I420-to-SN12 converting - Additional change : Enable videoconvertscale. : Remove unused directory(videoconvert, videoscale) which are already removed from upstream. [Version] 1.22.0-8 [Issue Type] Update Change-Id: I6d8635c0717b81d70a6eaa39cedb827111cf0f5b Signed-off-by: Jeongmo Yang --- packaging/gstreamer.spec | 10 +- .../gst-libs/gst/video/video-converter.c | 2 +- subprojects/gst-plugins-base/gst/meson.build | 2 +- .../gst/videoconvert/gstvideoconvert.c | 972 --------------- .../gst/videoconvert/gstvideoconvert.h | 64 - .../gst-plugins-base/gst/videoconvert/meson.build | 21 - .../gst/videoconvertscale/gstvideoconvertscale.c | 102 ++ .../gst/videoconvertscale/meson.build | 2 +- subprojects/gst-plugins-base/gst/videoscale/README | 5 - .../gst/videoscale/gstvideoscale.c | 1250 -------------------- .../gst/videoscale/gstvideoscale.h | 93 -- .../gst-plugins-base/gst/videoscale/meson.build | 14 - subprojects/gst-plugins-base/meson_options.txt | 4 +- 13 files changed, 109 insertions(+), 2432 deletions(-) delete mode 100644 subprojects/gst-plugins-base/gst/videoconvert/gstvideoconvert.c delete mode 100644 subprojects/gst-plugins-base/gst/videoconvert/gstvideoconvert.h delete mode 100644 subprojects/gst-plugins-base/gst/videoconvert/meson.build delete mode 100644 subprojects/gst-plugins-base/gst/videoscale/README delete mode 100644 subprojects/gst-plugins-base/gst/videoscale/gstvideoscale.c delete mode 100644 subprojects/gst-plugins-base/gst/videoscale/gstvideoscale.h delete mode 100644 subprojects/gst-plugins-base/gst/videoscale/meson.build diff --git a/packaging/gstreamer.spec b/packaging/gstreamer.spec index 890ca77..a4ea0a9 100644 --- a/packaging/gstreamer.spec +++ b/packaging/gstreamer.spec @@ -62,7 +62,7 @@ Name: %{_name} Version: 1.22.0 -Release: 7 +Release: 8 Summary: Streaming-Media Framework Runtime License: LGPL-2.0+ Group: Multimedia/Framework @@ -593,9 +593,7 @@ meson --auto-features=disabled --prefix=/usr --libdir=%{_libdir} --datadir=%{_da -D %{_base_opt}tools=disabled \ -D %{_base_opt}theora=enabled \ -D %{_base_opt}typefind=enabled \ - -D %{_base_opt}videoconvertscale=disabled \ - -D %{_base_opt}videoconvert=enabled \ - -D %{_base_opt}videoscale=enabled \ + -D %{_base_opt}videoconvertscale=enabled \ -D %{_base_opt}videorate=enabled \ -D %{_base_opt}videotestsrc=enabled \ -D %{_base_opt}volume=enabled \ @@ -901,9 +899,7 @@ rm -rf $RPM_BUILD_ROOT %{_lib_gstreamer_dir}/libgsttcp.so %{_lib_gstreamer_dir}/libgsttheora.so %{_lib_gstreamer_dir}/libgsttypefindfunctions.so -#%{_lib_gstreamer_dir}/libgstvideoconvertscale.so -%{_lib_gstreamer_dir}/libgstvideoconvert.so -%{_lib_gstreamer_dir}/libgstvideoscale.so +%{_lib_gstreamer_dir}/libgstvideoconvertscale.so %{_lib_gstreamer_dir}/libgstvideorate.so %{_lib_gstreamer_dir}/libgstvideotestsrc.so %{_lib_gstreamer_dir}/libgstvolume.so diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/video-converter.c b/subprojects/gst-plugins-base/gst-libs/gst/video/video-converter.c index 052543d..8081003 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/video-converter.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/video-converter.c @@ -7262,7 +7262,7 @@ convert_I420_SN12 (GstVideoConverter * convert, const GstVideoFrame * src, dst_Y = GST_VIDEO_FRAME_PLANE_DATA (dst, 0); dst_UV = GST_VIDEO_FRAME_PLANE_DATA (dst, 1); - GST_DEBUG_OBJECT (convert, "size %dx%d, stride src[0:%d,1:%d], dst[0:%d,1:%d]", + GST_DEBUG ("size %dx%d, stride src[0:%d,1:%d], dst[0:%d,1:%d]", width, height, src_stride_Y, src_stride_U, dst_stride_Y, dst_stride_UV); for (i = 0 ; i < loop_count_Y ; i += 2) { diff --git a/subprojects/gst-plugins-base/gst/meson.build b/subprojects/gst-plugins-base/gst/meson.build index 91be2a0..2d14191 100644 --- a/subprojects/gst-plugins-base/gst/meson.build +++ b/subprojects/gst-plugins-base/gst/meson.build @@ -1,6 +1,6 @@ foreach plugin : ['adder', 'app', 'audioconvert', 'audiomixer', 'audiorate', 'audioresample', 'audiotestsrc', 'compositor', 'encoding', 'gio', 'overlaycomposition', 'pbtypes', 'playback', - 'rawparse', 'subparse', 'tcp', 'typefind', 'videoconvert', 'videorate', 'videoscale', + 'rawparse', 'subparse', 'tcp', 'typefind', 'videoconvertscale', 'videorate', 'videotestsrc', 'volume'] if not get_option(plugin).disabled() subdir(plugin) diff --git a/subprojects/gst-plugins-base/gst/videoconvert/gstvideoconvert.c b/subprojects/gst-plugins-base/gst/videoconvert/gstvideoconvert.c deleted file mode 100644 index 4eb8a4e..0000000 --- a/subprojects/gst-plugins-base/gst/videoconvert/gstvideoconvert.c +++ /dev/null @@ -1,972 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * This file: - * Copyright (C) 2003 Ronald Bultje - * Copyright (C) 2010 David Schleef - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/** - * SECTION:element-videoconvert - * @title: videoconvert - * - * Convert video frames between a great variety of video formats. - * - * ## Example launch line - * |[ - * gst-launch-1.0 -v videotestsrc ! video/x-raw,format=YUY2 ! videoconvert ! autovideosink - * ]| - * This will output a test video (generated in YUY2 format) in a video - * window. If the video sink selected does not support YUY2 videoconvert will - * automatically convert the video to a format understood by the video sink. - * - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "gstvideoconvert.h" - -#include -#include -#include - -#ifdef USE_TBM -#include -#endif - -#include - -GST_DEBUG_CATEGORY (videoconvert_debug); -#define GST_CAT_DEFAULT videoconvert_debug -GST_DEBUG_CATEGORY_STATIC (CAT_PERFORMANCE); - -static GQuark _colorspace_quark; - -#define gst_video_convert_parent_class parent_class -G_DEFINE_TYPE (GstVideoConvert, gst_video_convert, GST_TYPE_VIDEO_FILTER); -GST_ELEMENT_REGISTER_DEFINE (videoconvert, "videoconvert", - GST_RANK_NONE, GST_TYPE_VIDEO_CONVERT); - -#define DEFAULT_PROP_DITHER GST_VIDEO_DITHER_BAYER -#define DEFAULT_PROP_DITHER_QUANTIZATION 1 -#define DEFAULT_PROP_CHROMA_RESAMPLER GST_VIDEO_RESAMPLER_METHOD_LINEAR -#define DEFAULT_PROP_ALPHA_MODE GST_VIDEO_ALPHA_MODE_COPY -#define DEFAULT_PROP_ALPHA_VALUE 1.0 -#define DEFAULT_PROP_CHROMA_MODE GST_VIDEO_CHROMA_MODE_FULL -#define DEFAULT_PROP_MATRIX_MODE GST_VIDEO_MATRIX_MODE_FULL -#define DEFAULT_PROP_GAMMA_MODE GST_VIDEO_GAMMA_MODE_NONE -#define DEFAULT_PROP_PRIMARIES_MODE GST_VIDEO_PRIMARIES_MODE_NONE -#define DEFAULT_PROP_N_THREADS 1 - -enum -{ - PROP_0, - PROP_DITHER, - PROP_DITHER_QUANTIZATION, - PROP_CHROMA_RESAMPLER, - PROP_ALPHA_MODE, - PROP_ALPHA_VALUE, - PROP_CHROMA_MODE, - PROP_MATRIX_MODE, - PROP_GAMMA_MODE, - PROP_PRIMARIES_MODE, - PROP_N_THREADS -}; - -#define CSP_VIDEO_CAPS GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ";" \ - GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", GST_VIDEO_FORMATS_ALL) ";" \ - GST_VIDEO_CAPS_MAKE("{ SUYV , SYVY , S420 , ITLV }") ";" \ - GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", "{ SUYV , SYVY , S420 , ITLV }") - -#define CSP_VIDEO_SRC_CAPS GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ";" \ - GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", GST_VIDEO_FORMATS_ALL) ";" \ - GST_VIDEO_CAPS_MAKE("{ SUYV , SYVY , S420 , ITLV , SN12 }") ";" \ - GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", "{ SUYV , SYVY , S420 , ITLV , SN12 }") - -static GstStaticPadTemplate gst_video_convert_src_template = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (CSP_VIDEO_SRC_CAPS) - ); - -static GstStaticPadTemplate gst_video_convert_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (CSP_VIDEO_CAPS) - ); - -static void gst_video_convert_set_property (GObject * object, - guint property_id, const GValue * value, GParamSpec * pspec); -static void gst_video_convert_get_property (GObject * object, - guint property_id, GValue * value, GParamSpec * pspec); - -static gboolean gst_video_convert_set_info (GstVideoFilter * filter, - GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps, - GstVideoInfo * out_info); -static GstFlowReturn gst_video_convert_transform_frame (GstVideoFilter * filter, - GstVideoFrame * in_frame, GstVideoFrame * out_frame); - -#ifdef USE_TBM -static gboolean gst_video_convert_decide_allocation (GstBaseTransform * bsrc, - GstQuery * query); -static GstFlowReturn gst_video_convert_prepare_output_buffer (GstBaseTransform * trans, - GstBuffer *input, GstBuffer **outbuf); -#endif -static GstCapsFeatures *features_format_interlaced, - *features_format_interlaced_sysmem; - -/* copies the given caps */ -static GstCaps * -gst_video_convert_caps_remove_format_info (GstCaps * caps) -{ - GstStructure *st; - GstCapsFeatures *f; - gint i, n; - GstCaps *res; - - res = gst_caps_new_empty (); - - n = gst_caps_get_size (caps); - for (i = 0; i < n; i++) { - st = gst_caps_get_structure (caps, i); - f = gst_caps_get_features (caps, i); - - /* If this is already expressed by the existing caps - * skip this structure */ - if (i > 0 && gst_caps_is_subset_structure_full (res, st, f)) - continue; - - st = gst_structure_copy (st); - /* Only remove format info for the cases when we can actually convert */ - if (!gst_caps_features_is_any (f) - && (gst_caps_features_is_equal (f, - GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY) - || gst_caps_features_is_equal (f, features_format_interlaced) - || gst_caps_features_is_equal (f, - features_format_interlaced_sysmem))) { - gst_structure_remove_fields (st, "format", "colorimetry", "chroma-site", - NULL); - } - - gst_caps_append_structure_full (res, st, gst_caps_features_copy (f)); - } - - return res; -} - -/* - * This is an incomplete matrix of in formats and a score for the preferred output - * format. - * - * out: RGB24 RGB16 ARGB AYUV YUV444 YUV422 YUV420 YUV411 YUV410 PAL GRAY - * in - * RGB24 0 2 1 2 2 3 4 5 6 7 8 - * RGB16 1 0 1 2 2 3 4 5 6 7 8 - * ARGB 2 3 0 1 4 5 6 7 8 9 10 - * AYUV 3 4 1 0 2 5 6 7 8 9 10 - * YUV444 2 4 3 1 0 5 6 7 8 9 10 - * YUV422 3 5 4 2 1 0 6 7 8 9 10 - * YUV420 4 6 5 3 2 1 0 7 8 9 10 - * YUV411 4 6 5 3 2 1 7 0 8 9 10 - * YUV410 6 8 7 5 4 3 2 1 0 9 10 - * PAL 1 3 2 6 4 6 7 8 9 0 10 - * GRAY 1 4 3 2 1 5 6 7 8 9 0 - * - * PAL or GRAY are never preferred, if we can we would convert to PAL instead - * of GRAY, though - * less subsampling is preferred and if any, preferably horizontal - * We would like to keep the alpha, even if we would need to to colorspace conversion - * or lose depth. - */ -#define SCORE_FORMAT_CHANGE 1 -#define SCORE_DEPTH_CHANGE 1 -#define SCORE_ALPHA_CHANGE 1 -#define SCORE_CHROMA_W_CHANGE 1 -#define SCORE_CHROMA_H_CHANGE 1 -#define SCORE_PALETTE_CHANGE 1 - -#define SCORE_COLORSPACE_LOSS 2 /* RGB <-> YUV */ -#define SCORE_DEPTH_LOSS 4 /* change bit depth */ -#define SCORE_ALPHA_LOSS 8 /* lose the alpha channel */ -#define SCORE_CHROMA_W_LOSS 16 /* vertical subsample */ -#define SCORE_CHROMA_H_LOSS 32 /* horizontal subsample */ -#define SCORE_PALETTE_LOSS 64 /* convert to palette format */ -#define SCORE_COLOR_LOSS 128 /* convert to GRAY */ - -#define COLORSPACE_MASK (GST_VIDEO_FORMAT_FLAG_YUV | \ - GST_VIDEO_FORMAT_FLAG_RGB | GST_VIDEO_FORMAT_FLAG_GRAY) -#define ALPHA_MASK (GST_VIDEO_FORMAT_FLAG_ALPHA) -#define PALETTE_MASK (GST_VIDEO_FORMAT_FLAG_PALETTE) - -/* calculate how much loss a conversion would be */ -static void -score_value (GstBaseTransform * base, const GstVideoFormatInfo * in_info, - const GValue * val, gint * min_loss, const GstVideoFormatInfo ** out_info) -{ - const gchar *fname; - const GstVideoFormatInfo *t_info; - GstVideoFormatFlags in_flags, t_flags; - gint loss; - - fname = g_value_get_string (val); - t_info = gst_video_format_get_info (gst_video_format_from_string (fname)); - if (!t_info) - return; - - /* accept input format immediately without loss */ - if (in_info == t_info) { - *min_loss = 0; - *out_info = t_info; - return; - } - - loss = SCORE_FORMAT_CHANGE; - - in_flags = GST_VIDEO_FORMAT_INFO_FLAGS (in_info); - in_flags &= ~GST_VIDEO_FORMAT_FLAG_LE; - in_flags &= ~GST_VIDEO_FORMAT_FLAG_COMPLEX; - in_flags &= ~GST_VIDEO_FORMAT_FLAG_UNPACK; - - t_flags = GST_VIDEO_FORMAT_INFO_FLAGS (t_info); - t_flags &= ~GST_VIDEO_FORMAT_FLAG_LE; - t_flags &= ~GST_VIDEO_FORMAT_FLAG_COMPLEX; - t_flags &= ~GST_VIDEO_FORMAT_FLAG_UNPACK; - - if ((t_flags & PALETTE_MASK) != (in_flags & PALETTE_MASK)) { - loss += SCORE_PALETTE_CHANGE; - if (t_flags & PALETTE_MASK) - loss += SCORE_PALETTE_LOSS; - } - - if ((t_flags & COLORSPACE_MASK) != (in_flags & COLORSPACE_MASK)) { - loss += SCORE_COLORSPACE_LOSS; - if (t_flags & GST_VIDEO_FORMAT_FLAG_GRAY) - loss += SCORE_COLOR_LOSS; - } - - if ((t_flags & ALPHA_MASK) != (in_flags & ALPHA_MASK)) { - loss += SCORE_ALPHA_CHANGE; - if (in_flags & ALPHA_MASK) - loss += SCORE_ALPHA_LOSS; - } - - if ((in_info->h_sub[1]) != (t_info->h_sub[1])) { - loss += SCORE_CHROMA_H_CHANGE; - if ((in_info->h_sub[1]) < (t_info->h_sub[1])) - loss += SCORE_CHROMA_H_LOSS; - } - if ((in_info->w_sub[1]) != (t_info->w_sub[1])) { - loss += SCORE_CHROMA_W_CHANGE; - if ((in_info->w_sub[1]) < (t_info->w_sub[1])) - loss += SCORE_CHROMA_W_LOSS; - } - - if ((in_info->bits) != (t_info->bits)) { - loss += SCORE_DEPTH_CHANGE; - if ((in_info->bits) > (t_info->bits)) - loss += SCORE_DEPTH_LOSS; - } - - GST_DEBUG_OBJECT (base, "score %s -> %s = %d", - GST_VIDEO_FORMAT_INFO_NAME (in_info), - GST_VIDEO_FORMAT_INFO_NAME (t_info), loss); - - if (loss < *min_loss) { - GST_DEBUG_OBJECT (base, "found new best %d", loss); - *out_info = t_info; - *min_loss = loss; - } -} - -static void -gst_video_convert_fixate_format (GstBaseTransform * base, GstCaps * caps, - GstCaps * result) -{ - GstStructure *ins, *outs; - const gchar *in_format; - const GstVideoFormatInfo *in_info, *out_info = NULL; - gint min_loss = G_MAXINT; - guint i, capslen; - - ins = gst_caps_get_structure (caps, 0); - in_format = gst_structure_get_string (ins, "format"); - if (!in_format) - return; - - GST_DEBUG_OBJECT (base, "source format %s", in_format); - - in_info = - gst_video_format_get_info (gst_video_format_from_string (in_format)); - if (!in_info) - return; - - outs = gst_caps_get_structure (result, 0); - - capslen = gst_caps_get_size (result); - GST_DEBUG_OBJECT (base, "iterate %d structures", capslen); - for (i = 0; i < capslen; i++) { - GstStructure *tests; - const GValue *format; - - tests = gst_caps_get_structure (result, i); - format = gst_structure_get_value (tests, "format"); - /* should not happen */ - if (format == NULL) - continue; - - if (GST_VALUE_HOLDS_LIST (format)) { - gint j, len; - - len = gst_value_list_get_size (format); - GST_DEBUG_OBJECT (base, "have %d formats", len); - for (j = 0; j < len; j++) { - const GValue *val; - - val = gst_value_list_get_value (format, j); - if (G_VALUE_HOLDS_STRING (val)) { - score_value (base, in_info, val, &min_loss, &out_info); - if (min_loss == 0) - break; - } - } - } else if (G_VALUE_HOLDS_STRING (format)) { - score_value (base, in_info, format, &min_loss, &out_info); - } - } - if (out_info) - gst_structure_set (outs, "format", G_TYPE_STRING, - GST_VIDEO_FORMAT_INFO_NAME (out_info), NULL); -} - -static gboolean -subsampling_unchanged (GstVideoInfo * in_info, GstVideoInfo * out_info) -{ - gint i; - const GstVideoFormatInfo *in_format, *out_format; - - if (GST_VIDEO_INFO_N_COMPONENTS (in_info) != - GST_VIDEO_INFO_N_COMPONENTS (out_info)) - return FALSE; - - in_format = in_info->finfo; - out_format = out_info->finfo; - - for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (in_info); i++) { - if (GST_VIDEO_FORMAT_INFO_W_SUB (in_format, - i) != GST_VIDEO_FORMAT_INFO_W_SUB (out_format, i)) - return FALSE; - if (GST_VIDEO_FORMAT_INFO_H_SUB (in_format, - i) != GST_VIDEO_FORMAT_INFO_H_SUB (out_format, i)) - return FALSE; - } - - return TRUE; -} - -static void -transfer_colorimetry_from_input (GstBaseTransform * trans, GstCaps * in_caps, - GstCaps * out_caps) -{ - GstStructure *out_caps_s = gst_caps_get_structure (out_caps, 0); - GstStructure *in_caps_s = gst_caps_get_structure (in_caps, 0); - gboolean have_colorimetry = - gst_structure_has_field (out_caps_s, "colorimetry"); - gboolean have_chroma_site = - gst_structure_has_field (out_caps_s, "chroma-site"); - - /* If the output already has colorimetry and chroma-site, stop, - * otherwise try and transfer what we can from the input caps */ - if (have_colorimetry && have_chroma_site) - return; - - { - GstVideoInfo in_info, out_info; - const GValue *in_colorimetry = - gst_structure_get_value (in_caps_s, "colorimetry"); - - if (!gst_video_info_from_caps (&in_info, in_caps)) { - GST_WARNING_OBJECT (trans, - "Failed to convert sink pad caps to video info"); - return; - } - if (!gst_video_info_from_caps (&out_info, out_caps)) { - GST_WARNING_OBJECT (trans, - "Failed to convert src pad caps to video info"); - return; - } - - if (!have_colorimetry && in_colorimetry != NULL) { - if ((GST_VIDEO_INFO_IS_YUV (&out_info) - && GST_VIDEO_INFO_IS_YUV (&in_info)) - || (GST_VIDEO_INFO_IS_RGB (&out_info) - && GST_VIDEO_INFO_IS_RGB (&in_info)) - || (GST_VIDEO_INFO_IS_GRAY (&out_info) - && GST_VIDEO_INFO_IS_GRAY (&in_info))) { - /* Can transfer the colorimetry intact from the input if it has it */ - gst_structure_set_value (out_caps_s, "colorimetry", in_colorimetry); - } else { - gchar *colorimetry_str; - - /* Changing between YUV/RGB - forward primaries and transfer function, but use - * default range and matrix. - * the primaries is used for conversion between RGB and XYZ (CIE 1931 coordinate). - * the transfer function could be another reference (e.g., HDR) - */ - out_info.colorimetry.primaries = in_info.colorimetry.primaries; - out_info.colorimetry.transfer = in_info.colorimetry.transfer; - - colorimetry_str = - gst_video_colorimetry_to_string (&out_info.colorimetry); - gst_caps_set_simple (out_caps, "colorimetry", G_TYPE_STRING, - colorimetry_str, NULL); - g_free (colorimetry_str); - } - } - - /* Only YUV output needs chroma-site. If the input was also YUV and had the same chroma - * subsampling, transfer the siting. If the sub-sampling is changing, then the planes get - * scaled anyway so there's no real reason to prefer the input siting. */ - if (!have_chroma_site && GST_VIDEO_INFO_IS_YUV (&out_info)) { - if (GST_VIDEO_INFO_IS_YUV (&in_info)) { - const GValue *in_chroma_site = - gst_structure_get_value (in_caps_s, "chroma-site"); - if (in_chroma_site != NULL - && subsampling_unchanged (&in_info, &out_info)) - gst_structure_set_value (out_caps_s, "chroma-site", in_chroma_site); - } - } - } -} - -static GstCaps * -gst_video_convert_fixate_caps (GstBaseTransform * trans, - GstPadDirection direction, GstCaps * caps, GstCaps * othercaps) -{ - GstCaps *result; - - GST_DEBUG_OBJECT (trans, "trying to fixate othercaps %" GST_PTR_FORMAT - " based on caps %" GST_PTR_FORMAT, othercaps, caps); - - result = gst_caps_intersect (othercaps, caps); - if (gst_caps_is_empty (result)) { - gst_caps_unref (result); - result = othercaps; - } else { - gst_caps_unref (othercaps); - } - - GST_DEBUG_OBJECT (trans, "now fixating %" GST_PTR_FORMAT, result); - - result = gst_caps_make_writable (result); - gst_video_convert_fixate_format (trans, caps, result); - - /* fixate remaining fields */ - result = gst_caps_fixate (result); - - if (direction == GST_PAD_SINK) { - if (gst_caps_is_subset (caps, result)) { - gst_caps_replace (&result, caps); - } else { - /* Try and preserve input colorimetry / chroma information */ - transfer_colorimetry_from_input (trans, caps, result); - } - } - - return result; -} - -static gboolean -gst_video_convert_filter_meta (GstBaseTransform * trans, GstQuery * query, - GType api, const GstStructure * params) -{ - /* This element cannot passthrough the crop meta, because it would convert the - * wrong sub-region of the image, and worst, our output image may not be large - * enough for the crop to be applied later */ - if (api == GST_VIDEO_CROP_META_API_TYPE) - return FALSE; - - /* propose all other metadata upstream */ - return TRUE; -} - -/* The caps can be transformed into any other caps with format info removed. - * However, we should prefer passthrough, so if passthrough is possible, - * put it first in the list. */ -static GstCaps * -gst_video_convert_transform_caps (GstBaseTransform * btrans, - GstPadDirection direction, GstCaps * caps, GstCaps * filter) -{ - GstCaps *tmp, *tmp2; - GstCaps *result; - - /* Get all possible caps that we can transform to */ - tmp = gst_video_convert_caps_remove_format_info (caps); - - if (filter) { - tmp2 = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (tmp); - tmp = tmp2; - } - - result = tmp; - - GST_DEBUG_OBJECT (btrans, "transformed %" GST_PTR_FORMAT " into %" - GST_PTR_FORMAT, caps, result); - - return result; -} - -static gboolean -gst_video_convert_transform_meta (GstBaseTransform * trans, GstBuffer * outbuf, - GstMeta * meta, GstBuffer * inbuf) -{ - const GstMetaInfo *info = meta->info; - gboolean ret; - - if (gst_meta_api_type_has_tag (info->api, _colorspace_quark)) { - /* don't copy colorspace specific metadata, FIXME, we need a MetaTransform - * for the colorspace metadata. */ - ret = FALSE; - } else { - /* copy other metadata */ - ret = TRUE; - } - return ret; -} - -static gboolean -gst_video_convert_set_info (GstVideoFilter * filter, - GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps, - GstVideoInfo * out_info) -{ - GstVideoConvert *space; - GstBaseTransformClass *gstbasetransform_class = - GST_BASE_TRANSFORM_GET_CLASS (filter); - GstVideoInfo tmp_info; - - space = GST_VIDEO_CONVERT_CAST (filter); - - if (space->convert) { - gst_video_converter_free (space->convert); - space->convert = NULL; - } - - /* these must match */ - if (in_info->width != out_info->width || in_info->height != out_info->height - || in_info->fps_n != out_info->fps_n || in_info->fps_d != out_info->fps_d) - goto format_mismatch; - - /* if present, these must match too */ - if (in_info->par_n != out_info->par_n || in_info->par_d != out_info->par_d) - goto format_mismatch; - - /* if present, these must match too */ - if (in_info->interlace_mode != out_info->interlace_mode) - goto format_mismatch; - - /* if the only thing different in the caps is the transfer function, and - * we're converting between equivalent transfer functions, do passthrough */ - tmp_info = *in_info; - tmp_info.colorimetry.transfer = out_info->colorimetry.transfer; - if (gst_video_info_is_equal (&tmp_info, out_info)) { - if (gst_video_transfer_function_is_equivalent (in_info-> - colorimetry.transfer, in_info->finfo->bits, - out_info->colorimetry.transfer, out_info->finfo->bits)) { - gstbasetransform_class->passthrough_on_same_caps = FALSE; - gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), TRUE); - return TRUE; - } - } - gstbasetransform_class->passthrough_on_same_caps = TRUE; - gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), FALSE); - - space->convert = gst_video_converter_new (in_info, out_info, - gst_structure_new ("GstVideoConvertConfig", - GST_VIDEO_CONVERTER_OPT_DITHER_METHOD, GST_TYPE_VIDEO_DITHER_METHOD, - space->dither, - GST_VIDEO_CONVERTER_OPT_DITHER_QUANTIZATION, G_TYPE_UINT, - space->dither_quantization, - GST_VIDEO_CONVERTER_OPT_CHROMA_RESAMPLER_METHOD, - GST_TYPE_VIDEO_RESAMPLER_METHOD, space->chroma_resampler, - GST_VIDEO_CONVERTER_OPT_ALPHA_MODE, - GST_TYPE_VIDEO_ALPHA_MODE, space->alpha_mode, - GST_VIDEO_CONVERTER_OPT_ALPHA_VALUE, - G_TYPE_DOUBLE, space->alpha_value, - GST_VIDEO_CONVERTER_OPT_CHROMA_MODE, - GST_TYPE_VIDEO_CHROMA_MODE, space->chroma_mode, - GST_VIDEO_CONVERTER_OPT_MATRIX_MODE, - GST_TYPE_VIDEO_MATRIX_MODE, space->matrix_mode, - GST_VIDEO_CONVERTER_OPT_GAMMA_MODE, - GST_TYPE_VIDEO_GAMMA_MODE, space->gamma_mode, - GST_VIDEO_CONVERTER_OPT_PRIMARIES_MODE, - GST_TYPE_VIDEO_PRIMARIES_MODE, space->primaries_mode, - GST_VIDEO_CONVERTER_OPT_THREADS, G_TYPE_UINT, - space->n_threads, NULL)); - if (space->convert == NULL) - goto no_convert; - - GST_DEBUG_OBJECT (filter, "converting format %s -> %s", - gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (in_info)), - gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (out_info))); - - return TRUE; - - /* ERRORS */ -format_mismatch: - { - GST_ERROR_OBJECT (space, "input and output formats do not match"); - return FALSE; - } -no_convert: - { - GST_ERROR_OBJECT (space, "could not create converter"); - return FALSE; - } -} - -static void -gst_video_convert_finalize (GObject * obj) -{ - GstVideoConvert *space = GST_VIDEO_CONVERT (obj); - -#ifdef USE_TBM - if (space->pool) { - gst_buffer_pool_set_active (space->pool, FALSE); - gst_object_unref (space->pool); - space->pool = NULL; - } -#endif - - if (space->convert) { - gst_video_converter_free (space->convert); - } - - G_OBJECT_CLASS (parent_class)->finalize (obj); -} - -static void -gst_video_convert_class_init (GstVideoConvertClass * klass) -{ - GObjectClass *gobject_class = (GObjectClass *) klass; - GstElementClass *gstelement_class = (GstElementClass *) klass; - GstBaseTransformClass *gstbasetransform_class = - (GstBaseTransformClass *) klass; - GstVideoFilterClass *gstvideofilter_class = (GstVideoFilterClass *) klass; - - gobject_class->set_property = gst_video_convert_set_property; - gobject_class->get_property = gst_video_convert_get_property; - gobject_class->finalize = gst_video_convert_finalize; - - gst_element_class_add_static_pad_template (gstelement_class, - &gst_video_convert_src_template); - gst_element_class_add_static_pad_template (gstelement_class, - &gst_video_convert_sink_template); - - gst_element_class_set_static_metadata (gstelement_class, - "Colorspace converter", "Filter/Converter/Video", - "Converts video from one colorspace to another", - "GStreamer maintainers "); - - gstbasetransform_class->transform_caps = - GST_DEBUG_FUNCPTR (gst_video_convert_transform_caps); - gstbasetransform_class->fixate_caps = - GST_DEBUG_FUNCPTR (gst_video_convert_fixate_caps); - gstbasetransform_class->filter_meta = - GST_DEBUG_FUNCPTR (gst_video_convert_filter_meta); - gstbasetransform_class->transform_meta = - GST_DEBUG_FUNCPTR (gst_video_convert_transform_meta); - - gstbasetransform_class->passthrough_on_same_caps = TRUE; - - gstvideofilter_class->set_info = - GST_DEBUG_FUNCPTR (gst_video_convert_set_info); - gstvideofilter_class->transform_frame = - GST_DEBUG_FUNCPTR (gst_video_convert_transform_frame); - -#ifdef USE_TBM - gstbasetransform_class->decide_allocation = gst_video_convert_decide_allocation; - gstbasetransform_class->prepare_output_buffer = gst_video_convert_prepare_output_buffer; -#endif - - g_object_class_install_property (gobject_class, PROP_DITHER, - g_param_spec_enum ("dither", "Dither", "Apply dithering while converting", - gst_video_dither_method_get_type (), DEFAULT_PROP_DITHER, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_DITHER_QUANTIZATION, - g_param_spec_uint ("dither-quantization", "Dither Quantize", - "Quantizer to use", 0, G_MAXUINT, DEFAULT_PROP_DITHER_QUANTIZATION, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_CHROMA_RESAMPLER, - g_param_spec_enum ("chroma-resampler", "Chroma resampler", - "Chroma resampler method", gst_video_resampler_method_get_type (), - DEFAULT_PROP_CHROMA_RESAMPLER, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_ALPHA_MODE, - g_param_spec_enum ("alpha-mode", "Alpha Mode", - "Alpha Mode to use", gst_video_alpha_mode_get_type (), - DEFAULT_PROP_ALPHA_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_ALPHA_VALUE, - g_param_spec_double ("alpha-value", "Alpha Value", - "Alpha Value to use", 0.0, 1.0, - DEFAULT_PROP_ALPHA_VALUE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_CHROMA_MODE, - g_param_spec_enum ("chroma-mode", "Chroma Mode", "Chroma Resampling Mode", - gst_video_chroma_mode_get_type (), DEFAULT_PROP_CHROMA_MODE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_MATRIX_MODE, - g_param_spec_enum ("matrix-mode", "Matrix Mode", "Matrix Conversion Mode", - gst_video_matrix_mode_get_type (), DEFAULT_PROP_MATRIX_MODE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_GAMMA_MODE, - g_param_spec_enum ("gamma-mode", "Gamma Mode", "Gamma Conversion Mode", - gst_video_gamma_mode_get_type (), DEFAULT_PROP_GAMMA_MODE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_PRIMARIES_MODE, - g_param_spec_enum ("primaries-mode", "Primaries Mode", - "Primaries Conversion Mode", gst_video_primaries_mode_get_type (), - DEFAULT_PROP_PRIMARIES_MODE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_N_THREADS, - g_param_spec_uint ("n-threads", "Threads", - "Maximum number of threads to use", 0, G_MAXUINT, - DEFAULT_PROP_N_THREADS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); -} - -static void -gst_video_convert_init (GstVideoConvert * space) -{ -#ifdef USE_TBM - space->pool = NULL; -#endif - space->dither = DEFAULT_PROP_DITHER; - space->dither_quantization = DEFAULT_PROP_DITHER_QUANTIZATION; - space->chroma_resampler = DEFAULT_PROP_CHROMA_RESAMPLER; - space->alpha_mode = DEFAULT_PROP_ALPHA_MODE; - space->alpha_value = DEFAULT_PROP_ALPHA_VALUE; - space->chroma_mode = DEFAULT_PROP_CHROMA_MODE; - space->matrix_mode = DEFAULT_PROP_MATRIX_MODE; - space->gamma_mode = DEFAULT_PROP_GAMMA_MODE; - space->primaries_mode = DEFAULT_PROP_PRIMARIES_MODE; - space->n_threads = DEFAULT_PROP_N_THREADS; -} - -void -gst_video_convert_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - GstVideoConvert *csp; - - csp = GST_VIDEO_CONVERT (object); - - switch (property_id) { - case PROP_DITHER: - csp->dither = g_value_get_enum (value); - break; - case PROP_CHROMA_RESAMPLER: - csp->chroma_resampler = g_value_get_enum (value); - break; - case PROP_ALPHA_MODE: - csp->alpha_mode = g_value_get_enum (value); - break; - case PROP_ALPHA_VALUE: - csp->alpha_value = g_value_get_double (value); - break; - case PROP_CHROMA_MODE: - csp->chroma_mode = g_value_get_enum (value); - break; - case PROP_MATRIX_MODE: - csp->matrix_mode = g_value_get_enum (value); - break; - case PROP_GAMMA_MODE: - csp->gamma_mode = g_value_get_enum (value); - break; - case PROP_PRIMARIES_MODE: - csp->primaries_mode = g_value_get_enum (value); - break; - case PROP_DITHER_QUANTIZATION: - csp->dither_quantization = g_value_get_uint (value); - break; - case PROP_N_THREADS: - csp->n_threads = g_value_get_uint (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -void -gst_video_convert_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - GstVideoConvert *csp; - - csp = GST_VIDEO_CONVERT (object); - - switch (property_id) { - case PROP_DITHER: - g_value_set_enum (value, csp->dither); - break; - case PROP_CHROMA_RESAMPLER: - g_value_set_enum (value, csp->chroma_resampler); - break; - case PROP_ALPHA_MODE: - g_value_set_enum (value, csp->alpha_mode); - break; - case PROP_ALPHA_VALUE: - g_value_set_double (value, csp->alpha_value); - break; - case PROP_CHROMA_MODE: - g_value_set_enum (value, csp->chroma_mode); - break; - case PROP_MATRIX_MODE: - g_value_set_enum (value, csp->matrix_mode); - break; - case PROP_GAMMA_MODE: - g_value_set_enum (value, csp->gamma_mode); - break; - case PROP_PRIMARIES_MODE: - g_value_set_enum (value, csp->primaries_mode); - break; - case PROP_DITHER_QUANTIZATION: - g_value_set_uint (value, csp->dither_quantization); - break; - case PROP_N_THREADS: - g_value_set_uint (value, csp->n_threads); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static GstFlowReturn -gst_video_convert_transform_frame (GstVideoFilter * filter, - GstVideoFrame * in_frame, GstVideoFrame * out_frame) -{ - GstVideoConvert *space; - - space = GST_VIDEO_CONVERT_CAST (filter); - - GST_CAT_DEBUG_OBJECT (CAT_PERFORMANCE, filter, - "doing colorspace conversion from %s -> to %s", - GST_VIDEO_INFO_NAME (&filter->in_info), - GST_VIDEO_INFO_NAME (&filter->out_info)); - - gst_video_converter_frame (space->convert, in_frame, out_frame); - - return GST_FLOW_OK; -} - -#ifdef USE_TBM -static gboolean -gst_video_convert_decide_allocation (GstBaseTransform * trans, - GstQuery * query) -{ - GstVideoConvert *vc = NULL; - GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans); - vc = GST_VIDEO_CONVERT_CAST(trans); - - if (filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12 ) { - guint size; - GstStructure *config; - GstCaps *caps = NULL; - GstVideoInfo vinfo; - gst_query_parse_allocation (query, &caps, NULL); - gst_video_info_init (&vinfo); - gst_video_info_from_caps (&vinfo, caps); - - size = vinfo.size; - - if (caps) { - vc->pool = gst_tizen_buffer_pool_new (); - config = gst_buffer_pool_get_config (vc->pool); - - gst_buffer_pool_config_set_params (config, caps, size, 4, 10); - gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); - gst_buffer_pool_set_config (vc->pool, config); - - if (!gst_buffer_pool_set_active (vc->pool, TRUE)) { - gst_object_unref (vc->pool); - vc->pool = NULL; - GST_INFO ("Failed to activate internal pool"); - } - } else { - GST_ERROR("Not using our internal pool and copying buffers for downstream"); - return FALSE; - } - } - GST_DEBUG("[%s]Creating Tizen Buffer Pool", __FUNCTION__); - - return GST_BASE_TRANSFORM_CLASS (parent_class)->decide_allocation (trans, query); -} - -static GstFlowReturn -gst_video_convert_prepare_output_buffer (GstBaseTransform * trans, - GstBuffer *input, GstBuffer **outbuf) -{ - GstBuffer *buf = NULL; - GstVideoConvert *vc = NULL; - GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans); - - vc = GST_VIDEO_CONVERT_CAST (trans); - - if (filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12 ) { - if (gst_buffer_pool_acquire_buffer (vc->pool, &buf, 0) != GST_FLOW_OK) { - GST_ERROR("[%s] memory prepare failed.",__FUNCTION__); - return GST_FLOW_ERROR; - } - - if (input != buf) - GST_BASE_TRANSFORM_CLASS (parent_class)->copy_metadata (trans, input, buf); - *outbuf = buf; - - return GST_FLOW_OK; - } - return GST_BASE_TRANSFORM_CLASS (parent_class)->prepare_output_buffer(trans, input, outbuf); -} -#endif - -static gboolean -plugin_init (GstPlugin * plugin) -{ - GST_DEBUG_CATEGORY_INIT (videoconvert_debug, "videoconvert", 0, - "Colorspace Converter"); - - GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE"); - - _colorspace_quark = g_quark_from_static_string ("colorspace"); - - features_format_interlaced = - gst_caps_features_new (GST_CAPS_FEATURE_FORMAT_INTERLACED, NULL); - features_format_interlaced_sysmem = - gst_caps_features_copy (features_format_interlaced); - gst_caps_features_add (features_format_interlaced_sysmem, - GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY); - - return GST_ELEMENT_REGISTER (videoconvert, plugin); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - videoconvert, "Colorspace conversion", plugin_init, VERSION, GST_LICENSE, - GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/subprojects/gst-plugins-base/gst/videoconvert/gstvideoconvert.h b/subprojects/gst-plugins-base/gst/videoconvert/gstvideoconvert.h deleted file mode 100644 index a7f9343..0000000 --- a/subprojects/gst-plugins-base/gst/videoconvert/gstvideoconvert.h +++ /dev/null @@ -1,64 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * This file: - * Copyright (C) 2003 Ronald Bultje - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __GST_VIDEOCONVERT_H__ -#define __GST_VIDEOCONVERT_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_VIDEO_CONVERT (gst_video_convert_get_type()) -#define GST_VIDEO_CONVERT_CAST(obj) ((GstVideoConvert *)(obj)) -G_DECLARE_FINAL_TYPE (GstVideoConvert, gst_video_convert, GST, VIDEO_CONVERT, - GstVideoFilter) - -/** - * GstVideoConvert: - * - * Opaque object data structure. - */ -struct _GstVideoConvert { - GstVideoFilter element; - - GstVideoConverter *convert; - GstVideoDitherMethod dither; - guint dither_quantization; - GstVideoResamplerMethod chroma_resampler; - GstVideoAlphaMode alpha_mode; - GstVideoChromaMode chroma_mode; - GstVideoMatrixMode matrix_mode; - GstVideoGammaMode gamma_mode; - GstVideoPrimariesMode primaries_mode; - gdouble alpha_value; - gint n_threads; -#ifdef USE_TBM - GstBufferPool *pool; -#endif -}; - -GST_ELEMENT_REGISTER_DECLARE (videoconvert); - -G_END_DECLS - -#endif /* __GST_VIDEOCONVERT_H__ */ diff --git a/subprojects/gst-plugins-base/gst/videoconvert/meson.build b/subprojects/gst-plugins-base/gst/videoconvert/meson.build deleted file mode 100644 index f8c04d7..0000000 --- a/subprojects/gst-plugins-base/gst/videoconvert/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -vconvert_extra_defs = [] - -vconvert_sources = [ - 'gstvideoconvert.c', -] - -if tbm_dep.found() - vconvert_extra_defs += ['-DUSE_TBM'] -endif - -gstvideoconvert = library('gstvideoconvert', - vconvert_sources, - c_args : gst_plugins_base_args, - include_directories: [configinc, libsinc], - dependencies : [video_dep, allocators_dep], - install : true, - install_dir : plugins_install_dir, -) -pkgconfig.generate(gstvideoconvert, install_dir : plugins_pkgconfig_install_dir, - extra_cflags : vconvert_extra_defs) -plugins += [gstvideoconvert] diff --git a/subprojects/gst-plugins-base/gst/videoconvertscale/gstvideoconvertscale.c b/subprojects/gst-plugins-base/gst/videoconvertscale/gstvideoconvertscale.c index d921b7f..4613371 100644 --- a/subprojects/gst-plugins-base/gst/videoconvertscale/gstvideoconvertscale.c +++ b/subprojects/gst-plugins-base/gst/videoconvertscale/gstvideoconvertscale.c @@ -80,6 +80,9 @@ #include #include +#ifdef USE_TBM +#include +#endif #include "gstvideoconvertscale.h" @@ -107,6 +110,9 @@ typedef struct gint borders_h; gint borders_w; +#ifdef USE_TBM + GstBufferPool *pool; +#endif } GstVideoConvertScalePrivate; #define gst_video_convert_scale_parent_class parent_class @@ -136,6 +142,10 @@ GST_DEBUG_CATEGORY_STATIC (CAT_PERFORMANCE); #define DEFAULT_PROP_GAMMA_MODE GST_VIDEO_GAMMA_MODE_NONE #define DEFAULT_PROP_PRIMARIES_MODE GST_VIDEO_PRIMARIES_MODE_NONE #define DEFAULT_PROP_N_THREADS 1 +#ifdef USE_TBM +#define TIZEN_BUFFER_POOL_MIN_BUFFERS 4 +#define TIZEN_BUFFER_POOL_MAX_BUFFERS 10 +#endif static GQuark _colorspace_quark; @@ -254,6 +264,12 @@ static gboolean gst_video_convert_scale_set_info (GstVideoFilter * filter, GstVideoInfo * out_info); static GstFlowReturn gst_video_convert_scale_transform_frame (GstVideoFilter * filter, GstVideoFrame * in, GstVideoFrame * out); +#ifdef USE_TBM +static gboolean gst_video_convert_scale_decide_allocation (GstBaseTransform * trans, + GstQuery * query); +static GstFlowReturn gst_video_convert_scale_prepare_output_buffer (GstBaseTransform * trans, + GstBuffer *input, GstBuffer **outbuf); +#endif static void gst_video_convert_scale_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); @@ -400,6 +416,10 @@ gst_video_convert_scale_class_init (GstVideoConvertScaleClass * klass) GST_DEBUG_FUNCPTR (gst_video_convert_scale_src_event); trans_class->transform_meta = GST_DEBUG_FUNCPTR (gst_video_convert_scale_transform_meta); +#ifdef USE_TBM + trans_class->decide_allocation = gst_video_convert_scale_decide_allocation; + trans_class->prepare_output_buffer = gst_video_convert_scale_prepare_output_buffer; +#endif filter_class->set_info = GST_DEBUG_FUNCPTR (gst_video_convert_scale_set_info); filter_class->transform_frame = @@ -415,6 +435,9 @@ gst_video_convert_scale_init (GstVideoConvertScale * self) { GstVideoConvertScalePrivate *priv = PRIV (self); +#ifdef USE_TBM + priv->pool = NULL; +#endif priv->method = DEFAULT_PROP_METHOD; priv->add_borders = DEFAULT_PROP_ADD_BORDERS; priv->sharpness = DEFAULT_PROP_SHARPNESS; @@ -440,6 +463,13 @@ gst_video_convert_scale_finalize (GstVideoConvertScale * self) if (priv->convert) gst_video_converter_free (priv->convert); +#ifdef USE_TBM + if (priv->pool) { + gst_buffer_pool_set_active (priv->pool, FALSE); + gst_object_unref (priv->pool); + priv->pool = NULL; + } +#endif G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (self)); } @@ -1799,3 +1829,75 @@ gst_video_convert_scale_src_event (GstBaseTransform * trans, GstEvent * event) return ret; } + +#ifdef USE_TBM +static gboolean +gst_video_convert_scale_decide_allocation (GstBaseTransform * trans, + GstQuery * query) +{ + GstVideoConvertScalePrivate *priv = PRIV (trans); + GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans); + + if (filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12 ) { + guint size; + GstStructure *config; + GstCaps *caps = NULL; + GstVideoInfo vinfo; + + gst_query_parse_allocation (query, &caps, NULL); + if (!caps) { + GST_WARNING_OBJECT (trans, "caps failed"); + return FALSE; + } + + gst_video_info_init (&vinfo); + gst_video_info_from_caps (&vinfo, caps); + + size = vinfo.size; + + priv->pool = gst_tizen_buffer_pool_new (); + config = gst_buffer_pool_get_config (priv->pool); + + gst_buffer_pool_config_set_params (config, caps, size, + TIZEN_BUFFER_POOL_MIN_BUFFERS, TIZEN_BUFFER_POOL_MAX_BUFFERS); + gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); + gst_buffer_pool_set_config (priv->pool, config); + + if (!gst_buffer_pool_set_active (priv->pool, TRUE)) { + gst_object_unref (priv->pool); + priv->pool = NULL; + GST_WARNING_OBJECT (trans, "Failed to activate pool"); + return FALSE; + } + + GST_INFO_OBJECT (trans, "Tizen buffer pool will be used for SN12"); + } + + return GST_BASE_TRANSFORM_CLASS (parent_class)->decide_allocation (trans, query); +} + +static GstFlowReturn +gst_video_convert_scale_prepare_output_buffer (GstBaseTransform * trans, + GstBuffer *input, GstBuffer **outbuf) +{ + GstVideoConvertScalePrivate *priv = PRIV (trans); + GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans); + GstBuffer *buf = NULL; + + if (filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12 ) { + if (gst_buffer_pool_acquire_buffer (priv->pool, &buf, 0) != GST_FLOW_OK) { + GST_ERROR_OBJECT (trans, "Buffer acquire failed"); + return GST_FLOW_ERROR; + } + + if (input != buf) + GST_BASE_TRANSFORM_CLASS (parent_class)->copy_metadata (trans, input, buf); + + *outbuf = buf; + + return GST_FLOW_OK; + } + + return GST_BASE_TRANSFORM_CLASS (parent_class)->prepare_output_buffer (trans, input, outbuf); +} +#endif diff --git a/subprojects/gst-plugins-base/gst/videoconvertscale/meson.build b/subprojects/gst-plugins-base/gst/videoconvertscale/meson.build index 88adb87..38e0dad 100644 --- a/subprojects/gst-plugins-base/gst/videoconvertscale/meson.build +++ b/subprojects/gst-plugins-base/gst/videoconvertscale/meson.build @@ -9,7 +9,7 @@ gstvideoconvertscale = library('gstvideoconvertscale', videoconvertscale_sources, c_args : gst_plugins_base_args, include_directories: [configinc, libsinc], - dependencies : [video_dep, gst_dep, gst_base_dep], + dependencies : [video_dep, gst_dep, gst_base_dep, allocators_dep], install : true, install_dir : plugins_install_dir, ) diff --git a/subprojects/gst-plugins-base/gst/videoscale/README b/subprojects/gst-plugins-base/gst/videoscale/README deleted file mode 100644 index 50f1fe2..0000000 --- a/subprojects/gst-plugins-base/gst/videoscale/README +++ /dev/null @@ -1,5 +0,0 @@ -- test different strides using -gst-launch -v videotestsrc ! video/x-raw,width=320,height=240,format=UYVY ! videoscale ! video/x-raw,width=328,height=240 ! xvimagesink -gst-launch -v videotestsrc ! video/x-raw,width=320,height=240,format=UYVY ! videoscale ! video/x-raw,width=324,height=240 ! xvimagesink -gst-launch -v videotestsrc ! video/x-raw,width=320,height=240,format=UYVY ! videoscale ! video/x-raw,width=322,height=240 ! xvimagesink -gst-launch -v videotestsrc ! video/x-raw,width=320,height=240,format=UYVY ! videoscale ! video/x-raw,width=321,height=240 ! xvimagesink diff --git a/subprojects/gst-plugins-base/gst/videoscale/gstvideoscale.c b/subprojects/gst-plugins-base/gst/videoscale/gstvideoscale.c deleted file mode 100644 index 0c43638..0000000 --- a/subprojects/gst-plugins-base/gst/videoscale/gstvideoscale.c +++ /dev/null @@ -1,1250 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * Copyright (C) 2005-2012 David Schleef - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/** - * SECTION:element-videoscale - * @title: videoscale - * @see_also: videorate, videoconvert - * - * This element resizes video frames. By default the element will try to - * negotiate to the same size on the source and sinkpad so that no scaling - * is needed. It is therefore safe to insert this element in a pipeline to - * get more robust behaviour without any cost if no scaling is needed. - * - * This element supports a wide range of color spaces including various YUV and - * RGB formats and is therefore generally able to operate anywhere in a - * pipeline. - * - * ## Example pipelines - * |[ - * gst-launch-1.0 -v filesrc location=videotestsrc.ogg ! oggdemux ! theoradec ! videoconvert ! videoscale ! autovideosink - * ]| - * Decode an Ogg/Theora and display the video. If the video sink chosen - * cannot perform scaling, the video scaling will be performed by videoscale - * when you resize the video window. - * To create the test Ogg/Theora file refer to the documentation of theoraenc. - * |[ - * gst-launch-1.0 -v filesrc location=videotestsrc.ogg ! oggdemux ! theoradec ! videoconvert ! videoscale ! video/x-raw,width=100 ! autovideosink - * ]| - * Decode an Ogg/Theora and display the video with a width of 100. - * - */ - -/* - * Formulas for PAR, DAR, width and height relations: - * - * dar_n w par_n - * ----- = - * ----- - * dar_d h par_d - * - * par_n h dar_n - * ----- = - * ----- - * par_d w dar_d - * - * dar_n par_d - * w = h * ----- * ----- - * dar_d par_n - * - * dar_d par_n - * h = w * ----- * ----- - * dar_n par_d - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include - -#include -#include - -#include "gstvideoscale.h" - -#define GST_CAT_DEFAULT video_scale_debug -GST_DEBUG_CATEGORY_STATIC (video_scale_debug); -GST_DEBUG_CATEGORY_STATIC (CAT_PERFORMANCE); - -#define DEFAULT_PROP_METHOD GST_VIDEO_SCALE_BILINEAR -#define DEFAULT_PROP_ADD_BORDERS TRUE -#define DEFAULT_PROP_SHARPNESS 1.0 -#define DEFAULT_PROP_SHARPEN 0.0 -#define DEFAULT_PROP_DITHER FALSE -#define DEFAULT_PROP_SUBMETHOD 1 -#define DEFAULT_PROP_ENVELOPE 2.0 -#define DEFAULT_PROP_GAMMA_DECODE FALSE -#define DEFAULT_PROP_N_THREADS 1 - -enum -{ - PROP_0, - PROP_METHOD, - PROP_ADD_BORDERS, - PROP_SHARPNESS, - PROP_SHARPEN, - PROP_DITHER, - PROP_SUBMETHOD, - PROP_ENVELOPE, - PROP_GAMMA_DECODE, - PROP_N_THREADS -}; - -#undef GST_VIDEO_SIZE_RANGE -#define GST_VIDEO_SIZE_RANGE "(int) [ 1, 32767]" - -/* FIXME: add v210 support - * FIXME: add v216 support - * FIXME: add UYVP support - * FIXME: add A420 support - * FIXME: add YUV9 support - * FIXME: add YVU9 support - * FIXME: add IYU1 support - * FIXME: add r210 support - */ - -#define GST_VIDEO_FORMATS GST_VIDEO_FORMATS_ALL - -static GstStaticCaps gst_video_scale_format_caps = - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS) ";" - GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", GST_VIDEO_FORMATS)); - -static GQuark _size_quark; -static GQuark _scale_quark; - -#define GST_TYPE_VIDEO_SCALE_METHOD (gst_video_scale_method_get_type()) -static GType -gst_video_scale_method_get_type (void) -{ - static GType video_scale_method_type = 0; - - static const GEnumValue video_scale_methods[] = { - {GST_VIDEO_SCALE_NEAREST, "Nearest Neighbour", "nearest-neighbour"}, - {GST_VIDEO_SCALE_BILINEAR, "Bilinear (2-tap)", "bilinear"}, - {GST_VIDEO_SCALE_4TAP, "4-tap Sinc", "4-tap"}, - {GST_VIDEO_SCALE_LANCZOS, "Lanczos", "lanczos"}, - {GST_VIDEO_SCALE_BILINEAR2, "Bilinear (multi-tap)", "bilinear2"}, - {GST_VIDEO_SCALE_SINC, "Sinc (multi-tap)", "sinc"}, - {GST_VIDEO_SCALE_HERMITE, "Hermite (multi-tap)", "hermite"}, - {GST_VIDEO_SCALE_SPLINE, "Spline (multi-tap)", "spline"}, - {GST_VIDEO_SCALE_CATROM, "Catmull-Rom (multi-tap)", "catrom"}, - {GST_VIDEO_SCALE_MITCHELL, "Mitchell (multi-tap)", "mitchell"}, - {0, NULL, NULL}, - }; - - if (!video_scale_method_type) { - video_scale_method_type = - g_enum_register_static ("GstVideoScaleMethod", video_scale_methods); - } - return video_scale_method_type; -} - -static GstCaps * -gst_video_scale_get_capslist (void) -{ - static GstCaps *caps = NULL; - static gsize inited = 0; - - if (g_once_init_enter (&inited)) { - caps = gst_static_caps_get (&gst_video_scale_format_caps); - g_once_init_leave (&inited, 1); - } - return caps; -} - -static GstPadTemplate * -gst_video_scale_src_template_factory (void) -{ - return gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - gst_video_scale_get_capslist ()); -} - -static GstPadTemplate * -gst_video_scale_sink_template_factory (void) -{ - return gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - gst_video_scale_get_capslist ()); -} - - -static void gst_video_scale_finalize (GstVideoScale * videoscale); -static gboolean gst_video_scale_src_event (GstBaseTransform * trans, - GstEvent * event); - -/* base transform vmethods */ -static GstCaps *gst_video_scale_transform_caps (GstBaseTransform * trans, - GstPadDirection direction, GstCaps * caps, GstCaps * filter); -static GstCaps *gst_video_scale_fixate_caps (GstBaseTransform * base, - GstPadDirection direction, GstCaps * caps, GstCaps * othercaps); -static gboolean gst_video_scale_transform_meta (GstBaseTransform * trans, - GstBuffer * outbuf, GstMeta * meta, GstBuffer * inbuf); - -static gboolean gst_video_scale_set_info (GstVideoFilter * filter, - GstCaps * in, GstVideoInfo * in_info, GstCaps * out, - GstVideoInfo * out_info); -static GstFlowReturn gst_video_scale_transform_frame (GstVideoFilter * filter, - GstVideoFrame * in, GstVideoFrame * out); - -static void gst_video_scale_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_video_scale_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -#define gst_video_scale_parent_class parent_class -G_DEFINE_TYPE (GstVideoScale, gst_video_scale, GST_TYPE_VIDEO_FILTER); -GST_ELEMENT_REGISTER_DEFINE (videoscale, "videoscale", - GST_RANK_NONE, GST_TYPE_VIDEO_SCALE); - -static GstCapsFeatures *features_format_interlaced, - *features_format_interlaced_sysmem; - -static void -gst_video_scale_class_init (GstVideoScaleClass * klass) -{ - GObjectClass *gobject_class = (GObjectClass *) klass; - GstElementClass *element_class = (GstElementClass *) klass; - GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass; - GstVideoFilterClass *filter_class = (GstVideoFilterClass *) klass; - - gobject_class->finalize = (GObjectFinalizeFunc) gst_video_scale_finalize; - gobject_class->set_property = gst_video_scale_set_property; - gobject_class->get_property = gst_video_scale_get_property; - - g_object_class_install_property (gobject_class, PROP_METHOD, - g_param_spec_enum ("method", "method", "method", - GST_TYPE_VIDEO_SCALE_METHOD, DEFAULT_PROP_METHOD, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_ADD_BORDERS, - g_param_spec_boolean ("add-borders", "Add Borders", - "Add black borders if necessary to keep the display aspect ratio", - DEFAULT_PROP_ADD_BORDERS, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_SHARPNESS, - g_param_spec_double ("sharpness", "Sharpness", - "Sharpness of filter", 0.5, 1.5, DEFAULT_PROP_SHARPNESS, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_SHARPEN, - g_param_spec_double ("sharpen", "Sharpen", - "Sharpening", 0.0, 1.0, DEFAULT_PROP_SHARPEN, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_DITHER, - g_param_spec_boolean ("dither", "Dither", - "Add dither (only used for Lanczos method)", - DEFAULT_PROP_DITHER, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - -#if 0 - /* I am hiding submethod for now, since it's poorly named, poorly - * documented, and will probably just get people into trouble. */ - g_object_class_install_property (gobject_class, PROP_SUBMETHOD, - g_param_spec_int ("submethod", "submethod", - "submethod", 0, 3, DEFAULT_PROP_SUBMETHOD, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); -#endif - - g_object_class_install_property (gobject_class, PROP_ENVELOPE, - g_param_spec_double ("envelope", "Envelope", - "Size of filter envelope", 1.0, 5.0, DEFAULT_PROP_ENVELOPE, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_GAMMA_DECODE, - g_param_spec_boolean ("gamma-decode", "Gamma Decode", - "Decode gamma before scaling", DEFAULT_PROP_GAMMA_DECODE, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_N_THREADS, - g_param_spec_uint ("n-threads", "Threads", - "Maximum number of threads to use", 0, G_MAXUINT, - DEFAULT_PROP_N_THREADS, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - gst_element_class_set_static_metadata (element_class, - "Video scaler", "Filter/Converter/Video/Scaler", - "Resizes video", "Wim Taymans "); - - gst_element_class_add_pad_template (element_class, - gst_video_scale_sink_template_factory ()); - gst_element_class_add_pad_template (element_class, - gst_video_scale_src_template_factory ()); - - trans_class->transform_caps = - GST_DEBUG_FUNCPTR (gst_video_scale_transform_caps); - trans_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_video_scale_fixate_caps); - trans_class->src_event = GST_DEBUG_FUNCPTR (gst_video_scale_src_event); - trans_class->transform_meta = - GST_DEBUG_FUNCPTR (gst_video_scale_transform_meta); - - filter_class->set_info = GST_DEBUG_FUNCPTR (gst_video_scale_set_info); - filter_class->transform_frame = - GST_DEBUG_FUNCPTR (gst_video_scale_transform_frame); - - _size_quark = g_quark_from_static_string (GST_META_TAG_VIDEO_SIZE_STR); - _scale_quark = gst_video_meta_transform_scale_get_quark (); - - gst_type_mark_as_plugin_api (GST_TYPE_VIDEO_SCALE_METHOD, 0); -} - -static void -gst_video_scale_init (GstVideoScale * videoscale) -{ - videoscale->method = DEFAULT_PROP_METHOD; - videoscale->add_borders = DEFAULT_PROP_ADD_BORDERS; - videoscale->submethod = DEFAULT_PROP_SUBMETHOD; - videoscale->sharpness = DEFAULT_PROP_SHARPNESS; - videoscale->sharpen = DEFAULT_PROP_SHARPEN; - videoscale->dither = DEFAULT_PROP_DITHER; - videoscale->envelope = DEFAULT_PROP_ENVELOPE; - videoscale->gamma_decode = DEFAULT_PROP_GAMMA_DECODE; - videoscale->n_threads = DEFAULT_PROP_N_THREADS; -} - -static void -gst_video_scale_finalize (GstVideoScale * videoscale) -{ - if (videoscale->convert) - gst_video_converter_free (videoscale->convert); - - G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (videoscale)); -} - -static void -gst_video_scale_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVideoScale *vscale = GST_VIDEO_SCALE (object); - - switch (prop_id) { - case PROP_METHOD: - GST_OBJECT_LOCK (vscale); - vscale->method = g_value_get_enum (value); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_ADD_BORDERS: - GST_OBJECT_LOCK (vscale); - vscale->add_borders = g_value_get_boolean (value); - GST_OBJECT_UNLOCK (vscale); - gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM_CAST (vscale)); - break; - case PROP_SHARPNESS: - GST_OBJECT_LOCK (vscale); - vscale->sharpness = g_value_get_double (value); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_SHARPEN: - GST_OBJECT_LOCK (vscale); - vscale->sharpen = g_value_get_double (value); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_DITHER: - GST_OBJECT_LOCK (vscale); - vscale->dither = g_value_get_boolean (value); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_SUBMETHOD: - GST_OBJECT_LOCK (vscale); - vscale->submethod = g_value_get_int (value); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_ENVELOPE: - GST_OBJECT_LOCK (vscale); - vscale->envelope = g_value_get_double (value); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_GAMMA_DECODE: - GST_OBJECT_LOCK (vscale); - vscale->gamma_decode = g_value_get_boolean (value); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_N_THREADS: - GST_OBJECT_LOCK (vscale); - vscale->n_threads = g_value_get_uint (value); - GST_OBJECT_UNLOCK (vscale); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_video_scale_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstVideoScale *vscale = GST_VIDEO_SCALE (object); - - switch (prop_id) { - case PROP_METHOD: - GST_OBJECT_LOCK (vscale); - g_value_set_enum (value, vscale->method); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_ADD_BORDERS: - GST_OBJECT_LOCK (vscale); - g_value_set_boolean (value, vscale->add_borders); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_SHARPNESS: - GST_OBJECT_LOCK (vscale); - g_value_set_double (value, vscale->sharpness); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_SHARPEN: - GST_OBJECT_LOCK (vscale); - g_value_set_double (value, vscale->sharpen); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_DITHER: - GST_OBJECT_LOCK (vscale); - g_value_set_boolean (value, vscale->dither); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_SUBMETHOD: - GST_OBJECT_LOCK (vscale); - g_value_set_int (value, vscale->submethod); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_ENVELOPE: - GST_OBJECT_LOCK (vscale); - g_value_set_double (value, vscale->envelope); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_GAMMA_DECODE: - GST_OBJECT_LOCK (vscale); - g_value_set_boolean (value, vscale->gamma_decode); - GST_OBJECT_UNLOCK (vscale); - break; - case PROP_N_THREADS: - GST_OBJECT_LOCK (vscale); - g_value_set_uint (value, vscale->n_threads); - GST_OBJECT_UNLOCK (vscale); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GstCaps * -gst_video_scale_transform_caps (GstBaseTransform * trans, - GstPadDirection direction, GstCaps * caps, GstCaps * filter) -{ - GstCaps *ret; - GstStructure *structure; - GstCapsFeatures *features; - gint i, n; - - GST_DEBUG_OBJECT (trans, - "Transforming caps %" GST_PTR_FORMAT " in direction %s", caps, - (direction == GST_PAD_SINK) ? "sink" : "src"); - - ret = gst_caps_new_empty (); - n = gst_caps_get_size (caps); - for (i = 0; i < n; i++) { - structure = gst_caps_get_structure (caps, i); - features = gst_caps_get_features (caps, i); - - /* If this is already expressed by the existing caps - * skip this structure */ - if (i > 0 && gst_caps_is_subset_structure_full (ret, structure, features)) - continue; - - /* make copy */ - structure = gst_structure_copy (structure); - - /* If the features are non-sysmem we can only do passthrough */ - if (!gst_caps_features_is_any (features) - && (gst_caps_features_is_equal (features, - GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY) - || gst_caps_features_is_equal (features, features_format_interlaced) - || gst_caps_features_is_equal (features, - features_format_interlaced_sysmem))) { - gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, - "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); - - /* if pixel aspect ratio, make a range of it */ - if (gst_structure_has_field (structure, "pixel-aspect-ratio")) { - gst_structure_set (structure, "pixel-aspect-ratio", - GST_TYPE_FRACTION_RANGE, 1, G_MAXINT, G_MAXINT, 1, NULL); - } - } - gst_caps_append_structure_full (ret, structure, - gst_caps_features_copy (features)); - } - - if (filter) { - GstCaps *intersection; - - intersection = - gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (ret); - ret = intersection; - } - - GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret); - - return ret; -} - -static gboolean -gst_video_scale_transform_meta (GstBaseTransform * trans, GstBuffer * outbuf, - GstMeta * meta, GstBuffer * inbuf) -{ - GstVideoFilter *videofilter = GST_VIDEO_FILTER (trans); - const GstMetaInfo *info = meta->info; - const gchar *const *tags; - const gchar *const *curr = NULL; - gboolean should_copy = TRUE; - const gchar *const valid_tags[] = { GST_META_TAG_VIDEO_STR, - GST_META_TAG_VIDEO_COLORSPACE_STR, - GST_META_TAG_VIDEO_ORIENTATION_STR, - GST_META_TAG_VIDEO_SIZE_STR - }; - - tags = gst_meta_api_type_get_tags (info->api); - - /* No specific tags, we are good to copy */ - if (!tags) { - return TRUE; - } - - /* We are only changing size, we can preserve other metas tagged as - orientation and colorspace */ - for (curr = tags; *curr; ++curr) { - - /* We dont handle any other tag */ - if (!g_strv_contains (valid_tags, *curr)) { - should_copy = FALSE; - break; - } - } - - /* Cant handle the tags in this meta, let the parent class handle it */ - if (!should_copy) { - return GST_BASE_TRANSFORM_CLASS (parent_class)->transform_meta (trans, - outbuf, meta, inbuf); - } - - /* This meta is size sensitive, try to transform it accordingly */ - if (gst_meta_api_type_has_tag (info->api, _size_quark)) { - GstVideoMetaTransform trans = - { &videofilter->in_info, &videofilter->out_info }; - - if (info->transform_func) - return info->transform_func (outbuf, meta, inbuf, _scale_quark, &trans); - return FALSE; - } - - /* No need to transform, we can safely copy this meta */ - return TRUE; -} - -static gboolean -gst_video_scale_set_info (GstVideoFilter * filter, GstCaps * in, - GstVideoInfo * in_info, GstCaps * out, GstVideoInfo * out_info) -{ - GstVideoScale *videoscale = GST_VIDEO_SCALE (filter); - gint from_dar_n, from_dar_d, to_dar_n, to_dar_d; - - if (!gst_util_fraction_multiply (in_info->width, - in_info->height, in_info->par_n, in_info->par_d, &from_dar_n, - &from_dar_d)) { - from_dar_n = from_dar_d = -1; - } - - if (!gst_util_fraction_multiply (out_info->width, - out_info->height, out_info->par_n, out_info->par_d, &to_dar_n, - &to_dar_d)) { - to_dar_n = to_dar_d = -1; - } - - videoscale->borders_w = videoscale->borders_h = 0; - if (to_dar_n != from_dar_n || to_dar_d != from_dar_d) { - if (videoscale->add_borders) { - gint n, d, to_h, to_w; - - if (from_dar_n != -1 && from_dar_d != -1 - && gst_util_fraction_multiply (from_dar_n, from_dar_d, - out_info->par_d, out_info->par_n, &n, &d)) { - to_h = gst_util_uint64_scale_int (out_info->width, d, n); - if (to_h <= out_info->height) { - videoscale->borders_h = out_info->height - to_h; - videoscale->borders_w = 0; - } else { - to_w = gst_util_uint64_scale_int (out_info->height, n, d); - g_assert (to_w <= out_info->width); - videoscale->borders_h = 0; - videoscale->borders_w = out_info->width - to_w; - } - } else { - GST_WARNING_OBJECT (videoscale, "Can't calculate borders"); - } - } else { - GST_WARNING_OBJECT (videoscale, "Can't keep DAR!"); - } - } - - if (in_info->width == out_info->width && in_info->height == out_info->height - && videoscale->borders_w == 0 && videoscale->borders_h == 0) { - gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), TRUE); - } else { - GstStructure *options; - GST_CAT_DEBUG_OBJECT (CAT_PERFORMANCE, filter, "setup videoscaling"); - gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), FALSE); - - options = gst_structure_new_empty ("videoscale"); - - switch (videoscale->method) { - case GST_VIDEO_SCALE_NEAREST: - gst_structure_set (options, - GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD, - GST_TYPE_VIDEO_RESAMPLER_METHOD, GST_VIDEO_RESAMPLER_METHOD_NEAREST, - NULL); - break; - case GST_VIDEO_SCALE_BILINEAR: - gst_structure_set (options, - GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD, - GST_TYPE_VIDEO_RESAMPLER_METHOD, GST_VIDEO_RESAMPLER_METHOD_LINEAR, - GST_VIDEO_RESAMPLER_OPT_MAX_TAPS, G_TYPE_INT, 2, NULL); - break; - case GST_VIDEO_SCALE_4TAP: - gst_structure_set (options, - GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD, - GST_TYPE_VIDEO_RESAMPLER_METHOD, GST_VIDEO_RESAMPLER_METHOD_SINC, - GST_VIDEO_RESAMPLER_OPT_MAX_TAPS, G_TYPE_INT, 4, NULL); - break; - case GST_VIDEO_SCALE_LANCZOS: - gst_structure_set (options, - GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD, - GST_TYPE_VIDEO_RESAMPLER_METHOD, GST_VIDEO_RESAMPLER_METHOD_LANCZOS, - NULL); - break; - case GST_VIDEO_SCALE_BILINEAR2: - gst_structure_set (options, - GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD, - GST_TYPE_VIDEO_RESAMPLER_METHOD, GST_VIDEO_RESAMPLER_METHOD_LINEAR, - NULL); - break; - case GST_VIDEO_SCALE_SINC: - gst_structure_set (options, - GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD, - GST_TYPE_VIDEO_RESAMPLER_METHOD, GST_VIDEO_RESAMPLER_METHOD_SINC, - NULL); - break; - case GST_VIDEO_SCALE_HERMITE: - gst_structure_set (options, - GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD, - GST_TYPE_VIDEO_RESAMPLER_METHOD, GST_VIDEO_RESAMPLER_METHOD_CUBIC, - GST_VIDEO_RESAMPLER_OPT_CUBIC_B, G_TYPE_DOUBLE, (gdouble) 0.0, - GST_VIDEO_RESAMPLER_OPT_CUBIC_C, G_TYPE_DOUBLE, (gdouble) 0.0, - NULL); - break; - case GST_VIDEO_SCALE_SPLINE: - gst_structure_set (options, - GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD, - GST_TYPE_VIDEO_RESAMPLER_METHOD, GST_VIDEO_RESAMPLER_METHOD_CUBIC, - GST_VIDEO_RESAMPLER_OPT_CUBIC_B, G_TYPE_DOUBLE, (gdouble) 1.0, - GST_VIDEO_RESAMPLER_OPT_CUBIC_C, G_TYPE_DOUBLE, (gdouble) 0.0, - NULL); - break; - case GST_VIDEO_SCALE_CATROM: - gst_structure_set (options, - GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD, - GST_TYPE_VIDEO_RESAMPLER_METHOD, GST_VIDEO_RESAMPLER_METHOD_CUBIC, - GST_VIDEO_RESAMPLER_OPT_CUBIC_B, G_TYPE_DOUBLE, (gdouble) 0.0, - GST_VIDEO_RESAMPLER_OPT_CUBIC_C, G_TYPE_DOUBLE, (gdouble) 0.5, - NULL); - break; - case GST_VIDEO_SCALE_MITCHELL: - gst_structure_set (options, - GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD, - GST_TYPE_VIDEO_RESAMPLER_METHOD, GST_VIDEO_RESAMPLER_METHOD_CUBIC, - GST_VIDEO_RESAMPLER_OPT_CUBIC_B, G_TYPE_DOUBLE, (gdouble) 1.0 / 3.0, - GST_VIDEO_RESAMPLER_OPT_CUBIC_C, G_TYPE_DOUBLE, (gdouble) 1.0 / 3.0, - NULL); - break; - } - gst_structure_set (options, - GST_VIDEO_RESAMPLER_OPT_ENVELOPE, G_TYPE_DOUBLE, videoscale->envelope, - GST_VIDEO_RESAMPLER_OPT_SHARPNESS, G_TYPE_DOUBLE, videoscale->sharpness, - GST_VIDEO_RESAMPLER_OPT_SHARPEN, G_TYPE_DOUBLE, videoscale->sharpen, - GST_VIDEO_CONVERTER_OPT_DEST_X, G_TYPE_INT, videoscale->borders_w / 2, - GST_VIDEO_CONVERTER_OPT_DEST_Y, G_TYPE_INT, videoscale->borders_h / 2, - GST_VIDEO_CONVERTER_OPT_DEST_WIDTH, G_TYPE_INT, - out_info->width - videoscale->borders_w, - GST_VIDEO_CONVERTER_OPT_DEST_HEIGHT, G_TYPE_INT, - out_info->height - videoscale->borders_h, - GST_VIDEO_CONVERTER_OPT_MATRIX_MODE, GST_TYPE_VIDEO_MATRIX_MODE, - GST_VIDEO_MATRIX_MODE_NONE, GST_VIDEO_CONVERTER_OPT_DITHER_METHOD, - GST_TYPE_VIDEO_DITHER_METHOD, GST_VIDEO_DITHER_NONE, - GST_VIDEO_CONVERTER_OPT_CHROMA_MODE, GST_TYPE_VIDEO_CHROMA_MODE, - GST_VIDEO_CHROMA_MODE_NONE, - GST_VIDEO_CONVERTER_OPT_THREADS, G_TYPE_UINT, videoscale->n_threads, - NULL); - - if (videoscale->gamma_decode) { - gst_structure_set (options, - GST_VIDEO_CONVERTER_OPT_GAMMA_MODE, GST_TYPE_VIDEO_GAMMA_MODE, - GST_VIDEO_GAMMA_MODE_REMAP, NULL); - } - - if (videoscale->convert) - gst_video_converter_free (videoscale->convert); - videoscale->convert = gst_video_converter_new (in_info, out_info, options); - } - - GST_DEBUG_OBJECT (videoscale, "from=%dx%d (par=%d/%d dar=%d/%d), size %" - G_GSIZE_FORMAT " -> to=%dx%d (par=%d/%d dar=%d/%d borders=%d:%d), " - "size %" G_GSIZE_FORMAT, - in_info->width, in_info->height, in_info->par_n, in_info->par_d, - from_dar_n, from_dar_d, in_info->size, out_info->width, - out_info->height, out_info->par_n, out_info->par_d, to_dar_n, to_dar_d, - videoscale->borders_w, videoscale->borders_h, out_info->size); - - return TRUE; -} - -static GstCaps * -gst_video_scale_fixate_caps (GstBaseTransform * base, GstPadDirection direction, - GstCaps * caps, GstCaps * othercaps) -{ - GstStructure *ins, *outs; - const GValue *from_par, *to_par; - GValue fpar = { 0, }; - GValue tpar = { 0, }; - - othercaps = gst_caps_truncate (othercaps); - othercaps = gst_caps_make_writable (othercaps); - - GST_DEBUG_OBJECT (base, "trying to fixate othercaps %" GST_PTR_FORMAT - " based on caps %" GST_PTR_FORMAT, othercaps, caps); - - ins = gst_caps_get_structure (caps, 0); - outs = gst_caps_get_structure (othercaps, 0); - - from_par = gst_structure_get_value (ins, "pixel-aspect-ratio"); - to_par = gst_structure_get_value (outs, "pixel-aspect-ratio"); - - /* If we're fixating from the sinkpad we always set the PAR and - * assume that missing PAR on the sinkpad means 1/1 and - * missing PAR on the srcpad means undefined - */ - if (direction == GST_PAD_SINK) { - if (!from_par) { - g_value_init (&fpar, GST_TYPE_FRACTION); - gst_value_set_fraction (&fpar, 1, 1); - from_par = &fpar; - } - if (!to_par) { - g_value_init (&tpar, GST_TYPE_FRACTION_RANGE); - gst_value_set_fraction_range_full (&tpar, 1, G_MAXINT, G_MAXINT, 1); - to_par = &tpar; - } - } else { - if (!to_par) { - g_value_init (&tpar, GST_TYPE_FRACTION); - gst_value_set_fraction (&tpar, 1, 1); - to_par = &tpar; - - gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, - NULL); - } - if (!from_par) { - g_value_init (&fpar, GST_TYPE_FRACTION); - gst_value_set_fraction (&fpar, 1, 1); - from_par = &fpar; - } - } - - /* we have both PAR but they might not be fixated */ - { - gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d; - gint w = 0, h = 0; - gint from_dar_n, from_dar_d; - gint num, den; - - /* from_par should be fixed */ - g_return_val_if_fail (gst_value_is_fixed (from_par), othercaps); - - from_par_n = gst_value_get_fraction_numerator (from_par); - from_par_d = gst_value_get_fraction_denominator (from_par); - - gst_structure_get_int (ins, "width", &from_w); - gst_structure_get_int (ins, "height", &from_h); - - gst_structure_get_int (outs, "width", &w); - gst_structure_get_int (outs, "height", &h); - - /* if both width and height are already fixed, we can't do anything - * about it anymore */ - if (w && h) { - guint n, d; - - GST_DEBUG_OBJECT (base, "dimensions already set to %dx%d, not fixating", - w, h); - if (!gst_value_is_fixed (to_par)) { - if (gst_video_calculate_display_ratio (&n, &d, from_w, from_h, - from_par_n, from_par_d, w, h)) { - GST_DEBUG_OBJECT (base, "fixating to_par to %dx%d", n, d); - if (gst_structure_has_field (outs, "pixel-aspect-ratio")) - gst_structure_fixate_field_nearest_fraction (outs, - "pixel-aspect-ratio", n, d); - else if (n != d) - gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, - n, d, NULL); - } - } - goto done; - } - - /* Calculate input DAR */ - if (!gst_util_fraction_multiply (from_w, from_h, from_par_n, from_par_d, - &from_dar_n, &from_dar_d)) { - GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), - ("Error calculating the output scaled size - integer overflow")); - goto done; - } - - GST_DEBUG_OBJECT (base, "Input DAR is %d/%d", from_dar_n, from_dar_d); - - /* If either width or height are fixed there's not much we - * can do either except choosing a height or width and PAR - * that matches the DAR as good as possible - */ - if (h) { - GstStructure *tmp; - gint set_w, set_par_n, set_par_d; - - GST_DEBUG_OBJECT (base, "height is fixed (%d)", h); - - /* If the PAR is fixed too, there's not much to do - * except choosing the width that is nearest to the - * width with the same DAR */ - if (gst_value_is_fixed (to_par)) { - to_par_n = gst_value_get_fraction_numerator (to_par); - to_par_d = gst_value_get_fraction_denominator (to_par); - - GST_DEBUG_OBJECT (base, "PAR is fixed %d/%d", to_par_n, to_par_d); - - if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_d, - to_par_n, &num, &den)) { - GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), - ("Error calculating the output scaled size - integer overflow")); - goto done; - } - - w = (guint) gst_util_uint64_scale_int_round (h, num, den); - gst_structure_fixate_field_nearest_int (outs, "width", w); - - goto done; - } - - /* The PAR is not fixed and it's quite likely that we can set - * an arbitrary PAR. */ - - /* Check if we can keep the input width */ - tmp = gst_structure_copy (outs); - gst_structure_fixate_field_nearest_int (tmp, "width", from_w); - gst_structure_get_int (tmp, "width", &set_w); - - /* Might have failed but try to keep the DAR nonetheless by - * adjusting the PAR */ - if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, h, set_w, - &to_par_n, &to_par_d)) { - GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), - ("Error calculating the output scaled size - integer overflow")); - gst_structure_free (tmp); - goto done; - } - - if (!gst_structure_has_field (tmp, "pixel-aspect-ratio")) - gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par); - gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio", - to_par_n, to_par_d); - gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n, - &set_par_d); - gst_structure_free (tmp); - - /* Check if the adjusted PAR is accepted */ - if (set_par_n == to_par_n && set_par_d == to_par_d) { - if (gst_structure_has_field (outs, "pixel-aspect-ratio") || - set_par_n != set_par_d) - gst_structure_set (outs, "width", G_TYPE_INT, set_w, - "pixel-aspect-ratio", GST_TYPE_FRACTION, set_par_n, set_par_d, - NULL); - goto done; - } - - /* Otherwise scale the width to the new PAR and check if the - * adjusted with is accepted. If all that fails we can't keep - * the DAR */ - if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d, - set_par_n, &num, &den)) { - GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), - ("Error calculating the output scaled size - integer overflow")); - goto done; - } - - w = (guint) gst_util_uint64_scale_int_round (h, num, den); - gst_structure_fixate_field_nearest_int (outs, "width", w); - if (gst_structure_has_field (outs, "pixel-aspect-ratio") || - set_par_n != set_par_d) - gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, - set_par_n, set_par_d, NULL); - - goto done; - } else if (w) { - GstStructure *tmp; - gint set_h, set_par_n, set_par_d; - - GST_DEBUG_OBJECT (base, "width is fixed (%d)", w); - - /* If the PAR is fixed too, there's not much to do - * except choosing the height that is nearest to the - * height with the same DAR */ - if (gst_value_is_fixed (to_par)) { - to_par_n = gst_value_get_fraction_numerator (to_par); - to_par_d = gst_value_get_fraction_denominator (to_par); - - GST_DEBUG_OBJECT (base, "PAR is fixed %d/%d", to_par_n, to_par_d); - - if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_d, - to_par_n, &num, &den)) { - GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), - ("Error calculating the output scaled size - integer overflow")); - goto done; - } - - h = (guint) gst_util_uint64_scale_int_round (w, den, num); - gst_structure_fixate_field_nearest_int (outs, "height", h); - - goto done; - } - - /* The PAR is not fixed and it's quite likely that we can set - * an arbitrary PAR. */ - - /* Check if we can keep the input height */ - tmp = gst_structure_copy (outs); - gst_structure_fixate_field_nearest_int (tmp, "height", from_h); - gst_structure_get_int (tmp, "height", &set_h); - - /* Might have failed but try to keep the DAR nonetheless by - * adjusting the PAR */ - if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_h, w, - &to_par_n, &to_par_d)) { - GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), - ("Error calculating the output scaled size - integer overflow")); - gst_structure_free (tmp); - goto done; - } - if (!gst_structure_has_field (tmp, "pixel-aspect-ratio")) - gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par); - gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio", - to_par_n, to_par_d); - gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n, - &set_par_d); - gst_structure_free (tmp); - - /* Check if the adjusted PAR is accepted */ - if (set_par_n == to_par_n && set_par_d == to_par_d) { - if (gst_structure_has_field (outs, "pixel-aspect-ratio") || - set_par_n != set_par_d) - gst_structure_set (outs, "height", G_TYPE_INT, set_h, - "pixel-aspect-ratio", GST_TYPE_FRACTION, set_par_n, set_par_d, - NULL); - goto done; - } - - /* Otherwise scale the height to the new PAR and check if the - * adjusted with is accepted. If all that fails we can't keep - * the DAR */ - if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d, - set_par_n, &num, &den)) { - GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), - ("Error calculating the output scaled size - integer overflow")); - goto done; - } - - h = (guint) gst_util_uint64_scale_int_round (w, den, num); - gst_structure_fixate_field_nearest_int (outs, "height", h); - if (gst_structure_has_field (outs, "pixel-aspect-ratio") || - set_par_n != set_par_d) - gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, - set_par_n, set_par_d, NULL); - - goto done; - } else if (gst_value_is_fixed (to_par)) { - GstStructure *tmp; - gint set_h, set_w, f_h, f_w; - - to_par_n = gst_value_get_fraction_numerator (to_par); - to_par_d = gst_value_get_fraction_denominator (to_par); - - /* Calculate scale factor for the PAR change */ - if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_n, - to_par_d, &num, &den)) { - GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), - ("Error calculating the output scaled size - integer overflow")); - goto done; - } - - /* Try to keep the input height (because of interlacing) */ - tmp = gst_structure_copy (outs); - gst_structure_fixate_field_nearest_int (tmp, "height", from_h); - gst_structure_get_int (tmp, "height", &set_h); - - /* This might have failed but try to scale the width - * to keep the DAR nonetheless */ - w = (guint) gst_util_uint64_scale_int_round (set_h, num, den); - gst_structure_fixate_field_nearest_int (tmp, "width", w); - gst_structure_get_int (tmp, "width", &set_w); - gst_structure_free (tmp); - - /* We kept the DAR and the height is nearest to the original height */ - if (set_w == w) { - gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", - G_TYPE_INT, set_h, NULL); - goto done; - } - - f_h = set_h; - f_w = set_w; - - /* If the former failed, try to keep the input width at least */ - tmp = gst_structure_copy (outs); - gst_structure_fixate_field_nearest_int (tmp, "width", from_w); - gst_structure_get_int (tmp, "width", &set_w); - - /* This might have failed but try to scale the width - * to keep the DAR nonetheless */ - h = (guint) gst_util_uint64_scale_int_round (set_w, den, num); - gst_structure_fixate_field_nearest_int (tmp, "height", h); - gst_structure_get_int (tmp, "height", &set_h); - gst_structure_free (tmp); - - /* We kept the DAR and the width is nearest to the original width */ - if (set_h == h) { - gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", - G_TYPE_INT, set_h, NULL); - goto done; - } - - /* If all this failed, keep the dimensions with the DAR that was closest - * to the correct DAR. This changes the DAR but there's not much else to - * do here. - */ - if (set_w * ABS (set_h - h) < ABS (f_w - w) * f_h) { - f_h = set_h; - f_w = set_w; - } - gst_structure_set (outs, "width", G_TYPE_INT, f_w, "height", G_TYPE_INT, - f_h, NULL); - goto done; - } else { - GstStructure *tmp; - gint set_h, set_w, set_par_n, set_par_d, tmp2; - - /* width, height and PAR are not fixed but passthrough is not possible */ - - /* First try to keep the height and width as good as possible - * and scale PAR */ - tmp = gst_structure_copy (outs); - gst_structure_fixate_field_nearest_int (tmp, "height", from_h); - gst_structure_get_int (tmp, "height", &set_h); - gst_structure_fixate_field_nearest_int (tmp, "width", from_w); - gst_structure_get_int (tmp, "width", &set_w); - - if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_h, set_w, - &to_par_n, &to_par_d)) { - GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), - ("Error calculating the output scaled size - integer overflow")); - gst_structure_free (tmp); - goto done; - } - - if (!gst_structure_has_field (tmp, "pixel-aspect-ratio")) - gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par); - gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio", - to_par_n, to_par_d); - gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n, - &set_par_d); - gst_structure_free (tmp); - - if (set_par_n == to_par_n && set_par_d == to_par_d) { - gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", - G_TYPE_INT, set_h, NULL); - - if (gst_structure_has_field (outs, "pixel-aspect-ratio") || - set_par_n != set_par_d) - gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, - set_par_n, set_par_d, NULL); - goto done; - } - - /* Otherwise try to scale width to keep the DAR with the set - * PAR and height */ - if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d, - set_par_n, &num, &den)) { - GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), - ("Error calculating the output scaled size - integer overflow")); - goto done; - } - - w = (guint) gst_util_uint64_scale_int_round (set_h, num, den); - tmp = gst_structure_copy (outs); - gst_structure_fixate_field_nearest_int (tmp, "width", w); - gst_structure_get_int (tmp, "width", &tmp2); - gst_structure_free (tmp); - - if (tmp2 == w) { - gst_structure_set (outs, "width", G_TYPE_INT, tmp2, "height", - G_TYPE_INT, set_h, NULL); - if (gst_structure_has_field (outs, "pixel-aspect-ratio") || - set_par_n != set_par_d) - gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, - set_par_n, set_par_d, NULL); - goto done; - } - - /* ... or try the same with the height */ - h = (guint) gst_util_uint64_scale_int_round (set_w, den, num); - tmp = gst_structure_copy (outs); - gst_structure_fixate_field_nearest_int (tmp, "height", h); - gst_structure_get_int (tmp, "height", &tmp2); - gst_structure_free (tmp); - - if (tmp2 == h) { - gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", - G_TYPE_INT, tmp2, NULL); - if (gst_structure_has_field (outs, "pixel-aspect-ratio") || - set_par_n != set_par_d) - gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, - set_par_n, set_par_d, NULL); - goto done; - } - - /* If all fails we can't keep the DAR and take the nearest values - * for everything from the first try */ - gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", - G_TYPE_INT, set_h, NULL); - if (gst_structure_has_field (outs, "pixel-aspect-ratio") || - set_par_n != set_par_d) - gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, - set_par_n, set_par_d, NULL); - } - } - -done: - othercaps = gst_caps_fixate (othercaps); - - GST_DEBUG_OBJECT (base, "fixated othercaps to %" GST_PTR_FORMAT, othercaps); - - if (from_par == &fpar) - g_value_unset (&fpar); - if (to_par == &tpar) - g_value_unset (&tpar); - - return othercaps; -} - -#define GET_LINE(frame, line) \ - (gpointer)(((guint8*)(GST_VIDEO_FRAME_PLANE_DATA (frame, 0))) + \ - GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0) * (line)) - -static GstFlowReturn -gst_video_scale_transform_frame (GstVideoFilter * filter, - GstVideoFrame * in_frame, GstVideoFrame * out_frame) -{ - GstVideoScale *videoscale = GST_VIDEO_SCALE_CAST (filter); - GstFlowReturn ret = GST_FLOW_OK; - - GST_CAT_DEBUG_OBJECT (CAT_PERFORMANCE, filter, "doing video scaling"); - - gst_video_converter_frame (videoscale->convert, in_frame, out_frame); - - return ret; -} - -static gboolean -gst_video_scale_src_event (GstBaseTransform * trans, GstEvent * event) -{ - GstVideoScale *videoscale = GST_VIDEO_SCALE_CAST (trans); - GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans); - gboolean ret; - gdouble a; - GstStructure *structure; - - GST_DEBUG_OBJECT (videoscale, "handling %s event", - GST_EVENT_TYPE_NAME (event)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NAVIGATION: - if (filter->in_info.width != filter->out_info.width || - filter->in_info.height != filter->out_info.height) { - event = - GST_EVENT (gst_mini_object_make_writable (GST_MINI_OBJECT (event))); - - structure = (GstStructure *) gst_event_get_structure (event); - if (gst_structure_get_double (structure, "pointer_x", &a)) { - gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, - a * filter->in_info.width / filter->out_info.width, NULL); - } - if (gst_structure_get_double (structure, "pointer_y", &a)) { - gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, - a * filter->in_info.height / filter->out_info.height, NULL); - } - } - break; - default: - break; - } - - ret = GST_BASE_TRANSFORM_CLASS (parent_class)->src_event (trans, event); - - return ret; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - features_format_interlaced = - gst_caps_features_new (GST_CAPS_FEATURE_FORMAT_INTERLACED, NULL); - features_format_interlaced_sysmem = - gst_caps_features_copy (features_format_interlaced); - gst_caps_features_add (features_format_interlaced_sysmem, - GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY); - - GST_DEBUG_CATEGORY_INIT (video_scale_debug, "videoscale", 0, - "videoscale element"); - GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE"); - - return GST_ELEMENT_REGISTER (videoscale, plugin); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - videoscale, - "Resizes video", plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, - GST_PACKAGE_ORIGIN) diff --git a/subprojects/gst-plugins-base/gst/videoscale/gstvideoscale.h b/subprojects/gst-plugins-base/gst/videoscale/gstvideoscale.h deleted file mode 100644 index f518d5e..0000000 --- a/subprojects/gst-plugins-base/gst/videoscale/gstvideoscale.h +++ /dev/null @@ -1,93 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __GST_VIDEO_SCALE_H__ -#define __GST_VIDEO_SCALE_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_VIDEO_SCALE (gst_video_scale_get_type()) -#define GST_VIDEO_SCALE_CAST(obj) ((GstVideoScale *)(obj)) -G_DECLARE_FINAL_TYPE (GstVideoScale, gst_video_scale, GST, VIDEO_SCALE, - GstVideoFilter) - - -/** - * GstVideoScaleMethod: - * @GST_VIDEO_SCALE_NEAREST: use nearest neighbour scaling (fast and ugly) - * @GST_VIDEO_SCALE_BILINEAR: use 2-tap bilinear scaling (slower but prettier). - * @GST_VIDEO_SCALE_4TAP: use a 4-tap sinc filter for scaling (slow). - * @GST_VIDEO_SCALE_LANCZOS: use a multitap Lanczos filter for scaling (slow). - * @GST_VIDEO_SCALE_BILINEAR2: use a multitap bilinear filter - * @GST_VIDEO_SCALE_SINC: use a multitap sinc filter - * @GST_VIDEO_SCALE_HERMITE: use a multitap bicubic Hermite filter - * @GST_VIDEO_SCALE_SPLINE: use a multitap bicubic spline filter - * @GST_VIDEO_SCALE_CATROM: use a multitap bicubic Catmull-Rom filter - * @GST_VIDEO_SCALE_MITCHELL: use a multitap bicubic Mitchell filter - * - * The videoscale method to use. - */ -typedef enum { - GST_VIDEO_SCALE_NEAREST, - GST_VIDEO_SCALE_BILINEAR, - GST_VIDEO_SCALE_4TAP, - GST_VIDEO_SCALE_LANCZOS, - - GST_VIDEO_SCALE_BILINEAR2, - GST_VIDEO_SCALE_SINC, - GST_VIDEO_SCALE_HERMITE, - GST_VIDEO_SCALE_SPLINE, - GST_VIDEO_SCALE_CATROM, - GST_VIDEO_SCALE_MITCHELL -} GstVideoScaleMethod; - -/** - * GstVideoScale: - * - * Opaque data structure - */ -struct _GstVideoScale { - GstVideoFilter element; - - /* properties */ - GstVideoScaleMethod method; - gboolean add_borders; - double sharpness; - double sharpen; - gboolean dither; - int submethod; - double envelope; - gboolean gamma_decode; - gint n_threads; - - GstVideoConverter *convert; - - gint borders_h; - gint borders_w; -}; - -GST_ELEMENT_REGISTER_DECLARE (videoscale); - -G_END_DECLS - -#endif /* __GST_VIDEO_SCALE_H__ */ diff --git a/subprojects/gst-plugins-base/gst/videoscale/meson.build b/subprojects/gst-plugins-base/gst/videoscale/meson.build deleted file mode 100644 index d5d6b9b..0000000 --- a/subprojects/gst-plugins-base/gst/videoscale/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -videoscale_sources = [ - 'gstvideoscale.c', -] - -gstvideoscale = library('gstvideoscale', - videoscale_sources, - c_args : gst_plugins_base_args, - include_directories: [configinc, libsinc], - dependencies : [video_dep, gst_dep, gst_base_dep], - install : true, - install_dir : plugins_install_dir, -) - -plugins += [gstvideoscale] diff --git a/subprojects/gst-plugins-base/meson_options.txt b/subprojects/gst-plugins-base/meson_options.txt index b2071ca..1ab0477 100644 --- a/subprojects/gst-plugins-base/meson_options.txt +++ b/subprojects/gst-plugins-base/meson_options.txt @@ -46,9 +46,7 @@ option('rawparse', type : 'feature', value : 'auto') option('subparse', type : 'feature', value : 'auto') option('tcp', type : 'feature', value : 'auto') option('typefind', type : 'feature', value : 'auto') -option('videoconvertscale', type : 'feature', value : 'disabled') -option('videoconvert', type : 'feature', value : 'auto') -option('videoscale', type : 'feature', value : 'auto') +option('videoconvertscale', type : 'feature', value : 'auto') option('videorate', type : 'feature', value : 'auto') option('videotestsrc', type : 'feature', value : 'auto') option('volume', type : 'feature', value : 'auto') -- 2.7.4