/* -*- Mode: C; c-basic-offset: 4 -*- */ /* gst-python * Copyright (C) 2002 David I. Lehn * Copyright (C) 2004 Johan Dahlin * * 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. * * Author: David I. Lehn */ %% headers /* define this for all source files that don't run init_pygobject() * before including pygobject.h */ #define NO_IMPORT_PYGOBJECT #ifdef HAVE_CONFIG_H # include #endif #include "common.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pygstvalue.h" #include "pygstminiobject.h" #include "pygstexception.h" /* These headers have been included directly to get around multiple * GetAttrString calls */ #include #include GST_DEBUG_CATEGORY_EXTERN (python_debug); GST_DEBUG_CATEGORY_EXTERN (pygst_debug); #define GST_CAT_DEFAULT pygst_debug /* This function checks if a former Python code threw an exception and if * so, transforms this exception into an error on the given GstElement. * This allows code run on the element to just raise an exception instead of * returning GStreamer specific return values. * The exception is cleared afterwards. */ gboolean _pygst_element_check_error (GstElement *element) { PyObject *type, *value, *traceback, *lineno, *msg, *typemsg; PyFrameObject *frame; if (!PyErr_Occurred()) return FALSE; PyErr_Fetch (&type, &value, &traceback); if (traceback) { frame = (PyFrameObject *) PyObject_GetAttrString (traceback, "tb_frame"); lineno = PyObject_GetAttrString (traceback, "tb_lineno"); } else { frame = NULL; lineno = NULL; } msg = PyObject_Str (value); typemsg = PyObject_Str (type); if (msg && PyString_Check (msg)) { gst_element_message_full (element, GST_MESSAGE_ERROR, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED, g_strdup (PyString_AsString (msg)), typemsg ? g_strconcat (PyString_AsString (typemsg), ": ", PyString_AsString (msg), NULL) : g_strdup (PyString_AsString (msg)), frame ? PyString_AsString(frame->f_code->co_filename) : "???", frame ? PyString_AsString(frame->f_code->co_name) : "???", lineno ? PyInt_AsLong (lineno) : 0); } else { gst_element_message_full (element, GST_MESSAGE_ERROR, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_TOO_LAZY, NULL, NULL, frame ? PyString_AsString(frame->f_code->co_filename) : "???", frame ? PyString_AsString(frame->f_code->co_name) : "???", lineno ? PyInt_AsLong (lineno) : 0); } PyErr_Clear (); Py_XDECREF (frame); Py_XDECREF (lineno); Py_DECREF (msg); Py_DECREF (typemsg); return TRUE; } #ifdef pyg_register_class_init PyTypeObject PyGstPadTemplate_Type; static int add_templates (gpointer gclass, PyObject *templates) { gint i, len; PyGObject *templ; if (pygobject_check(templates, &PyGstPadTemplate_Type)) { gst_element_class_add_pad_template (gclass, GST_PAD_TEMPLATE (pygobject_get (templates))); return 0; } if (!PyTuple_Check(templates)) { PyErr_SetString(PyExc_TypeError, "__gsttemplates__ attribute neither a tuple nor a GstPadTemplate!"); return -1; } len = PyTuple_Size(templates); if (len == 0) return 0; for (i = 0; i < len; i++) { templ = (PyGObject*) PyTuple_GetItem(templates, i); if (!pygobject_check(templ, &PyGstPadTemplate_Type)) { PyErr_SetString(PyExc_TypeError, "entries for __gsttemplates__ must be of type GstPadTemplate"); return -1; } } for (i = 0; i < len; i++) { templ = (PyGObject*) PyTuple_GetItem(templates, i); gst_element_class_add_pad_template (gclass, GST_PAD_TEMPLATE (templ->obj)); } return 0; } static int _pygst_element_set_details (gpointer gclass, PyObject *details) { GstElementDetails gstdetails = { 0, }; if (!PyTuple_Check (details)) { PyErr_SetString(PyExc_TypeError, "__gstdetails__ must be a tuple"); return -1; } if (PyTuple_Size (details) != 4) { PyErr_SetString(PyExc_TypeError, "__gstdetails__ must be contain 4 elements"); return -1; } if (!PyArg_ParseTuple (details, "ssss", &gstdetails.longname, &gstdetails.klass, &gstdetails.description, &gstdetails.author)) { PyErr_SetString (PyExc_TypeError, "__gstdetails__ must be contain 4 strings"); return -1; } gst_element_class_set_details (gclass, &gstdetails); return 0; } static int _pygst_element_init (gpointer gclass, PyTypeObject *pyclass) { PyObject *templates, *details; templates = PyDict_GetItemString(pyclass->tp_dict, "__gsttemplates__"); if (templates) { if (add_templates(gclass, templates) != 0) return -1; } else { PyErr_Clear(); } details = PyDict_GetItemString(pyclass->tp_dict, "__gstdetails__"); if (details) { if (_pygst_element_set_details (gclass, details) != 0) return -1; PyDict_DelItemString(pyclass->tp_dict, "__gstdetails__"); } else { PyErr_Clear(); } return 0; } #endif static PyObject * pygst_debug_log (PyObject *pyobject, PyObject *string, GstDebugLevel level, gboolean isgstobject) { #ifndef GST_DISABLE_GST_DEBUG gchar *str; gchar *function; gchar *filename; int lineno; PyFrameObject *frame; GObject *object = NULL; if (!PyArg_ParseTuple(string, "s:gst.debug_log", &str)) { PyErr_SetString(PyExc_TypeError, "Need a string!"); return NULL; } frame = PyEval_GetFrame(); function = PyString_AsString(frame->f_code->co_name); filename = g_path_get_basename(PyString_AsString(frame->f_code->co_filename)); lineno = PyCode_Addr2Line(frame->f_code, frame->f_lasti); /* gst_debug_log : category, level, file, function, line, object, format, va_list */ if (isgstobject) object = G_OBJECT (pygobject_get (pyobject)); gst_debug_log (python_debug, level, filename, function, lineno, object, "%s", str); if (filename) g_free(filename); Py_INCREF (Py_None); #endif return Py_None; } %% include gstbin.override gstbuffer.override gstbus.override gstcaps.override gstelement.override gstelementfactory.override gstevent.override gstmessage.override gstobject.override gstpad.override gstquery.override gststructure.override gsttaglist.override gstlibs.override gstbase.override gstversion.override %% init { /* FIXME: new in pygtk-2.6 */ #ifdef pyg_register_class_init pyg_register_class_init (GST_TYPE_ELEMENT, _pygst_element_init); #endif if (!pygst_value_init()) return; gst_controller_init(NULL, NULL); } %% modulename gst %% import gobject.GObject as PyGObject_Type %% ignore-glob _* *_copy *_error_quark *_free *_get_type *_private *_thyself *_valist *_ref *_unref *_init *_deinit *_full gst_class_* gst_init* gst_interface_* gst_value_* gst_param_spec_* %% ignore gst_alloc_trace_list gst_alloc_trace_get gst_error_get_message gst_parse_launchv gst_trace_read_tsc 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 gst_caps_replace gst_mini_object_replace gst_filter_run gst_flow_to_quark gst_implements_interface_cast gst_implements_interface_check gst_plugin_get_module gst_object_sink gst_version %% override-slot GstPluginFeature.tp_repr static PyObject * _wrap_gst_plugin_feature_tp_repr(PyObject *self) { gchar *repr; PyObject *ret; GstPluginFeature *feature = GST_PLUGIN_FEATURE (pygobject_get (self)); repr = g_strdup_printf ("<%s %s @ 0x%lx>", self->ob_type->tp_name, gst_plugin_feature_get_name (feature), (long) self); ret = PyString_FromString(repr); g_free (repr); return ret; } %% override-slot GstPluginFeature.tp_str static PyObject * _wrap_gst_plugin_feature_tp_str(PyObject *self) { gchar *repr; PyObject *ret; GstPluginFeature *feature = GST_PLUGIN_FEATURE (pygobject_get (self)); repr = g_strdup_printf ("<%s %s (%d)>", self->ob_type->tp_name, gst_plugin_feature_get_name (feature), gst_plugin_feature_get_rank (feature)); ret = PyString_FromString(repr); g_free (repr); return ret; } %% override gst_type_find_factory_get_caps noargs static PyObject * _wrap_gst_type_find_factory_get_caps(PyGObject *self) { GstCaps *ret = (GstCaps*)gst_type_find_factory_get_caps(GST_TYPE_FIND_FACTORY(self->obj)); return pyg_boxed_new(GST_TYPE_CAPS, ret, TRUE, TRUE); } %% override-attr GError.domain static PyObject * _wrap_gst_g_error__get_domain(PyGObject *self, void *closure) { return PyString_FromString(g_quark_to_string(((GError*)self->obj)->domain)); } %% override-slot GError.tp_str static PyObject * _wrap_gst_g_error_tp_str(PyGObject *self) { GError *error = (GError*)self->obj; return PyString_FromString(gst_error_get_message (error->domain, error->code)); } %% override-attr GstDate.day static PyObject * _wrap_gst_date__get_day(PyGObject *self, void *closure) { return PyInt_FromLong(g_date_get_day((GDate*)self->obj)); } static int _wrap_gst_date__set_day(PyGObject *self, PyObject *value, void *closure) { GDate *date = (GDate *) self->obj; if (!(PyInt_Check(value))) return -1; g_date_set_day(date, (int) PyInt_AsLong(value)); return 0; } %% override-attr GstDate.month static PyObject * _wrap_gst_date__get_month(PyGObject *self, void *closure) { return PyInt_FromLong(g_date_get_month((GDate*)self->obj)); } static int _wrap_gst_date__set_month(PyGObject *self, PyObject *value, void *closure) { GDate *date = (GDate *) self->obj; if (!(PyInt_Check(value))) return -1; g_date_set_month(date, (int) PyInt_AsLong(value)); return 0; } %% override-attr GstDate.year static PyObject * _wrap_gst_date__get_year(PyGObject *self, void *closure) { return PyInt_FromLong(g_date_get_year((GDate*)self->obj)); } static int _wrap_gst_date__set_year(PyGObject *self, PyObject *value, void *closure) { GDate *date = (GDate *) self->obj; if (!(PyInt_Check(value))) return -1; g_date_set_year(date, (int) PyInt_AsLong(value)); return 0; } %% override-slot GstDate.tp_repr static PyObject * _wrap_gst_date_tp_repr(PyGObject *self) { GDate *date = (GDate *) self->obj; return PyString_FromFormat ("", g_date_get_day(date), g_date_get_month(date), g_date_get_year(date)); } %% override gst_registry_get_path_list static PyObject * _wrap_gst_registry_get_path_list (PyGObject *self) { GstRegistry *registry; GList *l, *paths; PyObject *list; gint i; registry = GST_REGISTRY (self->obj); paths = gst_registry_get_path_list (registry); list = PyList_New (g_list_length(paths)); for (l = paths, i = 0; l; l = l->next, ++i) { gchar *path = (gchar *) l->data; PyList_SetItem (list, i, PyString_FromString(path)); } g_list_free (paths); return list; } %% override gst_registry_get_plugin_list static PyObject * _wrap_gst_registry_get_plugin_list (PyGObject *self) { GstRegistry *registry; GList *l, *plugins; PyObject *list; gint i; registry = GST_REGISTRY (self->obj); plugins = gst_registry_get_plugin_list (registry); list = PyList_New (g_list_length(plugins)); for (l = plugins, i = 0; l; l = l->next, ++i) { GstPlugin *plugin = (GstPlugin *) l->data; PyObject *object = pygstobject_new (G_OBJECT (plugin)); gst_object_unref (plugin); PyList_SetItem (list, i, object); } g_list_free (plugins); return list; } %% override gst_registry_get_feature_list kwargs static PyObject * _wrap_gst_registry_get_feature_list (PyGObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "type", NULL }; PyObject *py_type = NULL; GType type; GstRegistry *registry; GList *l, *features; PyObject *list; gint i; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GstRegistry.get_feature_list", kwlist, &py_type)) return NULL; if ((type = pyg_type_from_object(py_type)) == 0) return NULL; registry = GST_REGISTRY (self->obj); features = gst_registry_get_feature_list (registry, type); list = PyList_New (g_list_length(features)); for (l = features, i = 0; l; l = l->next, ++i) { GstPluginFeature *feature = (GstPluginFeature *) l->data; PyList_SetItem (list, i, pygobject_new (G_OBJECT (feature))); gst_object_unref (feature); } g_list_free (features); return list; } %% override gst_registry_get_feature_list_by_plugin kwargs static PyObject * _wrap_gst_registry_get_feature_list_by_plugin (PyGObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "name", NULL }; gchar * name = NULL; GstRegistry *registry; GList *l, *features; PyObject *list; gint i; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:GstRegistry.get_feature_list_by_plugin", kwlist, &name)) return NULL; registry = GST_REGISTRY (self->obj); features = gst_registry_get_feature_list_by_plugin (registry, name); list = PyList_New (g_list_length(features)); for (l = features, i = 0; l; l = l->next, ++i) { GstPluginFeature *feature = (GstPluginFeature *) l->data; PyList_SetItem (list, i, pygobject_new (G_OBJECT (feature))); } g_list_free (features); return list; } %% override gst_xml_new noargs extern PyObject * libxml_xmlDocPtrWrap(xmlDocPtr doc); extern PyObject * libxml_xmlNodePtrWrap(xmlNodePtr node); /* libxml2 available check */ static PyObject * _gst_get_libxml2_module(void) { PyObject *xml = NULL; xml = PyImport_ImportModule("libxml2"); if (!xml) { PyErr_Clear(); PyErr_SetString(PyExc_RuntimeError,"libxml2 bindings required"); return NULL; } return xml; } static int _wrap_gst_xml_new(PyGObject *self) { PyObject *xml = _gst_get_libxml2_module(); if(!xml) return -1; self->obj = (GObject *)gst_xml_new(); if (!self->obj) { PyErr_SetString(PyExc_RuntimeError, "could not create GstXML object"); return -1; } pygobject_register_wrapper((PyObject *)self); return 0; } %% override gst_xml_get_topelements noargs static PyObject * _wrap_gst_xml_get_topelements(PyGObject *self) { GList *l, *xml_elements; PyObject *py_list; gint i; xml_elements = gst_xml_get_topelements(GST_XML(self->obj)); py_list = PyList_New(g_list_length(xml_elements)); for (l = xml_elements, i = 0; l; l = l->next, ++i) { GstElement *element = (GstElement*)l->data; PyList_SetItem(py_list, i, pygstobject_new(G_OBJECT(element))); gst_object_unref (element); } return py_list; } %% override gst_xml_parse_memory kwargs static PyObject * _wrap_gst_xml_parse_memory(PyGObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "buffer", "root", NULL }; int buffer_len, ret; char *root = NULL; guchar *buffer; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|s:GstXML.parse_memory", kwlist, &buffer, &buffer_len, &root)) return NULL; ret = gst_xml_parse_memory(GST_XML(self->obj), buffer, buffer_len, root); return PyBool_FromLong(ret); } %% override gst_tag_setter_get_tag_list noargs static PyObject * _wrap_gst_tag_setter_get_tag_list(PyGObject *self) { GstTagList *ret; ret = (GstTagList*)gst_tag_setter_get_tag_list(GST_TAG_SETTER(self->obj)); /* pyg_boxed_new handles NULL checking */ return pyg_boxed_new(GST_TYPE_TAG_LIST, ret, TRUE, TRUE); } %% override gst_element_register kwargs static GstPlugin * _pygst_get_plugin(void) { PyObject *dict = NULL, *module = NULL, *pyplugin = NULL; GstPlugin *ret; if (!(module = PyImport_ImportModule ("gst"))) goto err; if (!(dict = PyModule_GetDict (module))) goto err; if (!(pyplugin = PyDict_GetItemString (dict, "__plugin__"))) goto err; ret = pyg_boxed_get (pyplugin, GstPlugin); Py_DECREF (module); return ret; err: Py_XDECREF (module); PyErr_Clear (); return NULL; } static PyObject * _wrap_gst_element_register(PyObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "type", "elementname", "rank", NULL }; PyObject *py_type = NULL; guint rank = GST_RANK_NONE; char *elementname = NULL; int ret; GType type; /* FIXME: can we make the name optional, too? Anyone know a good default? */ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os|I:element_register", kwlist, &py_type, &elementname, &rank)) return NULL; if ((type = pyg_type_from_object(py_type)) == 0) return NULL; ret = gst_element_register(_pygst_get_plugin(), elementname, rank, type); return PyBool_FromLong(ret); } %% override-attr GError.domain static PyObject * _wrap_gst_g_error__get_domain(PyGObject *self, void *closure) { return PyString_FromString(g_quark_to_string(((GError*)self->obj)->domain)); } %% override-slot GError.tp_str static PyObject * _wrap_gst_g_error_tp_str(PyGObject *self) { GError *error = (GError*)self->obj; return PyString_FromString(gst_error_get_message (error->domain, error->code)); } %% override gst_uri_handler_get_protocols noargs static PyObject * _wrap_gst_uri_handler_get_protocols (PyGObject *self) { gchar **tab; int i, len; PyObject *ret; tab = gst_uri_handler_get_protocols (GST_URI_HANDLER (self->obj)); if (!tab) { Py_INCREF (Py_None); return Py_None; } len = g_strv_length (tab); ret = PyList_New(len); for (i = 0; i < len; i++) { PyList_SetItem(ret, i, PyString_FromString(tab[i])); } return ret; } %% override gst_flow_get_name kwargs static PyObject * _wrap_gst_flow_get_name(PyObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "ret", NULL }; PyObject *py_ret = NULL; const gchar *ret; gchar *nret; GstFlowReturn flow; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:gst_flow_get_name", kwlist, &py_ret)) return NULL; if (pyg_enum_get_value(GST_TYPE_FLOW_RETURN, py_ret, (gint *)&flow)) return NULL; ret = gst_flow_get_name(flow); if (ret) { nret = g_strdup(ret); return PyString_FromString(nret); } Py_INCREF(Py_None); return Py_None; } %% override gst_log args static PyObject * _wrap_gst_log (PyObject *whatever, PyObject *string) { return pygst_debug_log (whatever, string, GST_LEVEL_LOG, FALSE); } %% override gst_debug args static PyObject * _wrap_gst_debug (PyObject *whatever, PyObject *string) { return pygst_debug_log (whatever, string, GST_LEVEL_DEBUG, FALSE); } %% override gst_info args static PyObject * _wrap_gst_info (PyObject *whatever, PyObject *string) { return pygst_debug_log (whatever, string, GST_LEVEL_INFO, FALSE); } %% override gst_warning args static PyObject * _wrap_gst_warning (PyObject *whatever, PyObject *string) { return pygst_debug_log (whatever, string, GST_LEVEL_WARNING, FALSE); } %% override gst_error args static PyObject * _wrap_gst_error (PyObject *whatever, PyObject *string) { return pygst_debug_log (whatever, string, GST_LEVEL_ERROR, FALSE); } %% override gst_object_log args static PyObject * _wrap_gst_object_log (PyObject *whatever, PyObject *string) { return pygst_debug_log (whatever, string, GST_LEVEL_LOG, TRUE); } %% override gst_object_debug args static PyObject * _wrap_gst_object_debug (PyObject *whatever, PyObject *string) { return pygst_debug_log (whatever, string, GST_LEVEL_DEBUG, TRUE); } %% override gst_object_info args static PyObject * _wrap_gst_object_info (PyObject *whatever, PyObject *string) { return pygst_debug_log (whatever, string, GST_LEVEL_INFO, TRUE); } %% override gst_object_warning args static PyObject * _wrap_gst_object_warning (PyObject *whatever, PyObject *string) { return pygst_debug_log (whatever, string, GST_LEVEL_WARNING, TRUE); } %% override gst_object_error args static PyObject * _wrap_gst_object_error (PyObject *whatever, PyObject *string) { return pygst_debug_log (whatever, string, GST_LEVEL_ERROR, TRUE); } %% override GST_TIME_ARGS kwargs static PyObject * _wrap_GST_TIME_ARGS(PyObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "time", NULL }; PyObject *py_time = NULL; PyObject *string; gchar *ret; guint64 time; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:time_to_string", kwlist, &py_time)) return NULL; time = PyInt_AsUnsignedLongLongMask(py_time); if (GST_CLOCK_TIME_IS_VALID (time)) ret = g_strdup_printf("%"GST_TIME_FORMAT, GST_TIME_ARGS(time)); else ret = g_strdup ("CLOCK_TIME_NONE"); if (!ret) { Py_INCREF(Py_None); return Py_None; } if (!(string = PyString_FromString(ret))) { g_free(ret); return NULL; } g_free(ret); return string; } %% override gst_type_find_factory_get_list noargs static PyObject * _wrap_gst_type_find_factory_get_list (PyObject *self) { GList *l, *list; PyObject *py_list; int i = 0; list = gst_type_find_factory_get_list (); py_list = PyList_New(g_list_length(list)); for (l = list; l ; l = g_list_next(l), i++) { GstTypeFindFactory *fact = (GstTypeFindFactory*) l->data; PyList_SetItem(py_list, i, pygstobject_new (G_OBJECT (fact))); } g_list_free (list); return py_list; } %% override gst_get_gst_version noargs static PyObject * _wrap_gst_get_gst_version (PyObject *self) { guint major, minor, micro, nano; PyObject *py_tuple; gst_version (&major, &minor, µ, &nano); py_tuple = PyTuple_New(4); PyTuple_SetItem(py_tuple, 0, PyInt_FromLong(major)); PyTuple_SetItem(py_tuple, 1, PyInt_FromLong(minor)); PyTuple_SetItem(py_tuple, 2, PyInt_FromLong(micro)); PyTuple_SetItem(py_tuple, 3, PyInt_FromLong(nano)); return py_tuple; } %% override gst_get_pygst_version noargs static PyObject * _wrap_gst_get_pygst_version (PyObject *self) { PyObject *py_tuple; py_tuple = Py_BuildValue ("(iiii)", PYGST_MAJOR_VERSION, PYGST_MINOR_VERSION, PYGST_MICRO_VERSION, PYGST_NANO_VERSION); return py_tuple; } %% override gst_clock_get_calibration noargs static PyObject * _wrap_gst_clock_get_calibration (PyGObject * self) { PyObject *ret; GstClockTime internal; GstClockTime external; GstClockTime rate_num; GstClockTime rate_denom; gst_clock_get_calibration (GST_CLOCK (self->obj), &internal, &external, &rate_num, &rate_denom); ret = PyTuple_New(4); PyTuple_SetItem(ret, 0, PyLong_FromUnsignedLongLong(internal)); PyTuple_SetItem(ret, 1, PyLong_FromUnsignedLongLong(external)); PyTuple_SetItem(ret, 2, PyLong_FromUnsignedLongLong(rate_num)); PyTuple_SetItem(ret, 3, PyLong_FromUnsignedLongLong(rate_denom)); return ret; } %% override gst_type_find_helper_for_buffer kwargs static PyObject * _wrap_gst_type_find_helper_for_buffer (PyObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "object", "buffer", NULL }; PyGObject *py_object; PyGstMiniObject *py_buffer; PyObject *py_ret; GstTypeFindProbability prob = 0; GstCaps *caps = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!:type_find_helper_for_buffer", kwlist, &PyGstObject_Type, &py_object, &PyGstBuffer_Type, &py_buffer)) return NULL; caps = gst_type_find_helper_for_buffer (GST_OBJECT (py_object->obj), GST_BUFFER (py_buffer->obj), &prob); py_ret = PyTuple_New(2); if (caps) PyTuple_SetItem(py_ret, 0, pyg_boxed_new (GST_TYPE_CAPS, caps, FALSE, TRUE)); else { Py_INCREF(Py_None); PyTuple_SetItem(py_ret, 0, Py_None); } if (prob) PyTuple_SetItem(py_ret, 1, pyg_enum_from_gtype(GST_TYPE_TYPE_FIND_PROBABILITY, prob)); else { Py_INCREF(Py_None); PyTuple_SetItem(py_ret, 1, Py_None); } return py_ret; } %% override gst_type_find_new kwargs static guint8 * gst_type_find_peek_handler (gpointer data, gint64 offset, guint size) { PyGILState_STATE state; guint8 * ret = NULL; PyObject *py_data; PyObject *callback, *args; PyObject *py_ret; GST_DEBUG ("mkay"); g_return_val_if_fail (data != NULL, NULL); py_data = (PyObject *) data; g_assert (PyTuple_Check (py_data)); state = pyg_gil_state_ensure (); /* Figure out the callback and create the arguments */ if (!(callback = PyTuple_GetItem(py_data, 1))) goto beach; args = Py_BuildValue ("(OLI)", PyTuple_GetItem(py_data, 0), offset, size); if (!args) goto beach; /* Call python method */ py_ret = PyObject_CallObject (callback, args); /* transform return value (a string) */ if (!py_ret) { Py_DECREF (args); goto beach; } if (!PyString_Check(py_ret)) { Py_DECREF (py_ret); Py_DECREF (args); goto beach; } else { gchar *str; int len; if ((PyString_AsStringAndSize(py_ret, &str, &len)) == -1) { Py_DECREF (py_ret); Py_DECREF (args); goto beach; } GST_DEBUG ("got string of len %d", len); if (len) ret = g_memdup((gconstpointer) str, (guint) len); } Py_DECREF (py_ret); Py_DECREF (args); beach: pyg_gil_state_release (state); return ret; } static void gst_type_find_suggest_handler (gpointer data, guint probability, const GstCaps * caps) { PyGILState_STATE state; PyObject *py_data; PyObject *callback, *args; GST_DEBUG ("mkay"); if (!data) return; py_data = (PyObject *) data; g_assert (PyTuple_Check (py_data)); state = pyg_gil_state_ensure (); /* Figure out the callback and create the arguments */ if (!(callback = PyTuple_GetItem(py_data, 2))) goto beach; args = Py_BuildValue ("(OIN)", PyTuple_GetItem(py_data, 0), probability, pyg_boxed_new (GST_TYPE_CAPS, (GstCaps*) caps, FALSE, TRUE)); if (!args) goto beach; /* Call python method */ PyObject_CallObject (callback, args); Py_DECREF (args); beach: pyg_gil_state_release (state); return; } static guint64 gst_type_find_get_length_handler (gpointer data) { guint64 ret = 0; /* Call python method */ return ret; } static PyObject * _wrap_gst_type_find_new (PyObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "data", "peekfunction", "suggestfunction", "getlengthfunction", NULL }; PyObject *py_data; gpointer data; PyObject *peekfunction; PyObject *suggestfunction; PyObject *getlengthfunction = NULL; PyObject *pytypefind = NULL; GstTypeFind *typefind = NULL; GST_DEBUG ("poeut"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOO|O:type_find_new", kwlist, &py_data, &peekfunction, &suggestfunction, &getlengthfunction)) { PyErr_SetString (PyExc_TypeError, "Error parsing values ..."); return NULL; } if (!PyCallable_Check(peekfunction)) { PyErr_SetString (PyExc_TypeError, "peekfunction is not callable"); return NULL; } if (!PyCallable_Check(suggestfunction)) { PyErr_SetString (PyExc_TypeError, "suggestfunction is not callable"); return NULL; } if (getlengthfunction && (!PyCallable_Check(suggestfunction))) { PyErr_SetString (PyExc_TypeError, "getlengthfunction is not callable"); return NULL; } /* Create a python list to put in typefind->data */ if (getlengthfunction) data = Py_BuildValue("(OOOO)", py_data, peekfunction, suggestfunction, getlengthfunction); else data = Py_BuildValue("(OOO)", py_data, peekfunction, suggestfunction); typefind = g_new0(GstTypeFind, 1); typefind->peek = gst_type_find_peek_handler; typefind->suggest = gst_type_find_suggest_handler; typefind->data = data; if (getlengthfunction) typefind->get_length = gst_type_find_get_length_handler; pytypefind = pyg_pointer_new (GST_TYPE_TYPE_FIND, typefind); if (!pytypefind) { PyErr_SetString (PyExc_TypeError, "pyg_pointer_new failed"); } GST_DEBUG ("poeut : %p", pytypefind); return pytypefind; }