blob: 22c98aa97dae149ca161d6653635cafa0b21f2be
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 | //#define LOG_NDEBUG 0 |
18 | #define LOG_TAG "screen_source" |
19 | #include <hardware/hardware.h> |
20 | #include <hardware/aml_screen.h> |
21 | |
22 | #include <signal.h> |
23 | #include <stdio.h> |
24 | #include <stdlib.h> |
25 | #include <string.h> |
26 | #include <fcntl.h> |
27 | #include <unistd.h> |
28 | #include <errno.h> |
29 | #include <sys/ioctl.h> |
30 | #include <sys/mman.h> |
31 | #include <sys/select.h> |
32 | #include <linux/videodev2.h> |
33 | #include <sys/time.h> |
34 | |
35 | |
36 | #include <errno.h> |
37 | #include <cutils/log.h> |
38 | #include <cutils/atomic.h> |
39 | |
40 | #include "v4l2_vdin.h" |
41 | |
42 | #ifndef LOGD |
43 | #define LOGD ALOGD |
44 | #endif |
45 | #ifndef LOGV |
46 | #define LOGV ALOGV |
47 | #endif |
48 | #ifndef LOGE |
49 | #define LOGE ALOGE |
50 | #endif |
51 | #ifndef LOGI |
52 | #define LOGI ALOGI |
53 | #endif |
54 | |
55 | static unsigned int gAmlScreenOpen = 0; |
56 | static android::Mutex gAmlScreenLock; |
57 | |
58 | /*****************************************************************************/ |
59 | |
60 | static int aml_screen_device_open(const struct hw_module_t* module, const char* name, |
61 | struct hw_device_t** device); |
62 | |
63 | static struct hw_module_methods_t aml_screen_module_methods = { |
64 | open: aml_screen_device_open |
65 | }; |
66 | |
67 | aml_screen_module_t HAL_MODULE_INFO_SYM = { |
68 | common: { |
69 | tag: HARDWARE_MODULE_TAG, |
70 | version_major: 1, |
71 | version_minor: 0, |
72 | id: AML_SCREEN_HARDWARE_MODULE_ID, |
73 | name: "aml screen source module", |
74 | author: "Amlogic", |
75 | methods: &aml_screen_module_methods, |
76 | dso : NULL, |
77 | reserved : {0}, |
78 | } |
79 | }; |
80 | |
81 | /*****************************************************************************/ |
82 | |
83 | static int aml_screen_device_close(struct hw_device_t *dev) |
84 | { |
85 | android::vdin_screen_source* source = NULL; |
86 | aml_screen_device_t* ctx = (aml_screen_device_t*)dev; |
87 | |
88 | android::Mutex::Autolock lock(gAmlScreenLock); |
89 | if (ctx) { |
90 | if (ctx->priv){ |
91 | source = (android::vdin_screen_source*)ctx->priv; |
92 | delete source; |
93 | source = NULL; |
94 | } |
95 | free(ctx); |
96 | } |
97 | gAmlScreenOpen--; |
98 | return 0; |
99 | } |
100 | |
101 | int screen_source_start(struct aml_screen_device* dev) |
102 | { |
103 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
104 | return source->start(); |
105 | } |
106 | |
107 | int screen_source_stop(struct aml_screen_device* dev) |
108 | { |
109 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
110 | return source->stop(); |
111 | } |
112 | |
113 | int screen_source_pause(struct aml_screen_device* dev) |
114 | { |
115 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
116 | return source->pause(); |
117 | } |
118 | |
119 | int screen_source_get_format(struct aml_screen_device* dev) |
120 | { |
121 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
122 | return source->get_format(); |
123 | } |
124 | |
125 | int screen_source_set_format(struct aml_screen_device* dev, int width, int height, int pix_format) |
126 | { |
127 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
128 | |
129 | if ((width > 0) && (height > 0) && ((pix_format == V4L2_PIX_FMT_NV21) || (pix_format == V4L2_PIX_FMT_YUV420) |
130 | || (pix_format == V4L2_PIX_FMT_RGB24) |
131 | || (pix_format == V4L2_PIX_FMT_RGB565X) )) { |
132 | return source->set_format(width, height, pix_format); |
133 | } else { |
134 | return source->set_format(); |
135 | } |
136 | } |
137 | |
138 | int screen_source_set_rotation(struct aml_screen_device* dev, int degree) |
139 | { |
140 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
141 | return source->set_rotation(degree); |
142 | } |
143 | |
144 | int screen_source_set_crop(struct aml_screen_device* dev, int x, int y, int width, int height) |
145 | { |
146 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
147 | |
148 | if ((x >= 0) && (y >= 0) && (width > 0) && (height > 0)) |
149 | return source->set_crop(x, y, width, height); |
150 | |
151 | return android::BAD_VALUE; |
152 | } |
153 | |
154 | int screen_source_get_amlvideo2_crop(struct aml_screen_device* dev, int *x, int *y, int *width, int *height) |
155 | { |
156 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
157 | |
158 | if ((x != NULL) && (y != NULL) && (width != NULL) && (height != NULL)) |
159 | return source->get_amlvideo2_crop(x, y, width, height); |
160 | |
161 | return android::BAD_VALUE; |
162 | } |
163 | |
164 | int screen_source_set_amlvideo2_crop(struct aml_screen_device* dev, int x, int y, int width, int height) |
165 | { |
166 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
167 | |
168 | if ((x >= 0) && (y >= 0) && (width > 0) && (height > 0)) |
169 | return source->set_amlvideo2_crop(x, y, width, height); |
170 | |
171 | return android::BAD_VALUE; |
172 | } |
173 | |
174 | int screen_source_aquire_buffer(struct aml_screen_device* dev, aml_screen_buffer_info_t* buff_info) |
175 | { |
176 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
177 | |
178 | return source->aquire_buffer(buff_info); |
179 | } |
180 | |
181 | int screen_source_release_buffer(struct aml_screen_device* dev, long* ptr) |
182 | { |
183 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
184 | return source->release_buffer(ptr); |
185 | } |
186 | |
187 | int screen_source_set_state_callback(struct aml_screen_device* dev, olStateCB callback) |
188 | { |
189 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
190 | return source->set_state_callback(callback); |
191 | } |
192 | |
193 | int screen_source_set_preview_window(struct aml_screen_device* dev, ANativeWindow* window) |
194 | { |
195 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
196 | return source->set_preview_window(window); |
197 | } |
198 | |
199 | int screen_source_set_data_callback(struct aml_screen_device* dev, app_data_callback callback, void* user) |
200 | { |
201 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
202 | return source->set_data_callback(callback, user); |
203 | } |
204 | |
205 | int screen_source_set_frame_rate(struct aml_screen_device* dev, int frameRate) |
206 | { |
207 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
208 | return source->set_frame_rate(frameRate); |
209 | } |
210 | |
211 | int screen_source_set_source_type(struct aml_screen_device* dev, SOURCETYPE sourceType) |
212 | { |
213 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
214 | return source->set_source_type(sourceType); |
215 | } |
216 | |
217 | int screen_source_get_source_type(struct aml_screen_device* dev) |
218 | { |
219 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
220 | return source->get_source_type(); |
221 | } |
222 | |
223 | int screen_source_get_current_sourcesize(struct aml_screen_device* dev, int *w, int *h) |
224 | { |
225 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
226 | return source->get_current_sourcesize(w, h); |
227 | } |
228 | |
229 | int screen_source_set_screen_mode(struct aml_screen_device* dev, int mode) |
230 | { |
231 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
232 | return source->set_screen_mode(mode); |
233 | } |
234 | |
235 | int screen_source_start_v4l2_device(struct aml_screen_device* dev) |
236 | { |
237 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
238 | return source->start_v4l2_device(); |
239 | } |
240 | |
241 | int screen_source_stop_v4l2_device(struct aml_screen_device* dev) |
242 | { |
243 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
244 | return source->stop_v4l2_device(); |
245 | } |
246 | |
247 | int screen_source_set_port_type(struct aml_screen_device* dev,int sourceType) |
248 | { |
249 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
250 | return source->set_port_type(sourceType); |
251 | } |
252 | |
253 | /* int screen_source_inc_buffer_refcount(struct aml_screen_device* dev, int* ptr) |
254 | { |
255 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
256 | return source->inc_buffer_refcount(ptr); |
257 | } */ |
258 | |
259 | /*****************************************************************************/ |
260 | |
261 | static int aml_screen_device_open(const struct hw_module_t* module, const char* name, |
262 | struct hw_device_t** device) |
263 | { |
264 | int status = -EINVAL; |
265 | android::vdin_screen_source* source = NULL; |
266 | android::Mutex::Autolock lock(gAmlScreenLock); |
267 | |
268 | LOGV("aml_screen_device_open"); |
269 | |
270 | if (!strcmp(name, AML_SCREEN_SOURCE)) { |
271 | if(gAmlScreenOpen > 1){ |
272 | ALOGD("aml screen device already open"); |
273 | *device = NULL; |
274 | return -EINVAL; |
275 | } |
276 | |
277 | aml_screen_device_t *dev = (aml_screen_device_t*)malloc(sizeof(aml_screen_device_t)); |
278 | |
279 | if (!dev) { |
280 | LOGE("no memory for the screen source device"); |
281 | return -ENOMEM; |
282 | } |
283 | /* initialize handle here */ |
284 | memset(dev, 0, sizeof(*dev)); |
285 | |
286 | source = new android::vdin_screen_source; |
287 | if (!source) { |
288 | LOGE("no memory for class of vdin_screen_source"); |
289 | free (dev); |
290 | return -ENOMEM; |
291 | } |
292 | |
293 | if (source->init()!= 0) { |
294 | LOGE("open vdin_screen_source failed!"); |
295 | free (dev); |
296 | return -1; |
297 | } |
298 | |
299 | dev->priv = (void*)source; |
300 | |
301 | /* initialize the procs */ |
302 | dev->common.tag = HARDWARE_DEVICE_TAG; |
303 | dev->common.version = 0; |
304 | dev->common.module = const_cast<hw_module_t*>(module); |
305 | dev->common.close = aml_screen_device_close; |
306 | |
307 | dev->ops.start = screen_source_start; |
308 | dev->ops.stop = screen_source_stop; |
309 | dev->ops.pause = screen_source_pause; |
310 | dev->ops.get_format = screen_source_get_format; |
311 | dev->ops.set_format = screen_source_set_format; |
312 | dev->ops.set_rotation = screen_source_set_rotation; |
313 | dev->ops.set_crop = screen_source_set_crop; |
314 | dev->ops.get_amlvideo2_crop = screen_source_get_amlvideo2_crop; |
315 | dev->ops.set_amlvideo2_crop = screen_source_set_amlvideo2_crop; |
316 | dev->ops.aquire_buffer = screen_source_aquire_buffer; |
317 | dev->ops.release_buffer = screen_source_release_buffer; |
318 | dev->ops.setStateCallBack = screen_source_set_state_callback; |
319 | dev->ops.setPreviewWindow = screen_source_set_preview_window; |
320 | dev->ops.setDataCallBack = screen_source_set_data_callback; |
321 | dev->ops.set_frame_rate = screen_source_set_frame_rate; |
322 | dev->ops.set_source_type = screen_source_set_source_type; |
323 | dev->ops.get_source_type = screen_source_get_source_type; |
324 | dev->ops.get_current_sourcesize = screen_source_get_current_sourcesize; |
325 | dev->ops.set_screen_mode = screen_source_set_screen_mode; |
326 | // dev->ops.inc_buffer_refcount = screen_source_inc_buffer_refcount; |
327 | dev->ops.start_v4l2_device = screen_source_start_v4l2_device; |
328 | dev->ops.stop_v4l2_device = screen_source_stop_v4l2_device; |
329 | dev->ops.set_port_type = screen_source_set_port_type; |
330 | *device = &dev->common; |
331 | status = 0; |
332 | gAmlScreenOpen++; |
333 | } |
334 | return status; |
335 | } |
336 |