From 8b8182da6e16dfd0820ef2418c1bb66d4bcc8079 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 2 Jul 2012 10:50:47 +0200 Subject: v4l-mfc-encoder: version 0.1 Signed-off-by: Andrzej Hajda Signed-off-by: Kamil Debski --- v4l2-mfc-encoder/func_dev.c | 132 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 v4l2-mfc-encoder/func_dev.c (limited to 'v4l2-mfc-encoder/func_dev.c') diff --git a/v4l2-mfc-encoder/func_dev.c b/v4l2-mfc-encoder/func_dev.c new file mode 100644 index 0000000..c3fff54 --- /dev/null +++ b/v4l2-mfc-encoder/func_dev.c @@ -0,0 +1,132 @@ +/* + * mfc codec encoding example application + * Andrzej Hajda + * + * func I/O device implementation. + * + * Copyright 2012 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include "io_dev.h" +#include "func_dev.h" +#include "mfc.h" + +int func_req_bufs(struct io_dev *dev, enum io_dir dir, int nelem) +{ + struct ring_buffer *rb; + + rb = malloc(sizeof(*rb) + (nelem + 1) * sizeof(rb->data[0])); + rb->begin = 0; + rb->end = 0; + rb->size = nelem + 1; + + dev->io[dir].queue = rb; + + dbg("Succesfully requested %d buffers for device %d:%d", nelem, + dev->fd, dir); + + return nelem; +} + +int func_deq_buf(struct io_dev *dev, enum io_dir dir) +{ + int i; + struct dev_buffers *bufs; + int ret; + int lens[MFC_MAX_PLANES]; + struct ring_buffer *q; + int idx; + int (*func)(struct io_dev *dev, int nbufs, char **bufs, int *lens); + + q = dev->io[dir].queue; + + if (q->begin == q->end) + return -1; + + idx = q->data[q->begin++]; + q->begin %= q->size; + + bufs = dev->io[dir].bufs; + + for (i = 0; i < bufs->nplanes; ++i) + lens[i] = (dir == DIR_IN) ? + bufs->bytesused[bufs->nplanes * idx + i] : + bufs->lengths[i]; + + func = (dir == DIR_OUT) ? dev->ops->read : dev->ops->write; + + ret = func(dev, bufs->nplanes, &bufs->addr[bufs->nplanes * idx], lens); + + for (i = 0; i < bufs->nplanes; ++i) + bufs->bytesused[bufs->nplanes * idx + i] = lens[i]; + + dbg("Dequeued buffer %d/%d from %d:%d", idx, bufs->count, dev->fd, dir); + + --dev->io[dir].nbufs; + + ++dev->io[dir].counter; + + if (ret <= 0 || (dev->io[dir].limit && + dev->io[dir].limit <= dev->io[dir].counter)) { + dev->io[dir].state = FS_END; + dbg("End on %d:%d", dev->fd, dir); + } else if (q->begin == q->end) { + dev->io[dir].state = FS_OFF; + } else if (dev->fd >= 0) { + dev->io[dir].state = FS_BUSY; + } + + return idx; +} + +int func_enq_buf(struct io_dev *dev, enum io_dir dir, int idx) +{ + struct ring_buffer *q; + + q = dev->io[dir].queue; + q->data[q->end++] = idx; + q->end %= q->size; + + ++dev->io[dir].nbufs; + + if (dev->io[dir].state == FS_OFF) + dev->io[dir].state = dev->fd >= 0 ? FS_BUSY : FS_READY; + else if (dev->io[dir].state == FS_BUSY && dev->fd < 0) + dev->io[dir].state = FS_READY; + + dbg("Enqueued buffer %d/%d to %d:%d", idx, q->size - 1, dev->fd, dir); + + return 0; +} + +int func_destroy(struct io_dev *dev) +{ + if (dev->io[DIR_IN].type == IO_FUNC) + free(dev->io[DIR_IN].queue); + + if (dev->io[DIR_OUT].type == IO_FUNC) + free(dev->io[DIR_OUT].queue); + + if (dev->fd >= 0) + close(dev->fd); + + free(dev); + + return 0; +} -- cgit v1.2.3