gst: Don't use private GstPad API to add data/buffer/event probes
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 25 May 2011 07:38:22 +0000 (09:38 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 25 May 2011 07:38:22 +0000 (09:38 +0200)
This does not work anymore with latest core because of the
pad cache that enables use of a fast path during data passing
in many situations.

Fixes bug #650987.

gst/gstpad.override

index 7ca50f5..89716a0 100644 (file)
@@ -859,175 +859,175 @@ _wrap_gst_pad_new(PyGObject *self, PyObject *args, PyObject *kwargs)
 }
 %%
 override gst_pad_add_data_probe args
-static PyObject *
-_wrap_gst_pad_add_data_probe(PyGObject *self, PyObject *args)
+
+static void
+data_probe_destroy_data (gpointer data)
 {
-    GstPad *pad = GST_PAD(self->obj);
-    PyObject *method = NULL;
-    PyObject *rv = NULL;
-    PyObject *mylist = PyList_New(1);
-    PyObject *mynewlist = NULL;
-    PyObject *myargs = NULL;
-    PyObject *signalname = NULL;
+    PyGILState_STATE state;
+    PyObject *py_data = (PyObject *) data;
+    
+    state = pyg_gil_state_ensure();
+    Py_DECREF (py_data);
 
-    signalname = PyString_FromString("have-data");
+    pyg_gil_state_release(state);
+}
 
-    if (PyList_SetItem(mylist, 0, signalname)) {
-       Py_DECREF(mylist);
-       return NULL;
-    }
+static gboolean
+data_probe_callback_marshal(GstPad *pad, GstMiniObject *obj, gpointer user_data)
+{
+    PyGILState_STATE state;
+    PyObject *callback, *args;
+    PyObject *pret;
+    PyObject *py_user_data;
+    gboolean ret;
 
-    mynewlist = PySequence_InPlaceConcat(mylist, args);
+    g_return_val_if_fail(user_data != NULL, TRUE);
 
-    Py_DECREF(mylist);
+    state = pyg_gil_state_ensure();
 
-    if (!mynewlist)
-       return NULL;
+    py_user_data = (PyObject *) user_data;
 
-    myargs = PyList_AsTuple(mynewlist);
+    callback = PyTuple_GetItem(py_user_data, 0);
+    args = Py_BuildValue("(NN)",
+             pygobject_new(G_OBJECT(pad)),
+             pygstminiobject_new(GST_MINI_OBJECT(obj)));
+    
+    {
+        PyObject *tmp = args;
+        args = PySequence_Concat(tmp, PyTuple_GetItem(py_user_data, 1));
+        Py_DECREF (tmp);
+    }
 
-    Py_DECREF(mynewlist);
+    pret = PyObject_CallObject(callback, args);
+    Py_DECREF(args);
 
-    if (!myargs)
-       return NULL;
+    if (!pret) {
+        PyErr_Print();
+        ret = TRUE;
+    } else {
+        ret = PyObject_IsTrue(pret)? TRUE : FALSE;
+        Py_DECREF(pret);
+    }
+    
+    pyg_gil_state_release(state);
+}
 
-    method = PyObject_GetAttrString((PyObject*)self, "connect");
+static PyObject *
+_wrap_gst_pad_add_data_probe(PyGObject *self, PyObject *args)
+{
+    PyObject *callback, *cbargs = NULL, *data;
+    PyObject *pret;
+    gulong ret;
+    gint len;
 
-    if (!method) {
-       Py_DECREF(mylist);
+    len = PyTuple_Size(args);
+    if (len < 1) {
+        PyErr_SetString(PyExc_TypeError, "Requires at least 1 arg");
         return NULL;
     }
 
-    GST_OBJECT_LOCK (pad);
-
-    rv = PyObject_CallObject(method, myargs);
-    if (rv) {
-       GST_PAD_DO_BUFFER_SIGNALS (pad)++;
-       GST_PAD_DO_EVENT_SIGNALS (pad)++;
-       GST_DEBUG_OBJECT (pad, "adding data probe, now %d buffer probes "
-                         "and %d event probes", GST_PAD_DO_BUFFER_SIGNALS (pad),
-                         GST_PAD_DO_EVENT_SIGNALS (pad));
+    callback = PyTuple_GetItem(args, 0);
+    if (!PyCallable_Check(callback)) {
+        PyErr_SetString(PyExc_TypeError, "callback is not callable");
+        return NULL;
     }
+    cbargs = PySequence_GetSlice(args, 1, len);
+    if (cbargs == NULL)
+        return NULL;
+    data = Py_BuildValue("(ON)", callback, cbargs);
+    if (data == NULL)
+        return NULL;
 
-    GST_OBJECT_UNLOCK (pad);
+    pyg_begin_allow_threads;
+    ret = gst_pad_add_data_probe_full(GST_PAD(self->obj),
+        (GCallback) data_probe_callback_marshal, data,
+       data_probe_destroy_data);
+    pyg_end_allow_threads;
 
-    Py_DECREF(myargs);
-    Py_DECREF(method);
+    pret = PyLong_FromUnsignedLong(ret);
+    Py_INCREF(pret);
 
-    return rv;
+    return pret;
 }
 %%
 override gst_pad_add_event_probe args
 static PyObject *
 _wrap_gst_pad_add_event_probe(PyGObject *self, PyObject *args)
 {
-    GstPad *pad = GST_PAD(self->obj);
-    PyObject *method = NULL;
-    PyObject *rv = NULL;
-    PyObject *mylist = PyList_New(1);
-    PyObject *mynewlist = NULL;
-    PyObject *myargs = NULL;
-    PyObject *signalname = NULL;
-
-    signalname = PyString_FromString("have-data::event");
+    PyObject *callback, *cbargs = NULL, *data;
+    PyObject *pret;
+    gulong ret;
+    gint len;
 
-    if (PyList_SetItem(mylist, 0, signalname)) {
-       Py_DECREF(mylist);
-       return NULL;
+    len = PyTuple_Size(args);
+    if (len < 1) {
+        PyErr_SetString(PyExc_TypeError, "Requires at least 1 arg");
+        return NULL;
     }
 
-    mynewlist = PySequence_InPlaceConcat(mylist, args);
-
-    Py_DECREF(mylist);
-
-    if (!mynewlist)
-       return NULL;
-
-    myargs = PyList_AsTuple(mynewlist);
-
-    Py_DECREF(mynewlist);
-
-    if (!myargs)
-       return NULL;
-
-    method = PyObject_GetAttrString((PyObject*)self, "connect");
-
-    if (!method) {
-       Py_DECREF(mylist);
+    callback = PyTuple_GetItem(args, 0);
+    if (!PyCallable_Check(callback)) {
+        PyErr_SetString(PyExc_TypeError, "callback is not callable");
         return NULL;
     }
+    cbargs = PySequence_GetSlice(args, 1, len);
+    if (cbargs == NULL)
+        return NULL;
+    data = Py_BuildValue("(ON)", callback, cbargs);
+    if (data == NULL)
+        return NULL;
 
-    GST_OBJECT_LOCK (pad);
-
-    rv = PyObject_CallObject(method, myargs);
-    if (rv) {
-       GST_PAD_DO_EVENT_SIGNALS (pad)++;
-       GST_DEBUG_OBJECT (pad, "adding event probe, now %d probes",
-                         GST_PAD_DO_EVENT_SIGNALS (pad));
-   }
-    GST_OBJECT_UNLOCK (pad);
+    pyg_begin_allow_threads;
+    ret = gst_pad_add_event_probe_full(GST_PAD(self->obj),
+        (GCallback) data_probe_callback_marshal, data,
+       data_probe_destroy_data);
+    pyg_end_allow_threads;
 
-    Py_DECREF(myargs);
-    Py_DECREF(method);
+    pret = PyLong_FromUnsignedLong(ret);
+    Py_INCREF(pret);
 
-    return rv;
+    return pret;
 }
 %%
 override gst_pad_add_buffer_probe args
+
 static PyObject *
 _wrap_gst_pad_add_buffer_probe(PyGObject *self, PyObject *args)
 {
-    GstPad *pad = GST_PAD(self->obj);
-    PyObject *method = NULL;
-    PyObject *rv = NULL;
-    PyObject *mylist = PyList_New(1);
-    PyObject *mynewlist = NULL;
-    PyObject *myargs = NULL;
-    PyObject *signalname = NULL;
-
-    signalname = PyString_FromString("have-data::buffer");
+    PyObject *callback, *cbargs = NULL, *data;
+    PyObject *pret;
+    gulong ret;
+    gint len;
 
-    if (PyList_SetItem(mylist, 0, signalname)) {
-       Py_DECREF(mylist);
-       return NULL;
+    len = PyTuple_Size(args);
+    if (len < 1) {
+        PyErr_SetString(PyExc_TypeError, "Requires at least 1 arg");
+        return NULL;
     }
 
-    mynewlist = PySequence_InPlaceConcat(mylist, args);
-
-    Py_DECREF(mylist);
-
-    if (!mynewlist)
-       return NULL;
-
-    myargs = PyList_AsTuple(mynewlist);
-
-    Py_DECREF(mynewlist);
-
-    if (!myargs)
-       return NULL;
-
-    method = PyObject_GetAttrString((PyObject*)self, "connect");
-
-    if (!method) {
-       Py_DECREF(mylist);
+    callback = PyTuple_GetItem(args, 0);
+    if (!PyCallable_Check(callback)) {
+        PyErr_SetString(PyExc_TypeError, "callback is not callable");
         return NULL;
     }
+    cbargs = PySequence_GetSlice(args, 1, len);
+    if (cbargs == NULL)
+        return NULL;
+    data = Py_BuildValue("(ON)", callback, cbargs);
+    if (data == NULL)
+        return NULL;
 
-    GST_OBJECT_LOCK (pad);
-
-    rv = PyObject_CallObject(method, myargs);
-    if (rv) {
-       GST_PAD_DO_BUFFER_SIGNALS (pad)++;
-       GST_DEBUG_OBJECT (pad, "adding buffer probe, now %d probes",
-                         GST_PAD_DO_BUFFER_SIGNALS (pad));
-   }
-
-    GST_OBJECT_UNLOCK (pad);
+    pyg_begin_allow_threads;
+    ret = gst_pad_add_buffer_probe_full(GST_PAD(self->obj),
+        (GCallback) data_probe_callback_marshal, data,
+       data_probe_destroy_data);
+    pyg_end_allow_threads;
 
-    Py_DECREF(myargs);
-    Py_DECREF(method);
+    pret = PyLong_FromUnsignedLong(ret);
+    Py_INCREF(pret);
 
-    return rv;
+    return pret;
 }
 %%
 override-slot GstPadTemplate.tp_getattr