Commit 1208a719 authored by Ghislain MARY's avatar Ghislain MARY
Browse files

Implement VideoSize class in the Python wrapper.

parent 51c72605
......@@ -45,9 +45,7 @@ blacklisted_functions = [
'linphone_call_log_get_start_date', # missing time_t
'linphone_call_log_get_user_pointer', # rename to linphone_call_log_get_user_data
'linphone_call_log_set_user_pointer', # rename to linphone_call_log_set_user_data
'linphone_call_params_get_received_video_size', # missing MSVideoSize
'linphone_call_params_get_privacy', # missing LinphonePrivacyMask
'linphone_call_params_get_sent_video_size', # missing MSVideoSize
'linphone_call_params_get_used_audio_codec', # missing PayloadType
'linphone_call_params_get_used_video_codec', # missing PayloadType
'linphone_call_params_set_privacy', # missing LinphonePrivacyMask
......@@ -68,7 +66,6 @@ blacklisted_functions = [
'linphone_core_get_chat_rooms', # missing MSList
'linphone_core_get_default_proxy', # to be handwritten because of double pointer indirection
'linphone_core_get_payload_type_bitrate', # missing PayloadType
'linphone_core_get_preferred_video_size', # missing MSVideoSize
'linphone_core_get_friend_list', # missing MSList
'linphone_core_get_proxy_config_list', # missing MSList
'linphone_core_get_sip_transports', # missing LCSipTransports
......@@ -84,12 +81,10 @@ blacklisted_functions = [
'linphone_core_set_log_handler', # Hand-written but put directly in the linphone module
'linphone_core_set_log_level', # There is no use to wrap this function
'linphone_core_set_payload_type_bitrate', # missing PayloadType
'linphone_core_set_preferred_video_size', # missing MSVideoSize
'linphone_core_set_video_policy', # missing LinphoneVideoPolicy
'linphone_core_play_dtmf', # handling of char
'linphone_core_send_dtmf', # handling of char
'linphone_core_set_audio_codecs', # missing PayloadType and MSList
'linphone_core_set_preview_video_size', # missing MSVideoSize
'linphone_core_set_sip_transports', # missing LCSipTransports
'linphone_core_subscribe', # missing LinphoneContent
'linphone_event_notify', # missing LinphoneContent
......
static PyTypeObject pylinphone_VideoSizeType;
typedef struct {
PyObject_HEAD
MSVideoSize vs;
} pylinphone_VideoSizeObject;
int PyLinphoneVideoSize_Check(PyObject *p);
MSVideoSize PyLinphoneVideoSize_AsMSVideoSize(PyObject *obj);
PyObject * PyLinphoneVideoSize_FromMSVideoSize(MSVideoSize vs);
......@@ -14,7 +14,7 @@ static void pylinphone_log(const char *level, int indent, const char *fmt, va_li
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
linphone_module = PyImport_ImportModule("linphone");
linphone_module = PyImport_ImportModule("linphone.linphone");
if ((linphone_module != NULL) && PyObject_HasAttrString(linphone_module, "__log_handler")) {
PyObject *log_handler = PyObject_GetAttrString(linphone_module, "__log_handler");
if ((log_handler != NULL) && PyCallable_Check(log_handler)) {
......@@ -71,7 +71,7 @@ static void pylinphone_module_log_handler(OrtpLogLevel lev, const char *fmt, va_
const char *level;
gstate = PyGILState_Ensure();
linphone_module = PyImport_ImportModule("linphone");
linphone_module = PyImport_ImportModule("linphone.linphone");
level = pylinphone_ortp_log_level_to_string(lev);
if ((linphone_module != NULL) && PyObject_HasAttrString(linphone_module, "__log_handler")) {
PyObject *log_handler = PyObject_GetAttrString(linphone_module, "__log_handler");
......@@ -97,7 +97,7 @@ static void pylinphone_init_logging(void) {
static PyObject * pylinphone_module_method_set_log_handler(PyObject *self, PyObject *args) {
PyObject *linphone_module = PyImport_ImportModule("linphone");
PyObject *linphone_module = PyImport_ImportModule("linphone.linphone");
PyObject *callback;
if (!PyArg_ParseTuple(args, "O", &callback)) {
return NULL;
......@@ -193,3 +193,113 @@ static PyObject * pylinphone_Core_class_method_new_with_config(PyObject *cls, Py
Py_DECREF(self);
return pyret;
}
static void pylinphone_VideoSize_dealloc(PyObject *self) {
pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p)", __FUNCTION__, self);
self->ob_type->tp_free(self);
pylinphone_trace(-1, "[PYLINPHONE] <<< %s", __FUNCTION__);
}
static PyObject * pylinphone_VideoSize_new(PyTypeObject *type, PyObject *args, PyObject *kw) {
pylinphone_VideoSizeObject *self = (pylinphone_VideoSizeObject *)type->tp_alloc(type, 0);
pylinphone_trace(1, "[PYLINPHONE] >>> %s()", __FUNCTION__);
pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> %p", __FUNCTION__, self);
return (PyObject *)self;
}
static int pylinphone_VideoSize_init(PyObject *self, PyObject *args, PyObject *kwds) {
pylinphone_VideoSizeObject *vso = (pylinphone_VideoSizeObject *)self;
int width;
int height;
if (!PyArg_ParseTuple(args, "ii", &width, &height)) {
return -1;
}
vso->vs.width = width;
vso->vs.height = height;
return 0;
}
static PyMemberDef pylinphone_VideoSize_members[] = {
{ "width", T_INT, offsetof(pylinphone_VideoSizeObject, vs) + offsetof(MSVideoSize, width), 0, "The width of the video" },
{ "height", T_INT, offsetof(pylinphone_VideoSizeObject, vs) + offsetof(MSVideoSize, height), 0, "The height of the video" },
{ NULL } /* Sentinel */
};
static PyTypeObject pylinphone_VideoSizeType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"linphone.VideoSize", /* tp_name */
sizeof(pylinphone_VideoSizeObject), /* tp_basicsize */
0, /* tp_itemsize */
pylinphone_VideoSize_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
"Object representing the size of a video: its width and its height in pixels.", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
pylinphone_VideoSize_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
pylinphone_VideoSize_init, /* tp_init */
0, /* tp_alloc */
pylinphone_VideoSize_new, /* tp_new */
0, /* tp_free */
};
int PyLinphoneVideoSize_Check(PyObject *p) {
return PyObject_IsInstance(p, (PyObject *)&pylinphone_VideoSizeType);
}
MSVideoSize PyLinphoneVideoSize_AsMSVideoSize(PyObject *obj) {
return ((pylinphone_VideoSizeObject *)obj)->vs;
}
PyObject * PyLinphoneVideoSize_FromMSVideoSize(MSVideoSize vs) {
PyObject *linphone_module;
PyObject *pyret = NULL;
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
linphone_module = PyImport_ImportModule("linphone.linphone");
if (linphone_module != NULL) {
PyObject *cls = PyObject_GetAttrString(linphone_module, "VideoSize");
if (cls != NULL) {
pyret = PyEval_CallObject(cls, Py_BuildValue("ii", vs.width, vs.height));
if (pyret == NULL) {
PyErr_Print();
}
Py_DECREF(cls);
}
Py_DECREF(linphone_module);
}
PyGILState_Release(gstate);
if (pyret == NULL) {
Py_RETURN_NONE;
}
return pyret;
}
......@@ -45,8 +45,11 @@ class ArgumentType:
self.type_str = None
self.check_func = None
self.convert_func = None
self.convert_from_func = None
self.fmt_str = 'O'
self.cfmt_str = '%p'
self.use_native_pointer = False
self.cast_convert_func_result = True
self.__compute()
def __compute(self):
......@@ -132,6 +135,14 @@ class ArgumentType:
self.convert_func = 'PyInt_AsLong'
self.fmt_str = 'i'
self.cfmt_str = '%d'
elif self.basic_type == 'MSVideoSize':
self.type_str = 'linphone.VideoSize'
self.check_func = 'PyLinphoneVideoSize_Check'
self.convert_func = 'PyLinphoneVideoSize_AsMSVideoSize'
self.convert_from_func = 'PyLinphoneVideoSize_FromMSVideoSize'
self.fmt_str = 'O'
self.cfmt_str = '%p'
self.cast_convert_func_result = False
else:
if strip_leading_linphone(self.basic_type) in self.linphone_module.enum_names:
self.type_str = 'int'
......@@ -139,6 +150,8 @@ class ArgumentType:
self.convert_func = 'PyInt_AsLong'
self.fmt_str = 'i'
self.cfmt_str = '%d'
elif '*' in splitted_type:
self.use_native_pointer = True
class MethodDefinition:
......@@ -177,7 +190,7 @@ class MethodDefinition:
arg_complete_type = xml_method_arg.get('completetype')
argument_type = ArgumentType(arg_type, arg_complete_type, self.linphone_module)
self.parse_tuple_format += argument_type.fmt_str
if argument_type.fmt_str == 'O':
if argument_type.use_native_pointer:
body += "\tPyObject * " + arg_name + ";\n"
body += "\t" + arg_complete_type + " " + arg_name + "_native_ptr;\n"
elif strip_leading_linphone(arg_complete_type) in self.linphone_module.enum_names:
......@@ -194,7 +207,7 @@ class MethodDefinition:
parse_tuple_code = ''
if len(self.arg_names) > 0:
parse_tuple_code = \
""" if (!PyArg_ParseTuple(args, "{fmt}", {args})) {{
"""if (!PyArg_ParseTuple(args, "{fmt}", {args})) {{
return NULL;
}}
""".format(fmt=self.parse_tuple_format, args=', '.join(map(lambda a: '&' + a, self.arg_names)))
......@@ -252,27 +265,35 @@ class MethodDefinition:
return_from_user_data_code = ''
new_from_native_pointer_code = ''
ref_native_pointer_code = ''
convert_from_code = ''
build_value_code = ''
result_variable = ''
if self.return_complete_type != 'void':
if self.build_value_format == 'O':
stripped_return_type = strip_leading_linphone(self.return_type)
return_type_class = self.find_class_definition(self.return_type)
if return_type_class['class_has_user_data']:
get_user_data_function = return_type_class['class_c_function_prefix'] + "get_user_data"
return_from_user_data_code = \
""" if ((cresult != NULL) && ({func}(cresult) != NULL)) {{
if return_type_class is not None:
if return_type_class['class_has_user_data']:
get_user_data_function = return_type_class['class_c_function_prefix'] + "get_user_data"
return_from_user_data_code = \
"""if ((cresult != NULL) && ({func}(cresult) != NULL)) {{
return (PyObject *){func}(cresult);
}}
""".format(func=get_user_data_function)
new_from_native_pointer_code = "\tpyresult = pylinphone_{return_type}_new_from_native_ptr(&pylinphone_{return_type}Type, cresult);\n".format(return_type=stripped_return_type)
if self.self_arg is not None and return_type_class['class_refcountable']:
ref_function = return_type_class['class_c_function_prefix'] + "ref"
ref_native_pointer_code = \
""" if (cresult != NULL) {{
new_from_native_pointer_code = "pyresult = pylinphone_{return_type}_new_from_native_ptr(&pylinphone_{return_type}Type, cresult);\n".format(return_type=stripped_return_type)
if self.self_arg is not None and return_type_class['class_refcountable']:
ref_function = return_type_class['class_c_function_prefix'] + "ref"
ref_native_pointer_code = \
"""if (cresult != NULL) {{
{func}(({cast_type})cresult);
}}
""".format(func=ref_function, cast_type=self.remove_const_from_complete_type(self.return_complete_type))
else:
return_argument_type = ArgumentType(self.return_type, self.return_complete_type, self.linphone_module)
if return_argument_type.convert_from_func is not None:
convert_from_code = \
"""pyresult = {convert_func}(cresult);
""".format(convert_func=return_argument_type.convert_from_func)
result_variable = 'pyresult'
else:
result_variable = 'cresult'
......@@ -284,11 +305,13 @@ class MethodDefinition:
{return_from_user_data_code}
{new_from_native_pointer_code}
{ref_native_pointer_code}
{convert_from_code}
{build_value_code}
""".format(c_function_call_code=c_function_call_code,
return_from_user_data_code=return_from_user_data_code,
new_from_native_pointer_code=new_from_native_pointer_code,
ref_native_pointer_code=ref_native_pointer_code,
convert_from_code=convert_from_code,
build_value_code=build_value_code)
return body
......@@ -316,7 +339,7 @@ class MethodDefinition:
if return_int:
return_value = "-1"
return \
""" native_ptr = pylinphone_{class_name}_get_native_ptr(self);
"""native_ptr = pylinphone_{class_name}_get_native_ptr(self);
if (native_ptr == NULL) {{
PyErr_SetString(PyExc_TypeError, "Invalid linphone.{class_name} instance");
return {return_value};
......@@ -353,48 +376,6 @@ class MethodDefinition:
splitted_type.remove('const')
return ' '.join(splitted_type)
def ctype_to_str_format(self, name, basic_type, complete_type, with_native_ptr=True):
splitted_type = complete_type.split(' ')
if basic_type == 'char':
if '*' in splitted_type:
return ('\\"%s\\"', [name])
elif 'unsigned' in splitted_type:
return ('%08x', [name])
elif basic_type == 'int':
# TODO:
return ('%d', [name])
elif basic_type == 'int8_t':
return ('%d', [name])
elif basic_type == 'uint8_t':
return ('%u', [name])
elif basic_type == 'int16_t':
return ('%d', [name])
elif basic_type == 'uint16_t':
return ('%u', [name])
elif basic_type == 'int32_t':
return ('%d', [name])
elif basic_type == 'uint32_t':
return ('%u', [name])
elif basic_type == 'int64_t':
return ('%ld', [name])
elif basic_type == 'uint64_t':
return ('%lu', [name])
elif basic_type == 'size_t':
return ('%lu', [name])
elif basic_type == 'float':
return ('%f', [name])
elif basic_type == 'double':
return ('%f', [name])
elif basic_type == 'bool_t':
return ('%d', [name])
else:
if strip_leading_linphone(basic_type) in self.linphone_module.enum_names:
return ('%d', [name])
elif with_native_ptr:
return ('%p [%p]', [name, name + "_native_ptr"])
else:
return ('%p', [name])
def find_class_definition(self, basic_type):
basic_type = strip_leading_linphone(basic_type)
for c in self.linphone_module.classes:
......@@ -544,10 +525,13 @@ class SetterMethodDefinition(MethodDefinition):
if self.first_argument_type.convert_func is None:
attribute_conversion_code = "{arg_name} = value;\n".format(arg_name="_" + self.first_arg_name)
else:
attribute_conversion_code = "{arg_name} = ({arg_type}){convertfunc}(value);\n".format(
arg_name="_" + self.first_arg_name, arg_type=self.first_arg_complete_type, convertfunc=self.first_argument_type.convert_func)
cast_code = ''
if self.first_argument_type.cast_convert_func_result:
cast_code = "({arg_type})".format(arg_type=self.first_arg_complete_type)
attribute_conversion_code = "{arg_name} = {cast_code}{convertfunc}(value);\n".format(
arg_name="_" + self.first_arg_name, cast_code=cast_code, convertfunc=self.first_argument_type.convert_func)
attribute_native_ptr_check_code = ''
if self.first_argument_type.fmt_str == 'O':
if self.first_argument_type.use_native_pointer:
attribute_native_ptr_check_code = \
"""{arg_name}_native_ptr = pylinphone_{arg_class}_get_native_ptr({arg_name});
if ({arg_name}_native_ptr == NULL) {{
......@@ -572,7 +556,7 @@ class SetterMethodDefinition(MethodDefinition):
def format_c_function_call(self):
use_native_ptr = ''
if self.first_argument_type.fmt_str == 'O':
if self.first_argument_type.use_native_pointer:
use_native_ptr = '_native_ptr'
return \
""" {method_name}(native_ptr, {arg_name}{use_native_ptr});
......
......@@ -17,6 +17,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Python.h>
#include <structmember.h>
#include <linphone/linphonecore.h>
#include <linphone/linphone_tunnel.h>
#include <linphone/linphonecore_utils.h>
......@@ -37,6 +38,10 @@ static void pylinphone_dispatch_messages(void);
static PYLINPHONE_INLINE void pylinphone_trace(int indent, const char *fmt, ...);
{{> handwritten_declarations}}
{{#classes}}
static PyTypeObject pylinphone_{{class_name}}Type;
{{/classes}}
......@@ -186,7 +191,7 @@ static PyTypeObject pylinphone_{{class_name}}Type = {
{{/classes}}
{{> handwritten}}
{{> handwritten_definitions}}
static PyMethodDef pylinphone_ModuleMethods[] = {
......@@ -236,6 +241,9 @@ PyMODINIT_FUNC initlinphone(void) {
if (PyType_Ready(&pylinphone_{{class_name}}Type) < 0) return;
{{/classes}}
/* Hand-written classes. */
if (PyType_Ready(&pylinphone_VideoSizeType) < 0) return;
m = Py_InitModule3("linphone", pylinphone_ModuleMethods, "Python module giving access to the Linphone library.");
if (m == NULL) return;
......@@ -252,4 +260,8 @@ PyMODINIT_FUNC initlinphone(void) {
Py_INCREF(&pylinphone_{{class_name}}Type);
PyModule_AddObject(m, "{{class_name}}", (PyObject *)&pylinphone_{{class_name}}Type);
{{/classes}}
/* Hand-written classes. */
Py_INCREF(&pylinphone_VideoSizeType);
PyModule_AddObject(m, "VideoSize", (PyObject *)&pylinphone_VideoSizeType);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment