1 /* GStreamer libswscale wrapper
2 * Copyright (C) 2005 Luca Ognibene <luogni@tin.it>
3 * Copyright (C) 2006 Martin Zlomek <martin.zlomek@itonis.tv>
4 * Copyright (C) 2008 Mark Nauwelaerts <mnauw@users.sf.net>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
26 #ifdef HAVE_FFMPEG_UNINSTALLED
29 #include <libswscale/swscale.h>
33 #include <gst/base/gstbasetransform.h>
34 #include <gst/video/video.h>
42 typedef struct _GstFFMpegScale
44 GstBaseTransform element;
47 GstPad *sinkpad, *srcpad;
50 GstVideoInfo in_info, out_info;
52 enum PixelFormat in_pixfmt, out_pixfmt;
53 struct SwsContext *ctx;
59 typedef struct _GstFFMpegScaleClass
61 GstBaseTransformClass parent_class;
62 } GstFFMpegScaleClass;
64 #define GST_TYPE_FFMPEGSCALE \
65 (gst_ffmpegscale_get_type())
66 #define GST_FFMPEGSCALE(obj) \
67 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGSCALE,GstFFMpegScale))
68 #define GST_FFMPEGSCALE_CLASS(klass) \
69 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGSCALE,GstFFMpegScaleClass))
70 #define GST_IS_FFMPEGSCALE(obj) \
71 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGSCALE))
72 #define GST_IS_FFMPEGSCALE_CLASS(klass) \
73 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGSCALE))
75 GType gst_ffmpegscale_get_type (void);
77 GST_DEBUG_CATEGORY (ffmpegscale_debug);
78 #define GST_CAT_DEFAULT ffmpegscale_debug
80 /* libswscale supported formats depend on endianness */
81 #if G_BYTE_ORDER == G_BIG_ENDIAN
83 GST_VIDEO_CAPS_MAKE ("{ RGB, BGR, xRGB, xBGR, ARGB, ABGR, I420, YUY2, UYVY, Y41B, Y42B }")
86 GST_VIDEO_CAPS_MAKE ("{ RGB, BGR, RGBx, BGRx, RGBA, BGRA, I420, YUY2, UYVY, Y41B, Y42B }")
89 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
92 GST_STATIC_CAPS (VIDEO_CAPS)
95 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
98 GST_STATIC_CAPS (VIDEO_CAPS)
101 static gint gst_ffmpegscale_method_flags[] = {
115 #define GST_TYPE_FFMPEGSCALE_METHOD (gst_ffmpegscale_method_get_type())
117 gst_ffmpegscale_method_get_type (void)
119 static GType ffmpegscale_method_type = 0;
121 static const GEnumValue ffmpegscale_methods[] = {
122 {0, "Fast Bilinear", "fast-bilinear"},
123 {1, "Bilinear", "bilinear"},
124 {2, "Bicubic", "bicubic"},
125 {3, "Experimental", "experimental"},
126 {4, "Nearest Neighbour", "nearest-neighbour"},
128 {6, "Luma Bicubic / Chroma Linear", "bicubic-lin"},
129 {7, "Gauss", "gauss"},
130 {8, "SincR", "sincr"},
131 {9, "Lanczos", "lanczos"},
132 {10, "Natural Bicubic Spline", "bicubic-spline"},
136 if (!ffmpegscale_method_type) {
137 ffmpegscale_method_type =
138 g_enum_register_static ("GstFFMpegVideoScaleMethod",
139 ffmpegscale_methods);
141 return ffmpegscale_method_type;
144 #define DEFAULT_PROP_METHOD 2
153 #define gst_ffmpegscale_parent_class parent_class
154 G_DEFINE_TYPE (GstFFMpegScale, gst_ffmpegscale, GST_TYPE_BASE_TRANSFORM);
156 static void gst_ffmpegscale_finalize (GObject * object);
157 static void gst_ffmpegscale_set_property (GObject * object, guint prop_id,
158 const GValue * value, GParamSpec * pspec);
159 static void gst_ffmpegscale_get_property (GObject * object, guint prop_id,
160 GValue * value, GParamSpec * pspec);
162 static gboolean gst_ffmpegscale_stop (GstBaseTransform * trans);
163 static GstCaps *gst_ffmpegscale_transform_caps (GstBaseTransform * trans,
164 GstPadDirection direction, GstCaps * caps, GstCaps * filter);
165 static void gst_ffmpegscale_fixate_caps (GstBaseTransform * trans,
166 GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
167 static gboolean gst_ffmpegscale_get_unit_size (GstBaseTransform * trans,
168 GstCaps * caps, gsize * size);
169 static gboolean gst_ffmpegscale_set_caps (GstBaseTransform * trans,
170 GstCaps * incaps, GstCaps * outcaps);
171 static GstFlowReturn gst_ffmpegscale_transform (GstBaseTransform * trans,
172 GstBuffer * inbuf, GstBuffer * outbuf);
174 static gboolean gst_ffmpegscale_handle_src_event (GstPad * pad,
178 gst_ffmpegscale_class_init (GstFFMpegScaleClass * klass)
180 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
181 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
182 GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass);
184 gobject_class->finalize = gst_ffmpegscale_finalize;
185 gobject_class->set_property = gst_ffmpegscale_set_property;
186 gobject_class->get_property = gst_ffmpegscale_get_property;
188 g_object_class_install_property (gobject_class, PROP_METHOD,
189 g_param_spec_enum ("method", "method", "method",
190 GST_TYPE_FFMPEGSCALE_METHOD, DEFAULT_PROP_METHOD,
191 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
193 gst_element_class_add_pad_template (gstelement_class,
194 gst_static_pad_template_get (&src_factory));
195 gst_element_class_add_pad_template (gstelement_class,
196 gst_static_pad_template_get (&sink_factory));
198 gst_element_class_set_details_simple (gstelement_class,
199 "FFMPEG Scale element", "Filter/Converter/Video",
200 "Converts video from one resolution to another",
201 "Luca Ognibene <luogni@tin.it>, Mark Nauwelaerts <mnauw@users.sf.net>");
203 trans_class->stop = GST_DEBUG_FUNCPTR (gst_ffmpegscale_stop);
204 trans_class->transform_caps =
205 GST_DEBUG_FUNCPTR (gst_ffmpegscale_transform_caps);
206 trans_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_ffmpegscale_fixate_caps);
207 trans_class->get_unit_size =
208 GST_DEBUG_FUNCPTR (gst_ffmpegscale_get_unit_size);
209 trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_ffmpegscale_set_caps);
210 trans_class->transform = GST_DEBUG_FUNCPTR (gst_ffmpegscale_transform);
212 trans_class->passthrough_on_same_caps = TRUE;
216 gst_ffmpegscale_init (GstFFMpegScale * scale)
218 GstBaseTransform *trans = GST_BASE_TRANSFORM (scale);
220 gst_pad_set_event_function (trans->srcpad, gst_ffmpegscale_handle_src_event);
222 scale->method = DEFAULT_PROP_METHOD;
224 scale->in_pixfmt = PIX_FMT_NONE;
225 scale->out_pixfmt = PIX_FMT_NONE;
229 gst_ffmpegscale_reset (GstFFMpegScale * scale)
231 if (scale->ctx != NULL) {
232 sws_freeContext (scale->ctx);
236 scale->in_pixfmt = PIX_FMT_NONE;
237 scale->out_pixfmt = PIX_FMT_NONE;
241 gst_ffmpegscale_finalize (GObject * object)
243 GstFFMpegScale *scale = GST_FFMPEGSCALE (object);
245 gst_ffmpegscale_reset (scale);
247 G_OBJECT_CLASS (parent_class)->finalize (object);
250 /* copies the given caps */
252 gst_ffmpegscale_caps_remove_format_info (GstCaps * caps)
255 GstStructure *structure;
259 caps = gst_caps_copy (caps);
261 for (i = 0; i < gst_caps_get_size (caps); i++) {
262 structure = gst_caps_get_structure (caps, i);
264 gst_structure_set_name (structure, "video/x-raw-yuv");
265 gst_structure_remove_field (structure, "format");
266 gst_structure_remove_field (structure, "endianness");
267 gst_structure_remove_field (structure, "depth");
268 gst_structure_remove_field (structure, "bpp");
269 gst_structure_remove_field (structure, "red_mask");
270 gst_structure_remove_field (structure, "green_mask");
271 gst_structure_remove_field (structure, "blue_mask");
272 gst_structure_remove_field (structure, "alpha_mask");
273 gst_structure_remove_field (structure, "palette_data");
276 rgbcaps = gst_caps_copy (caps);
278 for (i = 0; i < gst_caps_get_size (rgbcaps); i++) {
279 structure = gst_caps_get_structure (rgbcaps, i);
281 gst_structure_set_name (structure, "video/x-raw-rgb");
283 graycaps = gst_caps_copy (caps);
285 for (i = 0; i < gst_caps_get_size (graycaps); i++) {
286 structure = gst_caps_get_structure (graycaps, i);
288 gst_structure_set_name (structure, "video/x-raw-gray");
291 gst_caps_append (caps, graycaps);
292 gst_caps_append (caps, rgbcaps);
298 gst_ffmpegscale_transform_caps (GstBaseTransform * trans,
299 GstPadDirection direction, GstCaps * caps, GstCaps * filter)
302 GstStructure *structure;
305 /* this function is always called with a simple caps */
306 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL);
308 structure = gst_caps_get_structure (caps, 0);
310 ret = gst_caps_copy (caps);
311 structure = gst_structure_copy (gst_caps_get_structure (ret, 0));
313 gst_structure_set (structure,
314 "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
315 "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
317 gst_caps_merge_structure (ret, gst_structure_copy (structure));
319 /* if pixel aspect ratio, make a range of it */
320 if ((par = gst_structure_get_value (structure, "pixel-aspect-ratio"))) {
321 gst_structure_set (structure,
322 "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
324 gst_caps_merge_structure (ret, structure);
326 gst_structure_free (structure);
329 /* now also unfix colour space format */
330 gst_caps_append (ret, gst_ffmpegscale_caps_remove_format_info (ret));
332 GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret);
338 gst_ffmpegscale_fixate_caps (GstBaseTransform * trans,
339 GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
341 GstStructure *ins, *outs;
342 const GValue *from_par, *to_par;
344 g_return_if_fail (gst_caps_is_fixed (caps));
346 GST_DEBUG_OBJECT (trans, "trying to fixate othercaps %" GST_PTR_FORMAT
347 " based on caps %" GST_PTR_FORMAT, othercaps, caps);
349 ins = gst_caps_get_structure (caps, 0);
350 outs = gst_caps_get_structure (othercaps, 0);
352 from_par = gst_structure_get_value (ins, "pixel-aspect-ratio");
353 to_par = gst_structure_get_value (outs, "pixel-aspect-ratio");
355 /* we have both PAR but they might not be fixated */
356 if (from_par && to_par) {
357 gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d;
358 gint count = 0, w = 0, h = 0;
361 /* from_par should be fixed */
362 g_return_if_fail (gst_value_is_fixed (from_par));
364 from_par_n = gst_value_get_fraction_numerator (from_par);
365 from_par_d = gst_value_get_fraction_denominator (from_par);
367 /* fixate the out PAR */
368 if (!gst_value_is_fixed (to_par)) {
369 GST_DEBUG_OBJECT (trans, "fixating to_par to %dx%d", from_par_n,
371 gst_structure_fixate_field_nearest_fraction (outs, "pixel-aspect-ratio",
372 from_par_n, from_par_d);
375 to_par_n = gst_value_get_fraction_numerator (to_par);
376 to_par_d = gst_value_get_fraction_denominator (to_par);
378 /* if both width and height are already fixed, we can't do anything
379 * about it anymore */
380 if (gst_structure_get_int (outs, "width", &w))
382 if (gst_structure_get_int (outs, "height", &h))
385 GST_DEBUG_OBJECT (trans, "dimensions already set to %dx%d, not fixating",
390 gst_structure_get_int (ins, "width", &from_w);
391 gst_structure_get_int (ins, "height", &from_h);
393 if (!gst_video_calculate_display_ratio (&num, &den, from_w, from_h,
394 from_par_n, from_par_d, to_par_n, to_par_d)) {
395 GST_ELEMENT_ERROR (trans, CORE, NEGOTIATION, (NULL),
396 ("Error calculating the output scaled size - integer overflow"));
400 GST_DEBUG_OBJECT (trans,
401 "scaling input with %dx%d and PAR %d/%d to output PAR %d/%d",
402 from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d);
403 GST_DEBUG_OBJECT (trans, "resulting output should respect ratio of %d/%d",
406 /* now find a width x height that respects this display ratio.
407 * prefer those that have one of w/h the same as the incoming video
408 * using wd / hd = num / den */
410 /* if one of the output width or height is fixed, we work from there */
412 GST_DEBUG_OBJECT (trans, "height is fixed,scaling width");
413 w = (guint) gst_util_uint64_scale_int (h, num, den);
415 GST_DEBUG_OBJECT (trans, "width is fixed, scaling height");
416 h = (guint) gst_util_uint64_scale_int (w, den, num);
418 /* none of width or height is fixed, figure out both of them based only on
419 * the input width and height */
420 /* check hd / den is an integer scale factor, and scale wd with the PAR */
421 if (from_h % den == 0) {
422 GST_DEBUG_OBJECT (trans, "keeping video height");
424 w = (guint) gst_util_uint64_scale_int (h, num, den);
425 } else if (from_w % num == 0) {
426 GST_DEBUG_OBJECT (trans, "keeping video width");
428 h = (guint) gst_util_uint64_scale_int (w, den, num);
430 GST_DEBUG_OBJECT (trans, "approximating but keeping video height");
432 w = (guint) gst_util_uint64_scale_int (h, num, den);
435 GST_DEBUG_OBJECT (trans, "scaling to %dx%d", w, h);
438 gst_structure_fixate_field_nearest_int (outs, "width", w);
439 gst_structure_fixate_field_nearest_int (outs, "height", h);
443 if (gst_structure_get_int (ins, "width", &width)) {
444 if (gst_structure_has_field (outs, "width")) {
445 gst_structure_fixate_field_nearest_int (outs, "width", width);
448 if (gst_structure_get_int (ins, "height", &height)) {
449 if (gst_structure_has_field (outs, "height")) {
450 gst_structure_fixate_field_nearest_int (outs, "height", height);
455 GST_DEBUG_OBJECT (trans, "fixated othercaps to %" GST_PTR_FORMAT, othercaps);
459 gst_ffmpegscale_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
464 if (!gst_video_info_from_caps (&info, caps))
469 GST_DEBUG_OBJECT (trans, "unit size = %d for format %d w %d height %d",
470 *size, GST_VIDEO_INFO_FORMAT (&info), GST_VIDEO_INFO_WIDTH (&info),
471 GST_VIDEO_INFO_HEIGHT (&info));
476 /* Convert a GstCaps (video/raw) to a FFMPEG PixFmt
478 static enum PixelFormat
479 gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps)
482 enum PixelFormat pix_fmt;
484 GST_DEBUG ("converting caps %" GST_PTR_FORMAT, caps);
486 if (gst_video_info_from_caps (&info, caps))
489 switch (GST_VIDEO_INFO_FORMAT (&info)) {
490 case GST_VIDEO_FORMAT_YUY2:
491 pix_fmt = PIX_FMT_YUYV422;
493 case GST_VIDEO_FORMAT_UYVY:
494 pix_fmt = PIX_FMT_UYVY422;
496 case GST_VIDEO_FORMAT_I420:
497 pix_fmt = PIX_FMT_YUV420P;
499 case GST_VIDEO_FORMAT_Y41B:
500 pix_fmt = PIX_FMT_YUV411P;
502 case GST_VIDEO_FORMAT_Y42B:
503 pix_fmt = PIX_FMT_YUV422P;
505 case GST_VIDEO_FORMAT_YUV9:
506 pix_fmt = PIX_FMT_YUV410P;
508 case GST_VIDEO_FORMAT_ARGB:
509 pix_fmt = PIX_FMT_ARGB;
511 case GST_VIDEO_FORMAT_RGBA:
512 pix_fmt = PIX_FMT_RGBA;
514 case GST_VIDEO_FORMAT_BGRA:
515 pix_fmt = PIX_FMT_BGRA;
517 case GST_VIDEO_FORMAT_ABGR:
518 pix_fmt = PIX_FMT_ABGR;
520 case GST_VIDEO_FORMAT_BGR:
521 pix_fmt = PIX_FMT_BGR24;
523 case GST_VIDEO_FORMAT_RGB:
524 pix_fmt = PIX_FMT_RGB24;
526 case GST_VIDEO_FORMAT_RGB16:
527 pix_fmt = PIX_FMT_RGB565;
529 case GST_VIDEO_FORMAT_RGB15:
530 pix_fmt = PIX_FMT_RGB555;
532 case GST_VIDEO_FORMAT_RGB8_PALETTED:
533 pix_fmt = PIX_FMT_PAL8;
536 pix_fmt = PIX_FMT_NONE;
549 gst_ffmpegscale_set_caps (GstBaseTransform * trans, GstCaps * incaps,
552 GstFFMpegScale *scale = GST_FFMPEGSCALE (trans);
553 guint mmx_flags, altivec_flags;
557 g_return_val_if_fail (scale->method <
558 G_N_ELEMENTS (gst_ffmpegscale_method_flags), FALSE);
561 sws_freeContext (scale->ctx);
565 ok = gst_video_info_from_caps (&scale->in_info, incaps);
566 ok &= gst_video_info_from_caps (&scale->out_info, outcaps);
568 scale->in_pixfmt = gst_ffmpeg_caps_to_pixfmt (incaps);
569 scale->out_pixfmt = gst_ffmpeg_caps_to_pixfmt (outcaps);
571 if (!ok || scale->in_pixfmt == PIX_FMT_NONE ||
572 scale->out_pixfmt == PIX_FMT_NONE ||
573 GST_VIDEO_INFO_FORMAT (&scale->in_info) == GST_VIDEO_FORMAT_UNKNOWN ||
574 GST_VIDEO_INFO_FORMAT (&scale->out_info) == GST_VIDEO_FORMAT_UNKNOWN)
577 GST_DEBUG_OBJECT (scale, "format %d => %d, from=%dx%d -> to=%dx%d",
578 GST_VIDEO_INFO_FORMAT (&scale->in_info),
579 GST_VIDEO_INFO_FORMAT (&scale->out_info),
580 GST_VIDEO_INFO_WIDTH (&scale->in_info),
581 GST_VIDEO_INFO_HEIGHT (&scale->in_info),
582 GST_VIDEO_INFO_WIDTH (&scale->out_info),
583 GST_VIDEO_INFO_HEIGHT (&scale->out_info));
586 mmx_flags = orc_target_get_default_flags (orc_target_get_by_name ("mmx"));
588 orc_target_get_default_flags (orc_target_get_by_name ("altivec"));
589 swsflags = (mmx_flags & ORC_TARGET_MMX_MMX ? SWS_CPU_CAPS_MMX : 0)
590 | (mmx_flags & ORC_TARGET_MMX_MMXEXT ? SWS_CPU_CAPS_MMX2 : 0)
591 | (mmx_flags & ORC_TARGET_MMX_3DNOW ? SWS_CPU_CAPS_3DNOW : 0)
592 | (altivec_flags & ORC_TARGET_ALTIVEC_ALTIVEC ? SWS_CPU_CAPS_ALTIVEC : 0);
599 scale->ctx = sws_getContext (scale->in_info.width, scale->in_info.height,
600 scale->in_pixfmt, scale->out_info.width, scale->out_info.height,
601 scale->out_pixfmt, swsflags | gst_ffmpegscale_method_flags[scale->method],
611 GST_ELEMENT_ERROR (trans, LIBRARY, INIT, (NULL), (NULL));
616 GST_DEBUG_OBJECT (trans, "refused caps %" GST_PTR_FORMAT, incaps);
622 gst_ffmpegscale_transform (GstBaseTransform * trans, GstBuffer * inbuf,
625 GstFFMpegScale *scale = GST_FFMPEGSCALE (trans);
626 GstVideoFrame in_frame, out_frame;
628 if (!gst_video_frame_map (&in_frame, &scale->in_info, inbuf, GST_MAP_READ))
631 if (!gst_video_frame_map (&out_frame, &scale->out_info, outbuf,
635 sws_scale (scale->ctx, (const guint8 **) in_frame.data, in_frame.info.stride,
636 0, scale->in_info.height, (guint8 **) out_frame.data,
637 out_frame.info.stride);
639 gst_video_frame_unmap (&in_frame);
640 gst_video_frame_unmap (&out_frame);
652 gst_ffmpegscale_handle_src_event (GstPad * pad, GstEvent * event)
654 GstFFMpegScale *scale;
655 GstStructure *structure;
659 scale = GST_FFMPEGSCALE (gst_pad_get_parent (pad));
661 switch (GST_EVENT_TYPE (event)) {
662 case GST_EVENT_NAVIGATION:
664 GST_EVENT (gst_mini_object_make_writable (GST_MINI_OBJECT (event)));
666 structure = (GstStructure *) gst_event_get_structure (event);
667 if (gst_structure_get_double (structure, "pointer_x", &pointer)) {
668 gst_structure_set (structure,
669 "pointer_x", G_TYPE_DOUBLE,
670 pointer * scale->in_info.width / scale->out_info.width, NULL);
672 if (gst_structure_get_double (structure, "pointer_y", &pointer)) {
673 gst_structure_set (structure,
674 "pointer_y", G_TYPE_DOUBLE,
675 pointer * scale->in_info.height / scale->out_info.height, NULL);
682 res = gst_pad_event_default (pad, event);
684 gst_object_unref (scale);
690 gst_ffmpegscale_stop (GstBaseTransform * trans)
692 GstFFMpegScale *scale = GST_FFMPEGSCALE (trans);
694 gst_ffmpegscale_reset (scale);
700 gst_ffmpegscale_set_property (GObject * object, guint prop_id,
701 const GValue * value, GParamSpec * pspec)
703 GstFFMpegScale *scale = GST_FFMPEGSCALE (object);
707 scale->method = g_value_get_enum (value);
710 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
716 gst_ffmpegscale_get_property (GObject * object, guint prop_id, GValue * value,
719 GstFFMpegScale *scale = GST_FFMPEGSCALE (object);
723 g_value_set_enum (value, scale->method);
726 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
731 #ifndef GST_DISABLE_GST_DEBUG
733 gst_ffmpeg_log_callback (void *ptr, int level, const char *fmt, va_list vl)
735 GstDebugLevel gst_level;
739 gst_level = GST_LEVEL_NONE;
742 gst_level = GST_LEVEL_ERROR;
745 gst_level = GST_LEVEL_INFO;
748 gst_level = GST_LEVEL_DEBUG;
751 gst_level = GST_LEVEL_INFO;
755 gst_debug_log_valist (ffmpegscale_debug, gst_level, "", "", 0, NULL, fmt, vl);
760 plugin_init (GstPlugin * plugin)
762 GST_DEBUG_CATEGORY_INIT (ffmpegscale_debug, "ffvideoscale", 0,
763 "video scaling element");
769 #ifndef GST_DISABLE_GST_DEBUG
770 av_log_set_callback (gst_ffmpeg_log_callback);
773 return gst_element_register (plugin, "ffvideoscale",
774 GST_RANK_NONE, GST_TYPE_FFMPEGSCALE);
777 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
780 "videoscaling element (" FFMPEG_SOURCE ")",
783 #ifdef GST_FFMPEG_ENABLE_LGPL
788 "FFMpeg", "http://ffmpeg.sourceforge.net/")