示例#1
0
static void
gst_validate_ssim_configure_converter (GstValidateSsim * self, gint index,
    gboolean force, GstVideoFormat in_format, gint width, gint height)
{
  SSimConverterInfo *info = g_list_nth_data (self->priv->converters, index);

  if (!info) {
    info = g_slice_new0 (SSimConverterInfo);

    self->priv->converters =
        g_list_insert (self->priv->converters, info, index);
  }

  if (force || info->in_info.height != height || info->in_info.width != width ||
      info->in_info.finfo->format != in_format) {
    gst_video_info_init (&info->in_info);
    gst_video_info_set_format (&info->in_info, in_format, width, height);

    if (info->converter)
      gst_video_converter_free (info->converter);

    info->out_info = self->priv->out_info;

    if (gst_video_info_is_equal (&info->in_info, &info->out_info))
      info->converter = NULL;
    else
      info->converter =
          gst_video_converter_new (&info->in_info, &info->out_info, NULL);
  }
}
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));
}
示例#3
0
static void
ssim_convert_info_free (SSimConverterInfo * info)
{
  if (info->converter)
    gst_video_converter_free (info->converter);

  g_slice_free (SSimConverterInfo, info);
}
static void
gst_video_convert_finalize (GObject * obj)
{
  GstVideoConvert *space = GST_VIDEO_CONVERT (obj);

  if (space->convert) {
    gst_video_converter_free (space->convert);
  }

  G_OBJECT_CLASS (parent_class)->finalize (obj);
}
static gboolean
gst_video_convert_set_info (GstVideoFilter * filter,
    GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
    GstVideoInfo * out_info)
{
  GstVideoConvert *space;

  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;


  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, NULL));
  if (space->convert == NULL)
    goto no_convert;

  GST_DEBUG ("reconfigured %d %d", GST_VIDEO_INFO_FORMAT (in_info),
      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;
  }
}
示例#6
0
static void
gst_validate_ssim_finalize (GObject * object)
{
  GstValidateSsim *self = GST_VALIDATE_SSIM (object);
  void (*chain_up) (GObject *) =
      ((GObjectClass *) gst_validate_ssim_parent_class)->finalize;

  g_list_free_full (self->priv->converters,
      (GDestroyNotify) ssim_convert_info_free);

  if (self->priv->outconverter_info.converter)
    gst_video_converter_free (self->priv->outconverter_info.converter);
  g_hash_table_unref (self->priv->ref_frames_cache);

  chain_up (object);
}
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;
}
示例#8
0
static void
gst_validate_ssim_save_out (GstValidateSsim * self, GstBuffer * buffer,
    const gchar * ref_file, const gchar * file, const gchar * outfolder)
{
  GstVideoFrame frame, converted;

  if (!g_file_test (outfolder, G_FILE_TEST_IS_DIR)) {
    if (g_mkdir_with_parents (outfolder, 0755) != 0) {

      GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR,
          "Could not create output directory %s", outfolder);
      return;
    }
  }

  if (self->priv->outconverter_info.converter == NULL ||
      self->priv->width != self->priv->outconverter_info.out_info.width ||
      self->priv->height != self->priv->outconverter_info.out_info.height) {

    if (self->priv->outconverter_info.converter)
      gst_video_converter_free (self->priv->outconverter_info.converter);

    gst_video_info_init (&self->priv->outconverter_info.in_info);
    gst_video_info_set_format (&self->priv->outconverter_info.in_info,
        GST_VIDEO_FORMAT_GRAY8, self->priv->width, self->priv->height);

    gst_video_info_init (&self->priv->outconverter_info.out_info);
    gst_video_info_set_format (&self->priv->outconverter_info.out_info,
        GST_VIDEO_FORMAT_RGBx, self->priv->width, self->priv->height);

    self->priv->outconverter_info.converter =
        gst_video_converter_new (&self->priv->outconverter_info.in_info,
        &self->priv->outconverter_info.out_info, NULL);
  }

  if (!gst_video_frame_map (&frame, &self->priv->outconverter_info.in_info,
          buffer, GST_MAP_READ)) {
    GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR,
        "Could not map output frame");

    return;
  }

  if (gst_validate_ssim_convert (self, &self->priv->outconverter_info,
          &frame, &converted)) {
    cairo_status_t status;
    cairo_surface_t *surface;
    gchar *bn1 = g_path_get_basename (ref_file);
    gchar *bn2 = g_path_get_basename (file);
    gchar *fname = g_strdup_printf ("%s.VS.%s.result.png", bn1, bn2);
    gchar *outfile = g_build_path (G_DIR_SEPARATOR_S, outfolder, fname, NULL);

    surface =
        cairo_image_surface_create_for_data (GST_VIDEO_FRAME_PLANE_DATA
        (&converted, 0), CAIRO_FORMAT_RGB24, GST_VIDEO_FRAME_WIDTH (&converted),
        GST_VIDEO_FRAME_HEIGHT (&converted),
        GST_VIDEO_FRAME_PLANE_STRIDE (&converted, 0));

    if ((status = cairo_surface_write_to_png (surface, outfile)) !=
        CAIRO_STATUS_SUCCESS) {
      GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR,
          "Could not save '%s', cairo status is '%s'", outfile,
          cairo_status_to_string (status));
    }

    cairo_surface_destroy (surface);
    gst_video_frame_unmap (&frame);
    gst_video_frame_unmap (&converted);
    g_free (bn1);
    g_free (bn2);
    g_free (fname);
    g_free (outfile);
  }
}
static gboolean
gst_video_convert_set_info (GstVideoFilter * filter,
    GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
    GstVideoInfo * out_info)
{
  GstVideoConvert *space;

  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;


  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 ("reconfigured %d %d", GST_VIDEO_INFO_FORMAT (in_info),
      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;
  }
}