summaryrefslogtreecommitdiff
path: root/amvdec/ionv4l.c (plain)
blob: b7f3f4eeb34d7191af8f58361a2cb6a23e3b0e28
1/*
2 * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
3 *
4 * This source code is subject to the terms and conditions defined in the
5 * file 'LICENSE' which is part of this source code package.
6 *
7 * Description:
8 */
9
10
11#include <stdio.h>
12#include <fcntl.h>
13#include <errno.h>
14#include <sys/mman.h>
15#include <sys/ioctl.h>
16
17#include "ionv4l.h"
18#include "ionvdec_priv.h"
19#define V4LDEVICE_NAME "/dev/video13"
20#define CLEAR(s) memset(&s, 0, sizeof(s))
21
22static int ionv4l_unmapbufs(ionvideo_dev_t *dev);
23static int ionv4l_mapbufs(ionvideo_dev_t *dev);
24int ionv4l_setfmt(ionvideo_dev_t *dev, struct v4l2_format *fmt);
25int ionv4l_stop(ionvideo_dev_t *dev);
26int ionv4l_init(ionvideo_dev_t *dev, int type, int width, int height, int fmt, int buffernum)
27{
28 int ret;
29 ionv4l_dev_t *v4l = dev->devpriv;
30 struct v4l2_format v4lfmt;
31 v4l->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
32 v4l->width = width;
33 v4l->height = height;
34 v4l->pixformat = fmt;
35 v4l->buffer_num = buffernum;
36 v4lfmt.type = v4l->type;
37 v4lfmt.fmt.pix.width = v4l->width;
38 v4lfmt.fmt.pix.height = v4l->height;
39 v4lfmt.fmt.pix.pixelformat = v4l->pixformat;
40 ret = ionv4l_setfmt(dev, &v4lfmt);
41 if (ret != 0) {
42 goto error_out;
43 }
44 ret = ionv4l_mapbufs(dev);
45error_out:
46 return ret;
47}
48
49static int ionv4l_ioctl(ionvideo_dev_t *dev, int request, void *arg)
50{
51 int ret;
52 ionv4l_dev_t *v4l = dev->devpriv;
53 ret = ioctl(v4l->v4l_fd, request, arg);
54 if (ret == -1 && errno) {
55 ret = -errno;
56 }
57 return ret;
58}
59
60int ionv4l_release(ionvideo_dev_t *dev)
61{
62 int ret = -1;
63 ionv4l_dev_t *v4l = dev->devpriv;
64 if (v4l->v4l_fd < 0) {
65 return 0;
66 }
67 ionv4l_stop(dev);
68 ionv4l_unmapbufs(dev);
69 if (v4l->v4l_fd >= 0) {
70 ret = close(v4l->v4l_fd);
71 }
72 v4l->v4l_fd = -1;
73 free(dev);
74 if (ret == -1 && errno) {
75 ret = -errno;
76 }
77
78 return ret;
79}
80
81int ionv4l_dequeue_buf(ionvideo_dev_t *dev, vframebuf_t *vf)
82{
83 struct v4l2_buffer vbuf;
84 CLEAR(vbuf);
85 int ret;
86 ionv4l_dev_t *v4l = dev->devpriv;
87 vbuf.type = v4l->type;
88 vbuf.memory = v4l->memory_mode;
89 vbuf.length = vf->length;
90 ret = ionv4l_ioctl(dev, VIDIOC_DQBUF, &vbuf);
91 if (!ret && vbuf.index < v4l->buffer_num) {
92 vf->pts = vbuf.timestamp.tv_sec & 0xFFFFFFFF;
93 vf->pts <<= 32;
94 vf->pts += vbuf.timestamp.tv_usec & 0xFFFFFFFF;
95 vf->fd = vbuf.m.fd;
96 vf->index = vbuf.index;
97 }
98
99 return ret;
100}
101
102int ionv4l_queue_buf(ionvideo_dev_t *dev, vframebuf_t *vf)
103{
104 struct v4l2_buffer vbuf;
105 CLEAR(vbuf);
106 int ret;
107 ionv4l_dev_t *v4l = dev->devpriv;
108 vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
109 vbuf.memory = V4L2_MEMORY_DMABUF;
110 vbuf.index = vf->index;
111 vbuf.m.fd = vf->fd;
112 vbuf.length = vf->length;
113 return ionv4l_ioctl(dev, VIDIOC_QBUF, &vbuf);
114}
115
116int ionv4l_start(ionvideo_dev_t *dev)
117{
118 int type;
119 ionv4l_dev_t *v4l = dev->devpriv;
120 type = v4l->type;
121 return ionv4l_ioctl(dev, VIDIOC_STREAMON, &type);
122}
123
124int ionv4l_stop(ionvideo_dev_t *dev)
125{
126 int type;
127 ionv4l_dev_t *v4l = dev->devpriv;
128 type = v4l->type;
129 return ionv4l_ioctl(dev, VIDIOC_STREAMOFF, &type);
130}
131
132int ionv4l_setfmt(ionvideo_dev_t *dev, struct v4l2_format *fmt)
133{
134 return ionv4l_ioctl(dev, VIDIOC_S_FMT, fmt);
135}
136
137int ionv4l_getfmt(ionvideo_dev_t *dev, struct v4l2_format *fmt)
138{
139 return ionv4l_ioctl(dev, VIDIOC_G_FMT, fmt);
140}
141
142static int ionv4l_unmapbufs(ionvideo_dev_t *dev)
143{
144 return 0;
145}
146
147static int ionv4l_mapbufs(ionvideo_dev_t *dev)
148{
149 int ret;
150 struct v4l2_requestbuffers rb;
151 CLEAR(rb);
152 ionv4l_dev_t *v4l = dev->devpriv;
153 rb.count = v4l->buffer_num;
154 rb.type = v4l->type;
155 rb.memory = v4l->memory_mode;
156 return ionv4l_ioctl(dev, VIDIOC_REQBUFS, &rb);
157}
158
159ionvideo_dev_t *new_ionv4l(void)
160{
161 ionvideo_dev_t *dev;
162 ionv4l_dev_t *v4l;
163 dev = malloc(sizeof(ionvideo_dev_t) + sizeof(ionv4l_dev_t));
164 memset(dev, 0, sizeof(ionvideo_dev_t) + sizeof(ionv4l_dev_t));
165 dev->devpriv = (void *)((long)(&dev->devpriv) + 4);
166 v4l = dev->devpriv;
167 v4l->memory_mode = V4L2_MEMORY_DMABUF;
168 dev->ops.init = ionv4l_init;
169 dev->ops.release = ionv4l_release;
170 dev->ops.dequeuebuf = ionv4l_dequeue_buf;
171 dev->ops.queuebuf = ionv4l_queue_buf;
172 dev->ops.start = ionv4l_start;
173 dev->ops.stop = ionv4l_stop;
174 dev->ops.getparameters = ionv4l_getfmt;
175 v4l->v4l_fd = open(V4LDEVICE_NAME, O_RDWR | O_NONBLOCK);
176 if (v4l->v4l_fd < 0) {
177 free(dev);
178 LOGE("v4l device opend failed!,%s(%d)\n", strerror(errno), errno);
179 return NULL;
180 }
181 return dev;
182}
183
184