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; } }
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; } }