static gboolean gst_video_scale_src_event (GstBaseTransform * trans, GstEvent * event) { GstVideoScale *videoscale = GST_VIDEO_SCALE (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: 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 * videoscale->from_width / videoscale->to_width, NULL); } if (gst_structure_get_double (structure, "pointer_y", &a)) { gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, a * videoscale->from_height / videoscale->to_height, NULL); } break; default: break; } ret = GST_BASE_TRANSFORM_CLASS (parent_class)->src_event (trans, event); return ret; }
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; 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; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
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 (GST_BASE_TRANSFORM_CAST (vscale)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
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, 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 gboolean gst_video_scale_set_caps (GstBaseTransform * trans, GstCaps * in, GstCaps * out) { GstVideoScale *videoscale = GST_VIDEO_SCALE (trans); gboolean ret; gint from_dar_n, from_dar_d, to_dar_n, to_dar_d; gint from_par_n, from_par_d, to_par_n, to_par_d; ret = gst_video_format_parse_caps (in, &videoscale->format, &videoscale->from_width, &videoscale->from_height); ret &= gst_video_format_parse_caps (out, NULL, &videoscale->to_width, &videoscale->to_height); if (!ret) goto done; videoscale->src_size = gst_video_format_get_size (videoscale->format, videoscale->from_width, videoscale->from_height); videoscale->dest_size = gst_video_format_get_size (videoscale->format, videoscale->to_width, videoscale->to_height); if (!gst_video_parse_caps_pixel_aspect_ratio (in, &from_par_n, &from_par_d)) from_par_n = from_par_d = 1; if (!gst_video_parse_caps_pixel_aspect_ratio (out, &to_par_n, &to_par_d)) to_par_n = to_par_d = 1; if (!gst_util_fraction_multiply (videoscale->from_width, videoscale->from_height, from_par_n, from_par_d, &from_dar_n, &from_dar_d)) { from_dar_n = from_dar_d = -1; } if (!gst_util_fraction_multiply (videoscale->to_width, videoscale->to_height, to_par_n, to_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, to_par_n, to_par_d, &n, &d)) { to_h = gst_util_uint64_scale_int (videoscale->to_width, d, n); if (to_h <= videoscale->to_height) { videoscale->borders_h = videoscale->to_height - to_h; videoscale->borders_w = 0; } else { to_w = gst_util_uint64_scale_int (videoscale->to_height, n, d); g_assert (to_w <= videoscale->to_width); videoscale->borders_h = 0; videoscale->borders_w = videoscale->to_width - to_w; } } else { GST_WARNING_OBJECT (videoscale, "Can't calculate borders"); } } else { GST_WARNING_OBJECT (videoscale, "Can't keep DAR!"); } } if (videoscale->tmp_buf) g_free (videoscale->tmp_buf); videoscale->tmp_buf = g_malloc (videoscale->to_width * 8 * 4); gst_base_transform_set_passthrough (trans, (videoscale->from_width == videoscale->to_width && videoscale->from_height == videoscale->to_height)); GST_DEBUG_OBJECT (videoscale, "from=%dx%d (par=%d/%d dar=%d/%d), size %d " "-> to=%dx%d (par=%d/%d dar=%d/%d borders=%d:%d), size %d", videoscale->from_width, videoscale->from_height, from_par_n, from_par_d, from_dar_n, from_dar_d, videoscale->src_size, videoscale->to_width, videoscale->to_height, to_par_n, to_par_d, to_dar_n, to_dar_d, videoscale->borders_w, videoscale->borders_h, videoscale->dest_size); done: return ret; }
static GstFlowReturn gst_video_scale_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out) { GstVideoScale *videoscale = GST_VIDEO_SCALE (trans); GstFlowReturn ret = GST_FLOW_OK; VSImage dest = { NULL, }; VSImage src = { NULL, }; VSImage dest_u = { NULL, }; VSImage dest_v = { NULL, }; VSImage src_u = { NULL, }; VSImage src_v = { NULL, }; gint method; const guint8 *black = _get_black_for_format (videoscale->format); gboolean add_borders; GST_OBJECT_LOCK (videoscale); method = videoscale->method; add_borders = videoscale->add_borders; GST_OBJECT_UNLOCK (videoscale); if (videoscale->from_width == 1) { method = GST_VIDEO_SCALE_NEAREST; } if (method == GST_VIDEO_SCALE_4TAP && (videoscale->from_width < 4 || videoscale->from_height < 4)) { method = GST_VIDEO_SCALE_BILINEAR; } gst_video_scale_setup_vs_image (&src, videoscale->format, 0, videoscale->from_width, videoscale->from_height, 0, 0, GST_BUFFER_DATA (in)); gst_video_scale_setup_vs_image (&dest, videoscale->format, 0, videoscale->to_width, videoscale->to_height, videoscale->borders_w, videoscale->borders_h, GST_BUFFER_DATA (out)); if (videoscale->format == GST_VIDEO_FORMAT_I420 || videoscale->format == GST_VIDEO_FORMAT_YV12 || videoscale->format == GST_VIDEO_FORMAT_Y444 || videoscale->format == GST_VIDEO_FORMAT_Y42B || videoscale->format == GST_VIDEO_FORMAT_Y41B) { gst_video_scale_setup_vs_image (&src_u, videoscale->format, 1, videoscale->from_width, videoscale->from_height, 0, 0, GST_BUFFER_DATA (in)); gst_video_scale_setup_vs_image (&src_v, videoscale->format, 2, videoscale->from_width, videoscale->from_height, 0, 0, GST_BUFFER_DATA (in)); gst_video_scale_setup_vs_image (&dest_u, videoscale->format, 1, videoscale->to_width, videoscale->to_height, videoscale->borders_w, videoscale->borders_h, GST_BUFFER_DATA (out)); gst_video_scale_setup_vs_image (&dest_v, videoscale->format, 2, videoscale->to_width, videoscale->to_height, videoscale->borders_w, videoscale->borders_h, GST_BUFFER_DATA (out)); } switch (videoscale->format) { case GST_VIDEO_FORMAT_RGBx: case GST_VIDEO_FORMAT_xRGB: case GST_VIDEO_FORMAT_BGRx: case GST_VIDEO_FORMAT_xBGR: case GST_VIDEO_FORMAT_RGBA: case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_BGRA: case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_AYUV: if (add_borders) vs_fill_borders_RGBA (&dest, black); switch (method) { case GST_VIDEO_SCALE_NEAREST: vs_image_scale_nearest_RGBA (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_BILINEAR: vs_image_scale_linear_RGBA (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_4TAP: vs_image_scale_4tap_RGBA (&dest, &src, videoscale->tmp_buf); break; default: goto unknown_mode; } break; case GST_VIDEO_FORMAT_ARGB64: case GST_VIDEO_FORMAT_AYUV64: if (add_borders) vs_fill_borders_AYUV64 (&dest, black); switch (method) { case GST_VIDEO_SCALE_NEAREST: vs_image_scale_nearest_AYUV64 (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_BILINEAR: vs_image_scale_linear_AYUV64 (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_4TAP: vs_image_scale_4tap_AYUV64 (&dest, &src, videoscale->tmp_buf); break; default: goto unknown_mode; } break; case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_v308: if (add_borders) vs_fill_borders_RGB (&dest, black); switch (method) { case GST_VIDEO_SCALE_NEAREST: vs_image_scale_nearest_RGB (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_BILINEAR: vs_image_scale_linear_RGB (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_4TAP: vs_image_scale_4tap_RGB (&dest, &src, videoscale->tmp_buf); break; default: goto unknown_mode; } break; case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_YVYU: if (add_borders) vs_fill_borders_YUYV (&dest, black); switch (method) { case GST_VIDEO_SCALE_NEAREST: vs_image_scale_nearest_YUYV (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_BILINEAR: vs_image_scale_linear_YUYV (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_4TAP: vs_image_scale_4tap_YUYV (&dest, &src, videoscale->tmp_buf); break; default: goto unknown_mode; } break; case GST_VIDEO_FORMAT_UYVY: if (add_borders) vs_fill_borders_UYVY (&dest, black); switch (method) { case GST_VIDEO_SCALE_NEAREST: vs_image_scale_nearest_UYVY (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_BILINEAR: vs_image_scale_linear_UYVY (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_4TAP: vs_image_scale_4tap_UYVY (&dest, &src, videoscale->tmp_buf); break; default: goto unknown_mode; } break; case GST_VIDEO_FORMAT_Y800: case GST_VIDEO_FORMAT_GRAY8: if (add_borders) vs_fill_borders_Y (&dest, black); switch (method) { case GST_VIDEO_SCALE_NEAREST: vs_image_scale_nearest_Y (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_BILINEAR: vs_image_scale_linear_Y (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_4TAP: vs_image_scale_4tap_Y (&dest, &src, videoscale->tmp_buf); break; default: goto unknown_mode; } break; case GST_VIDEO_FORMAT_GRAY16_LE: case GST_VIDEO_FORMAT_GRAY16_BE: case GST_VIDEO_FORMAT_Y16: if (add_borders) vs_fill_borders_Y16 (&dest, 0); switch (method) { case GST_VIDEO_SCALE_NEAREST: vs_image_scale_nearest_Y16 (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_BILINEAR: vs_image_scale_linear_Y16 (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_4TAP: vs_image_scale_4tap_Y16 (&dest, &src, videoscale->tmp_buf); break; default: goto unknown_mode; } break; case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_Y444: case GST_VIDEO_FORMAT_Y42B: case GST_VIDEO_FORMAT_Y41B: if (add_borders) { vs_fill_borders_Y (&dest, black); vs_fill_borders_Y (&dest_u, black + 1); vs_fill_borders_Y (&dest_v, black + 2); } switch (method) { case GST_VIDEO_SCALE_NEAREST: vs_image_scale_nearest_Y (&dest, &src, videoscale->tmp_buf); vs_image_scale_nearest_Y (&dest_u, &src_u, videoscale->tmp_buf); vs_image_scale_nearest_Y (&dest_v, &src_v, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_BILINEAR: vs_image_scale_linear_Y (&dest, &src, videoscale->tmp_buf); vs_image_scale_linear_Y (&dest_u, &src_u, videoscale->tmp_buf); vs_image_scale_linear_Y (&dest_v, &src_v, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_4TAP: vs_image_scale_4tap_Y (&dest, &src, videoscale->tmp_buf); vs_image_scale_4tap_Y (&dest_u, &src_u, videoscale->tmp_buf); vs_image_scale_4tap_Y (&dest_v, &src_v, videoscale->tmp_buf); break; default: goto unknown_mode; } break; case GST_VIDEO_FORMAT_RGB16: if (add_borders) vs_fill_borders_RGB565 (&dest, black); switch (method) { case GST_VIDEO_SCALE_NEAREST: vs_image_scale_nearest_RGB565 (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_BILINEAR: vs_image_scale_linear_RGB565 (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_4TAP: vs_image_scale_4tap_RGB565 (&dest, &src, videoscale->tmp_buf); break; default: goto unknown_mode; } break; case GST_VIDEO_FORMAT_RGB15: if (add_borders) vs_fill_borders_RGB555 (&dest, black); switch (method) { case GST_VIDEO_SCALE_NEAREST: vs_image_scale_nearest_RGB555 (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_BILINEAR: vs_image_scale_linear_RGB555 (&dest, &src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_4TAP: vs_image_scale_4tap_RGB555 (&dest, &src, videoscale->tmp_buf); break; default: goto unknown_mode; } break; default: goto unsupported; } GST_LOG_OBJECT (videoscale, "pushing buffer of %d bytes", GST_BUFFER_SIZE (out)); return ret; /* ERRORS */ unsupported: { GST_ELEMENT_ERROR (videoscale, STREAM, NOT_IMPLEMENTED, (NULL), ("Unsupported format %d for scaling method %d", videoscale->format, method)); return GST_FLOW_ERROR; } unknown_mode: { GST_ELEMENT_ERROR (videoscale, STREAM, NOT_IMPLEMENTED, (NULL), ("Unknown scaling method %d", videoscale->method)); return GST_FLOW_ERROR; } }