gstreamer/gst/gstcaps.override
Edward Hervey f884a2a7de gstcaps: Remove dead code.
Those two lines will never be called, because caps2 will always be NULL
if we go to error (either we haven't used it yet (first goto and in this
case it's NULL), or.. it's NULL (second goto)).
2009-03-05 13:59:30 +01:00

474 lines
13 KiB
C

/* -*- Mode: C; c-basic-offset: 4 -*- */
/* gst-python
* Copyright (C) 2005 Johan Dahlin
* 2005 Benjamin Otte <otte@gnome.org>
*
* 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: Johan Dahlin <johan@gnome.org>
* Benjamin Otte <otte@gnome.org>
*/
%%
headers
/* This is a (hopefully) smart hack to allow access to a caps'
* structures without falling into traps when the caps get destroyed
* before the structures get.
* This Hash Table uses the structure PyObjects as keys and the caps
* PyObjects as values. No clue if this is a fast data structure but it
* probably doesn't matter anyway.
*/
static GHashTable *structure_caps_map = NULL;
static void
pygst_caps_map_add (PyObject *structure, PyObject *caps)
{
/* we can't have free_on_dealloc stuff in here */
g_assert (((PyGBoxed *)structure)->free_on_dealloc == FALSE);
g_hash_table_insert (structure_caps_map, structure, caps);
}
static void
pygst_caps_map_remove_structure (PyObject *structure)
{
g_hash_table_remove (structure_caps_map, structure);
}
static gboolean
pygst_caps_map_foreach (gpointer structure, gpointer caps, gpointer match)
{
PyGBoxed *boxed = structure;
if (match != caps)
return FALSE;
/* we can't have free_on_dealloc stuff in here */
g_assert (boxed->free_on_dealloc == FALSE);
boxed->boxed = gst_structure_copy (boxed->boxed);
boxed->free_on_dealloc = TRUE;
return TRUE;
}
static void
pygst_caps_map_modified (PyObject *caps)
{
g_hash_table_foreach_remove (structure_caps_map, pygst_caps_map_foreach, caps);
}
%%
init
structure_caps_map = g_hash_table_new (g_direct_hash, g_direct_equal);
%%
ignore
gst_caps_new_simple
gst_caps_new_full
gst_caps_set_simple
%%
override gst_caps_get_structure kwargs
static PyObject *pygst_caps_sq_item(PyObject *self, Py_ssize_t i);
static PyObject *
_wrap_gst_caps_get_structure(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "index", NULL };
int index;
if (PyErr_Warn(PyExc_DeprecationWarning, "caps.get_structure(i) is deprecated, use caps[i]") < 0)
return NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:GstCaps.get_structure", kwlist, &index))
return NULL;
return pygst_caps_sq_item (self, index);
}
%%
override gst_caps_new_empty kwargs
static int
_wrap_gst_caps_new_empty(PyGBoxed *self, PyObject *args, PyObject *kwargs)
{
PyObject* item;
int len, i;
/* we wrap caps_new, caps_from_string and caps_new_full */
len = PyTuple_Size(args);
self->gtype = GST_TYPE_CAPS;
self->free_on_dealloc = TRUE;
if (len == 0) {
/* 0 length creates a new empty caps */
self->boxed = gst_caps_new_empty();
} else if (len == 1) {
item = PyTuple_GetItem(args, 0);
/* 1 length is either a string or a structure */
self->boxed = pygst_caps_from_pyobject (item, NULL);
} else {
/* it's multiple arguments that can all be made to caps */
GstCaps *append;
self->boxed = gst_caps_new_empty();
for (i = 0; i < len; i++)
{
item = PyTuple_GetItem(args, i);
append = pygst_caps_from_pyobject (item, NULL);
if (!append) {
gst_caps_unref (self->boxed);
self->boxed = NULL;
break;
}
gst_caps_append (self->boxed, append);
}
}
if (!self->boxed) {
PyErr_SetString(PyExc_TypeError, "wrong arguments when creating GstCaps object");
return -1;
}
return 0;
}
%%
override-slot GstCaps.tp_richcompare
static gboolean
pygst_caps_is_true_subset (GstCaps *caps1, GstCaps *caps2)
{
GstCaps *tmp;
gboolean ret;
/* order is important here */
if (gst_caps_is_any (caps1))
return FALSE;
if (gst_caps_is_any (caps2))
return TRUE;
if (gst_caps_is_empty (caps2))
return FALSE;
if (gst_caps_is_empty (caps1))
return TRUE;
tmp = gst_caps_subtract (caps1, caps2);
ret = gst_caps_is_empty (tmp);
gst_caps_unref (tmp);
if (!ret)
return FALSE;
tmp = gst_caps_subtract (caps2, caps1);
ret = gst_caps_is_empty (tmp);
gst_caps_unref (tmp);
return !ret;
}
static PyObject *
_wrap_gst_caps_tp_richcompare (PyObject *py_caps1, PyObject *py_caps2, int comparison)
{
GstCaps *caps1, *caps2;
gboolean caps2_is_copy;
PyObject *ret;
caps1 = pyg_boxed_get (py_caps1, GstCaps);
caps2 = pygst_caps_from_pyobject (py_caps2, &caps2_is_copy);
if (PyErr_Occurred()) {
/* the second arg is not a caps */
switch (comparison) {
case Py_EQ:
PyErr_Clear();
ret = Py_False;
Py_INCREF (ret);
return ret;
case Py_NE:
PyErr_Clear();
ret = Py_True;
Py_INCREF (ret);
return ret;
default:
return NULL;
}
}
switch (comparison) {
case Py_LT:
ret = pygst_caps_is_true_subset (caps1, caps2) ? Py_True : Py_False;
break;
case Py_LE:
ret = gst_caps_is_subset (caps1, caps2) ? Py_True : Py_False;
break;
case Py_NE:
ret = gst_caps_is_equal (caps1, caps2) ? Py_False : Py_True;
break;
case Py_EQ:
ret = gst_caps_is_equal (caps1, caps2) ? Py_True : Py_False;
break;
case Py_GE:
ret = gst_caps_is_subset (caps2, caps1) ? Py_True : Py_False;
break;
case Py_GT:
ret = pygst_caps_is_true_subset (caps2, caps1) ? Py_True : Py_False;
break;
default:
PyErr_SetString (PyExc_RuntimeError, "invalid comparison operation");
if (caps2 && caps2_is_copy)
gst_caps_unref (caps2);
return NULL;
}
if (caps2 && caps2_is_copy)
gst_caps_unref (caps2);
Py_INCREF (ret);
return ret;
}
%%
override-slot GstCaps.tp_as_number
/* In this number code, we mimic the Python set.Set datatype.
* The same operations are supported. If you want to have an operation
* supported for caps, add it to Python's Set type first.
*/
#define BINARY_FUNC(name,func) \
static PyObject * \
name (PyObject *py_caps1, PyObject *py_caps2) \
{ \
GstCaps *caps1, *caps2, *ret; \
gboolean caps2_is_copy; \
\
caps1 = pyg_boxed_get (py_caps1, GstCaps); \
caps2 = pygst_caps_from_pyobject (py_caps2, &caps2_is_copy); \
if (PyErr_Occurred()) \
return NULL; \
ret = func (caps1, caps2); \
if (caps2 && caps2_is_copy) \
gst_caps_unref (caps2); \
return pyg_boxed_new (GST_TYPE_CAPS, ret, FALSE, TRUE); \
}
BINARY_FUNC (pygst_caps_nb_subtract, gst_caps_subtract)
BINARY_FUNC (pygst_caps_nb_and, gst_caps_intersect)
BINARY_FUNC (pygst_caps_nb_or, gst_caps_union)
static GstCaps *
pygst_caps_xor (const GstCaps *caps1, const GstCaps *caps2)
{
GstCaps *intersect, *_union, *ret;
intersect = gst_caps_intersect (caps1, caps2);
_union = gst_caps_union (caps1, caps2);
ret = gst_caps_subtract (_union, intersect);
gst_caps_unref (_union);
gst_caps_unref (intersect);
gst_caps_do_simplify (ret);
return ret;
}
BINARY_FUNC (pygst_caps_nb_xor, pygst_caps_xor)
static int
pygst_caps_nb_nonzero (PyObject *py_caps)
{
GstCaps *caps = pyg_boxed_get (py_caps, GstCaps);
if (gst_caps_is_empty (caps))
return 0;
else
return 1;
}
static int
pygst_caps_nb_coerce (PyObject **py_caps1, PyObject **py_caps2)
{
GstCaps *caps1, *caps2 = NULL;
gboolean caps1_is_copy, caps2_is_copy;
caps1 = pygst_caps_from_pyobject (*py_caps1, &caps1_is_copy);
if (!caps1)
goto error;
caps2 = pygst_caps_from_pyobject (*py_caps2, &caps2_is_copy);
if (!caps2)
goto error;
/* if they're not copies, they're caps already */
if (caps1_is_copy)
*py_caps1 = pyg_boxed_new (GST_TYPE_CAPS, caps1, FALSE, TRUE);
else
Py_INCREF (*py_caps1);
if (caps2_is_copy)
*py_caps2 = pyg_boxed_new (GST_TYPE_CAPS, caps2, FALSE, TRUE);
else
Py_INCREF (*py_caps2);
return 0;
error:
g_assert (PyErr_Occurred ());
PyErr_Clear ();
if (caps1 && !caps1_is_copy)
gst_caps_unref (caps1);
return 1;
}
static PyNumberMethods _wrap_gst_caps_tp_as_number = {
0, /* nb_add */
pygst_caps_nb_subtract, /* nb_subtract */
0, /* nb_multiply */
0, /* nb_divide */
0, /* nb_remainder */
0, /* nb_divmod */
0, /* nb_power */
0, /* nb_negative */
0, /* nb_positive */
0, /* nb_absolute */
pygst_caps_nb_nonzero, /* nb_nonzero */
0, /* nb_invert */
0, /* nb_lshift */
0, /* nb_rshift */
pygst_caps_nb_and, /* nb_and */
pygst_caps_nb_xor, /* nb_xor */
pygst_caps_nb_or, /* nb_or */
pygst_caps_nb_coerce, /* nb_coerce */
0, /* nb_int */
0, /* nb_long */
0, /* nb_float */
0, /* nb_oct */
0, /* nb_hex */
0, /* nb_inplace_add */
0, /* nb_inplace_subtract */
0, /* nb_inplace_multiply */
0, /* nb_inplace_divide */
0, /* nb_inplace_remainder */
0, /* nb_inplace_power */
0, /* nb_inplace_lshift */
0, /* nb_inplace_rshift */
0, /* nb_inplace_and */
0, /* nb_inplace_xor */
0, /* nb_inplace_or */
0, /* nb_floor_divide */
0, /* nb_true_divide */
0, /* nb_inplace_floor_divide */
0, /* nb_inplace_true_divide */
};
%%
override-slot GstCaps.tp_as_sequence
static Py_ssize_t
pygst_caps_sq_length(PyObject *self)
{
GstCaps *caps = pyg_boxed_get (self, GstCaps);
return gst_caps_get_size(caps);
}
static PyObject *
pygst_caps_sq_item(PyObject *self, Py_ssize_t i)
{
GstCaps *caps = pyg_boxed_get (self, GstCaps);
GstStructure *structure;
PyObject *ret;
if (i < 0 || i >= gst_caps_get_size(caps)) {
PyErr_SetString(PyExc_IndexError, "list index out of range");
return NULL;
}
structure = gst_caps_get_structure(caps, i);
/* pyg_boxed_new handles NULL checking */
ret = pyg_boxed_new(GST_TYPE_STRUCTURE,
gst_caps_get_structure(pyg_boxed_get(self, GstCaps), i),
FALSE, FALSE);
if (ret)
pygst_caps_map_add (ret, self);
return ret;
}
/* FIXME: This syntax sucks */
static PyObject *
pygst_caps_sq_slice(PyObject *self, Py_ssize_t start, Py_ssize_t end)
{
GstCaps *caps = pyg_boxed_get (self, GstCaps);
GstCaps *ret = gst_caps_new_empty ();
int i;
if (start < 0)
start = 0;
if (end > gst_caps_get_size (caps))
end = gst_caps_get_size (caps);
for (i = start; i < end; i++)
gst_caps_append_structure (ret, gst_structure_copy (gst_caps_get_structure (caps, i)));
return pyg_boxed_new(GST_TYPE_CAPS, ret, FALSE, TRUE);
}
static PySequenceMethods _wrap_gst_caps_tp_as_sequence = {
pygst_caps_sq_length,
NULL, /* not allowed for sets, use | instead of + */
NULL, /* doesn't make sense, because it'd still be the same */
pygst_caps_sq_item,
pygst_caps_sq_slice,
NULL, /* doesn't make sense, you can only append */
NULL, /* doesn't make sense, you can only append */
NULL, /* doesn't make sense really, unless you use is_subset */
NULL, /* not allowed for sets, use | instead of + */
NULL /* doesn't make sense, because it'd still be the same */
};
%%
override-slot GstCaps.tp_dealloc
static void
_wrap_gst_caps_tp_dealloc (PyObject *self)
{
PyGBoxed *boxed = (PyGBoxed *) self;
if (boxed->free_on_dealloc && boxed->boxed) {
pygst_caps_map_modified (self);
GST_DEBUG ("unreffing caps %" GST_PTR_FORMAT " at %p with refcount %d",
boxed->boxed, boxed->boxed, GST_CAPS_REFCOUNT (boxed->boxed));
gst_caps_unref (boxed->boxed);
}
self->ob_type->tp_free((PyObject *)self);
}
%%
override-slot GstCaps.tp_str
static PyObject *
_wrap_gst_caps_tp_str(PyGObject *self)
{
gchar *tmp;
PyObject *retval;
tmp = gst_caps_to_string((GstCaps*)self->obj);
retval = PyString_FromString(tmp);
g_free(tmp);
return retval;
}
%%
override-attr GstCaps.__refcount__
static PyObject *
_wrap_gst_caps__get___refcount__(PyGObject *self, void *closure)
{
return PyInt_FromLong(GST_CAPS_REFCOUNT(self->obj));
}
%%
override gst_caps_append_structure kwargs
static PyObject *
_wrap_gst_caps_append_structure(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "structure", NULL };
PyObject *py_structure;
GstStructure *structure = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O:GstCaps.append_structure", kwlist, &py_structure))
return NULL;
if (pyg_boxed_check(py_structure, GST_TYPE_STRUCTURE))
structure = gst_structure_copy(pyg_boxed_get(py_structure, GstStructure));
else {
PyErr_SetString(PyExc_TypeError, "structure should be a GstStructure");
return NULL;
}
pyg_begin_allow_threads;
gst_caps_append_structure(pyg_boxed_get(self, GstCaps), structure);
pyg_end_allow_threads;
Py_INCREF(Py_None);
return Py_None;
}