blob: 1d748a887daf754f2ee1a33d0887fb724008d677
1 | /* |
2 | * Copyright (C) 2013 The Android Open Source Project |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | |
18 | //reinclude because of a bug with the log macros |
19 | //#define LOG_NDEBUG 0 |
20 | #define LOG_TAG "V4L2VINSOURCE" |
21 | #include <utils/Log.h> |
22 | #include <utils/String8.h> |
23 | |
24 | #include <signal.h> |
25 | #include <stdio.h> |
26 | #include <stdlib.h> |
27 | #include <string.h> |
28 | #include <fcntl.h> |
29 | #include <unistd.h> |
30 | #include <errno.h> |
31 | #include <sys/ioctl.h> |
32 | #include <sys/mman.h> |
33 | #include <sys/select.h> |
34 | #include <linux/videodev.h> |
35 | #include <sys/time.h> |
36 | |
37 | #include <cutils/properties.h> |
38 | #include <sys/types.h> |
39 | #include <sys/stat.h> |
40 | |
41 | #include "v4l2_vdin.h" |
42 | |
43 | namespace android { |
44 | |
45 | vdin_screen_source::vdin_screen_source() |
46 | : mCameraHandle(-1), |
47 | mVideoInfo(NULL) |
48 | { |
49 | mCameraHandle = open("/dev/video11", O_RDWR| O_NONBLOCK); |
50 | if (mCameraHandle < 0) |
51 | { |
52 | ALOGE("[%s %d] mCameraHandle:%x", __FUNCTION__, __LINE__, mCameraHandle); |
53 | } |
54 | mVideoInfo = (struct VideoInfo *) calloc (1, sizeof (struct VideoInfo)); |
55 | if (mVideoInfo == NULL) |
56 | { |
57 | ALOGE("[%s %d] no memory for mVideoInfo", __FUNCTION__, __LINE__); |
58 | } |
59 | } |
60 | |
61 | vdin_screen_source::~vdin_screen_source() |
62 | { |
63 | if (mCameraHandle >= 0) |
64 | { |
65 | close(mCameraHandle); |
66 | } |
67 | if (mVideoInfo) |
68 | { |
69 | free (mVideoInfo); |
70 | } |
71 | } |
72 | |
73 | int vdin_screen_source::start() |
74 | { |
75 | int ret = -1; |
76 | |
77 | ALOGV("[%s %d] mCameraHandle:%x", __FUNCTION__, __LINE__, mCameraHandle); |
78 | |
79 | ioctl(mCameraHandle, VIDIOC_QUERYCAP, &mVideoInfo->cap); |
80 | |
81 | mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
82 | mVideoInfo->rb.memory = V4L2_MEMORY_MMAP; |
83 | mVideoInfo->rb.count = NB_BUFFER; |
84 | |
85 | ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb); |
86 | |
87 | if (ret < 0) { |
88 | ALOGE("[%s %d] VIDIOC_REQBUFS:%d mCameraHandle:%x", __FUNCTION__, __LINE__, ret, mCameraHandle); |
89 | return ret; |
90 | } |
91 | |
92 | for (int i = 0; i < NB_BUFFER; i++) { |
93 | memset (&mVideoInfo->buf, 0, sizeof (struct v4l2_buffer)); |
94 | |
95 | mVideoInfo->buf.index = i; |
96 | mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
97 | mVideoInfo->buf.memory = V4L2_MEMORY_MMAP; |
98 | |
99 | ret = ioctl (mCameraHandle, VIDIOC_QUERYBUF, &mVideoInfo->buf); |
100 | if (ret < 0) { |
101 | ALOGE("[%s %d]VIDIOC_QUERYBUF %d failed", __FUNCTION__, __LINE__, i); |
102 | return ret; |
103 | } |
104 | mVideoInfo->canvas[i] = mVideoInfo->buf.reserved; |
105 | mVideoInfo->mem[i] = mmap (0, mVideoInfo->buf.length, PROT_READ | PROT_WRITE, |
106 | MAP_SHARED, mCameraHandle, mVideoInfo->buf.m.offset); |
107 | |
108 | if (mVideoInfo->mem[i] == MAP_FAILED) { |
109 | ALOGE("[%s %d] MAP_FAILED", __FUNCTION__, __LINE__); |
110 | return -1; |
111 | } |
112 | |
113 | mBufs.add((int)mVideoInfo->mem[i], i); |
114 | } |
115 | ALOGV("[%s %d] VIDIOC_QUERYBUF successful", __FUNCTION__, __LINE__); |
116 | |
117 | for (int i = 0; i < NB_BUFFER; i++) { |
118 | mVideoInfo->buf.index = i; |
119 | mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
120 | mVideoInfo->buf.memory = V4L2_MEMORY_MMAP; |
121 | ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf); |
122 | if (ret < 0) { |
123 | ALOGE("VIDIOC_QBUF Failed"); |
124 | return -1; |
125 | } |
126 | } |
127 | enum v4l2_buf_type bufType; |
128 | bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
129 | |
130 | ret = ioctl (mCameraHandle, VIDIOC_STREAMON, &bufType); |
131 | |
132 | ALOGV("[%s %d] VIDIOC_STREAMON:%x", __FUNCTION__, __LINE__, ret); |
133 | |
134 | return ret; |
135 | } |
136 | |
137 | int vdin_screen_source::stop() |
138 | { |
139 | int ret; |
140 | enum v4l2_buf_type bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
141 | |
142 | ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType); |
143 | if (ret < 0) { |
144 | ALOGE("StopStreaming: Unable to stop capture: %s", strerror(errno)); |
145 | } |
146 | for (int i = 0; i < NB_BUFFER; i++) |
147 | { |
148 | if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0) |
149 | ALOGE("Unmap failed"); |
150 | } |
151 | return ret; |
152 | } |
153 | |
154 | int vdin_screen_source::get_format() |
155 | { |
156 | return 0; |
157 | } |
158 | |
159 | int vdin_screen_source::set_format(int width, int height, int color_format) |
160 | { |
161 | ALOGV("[%s %d]", __FUNCTION__, __LINE__); |
162 | int ret; |
163 | |
164 | mVideoInfo->width = width; |
165 | mVideoInfo->height = height; |
166 | mVideoInfo->framesizeIn = (width * height << 1); //note color format |
167 | mVideoInfo->formatIn = color_format; |
168 | |
169 | mVideoInfo->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
170 | mVideoInfo->format.fmt.pix.width = width; |
171 | mVideoInfo->format.fmt.pix.height = height; |
172 | mVideoInfo->format.fmt.pix.pixelformat = color_format; |
173 | |
174 | ret = ioctl(mCameraHandle, VIDIOC_S_FMT, &mVideoInfo->format); |
175 | if (ret < 0) { |
176 | ALOGE("[%s %d]VIDIOC_S_FMT %d", __FUNCTION__, __LINE__, ret); |
177 | return ret; |
178 | } |
179 | |
180 | return ret; |
181 | } |
182 | |
183 | int vdin_screen_source::set_rotation(int degree) |
184 | { |
185 | ALOGV("[%s %d]", __FUNCTION__, __LINE__); |
186 | int ret = 0; |
187 | return ret; |
188 | } |
189 | |
190 | |
191 | int vdin_screen_source::aquire_buffer(unsigned *buff_info) |
192 | { |
193 | int ret = -1; |
194 | |
195 | mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
196 | mVideoInfo->buf.memory = V4L2_MEMORY_MMAP; |
197 | |
198 | ret = ioctl(mCameraHandle, VIDIOC_DQBUF, &mVideoInfo->buf); |
199 | if (ret < 0) { |
200 | if(EAGAIN == errno){ |
201 | ret = -EAGAIN; |
202 | }else{ |
203 | ALOGE("[%s %d]aquire_buffer %d", __FUNCTION__, __LINE__, ret); |
204 | } |
205 | buff_info[0] = 0; |
206 | buff_info[1] = 0; |
207 | return ret; |
208 | } |
209 | buff_info[0] = (unsigned)mVideoInfo->mem[mVideoInfo->buf.index]; |
210 | buff_info[1] = (unsigned)mVideoInfo->canvas[mVideoInfo->buf.index]; |
211 | return ret; |
212 | } |
213 | |
214 | int vdin_screen_source::release_buffer(char* ptr) |
215 | { |
216 | int ret = -1; |
217 | int CurrentIndex; |
218 | v4l2_buffer hbuf_query; |
219 | memset(&hbuf_query,0,sizeof(v4l2_buffer)); |
220 | |
221 | CurrentIndex = mBufs.valueFor(( unsigned int )ptr); |
222 | hbuf_query.index = CurrentIndex; |
223 | hbuf_query.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
224 | hbuf_query.memory = V4L2_MEMORY_MMAP; |
225 | ret = ioctl(mCameraHandle, VIDIOC_QBUF, &hbuf_query); |
226 | |
227 | return 0; |
228 | } |
229 | |
230 | } |
231 |