/** @This allocates a new uclock structure. * * @param flags flags for the creation of a uclock structure * @return pointer to uclock, or NULL in case of error */ struct uclock *uclock_std_alloc(enum uclock_std_flags flags) { #ifdef __MACH__ clock_serv_t cclock; mach_timespec_t ts; if (unlikely(host_get_clock_service(mach_host_self(), unlikely(flags & UCLOCK_FLAG_REALTIME) ? CALENDAR_CLOCK : REALTIME_CLOCK, &cclock) < 0)) { return NULL; } if(unlikely(clock_get_time(cclock, &ts) < 0)) { mach_port_deallocate(mach_task_self(), cclock); return NULL; } #else struct timespec ts; if (unlikely(clock_gettime(unlikely(flags & UCLOCK_FLAG_REALTIME) ? CLOCK_REALTIME : CLOCK_MONOTONIC, &ts) == -1)) return NULL; #endif struct uclock_std *uclock_std = malloc(sizeof(struct uclock_std)); if (unlikely(uclock_std == NULL)) return NULL; uclock_std->flags = flags; urefcount_init(uclock_std_to_urefcount(uclock_std), uclock_std_free); uclock_std->uclock.refcount = uclock_std_to_urefcount(uclock_std); uclock_std->uclock.uclock_now = uclock_std_now; uclock_std->uclock.uclock_to_real = uclock_std_to_real; uclock_std->uclock.uclock_from_real = uclock_std_from_real; #ifdef __MACH__ memcpy(&uclock_std->cclock, &cclock, sizeof(cclock)); #endif return uclock_std_to_uclock(uclock_std); }
/** @This allocates a new instance of the standard uref manager * * @param uref_pool_depth maximum number of uref structures in the pool * @param udict_mgr udict manager to use to allocate udict structures * @param control_attr_size extra attributes space for control packets * @return pointer to manager, or NULL in case of error */ struct uref_mgr *uref_std_mgr_alloc(uint16_t uref_pool_depth, struct udict_mgr *udict_mgr, int control_attr_size) { assert(udict_mgr != NULL); assert(control_attr_size >= 0); struct uref_std_mgr *std_mgr = malloc(sizeof(struct uref_std_mgr) + upool_sizeof(uref_pool_depth)); if (unlikely(std_mgr == NULL)) return NULL; upool_init(&std_mgr->uref_pool, uref_pool_depth, std_mgr->upool_extra, uref_std_alloc_inner, uref_std_free_inner); std_mgr->mgr.control_attr_size = control_attr_size; std_mgr->mgr.udict_mgr = udict_mgr; udict_mgr_use(udict_mgr); urefcount_init(uref_std_mgr_to_urefcount(std_mgr), uref_std_mgr_free); std_mgr->mgr.refcount = uref_std_mgr_to_urefcount(std_mgr); std_mgr->mgr.uref_alloc = uref_std_alloc; std_mgr->mgr.uref_free = uref_std_free; std_mgr->mgr.uref_mgr_control = uref_std_mgr_control; return uref_std_mgr_to_uref_mgr(std_mgr); }
/** @This allocates a new instance of the umem alloc manager allocating buffers * from application memory directly with malloc()/free(), without any pool. * * @return pointer to manager, or NULL in case of error */ struct umem_mgr *umem_alloc_mgr_alloc(void) { struct umem_alloc_mgr *alloc_mgr = malloc(sizeof(struct umem_alloc_mgr)); if (unlikely(alloc_mgr == NULL)) return NULL; urefcount_init(&alloc_mgr->mgr.refcount); alloc_mgr->mgr.umem_alloc = umem_alloc_alloc; alloc_mgr->mgr.umem_realloc = umem_alloc_realloc; alloc_mgr->mgr.umem_free = umem_alloc_free; alloc_mgr->mgr.umem_mgr_vacuum = NULL; alloc_mgr->mgr.umem_mgr_free = umem_alloc_mgr_free; return umem_alloc_mgr_to_umem_mgr(alloc_mgr); }
/** @This returns the management structure for all fdec pipes. * * @return pointer to manager */ struct upipe_mgr *upipe_fdec_mgr_alloc(void) { struct upipe_fdec_mgr *fdec_mgr = malloc(sizeof(struct upipe_fdec_mgr)); if (unlikely(fdec_mgr == NULL)) return NULL; fdec_mgr->avcdec_mgr = NULL; urefcount_init(upipe_fdec_mgr_to_urefcount(fdec_mgr), upipe_fdec_mgr_free); fdec_mgr->mgr.refcount = upipe_fdec_mgr_to_urefcount(fdec_mgr); fdec_mgr->mgr.signature = UPIPE_FDEC_SIGNATURE; fdec_mgr->mgr.upipe_alloc = upipe_fdec_alloc; fdec_mgr->mgr.upipe_input = upipe_fdec_bin_input; fdec_mgr->mgr.upipe_control = upipe_fdec_control; fdec_mgr->mgr.upipe_mgr_control = upipe_fdec_mgr_control; return upipe_fdec_mgr_to_upipe_mgr(fdec_mgr); }
/** @internal @This allocates a fdec pipe. * * @param mgr common management structure * @param uprobe structure used to raise events * @param signature signature of the pipe allocator * @param args optional arguments * @return pointer to upipe or NULL in case of allocation error */ static struct upipe *upipe_fdec_alloc(struct upipe_mgr *mgr, struct uprobe *uprobe, uint32_t signature, va_list args) { struct upipe *upipe = upipe_fdec_alloc_void(mgr, uprobe, signature, args); if (unlikely(upipe == NULL)) return NULL; struct upipe_fdec *upipe_fdec = upipe_fdec_from_upipe(upipe); upipe_fdec_init_urefcount(upipe); urefcount_init(upipe_fdec_to_urefcount_real(upipe_fdec), upipe_fdec_free); upipe_fdec_init_uref_mgr(upipe); upipe_fdec_init_bin_input(upipe); upipe_fdec_init_bin_output(upipe, upipe_fdec_to_urefcount_real(upipe_fdec)); upipe_fdec->options = NULL; upipe_throw_ready(upipe); upipe_fdec_demand_uref_mgr(upipe); return upipe; }
/** @This returns the management structure for all wsrc pipes. * * @param xfer_mgr manager to transfer pipes to the remote thread * @return pointer to manager */ struct upipe_mgr *upipe_wsrc_mgr_alloc(struct upipe_mgr *xfer_mgr) { assert(xfer_mgr != NULL); struct upipe_wsrc_mgr *wsrc_mgr = malloc(sizeof(struct upipe_wsrc_mgr)); if (unlikely(wsrc_mgr == NULL)) return NULL; wsrc_mgr->qsrc_mgr = upipe_qsrc_mgr_alloc(); wsrc_mgr->qsink_mgr = upipe_qsink_mgr_alloc(); wsrc_mgr->xfer_mgr = upipe_mgr_use(xfer_mgr); urefcount_init(upipe_wsrc_mgr_to_urefcount(wsrc_mgr), upipe_wsrc_mgr_free); wsrc_mgr->mgr.refcount = upipe_wsrc_mgr_to_urefcount(wsrc_mgr); wsrc_mgr->mgr.signature = UPIPE_WSRC_SIGNATURE; wsrc_mgr->mgr.upipe_alloc = _upipe_wsrc_alloc; wsrc_mgr->mgr.upipe_input = NULL; wsrc_mgr->mgr.upipe_control = upipe_wsrc_control_bin_output; wsrc_mgr->mgr.upipe_mgr_control = upipe_wsrc_mgr_control; return upipe_wsrc_mgr_to_upipe_mgr(wsrc_mgr); }
/** @internal @This allocates a burst pipe. * * @param mgr management structure for this pipe type * @param uprobe structure used to raise events * @param signature signature of the pipe allocator * @param args optional arguments * @return an allocated pipe */ static struct upipe *upipe_burst_alloc(struct upipe_mgr *mgr, struct uprobe *uprobe, uint32_t signature, va_list args) { struct upipe *upipe = upipe_burst_alloc_void(mgr, uprobe, signature, args); if (unlikely(upipe == NULL)) return NULL; upipe_burst_init_urefcount(upipe); upipe_burst_init_output(upipe); upipe_burst_init_upump_mgr(upipe); upipe_burst_init_upump(upipe); struct upipe_burst *upipe_burst = upipe_burst_from_upipe(upipe); urefcount_init(&upipe_burst->urefcount_real, upipe_burst_free); ulist_init(&upipe_burst->urefs); ueventfd_init(&upipe_burst->ueventfd, false); upipe_burst->empty = true; upipe_throw_ready(upipe); return upipe; }
/** @internal @This allocates a wsrc pipe. * * @param mgr common management structure * @param uprobe structure used to raise events * @param signature signature of the pipe allocator * @param args optional arguments * @return pointer to upipe or NULL in case of allocation error */ static struct upipe *_upipe_wsrc_alloc(struct upipe_mgr *mgr, struct uprobe *uprobe, uint32_t signature, va_list args) { struct upipe_wsrc_mgr *wsrc_mgr = upipe_wsrc_mgr_from_upipe_mgr(mgr); if (unlikely(signature != UPIPE_WSRC_SIGNATURE || wsrc_mgr->xfer_mgr == NULL)) goto upipe_wsrc_alloc_err; struct upipe *remote = va_arg(args, struct upipe *); struct uprobe *uprobe_remote = va_arg(args, struct uprobe *); unsigned int queue_length = va_arg(args, unsigned int); assert(queue_length); if (unlikely(remote == NULL)) goto upipe_wsrc_alloc_err2; struct upipe_wsrc *upipe_wsrc = malloc(sizeof(struct upipe_wsrc)); if (unlikely(upipe_wsrc == NULL)) goto upipe_wsrc_alloc_err2; struct upipe *upipe = upipe_wsrc_to_upipe(upipe_wsrc); upipe_init(upipe, mgr, uprobe); upipe_wsrc_init_urefcount(upipe); urefcount_init(upipe_wsrc_to_urefcount_real(upipe_wsrc), upipe_wsrc_free); upipe_wsrc_init_last_inner_probe(upipe); upipe_wsrc_init_bin_output(upipe); upipe_wsrc->source = NULL; uprobe_init(&upipe_wsrc->proxy_probe, upipe_wsrc_proxy_probe, NULL); upipe_wsrc->proxy_probe.refcount = upipe_wsrc_to_urefcount_real(upipe_wsrc); uprobe_init(&upipe_wsrc->qsrc_probe, upipe_wsrc_qsrc_probe, &upipe_wsrc->last_inner_probe); upipe_wsrc->qsrc_probe.refcount = upipe_wsrc_to_urefcount_real(upipe_wsrc); upipe_throw_ready(upipe); /* output queue */ struct upipe *out_qsrc = upipe_qsrc_alloc(wsrc_mgr->qsrc_mgr, uprobe_pfx_alloc(uprobe_use(&upipe_wsrc->qsrc_probe), UPROBE_LOG_VERBOSE, "out_qsrc"), queue_length > UINT8_MAX ? UINT8_MAX : queue_length); if (unlikely(out_qsrc == NULL)) goto upipe_wsrc_alloc_err3; struct upipe *out_qsink = upipe_qsink_alloc(wsrc_mgr->qsink_mgr, uprobe_pfx_alloc(uprobe_remote, UPROBE_LOG_VERBOSE, "out_qsink"), out_qsrc); if (unlikely(out_qsink == NULL)) { upipe_release(out_qsrc); goto upipe_wsrc_alloc_err3; } if (queue_length > UINT8_MAX) upipe_set_max_length(out_qsink, queue_length - UINT8_MAX); upipe_attach_upump_mgr(out_qsrc); upipe_wsrc_store_bin_output(upipe, out_qsrc); /* last remote */ struct upipe *last_remote = upipe_use(remote); struct upipe *tmp; /* upipe_get_output is a control command and may trigger a need_upump_mgr * event */ uprobe_throw(upipe->uprobe, NULL, UPROBE_FREEZE_UPUMP_MGR); while (ubase_check(upipe_get_output(last_remote, &tmp)) && tmp != NULL) { upipe_use(tmp); upipe_release(last_remote); last_remote = tmp; } uprobe_throw(upipe->uprobe, NULL, UPROBE_THAW_UPUMP_MGR); struct upipe *last_remote_xfer = upipe_xfer_alloc(wsrc_mgr->xfer_mgr, uprobe_pfx_alloc(uprobe_use(&upipe_wsrc->proxy_probe), UPROBE_LOG_VERBOSE, "src_last_xfer"), last_remote); if (unlikely(last_remote_xfer == NULL)) { upipe_release(out_qsink); goto upipe_wsrc_alloc_err3; } upipe_attach_upump_mgr(last_remote_xfer); upipe_set_output(last_remote_xfer, out_qsink); upipe_release(out_qsink); /* remote */ if (last_remote != remote) { upipe_wsrc->source = upipe_xfer_alloc(wsrc_mgr->xfer_mgr, uprobe_pfx_alloc(uprobe_use(&upipe_wsrc->proxy_probe), UPROBE_LOG_VERBOSE, "src_xfer"), remote); if (unlikely(upipe_wsrc->source == NULL)) { upipe_release(out_qsink); upipe_release(upipe); return NULL; } upipe_attach_upump_mgr(upipe_wsrc->source); upipe_release(last_remote_xfer); } else { upipe_wsrc->source = last_remote_xfer; upipe_release(remote); } return upipe; upipe_wsrc_alloc_err3: upipe_release(remote); upipe_release(upipe); return NULL; upipe_wsrc_alloc_err2: uprobe_release(uprobe_remote); upipe_release(remote); upipe_wsrc_alloc_err: uprobe_release(uprobe); return NULL; }
/** @internal @This allocates a wsink pipe. * * @param mgr common management structure * @param uprobe structure used to raise events * @param signature signature of the pipe allocator * @param args optional arguments * @return pointer to upipe or NULL in case of allocation error */ static struct upipe *_upipe_wsink_alloc(struct upipe_mgr *mgr, struct uprobe *uprobe, uint32_t signature, va_list args) { struct upipe_wsink_mgr *wsink_mgr = upipe_wsink_mgr_from_upipe_mgr(mgr); if (unlikely(signature != UPIPE_WSINK_SIGNATURE || wsink_mgr->xfer_mgr == NULL)) goto upipe_wsink_alloc_err; struct upipe *remote = va_arg(args, struct upipe *); struct uprobe *uprobe_remote = va_arg(args, struct uprobe *); unsigned int queue_length = va_arg(args, unsigned int); assert(queue_length); if (unlikely(remote == NULL)) goto upipe_wsink_alloc_err2; struct upipe_wsink *upipe_wsink = malloc(sizeof(struct upipe_wsink)); if (unlikely(upipe_wsink == NULL)) goto upipe_wsink_alloc_err2; struct upipe *upipe = upipe_wsink_to_upipe(upipe_wsink); upipe_init(upipe, mgr, uprobe); upipe_wsink_init_urefcount(upipe); urefcount_init(upipe_wsink_to_urefcount_real(upipe_wsink), upipe_wsink_free); upipe_wsink_init_bin_input(upipe); uprobe_init(&upipe_wsink->proxy_probe, upipe_wsink_proxy_probe, NULL); upipe_wsink->proxy_probe.refcount = upipe_wsink_to_urefcount_real(upipe_wsink); uprobe_init(&upipe_wsink->in_qsrc_probe, upipe_wsink_in_qsrc_probe, uprobe_remote); upipe_wsink->in_qsrc_probe.refcount = upipe_wsink_to_urefcount_real(upipe_wsink); upipe_throw_ready(upipe); /* remote */ upipe_use(remote); struct upipe *remote_xfer = upipe_xfer_alloc(wsink_mgr->xfer_mgr, uprobe_pfx_alloc(uprobe_use(&upipe_wsink->proxy_probe), UPROBE_LOG_VERBOSE, "sink_xfer"), remote); if (unlikely(remote_xfer == NULL)) { upipe_release(remote); upipe_release(upipe); return NULL; } upipe_attach_upump_mgr(remote_xfer); /* input queue */ struct upipe *in_qsrc = upipe_qsrc_alloc(wsink_mgr->qsrc_mgr, uprobe_pfx_alloc( uprobe_use(&upipe_wsink->in_qsrc_probe), UPROBE_LOG_VERBOSE, "in_qsrc"), queue_length > UINT8_MAX ? UINT8_MAX : queue_length); if (unlikely(in_qsrc == NULL)) goto upipe_wsink_alloc_err3; struct upipe *in_qsink = upipe_qsink_alloc(wsink_mgr->qsink_mgr, uprobe_pfx_alloc(uprobe_use(&upipe_wsink->proxy_probe), UPROBE_LOG_VERBOSE, "in_qsink"), in_qsrc); if (unlikely(in_qsink == NULL)) goto upipe_wsink_alloc_err3; upipe_wsink_store_bin_input(upipe, in_qsink); if (queue_length > UINT8_MAX) upipe_set_max_length(upipe_wsink->in_qsink, queue_length - UINT8_MAX); struct upipe *in_qsrc_xfer = upipe_xfer_alloc(wsink_mgr->xfer_mgr, uprobe_pfx_alloc(uprobe_use(&upipe_wsink->proxy_probe), UPROBE_LOG_VERBOSE, "in_qsrc_xfer"), in_qsrc); if (unlikely(in_qsrc_xfer == NULL)) goto upipe_wsink_alloc_err3; upipe_set_output(in_qsrc_xfer, remote); upipe_attach_upump_mgr(in_qsrc_xfer); upipe_release(remote); upipe_release(remote_xfer); upipe_release(in_qsrc_xfer); return upipe; upipe_wsink_alloc_err3: upipe_release(remote); upipe_release(remote_xfer); upipe_release(upipe); return NULL; upipe_wsink_alloc_err2: upipe_release(remote); upipe_wsink_alloc_err: uprobe_release(uprobe); return NULL; }