/**@ingroup tsk_object_group * Creates new object. The object MUST be declared using @ref TSK_DECLARE_OBJECT macro. * @param objdef The object meta-data (definition). For more infomation see @ref tsk_object_def_t. * @param ... List of parameters to pass to the constructor(defined in the meta-data). * @retval @ref tsk_object_t object with a reference counter equal to 1. * @sa @ref tsk_object_new_2. */ tsk_object_t* tsk_object_new(const tsk_object_def_t *objdef, ...) { // Do not check "objdef", let the application die if it's null tsk_object_t *newobj = tsk_calloc(1, objdef->size); if(newobj){ (*(const tsk_object_def_t **) newobj) = objdef; TSK_OBJECT_HEADER(newobj)->refCount = 1; if(objdef->constructor){ va_list ap; tsk_object_t * newobj_ = newobj;// save va_start(ap, objdef); newobj = objdef->constructor(newobj, &ap); // must return new va_end(ap); if(!newobj){ // null if constructor failed to initialized the object if(objdef->destructor){ objdef->destructor(newobj_); } tsk_free(&newobj_); } #if TSK_DEBUG_OBJECTS TSK_DEBUG_INFO("N∞ objects:%d", ++tsk_objects_count); #endif } else{ TSK_DEBUG_WARN("No constructor found."); } } else{ TSK_DEBUG_ERROR("Failed to create new tsk_object."); } return newobj; }
/**@ingroup tsk_buffer_group * Cleanups the internal data and reset the size. * @param self The buffer holding the internal data to free. * @retval Zero if succeed and non-zero error code otherwise. */ int tsk_buffer_cleanup(tsk_buffer_t* self) { if(self && self->data){ tsk_free(&(self->data)); self->size = 0; } return 0; }
/**@ingroup tsk_string_group * Adds quotes to the beginning and end of @a str. * @param str The string to quote. * @param lquote Quote to add to the begining of @a str. * @param rquote Quote to add to the end of @a str. */ void tsk_strquote_2(char **str, char lquote, char rquote) { if(str && *str){ char *result = tsk_null; tsk_sprintf(&result, "%c%s%c", lquote, *str, rquote); tsk_free((void**)str); *str = result; } }
/**@ingroup tsk_buffer_group * Takes the ownership of the @a data. If the destination buffer had data, then it will * be cleaned up. * @param self The buffer * @param data * @param size * @retval Zero if succeed and non-zero error code otherwise. */ int tsk_buffer_takeownership(tsk_buffer_t* self, void** data, tsk_size_t size) { if(!self || !data || !*data || !size){ TSK_DEBUG_ERROR("Invalid parameter"); return -1; } if(self->data){ tsk_free(&(self->data)); } self->data = *data; self->size = size; *data = tsk_null; return 0; }
/**@ingroup tsk_string_group */ int tsk_sprintf_2(char** str, const char* format, va_list* ap) { int len = 0; va_list ap2; /* free previous value */ if(*str){ tsk_free((void**)str); } /* needed for 64bit platforms where vsnprintf will change the va_list */ tsk_va_copy(ap2, *ap); /* compute destination len for windows mobile */ #if defined(_WIN32_WCE) { int n; len = (tsk_strlen(format)*2); *str = (char*)tsk_calloc(1, len+1); for(;;){ if( (n = vsnprintf(*str, len, format, *ap)) >= 0 && (n<len) ){ len = n; goto done; } else{ len += 10; *str = tsk_realloc(*str, len+1); } } done: (*str)[len] = '\0'; } #else len = vsnprintf(0, 0, format, *ap); *str = (char*)tsk_calloc(1, len+1); vsnprintf(*str, len #if !defined(_MSC_VER) || defined(__GNUC__) +1 #endif , format, ap2); #endif va_end(ap2); return len; }
/**@ingroup tsk_condwait_group * Safely free a condwait variable previously created using @ref tsk_condwait_create. * @param handle The condwait handle to free. * @sa @ref tsk_condwait_create */ void tsk_condwait_destroy(tsk_condwait_handle_t** handle) { tsk_condwait_t **condwait = (tsk_condwait_t**)handle; if(condwait && *condwait){ #if TSK_UNDER_WINDOWS CloseHandle((*condwait)->pcond); #else tsk_mutex_destroy(&((*condwait)->mutex)); pthread_cond_destroy((*condwait)->pcond); TSK_FREE((*condwait)->pcond); #endif tsk_free((void**)condwait); } else{ TSK_DEBUG_WARN("Cannot free an uninitialized condwait object"); } }
/**@ingroup tsk_mutex_group * Unlock a mutex previously locked using @ref tsk_mutex_lock. * @param handle The handle of the mutex to unlock. * @retval Zero if succeed and non-zero otherwise. * @sa @ref tsk_mutex_lock. */ int tsk_mutex_unlock(tsk_mutex_handle_t* handle) { int ret = EINVAL; if(handle) { #if TSK_UNDER_WINDOWS if((ret = ReleaseMutex((MUTEX_T)handle) ? 0 : -1)) { ret = GetLastError(); #else if((ret = pthread_mutex_unlock((MUTEX_T)handle))) { #endif if(ret == TSK_ERROR_NOT_OWNER) { TSK_DEBUG_WARN("The calling thread does not own the mutex: %d", ret); } else { TSK_DEBUG_ERROR("Failed to unlock the mutex: %d", ret); } } } return ret; } /**@ingroup tsk_mutex_group * Free/destroy a mutex. * @param handle The mutex to free. * @sa @ref tsk_mutex_create. */ void tsk_mutex_destroy(tsk_mutex_handle_t** handle) { if(handle && *handle) { #if TSK_UNDER_WINDOWS CloseHandle((MUTEX_T)*handle); *handle = tsk_null; #else pthread_mutex_destroy((MUTEX_T)*handle); tsk_free(handle); #endif } else { TSK_DEBUG_WARN("Cannot free an uninitialized mutex"); } }
/**@ingroup tsk_semaphore_group * Destroy a semaphore previously created using @ref tsk_semaphore_create. * @param handle The semaphore to free. * @sa @ref tsk_semaphore_create */ void tsk_semaphore_destroy(tsk_semaphore_handle_t** handle) { if(handle && *handle) { #if TSK_UNDER_WINDOWS CloseHandle((SEMAPHORE_T)*handle); *handle = tsk_null; #else # if TSK_USE_NAMED_SEM named_sem_t * nsem = ((named_sem_t*)*handle); sem_close(nsem->sem); #else sem_destroy((SEMAPHORE_T)GET_SEM(*handle)); #endif /* TSK_USE_NAMED_SEM */ tsk_free(handle); #endif } else{ TSK_DEBUG_WARN("Cannot free an uninitialized semaphore object"); } }
/**@ingroup tsk_string_group * Updates the value of @a str. * @param str The string to update. * @param newval The new value of @a str. */ void tsk_strupdate(char** str, const char* newval) { tsk_free((void**)str); *str = tsk_strdup(newval); }
static int _v4l2_send_frame(tdav_producer_video_v4l2_t* p_self) { struct v4l2_buffer buf; unsigned int i; #define V4L2_SEND_BUFF(_buff, _size) \ TMEDIA_PRODUCER(p_self)->enc_cb.callback(TMEDIA_PRODUCER(p_self)->enc_cb.callback_data, (_buff), (_size)); #if V4L2_FAKE_UYVY { tsk_size_t size = (TMEDIA_PRODUCER(p_self)->video.width * TMEDIA_PRODUCER(p_self)->video.height) << 1; uint8_t* buff = (uint8_t*)tsk_malloc(size); if (buff) { tsk_size_t i; for (i = 0; i < size; ++i) { buff[i] = rand() & 254; } V4L2_SEND_BUFF(buff, size); tsk_free((void**)&buff); } return 0; } #endif switch (p_self->io) { case V4L2_IO_METHOD_READ: if (-1 == read(p_self->fd, p_self->p_buffers[0].p_start, p_self->p_buffers[0].n_length)) { switch (errno) { case EAGAIN: return 0; case EIO: /* Could ignore EIO, see spec. */ /* fall through */ default: V4L2_DEBUG_ERROR("read() failed: %s error %d", strerror(errno), errno); break; } } V4L2_SEND_BUFF(p_self->p_buffers[0].p_start, p_self->p_buffers[0].n_length); return 0; case V4L2_IO_METHOD_MMAP: V4L2_CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; if (-1 == _v4l2_xioctl(p_self->fd, VIDIOC_DQBUF, &buf)) { switch (errno) { case EAGAIN: V4L2_DEBUG_INFO("EAGAIN"); return 0; case EIO: /* Could ignore EIO, see spec. */ /* fall through */ default: V4L2_DEBUG_ERROR("xioctl(VIDIOC_DQBUF) failed: %s error %d", strerror(errno), errno); break; } } assert(buf.index < p_self->n_buffers); V4L2_SEND_BUFF(p_self->p_buffers[buf.index].p_start, buf.bytesused); if (-1 == _v4l2_xioctl(p_self->fd, VIDIOC_QBUF, &buf)) { V4L2_DEBUG_ERROR("xioctl(VIDIOC_DQBUF) failed: %s error %d", strerror(errno), errno); break; } return 0; case V4L2_IO_METHOD_USERPTR: V4L2_CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_USERPTR; if (-1 == _v4l2_xioctl(p_self->fd, VIDIOC_DQBUF, &buf)) { switch (errno) { case EAGAIN: V4L2_DEBUG_INFO("EAGAIN"); return 0; case EIO: /* Could ignore EIO, see spec. */ /* fall through */ default: V4L2_DEBUG_ERROR("xioctl(VIDIOC_DQBUF) failed: %s error %d", strerror(errno), errno); break; } } for (i = 0; i < p_self->n_buffers; ++i) { if (buf.m.userptr == (unsigned long)p_self->p_buffers[i].p_start && buf.length == p_self->p_buffers[i].n_length) { break; } } V4L2_SEND_BUFF((void *)buf.m.userptr, buf.bytesused); if (-1 == _v4l2_xioctl(p_self->fd, VIDIOC_QBUF, &buf)) { V4L2_DEBUG_ERROR("xioctl(VIDIOC_DQBUF) failed: %s error %d", strerror(errno), errno); break; } return 0; } return -1; }