diff --git a/ChangeLog b/ChangeLog index 2105c48381..ae7f9211de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2007-06-12 Jan Schmidt + + * configure.ac: + * docs/plugins/Makefile.am: + * docs/plugins/gst-plugins-bad-plugins-docs.sgml: + * docs/plugins/gst-plugins-bad-plugins-sections.txt: + * docs/plugins/inspect/plugin-osxvideo.xml: + * docs/plugins/inspect/plugin-videocrop.xml: + * gst-plugins-bad.spec.in: + * gst/videocrop/Makefile.am: + * gst/videocrop/gstvideocrop.c: + * gst/videocrop/gstvideocrop.h: + * gst/videocrop/videocrop.vcproj: + * sys/Makefile.am: + * sys/osxvideo/Makefile.am: + * sys/osxvideo/cocoawindow.h: + * sys/osxvideo/cocoawindow.m: + * sys/osxvideo/osxvideosink.h: + * sys/osxvideo/osxvideosink.m: + * tests/check/Makefile.am: + * tests/check/elements/videocrop.c: + * tests/icles/Makefile.am: + * tests/icles/videocrop-test.c: + Move videocrop and osxvideo to -good. + 2007-06-12 Jan Schmidt * configure.ac: diff --git a/configure.ac b/configure.ac index a835f18633..92c84040cd 100644 --- a/configure.ac +++ b/configure.ac @@ -102,7 +102,6 @@ GST_PLUGINS_ALL="\ speed \ switch \ tta \ - videocrop \ videoparse \ videosignal \ vmnc \ @@ -317,23 +316,6 @@ AG_GST_CHECK_FEATURE(X, [X libraries and plugins], CPPFLAGS="$ac_cppflags_save" ]) -dnl *** OS X video *** -translit(dnm, m, l) AM_CONDITIONAL(USE_OSX_VIDEO, true) -HAVE_OSX_VIDEO="no" -AG_GST_CHECK_FEATURE(OSX_VIDEO, [OSX video], osxvideosink, [ - AC_CHECK_HEADER(OpenGL/gl.h, HAVE_OSX_VIDEO="yes", HAVE_OSX_VIDEO="no") -]) -dnl in case header OpenGL/gl.h is found on other platforms -case "$host" in - *-*darwin*) - dnl do nothing - ;; - *) - HAVE_OSX_VIDEO="no" - ;; -esac - - dnl *** ext plug-ins *** dnl keep this list sorted alphabetically ! @@ -911,7 +893,6 @@ AM_CONDITIONAL(USE_MUSICBRAINZ, false) AM_CONDITIONAL(USE_MYTHTV, false) AM_CONDITIONAL(USE_NAS, false) AM_CONDITIONAL(USE_NEON, false) -AM_CONDITIONAL(USE_OSX_VIDEO, false) AM_CONDITIONAL(USE_SDL, false) AM_CONDITIONAL(USE_SNDFILE, false) AM_CONDITIONAL(USE_SOUNDTOUCH, false) @@ -999,7 +980,6 @@ gst/spectrum/Makefile gst/speed/Makefile gst/switch/Makefile gst/tta/Makefile -gst/videocrop/Makefile gst/videoparse/Makefile gst/videosignal/Makefile gst/vmnc/Makefile @@ -1012,7 +992,6 @@ gst-libs/gst/app/Makefile sys/Makefile sys/glsink/Makefile sys/dvb/Makefile -sys/osxvideo/Makefile examples/Makefile examples/app/Makefile examples/directfb/Makefile diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index 279c30d26d..a49a07ba7c 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -61,7 +61,7 @@ FIXXREF_OPTIONS=--extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/gobject \ # Used for dependencies. HFILE_GLOB=$(DOC_SOURCE_DIR)/*/*/*.h -CFILE_GLOB=$(DOC_SOURCE_DIR)/*/*/*.c $(DOC_SOURCE_DIR)/*/*/*.cc $(DOC_SOURCE_DIR)/*/*/*.m +CFILE_GLOB=$(DOC_SOURCE_DIR)/*/*/*.c $(DOC_SOURCE_DIR)/*/*/*.cc # this is a wingo addition # thomasvs: another nice wingo addition would be an explanation on why @@ -89,7 +89,6 @@ EXAMPLE_CFILES = \ $(top_srcdir)/ext/directfb/dfb-example.c EXTRA_HFILES = \ - $(top_srcdir)/sys/osxvideo/osxvideosink.h \ $(top_srcdir)/ext/directfb/dfbvideosink.h \ $(top_srcdir)/ext/jack/gstjackaudiosink.h \ $(top_srcdir)/ext/musicbrainz/gsttrm.h \ @@ -104,7 +103,6 @@ EXTRA_HFILES = \ $(top_srcdir)/gst/rtpmanager/gstrtpptdemux.h \ $(top_srcdir)/gst/rtpmanager/gstrtpsession.h \ $(top_srcdir)/gst/rtpmanager/gstrtpssrcdemux.h \ - $(top_srcdir)/gst/videocrop/gstvideocrop.h \ $(top_srcdir)/gst/videosignal/gstvideoanalyse.h \ $(top_srcdir)/gst/videosignal/gstvideodetect.h \ $(top_srcdir)/gst/videosignal/gstvideomark.h diff --git a/docs/plugins/gst-plugins-bad-plugins-docs.sgml b/docs/plugins/gst-plugins-bad-plugins-docs.sgml index a5c5f115f0..2478e39681 100644 --- a/docs/plugins/gst-plugins-bad-plugins-docs.sgml +++ b/docs/plugins/gst-plugins-bad-plugins-docs.sgml @@ -14,7 +14,6 @@ gst-plugins-bad Elements - @@ -26,7 +25,6 @@ - @@ -48,14 +46,12 @@ - - diff --git a/docs/plugins/gst-plugins-bad-plugins-sections.txt b/docs/plugins/gst-plugins-bad-plugins-sections.txt index f9ce4f1fe6..c8f28dee42 100644 --- a/docs/plugins/gst-plugins-bad-plugins-sections.txt +++ b/docs/plugins/gst-plugins-bad-plugins-sections.txt @@ -15,22 +15,6 @@ GstJackConnect GstJackAudioSinkClass -
-element-osxvideosink -GstOSXVideoSink -osxvideosink - -GstOSXVideoSinkClass - -GST_IS_OSX_VIDEO_SINK -GST_IS_OSX_VIDEO_SINK_CLASS -GST_OSX_VIDEO_SINK -GST_OSX_VIDEO_SINK_CLASS -GST_TYPE_OSXVIDEOBUFFER -GST_TYPE_OSX_VIDEO_SINK -GstOSXWindow -
-
element-rganalysis GstRgAnalysis @@ -169,14 +153,6 @@ GstTRM GstTRMClass
-
-element-videocrop -GstVideoCrop -videocrop - -GstVideoCropClass -
-
element-videoanalyse videoanalyse diff --git a/docs/plugins/inspect/plugin-osxvideo.xml b/docs/plugins/inspect/plugin-osxvideo.xml deleted file mode 100644 index 45bdeeb5d8..0000000000 --- a/docs/plugins/inspect/plugin-osxvideo.xml +++ /dev/null @@ -1,20 +0,0 @@ - - osxvideo - OSX native video output plugin - ../../ext/osxvideo/.libs/libgstosxvideo.so - libgstosxvideo.so - 0.10.4 - LGPL - gst-plugins-bad - Gstreamer - http://gstreamer.freedesktop.org - - - osxvideosink - OSX Video sink - Sink/Video - OSX native videosink - Zaheer Abbas Merali <zaheerabas at merali dot org> - - - diff --git a/docs/plugins/inspect/plugin-videocrop.xml b/docs/plugins/inspect/plugin-videocrop.xml deleted file mode 100644 index bc26268331..0000000000 --- a/docs/plugins/inspect/plugin-videocrop.xml +++ /dev/null @@ -1,20 +0,0 @@ - - videocrop - Crops video into a user-defined region - ../../gst/videocrop/.libs/libgstvideocrop.so - libgstvideocrop.so - 0.10.4.1 - LGPL - gst-plugins-bad - GStreamer Bad Plug-ins CVS/prerelease - Unknown package origin - - - videocrop - Crop - Filter/Effect/Video - Crops video into a user-defined region - Tim-Philipp Müller <tim centricular net> - - - \ No newline at end of file diff --git a/gst-plugins-bad.spec.in b/gst-plugins-bad.spec.in index 43e9badc83..be4a740647 100644 --- a/gst-plugins-bad.spec.in +++ b/gst-plugins-bad.spec.in @@ -91,7 +91,6 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/gstreamer-%{majorminor}/libgstspectrum.so %{_libdir}/gstreamer-%{majorminor}/libgstfilter.so %{_libdir}/gstreamer-%{majorminor}/libgstnsf.so -%{_libdir}/gstreamer-%{majorminor}/libgstvideocrop.so %{_libdir}/gstreamer-%{majorminor}/libgstdvbsrc.so %{_libdir}/gstreamer-%{majorminor}/libgstreplaygain.so %{_libdir}/gstreamer-%{majorminor}/libgstdeinterlace.so diff --git a/gst/videocrop/Makefile.am b/gst/videocrop/Makefile.am deleted file mode 100644 index 9557742c9b..0000000000 --- a/gst/videocrop/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -plugin_LTLIBRARIES = libgstvideocrop.la - -# Note: we only use defines from gst/video/video.h, but none -# of the functions, so we don't need to link to libgstvideo - -libgstvideocrop_la_SOURCES = gstvideocrop.c -libgstvideocrop_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \ - $(GST_PLUGINS_BASE_CFLAGS) -libgstvideocrop_la_LIBADD = $(GST_BASE_LIBS) -libgstvideocrop_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -noinst_HEADERS = gstvideocrop.h diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c deleted file mode 100644 index 78375545f5..0000000000 --- a/gst/videocrop/gstvideocrop.c +++ /dev/null @@ -1,725 +0,0 @@ -/* GStreamer video frame cropping - * Copyright (C) 2006 Tim-Philipp Müller - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-videocrop - * @see_also: GstVideoBox - * - * - * - * This element crops video frames, meaning it can remove parts of the - * picture on the left, right, top or bottom of the picture and output - * a smaller picture than the input picture, with the unwanted parts at the - * border removed. - * - * - * The videocrop element is similar to the videobox element, but its main - * goal is to support a multitude of formats as efficiently as possible. - * Unlike videbox, it cannot add borders to the picture and unlike videbox - * it will always output images in exactly the same format as the input image. - * - * - * If there is nothing to crop, the element will operate in pass-through mode. - * - * - * Note that no special efforts are made to handle chroma-subsampled formats - * in the case of odd-valued cropping and compensate for sub-unit chroma plane - * shifts for such formats in the case where the "left" or "top" property is - * set to an odd number. This doesn't matter for most use cases, but it might - * matter for yours. - * - * Example launch line - * - * - * gst-launch -v videotestsrc ! videocrop top=42 left=1 right=4 bottom=0 ! ximagesink - * - * - * - */ - -/* TODO: - * - for packed formats, we could avoid memcpy() in case crop_left - * and crop_right are 0 and just create a sub-buffer of the input - * buffer - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "gstvideocrop.h" - -#include - -GST_DEBUG_CATEGORY_STATIC (videocrop_debug); -#define GST_CAT_DEFAULT videocrop_debug - -static const GstElementDetails video_crop_details = GST_ELEMENT_DETAILS ("Crop", - "Filter/Effect/Video", - "Crops video into a user-defined region", - "Tim-Philipp Müller "); - -enum -{ - ARG_0, - ARG_LEFT, - ARG_RIGHT, - ARG_TOP, - ARG_BOTTOM -}; - -/* the formats we support */ -#define VIDEO_CROP_CAPS \ - GST_VIDEO_CAPS_RGBx ";" \ - GST_VIDEO_CAPS_xRGB ";" \ - GST_VIDEO_CAPS_BGRx ";" \ - GST_VIDEO_CAPS_xBGR ";" \ - GST_VIDEO_CAPS_RGBA ";" \ - GST_VIDEO_CAPS_ARGB ";" \ - GST_VIDEO_CAPS_BGRA ";" \ - GST_VIDEO_CAPS_ABGR ";" \ - GST_VIDEO_CAPS_RGB ";" \ - GST_VIDEO_CAPS_BGR ";" \ - GST_VIDEO_CAPS_YUV ("AYUV") ";" \ - GST_VIDEO_CAPS_YUV ("YUY2") ";" \ - GST_VIDEO_CAPS_YUV ("YVYU") ";" \ - GST_VIDEO_CAPS_YUV ("UYVY") ";" \ - GST_VIDEO_CAPS_YUV ("Y800") ";" \ - GST_VIDEO_CAPS_YUV ("I420") ";" \ - GST_VIDEO_CAPS_YUV ("YV12") ";" \ - GST_VIDEO_CAPS_RGB_16 ";" \ - GST_VIDEO_CAPS_RGB_15 - -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (VIDEO_CROP_CAPS) - ); - -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (VIDEO_CROP_CAPS) - ); - -GST_BOILERPLATE (GstVideoCrop, gst_video_crop, GstBaseTransform, - GST_TYPE_BASE_TRANSFORM); - -static void gst_video_crop_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_video_crop_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static GstCaps *gst_video_crop_transform_caps (GstBaseTransform * trans, - GstPadDirection direction, GstCaps * caps); -static GstFlowReturn gst_video_crop_transform (GstBaseTransform * trans, - GstBuffer * inbuf, GstBuffer * outbuf); -static gboolean gst_video_crop_get_unit_size (GstBaseTransform * trans, - GstCaps * caps, guint * size); -static gboolean gst_video_crop_set_caps (GstBaseTransform * trans, - GstCaps * in_caps, GstCaps * outcaps); - -static void -gst_video_crop_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_set_details (element_class, &video_crop_details); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); -} - -static void -gst_video_crop_class_init (GstVideoCropClass * klass) -{ - GObjectClass *gobject_class; - GstBaseTransformClass *basetransform_class; - - gobject_class = (GObjectClass *) klass; - basetransform_class = (GstBaseTransformClass *) klass; - - gobject_class->set_property = gst_video_crop_set_property; - gobject_class->get_property = gst_video_crop_get_property; - - g_object_class_install_property (gobject_class, ARG_LEFT, - g_param_spec_int ("left", "Left", "Pixels to crop at left", - 0, G_MAXINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, ARG_RIGHT, - g_param_spec_int ("right", "Right", "Pixels to crop at right", - 0, G_MAXINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, ARG_TOP, - g_param_spec_int ("top", "Top", "Pixels to crop at top", - 0, G_MAXINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, ARG_BOTTOM, - g_param_spec_int ("bottom", "Bottom", "Pixels to crop at bottom", - 0, G_MAXINT, 0, G_PARAM_READWRITE)); - - basetransform_class->transform = GST_DEBUG_FUNCPTR (gst_video_crop_transform); - basetransform_class->transform_caps = - GST_DEBUG_FUNCPTR (gst_video_crop_transform_caps); - basetransform_class->set_caps = GST_DEBUG_FUNCPTR (gst_video_crop_set_caps); - basetransform_class->get_unit_size = - GST_DEBUG_FUNCPTR (gst_video_crop_get_unit_size); - - basetransform_class->passthrough_on_same_caps = FALSE; -} - -static void -gst_video_crop_init (GstVideoCrop * vcrop, GstVideoCropClass * klass) -{ - vcrop->crop_right = 0; - vcrop->crop_left = 0; - vcrop->crop_top = 0; - vcrop->crop_bottom = 0; - vcrop->noop = TRUE; - GST_BASE_TRANSFORM (vcrop)->passthrough = vcrop->noop; -} - -static gboolean -gst_video_crop_get_image_details_from_caps (GstVideoCrop * vcrop, - GstVideoCropImageDetails * details, GstCaps * caps) -{ - GstStructure *structure; - gint width, height; - - structure = gst_caps_get_structure (caps, 0); - if (!gst_structure_get_int (structure, "width", &width) || - !gst_structure_get_int (structure, "height", &height)) { - goto incomplete_format; - } - - details->width = width; - details->height = height; - - if (gst_structure_has_name (structure, "video/x-raw-rgb")) { - gint bpp = 0; - - if (!gst_structure_get_int (structure, "bpp", &bpp) || (bpp & 0x07) != 0) - goto incomplete_format; - - details->packing = VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE; - details->bytes_per_pixel = bpp / 8; - details->stride = GST_ROUND_UP_4 (width * details->bytes_per_pixel); - details->size = details->stride * height; - } else if (gst_structure_has_name (structure, "video/x-raw-yuv")) { - guint32 format = 0; - - if (!gst_structure_get_fourcc (structure, "format", &format)) - goto incomplete_format; - - switch (format) { - case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'): - details->packing = VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE; - details->bytes_per_pixel = 4; - details->stride = GST_ROUND_UP_4 (width * 4); - details->size = details->stride * height; - break; - case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'): - case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): - case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'): - details->packing = VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX; - details->bytes_per_pixel = 2; - details->stride = GST_ROUND_UP_4 (width * 2); - details->size = details->stride * height; - if (format == GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y')) { - /* UYVY = 4:2:2 - [U0 Y0 V0 Y1] [U2 Y2 V2 Y3] [U4 Y4 V4 Y5] */ - details->macro_y_off = 1; - } else { - /* YUYV = 4:2:2 - [Y0 U0 Y1 V0] [Y2 U2 Y3 V2] [Y4 U4 Y5 V4] = YUY2 */ - details->macro_y_off = 0; - } - break; - case GST_MAKE_FOURCC ('Y', '8', '0', '0'): - details->packing = VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE; - details->bytes_per_pixel = 1; - details->stride = GST_ROUND_UP_4 (width); - details->size = details->stride * height; - break; - case GST_MAKE_FOURCC ('I', '4', '2', '0'): - case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):{ - details->packing = VIDEO_CROP_PIXEL_FORMAT_PLANAR; - - details->y_stride = GST_ROUND_UP_4 (width); - details->u_stride = GST_ROUND_UP_8 (width) / 2; - details->v_stride = GST_ROUND_UP_8 (width) / 2; - - /* I420 and YV12 have U/V planes swapped, but doesn't matter for us */ - details->y_off = 0; - details->u_off = 0 + details->y_stride * GST_ROUND_UP_2 (height); - details->v_off = details->u_off + - details->u_stride * (GST_ROUND_UP_2 (height) / 2); - details->size = details->v_off + - details->v_stride * (GST_ROUND_UP_2 (height) / 2); - break; - } - default: - goto unknown_format; - } - } else { - goto unknown_format; - } - - return TRUE; - - /* ERRORS */ -unknown_format: - { - GST_ELEMENT_ERROR (vcrop, STREAM, NOT_IMPLEMENTED, (NULL), - ("Unsupported format")); - return FALSE; - } - -incomplete_format: - { - GST_ELEMENT_ERROR (vcrop, CORE, NEGOTIATION, (NULL), - ("Incomplete caps, some required field is missing")); - return FALSE; - } -} - -static gboolean -gst_video_crop_get_unit_size (GstBaseTransform * trans, GstCaps * caps, - guint * size) -{ - GstVideoCropImageDetails img_details = { 0, }; - GstVideoCrop *vcrop = GST_VIDEO_CROP (trans); - - if (!gst_video_crop_get_image_details_from_caps (vcrop, &img_details, caps)) - return FALSE; - - *size = img_details.size; - return TRUE; -} - -#define ROUND_DOWN_2(n) ((n)&(~1)) - -static void -gst_video_crop_transform_packed_complex (GstVideoCrop * vcrop, - GstBuffer * inbuf, GstBuffer * outbuf) -{ - guint8 *in_data, *out_data; - guint i, dx; - - in_data = GST_BUFFER_DATA (inbuf); - out_data = GST_BUFFER_DATA (outbuf); - - in_data += vcrop->crop_top * vcrop->in.stride; - - /* rounding down here so we end up at the start of a macro-pixel and not - * in the middle of one */ - in_data += ROUND_DOWN_2 (vcrop->crop_left) * vcrop->in.bytes_per_pixel; - - dx = vcrop->out.width * vcrop->out.bytes_per_pixel; - - /* UYVY = 4:2:2 - [U0 Y0 V0 Y1] [U2 Y2 V2 Y3] [U4 Y4 V4 Y5] - * YUYV = 4:2:2 - [Y0 U0 Y1 V0] [Y2 U2 Y3 V2] [Y4 U4 Y5 V4] = YUY2 */ - if ((vcrop->crop_left % 2) != 0) { - for (i = 0; i < vcrop->out.height; ++i) { - gint j; - - memcpy (out_data, in_data, dx); - - /* move just the Y samples one pixel to the left, don't worry about - * chroma shift */ - for (j = vcrop->in.macro_y_off; j < vcrop->out.stride - 2; j += 2) - out_data[j] = in_data[j + 2]; - - in_data += vcrop->in.stride; - out_data += vcrop->out.stride; - } - } else { - for (i = 0; i < vcrop->out.height; ++i) { - memcpy (out_data, in_data, dx); - in_data += vcrop->in.stride; - out_data += vcrop->out.stride; - } - } -} - -static void -gst_video_crop_transform_packed_simple (GstVideoCrop * vcrop, - GstBuffer * inbuf, GstBuffer * outbuf) -{ - guint8 *in_data, *out_data; - guint i, dx; - - in_data = GST_BUFFER_DATA (inbuf); - out_data = GST_BUFFER_DATA (outbuf); - - in_data += vcrop->crop_top * vcrop->in.stride; - in_data += vcrop->crop_left * vcrop->in.bytes_per_pixel; - - dx = vcrop->out.width * vcrop->out.bytes_per_pixel; - - for (i = 0; i < vcrop->out.height; ++i) { - memcpy (out_data, in_data, dx); - in_data += vcrop->in.stride; - out_data += vcrop->out.stride; - } -} - -static void -gst_video_crop_transform_planar (GstVideoCrop * vcrop, GstBuffer * inbuf, - GstBuffer * outbuf) -{ - guint8 *y_out, *u_out, *v_out; - guint8 *y_in, *u_in, *v_in; - guint i, dx; - - /* Y plane */ - y_in = GST_BUFFER_DATA (inbuf); - y_out = GST_BUFFER_DATA (outbuf); - - y_in += (vcrop->crop_top * vcrop->in.y_stride) + vcrop->crop_left; - dx = vcrop->out.width * 1; - - for (i = 0; i < vcrop->out.height; ++i) { - memcpy (y_out, y_in, dx); - y_in += vcrop->in.y_stride; - y_out += vcrop->out.y_stride; - } - - /* U + V planes */ - u_in = GST_BUFFER_DATA (inbuf) + vcrop->in.u_off; - u_out = GST_BUFFER_DATA (outbuf) + vcrop->out.u_off; - - u_in += (vcrop->crop_top / 2) * vcrop->in.u_stride; - u_in += vcrop->crop_left / 2; - - v_in = GST_BUFFER_DATA (inbuf) + vcrop->in.v_off; - v_out = GST_BUFFER_DATA (outbuf) + vcrop->out.v_off; - - v_in += (vcrop->crop_top / 2) * vcrop->in.v_stride; - v_in += vcrop->crop_left / 2; - - dx = GST_ROUND_UP_2 (vcrop->out.width) / 2; - - for (i = 0; i < GST_ROUND_UP_2 (vcrop->out.height) / 2; ++i) { - memcpy (u_out, u_in, dx); - memcpy (v_out, v_in, dx); - u_in += vcrop->in.u_stride; - u_out += vcrop->out.u_stride; - v_in += vcrop->in.v_stride; - v_out += vcrop->out.v_stride; - } -} - -static GstFlowReturn -gst_video_crop_transform (GstBaseTransform * trans, GstBuffer * inbuf, - GstBuffer * outbuf) -{ - GstVideoCrop *vcrop = GST_VIDEO_CROP (trans); - - /* we should be operating in passthrough mode if there's nothing to do */ - g_assert (vcrop->noop == FALSE); - - GST_OBJECT_LOCK (vcrop); - - if (G_UNLIKELY ((vcrop->crop_left + vcrop->crop_right) >= vcrop->in.width || - (vcrop->crop_top + vcrop->crop_bottom) >= vcrop->in.height)) { - GST_OBJECT_UNLOCK (vcrop); - goto cropping_too_much; - } - - switch (vcrop->in.packing) { - case VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE: - gst_video_crop_transform_packed_simple (vcrop, inbuf, outbuf); - break; - case VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX: - gst_video_crop_transform_packed_complex (vcrop, inbuf, outbuf); - break; - case VIDEO_CROP_PIXEL_FORMAT_PLANAR: - gst_video_crop_transform_planar (vcrop, inbuf, outbuf); - break; - default: - g_assert_not_reached (); - } - - GST_OBJECT_UNLOCK (vcrop); - - return GST_FLOW_OK; - -cropping_too_much: - { - /* is there a better error code for this? */ - GST_ELEMENT_ERROR (vcrop, LIBRARY, SETTINGS, (NULL), - ("Can't crop more pixels than there are")); - return GST_FLOW_ERROR; - } -} - -static gint -gst_video_crop_transform_dimension (gint val, gint delta) -{ - gint64 new_val = (gint64) val + (gint64) delta; - - new_val = CLAMP (new_val, 1, G_MAXINT); - - return (gint) new_val; -} - -static gboolean -gst_video_crop_transform_dimension_value (const GValue * src_val, - gint delta, GValue * dest_val) -{ - gboolean ret = TRUE; - - g_value_init (dest_val, G_VALUE_TYPE (src_val)); - - if (G_VALUE_HOLDS_INT (src_val)) { - gint ival = g_value_get_int (src_val); - - ival = gst_video_crop_transform_dimension (ival, delta); - g_value_set_int (dest_val, ival); - } else if (GST_VALUE_HOLDS_INT_RANGE (src_val)) { - gint min = gst_value_get_int_range_min (src_val); - gint max = gst_value_get_int_range_max (src_val); - - min = gst_video_crop_transform_dimension (min, delta); - max = gst_video_crop_transform_dimension (max, delta); - gst_value_set_int_range (dest_val, min, max); - } else if (GST_VALUE_HOLDS_LIST (src_val)) { - gint i; - - for (i = 0; i < gst_value_list_get_size (src_val); ++i) { - const GValue *list_val; - GValue newval = { 0, }; - - list_val = gst_value_list_get_value (src_val, i); - if (gst_video_crop_transform_dimension_value (list_val, delta, &newval)) - gst_value_list_append_value (dest_val, &newval); - g_value_unset (&newval); - } - - if (gst_value_list_get_size (dest_val) == 0) { - g_value_unset (dest_val); - ret = FALSE; - } - } else { - g_value_unset (dest_val); - ret = FALSE; - } - - return ret; -} - -static GstCaps * -gst_video_crop_transform_caps (GstBaseTransform * trans, - GstPadDirection direction, GstCaps * caps) -{ - GstVideoCrop *vcrop; - GstCaps *other_caps; - gint dy, dx, i; - - vcrop = GST_VIDEO_CROP (trans); - - GST_OBJECT_LOCK (vcrop); - - GST_LOG_OBJECT (vcrop, "l=%d,r=%d,b=%d,t=%d noop=%d", - vcrop->crop_left, vcrop->crop_right, vcrop->crop_bottom, - vcrop->crop_top, vcrop->noop); - - if (vcrop->noop) { - GST_OBJECT_UNLOCK (vcrop); - return gst_caps_ref (caps); - } - - if (direction == GST_PAD_SRC) { - dx = vcrop->crop_left + vcrop->crop_right; - dy = vcrop->crop_top + vcrop->crop_bottom; - } else { - dx = 0 - (vcrop->crop_left + vcrop->crop_right); - dy = 0 - (vcrop->crop_top + vcrop->crop_bottom); - } - GST_OBJECT_UNLOCK (vcrop); - - GST_LOG_OBJECT (vcrop, "transforming caps %" GST_PTR_FORMAT, caps); - - other_caps = gst_caps_new_empty (); - - for (i = 0; i < gst_caps_get_size (caps); ++i) { - const GValue *v; - GstStructure *structure, *new_structure; - GValue w_val = { 0, }, h_val = { - 0,}; - - structure = gst_caps_get_structure (caps, i); - - v = gst_structure_get_value (structure, "width"); - if (!gst_video_crop_transform_dimension_value (v, dx, &w_val)) { - GST_WARNING_OBJECT (vcrop, "could not tranform width value with dx=%d" - ", caps structure=%" GST_PTR_FORMAT, dx, structure); - continue; - } - - v = gst_structure_get_value (structure, "height"); - if (!gst_video_crop_transform_dimension_value (v, dy, &h_val)) { - g_value_unset (&w_val); - GST_WARNING_OBJECT (vcrop, "could not tranform height value with dy=%d" - ", caps structure=%" GST_PTR_FORMAT, dy, structure); - continue; - } - - new_structure = gst_structure_copy (structure); - gst_structure_set_value (new_structure, "width", &w_val); - gst_structure_set_value (new_structure, "height", &h_val); - g_value_unset (&w_val); - g_value_unset (&h_val); - GST_LOG_OBJECT (vcrop, "transformed structure %2d: %" GST_PTR_FORMAT - " => %" GST_PTR_FORMAT, i, structure, new_structure); - gst_caps_append_structure (other_caps, new_structure); - } - - if (gst_caps_is_empty (other_caps)) { - gst_caps_unref (other_caps); - other_caps = NULL; - } - - return other_caps; -} - -static gboolean -gst_video_crop_set_caps (GstBaseTransform * trans, GstCaps * incaps, - GstCaps * outcaps) -{ - GstVideoCrop *crop = GST_VIDEO_CROP (trans); - - if (!gst_video_crop_get_image_details_from_caps (crop, &crop->in, incaps)) { - GST_DEBUG_OBJECT (crop, "failed to parse input caps %" GST_PTR_FORMAT, - incaps); - return FALSE; - } - - if (!gst_video_crop_get_image_details_from_caps (crop, &crop->out, outcaps)) { - GST_DEBUG_OBJECT (crop, "failed to parse output caps %" GST_PTR_FORMAT, - outcaps); - return FALSE; - } - - GST_LOG_OBJECT (crop, "incaps = %" GST_PTR_FORMAT ", outcaps = %" - GST_PTR_FORMAT, incaps, outcaps); - - return TRUE; -} - -/* This is extremely hackish, but the only way to force basetransform to - * renegotiated at the moment. There should really be a basetransform - * function for this */ -static void -gst_videocrop_clear_negotiated_caps_locked (GstVideoCrop * crop) -{ - GST_LOG_OBJECT (crop, "clearing negotiated caps"); - GST_BASE_TRANSFORM (crop)->negotiated = FALSE; - gst_caps_replace (&GST_PAD_CAPS (GST_BASE_TRANSFORM (crop)->srcpad), NULL); - gst_caps_replace (&GST_PAD_CAPS (GST_BASE_TRANSFORM (crop)->sinkpad), NULL); - gst_caps_replace (&GST_BASE_TRANSFORM (crop)->cache_caps1, NULL); - GST_BASE_TRANSFORM (crop)->cache_caps1_size = 0; - gst_caps_replace (&GST_BASE_TRANSFORM (crop)->cache_caps2, NULL); - GST_BASE_TRANSFORM (crop)->cache_caps2_size = 0; - GST_LOG_OBJECT (crop, "clearing caps done"); -} - -static void -gst_video_crop_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVideoCrop *video_crop; - - video_crop = GST_VIDEO_CROP (object); - - GST_OBJECT_LOCK (video_crop); - switch (prop_id) { - case ARG_LEFT: - video_crop->crop_left = g_value_get_int (value); - break; - case ARG_RIGHT: - video_crop->crop_right = g_value_get_int (value); - break; - case ARG_TOP: - video_crop->crop_top = g_value_get_int (value); - break; - case ARG_BOTTOM: - video_crop->crop_bottom = g_value_get_int (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - - video_crop->noop = ((video_crop->crop_left | video_crop->crop_right | - video_crop->crop_top | video_crop->crop_bottom) == 0); - - GST_LOG_OBJECT (video_crop, "l=%d,r=%d,b=%d,t=%d noop=%d", - video_crop->crop_left, video_crop->crop_right, video_crop->crop_bottom, - video_crop->crop_top, video_crop->noop); - - GST_BASE_TRANSFORM (video_crop)->passthrough = video_crop->noop; - gst_videocrop_clear_negotiated_caps_locked (video_crop); - GST_OBJECT_UNLOCK (video_crop); -} - -static void -gst_video_crop_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstVideoCrop *video_crop; - - video_crop = GST_VIDEO_CROP (object); - - GST_OBJECT_LOCK (video_crop); - switch (prop_id) { - case ARG_LEFT: - g_value_set_int (value, video_crop->crop_left); - break; - case ARG_RIGHT: - g_value_set_int (value, video_crop->crop_right); - break; - case ARG_TOP: - g_value_set_int (value, video_crop->crop_top); - break; - case ARG_BOTTOM: - g_value_set_int (value, video_crop->crop_bottom); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - GST_OBJECT_UNLOCK (video_crop); -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - GST_DEBUG_CATEGORY_INIT (videocrop_debug, "videocrop", 0, "videocrop"); - - return gst_element_register (plugin, "videocrop", GST_RANK_NONE, - GST_TYPE_VIDEO_CROP); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "videocrop", - "Crops video into a user-defined region", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/gst/videocrop/gstvideocrop.h b/gst/videocrop/gstvideocrop.h deleted file mode 100644 index 0075997f02..0000000000 --- a/gst/videocrop/gstvideocrop.h +++ /dev/null @@ -1,92 +0,0 @@ -/* GStreamer video frame cropping - * Copyright (C) 2006 Tim-Philipp Müller - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_VIDEO_CROP_H__ -#define __GST_VIDEO_CROP_H__ - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_VIDEO_CROP \ - (gst_video_crop_get_type()) -#define GST_VIDEO_CROP(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VIDEO_CROP,GstVideoCrop)) -#define GST_VIDEO_CROP_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VIDEO_CROP,GstVideoCropClass)) -#define GST_IS_VIDEO_CROP(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VIDEO_CROP)) -#define GST_IS_VIDEO_CROP_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEO_CROP)) - -typedef enum { - VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE = 0, /* RGBx, AYUV */ - VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX, /* UYVY, YVYU */ - VIDEO_CROP_PIXEL_FORMAT_PLANAR /* I420, YV12 */ -} VideoCropPixelFormat; - -typedef struct _GstVideoCropImageDetails GstVideoCropImageDetails; -struct _GstVideoCropImageDetails -{ - /*< private >*/ - VideoCropPixelFormat packing; - - guint width; - guint height; - guint size; - - /* for packed RGB and YUV */ - guint stride; - guint bytes_per_pixel; - guint8 macro_y_off; /* for YUY2, YVYU, UYVY, Y offset within macropixel in bytes */ - - /* for planar YUV */ - guint y_stride, y_off; - guint u_stride, u_off; - guint v_stride, v_off; -}; - -typedef struct _GstVideoCrop GstVideoCrop; -typedef struct _GstVideoCropClass GstVideoCropClass; - -struct _GstVideoCrop -{ - GstBaseTransform basetransform; - - /*< private >*/ - gboolean noop; /* TRUE if crop_left,_right,_top and _bottom are all 0 */ - - gint crop_left; - gint crop_right; - gint crop_top; - gint crop_bottom; - - GstVideoCropImageDetails in; /* details of input image */ - GstVideoCropImageDetails out; /* details of output image */ -}; - -struct _GstVideoCropClass -{ - GstBaseTransformClass basetransform_class; -}; - -G_END_DECLS - -#endif /* __GST_VIDEO_CROP_H__ */ - diff --git a/gst/videocrop/videocrop.vcproj b/gst/videocrop/videocrop.vcproj deleted file mode 100644 index aa81b92559..0000000000 --- a/gst/videocrop/videocrop.vcproj +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sys/Makefile.am b/sys/Makefile.am index 468b7b706b..3866499c89 100644 --- a/sys/Makefile.am +++ b/sys/Makefile.am @@ -34,12 +34,6 @@ else DVB_DIR= endif -if USE_OSX_VIDEO -OSX_VIDEO_DIR=osxvideo -else -OSX_VIDEO_DIR= -endif +SUBDIRS = $(GL_DIR) $(DVB_DIR) -SUBDIRS = $(GL_DIR) $(DVB_DIR) $(OSX_VIDEO_DIR) - -DIST_SUBDIRS = glsink dvb osxvideo +DIST_SUBDIRS = glsink dvb diff --git a/sys/osxvideo/Makefile.am b/sys/osxvideo/Makefile.am deleted file mode 100644 index 99bb048990..0000000000 --- a/sys/osxvideo/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -# FIXME: clean up this crap -OBJC=gcc - -plugin_LTLIBRARIES = libgstosxvideosink.la - -libgstosxvideosink_la_SOURCES = osxvideosink.m cocoawindow.m -libgstosxvideosink_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \ - $(GST_PLUGINS_BASE_CFLAGS) -libgstosxvideosink_la_LIBADD = \ - $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) \ - -lgstinterfaces-$(GST_MAJORMINOR) - -libgstosxvideosink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -Wl,-framework -Wl,Cocoa -Wl,-framework -Wl,QuickTime -Wl,-framework -Wl,OpenGL - -AM_OBJCFLAGS=$(CFLAGS) $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) - -noinst_HEADERS = osxvideosink.h cocoawindow.h diff --git a/sys/osxvideo/cocoawindow.h b/sys/osxvideo/cocoawindow.h deleted file mode 100644 index 340bd160fb..0000000000 --- a/sys/osxvideo/cocoawindow.h +++ /dev/null @@ -1,70 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Zaheer Abbas Merali - * Copyright (C) 2007 Pioneers of the Inevitable - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * The development of this code was made possible due to the involvement of Pioneers - * of the Inevitable, the creators of the Songbird Music player - * - */ - -/* inspiration gained from looking at source of osx video out of xine and vlc - * and is reflected in the code - */ - -#import -#import -#import - -struct _GstOSXImage; - -@interface GstGLView : NSOpenGLView -{ - int i_effect; - unsigned long pi_texture; - float f_x; - float f_y; - int initDone; - char* data; - int width, height; - BOOL fullscreen; - NSOpenGLContext* fullScreenContext; - NSOpenGLContext* actualContext; -} -- (void) drawQuad; -- (void) drawRect: (NSRect) rect; -- (id) initWithFrame: (NSRect) frame; -- (void) initTextures; -- (void) reloadTexture; -- (void) cleanUp; -- (void) displayTexture; -- (char*) getTextureBuffer; -- (void) setFullScreen: (BOOL) flag; -- (void) reshape; -- (void) setVideoSize: (int) w: (int) h; - -@end - -@interface GstOSXVideoSinkWindow: NSWindow { - int width, height; - GstGLView *gstview; -} - -- (void) setContentSize: (NSSize) size; -- (GstGLView *) gstView; -- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag screen:(NSScreen *)aScreen; -@end diff --git a/sys/osxvideo/cocoawindow.m b/sys/osxvideo/cocoawindow.m deleted file mode 100644 index 9b5e7b311b..0000000000 --- a/sys/osxvideo/cocoawindow.m +++ /dev/null @@ -1,400 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Zaheer Abbas Merali - * Copyright (C) 2007 Pioneers of the Inevitable - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * The development of this code was made possible due to the involvement of Pioneers - * of the Inevitable, the creators of the Songbird Music player - * - */ - -/* inspiration gained from looking at source of osx video out of xine and vlc - * and is reflected in the code - */ - - -#include -#include -#import "cocoawindow.h" -#import "osxvideosink.h" - -#include -#include -#include - -/* Debugging category */ -#include - -@ implementation GstOSXVideoSinkWindow - -/* The object has to be released */ -- (id) initWithContentRect: (NSRect) rect - styleMask: (unsigned int) styleMask - backing: (NSBackingStoreType) bufferingType - defer: (BOOL) flag - screen:(NSScreen *) aScreen -{ - self = [super initWithContentRect: rect - styleMask: styleMask - backing: bufferingType - defer: flag - screen:aScreen]; - - GST_DEBUG ("Initializing GstOSXvideoSinkWindow"); - - gstview = [[GstGLView alloc] initWithFrame:rect]; - - if (gstview) - [self setContentView:gstview]; - [self setTitle:@"GStreamer Video Output"]; - - return self; -} - -- (void) setContentSize:(NSSize) size { - width = size.width; - height = size.height; - - [gstview setVideoSize: (int) width:(int) height]; - - [super setContentSize:size]; -} - -- (GstGLView *) gstView { - return gstview; -} - -- (void) awakeFromNib { - [self setAcceptsMouseMovedEvents:YES]; -} - -- (void) sendEvent:(NSEvent *) event { - BOOL taken = NO; - - GST_DEBUG ("event %p type:%d", event,[event type]); - - if ([event type] == NSKeyDown) { - } - /*taken = [gstview keyDown:event]; */ - - if (!taken) { - [super sendEvent:event]; - } -} - - -@end - - -// -// OpenGL implementation -// - -@ implementation GstGLView - -- (id) initWithFrame:(NSRect) frame { - NSOpenGLPixelFormat *fmt; - NSOpenGLPixelFormatAttribute attribs[] = { - NSOpenGLPFAAccelerated, - NSOpenGLPFANoRecovery, - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAColorSize, 24, - NSOpenGLPFAAlphaSize, 8, - NSOpenGLPFADepthSize, 24, - NSOpenGLPFAWindow, - 0 - }; - - fmt = [[NSOpenGLPixelFormat alloc] - initWithAttributes:attribs]; - - if (!fmt) { - GST_WARNING ("Cannot create NSOpenGLPixelFormat"); - return nil; - } - - self = [super initWithFrame: frame pixelFormat:fmt]; - - actualContext = [self openGLContext]; - [actualContext makeCurrentContext]; - [actualContext update]; - - /* Black background */ - glClearColor (0.0, 0.0, 0.0, 0.0); - - pi_texture = 0; - data = nil; - width = frame.size.width; - height = frame.size.height; - - GST_LOG ("Width: %d Height: %d", width, height); - - [self initTextures]; - return self; -} - -- (void) reshape { - NSRect bounds; - - GST_LOG ("reshaping"); - - if (!initDone) { - return; - } - - [actualContext makeCurrentContext]; - - bounds = [self bounds]; - - glViewport (0, 0, (GLint) bounds.size.width, (GLint) bounds.size.height); - -} - -- (void) initTextures { - - [actualContext makeCurrentContext]; - - /* Free previous texture if any */ - if (pi_texture) { - glDeleteTextures (1, &pi_texture); - } - - if (data) { - data = g_realloc (data, width * height * sizeof(short)); // short or 3byte? - } else { - data = g_malloc0(width * height * sizeof(short)); - } - /* Create textures */ - glGenTextures (1, &pi_texture); - - glEnable (GL_TEXTURE_RECTANGLE_EXT); - glEnable (GL_UNPACK_CLIENT_STORAGE_APPLE); - - glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - glPixelStorei (GL_UNPACK_ROW_LENGTH, width); - - glBindTexture (GL_TEXTURE_RECTANGLE_EXT, pi_texture); - - /* Use VRAM texturing */ - glTexParameteri (GL_TEXTURE_RECTANGLE_EXT, - GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE); - - /* Tell the driver not to make a copy of the texture but to use - our buffer */ - glPixelStorei (GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); - - /* Linear interpolation */ - glTexParameteri (GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - /* I have no idea what this exactly does, but it seems to be - necessary for scaling */ - glTexParameteri (GL_TEXTURE_RECTANGLE_EXT, - GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (GL_TEXTURE_RECTANGLE_EXT, - GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - // glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); WHY ?? - - glTexImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, - width, height, 0, - GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, data); - - - initDone = 1; -} - -- (void) reloadTexture { - if (!initDone) { - return; - } - - GST_LOG ("Reloading Texture"); - - [actualContext makeCurrentContext]; - - glBindTexture (GL_TEXTURE_RECTANGLE_EXT, pi_texture); - glPixelStorei (GL_UNPACK_ROW_LENGTH, width); - - /* glTexSubImage2D is faster than glTexImage2D - http://developer.apple.com/samplecode/Sample_Code/Graphics_3D/ - TextureRange/MainOpenGLView.m.htm */ - glTexSubImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, - width, height, - GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, data); //FIXME -} - -- (void) cleanUp { - initDone = 0; -} - -- (void) drawQuad { - f_x = 1.0; - f_y = 1.0; - - glBegin (GL_QUADS); - /* Top left */ - glTexCoord2f (0.0, 0.0); - glVertex2f (-f_x, f_y); - /* Bottom left */ - glTexCoord2f (0.0, (float) height); - glVertex2f (-f_x, -f_y); - /* Bottom right */ - glTexCoord2f ((float) width, (float) height); - glVertex2f (f_x, -f_y); - /* Top right */ - glTexCoord2f ((float) width, 0.0); - glVertex2f (f_x, f_y); - glEnd (); -} - -- (void) drawRect:(NSRect) rect { - long params[] = { 1 }; - - [actualContext makeCurrentContext]; - - CGLSetParameter (CGLGetCurrentContext (), kCGLCPSwapInterval, params); - - /* Black background */ - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (!initDone) { - [actualContext flushBuffer]; - return; - } - - /* Draw */ - glBindTexture (GL_TEXTURE_RECTANGLE_EXT, pi_texture); // FIXME - [self drawQuad]; - /* Draw */ - [actualContext flushBuffer]; -} - -- (void) displayTexture { - if ([self lockFocusIfCanDraw]) { - - [self drawRect:[self bounds]]; - [self reloadTexture]; - - [self unlockFocus]; - - } - -} - -- (char *) getTextureBuffer { - return data; -} - -- (void) setFullScreen:(BOOL) flag { - if (!fullscreen && flag) { - // go to full screen - /* Create the new pixel format */ - NSOpenGLPixelFormat *fmt; - NSOpenGLPixelFormatAttribute attribs[] = { - NSOpenGLPFAAccelerated, - NSOpenGLPFANoRecovery, - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAColorSize, 24, - NSOpenGLPFAAlphaSize, 8, - NSOpenGLPFADepthSize, 24, - NSOpenGLPFAFullScreen, - NSOpenGLPFAScreenMask, - CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay), - 0 - }; - - fmt = [[NSOpenGLPixelFormat alloc] - initWithAttributes:attribs]; - - if (!fmt) { - GST_WARNING ("Cannot create NSOpenGLPixelFormat"); - return; - } - - /* Create the new OpenGL context */ - fullScreenContext = [[NSOpenGLContext alloc] - initWithFormat: fmt shareContext:nil]; - if (!fullScreenContext) { - GST_WARNING ("Failed to create new NSOpenGLContext"); - return; - } - - actualContext = fullScreenContext; - - /* Capture display, switch to fullscreen */ - if (CGCaptureAllDisplays () != CGDisplayNoErr) { - GST_WARNING ("CGCaptureAllDisplays() failed"); - return; - } - [fullScreenContext setFullScreen]; - [fullScreenContext makeCurrentContext]; - - fullscreen = YES; - - [self initTextures]; - [self setNeedsDisplay:YES]; - - } else if (fullscreen && !flag) { - // fullscreen now and needs to go back to normal - initDone = NO; - - actualContext = [self openGLContext]; - - [NSOpenGLContext clearCurrentContext]; - [fullScreenContext clearDrawable]; - [fullScreenContext release]; - fullScreenContext = nil; - - CGReleaseAllDisplays (); - - [self reshape]; - [self initTextures]; - - [self setNeedsDisplay:YES]; - - fullscreen = NO; - initDone = YES; - } -} - -- (void) setVideoSize: (int) w:(int) h { - GST_LOG ("width:%d, height:%d", w, h); - - width = w; - height = h; - -// if (data) g_free(data); - -// data = g_malloc0 (2 * w * h); - [self initTextures]; -} - -- (void) dealloc { - GST_LOG ("dealloc called"); - if (data) g_free(data); - - if (fullScreenContext) { - [NSOpenGLContext clearCurrentContext]; - [fullScreenContext clearDrawable]; - [fullScreenContext release]; - if (actualContext == fullScreenContext) actualContext = nil; - fullScreenContext = nil; - } - - [super dealloc]; -} -@end diff --git a/sys/osxvideo/osxvideosink.h b/sys/osxvideo/osxvideosink.h deleted file mode 100644 index d7fba96655..0000000000 --- a/sys/osxvideo/osxvideosink.h +++ /dev/null @@ -1,107 +0,0 @@ -/* GStreamer - * Copyright (C) 2004-6 Zaheer Abbas Merali - * Copyright (C) 2007 Pioneers of the Inevitable - * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * - * The development of this code was made possible due to the involvement of Pioneers - * of the Inevitable, the creators of the Songbird Music player - * - */ - -#ifndef __GST_OSX_VIDEO_SINK_H__ -#define __GST_OSX_VIDEO_SINK_H__ - -#include - -#include -#include -#include - -#include -#import "cocoawindow.h" - -GST_DEBUG_CATEGORY_EXTERN (gst_debug_osx_video_sink); -#define GST_CAT_DEFAULT gst_debug_osx_video_sink - -G_BEGIN_DECLS - -#define GST_TYPE_OSX_VIDEO_SINK \ - (gst_osx_video_sink_get_type()) -#define GST_OSX_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_OSX_VIDEO_SINK, GstOSXVideoSink)) -#define GST_OSX_VIDEO_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_OSX_VIDEO_SINK, GstOSXVideoSinkClass)) -#define GST_IS_OSX_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_OSX_VIDEO_SINK)) -#define GST_IS_OSX_VIDEO_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_OSX_VIDEO_SINK)) - -typedef struct _GstOSXWindow GstOSXWindow; - -typedef struct _GstOSXVideoSink GstOSXVideoSink; -typedef struct _GstOSXVideoSinkClass GstOSXVideoSinkClass; - -#define GST_TYPE_OSXVIDEOBUFFER (gst_osxvideobuffer_get_type()) - -/* OSXWindow stuff */ -struct _GstOSXWindow { - gint width, height; - gboolean internal; - GstOSXVideoSinkWindow* win; - GstGLView* gstview; - NSAutoreleasePool *pool; -}; - -struct _GstOSXVideoSink { - /* Our element stuff */ - GstVideoSink videosink; - GstOSXWindow *osxwindow; - - gint fps_n; - gint fps_d; - - /* Unused */ - gint pixel_width, pixel_height; - - GstClockTime time; - - gboolean embed; - gboolean fullscreen; - gboolean sw_scaling_failed; -}; - -struct _GstOSXVideoSinkClass { - GstVideoSinkClass parent_class; -}; - -GType gst_osx_video_sink_get_type(void); - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 -@interface NSApplication(AppleMenu) -- (void)setAppleMenu:(NSMenu *)menu; -@end -#endif - -@interface GstAppDelegate : NSObject -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; -@end - -G_END_DECLS - -#endif /* __GST_OSX_VIDEO_SINK_H__ */ diff --git a/sys/osxvideo/osxvideosink.m b/sys/osxvideo/osxvideosink.m deleted file mode 100644 index 2bb0447bb2..0000000000 --- a/sys/osxvideo/osxvideosink.m +++ /dev/null @@ -1,665 +0,0 @@ -/* GStreamer - * OSX video sink - * Copyright (C) 2004-6 Zaheer Abbas Merali - * Copyright (C) 2007 Pioneers of the Inevitable - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * The development of this code was made possible due to the involvement of - * Pioneers of the Inevitable, the creators of the Songbird Music player. - * - */ - -/** - * SECTION:element-osxvideosink - * - * - * - * The OSXVideoSink renders video frames to a MacOSX window. The video output - * can be directed to a window embedded in an existing NSApp. This can be done - * by setting the "embed" property to #TRUE. When the NSView to be embedded is - * created an element #GstMessage with a name of 'have-ns-view' will be created - * and posted on the bus. The pointer to the NSView to embed will be in the - * 'nsview' field of that message. If no embedding is requested, the plugin will - * create a standalone window. - * - * Examples - * - * Simple timeline to test the sink : - * - * gst-launch-0.10 -v videotestsrc ! osxvideosink - * - * - * - */ - -#include "config.h" - -/* Object header */ -#include "osxvideosink.h" -#include -#import "cocoawindow.h" - -/* Debugging category */ -GST_DEBUG_CATEGORY (gst_debug_osx_video_sink); -#define GST_CAT_DEFAULT gst_debug_osx_video_sink - -/* ElementFactory information */ -static const GstElementDetails gst_osx_video_sink_details = -GST_ELEMENT_DETAILS ("OSX Video sink", - "Sink/Video", - "OSX native videosink", - "Zaheer Abbas Merali "); - -/* Default template - initiated with class struct to allow gst-register to work - without X running */ -static GstStaticPadTemplate gst_osx_video_sink_sink_template_factory = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-raw-yuv, " - "framerate = (fraction) [ 0, MAX ], " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ], " -#if G_BYTE_ORDER == G_BIG_ENDIAN - "format = (fourcc) YUY2") -#else - "format = (fourcc) UYVY") -#endif - ); - -// much of the following cocoa NSApp code comes from libsdl and libcaca -@implementation NSApplication(Gst) -- (void)setRunning -{ - _running = 1; -} -@end - -@implementation GstAppDelegate : NSObject -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender -{ - // destroy stuff here! - GST_DEBUG("Kill me please!"); - return NSTerminateNow; -} -@end - - -enum -{ - ARG_0, - ARG_EMBED, - ARG_FULLSCREEN - /* FILL ME */ -}; - -static GstVideoSinkClass *parent_class = NULL; - - -/* cocoa event loop - needed if not run in own app */ -gint -cocoa_event_loop (GstOSXVideoSink * vsink) -{ - NSAutoreleasePool *pool; - gboolean ret = TRUE; - - GST_DEBUG_OBJECT (vsink, "Entering event loop"); - - pool = [[NSAutoreleasePool alloc] init]; - - if ([NSApp isRunning]) { - NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate distantPast] - inMode:NSDefaultRunLoopMode dequeue:YES ]; - if ( event != nil ) { - switch ([event type]) { - default: //XXX Feed me please - [NSApp sendEvent:event]; - break; - } - } - } - - [pool release]; - - GST_DEBUG_OBJECT (vsink, "Leaving event loop with ret : %d", ret); - - return ret; -} - -static NSString * -GetApplicationName(void) -{ - NSDictionary *dict; - NSString *appName = 0; - - /* Determine the application name */ - dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); - if (dict) - appName = [dict objectForKey: @"CFBundleName"]; - - if (![appName length]) - appName = [[NSProcessInfo processInfo] processName]; - - return appName; -} - -static void -CreateApplicationMenus(void) -{ - NSString *appName; - NSString *title; - NSMenu *appleMenu; - NSMenu *windowMenu; - NSMenuItem *menuItem; - - /* Create the main menu bar */ - [NSApp setMainMenu:[[NSMenu alloc] init]]; - - /* Create the application menu */ - appName = GetApplicationName(); - appleMenu = [[NSMenu alloc] initWithTitle:@""]; - - /* Add menu items */ - title = [@"About " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@/*"h"*/""]; - - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@/*"h"*/""]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - - [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@/*"q"*/""]; - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:appleMenu]; - [[NSApp mainMenu] addItem:menuItem]; - [menuItem release]; - - /* Tell the application object that this is now the application menu */ - [NSApp setAppleMenu:appleMenu]; - [appleMenu release]; - - - /* Create the window menu */ - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@/*"m"*/""]; - [windowMenu addItem:menuItem]; - [menuItem release]; - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:windowMenu]; - [[NSApp mainMenu] addItem:menuItem]; - [menuItem release]; - - /* Tell the application object that this is now the window menu */ - [NSApp setWindowsMenu:windowMenu]; - [windowMenu release]; -} - -/* This function handles osx window creation */ -static GstOSXWindow * -gst_osx_video_sink_osxwindow_new (GstOSXVideoSink * osxvideosink, gint width, - gint height) -{ - NSRect rect; - - GstOSXWindow *osxwindow = NULL; - - g_return_val_if_fail (GST_IS_OSX_VIDEO_SINK (osxvideosink), NULL); - - osxwindow = g_new0 (GstOSXWindow, 1); - - osxwindow->width = width; - osxwindow->height = height; - osxwindow->internal = TRUE; - osxwindow->pool = [[NSAutoreleasePool alloc] init]; - - if (osxvideosink->embed == FALSE) { - ProcessSerialNumber psn; - unsigned int mask = NSTitledWindowMask | - NSClosableWindowMask | - NSResizableWindowMask | - NSTexturedBackgroundWindowMask | - NSMiniaturizableWindowMask; - - rect.origin.x = 100.0; - rect.origin.y = 100.0; - rect.size.width = (float) osxwindow->width; - rect.size.height = (float) osxwindow->height; - - if (!GetCurrentProcess(&psn)) { - TransformProcessType(&psn, kProcessTransformToForegroundApplication); - SetFrontProcess(&psn); - } - - [NSApplication sharedApplication]; - - osxwindow->win =[[GstOSXVideoSinkWindow alloc] - initWithContentRect: rect - styleMask: mask - backing: NSBackingStoreBuffered - defer: NO - screen: nil]; - [osxwindow->win autorelease]; - [NSApplication sharedApplication]; - [osxwindow->win makeKeyAndOrderFront:NSApp]; - osxwindow->gstview =[osxwindow->win gstView]; - [osxwindow->gstview autorelease]; - if (osxvideosink->fullscreen) - [osxwindow->gstview setFullScreen:YES]; - - CreateApplicationMenus(); - - [NSApp finishLaunching]; - [NSApp setDelegate:[[GstAppDelegate alloc] init]]; - - [NSApp setRunning]; - // insert event dispatch in the glib main loop - g_idle_add ((GSourceFunc) cocoa_event_loop, osxvideosink); - } else { - GstStructure *s; - GstMessage *msg; - gchar * tmp; - /* Needs to be embedded */ - - rect.origin.x = 0.0; - rect.origin.y = 0.0; - rect.size.width = (float) osxwindow->width; - rect.size.height = (float) osxwindow->height; - osxwindow->gstview =[[GstGLView alloc] initWithFrame:rect]; - [osxwindow->gstview autorelease]; - - s = gst_structure_new ("have-ns-view", - "nsview", G_TYPE_POINTER, osxwindow->gstview, - nil); - - tmp = gst_structure_to_string (s); - GST_DEBUG_OBJECT (osxvideosink, "Sending message %s", - tmp); - g_free (tmp); - - msg = gst_message_new_element (GST_OBJECT (osxvideosink), s); - gst_element_post_message (GST_ELEMENT (osxvideosink), msg); - - GST_LOG_OBJECT (osxvideosink, "'have-ns-view' message sent"); - } - return osxwindow; -} - -/* This function destroys a GstXWindow */ -static void -gst_osx_video_sink_osxwindow_destroy (GstOSXVideoSink * osxvideosink, - GstOSXWindow * osxwindow) -{ - g_return_if_fail (osxwindow != NULL); - g_return_if_fail (GST_IS_OSX_VIDEO_SINK (osxvideosink)); - - [osxwindow->pool release]; - - g_free (osxwindow); -} - -/* This function resizes a GstXWindow */ -static void -gst_osx_video_sink_osxwindow_resize (GstOSXVideoSink * osxvideosink, - GstOSXWindow * osxwindow, guint width, guint height) -{ - NSSize size; - NSAutoreleasePool *subPool = [[NSAutoreleasePool alloc] init]; - g_return_if_fail (osxwindow != NULL); - g_return_if_fail (GST_IS_OSX_VIDEO_SINK (osxvideosink)); - - osxwindow->width = width; - osxwindow->height = height; - - size.width = width; - size.height = height; - /* Call relevant cocoa function to resize window */ - [osxwindow->win setContentSize:size]; - [subPool release]; -} - -static void -gst_osx_video_sink_osxwindow_clear (GstOSXVideoSink * osxvideosink, - GstOSXWindow * osxwindow) -{ - - g_return_if_fail (osxwindow != NULL); - g_return_if_fail (GST_IS_OSX_VIDEO_SINK (osxvideosink)); - -} - - -/* Element stuff */ -static gboolean -gst_osx_video_sink_setcaps (GstBaseSink * bsink, GstCaps * caps) -{ - GstOSXVideoSink *osxvideosink; - GstStructure *structure; - gboolean res, result = FALSE; - gint video_width, video_height; - const GValue *framerate; - - osxvideosink = GST_OSX_VIDEO_SINK (bsink); - - GST_DEBUG_OBJECT (osxvideosink, "caps: %" GST_PTR_FORMAT, caps); - - structure = gst_caps_get_structure (caps, 0); - res = gst_structure_get_int (structure, "width", &video_width); - res &= gst_structure_get_int (structure, "height", &video_height); - framerate = gst_structure_get_value (structure, "framerate"); - res &= (framerate != NULL); - - if (!res) { - goto beach; - } - - osxvideosink->fps_n = gst_value_get_fraction_numerator (framerate); - osxvideosink->fps_d = gst_value_get_fraction_denominator (framerate); - - GST_DEBUG_OBJECT (osxvideosink, "our format is: %dx%d video at %d/%d fps", - video_width, video_height, osxvideosink->fps_n, osxvideosink->fps_d); - - GST_VIDEO_SINK_WIDTH (osxvideosink) = video_width; - GST_VIDEO_SINK_HEIGHT (osxvideosink) = video_height; - - gst_osx_video_sink_osxwindow_resize (osxvideosink, osxvideosink->osxwindow, - video_width, video_height); - result = TRUE; - -beach: - return result; - -} - -static GstStateChangeReturn -gst_osx_video_sink_change_state (GstElement * element, - GstStateChange transition) -{ - GstOSXVideoSink *osxvideosink; - - osxvideosink = GST_OSX_VIDEO_SINK (element); - - GST_DEBUG_OBJECT (osxvideosink, "%s => %s", - gst_element_state_get_name(GST_STATE_TRANSITION_CURRENT (transition)), - gst_element_state_get_name(GST_STATE_TRANSITION_NEXT (transition))); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - /* Creating our window and our image */ - if (!osxvideosink->osxwindow) { - GST_VIDEO_SINK_WIDTH (osxvideosink) = 320; - GST_VIDEO_SINK_HEIGHT (osxvideosink) = 240; - osxvideosink->osxwindow = - gst_osx_video_sink_osxwindow_new (osxvideosink, - GST_VIDEO_SINK_WIDTH (osxvideosink), - GST_VIDEO_SINK_HEIGHT (osxvideosink)); - gst_osx_video_sink_osxwindow_clear (osxvideosink, - osxvideosink->osxwindow); - } else { - if (osxvideosink->osxwindow->internal) - gst_osx_video_sink_osxwindow_resize (osxvideosink, - osxvideosink->osxwindow, GST_VIDEO_SINK_WIDTH (osxvideosink), - GST_VIDEO_SINK_HEIGHT (osxvideosink)); - } - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - GST_DEBUG ("ready to paused"); - if (osxvideosink->osxwindow) - gst_osx_video_sink_osxwindow_clear (osxvideosink, - osxvideosink->osxwindow); - osxvideosink->time = 0; - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - break; - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - osxvideosink->fps_n = 0; - osxvideosink->fps_d = 0; - osxvideosink->sw_scaling_failed = FALSE; - GST_VIDEO_SINK_WIDTH (osxvideosink) = 0; - GST_VIDEO_SINK_HEIGHT (osxvideosink) = 0; - break; - case GST_STATE_CHANGE_READY_TO_NULL: - - if (osxvideosink->osxwindow) { - gst_osx_video_sink_osxwindow_destroy (osxvideosink, - osxvideosink->osxwindow); - osxvideosink->osxwindow = NULL; - } - break; - } - - return (GST_ELEMENT_CLASS (parent_class))->change_state (element, transition); - -} - -static GstFlowReturn -gst_osx_video_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) -{ - GstOSXVideoSink *osxvideosink; - - osxvideosink = GST_OSX_VIDEO_SINK (bsink); - - char *viewdata =[osxvideosink->osxwindow->gstview getTextureBuffer]; - - GST_DEBUG ("show_frame"); - memcpy (viewdata, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); - [osxvideosink->osxwindow->gstview displayTexture]; - - return GST_FLOW_OK; -} - -/* Buffer management */ - - - -/* =========================================== */ -/* */ -/* Init & Class init */ -/* */ -/* =========================================== */ - -static void -gst_osx_video_sink_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstOSXVideoSink *osxvideosink; - - g_return_if_fail (GST_IS_OSX_VIDEO_SINK (object)); - - osxvideosink = GST_OSX_VIDEO_SINK (object); - - switch (prop_id) { - case ARG_EMBED: - osxvideosink->embed = g_value_get_boolean (value); - break; - case ARG_FULLSCREEN: - osxvideosink->fullscreen = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_osx_video_sink_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstOSXVideoSink *osxvideosink; - - g_return_if_fail (GST_IS_OSX_VIDEO_SINK (object)); - - osxvideosink = GST_OSX_VIDEO_SINK (object); - - switch (prop_id) { - case ARG_EMBED: - g_value_set_boolean (value, osxvideosink->embed); - break; - case ARG_FULLSCREEN: - g_value_set_boolean (value, osxvideosink->fullscreen); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_osx_video_sink_init (GstOSXVideoSink * osxvideosink) -{ - - osxvideosink->osxwindow = NULL; - - osxvideosink->fps_n = 0; - osxvideosink->fps_d = 0; - - osxvideosink->pixel_width = osxvideosink->pixel_height = 1; - osxvideosink->sw_scaling_failed = FALSE; - osxvideosink->embed = FALSE; - osxvideosink->fullscreen = FALSE; - -} - -static void -gst_osx_video_sink_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_set_details (element_class, &gst_osx_video_sink_details); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_osx_video_sink_sink_template_factory)); -} - -static void -gst_osx_video_sink_class_init (GstOSXVideoSinkClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSinkClass *gstbasesink_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasesink_class = (GstBaseSinkClass *) klass; - - - parent_class = g_type_class_ref (GST_TYPE_VIDEO_SINK); - - gobject_class->set_property = gst_osx_video_sink_set_property; - gobject_class->get_property = gst_osx_video_sink_get_property; - - gstbasesink_class->set_caps = gst_osx_video_sink_setcaps; - gstbasesink_class->preroll = gst_osx_video_sink_show_frame; - gstbasesink_class->render = gst_osx_video_sink_show_frame; - gstelement_class->change_state = gst_osx_video_sink_change_state; - - /** - * GstOSXVideoSink:embed - * - * Set to #TRUE if you are embedding the video window in an application. - * - **/ - - g_object_class_install_property (gobject_class, ARG_EMBED, - g_param_spec_boolean ("embed", "embed", "When enabled, it " - "can be embedded", FALSE, G_PARAM_READWRITE)); - - /** - * GstOSXVideoSink:fullscreen - * - * Set to #TRUE to have the video displayed in fullscreen. - **/ - - g_object_class_install_property (gobject_class, ARG_FULLSCREEN, - g_param_spec_boolean ("fullscreen", "fullscreen", - "When enabled, the view " "is fullscreen", FALSE, - G_PARAM_READWRITE)); -} - -/* ============================================================= */ -/* */ -/* Public Methods */ -/* */ -/* ============================================================= */ - -/* =========================================== */ -/* */ -/* Object typing & Creation */ -/* */ -/* =========================================== */ - -GType -gst_osx_video_sink_get_type (void) -{ - static GType osxvideosink_type = 0; - - if (!osxvideosink_type) { - static const GTypeInfo osxvideosink_info = { - sizeof (GstOSXVideoSinkClass), - gst_osx_video_sink_base_init, - NULL, - (GClassInitFunc) gst_osx_video_sink_class_init, - NULL, - NULL, - sizeof (GstOSXVideoSink), - 0, - (GInstanceInitFunc) gst_osx_video_sink_init, - }; - - osxvideosink_type = g_type_register_static (GST_TYPE_VIDEO_SINK, - "GstOSXVideoSink", &osxvideosink_info, 0); - - } - - return osxvideosink_type; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - - if (!gst_element_register (plugin, "osxvideosink", - GST_RANK_PRIMARY, GST_TYPE_OSX_VIDEO_SINK)) - return FALSE; - - GST_DEBUG_CATEGORY_INIT (gst_debug_osx_video_sink, "osxvideosink", 0, - "osxvideosink element"); - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "osxvideo", - "OSX native video output plugin", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 6db6685054..3db85362d7 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -42,9 +42,7 @@ VALGRIND_TO_FIX = \ elements/mpeg2enc # valgrind testing -# videocrop disabled since it takes way too long in valgrind VALGRIND_TESTS_DISABLE = \ - elements/videocrop \ $(VALGRIND_TO_FIX) check_PROGRAMS = \ @@ -53,7 +51,6 @@ check_PROGRAMS = \ elements/rganalysis \ elements/rglimiter \ elements/rgvolume \ - elements/videocrop \ elements/y4menc TESTS = $(check_PROGRAMS) @@ -61,7 +58,3 @@ TESTS = $(check_PROGRAMS) AM_CFLAGS = $(GST_OBJ_CFLAGS) $(GST_CHECK_CFLAGS) $(CHECK_CFLAGS) LDADD = $(GST_OBJ_LIBS) $(GST_CHECK_LIBS) $(CHECK_LIBS) - -elements_videocrop_LDADD = $(LDADD) $(GST_BASE_LIBS) -elements_videocrop_CFLAGS = $(CFLAGS) $(AM_CFLAGS) $(GST_BASE_CFLAGS) - diff --git a/tests/check/elements/videocrop.c b/tests/check/elements/videocrop.c deleted file mode 100644 index 25cc00a960..0000000000 --- a/tests/check/elements/videocrop.c +++ /dev/null @@ -1,802 +0,0 @@ -/* GStreamer unit test for the videocrop element - * Copyright (C) 2006 Tim-Philipp Müller - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef HAVE_VALGRIND -# include -#endif - -#include - -#include -#include - -/* return a list of caps where we only need to set - * width and height to get fixed caps */ -static GList * -video_crop_get_test_caps (GstElement * videocrop) -{ - const GstCaps *allowed_caps; - GstPad *srcpad; - GList *list = NULL; - guint i; - - srcpad = gst_element_get_pad (videocrop, "src"); - fail_unless (srcpad != NULL); - allowed_caps = gst_pad_get_pad_template_caps (srcpad); - fail_unless (allowed_caps != NULL); - - for (i = 0; i < gst_caps_get_size (allowed_caps); ++i) { - GstStructure *new_structure; - GstCaps *single_caps; - - single_caps = gst_caps_new_empty (); - new_structure = - gst_structure_copy (gst_caps_get_structure (allowed_caps, i)); - gst_structure_set (new_structure, "framerate", GST_TYPE_FRACTION, - 1, 1, NULL); - gst_structure_remove_field (new_structure, "width"); - gst_structure_remove_field (new_structure, "height"); - gst_caps_append_structure (single_caps, new_structure); - - /* should be fixed without width/height */ - fail_unless (gst_caps_is_fixed (single_caps)); - - list = g_list_prepend (list, single_caps); - } - - gst_object_unref (srcpad); - - return list; -} - -GST_START_TEST (test_unit_sizes) -{ - GstBaseTransformClass *csp_klass, *vcrop_klass; - GstElement *videocrop, *csp; - GList *caps_list, *l; - gint i; - - videocrop = gst_element_factory_make ("videocrop", "videocrop"); - fail_unless (videocrop != NULL, "Failed to create videocrop element"); - vcrop_klass = GST_BASE_TRANSFORM_GET_CLASS (videocrop); - - csp = gst_element_factory_make ("ffmpegcolorspace", "csp"); - fail_unless (csp != NULL, "Failed to create ffmpegcolorspace element"); - csp_klass = GST_BASE_TRANSFORM_GET_CLASS (csp); - - caps_list = video_crop_get_test_caps (videocrop); - - for (l = caps_list; l != NULL; l = l->next) { - const struct - { - gint width, height; - } sizes_to_try[] = { - { - 160, 120}, { - 161, 120}, { - 160, 121}, { - 161, 121}, { - 159, 120}, { - 160, 119}, { - 159, 119}, { - 159, 121} - }; - GstStructure *s; - GstCaps *caps; - gint i; - - caps = gst_caps_copy (GST_CAPS (l->data)); - s = gst_caps_get_structure (caps, 0); - fail_unless (s != NULL); - - for (i = 0; i < G_N_ELEMENTS (sizes_to_try); ++i) { - gchar *caps_str; - guint32 format = 0; - guint csp_size = 0; - guint vc_size = 0; - - gst_structure_set (s, "width", G_TYPE_INT, sizes_to_try[i].width, - "height", G_TYPE_INT, sizes_to_try[i].height, NULL); - - caps_str = gst_caps_to_string (caps); - GST_INFO ("Testing unit size for %s", caps_str); - - /* skip if ffmpegcolorspace doesn't support these caps - * (only works with gst-plugins-base 0.10.9.1 or later) */ - if (!csp_klass->get_unit_size ((GstBaseTransform *) csp, caps, &csp_size)) { - GST_INFO ("ffmpegcolorspace does not support format %s", caps_str); - g_free (caps_str); - continue; - } - - fail_unless (vcrop_klass->get_unit_size ((GstBaseTransform *) videocrop, - caps, &vc_size)); - - fail_unless (vc_size == csp_size, - "videocrop and ffmpegcolorspace return different unit sizes for " - "caps %s: vc_size=%d, csp_size=%d", caps_str, vc_size, csp_size); - - g_free (caps_str); - } - - gst_caps_unref (caps); - } - - g_list_foreach (caps_list, (GFunc) gst_caps_unref, NULL); - g_list_free (caps_list); - - gst_object_unref (csp); - gst_object_unref (videocrop); -} - -GST_END_TEST; - -typedef struct -{ - GstElement *pipeline; - GstElement *src; - GstElement *filter; - GstElement *crop; - GstElement *sink; - GstBuffer *last_buf; -} GstVideoCropTestContext; - -static void -handoff_cb (GstElement * sink, GstBuffer * buf, GstPad * pad, - GstBuffer ** p_buf) -{ - gst_buffer_replace (p_buf, buf); -} - -static void -videocrop_test_cropping_init_context (GstVideoCropTestContext * ctx) -{ - fail_unless (ctx != NULL); - - ctx->pipeline = gst_pipeline_new ("pipeline"); - fail_unless (ctx->pipeline != NULL); - ctx->src = gst_element_factory_make ("videotestsrc", "src"); - fail_unless (ctx->src != NULL, "Failed to create videotestsrc element"); - ctx->filter = gst_element_factory_make ("capsfilter", "filter"); - fail_unless (ctx->filter != NULL, "Failed to create capsfilter element"); - ctx->crop = gst_element_factory_make ("videocrop", "crop"); - fail_unless (ctx->crop != NULL, "Failed to create videocrop element"); - ctx->sink = gst_element_factory_make ("fakesink", "sink"); - fail_unless (ctx->sink != NULL, "Failed to create fakesink element"); - - gst_bin_add_many (GST_BIN (ctx->pipeline), ctx->src, ctx->filter, - ctx->crop, ctx->sink, NULL); - gst_element_link_many (ctx->src, ctx->filter, ctx->crop, ctx->sink, NULL); - - /* set pattern to 'red' - for our purposes it doesn't matter anyway */ - g_object_set (ctx->src, "pattern", 4, NULL); - - g_object_set (ctx->sink, "signal-handoffs", TRUE, NULL); - g_signal_connect (ctx->sink, "preroll-handoff", G_CALLBACK (handoff_cb), - &ctx->last_buf); - - ctx->last_buf = NULL; - - GST_LOG ("context inited"); -} - -static void -videocrop_test_cropping_deinit_context (GstVideoCropTestContext * ctx) -{ - GST_LOG ("deiniting context"); - - gst_element_set_state (ctx->pipeline, GST_STATE_NULL); - gst_object_unref (ctx->pipeline); - gst_buffer_replace (&ctx->last_buf, NULL); - memset (ctx, 0x00, sizeof (GstVideoCropTestContext)); -} -typedef void (*GstVideoCropTestBufferFunc) (GstBuffer * buffer); - -static void -videocrop_test_cropping (GstVideoCropTestContext * ctx, GstCaps * in_caps, - gint left, gint right, gint top, gint bottom, - GstVideoCropTestBufferFunc func) -{ - GST_LOG ("lrtb = %03u %03u %03u %03u, caps = %" GST_PTR_FORMAT, left, right, - top, bottom, in_caps); - - g_object_set (ctx->filter, "caps", in_caps, NULL); - - g_object_set (ctx->crop, "left", left, "right", right, "top", top, - "bottom", bottom, NULL); - - /* this will fail if videotestsrc doesn't support our format; we need - * videotestsrc from -base CVS 0.10.9.1 with RGBA and AYUV support */ - fail_unless (gst_element_set_state (ctx->pipeline, - GST_STATE_PAUSED) != GST_STATE_CHANGE_FAILURE); - fail_unless (gst_element_get_state (ctx->pipeline, NULL, NULL, - -1) == GST_STATE_CHANGE_SUCCESS); - - if (func != NULL) { - func (ctx->last_buf); - } - - gst_element_set_state (ctx->pipeline, GST_STATE_NULL); -} - -static void -check_1x1_buffer (GstBuffer * buf) -{ - GstStructure *s; - - fail_unless (buf != NULL); - fail_unless (GST_BUFFER_CAPS (buf) != NULL); - - s = gst_caps_get_structure (GST_BUFFER_CAPS (buf), 0); - if (gst_structure_has_name (s, "video/x-raw-yuv")) { - guint32 format = 0; - - fail_unless (gst_structure_get_fourcc (s, "format", &format)); - - /* the exact values we check for come from videotestsrc */ - switch (format) { - case GST_MAKE_FOURCC ('I', '4', '2', '0'): - fail_unless_equals_int (GST_BUFFER_DATA (buf)[0], 76); - fail_unless_equals_int (GST_BUFFER_DATA (buf)[8], 85); - fail_unless_equals_int (GST_BUFFER_DATA (buf)[12], 255); - break; - case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - fail_unless_equals_int (GST_BUFFER_DATA (buf)[0], 76); - fail_unless_equals_int (GST_BUFFER_DATA (buf)[8], 255); - fail_unless_equals_int (GST_BUFFER_DATA (buf)[12], 85); - break; - case GST_MAKE_FOURCC ('Y', '8', '0', '0'): - fail_unless_equals_int (GST_BUFFER_DATA (buf)[0], 76); - /* no chroma planes */ - break; - case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'): - fail_unless_equals_int (GST_BUFFER_DATA (buf)[1], 76); - fail_unless_equals_int (GST_BUFFER_DATA (buf)[2], 85); - fail_unless_equals_int (GST_BUFFER_DATA (buf)[3], 255); - /* no chroma planes */ - break; - default: - GST_LOG ("not checking %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (format)); - break; - } - } else if (gst_structure_has_name (s, "video/x-raw-rgb")) { - guint32 pixel; - gint rmask = 0, bmask = 0, gmask = 0, endianness = 0, bpp = 0; - gint rshift, gshift, bshift; - - fail_unless (gst_structure_get_int (s, "red_mask", &rmask)); - fail_unless (gst_structure_get_int (s, "blue_mask", &bmask)); - fail_unless (gst_structure_get_int (s, "green_mask", &gmask)); - fail_unless (gst_structure_get_int (s, "bpp", &bpp)); - fail_unless (gst_structure_get_int (s, "endianness", &endianness)); - - fail_unless (rmask != 0); - fail_unless (gmask != 0); - fail_unless (bmask != 0); - fail_unless (bpp != 0); - fail_unless (endianness != 0); - - rshift = g_bit_nth_lsf (rmask, -1); - gshift = g_bit_nth_lsf (gmask, -1); - bshift = g_bit_nth_lsf (bmask, -1); - - switch (bpp) { - case 32:{ - if (endianness == G_LITTLE_ENDIAN) - pixel = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)); - else - pixel = GST_READ_UINT32_BE (GST_BUFFER_DATA (buf)); - break; - } - case 24:{ - if (endianness == G_BIG_ENDIAN) { - pixel = (GST_READ_UINT8 (GST_BUFFER_DATA (buf)) << 16) | - (GST_READ_UINT8 (GST_BUFFER_DATA (buf) + 1) << 8) | - (GST_READ_UINT8 (GST_BUFFER_DATA (buf) + 2) << 0); - } else { - pixel = (GST_READ_UINT8 (GST_BUFFER_DATA (buf) + 2) << 16) | - (GST_READ_UINT8 (GST_BUFFER_DATA (buf) + 1) << 8) | - (GST_READ_UINT8 (GST_BUFFER_DATA (buf) + 0) << 0); - } - break; - } - default:{ - GST_LOG ("not checking RGB-format buffer with %ubpp", bpp); - return; - } - } - - fail_unless_equals_int ((pixel & rmask) >> rshift, 0xff); - fail_unless_equals_int ((pixel & gmask) >> gshift, 0x00); - fail_unless_equals_int ((pixel & bmask) >> bshift, 0x00); - } -} - -GST_START_TEST (test_crop_to_1x1) -{ - GstVideoCropTestContext ctx; - GList *caps_list, *node; - - videocrop_test_cropping_init_context (&ctx); - - caps_list = video_crop_get_test_caps (ctx.crop); - - for (node = caps_list; node != NULL; node = node->next) { - GstStructure *s; - GstCaps *caps; - - caps = gst_caps_copy (GST_CAPS (node->data)); - s = gst_caps_get_structure (caps, 0); - fail_unless (s != NULL); - - GST_INFO ("testing format: %" GST_PTR_FORMAT, caps); - - gst_structure_set (s, "width", G_TYPE_INT, 160, - "height", G_TYPE_INT, 160, NULL); - - videocrop_test_cropping (&ctx, caps, 159, 0, 159, 0, check_1x1_buffer); - /* commented out because they don't really add anything useful check-wise: - videocrop_test_cropping (&ctx, caps, 0, 159, 0, 159, check_1x1_buffer); - videocrop_test_cropping (&ctx, caps, 159, 0, 0, 159, check_1x1_buffer); - videocrop_test_cropping (&ctx, caps, 0, 159, 159, 0, check_1x1_buffer); - */ - gst_caps_unref (caps); - } - g_list_foreach (caps_list, (GFunc) gst_caps_unref, NULL); - g_list_free (caps_list); - - videocrop_test_cropping_deinit_context (&ctx); -} - -GST_END_TEST; - - - -GST_START_TEST (test_cropping) -{ - GstVideoCropTestContext ctx; - struct - { - gint width, height; - } sizes_to_try[] = { - { - 160, 160}, { - 161, 160}, { - 160, 161}, { - 161, 161}, { - 159, 160}, { - 160, 159}, { - 159, 159}, { - 159, 161} - }; - GList *caps_list, *node; - gint i; - - videocrop_test_cropping_init_context (&ctx); - - caps_list = video_crop_get_test_caps (ctx.crop); - - for (node = caps_list; node != NULL; node = node->next) { - GstStructure *s; - GstCaps *caps; - - caps = gst_caps_copy (GST_CAPS (node->data)); - s = gst_caps_get_structure (caps, 0); - fail_unless (s != NULL); - - GST_INFO ("testing format: %" GST_PTR_FORMAT, caps); - - for (i = 0; i < G_N_ELEMENTS (sizes_to_try); ++i) { - gst_structure_set (s, "width", G_TYPE_INT, sizes_to_try[i].width, - "height", G_TYPE_INT, sizes_to_try[i].height, NULL); - - GST_INFO (" - %d x %d", sizes_to_try[i].width, sizes_to_try[i].height); - - videocrop_test_cropping (&ctx, caps, 0, 0, 0, 0, NULL); - videocrop_test_cropping (&ctx, caps, 1, 0, 0, 0, NULL); - videocrop_test_cropping (&ctx, caps, 0, 1, 0, 0, NULL); - videocrop_test_cropping (&ctx, caps, 0, 0, 1, 0, NULL); - videocrop_test_cropping (&ctx, caps, 0, 0, 0, 1, NULL); - videocrop_test_cropping (&ctx, caps, 63, 0, 0, 0, NULL); - videocrop_test_cropping (&ctx, caps, 0, 63, 0, 0, NULL); - videocrop_test_cropping (&ctx, caps, 0, 0, 63, 0, NULL); - videocrop_test_cropping (&ctx, caps, 0, 0, 0, 63, NULL); - videocrop_test_cropping (&ctx, caps, 63, 0, 0, 1, NULL); - videocrop_test_cropping (&ctx, caps, 0, 63, 1, 0, NULL); - videocrop_test_cropping (&ctx, caps, 0, 1, 63, 0, NULL); - videocrop_test_cropping (&ctx, caps, 1, 0, 0, 63, NULL); - videocrop_test_cropping (&ctx, caps, 0, 0, 0, 0, NULL); - videocrop_test_cropping (&ctx, caps, 32, 0, 0, 128, NULL); - videocrop_test_cropping (&ctx, caps, 0, 32, 128, 0, NULL); - videocrop_test_cropping (&ctx, caps, 0, 128, 32, 0, NULL); - videocrop_test_cropping (&ctx, caps, 128, 0, 0, 32, NULL); - videocrop_test_cropping (&ctx, caps, 1, 1, 1, 1, NULL); - videocrop_test_cropping (&ctx, caps, 63, 63, 63, 63, NULL); - videocrop_test_cropping (&ctx, caps, 64, 64, 64, 64, NULL); - } - - gst_caps_unref (caps); - } - g_list_foreach (caps_list, (GFunc) gst_caps_unref, NULL); - g_list_free (caps_list); - - videocrop_test_cropping_deinit_context (&ctx); -} - -GST_END_TEST; - - -static gboolean -buffer_probe_cb (GstPad * pad, GstBuffer * buf, GstBuffer ** p_buf) -{ - gst_buffer_replace (p_buf, buf); - return TRUE; /* keep data */ -} - -GST_START_TEST (test_passthrough) -{ - GstStateChangeReturn state_ret; - GstVideoCropTestContext ctx; - GstPad *srcpad; - GstBuffer *gen_buf = NULL; /* buffer generated by videotestsrc */ - - videocrop_test_cropping_init_context (&ctx); - - g_object_set (ctx.src, "num-buffers", 1, NULL); - - srcpad = gst_element_get_pad (ctx.src, "src"); - fail_unless (srcpad != NULL); - gst_pad_add_buffer_probe (srcpad, G_CALLBACK (buffer_probe_cb), &gen_buf); - gst_object_unref (srcpad); - - g_object_set (ctx.crop, "left", 0, "right", 0, "top", 0, "bottom", 0, NULL); - - state_ret = gst_element_set_state (ctx.pipeline, GST_STATE_PAUSED); - fail_unless (state_ret != GST_STATE_CHANGE_FAILURE, - "couldn't set pipeline to PAUSED state"); - - state_ret = gst_element_get_state (ctx.pipeline, NULL, NULL, -1); - fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS, - "pipeline failed to go to PAUSED state"); - - fail_unless (gen_buf != NULL); - fail_unless (ctx.last_buf != NULL); - - /* pass through should do nothing */ - fail_unless (gen_buf == ctx.last_buf); - - videocrop_test_cropping_deinit_context (&ctx); - - fail_unless_equals_int (GST_MINI_OBJECT_REFCOUNT_VALUE (gen_buf), 1); - gst_buffer_unref (gen_buf); -} - -GST_END_TEST; - -static gint -notgst_value_list_get_nth_int (const GValue * list_val, guint n) -{ - const GValue *v; - - fail_unless (GST_VALUE_HOLDS_LIST (list_val)); - fail_unless (n < gst_value_list_get_size (list_val)); - - v = gst_value_list_get_value (list_val, n); - fail_unless (G_VALUE_HOLDS_INT (v)); - return g_value_get_int (v); -} - -GST_START_TEST (test_caps_transform) -{ - GstVideoCropTestContext ctx; - GstBaseTransformClass *klass; - GstBaseTransform *crop; - const GValue *w_val; - const GValue *h_val; - GstCaps *caps, *adj_caps; - - videocrop_test_cropping_init_context (&ctx); - - crop = GST_BASE_TRANSFORM (ctx.crop); - klass = GST_BASE_TRANSFORM_GET_CLASS (ctx.crop); - fail_unless (klass != NULL); - - caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'), - "framerate", GST_TYPE_FRACTION, 1, 1, - "width", G_TYPE_INT, 200, "height", G_TYPE_INT, 100, NULL); - - /* by default, it should be no cropping and hence passthrough */ - adj_caps = klass->transform_caps (crop, GST_PAD_SRC, caps); - fail_unless (adj_caps != NULL); - fail_unless (gst_caps_is_equal (adj_caps, caps)); - gst_caps_unref (adj_caps); - - adj_caps = klass->transform_caps (crop, GST_PAD_SINK, caps); - fail_unless (adj_caps != NULL); - fail_unless (gst_caps_is_equal (adj_caps, caps)); - gst_caps_unref (adj_caps); - - /* make sure that's still true after changing properties back and forth */ - g_object_set (ctx.crop, "left", 1, "right", 3, "top", 5, "bottom", 7, NULL); - g_object_set (ctx.crop, "left", 0, "right", 0, "top", 0, "bottom", 0, NULL); - - adj_caps = klass->transform_caps (crop, GST_PAD_SRC, caps); - fail_unless (adj_caps != NULL); - fail_unless (gst_caps_is_equal (adj_caps, caps)); - gst_caps_unref (adj_caps); - - adj_caps = klass->transform_caps (crop, GST_PAD_SINK, caps); - fail_unless (adj_caps != NULL); - fail_unless (gst_caps_is_equal (adj_caps, caps)); - gst_caps_unref (adj_caps); - - /* now check adjustments made ... */ - g_object_set (ctx.crop, "left", 1, "right", 3, "top", 5, "bottom", 7, NULL); - - /* ========= (1) fixed value ============================================= */ - - /* sink => source, source must be bigger if we crop stuff off */ - adj_caps = klass->transform_caps (crop, GST_PAD_SRC, caps); - fail_unless (adj_caps != NULL); - fail_unless (gst_caps_get_size (adj_caps) == 1); - w_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "width"); - fail_unless (w_val != NULL); - fail_unless (G_VALUE_HOLDS_INT (w_val)); - fail_unless_equals_int (g_value_get_int (w_val), 200 + (1 + 3)); - h_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "height"); - fail_unless (h_val != NULL); - fail_unless (G_VALUE_HOLDS_INT (h_val)); - fail_unless_equals_int (g_value_get_int (h_val), 100 + (5 + 7)); - gst_caps_unref (adj_caps); - - /* source => sink becomes smaller */ - adj_caps = klass->transform_caps (crop, GST_PAD_SINK, caps); - fail_unless (adj_caps != NULL); - fail_unless (gst_caps_get_size (adj_caps) == 1); - w_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "width"); - fail_unless (w_val != NULL); - fail_unless (G_VALUE_HOLDS_INT (w_val)); - fail_unless_equals_int (g_value_get_int (w_val), 200 - (1 + 3)); - h_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "height"); - fail_unless (h_val != NULL); - fail_unless (G_VALUE_HOLDS_INT (h_val)); - fail_unless_equals_int (g_value_get_int (h_val), 100 - (5 + 7)); - gst_caps_unref (adj_caps); - - /* ========= (2) range (simple adjustment) =============================== */ - - gst_structure_set (gst_caps_get_structure (caps, 0), - "width", GST_TYPE_INT_RANGE, 1000, 2000, - "height", GST_TYPE_INT_RANGE, 3000, 4000, NULL); - - /* sink => source, source must be bigger if we crop stuff off */ - adj_caps = klass->transform_caps (crop, GST_PAD_SRC, caps); - fail_unless (adj_caps != NULL); - fail_unless (gst_caps_get_size (adj_caps) == 1); - w_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "width"); - fail_unless (w_val != NULL); - fail_unless (GST_VALUE_HOLDS_INT_RANGE (w_val)); - fail_unless_equals_int (gst_value_get_int_range_min (w_val), 1000 + (1 + 3)); - fail_unless_equals_int (gst_value_get_int_range_max (w_val), 2000 + (1 + 3)); - h_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "height"); - fail_unless (h_val != NULL); - fail_unless (GST_VALUE_HOLDS_INT_RANGE (h_val)); - fail_unless_equals_int (gst_value_get_int_range_min (h_val), 3000 + (5 + 7)); - fail_unless_equals_int (gst_value_get_int_range_max (h_val), 4000 + (5 + 7)); - gst_caps_unref (adj_caps); - - /* source => sink becomes smaller */ - adj_caps = klass->transform_caps (crop, GST_PAD_SINK, caps); - fail_unless (adj_caps != NULL); - fail_unless (gst_caps_get_size (adj_caps) == 1); - w_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "width"); - fail_unless (w_val != NULL); - fail_unless (GST_VALUE_HOLDS_INT_RANGE (w_val)); - fail_unless_equals_int (gst_value_get_int_range_min (w_val), 1000 - (1 + 3)); - fail_unless_equals_int (gst_value_get_int_range_max (w_val), 2000 - (1 + 3)); - h_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "height"); - fail_unless (h_val != NULL); - fail_unless (GST_VALUE_HOLDS_INT_RANGE (h_val)); - fail_unless_equals_int (gst_value_get_int_range_min (h_val), 3000 - (5 + 7)); - fail_unless_equals_int (gst_value_get_int_range_max (h_val), 4000 - (5 + 7)); - gst_caps_unref (adj_caps); - - /* ========= (3) range (adjustment at boundary) ========================== */ - - gst_structure_set (gst_caps_get_structure (caps, 0), - "width", GST_TYPE_INT_RANGE, 2, G_MAXINT, - "height", GST_TYPE_INT_RANGE, 2, G_MAXINT, NULL); - - /* sink => source, source must be bigger if we crop stuff off */ - adj_caps = klass->transform_caps (crop, GST_PAD_SRC, caps); - fail_unless (adj_caps != NULL); - fail_unless (gst_caps_get_size (adj_caps) == 1); - w_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "width"); - fail_unless (w_val != NULL); - fail_unless (GST_VALUE_HOLDS_INT_RANGE (w_val)); - fail_unless_equals_int (gst_value_get_int_range_min (w_val), 2 + (1 + 3)); - fail_unless_equals_int (gst_value_get_int_range_max (w_val), G_MAXINT); - h_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "height"); - fail_unless (h_val != NULL); - fail_unless (GST_VALUE_HOLDS_INT_RANGE (h_val)); - fail_unless_equals_int (gst_value_get_int_range_min (h_val), 2 + (5 + 7)); - fail_unless_equals_int (gst_value_get_int_range_max (h_val), G_MAXINT); - gst_caps_unref (adj_caps); - - /* source => sink becomes smaller */ - adj_caps = klass->transform_caps (crop, GST_PAD_SINK, caps); - fail_unless (adj_caps != NULL); - fail_unless (gst_caps_get_size (adj_caps) == 1); - w_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "width"); - fail_unless (w_val != NULL); - fail_unless (GST_VALUE_HOLDS_INT_RANGE (w_val)); - fail_unless_equals_int (gst_value_get_int_range_min (w_val), 1); - fail_unless_equals_int (gst_value_get_int_range_max (w_val), - G_MAXINT - (1 + 3)); - h_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "height"); - fail_unless (h_val != NULL); - fail_unless (GST_VALUE_HOLDS_INT_RANGE (h_val)); - fail_unless_equals_int (gst_value_get_int_range_min (h_val), 1); - fail_unless_equals_int (gst_value_get_int_range_max (h_val), - G_MAXINT - (5 + 7)); - gst_caps_unref (adj_caps); - - /* ========= (4) list of values ========================================== */ - - { - GValue list = { 0, }; - GValue ival = { 0, }; - - g_value_init (&ival, G_TYPE_INT); - g_value_init (&list, GST_TYPE_LIST); - g_value_set_int (&ival, 2); - gst_value_list_append_value (&list, &ival); - g_value_set_int (&ival, G_MAXINT); - gst_value_list_append_value (&list, &ival); - gst_structure_set_value (gst_caps_get_structure (caps, 0), "width", &list); - g_value_unset (&list); - g_value_unset (&ival); - - g_value_init (&ival, G_TYPE_INT); - g_value_init (&list, GST_TYPE_LIST); - g_value_set_int (&ival, 5); - gst_value_list_append_value (&list, &ival); - g_value_set_int (&ival, 1000); - gst_value_list_append_value (&list, &ival); - gst_structure_set_value (gst_caps_get_structure (caps, 0), "height", &list); - g_value_unset (&list); - g_value_unset (&ival); - } - - /* sink => source, source must be bigger if we crop stuff off */ - adj_caps = klass->transform_caps (crop, GST_PAD_SRC, caps); - fail_unless (adj_caps != NULL); - fail_unless (gst_caps_get_size (adj_caps) == 1); - w_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "width"); - fail_unless (w_val != NULL); - fail_unless (GST_VALUE_HOLDS_LIST (w_val)); - fail_unless_equals_int (notgst_value_list_get_nth_int (w_val, 0), - 2 + (1 + 3)); - fail_unless_equals_int (notgst_value_list_get_nth_int (w_val, 1), G_MAXINT); - h_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "height"); - fail_unless (h_val != NULL); - fail_unless (GST_VALUE_HOLDS_LIST (h_val)); - fail_unless_equals_int (notgst_value_list_get_nth_int (h_val, 0), - 5 + (5 + 7)); - fail_unless_equals_int (notgst_value_list_get_nth_int (h_val, 1), - 1000 + (5 + 7)); - gst_caps_unref (adj_caps); - - /* source => sink becomes smaller */ - adj_caps = klass->transform_caps (crop, GST_PAD_SINK, caps); - fail_unless (adj_caps != NULL); - fail_unless (gst_caps_get_size (adj_caps) == 1); - w_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "width"); - fail_unless (w_val != NULL); - fail_unless (GST_VALUE_HOLDS_LIST (w_val)); - fail_unless_equals_int (notgst_value_list_get_nth_int (w_val, 0), 1); - fail_unless_equals_int (notgst_value_list_get_nth_int (w_val, 1), - G_MAXINT - (1 + 3)); - h_val = - gst_structure_get_value (gst_caps_get_structure (adj_caps, 0), "height"); - fail_unless (h_val != NULL); - fail_unless (GST_VALUE_HOLDS_LIST (h_val)); - fail_unless_equals_int (notgst_value_list_get_nth_int (h_val, 0), 1); - fail_unless_equals_int (notgst_value_list_get_nth_int (h_val, 1), - 1000 - (5 + 7)); - gst_caps_unref (adj_caps); - - gst_caps_unref (caps); - videocrop_test_cropping_deinit_context (&ctx); -} - -GST_END_TEST; - -static Suite * -videocrop_suite (void) -{ - Suite *s = suite_create ("videocrop"); - TCase *tc_chain = tcase_create ("general"); - -#ifdef HAVE_VALGRIND - if (RUNNING_ON_VALGRIND) { - /* our tests take quite a long time, so increase - * timeout (~25 minutes on my 1.6GHz AMD K7) */ - tcase_set_timeout (tc_chain, 30 * 60); - } else -#endif - { - /* increase timeout, these tests take a long time (60 secs here) */ - tcase_set_timeout (tc_chain, 2 * 60); - } - - suite_add_tcase (s, tc_chain); - tcase_add_test (tc_chain, test_crop_to_1x1); - tcase_add_test (tc_chain, test_caps_transform); - tcase_add_test (tc_chain, test_passthrough); - tcase_add_test (tc_chain, test_unit_sizes); - tcase_add_test (tc_chain, test_cropping); - - return s; -} - -int -main (int argc, char **argv) -{ - int nf; - - Suite *s = videocrop_suite (); - SRunner *sr = srunner_create (s); - -#ifdef HAVE_VALGRIND - if (RUNNING_ON_VALGRIND) { - /* otherwise valgrind errors out when liboil probes CPU extensions - * in oil_init() during which it causes SIGILLs etc. to be fired */ - g_setenv ("OIL_CPU_FLAGS", "0", 0); - } -#endif - - gst_check_init (&argc, &argv); - - srunner_run_all (sr, CK_NORMAL); - nf = srunner_ntests_failed (sr); - srunner_free (sr); - - return nf; -} diff --git a/tests/icles/Makefile.am b/tests/icles/Makefile.am index b57880e48f..da44e312d5 100644 --- a/tests/icles/Makefile.am +++ b/tests/icles/Makefile.am @@ -11,14 +11,9 @@ else GST_SOUNDTOUCH_TESTS = endif -videocrop_test_SOURCES = videocrop-test.c -videocrop_test_CFLAGS = $(GST_CFLAGS) -videocrop_test_LDADD = $(GST_LIBS) -videocrop_test_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - equalizer_test_SOURCES = equalizer-test.c equalizer_test_CFLAGS = $(GST_CFLAGS) equalizer_test_LDADD = $(GST_LIBS) equalizer_test_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -noinst_PROGRAMS = $(GST_SOUNDTOUCH_TESTS) equalizer-test videocrop-test +noinst_PROGRAMS = $(GST_SOUNDTOUCH_TESTS) equalizer-test diff --git a/tests/icles/videocrop-test.c b/tests/icles/videocrop-test.c deleted file mode 100644 index 1c7ae4baa6..0000000000 --- a/tests/icles/videocrop-test.c +++ /dev/null @@ -1,356 +0,0 @@ -/* GStreamer interactive test for the videocrop element - * Copyright (C) 2006 Tim-Philipp Müller - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include -#include - -GST_DEBUG_CATEGORY_STATIC (videocrop_test_debug); -#define GST_CAT_DEFAULT videocrop_test_debug - -#define OUT_WIDTH 640 -#define OUT_HEIGHT 480 -#define TIME_PER_TEST 10 /* seconds each format is tested */ -#define FRAMERATE 15 /* frames per second */ - -#define DEFAULT_VIDEOSINK "xvimagesink" - -static gboolean -check_bus_for_errors (GstBus * bus, GstClockTime max_wait_time) -{ - GstMessage *msg; - - msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, max_wait_time); - - if (msg) { - GError *err = NULL; - gchar *debug = NULL; - - g_assert (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR); - gst_message_parse_error (msg, &err, &debug); - GST_ERROR ("ERROR: %s [%s]", err->message, debug); - g_print ("\n===========> ERROR: %s\n%s\n\n", err->message, debug); - g_error_free (err); - g_free (debug); - gst_message_unref (msg); - } - - return (msg != NULL); -} - -static void -test_with_caps (GstElement * src, GstElement * videocrop, GstCaps * caps) -{ - GstClockTime time_run; - GstElement *pipeline; - GTimer *timer; - GstBus *bus; - GstPad *pad; - guint hcrop; - guint vcrop; - - /* caps must be writable, we can't check that here though */ - g_assert (GST_CAPS_REFCOUNT_VALUE (caps) == 1); - - timer = g_timer_new (); - vcrop = 0; - hcrop = 0; - - pipeline = GST_ELEMENT (gst_element_get_parent (videocrop)); - g_assert (GST_IS_PIPELINE (pipeline)); - - /* at this point the pipeline is in PLAYING state; we only want to capture - * errors resulting from our on-the-fly changing of the filtercaps */ - bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); - - /* pad to block */ - pad = gst_element_get_pad (src, "src"); - - time_run = 0; - do { - GstClockTime wait_time, waited_for_block; - - if (check_bus_for_errors (bus, 0)) - break; - - wait_time = GST_SECOND / FRAMERATE; - - GST_LOG ("hcrop = %3d, vcrop = %3d", vcrop, hcrop); - - g_timer_reset (timer); - - /* need to block the streaming thread while changing these properties, - * otherwise we might get random not-negotiated errors (when caps are - * changed in between upstream calling pad_alloc_buffer() and pushing - * the processed buffer?) */ - gst_pad_set_blocked (pad, TRUE); - g_object_set (videocrop, "left", hcrop, "top", vcrop, NULL); - gst_pad_set_blocked (pad, FALSE); - - waited_for_block = g_timer_elapsed (timer, NULL) * (double) GST_SECOND; - /* GST_LOG ("waited: %" GST_TIME_FORMAT ", frame len: %" GST_TIME_FORMAT, - GST_TIME_ARGS (waited_for_block), GST_TIME_ARGS (wait_time)); */ - ++vcrop; - ++hcrop; - - if (wait_time > waited_for_block) { - g_usleep ((wait_time - waited_for_block) / GST_MSECOND); - } - - time_run += wait_time; - } - while (time_run < (TIME_PER_TEST * GST_SECOND)); - - g_timer_destroy (timer); - gst_object_unref (bus); - gst_object_unref (pad); -} - -/* return a list of caps where we only need to set - * width and height to get fixed caps */ -static GList * -video_crop_get_test_caps (GstElement * videocrop) -{ - const GstCaps *allowed_caps; - GstPad *srcpad; - GList *list = NULL; - guint i; - - srcpad = gst_element_get_pad (videocrop, "src"); - g_assert (srcpad != NULL); - allowed_caps = gst_pad_get_pad_template_caps (srcpad); - g_assert (allowed_caps != NULL); - - for (i = 0; i < gst_caps_get_size (allowed_caps); ++i) { - GstStructure *new_structure; - GstCaps *single_caps; - - single_caps = gst_caps_new_empty (); - new_structure = - gst_structure_copy (gst_caps_get_structure (allowed_caps, i)); - gst_structure_set (new_structure, "framerate", GST_TYPE_FRACTION, - FRAMERATE, 1, NULL); - gst_structure_remove_field (new_structure, "width"); - gst_structure_remove_field (new_structure, "height"); - gst_caps_append_structure (single_caps, new_structure); - - /* should be fixed without width/height */ - g_assert (gst_caps_is_fixed (single_caps)); - - list = g_list_prepend (list, single_caps); - } - - gst_object_unref (srcpad); - - return list; -} - -static gchar *opt_videosink_str; /* NULL */ -static gchar *opt_filtercaps_str; /* NULL */ -static gboolean opt_with_ffmpegcolorspace; /* FALSE */ - -int -main (int argc, char **argv) -{ - static const GOptionEntry test_goptions[] = { - {"videosink", '\0', 0, G_OPTION_ARG_STRING, &opt_videosink_str, - "videosink to use (default: " DEFAULT_VIDEOSINK ")", NULL}, - {"caps", '\0', 0, G_OPTION_ARG_STRING, &opt_filtercaps_str, - "filter caps to narrow down formats to test", NULL}, - {"with-ffmpegcolorspace", '\0', 0, G_OPTION_ARG_NONE, - &opt_with_ffmpegcolorspace, - "whether to add an ffmpegcolorspace element in front of the sink", - NULL}, - {NULL, '\0', 0, 0, NULL, NULL, NULL} - }; - GOptionContext *ctx; - GError *opt_err = NULL; - - GstElement *pipeline, *src, *filter1, *crop, *scale, *filter2, *csp, *sink; - GMainLoop *loop; - GstCaps *filter_caps = NULL; - GList *caps_list, *l; - - if (!g_thread_supported ()) - g_thread_init (NULL); - - /* command line option parsing */ - ctx = g_option_context_new (""); - g_option_context_add_group (ctx, gst_init_get_option_group ()); - g_option_context_add_main_entries (ctx, test_goptions, NULL); - - if (!g_option_context_parse (ctx, &argc, &argv, &opt_err)) { - g_error ("Error parsing command line options: %s", opt_err->message); - return -1; - } - - GST_DEBUG_CATEGORY_INIT (videocrop_test_debug, "videocroptest", 0, "vctest"); - - loop = g_main_loop_new (NULL, FALSE); - - pipeline = gst_pipeline_new ("pipeline"); - src = gst_element_factory_make ("videotestsrc", "videotestsrc"); - g_assert (src != NULL); - filter1 = gst_element_factory_make ("capsfilter", "capsfilter1"); - g_assert (filter1 != NULL); - crop = gst_element_factory_make ("videocrop", "videocrop"); - g_assert (crop != NULL); - scale = gst_element_factory_make ("videoscale", "videoscale"); - g_assert (scale != NULL); - filter2 = gst_element_factory_make ("capsfilter", "capsfilter2"); - g_assert (filter2 != NULL); - - if (opt_with_ffmpegcolorspace) { - g_print ("Adding ffmpegcolorspace\n"); - csp = gst_element_factory_make ("ffmpegcolorspace", "colorspace"); - } else { - csp = gst_element_factory_make ("identity", "colorspace"); - } - g_assert (csp != NULL); - - if (opt_filtercaps_str) { - filter_caps = gst_caps_from_string (opt_filtercaps_str); - if (filter_caps == NULL) { - g_error ("Invalid filter caps string '%s'", opt_filtercaps_str); - } else { - g_print ("Using filter caps '%s'\n", opt_filtercaps_str); - } - } - - if (opt_videosink_str) { - g_print ("Trying videosink '%s' ...", opt_videosink_str); - sink = gst_element_factory_make (opt_videosink_str, "sink"); - g_print ("%s\n", (sink) ? "ok" : "element couldn't be created"); - } else { - sink = NULL; - } - - if (sink == NULL) { - g_print ("Trying videosink '%s' ...", DEFAULT_VIDEOSINK); - sink = gst_element_factory_make (DEFAULT_VIDEOSINK, "sink"); - g_print ("%s\n", (sink) ? "ok" : "element couldn't be created"); - } - if (sink == NULL) { - g_print ("Trying videosink '%s' ...", "xvimagesink"); - sink = gst_element_factory_make ("xvimagesink", "sink"); - g_print ("%s\n", (sink) ? "ok" : "element couldn't be created"); - } - if (sink == NULL) { - g_print ("Trying videosink '%s' ...", "ximagesink"); - sink = gst_element_factory_make ("ximagesink", "sink"); - g_print ("%s\n", (sink) ? "ok" : "element couldn't be created"); - } - - g_assert (sink != NULL); - - gst_bin_add_many (GST_BIN (pipeline), src, filter1, crop, scale, filter2, - csp, sink, NULL); - - if (!gst_element_link (src, filter1)) - g_error ("Failed to link videotestsrc to capsfilter1"); - - if (!gst_element_link (filter1, crop)) - g_error ("Failed to link capsfilter1 to videocrop"); - - if (!gst_element_link (crop, scale)) - g_error ("Failed to link videocrop to videoscale"); - - if (!gst_element_link (scale, filter2)) - g_error ("Failed to link videoscale to capsfilter2"); - - if (!gst_element_link (filter2, csp)) - g_error ("Failed to link capsfilter2 to ffmpegcolorspace"); - - if (!gst_element_link (csp, sink)) - g_error ("Failed to link ffmpegcolorspace to video sink"); - - caps_list = video_crop_get_test_caps (crop); - for (l = caps_list; l != NULL; l = l->next) { - GstStateChangeReturn ret; - GstCaps *caps, *out_caps; - gboolean skip = FALSE; - gchar *s; - - if (filter_caps) { - GstCaps *icaps; - - icaps = gst_caps_intersect (filter_caps, GST_CAPS (l->data)); - skip = gst_caps_is_empty (icaps); - gst_caps_unref (icaps); - } - - /* this is the size of our window (stays fixed) */ - out_caps = gst_caps_copy (GST_CAPS (l->data)); - gst_structure_set (gst_caps_get_structure (out_caps, 0), "width", - G_TYPE_INT, OUT_WIDTH, "height", G_TYPE_INT, OUT_HEIGHT, NULL); - - g_object_set (filter2, "caps", out_caps, NULL); - - /* filter1 gets these too to prevent videotestsrc from renegotiating */ - g_object_set (filter1, "caps", out_caps, NULL); - gst_caps_unref (out_caps); - - caps = gst_caps_copy (GST_CAPS (l->data)); - GST_INFO ("testing format: %" GST_PTR_FORMAT, caps); - - s = gst_caps_to_string (caps); - - if (skip) { - g_print ("Skipping format: %s\n", s); - g_free (s); - continue; - } - - g_print ("Format: %s\n", s); - - caps = gst_caps_make_writable (caps); - - /* FIXME: check return values */ - ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); - if (ret != GST_STATE_CHANGE_FAILURE) { - ret = gst_element_get_state (pipeline, NULL, NULL, -1); - - if (ret != GST_STATE_CHANGE_FAILURE) { - test_with_caps (src, crop, caps); - } else { - g_print ("Format: %s not supported (failed to go to PLAYING)\n", s); - } - } else { - g_print ("Format: %s not supported\n", s); - } - - gst_element_set_state (pipeline, GST_STATE_NULL); - - gst_caps_unref (caps); - g_free (s); - } - - g_list_foreach (caps_list, (GFunc) gst_caps_unref, NULL); - g_list_free (caps_list); - - gst_element_set_state (pipeline, GST_STATE_NULL); - gst_object_unref (pipeline); - - return 0; -}