diff --git a/ChangeLog b/ChangeLog index 157628c958..dbf498ad59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +2005-10-11 Edward Hervey + + * gst/common.h: + cleanup + * gst/gst-types.defs: + * gst/gst.defs: + Updated defs file to current gstreamer core + * gst/gst.override: + Added useless function (at least from python bindings) and little correction + on _wrap_gst_xml_get_topelements() + * gst/gstbin.override: + * gst/gstbuffer.override: + Fix memleak in gst.Buffer.set_caps() + * gst/gstevent.override: + Added wrapper for remaining gst_event_parse_*() + * gst/gstlibs.override: + Wrapped more gst.Controller methods + * gst/gstmodule.c: (init_gst): + new gst_init() + Added atexit(gst_deinit) + * gst/gstpad.override: + Fix memleak in gst.Pad.set_caps() + * gst/gstquery.override: + add gst.Query.parse_segment() + * gst/libs.defs: + Updated to current gst-libs + * gst/pygstminiobject.c: (pygstminiobject_register_wrapper), + (pygstminiobject_new), (pygstminiobject_dealloc): + Added debug + + * testsuite/Makefile.am: + * testsuite/common.py: + * testsuite/gstpython.supp: + * testsuite/python.supp: + * testsuite/test_bin.py: + * testsuite/test_buffer.py: + * testsuite/test_element.py: + * testsuite/test_event.py: + * testsuite/test_ghostpad.py: + * testsuite/test_iterator.py: + * testsuite/test_message.py: + * testsuite/test_pipeline.py: + Proper valgrind testing, + Updated tests to new API + 2005-10-09 Thomas Vander Stichele * examples/play.py: diff --git a/common b/common index eb0dd118a0..54920e38c6 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit eb0dd118a086dd4aa405d3871131839d81306245 +Subproject commit 54920e38c65eaf03ea52c21b14a6d104a56581a9 diff --git a/gst/common.h b/gst/common.h index 064cefb4d9..06a1b7589f 100644 --- a/gst/common.h +++ b/gst/common.h @@ -58,8 +58,6 @@ PyTypeObject PyGstIterator_Type; /* from gst-types.c */ -/* gboolean pygst_data_from_pyobject(PyObject *object, GstData **data); */ -/* PyObject *pygst_data_to_pyobject(GstData *data); */ GstCaps *pygst_caps_from_pyobject (PyObject *object, gboolean *copy); PyObject* pygst_iterator_new(GstIterator *iter); diff --git a/gst/gst-types.defs b/gst/gst-types.defs index 5b544800b5..3141d07a21 100644 --- a/gst/gst-types.defs +++ b/gst/gst-types.defs @@ -334,6 +334,8 @@ (values '("locked-state" "GST_ELEMENT_LOCKED_STATE") '("is-sink" "GST_ELEMENT_IS_SINK") + '("unparenting" "GST_ELEMENT_UNPARENTING") + '("changing-state" "GST_ELEMENT_CHANGING_STATE") '("flag-last" "GST_ELEMENT_FLAG_LAST") ) ) @@ -422,15 +424,21 @@ (gtype-id "GST_TYPE_EVENT_TYPE") (values '("unknown" "GST_EVENT_UNKNOWN") + '("flush-start" "GST_EVENT_FLUSH_START") + '("flush-stop" "GST_EVENT_FLUSH_STOP") '("eos" "GST_EVENT_EOS") - '("flush" "GST_EVENT_FLUSH") - '("discontinuous" "GST_EVENT_DISCONTINUOUS") + '("newsegment" "GST_EVENT_NEWSEGMENT") + '("tag" "GST_EVENT_TAG") + '("filler" "GST_EVENT_FILLER") + '("buffersize" "GST_EVENT_BUFFERSIZE") '("qos" "GST_EVENT_QOS") '("seek" "GST_EVENT_SEEK") - '("size" "GST_EVENT_SIZE") - '("rate" "GST_EVENT_RATE") '("navigation" "GST_EVENT_NAVIGATION") - '("tag" "GST_EVENT_TAG") + '("custom-up" "GST_EVENT_CUSTOM_UP") + '("custom-ds" "GST_EVENT_CUSTOM_DS") + '("custom-ds-oob" "GST_EVENT_CUSTOM_DS_OOB") + '("custom-both" "GST_EVENT_CUSTOM_BOTH") + '("custom-both-oob" "GST_EVENT_CUSTOM_BOTH_OOB") ) ) @@ -619,10 +627,13 @@ '("buffering" "GST_MESSAGE_BUFFERING") '("state-changed" "GST_MESSAGE_STATE_CHANGED") '("step-done" "GST_MESSAGE_STEP_DONE") + '("clock-provide" "GST_MESSAGE_CLOCK_PROVIDE") + '("clock-lost" "GST_MESSAGE_CLOCK_LOST") '("new-clock" "GST_MESSAGE_NEW_CLOCK") '("structure-change" "GST_MESSAGE_STRUCTURE_CHANGE") '("stream-status" "GST_MESSAGE_STREAM_STATUS") '("application" "GST_MESSAGE_APPLICATION") + '("element" "GST_MESSAGE_ELEMENT") '("segment-start" "GST_MESSAGE_SEGMENT_START") '("segment-done" "GST_MESSAGE_SEGMENT_DONE") '("any" "GST_MESSAGE_ANY") diff --git a/gst/gst.defs b/gst/gst.defs index 70a136af2e..4ce32edd1e 100644 --- a/gst/gst.defs +++ b/gst/gst.defs @@ -21,32 +21,18 @@ (parameters '("int*" "argc") '("char**[]" "argv") + '("GError**" "err") ) ) -(define-function init_with_popt_table - (c-name "gst_init_with_popt_table") +(define-function gst_init_get_option_group + (c-name "gst_init_get_option_group") + (return-type "GOptionGroup*") +) + +(define-function gst_deinit + (c-name "gst_deinit") (return-type "none") - (parameters - '("int*" "argc") - '("char**[]" "argv") - '("const-GstPoptOption*" "popt_options") - ) -) - -(define-function init_check_with_popt_table - (c-name "gst_init_check_with_popt_table") - (return-type "gboolean") - (parameters - '("int*" "argc") - '("char**[]" "argv") - '("const-GstPoptOption*" "popt_options") - ) -) - -(define-function init_get_popt_table - (c-name "gst_init_get_popt_table") - (return-type "const-GstPoptOption*") ) @@ -1141,15 +1127,6 @@ ) ) -(define-method set_state_async - (of-object "GstElement") - (c-name "gst_element_set_state_async") - (return-type "GstStateChangeReturn") - (parameters - '("GstState" "state") - ) -) - (define-method abort_state (of-object "GstElement") (c-name "gst_element_abort_state") @@ -1159,7 +1136,7 @@ (define-method commit_state (of-object "GstElement") (c-name "gst_element_commit_state") - (return-type "none") + (return-type "GstStateChangeReturn") ) (define-method lost_state @@ -1653,6 +1630,18 @@ ;; From ../gstreamer/gst/gstevent.h +(define-method get_name + (of-object "GstEventType") + (c-name "gst_event_type_get_name") + (return-type "const-gchar*") +) + +(define-method to_quark + (of-object "GstEventType") + (c-name "gst_event_type_to_quark") + (return-type "GQuark") +) + (define-function event_get_type (c-name "gst_event_get_type") (return-type "GType") @@ -1742,6 +1731,29 @@ (caller-owns-return #t) ) +(define-function gst_event_new_buffersize + (c-name "gst_event_new_buffersize") + (return-type "GstEvent*") + (parameters + '("GstFormat" "format") + '("gint64" "minsize") + '("gint64" "maxsize") + '("gboolean" "async") + ) +) + +(define-method parse_buffersize + (of-object "GstEvent") + (c-name "gst_event_parse_buffersize") + (return-type "none") + (parameters + '("GstFormat*" "format") + '("gint64*" "minsize") + '("gint64*" "maxsize") + '("gboolean*" "async") + ) +) + (define-function event_new_qos (c-name "gst_event_new_qos") (return-type "GstEvent*") @@ -2421,6 +2433,7 @@ (return-type "GstIterator*") (parameters '("guint" "size") + '("GType" "type") '("GMutex*" "lock") '("guint32*" "master_cookie") '("GstIteratorNextFunction" "next") @@ -2434,6 +2447,7 @@ (c-name "gst_iterator_new_list") (return-type "GstIterator*") (parameters + '("GType" "type") '("GMutex*" "lock") '("guint32*" "master_cookie") '("GList**" "list") @@ -2629,6 +2643,34 @@ ) ) +(define-function gst_message_new_clock_provide + (c-name "gst_message_new_clock_provide") + (return-type "GstMessage*") + (parameters + '("GstObject*" "src") + '("GstClock*" "clock") + '("gboolean" "ready") + ) +) + +(define-function gst_message_new_clock_lost + (c-name "gst_message_new_clock_lost") + (return-type "GstMessage*") + (parameters + '("GstObject*" "src") + '("GstClock*" "clock") + ) +) + +(define-function gst_message_new_new_clock + (c-name "gst_message_new_new_clock") + (return-type "GstMessage*") + (parameters + '("GstObject*" "src") + '("GstClock*" "clock") + ) +) + (define-function gst_message_new_segment_start (c-name "gst_message_new_segment_start") (return-type "GstMessage*") @@ -2649,6 +2691,24 @@ ) ) +(define-function gst_message_new_application + (c-name "gst_message_new_application") + (return-type "GstMessage*") + (parameters + '("GstObject*" "src") + '("GstStructure*" "structure") + ) +) + +(define-function gst_message_new_element + (c-name "gst_message_new_element") + (return-type "GstMessage*") + (parameters + '("GstObject*" "src") + '("GstStructure*" "structure") + ) +) + (define-function message_new_custom (c-name "gst_message_new_custom") (return-type "GstMessage*") @@ -2696,6 +2756,35 @@ (parameters '("GstState*" "old_state") '("GstState*" "new_state") + '("GstState*" "pending") + ) +) + +(define-method parse_clock_provide + (of-object "GstMessage") + (c-name "gst_message_parse_clock_provide") + (return-type "none") + (parameters + '("GstClock**" "clock") + '("gboolean*" "ready") + ) +) + +(define-method parse_clock_lost + (of-object "GstMessage") + (c-name "gst_message_parse_clock_lost") + (return-type "none") + (parameters + '("GstClock**" "clock") + ) +) + +(define-method parse_new_clock + (of-object "GstMessage") + (c-name "gst_message_parse_new_clock") + (return-type "none") + (parameters + '("GstClock**" "clock") ) ) @@ -3004,6 +3093,22 @@ ;; From ../gstreamer/gst/gstpad.h +(define-function flow_get_name + (c-name "gst_flow_get_name") + (return-type "const-gchar*") + (parameters + '("GstFlowReturn" "ret") + ) +) + +(define-function flow_to_quark + (c-name "gst_flow_to_quark") + (return-type "GQuark") + (parameters + '("GstFlowReturn" "ret") + ) +) + (define-function gst_pad_get_type (c-name "gst_pad_get_type") (return-type "GType") @@ -5635,6 +5740,22 @@ ) ) +(define-function gst_gdouble_to_guint64 + (c-name "gst_gdouble_to_guint64") + (return-type "guint64") + (parameters + '("gdouble" "value") + ) +) + +(define-function gst_guint64_to_gdouble + (c-name "gst_guint64_to_gdouble") + (return-type "gdouble") + (parameters + '("guint64" "value") + ) +) + (define-function gst_util_uint64_scale (c-name "gst_util_uint64_scale") (return-type "guint64") @@ -5675,6 +5796,40 @@ ) ) +(define-function g_static_rec_cond_wait + (c-name "g_static_rec_cond_wait") + (return-type "none") + (parameters + '("GCond*" "cond") + '("GStaticRecMutex*" "mutex") + ) +) + +(define-function g_static_rec_cond_timed_wait + (c-name "g_static_rec_cond_timed_wait") + (return-type "gboolean") + (parameters + '("GCond*" "cond") + '("GStaticRecMutex*" "mutex") + '("GTimeVal*" "end_time") + ) +) + +(define-method abort_preroll + (of-object "GstElement") + (c-name "gst_element_abort_preroll") + (return-type "GstFlowReturn") +) + +(define-method finish_preroll + (of-object "GstElement") + (c-name "gst_element_finish_preroll") + (return-type "GstFlowReturn") + (parameters + '("GstPad*" "pad") + ) +) + (define-method create_all_pads (of-object "GstElement") (c-name "gst_element_create_all_pads") @@ -5893,14 +6048,6 @@ (caller-owns-return #t) ) -(define-function flow_get_name - (c-name "gst_flow_get_name") - (return-type "const-gchar*") - (parameters - '("GstFlowReturn" "ret") - ) -) - (define-method query_position (of-object "GstPad") (c-name "gst_pad_query_position") @@ -5934,12 +6081,6 @@ (varargs #t) ) -(define-method watch_for_state_change - (of-object "GstBin") - (c-name "gst_bin_watch_for_state_change") - (return-type "none") -) - (define-method merge (of-object "GstBuffer") (c-name "gst_buffer_merge") diff --git a/gst/gst.override b/gst/gst.override index 3cb88944b5..3f2a050e09 100644 --- a/gst/gst.override +++ b/gst/gst.override @@ -311,6 +311,12 @@ ignore gst_debug_log gst_debug_log_default gst_iterator_new_list + gst_task_set_lock + gst_clock_id_compare_func + gst_print_pad_caps + gst_util_set_value_from_string + gst_print_element_args + gst_atomic_int_set %% override-slot GstPluginFeature.tp_repr static PyObject * @@ -542,7 +548,8 @@ _wrap_gst_xml_get_topelements(PyGObject *self) for (l = xml_elements; l; l = l->next) { GstElement *element = (GstElement*)l->data; - PyList_Append(py_list, pygobject_new(G_OBJECT(element))); + PyList_Append(py_list, pygstobject_new(G_OBJECT(element))); + gst_object_unref (element); } return py_list; diff --git a/gst/gstbin.override b/gst/gstbin.override index 8049291080..d4d74d5057 100644 --- a/gst/gstbin.override +++ b/gst/gstbin.override @@ -136,8 +136,7 @@ _wrap_gst_bin_get_by_name(PyGObject *self, PyObject *args, PyObject *kwargs) /* pygobject_new handles NULL checking */ ret = pygstobject_new((GObject *)el); - - gst_object_unref (el); /* from _get_by_name */ + gst_object_unref (((PyGObject *) ret)->obj); /* from _get_by_name */ return ret; } %% diff --git a/gst/gstbuffer.override b/gst/gstbuffer.override index 4e093b7f80..92003f49a7 100644 --- a/gst/gstbuffer.override +++ b/gst/gstbuffer.override @@ -534,6 +534,28 @@ _wrap_gst_buffer__set_caps (PyGstMiniObject *self, PyObject *value, void *closur return -1; pyg_begin_allow_threads; gst_buffer_set_caps(GST_BUFFER(self->obj), caps); + gst_caps_unref (caps); pyg_end_allow_threads; return 0; } +%% +override gst_buffer_set_caps kwargs +static PyObject * +_wrap_gst_buffer_set_caps(PyGstMiniObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "caps", NULL }; + PyObject *py_caps; + GstCaps *caps; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GstBuffer.set_caps", kwlist, &py_caps)) + return NULL; + caps = pygst_caps_from_pyobject (py_caps, NULL); + if (PyErr_Occurred()) + return NULL; + pyg_begin_allow_threads; + gst_buffer_set_caps(GST_BUFFER(self->obj), caps); + gst_caps_unref (caps); + pyg_end_allow_threads; + Py_INCREF(Py_None); + return Py_None; +} diff --git a/gst/gstevent.override b/gst/gstevent.override index 2dba8eb8c3..839bb32580 100644 --- a/gst/gstevent.override +++ b/gst/gstevent.override @@ -1,4 +1,4 @@ -/* -*- Mode: C; ; c-file-style: "python" -*- */ +/* -*- Mode: C; ; c-file-style: "k&r"; c-basic-offset: 4 -*- */ /* gst-python * Copyright (C) 2005 Edward Hervey * @@ -24,11 +24,11 @@ override gst_event_get_structure noargs static PyObject * _wrap_gst_event_get_structure(PyGstMiniObject *self) { - GstStructure *ret; + GstStructure *ret; - ret = (GstStructure *) gst_event_get_structure(GST_EVENT(self->obj)); - /* pyg_boxed_new handles NULL checking */ - return pyg_boxed_new(GST_TYPE_STRUCTURE, ret, TRUE, TRUE); + ret = (GstStructure *) gst_event_get_structure(GST_EVENT(self->obj)); + /* pyg_boxed_new handles NULL checking */ + return pyg_boxed_new(GST_TYPE_STRUCTURE, ret, TRUE, TRUE); } %% @@ -36,17 +36,120 @@ override-slot GstEvent.tp_repr static PyObject * _wrap_gst_event_tp_repr (PyGObject *self) { - char *buf; - PyObject *retval; - GstEvent *event; + char *buf; + PyObject *retval; + GstEvent *event; - event = GST_EVENT(self->obj); + event = GST_EVENT(self->obj); - buf = g_strdup_printf ("", - gst_event_type_get_name (event->type), (long) self->obj); + buf = g_strdup_printf ("", + gst_event_type_get_name (event->type), (long) self->obj); - retval = PyString_FromString(buf); - g_free(buf); - return retval; + retval = PyString_FromString(buf); + g_free(buf); + return retval; } +%% +override gst_event_parse_newsegment noargs +static PyObject * +_wrap_gst_event_parse_newsegment (PyGstMiniObject *self) +{ + PyObject *ret; + gdouble rate; + GstFormat format; + gint64 start_value, stop_value, base; + if (GST_EVENT_TYPE(self->obj) != GST_EVENT_NEWSEGMENT) { + PyErr_SetString(PyExc_TypeError, "Even is not a 'NewSegment' event"); + return NULL; + } + + gst_event_parse_newsegment (GST_EVENT(self->obj), &rate, &format, + &start_value, &stop_value, &base); + + ret = PyList_New(0); + PyList_Append (ret, PyFloat_FromDouble(rate)); + PyList_Append (ret, pyg_enum_from_gtype (GST_TYPE_FORMAT, format)); + PyList_Append (ret, PyLong_FromUnsignedLongLong(start_value)); + PyList_Append (ret, PyLong_FromUnsignedLongLong(stop_value)); + PyList_Append (ret, PyLong_FromUnsignedLongLong(base)); + + return ret; +} +%% +override gst_event_parse_tag noargs +static PyObject * +_wrap_gst_event_parse_tag (PyGstMiniObject *self) +{ + PyObject *ret; + GstTagList *taglist; + + if (GST_EVENT_TYPE(self->obj) != GST_EVENT_TAG) { + PyErr_SetString(PyExc_TypeError, "Event is not an 'Tag' event"); + return NULL; + } + + gst_event_parse_tag (GST_EVENT(self->obj), &taglist); + + ret = pyg_boxed_new (GST_TYPE_TAG_LIST, taglist, TRUE, TRUE); + + return ret; +} +%% +override gst_event_parse_qos noargs +static PyObject * +_wrap_gst_event_parse_qos (PyGstMiniObject *self) +{ + PyObject *ret; + gdouble proportion; + GstClockTimeDiff diff; + GstClockTime timestamp; + + if (GST_EVENT_TYPE(self->obj) != GST_EVENT_QOS) { + PyErr_SetString(PyExc_TypeError, "Event is not an 'Qos' event"); + return NULL; + } + + gst_event_parse_qos (GST_EVENT(self->obj), &proportion, + &diff, ×tamp); + + ret = PyList_New (0); + PyList_Append (ret, PyFloat_FromDouble(proportion)); + PyList_Append (ret, PyLong_FromLongLong(diff)); + PyList_Append (ret, PyLong_FromUnsignedLongLong(timestamp)); + + return ret; +} +%% +override gst_event_parse_seek noargs +static PyObject * +_wrap_gst_event_parse_seek (PyGstMiniObject *self) +{ + PyObject *ret; + gdouble rate; + GstFormat format; + GstSeekFlags flags; + GstSeekType cur_type; + gint64 cur; + GstSeekType stop_type; + gint64 stop; + + if (GST_EVENT_TYPE(self->obj) != GST_EVENT_SEEK) { + PyErr_SetString(PyExc_TypeError, "Event is not an 'Seek' event"); + return NULL; + } + + gst_event_parse_seek (GST_EVENT(self->obj), &rate, &format, &flags, + &cur_type, &cur, &stop_type, &stop); + + ret = PyList_New (0); + PyList_Append (ret, PyFloat_FromDouble(rate)); + PyList_Append (ret, pyg_enum_from_gtype (GST_TYPE_FORMAT, format)); + PyList_Append (ret, pyg_flags_from_gtype (GST_TYPE_SEEK_FLAGS, flags)); + PyList_Append (ret, pyg_enum_from_gtype (GST_TYPE_SEEK_TYPE, cur_type)); + PyList_Append (ret, PyLong_FromUnsignedLongLong (cur)); + PyList_Append (ret, pyg_enum_from_gtype (GST_TYPE_SEEK_TYPE, stop_type)); + PyList_Append (ret, PyLong_FromUnsignedLongLong (stop)); + + return ret; +} diff --git a/gst/gstlibs.override b/gst/gstlibs.override index 17dccab094..3934375ff2 100644 --- a/gst/gstlibs.override +++ b/gst/gstlibs.override @@ -20,6 +20,12 @@ * Author: Johan Dahlin */ %% +ignore + gst_controller_new + gst_controller_*_valist + gst_controller_remove_properties_list + +%% override gst_controller_set args static PyObject * _wrap_gst_controller_set (PyGObject *self, PyObject *args) @@ -67,6 +73,31 @@ _wrap_gst_controller_set (PyGObject *self, PyObject *args) return Py_False; } %% +override gst_controller_get kwargs +static PyObject * +_wrap_gst_controller_get (PyGObject *self, PyObject *args, PyObject *kwargs) +{ + GstController *controller = (GstController *) self->obj; + static char *kwlist[] = { "propertyname", "timestamp", NULL }; + gchar *propertyname; + GstClockTime timestamp; + GValue *value = NULL; + PyObject *pyvalue; + + if (!PyArg_ParseTupleAndKeywords (args, kwargs, + "sL:GstController.get", + kwlist, &propertyname, ×tamp)) + return NULL; + + value = gst_controller_get (controller, propertyname, timestamp); + if (value) { + pyvalue = pyg_value_as_pyobject (value, FALSE); + return pyvalue; + } + Py_INCREF (Py_None); + return Py_None; +} +%% override gst_controller_new_list args static int _wrap_gst_controller_new_list(PyGObject *self, PyObject *args) @@ -101,3 +132,120 @@ _wrap_gst_controller_new_list(PyGObject *self, PyObject *args) pygobject_register_wrapper((PyObject *) self); return 0; } +%% +override gst_controller_remove_properties args +static PyObject * +_wrap_gst_controller_remove_properties (PyGObject *self, PyObject *args) +{ + GstController *controller = (GstController *) self->obj; + gint len; + GList *list = NULL; + gboolean res = FALSE; + PyObject *pret; + + if ((len = PyTuple_Size(args)) < 1) { + PyErr_SetString(PyExc_TypeError, "Please give at least one property name to remove"); + return NULL; + } + + while (len--) { + PyObject *temp; + gchar *str; + + temp = PyTuple_GetItem(args, len); + str = PyString_AsString(temp); + GST_INFO("prepending %s [%d]", str, len); + list = g_list_prepend(list, PyString_AsString(temp)); + } + + res = gst_controller_remove_properties_list(controller, list); + + if (res) + pret = Py_True; + else + pret = Py_False; + + Py_INCREF (pret); + + return pret; +} +%% +override gst_controller_set_from_list args +static PyObject * +_wrap_gst_controller_set_from_list (PyGObject *self, PyObject *args) +{ + GstController *controller = (GstController *) self->obj; + PyObject *temp; + gint len; + gchar *pname; + GSList *list = NULL; + GList *props; + gboolean res = FALSE; + GType vtype = 0; + PyObject *pret; + + if ((len = PyTuple_Size(args)) < 2) { + PyErr_SetString(PyExc_TypeError, "Please give a property name and a tuple of (time,value)"); + return NULL; + } + + temp = PyTuple_GetItem(args, 0); + if (!PyString_Check (temp)) { + PyErr_SetString(PyExc_TypeError, "First argument must be a string"); + return NULL; + } + pname = PyString_AsString(temp); + + /* Get the GType of the given property */ + g_mutex_lock (controller->lock); + for (props = controller->properties; props; props = g_list_next(props)) { + GstControlledProperty *prop = (GstControlledProperty *) props->data; + + if (!strcmp(prop->name, pname)) { + vtype = prop->type; + break; + } + } + g_mutex_unlock (controller->lock); + if (!vtype) + goto error; + + while (len-- > 1) { + PyObject *temp2; + GstTimedValue *tval; + + temp2 = PyTuple_GetItem(args, len); + if (!PyTuple_Check (temp2)) { + PyErr_SetString (PyExc_TypeError, "Tuple doesn't contain tuples !"); + goto error; + } + tval = g_new0(GstTimedValue, 1); + tval->timestamp = PyLong_AsUnsignedLongLong(PyTuple_GetItem(temp2, 0)); + g_value_init (&tval->value, vtype); + if ((pyg_value_from_pyobject (&tval->value, PyTuple_GetItem (temp2, 1))) < 0) { + PyErr_SetString (PyExc_TypeError, "Couldn't convert value to correct type"); + goto error; + }; + + list = g_slist_prepend(list, tval); + } + + res = gst_controller_set_from_list(controller, pname, list); + + if (res) + pret = Py_True; + else + pret = Py_False; + + Py_INCREF (pret); + + return pret; + + error: + while (list) { + g_free(list->data); + list = g_slist_next(list); + } + g_slist_free (list); + return NULL; +} diff --git a/gst/gstmodule.c b/gst/gstmodule.c index e4f9906c2a..6b33417f25 100644 --- a/gst/gstmodule.c +++ b/gst/gstmodule.c @@ -113,6 +113,7 @@ init_gst (void) PyObject *av, *tuple; int argc, i; char **argv; + GError *error = NULL; init_pygobject (); @@ -129,13 +130,14 @@ init_gst (void) argv = g_new (char *, argc); argv[0] = g_strdup(""); } - if (!gst_init_check (&argc, &argv)) { + if (!gst_init_check (&argc, &argv, &error)) { if (argv != NULL) { for (i = 0; i < argc; i++) g_free (argv[i]); g_free (argv); } PyErr_SetString (PyExc_RuntimeError, "can't initialize module gst"); + g_error_free (error); setlocale(LC_NUMERIC, "C"); return; } @@ -215,6 +217,8 @@ init_gst (void) pyg_type_wrapper_new(GST_TYPE_TYPE_FIND_FACTORY)); g_timeout_add_full (0, 100, python_do_pending_calls, NULL, NULL); + + atexit(gst_deinit); if (PyErr_Occurred ()) { Py_FatalError ("can't initialize module gst"); diff --git a/gst/gstpad.override b/gst/gstpad.override index 3318bb6aad..cb44eeaab0 100644 --- a/gst/gstpad.override +++ b/gst/gstpad.override @@ -226,7 +226,7 @@ call_link_function (GstPad *pad, GstPad *peer) g_value_init (&args[0], GST_TYPE_PAD); g_value_init (&args[1], GST_TYPE_PAD); g_value_set_object (&args[0], pad); - g_value_set_boxed (&args[1], peer); + g_value_set_object (&args[1], peer); closure = pad_private(pad)->link_function; @@ -340,51 +340,10 @@ _wrap_gst_pad_set_event_function (PyGObject *self, PyObject *args, PyObject *kwargs) { - SET_PAD_CLOSURE (self, args, kwargs, event_function) + SET_PAD_CLOSURE (self, args, + kwargs, event_function) } -%% -override gst_pad_set_get_function kwargs - -static void EXCEPTION_HANDLER -handle_get_function_exception (GValue *ret, guint n, const GValue *params) -{ - GstElement *element = gst_pad_get_parent (g_value_get_object (¶ms[0])); - - if (!_pygst_element_check_error (element)) - g_assert_not_reached (); /* only returns FALSE when there's no error */ -} - -static GstData* -call_get_function (GstPad *pad) -{ - GClosure *closure; - GValue ret = { 0, }; - GValue args = { 0, }; - GstData *data = NULL; - - g_value_init (&ret, GST_TYPE_DATA); - g_value_init (&args, GST_TYPE_REAL_PAD); - g_value_set_object (&args, pad); - closure = pad_private(pad)->get_function; - - g_closure_invoke (closure, &ret, 1, &args, NULL); - - data = g_value_get_boxed (&ret); - gst_data_ref (data); - - g_value_unset (&ret); - g_value_unset (&args); - return data; -} - -static PyObject* -_wrap_gst_pad_set_get_function (PyGObject *self, - PyObject *args, - PyObject *kwargs) -{ - SET_PAD_CLOSURE (self, args, kwargs, get_function) -} %% override-slot GstPad.tp_repr static PyObject * @@ -1018,3 +977,26 @@ _wrap_gst_pad_set_blocked_async (PyGObject *self, PyObject *args) return pret; } +%% +override gst_pad_set_caps kwargs +static PyObject * +_wrap_gst_pad_set_caps(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "caps", NULL }; + PyObject *py_caps; + int ret; + GstCaps *caps; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GstPad.set_caps", kwlist, &py_caps)) + return NULL; + caps = pygst_caps_from_pyobject (py_caps, NULL); + if (PyErr_Occurred()) + return NULL; + pyg_begin_allow_threads; + ret = gst_pad_set_caps(GST_PAD(self->obj), caps); + if (ret) + gst_caps_unref (caps); + pyg_end_allow_threads; + return PyBool_FromLong(ret); + +} diff --git a/gst/gstquery.override b/gst/gstquery.override index 782ebfdc2f..682ea7765f 100644 --- a/gst/gstquery.override +++ b/gst/gstquery.override @@ -30,7 +30,7 @@ _wrap_gst_query_parse_position (PyGstMiniObject *self) PyObject *ret; if (GST_QUERY_TYPE(self->obj) != GST_QUERY_POSITION) { - PyErr_SetString(PyExc_TypeError, "Query is not a position query"); + PyErr_SetString(PyExc_TypeError, "Query is not a 'Position' query"); return NULL; } @@ -53,7 +53,7 @@ _wrap_gst_query_parse_convert (PyGstMiniObject *self) PyObject *ret; if (GST_QUERY_TYPE(self->obj) != GST_QUERY_CONVERT) { - PyErr_SetString(PyExc_TypeError, "Query is not a convert query"); + PyErr_SetString(PyExc_TypeError, "Query is not a 'Convert' query"); return NULL; } @@ -69,3 +69,33 @@ _wrap_gst_query_parse_convert (PyGstMiniObject *self) return ret; } +%% +override gst_query_parse_segment noargs +static PyObject * +_wrap_gst_query_parse_segment (PyGstMiniObject *self) +{ + PyObject *ret; + gdouble rate; + GstFormat format; + gint64 start_value; + gint64 stop_value; + gint64 base; + + if (GST_QUERY_TYPE(self->obj) != GST_QUERY_SEGMENT) { + PyErr_SetString(PyExc_TypeError, "Query is not a 'Segment' query"); + return NULL; + } + + gst_query_parse_segment (GST_QUERY(self->obj), + &rate, &format, + &start_value, &stop_value, &base); + + ret = PyList_New(0); + PyList_Append (ret, PyFloat_FromDouble(rate)); + PyList_Append (ret, pyg_enum_from_gtype (GST_TYPE_FORMAT, format)); + PyList_Append (ret, PyLong_FromUnsignedLongLong(start_value)); + PyList_Append (ret, PyLong_FromUnsignedLongLong(stop_value)); + PyList_Append (ret, PyLong_FromUnsignedLongLong(base)); + + return ret; +} diff --git a/gst/libs.defs b/gst/libs.defs index a330b43c7d..66856875a3 100644 --- a/gst/libs.defs +++ b/gst/libs.defs @@ -98,6 +98,15 @@ (varargs #t) ) +(define-method remove_properties_list + (of-object "GstController") + (c-name "gst_controller_remove_properties_list") + (return-type "gboolean") + (parameters + '("GList*" "list") + ) +) + (define-method set (of-object "GstController") (c-name "gst_controller_set") diff --git a/gst/pygstminiobject.c b/gst/pygstminiobject.c index d7859955ee..e678f8cfef 100644 --- a/gst/pygstminiobject.c +++ b/gst/pygstminiobject.c @@ -142,8 +142,11 @@ pygstminiobject_register_wrapper (PyObject *self) PyGILState_STATE state; g_assert (obj); - GST_DEBUG ("inserting self %p in the table for object %p", self, obj); + g_assert (GST_IS_MINI_OBJECT (obj)); + state = pyg_gil_state_ensure (); + GST_DEBUG ("inserting self %p in the table for object %p [ref:%d]", + self, obj, GST_MINI_OBJECT_REFCOUNT_VALUE (obj)); g_hash_table_insert (_miniobjs, (gpointer) obj, (gpointer) self); GST_DEBUG ("There are now %d elements in the hash table", g_hash_table_size (_miniobjs)); @@ -204,7 +207,8 @@ pygstminiobject_new (GstMiniObject *obj) self->weakreflist = NULL; /* save wrapper pointer so we can access it later */ - GST_DEBUG ("inserting self %p in the table for object %p", self, obj); + GST_DEBUG ("inserting self %p in the table for object %p [ref:%d]", + self, obj, GST_MINI_OBJECT_REFCOUNT_VALUE (obj)); state = pyg_gil_state_ensure (); g_hash_table_insert (_miniobjs, (gpointer) obj, (gpointer) self); GST_DEBUG ("There are now %d elements in the hash table", @@ -226,20 +230,20 @@ pygstminiobject_dealloc(PyGstMiniObject *self) state = pyg_gil_state_ensure(); if (self->obj) { - GST_DEBUG ("removing self %p from the table for object %p", self, - self->obj); + GST_DEBUG ("removing self %p from the table for object %p [ref:%d]", self, + self->obj, GST_MINI_OBJECT_REFCOUNT_VALUE (self->obj)); g_assert (g_hash_table_remove (_miniobjs, (gpointer) self->obj)); GST_DEBUG ("There are now %d elements in the hash table", g_hash_table_size (_miniobjs)); gst_mini_object_unref(self->obj); + GST_DEBUG ("setting self %p -> obj to NULL", self); + self->obj = NULL; } - GST_DEBUG ("setting self %p -> obj to NULL", self); - self->obj = NULL; if (self->inst_dict) { Py_DECREF(self->inst_dict); + self->inst_dict = NULL; } - self->inst_dict = NULL; self->ob_type->tp_free((PyObject *) self); pyg_gil_state_release(state); diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 8c791a3d4e..853a2b66b1 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -61,7 +61,8 @@ GSTPYTHONSUPP = $(top_srcdir)/testsuite/gstpython.supp --suppressions=$(GSTSUPP) \ --suppressions=$(PYTHONSUPP) \ --suppressions=$(GSTPYTHONSUPP) \ - --tool=memcheck --leak-check=yes --trace-children=yes \ + --tool=memcheck --leak-check=yes --trace-children=yes \ + --leak-resolution=med --num-callers=50 \ $(PYTHON) \ $* 2>&1 | tee valgrind.log @if grep "tely lost" valgrind.log; then \ @@ -71,10 +72,10 @@ GSTPYTHONSUPP = $(top_srcdir)/testsuite/gstpython.supp @rm valgrind.log # valgrind all tests -valgrind: $(TESTS) +valgrind: $(tests) @echo "Valgrinding tests ..." @failed=0; \ - for t in $(filter-out $(VALGRIND_TESTS_DISABLE),$(TESTS)); do \ + for t in $(filter-out $(VALGRIND_TESTS_DISABLE),$(tests)); do \ make $$t.valgrind; \ if test "$$?" -ne 0; then \ echo "Valgrind error for test $$t"; \ diff --git a/testsuite/common.py b/testsuite/common.py index 85c45b77cf..25226bcf33 100644 --- a/testsuite/common.py +++ b/testsuite/common.py @@ -110,7 +110,7 @@ def run_silent(function, *args, **kwargs): class TestCase(unittest.TestCase): - _types = [gst.Element, gst.Pad, gst.Bus] + _types = [gst.Controller, gst.Object, gst.Element, gst.Pad, gst.Bus, gst.MiniObject] def gccollect(self): # run the garbage collector diff --git a/testsuite/gstpython.supp b/testsuite/gstpython.supp index 2f4641b153..26203c2eb9 100644 --- a/testsuite/gstpython.supp +++ b/testsuite/gstpython.supp @@ -47,11 +47,8 @@ write(buf) fun:__pthread_initialize_manager fun:pthread_create@@GLIBC_2.2.5 - fun:* - fun:* - fun:* - fun:* - fun:gst_task_start + fun:g_thread_create* + fun:g_thread_create* } { @@ -67,14 +64,145 @@ } { - memory loss when creating thread from gst_task_start + Syscall param clone(child_tidptr) contains uninitialised byte(s) + Memcheck:Param + clone(child_tidptr) + fun:clone +} + +{ + memory loss when creating thread Memcheck:Leak fun:malloc fun:__pthread_initialize_manager - fun:* - fun:* - fun:* - fun:* - fun:* - fun:gst_task_start + fun:pthread_create* +} + +# pyg_enable_threads memleak + +{ + memleak in pyg_enable_threads + Memcheck:Leak + fun:malloc + fun:* + fun:* + fun:* + fun:* + fun:* + fun:pyg_enable_threads +} + + +{ + memleak in pyg_enable_threads 2 + Memcheck:Leak + fun:malloc + fun:* + fun:* + fun:* + fun:* + fun:pyg_enable_threads +} + +{ + memleak in pyg_enable_threads 3 + Memcheck:Leak + fun:malloc + fun:* + fun:* + fun:* + fun:pyg_enable_threads +} + +#pygobject leaks + +{ + PyType_Ready leak + Memcheck:Leak + fun:malloc + fun:PyObject_Malloc + fun:_PyObject_GC_Malloc + fun:PyType_GenericAlloc + fun:* + fun:* + fun:PyType_Ready +} + +#gst debug category new leak +{ + gst debug category new leak + Memcheck:Leak + fun:malloc + fun:g_malloc + fun:g_strdup + fun:_gst_debug_category_new +} + +# memleak in gst_element_state_get_name that we can't get rid of +{ + gst_element_state_get_name + Memcheck:Leak + fun:malloc + fun:* + fun:g_vasprintf + fun:g_strdup* + fun:g_strdup* + fun:_wrap_gst_element_state_get_name +} + +#memleak in pygobject_new_with_interfaces +# weird, cos it seems to free the return value of g_type_interfaces +{ + _gst_element_factory_make + Memcheck:Leak + fun:malloc + fun:g_malloc + fun:g_type_interfaces +} + +#memleak in static_pad_template +{ + gst_static_pad_template_get + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:g_type_create_instance + fun:g_object_constructor + fun:gst_object_constructor + fun:* + fun:* + fun:* + fun:gst_static_pad_template_get +} + +#leak in libxml +{ + xml_parse_memory leak + Memcheck:Leak + fun:malloc + fun:* + fun:xml* +} + +# FIXME : This is an awful leak that has do to with the gst_pad_set_*_function wrappers +{ + leak in gst_pad_set_*_function wrappers + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:pad_private +} + +# python leak in runtime compiler +{ + python leak in runtime compiler + Memcheck:Leak + fun:malloc + fun:_PyObject_GC_Malloc + fun:_PyObject_GC_New* + fun:PyDict_New + fun:PySymtableEntry_New + fun:symtable_* + fun:symtable_* + fun:jcompile } diff --git a/testsuite/python.supp b/testsuite/python.supp index 642667437a..81554e1f13 100644 --- a/testsuite/python.supp +++ b/testsuite/python.supp @@ -356,3 +356,88 @@ } +# python init memleak +{ + Py_Main memleak + Memcheck:Leak + fun:malloc + fun:PyObject_Malloc + fun:_PyObject_GC_Malloc + fun:_PyObject_GC_* + fun:* + fun:* + fun:* + fun:* + fun:Py_InitializeEx +} + +{ + Py_Main memleak + Memcheck:Leak + fun:malloc + fun:PyObject_Malloc + fun:_PyObject_GC_Malloc + fun:_PyObject_GC_* + fun:* + fun:* + fun:* + fun:* + fun:* + fun:* + fun:* + fun:Py_InitializeEx +} + +{ + Py_Main memleak v2 + Memcheck:Leak + fun:malloc + fun:_PyObject_GC_Malloc + fun:_PyObject_GC_New + fun:* + fun:* + fun:* + fun:* + fun:* + fun:Py_InitializeEx +} + +{ + Read compiled module memleak + Memcheck:Leak + fun:malloc + fun:PyObject_Malloc + fun:_PyObject_GC_Malloc + fun:_PyObject_GC_NewVar + fun:* + fun:* + fun:* + fun:* + fun:* + fun:* + fun:* + fun:read_compiled_module +} + +{ + PyRun_SimpleFileExFlags memleak + Memcheck:Leak + fun:malloc + fun:_PyObject_GC_Malloc + fun:_PyObject_GC_New* + fun:* + fun:* + fun:* + fun:PyRun_SimpleFileExFlags +} + +# memleak in update_keyword_args +{ + update_keyword_args + Memcheck:Leak + fun:malloc + fun:_PyObject_GC_Malloc + fun:* + fun:* + fun:update_keyword_args +} diff --git a/testsuite/test_bin.py b/testsuite/test_bin.py index e8fe9c0c36..5dca82f238 100644 --- a/testsuite/test_bin.py +++ b/testsuite/test_bin.py @@ -150,7 +150,7 @@ class Preroll(TestCase): ret = self.bin.get_state(timeout=0.0) self.assertEquals(ret[0], gst.STATE_CHANGE_ASYNC) self.assertEquals(ret[1], gst.STATE_PAUSED) - self.assertEquals(ret[2], gst.STATE_VOID_PENDING) + self.assertEquals(ret[2], gst.STATE_PAUSED) # to actually complete preroll, we need to link and re-enable fakesrc src.set_state(gst.STATE_READY) diff --git a/testsuite/test_buffer.py b/testsuite/test_buffer.py index e97fb113ec..bce6d1abec 100644 --- a/testsuite/test_buffer.py +++ b/testsuite/test_buffer.py @@ -157,8 +157,11 @@ class BufferTest(TestCase): def testBufferCaps(self): buffer = gst.Buffer() caps = gst.caps_from_string('foo/blah') + gst.info("before settings caps") buffer.set_caps(caps) + gst.info("after settings caps") c = buffer.get_caps() + gst.info("after getting caps") self.assertEquals(caps, c) if __name__ == "__main__": diff --git a/testsuite/test_element.py b/testsuite/test_element.py index 7f4ea14ce0..71b9438627 100644 --- a/testsuite/test_element.py +++ b/testsuite/test_element.py @@ -39,47 +39,49 @@ class ElementTest(TestCase): assert element is not None, 'element is None' assert isinstance(element, gst.Element) assert element.get_name() == self.alias + +## FIXME : Make a new test for state changes, using bus signals -class FakeSinkTest(ElementTest): - FAKESINK_STATE_ERROR_NONE = "0" - FAKESINK_STATE_ERROR_NULL_READY, = "1" - FAKESINK_STATE_ERROR_READY_PAUSED, = "2" - FAKESINK_STATE_ERROR_PAUSED_PLAYING = "3" - FAKESINK_STATE_ERROR_PLAYING_PAUSED = "4" - FAKESINK_STATE_ERROR_PAUSED_READY = "5" - FAKESINK_STATE_ERROR_READY_NULL = "6" +## class FakeSinkTest(ElementTest): +## FAKESINK_STATE_ERROR_NONE = "0" +## FAKESINK_STATE_ERROR_NULL_READY, = "1" +## FAKESINK_STATE_ERROR_READY_PAUSED, = "2" +## FAKESINK_STATE_ERROR_PAUSED_PLAYING = "3" +## FAKESINK_STATE_ERROR_PLAYING_PAUSED = "4" +## FAKESINK_STATE_ERROR_PAUSED_READY = "5" +## FAKESINK_STATE_ERROR_READY_NULL = "6" - name = 'fakesink' - alias = 'sink' - def setUp(self): - ElementTest.setUp(self) - self.element = gst.element_factory_make('fakesink', 'sink') +## name = 'fakesink' +## alias = 'sink' +## def setUp(self): +## ElementTest.setUp(self) +## self.element = gst.element_factory_make('fakesink', 'sink') - def tearDown(self): - self.element.set_state(gst.STATE_NULL) - del self.element - ElementTest.tearDown(self) +## def tearDown(self): +## self.element.set_state(gst.STATE_NULL) +## del self.element +## ElementTest.tearDown(self) - def checkError(self, old_state, state, name): - assert self.element.get_state() == gst.STATE_NULL - assert self.element.set_state(old_state) - assert self.element.get_state() == old_state - self.element.set_property('state-error', name) - self.error = False - def error_cb(element, source, gerror, debug): - assert isinstance(element, gst.Element) - assert element == self.element - assert isinstance(source, gst.Element) - assert source == self.element - assert isinstance(gerror, gst.GError) - self.error = True +## def checkError(self, old_state, state, name): +## assert self.element.get_state() == gst.STATE_NULL +## assert self.element.set_state(old_state) +## assert self.element.get_state() == old_state +## self.element.set_property('state-error', name) +## self.error = False +## def error_cb(element, source, gerror, debug): +## assert isinstance(element, gst.Element) +## assert element == self.element +## assert isinstance(source, gst.Element) +## assert source == self.element +## assert isinstance(gerror, gst.GError) +## self.error = True - self.element.connect('error', error_cb) - self.element.set_state (state) - assert self.error, 'error not set' - #assert error_message.find('ERROR') != -1 +## self.element.connect('error', error_cb) +## self.element.set_state (state) +## assert self.error, 'error not set' +## #assert error_message.find('ERROR') != -1 - self.element.get_state() == old_state, 'state changed' +## self.element.get_state() == old_state, 'state changed' ## def testStateErrorNullReady(self): ## self.checkError(gst.STATE_NULL, gst.STATE_READY, @@ -105,24 +107,24 @@ class FakeSinkTest(ElementTest): ## self.checkError(gst.STATE_READY, gst.STATE_NULL, ## self.FAKESINK_STATE_ERROR_READY_NULL) - def checkStateChange(self, old, new): - def state_change_cb(element, old_s, new_s): - assert isinstance(element, gst.Element) - assert element == self.element - assert old_s == old - assert new_s == new +## def checkStateChange(self, old, new): +## def state_change_cb(element, old_s, new_s): +## assert isinstance(element, gst.Element) +## assert element == self.element +## assert old_s == old +## assert new_s == new - assert self.element.set_state(old) - assert self.element.get_state(0.0)[1] == old +## assert self.element.set_state(old) +## assert self.element.get_state(0.0)[1] == old -# FIXME: replace with messages -# self.element.connect('state-change', state_change_cb) +## # FIXME: replace with messages +## # self.element.connect('state-change', state_change_cb) - assert self.element.set_state(new) - assert self.element.get_state(0.0)[1] == new +## assert self.element.set_state(new) +## assert self.element.get_state(0.0)[1] == new - def testStateChangeNullReady(self): - self.checkStateChange(gst.STATE_NULL, gst.STATE_READY) +## def testStateChangeNullReady(self): +## self.checkStateChange(gst.STATE_NULL, gst.STATE_READY) ## def testStateChangeReadyPaused(self): ## self.checkStateChange(gst.STATE_READY, gst.STATE_PAUSED) @@ -136,8 +138,8 @@ class FakeSinkTest(ElementTest): ## def testStateChangePausedReady(self): ## self.checkStateChange(gst.STATE_PAUSED, gst.STATE_READY) - def testStateChangeReadyNull(self): - self.checkStateChange(gst.STATE_READY, gst.STATE_NULL) +## def testStateChangeReadyNull(self): +## self.checkStateChange(gst.STATE_READY, gst.STATE_NULL) class NonExistentTest(ElementTest): name = 'this-element-does-not-exist' @@ -154,7 +156,7 @@ class FileSinkTest(ElementTest): name = 'filesink' alias = 'sink' -class ElementName(unittest.TestCase): +class ElementName(TestCase): def testElementStateGetName(self): get_name = gst.element_state_get_name for state in ('NULL', diff --git a/testsuite/test_event.py b/testsuite/test_event.py index 163f2052e1..18492bee21 100644 --- a/testsuite/test_event.py +++ b/testsuite/test_event.py @@ -22,13 +22,14 @@ import os import sys -from common import gst, unittest, testhelper +from common import gst, unittest, testhelper, TestCase -class EventTest(unittest.TestCase): +class EventTest(TestCase): def setUp(self): pipeline = gst.parse_launch('fakesrc ! fakesink name=sink') self.sink = pipeline.get_by_name('sink') pipeline.set_state(gst.STATE_PLAYING) + TestCase.setUp(self) def testEventSeek(self): event = gst.event_new_seek(1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_FLUSH, @@ -95,7 +96,7 @@ class EventTest(unittest.TestCase): # # #print self.playAndIter() -class TestEmit(unittest.TestCase): +class TestEmit(TestCase): def testEmit(self): object = testhelper.get_object() object.connect('event', self._event_cb) diff --git a/testsuite/test_ghostpad.py b/testsuite/test_ghostpad.py index 41c89a03e4..fad9d6bc03 100644 --- a/testsuite/test_ghostpad.py +++ b/testsuite/test_ghostpad.py @@ -53,6 +53,7 @@ gobject.type_register(SinkBin) class PipeTest(TestCase): def setUp(self): + gst.info("setUp") TestCase.setUp(self) self.pipeline = gst.Pipeline() self.assertEquals(self.pipeline.__gstrefcount__, 1) @@ -66,8 +67,10 @@ class PipeTest(TestCase): self.assertEquals(sys.getrefcount(self.src), 3) self.assertEquals(self.sink.__gstrefcount__, 1) self.assertEquals(sys.getrefcount(self.sink), 3) + gst.info("end of SetUp") def tearDown(self): + gst.info("tearDown") self.assertEquals(self.pipeline.__gstrefcount__, 1) self.assertEquals(sys.getrefcount(self.pipeline), 3) self.assertEquals(self.src.__gstrefcount__, 2) @@ -97,7 +100,7 @@ class PipeTest(TestCase): self.sink.connect_handoff(self._sink_handoff_cb) self._handoffs = 0 - self.pipeline.set_state_async(gst.STATE_PLAYING) + self.pipeline.set_state(gst.STATE_PLAYING) while True: (ret, cur, pen) = self.pipeline.get_state(timeout=None) if ret == gst.STATE_CHANGE_SUCCESS and cur == gst.STATE_PLAYING: @@ -106,7 +109,7 @@ class PipeTest(TestCase): while self._handoffs < 10: pass - self.pipeline.set_state_async(gst.STATE_NULL) + self.pipeline.set_state(gst.STATE_NULL) while True: (ret, cur, pen) = self.pipeline.get_state(timeout=None) if ret == gst.STATE_CHANGE_SUCCESS and cur == gst.STATE_NULL: @@ -126,7 +129,7 @@ class PipeTest(TestCase): self._probed = False - self.pipeline.set_state_async(gst.STATE_PLAYING) + self.pipeline.set_state(gst.STATE_PLAYING) while True: (ret, cur, pen) = self.pipeline.get_state(timeout=None) if ret == gst.STATE_CHANGE_SUCCESS and cur == gst.STATE_PLAYING: @@ -138,7 +141,7 @@ class PipeTest(TestCase): while self._handoffs < 10: pass - self.pipeline.set_state_async(gst.STATE_NULL) + self.pipeline.set_state(gst.STATE_NULL) while True: (ret, cur, pen) = self.pipeline.get_state(timeout=None) if ret == gst.STATE_CHANGE_SUCCESS and cur == gst.STATE_NULL: @@ -162,7 +165,7 @@ class PipeTest(TestCase): # FIXME: the following print can cause a lock-up; why ? # print target # if we don't set async, it will possibly end up in PAUSED - self.sink.set_state_async(target) + self.sink.set_state(target) gst.debug('linking') self.src.link(self.sink) diff --git a/testsuite/test_iterator.py b/testsuite/test_iterator.py index 4a4e22542c..82f26da9c9 100644 --- a/testsuite/test_iterator.py +++ b/testsuite/test_iterator.py @@ -41,24 +41,34 @@ class IteratorTest(TestCase): # XXX : There seems to be a problem about the GType # set in gst_bin_iterated_sorted -## def testBinIterateSorted(self): -## gst.info("testBinIterateSorted beginning") -## pipeline = gst.parse_launch("fakesrc name=src ! fakesink name=sink") -## gst.info("before calling pipeline.sorted()") -## elements = list(pipeline.sorted()) -## gst.info("after calling pipeline.sorted()") -## fakesrc = pipeline.get_by_name("src") -## fakesink = pipeline.get_by_name("sink") + def testBinIterateSorted(self): + pipeline = gst.parse_launch("fakesrc name=src ! fakesink name=sink") + elements = list(pipeline.sorted()) + fakesrc = pipeline.get_by_name("src") + fakesink = pipeline.get_by_name("sink") -## self.assertEqual(elements[0], fakesink) -## self.assertEqual(elements[1], fakesrc) -## gst.info("testBinIterateSorted end") + self.assertEqual(elements[0], fakesink) + self.assertEqual(elements[1], fakesrc) + + def testBinIterateRecurse(self): + pipeline = gst.parse_launch("fakesrc name=src ! fakesink name=sink") + elements = list(pipeline.recurse()) + fakesrc = pipeline.get_by_name("src") + fakesink = pipeline.get_by_name("sink") + + self.assertEqual(elements[0], fakesink) + self.assertEqual(elements[1], fakesrc) def testBinIterateSinks(self): pipeline = gst.parse_launch("fakesrc name=src ! fakesink name=sink") - elements = list(pipeline.elements()) + elements = list(pipeline.sinks()) fakesrc = pipeline.get_by_name("src") fakesink = pipeline.get_by_name("sink") + + self.assertEqual(len(elements), 1) + self.failUnless(fakesink in elements) + self.failUnless(not fakesrc in elements) + def testIteratePadsFakeSrc(self): fakesrc = gst.element_factory_make('fakesrc') diff --git a/testsuite/test_message.py b/testsuite/test_message.py index ea232050b3..88cdeb6d54 100644 --- a/testsuite/test_message.py +++ b/testsuite/test_message.py @@ -22,11 +22,13 @@ import sys from common import gobject, gst, unittest, TestCase import gc -class NewTest(unittest.TestCase): +class NewTest(TestCase): def testEOS(self): + gst.info("creating new bin") b = gst.Bin() + gst.info("creating new EOS message from that bin") m = gst.message_new_eos(b) - while gc.collect(): pass + gst.info("got message : %s" % m) if __name__ == "__main__": unittest.main() diff --git a/testsuite/test_pipeline.py b/testsuite/test_pipeline.py index 00b29799dc..4cd8a2381c 100644 --- a/testsuite/test_pipeline.py +++ b/testsuite/test_pipeline.py @@ -90,7 +90,6 @@ class PipelineAndBus(TestCase): def setUp(self): TestCase.setUp(self) self.pipeline = gst.Pipeline('test-pipeline') - self.pipeline.set_property('play-timeout', 0L) source = gst.element_factory_make('fakesrc', 'source') sink = gst.element_factory_make('fakesink', 'sink') self.pipeline.add(source, sink) @@ -143,7 +142,7 @@ class PipelineAndBus(TestCase): def testPlaying(self): self.final = gst.STATE_PLAYING - ret = self.pipeline.set_state_async(gst.STATE_PLAYING) + ret = self.pipeline.set_state(gst.STATE_PLAYING) self.assertEquals(ret, gst.STATE_CHANGE_ASYNC) # go into a main loop to wait for messages @@ -152,8 +151,8 @@ class PipelineAndBus(TestCase): # we go to READY so we get messages; going to NULL would set # the bus flushing self.final = gst.STATE_READY - ret = self.pipeline.set_state_async(gst.STATE_READY) - self.assertEquals(ret, gst.STATE_CHANGE_ASYNC) + ret = self.pipeline.set_state(gst.STATE_READY) + self.assertEquals(ret, gst.STATE_CHANGE_SUCCESS) self.loop.run() # FIXME: not setting to NULL causes a deadlock; we might want to