%module oggplay %{ #include "oggplay/oggplay.h" %} typedef enum OggPlayErrorCode { E_OGGPLAY_CONTINUE = 1, E_OGGPLAY_OK = 0, E_OGGPLAY_BAD_OGGPLAY = -1, E_OGGPLAY_BAD_READER = -2, E_OGGPLAY_BAD_INPUT = -3, E_OGGPLAY_NO_SUCH_CHUNK = -4, E_OGGPLAY_BAD_TRACK = -5, E_OGGPLAY_TRACK_IS_SKELETON = -6, E_OGGPLAY_OGGZ_UNHAPPY = -7, E_OGGPLAY_END_OF_FILE = -8, E_OGGPLAY_TRACK_IS_OVER = -9, E_OGGPLAY_BAD_CALLBACK_INFO = -10, E_OGGPLAY_WRONG_TRACK_TYPE = -11, E_OGGPLAY_UNINITIALISED = -12, E_OGGPLAY_CALLBACK_MODE = -13, E_OGGPLAY_BUFFER_MODE = -14, E_OGGPLAY_USER_INTERRUPT = -15, E_OGGPLAY_SOCKET_ERROR = -16, E_OGGPLAY_TIMEOUT = -17, E_OGGPLAY_CANT_SEEK = -18, E_OGGPLAY_NO_KATE_SUPPORT = -19, E_OGGPLAY_NO_TIGER_SUPPORT = -20, E_OGGPLAY_NOTCHICKENPAYBACK = -777 } OggPlayErrorCode; typedef enum OggzStreamContent { OGGZ_CONTENT_THEORA = 0, OGGZ_CONTENT_VORBIS, OGGZ_CONTENT_SPEEX, OGGZ_CONTENT_PCM, OGGZ_CONTENT_CMML, OGGZ_CONTENT_ANX2, OGGZ_CONTENT_SKELETON, OGGZ_CONTENT_FLAC0, OGGZ_CONTENT_FLAC, OGGZ_CONTENT_ANXDATA, OGGZ_CONTENT_CELT, OGGZ_CONTENT_KATE, OGGZ_CONTENT_UNKNOWN } OggzStreamContent; typedef int (OggPlayDataCallback)(OggPlay *player, int num_records, OggPlayCallbackInfo **records, void *user); %{ static int PythonCallBack(OggPlay *player, int num_records, OggPlayCallbackInfo **records, void *user_data) { PyObject * func; PyObject * arglist; PyObject * player_p; PyObject * result; int r = 0; int i; PyObject * list; list = PyList_New(4); for (i = 0; i < num_records; i++) { PyList_SetItem(list, i, SWIG_NewPointerObj(SWIG_as_voidptr(records[i]), SWIGTYPE_p_OggPlayCallbackInfo, 0 | 0)); } player_p = SWIG_NewPointerObj(SWIG_as_voidptr(player), SWIGTYPE_p_OggPlay, 0 | 0); func = (PyObject *)user_data; arglist = Py_BuildValue("NN", player_p, list); result = PyEval_CallObject(func, arglist); Py_DECREF(arglist); Py_DECREF(list); if (result) { r = (int)PyInt_AsLong(result); } Py_XDECREF(result); return r; } static void oggplay_set_data_pycallback(OggPlay *me, PyObject *pycallback) { oggplay_set_data_callback(me, PythonCallBack, pycallback); Py_INCREF(pycallback); } #define CLAMP(v) ((v) > 255 ? 255 : (v) < 0 ? 0 : (v)) typedef struct { unsigned char *data; int width; int height; } OggPlayVideoFrame; OggPlayVideoFrame *oggplay_generate_frame(OggPlay *p, int track, OggPlayDataHeader *h) { OggPlayVideoData *yuv = oggplay_callback_info_get_video_data(h); int width; int height; oggplay_get_video_y_size(p, track, &width, &height); unsigned char * ptry = yuv->y; unsigned char * ptru = yuv->u; unsigned char * ptrv = yuv->v; unsigned char * ptro = malloc(width * height * 4); unsigned char * out = ptro; unsigned char * ptro2; int i, j; for (i = 0; i < height; i++) { ptro2 = ptro; for (j = 0; j < width; j += 2) { short pr, pg, pb; short r, g, b; //pr = ((128 + (ptrv[j/2] - 128) * 292) >> 8) - 16; /* 1.14 * 256 */ pr = (-41344 + ptrv[j/2] * 292) >> 8; //pg = ((128 - (ptru[j/2] - 128) * 101 - (ptrv[j/2] - 128) * 149) >> 8)-16; // /* 0.395 & 0.581 */ pg = (28032 - ptru[j/2] * 101 - ptrv[j/2] * 149) >> 8; //pb = ((128 + (ptru[j/2] - 128) * 520) >> 8) - 16; /* 2.032 */ pb = (-70528 + ptru[j/2] * 520) >> 8; r = ptry[j] + pr; g = ptry[j] + pg; b = ptry[j] + pb; *ptro2++ = CLAMP(r); *ptro2++ = CLAMP(g); *ptro2++ = CLAMP(b); *ptro2++ = 255; r = ptry[j + 1] + pr; g = ptry[j + 1] + pg; b = ptry[j + 1] + pb; *ptro2++ = CLAMP(r); *ptro2++ = CLAMP(g); *ptro2++ = CLAMP(b); *ptro2++ = 255; } ptry += width; if (i & 1) { ptru += width/2; ptrv += width/2; } ptro += width * 4; } OggPlayVideoFrame *r = malloc(sizeof(OggPlayVideoFrame)); r->data = out; r->width = width; r->height = height; return r; } %} %typemap(out) OggPlayDataHeader ** { int len = 0; $result = PyList_New(0); while ($1[len]) { PyList_Append($result, SWIG_NewPointerObj(SWIG_as_voidptr($1[len]), SWIGTYPE_p__OggPlayDataHeader, 0 | 0)); len++; } } %typemap(argout) (int *width, int *height) { PyObject *o1 = PyInt_FromLong(*$1); PyObject *o2 = PyInt_FromLong(*$2); $result = PyList_New(0); PyList_Append($result, o1); PyList_Append($result, o2); Py_XDECREF(o1); Py_XDECREF(o2); } %typemap(in,numinputs=0) (int *width, int *height) (int a, int b) { $1 = &a; $2 = &b; } %typemap(out) (OggPlayVideoFrame *) { $result = PyTuple_New(2); PyTuple_SetItem($result, 0, Py_BuildValue("s#", $1->data, $1->width * $1->height * 4)); PyTuple_SetItem($result, 1, Py_BuildValue("ii", $1->width, $1->height)); free($1->data); free($1); } typedef long long ogg_int64_t; OggPlay * oggplay_open_with_reader(OggPlayReader *reader); OggPlay * oggplay_new_with_reader(OggPlayReader *reader); OggPlayErrorCode oggplay_initialise(OggPlay *me, int block); void oggplay_set_data_pycallback(OggPlay *me, PyObject *pycallback); typedef struct { unsigned char *data; int width; int height; } OggPlayVideoFrame; OggPlayVideoFrame *oggplay_generate_frame(OggPlay *p, int track, OggPlayDataHeader *h); OggPlayErrorCode oggplay_set_callback_num_frames(OggPlay *me, int stream, int frames); OggPlayErrorCode oggplay_set_callback_period(OggPlay *me, int stream, int milliseconds); OggPlayErrorCode oggplay_set_offset(OggPlay *me, int track, ogg_int64_t offset); OggPlayErrorCode oggplay_get_video_y_size(OggPlay *me, int track, int *width, int *height); OggPlayErrorCode oggplay_get_video_uv_size(OggPlay *me, int track, int *width, int *height); OggPlayErrorCode oggplay_get_audio_channels(OggPlay *me, int track, int *channels); OggPlayErrorCode oggplay_get_audio_samplerate(OggPlay *me, int track, int *samplerate); OggPlayErrorCode oggplay_get_video_fps(OggPlay *me, int track, int* fps_denom, int* fps_num); OggPlayErrorCode oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert); OggPlayErrorCode oggplay_get_kate_language(OggPlay *me, int track, const char** language); OggPlayErrorCode oggplay_get_kate_category(OggPlay *me, int track, const char** category); OggPlayErrorCode oggplay_set_kate_tiger_rendering(OggPlay *me, int track, int use_tiger); OggPlayErrorCode oggplay_overlay_kate_track_on_video(OggPlay *me, int kate_track, int video_track); OggPlayErrorCode oggplay_start_decoding(OggPlay *me); OggPlayErrorCode oggplay_step_decoding(OggPlay *me); OggPlayErrorCode oggplay_use_buffer(OggPlay *player, int size); OggPlayCallbackInfo ** oggplay_buffer_retrieve_next(OggPlay *player); OggPlayErrorCode oggplay_buffer_release(OggPlay *player, OggPlayCallbackInfo **track_info); void oggplay_prepare_for_close(OggPlay *me); OggPlayErrorCode oggplay_close(OggPlay *player); int oggplay_get_available(OggPlay *player); int oggplay_get_duration(OggPlay * player); OggPlayReader * oggplay_file_reader_new(char *filename); OggPlayReader * oggplay_tcp_reader_new(char *uri, char *proxy, int proxy_port); int oggplay_get_num_tracks (OggPlay * me); OggzStreamContent oggplay_get_track_type (OggPlay * me, int track_num); const char * oggplay_get_track_typename (OggPlay * me, int track_num); OggPlayErrorCode oggplay_set_track_active(OggPlay *me, int track_num); typedef void * OggPlayAudioData; typedef char OggPlayTextData; struct _OggPlayDataHeader; typedef struct _OggPlayDataHeader OggPlayDataHeader; OggPlayDataType oggplay_callback_info_get_type(OggPlayCallbackInfo *info); int oggplay_callback_info_get_available(OggPlayCallbackInfo *info); int oggplay_callback_info_get_required(OggPlayCallbackInfo *info); OggPlayDataHeader ** oggplay_callback_info_get_headers(OggPlayCallbackInfo *info); int oggplay_callback_info_get_record_size(OggPlayDataHeader *header); OggPlayVideoData * oggplay_callback_info_get_video_data(OggPlayDataHeader *header); OggPlayAudioData * oggplay_callback_info_get_audio_data(OggPlayDataHeader *header); OggPlayTextData * oggplay_callback_info_get_text_data(OggPlayDataHeader *header); OggPlayStreamInfo oggplay_callback_info_get_stream_info(OggPlayCallbackInfo *info); void oggplay_callback_info_lock_item(OggPlayDataHeader *header); void oggplay_callback_info_unlock_item(OggPlayDataHeader *header); long oggplay_callback_info_get_presentation_time(OggPlayDataHeader *header); OggPlayErrorCode oggplay_seek(OggPlay *me, ogg_int64_t milliseconds);