/** * Enable/disable vidmix source * * @param src Video mixer source * @param enable True to enable, false to disable */ void vidmix_source_enable(struct vidmix_source *src, bool enable) { if (!src) return; if (src->le.list && enable) return; if (!src->le.list && !enable) return; pthread_rwlock_wrlock(&src->mix->rwlock); if (enable) { if (src->frame_rx) clear_frame(src->frame_rx); list_append(&src->mix->srcl, &src->le, src); } else { list_unlink(&src->le); } clear_all(src->mix); pthread_rwlock_unlock(&src->mix->rwlock); }
/* * Function to deallocate a frame. */ void free_frame(page_t* page) { uint32_t frame; if (!(frame=page->frame)) { return; } else { clear_frame(frame); page->frame = 0x0; } }
void free_frame(struct page *page) { uint32_t frame; if (!(frame = page->frame)) return; else { clear_frame(frame); page->frame = 0x00000; } }
/* Function to deallocate a frame */ void frame_free(struct page* p) { addr frame; if (!(frame = p->frame)) { /* The given page didn't actually have an allocate frame */ } else { clear_frame(frame); /* Frame is now free again */ p->frame = 0x0; /* Page now doesn't have a frame */ } }
/** * Allocate a video mixer source * * @param srcp Pointer to allocated video source * @param mix Video mixer * @param sz Size of output video frame (optional) * @param fps Output frame rate (frames per second) * @param content True if source is of type content * @param fh Mixer frame handler * @param arg Handler argument * * @return 0 for success, otherwise error code */ int vidmix_source_alloc(struct vidmix_source **srcp, struct vidmix *mix, const struct vidsz *sz, unsigned fps, bool content, vidmix_frame_h *fh, void *arg) { struct vidmix_source *src; int err; if (!srcp || !mix || !fps || !fh) return EINVAL; src = mem_zalloc(sizeof(*src), source_destructor); if (!src) return ENOMEM; src->mix = mem_ref(mix); src->fint = 1000/fps; src->content = content; src->fh = fh; src->arg = arg; err = pthread_mutex_init(&src->mutex, NULL); if (err) goto out; if (sz) { err = vidframe_alloc(&src->frame_tx, VID_FMT_YUV420P, sz); if (err) goto out; clear_frame(src->frame_tx); } out: if (err) mem_deref(src); else *srcp = src; return err; }
void page_free(struct page *p) { uint32_t frame; ASSERT(p != NULL); #ifdef _DEBUG_MM DEBUG(DL_DBG, ("page(%p), frame(%x).\n", p, p->frame)); #endif /* _DEBUG_MM */ if (!(frame = p->frame)) { DEBUG(DL_WRN, ("free page(%p) not allocated.\n", p)); PANIC("free page not allocated"); } else { spinlock_acquire(&_pages_lock); clear_frame(frame); spinlock_release(&_pages_lock); p->frame = 0; p->present = 0; } }
/** * Set video mixer output frame size * * @param src Video mixer source * @param sz Size of output video frame * * @return 0 for success, otherwise error code */ int vidmix_source_set_size(struct vidmix_source *src, const struct vidsz *sz) { struct vidframe *frame; int err; if (!src || !sz) return EINVAL; if (src->frame_tx && vidsz_cmp(&src->frame_tx->size, sz)) return 0; err = vidframe_alloc(&frame, VID_FMT_YUV420P, sz); if (err) return err; clear_frame(frame); pthread_mutex_lock(&src->mutex); mem_deref(src->frame_tx); src->frame_tx = frame; pthread_mutex_unlock(&src->mutex); return 0; }
static void *vidmix_thread(void *arg) { struct vidmix_source *src = arg; struct vidmix *mix = src->mix; uint64_t ts = tmr_jiffies(); pthread_mutex_lock(&src->mutex); while (src->run) { unsigned n, rows, idx; struct le *le; uint64_t now; pthread_mutex_unlock(&src->mutex); (void)usleep(4000); pthread_mutex_lock(&src->mutex); now = tmr_jiffies(); if (ts > now) continue; if (!src->frame_tx) { ts += src->fint; continue; } pthread_rwlock_rdlock(&mix->rwlock); if (src->clear) { clear_frame(src->frame_tx); src->clear = false; } for (le=mix->srcl.head, n=0; le; le=le->next) { const struct vidmix_source *lsrc = le->data; if (lsrc == src && !src->selfview) continue; if (lsrc->content && src->content_hide) continue; if (lsrc == src->focus && src->focus_full) source_mix_full(src->frame_tx, lsrc->frame_rx); ++n; } rows = calc_rows(n); for (le=mix->srcl.head, idx=0; le; le=le->next) { const struct vidmix_source *lsrc = le->data; if (lsrc == src && !src->selfview) continue; if (lsrc->content && src->content_hide) continue; if (lsrc == src->focus && src->focus_full) continue; source_mix(src->frame_tx, lsrc->frame_rx, n, rows, idx, src->focus != NULL, src->focus == lsrc, src->focus_full); if (src->focus != lsrc) ++idx; } pthread_rwlock_unlock(&mix->rwlock); src->fh((uint32_t)ts * 90, src->frame_tx, src->arg); ts += src->fint; } pthread_mutex_unlock(&src->mutex); return NULL; }
void free_frame(u32int p) { clear_frame(p); }
void mpxplay_infile_close(struct mpxpframe_s *frp) { mpxplay_infile_suspend_close(frp); clear_frame(frp); }