Esempio n. 1
0
static gboolean
gst_ffmpegscale_set_caps(GstBaseTransform* trans, GstCaps* incaps,
                         GstCaps* outcaps) {
    GstFFMpegScale* scale = GST_FFMPEGSCALE(trans);
    guint mmx_flags, altivec_flags, sse_flags;
    gint swsflags;
    gboolean ok;

    g_return_val_if_fail(scale->method <
                         G_N_ELEMENTS(gst_ffmpegscale_method_flags), FALSE);

    if (scale->ctx) {
        sws_freeContext(scale->ctx);
        scale->ctx = NULL;
    }

    scale->borders_h = 0;
    scale->borders_w = 0;

    ok = gst_video_format_parse_caps(incaps, &scale->in_format, &scale->in_width,
                                     &scale->in_height);
    ok &= gst_video_format_parse_caps(outcaps, &scale->out_format, &scale->out_width,
                                      &scale->out_height);
    scale->in_pixfmt = gst_ffmpeg_caps_to_pixfmt(incaps);
    scale->out_pixfmt = gst_ffmpeg_caps_to_pixfmt(outcaps);

    if (!ok || scale->in_pixfmt == PIX_FMT_NONE ||
            scale->out_pixfmt == PIX_FMT_NONE ||
            scale->in_format == GST_VIDEO_FORMAT_UNKNOWN ||
            scale->out_format == GST_VIDEO_FORMAT_UNKNOWN) {
        goto refuse_caps;
    }

    GST_DEBUG_OBJECT(scale, "format %d => %d, from=%dx%d -> to=%dx%d", scale->in_format,
                     scale->out_format, scale->in_width, scale->in_height, scale->out_width,
                     scale->out_height);

    gst_ffmpegscale_fill_info(scale, scale->in_format, scale->in_width,
                              scale->in_height, scale->in_stride, scale->in_offset);
    gst_ffmpegscale_fill_info(scale, scale->out_format, scale->out_width,
                              scale->out_height, scale->out_stride, scale->out_offset);

#ifdef HAVE_ORC
    mmx_flags = orc_target_get_default_flags(orc_target_get_by_name("mmx"));
    altivec_flags =
        orc_target_get_default_flags(orc_target_get_by_name("altivec"));
    sse_flags = orc_target_get_default_flags(orc_target_get_by_name("sse"));

    swsflags = (mmx_flags & ORC_TARGET_MMX_MMX ? SWS_CPU_CAPS_MMX : 0)
               | (mmx_flags & ORC_TARGET_MMX_MMXEXT ? SWS_CPU_CAPS_MMX2 : 0)
               | (mmx_flags & ORC_TARGET_MMX_3DNOW ? SWS_CPU_CAPS_3DNOW : 0)
               | (altivec_flags & ORC_TARGET_ALTIVEC_ALTIVEC ? SWS_CPU_CAPS_ALTIVEC : 0)
               | (sse_flags & ORC_TARGET_SSE_SSE2 ? SWS_CPU_CAPS_SSE2 : 0);
#else
    mmx_flags = 0;
    altivec_flags = 0;
    swsflags = 0;
#endif

    if (scale->add_borders && scale->in_width > 0 && scale->in_height > 0 && scale->out_height > 0
            && scale->out_width > 0) {
        gfloat ratio = scale->in_width * 1.0f / scale->in_height;
        gint ratio_width = (gint)(scale->out_height * ratio);

        if (ratio_width > scale->out_width) {
            gint ratio_height = (gint)(scale->out_width / ratio);


            scale->ctx = sws_getContext(scale->in_width, scale->in_height,
                                        scale->in_pixfmt, scale->out_width, ratio_height, scale->out_pixfmt,
                                        swsflags | gst_ffmpegscale_method_flags[scale->method], NULL, NULL, NULL);

            if (ratio_height != scale->out_height) {
                gint rows = 0;
                scale->borders_h = scale->out_height - ratio_height;
                rows = scale->borders_h / 2;

                if (rows > 0) {
                    gst_video_format_add_top_border(scale->out_format, rows, scale->out_offset, scale->out_stride);
                }
            }
        } else {

            if (ratio_width != scale->out_width) {
                 gint cols = 0;
                 scale->borders_w = scale->out_width - ratio_width;
                 cols = scale->borders_w / 2;

                if (cols > 0) {
                    int i = 0;

                    for (i = 0; i < 3; i ++) {
                        scale->out_offset[i] += cols * scale->out_stride[i] / scale->out_width;
                    }
                }
            }

            scale->ctx = sws_getContext(scale->in_width, scale->in_height,
                                        scale->in_pixfmt, ratio_width, scale->out_height, scale->out_pixfmt,
                                        swsflags | gst_ffmpegscale_method_flags[scale->method], NULL, NULL, NULL);
        }

    } else {
        scale->ctx = sws_getContext(scale->in_width, scale->in_height,
                                    scale->in_pixfmt, scale->out_width, scale->out_height, scale->out_pixfmt,
                                    swsflags | gst_ffmpegscale_method_flags[scale->method], NULL, NULL, NULL);
    }

    if (!scale->ctx) {
        goto setup_failed;
    }

    return TRUE;

    /* ERRORS */
setup_failed: {
        GST_ELEMENT_ERROR(trans, LIBRARY, INIT, (NULL), (NULL));
        return FALSE;
    }
refuse_caps: {
        GST_DEBUG_OBJECT(trans, "refused caps %" GST_PTR_FORMAT, incaps);
        return FALSE;
    }
}
Esempio n. 2
0
static gboolean
gst_ffmpegscale_set_caps (GstBaseTransform * trans, GstCaps * incaps,
                          GstCaps * outcaps)
{
    GstFFMpegScale *scale = GST_FFMPEGSCALE (trans);
#ifdef HAVE_ORC
    guint mmx_flags, altivec_flags;
#endif
    gint swsflags;
    gboolean ok;

    g_return_val_if_fail (scale->method <
                          G_N_ELEMENTS (gst_ffmpegscale_method_flags), FALSE);

    if (scale->ctx) {
        sws_freeContext (scale->ctx);
        scale->ctx = NULL;
    }

    ok = gst_video_info_from_caps (&scale->in_info, incaps);
    ok &= gst_video_info_from_caps (&scale->out_info, outcaps);

    scale->in_pixfmt = gst_ffmpeg_caps_to_pixfmt (incaps);
    scale->out_pixfmt = gst_ffmpeg_caps_to_pixfmt (outcaps);

    if (!ok || scale->in_pixfmt == AV_PIX_FMT_NONE ||
            scale->out_pixfmt == AV_PIX_FMT_NONE ||
            GST_VIDEO_INFO_FORMAT (&scale->in_info) == GST_VIDEO_FORMAT_UNKNOWN ||
            GST_VIDEO_INFO_FORMAT (&scale->out_info) == GST_VIDEO_FORMAT_UNKNOWN)
        goto refuse_caps;

    GST_DEBUG_OBJECT (scale, "format %d => %d, from=%dx%d -> to=%dx%d",
                      GST_VIDEO_INFO_FORMAT (&scale->in_info),
                      GST_VIDEO_INFO_FORMAT (&scale->out_info),
                      GST_VIDEO_INFO_WIDTH (&scale->in_info),
                      GST_VIDEO_INFO_HEIGHT (&scale->in_info),
                      GST_VIDEO_INFO_WIDTH (&scale->out_info),
                      GST_VIDEO_INFO_HEIGHT (&scale->out_info));

#ifdef HAVE_ORC
    mmx_flags = orc_target_get_default_flags (orc_target_get_by_name ("mmx"));
    altivec_flags =
        orc_target_get_default_flags (orc_target_get_by_name ("altivec"));
    swsflags = (mmx_flags & ORC_TARGET_MMX_MMX ? SWS_CPU_CAPS_MMX : 0)
               | (mmx_flags & ORC_TARGET_MMX_MMXEXT ? SWS_CPU_CAPS_MMX2 : 0)
               | (mmx_flags & ORC_TARGET_MMX_3DNOW ? SWS_CPU_CAPS_3DNOW : 0)
               | (altivec_flags & ORC_TARGET_ALTIVEC_ALTIVEC ? SWS_CPU_CAPS_ALTIVEC : 0);
#else
    swsflags = 0;
#endif

    scale->ctx = sws_getContext (scale->in_info.width, scale->in_info.height,
                                 scale->in_pixfmt, scale->out_info.width, scale->out_info.height,
                                 scale->out_pixfmt, swsflags | gst_ffmpegscale_method_flags[scale->method],
                                 NULL, NULL, NULL);
    if (!scale->ctx)
        goto setup_failed;

    return TRUE;

    /* ERRORS */
setup_failed:
    {
        GST_ELEMENT_ERROR (trans, LIBRARY, INIT, (NULL), (NULL));
        return FALSE;
    }
refuse_caps:
    {
        GST_DEBUG_OBJECT (trans, "refused caps %" GST_PTR_FORMAT, incaps);
        return FALSE;
    }
}