blob: d86b13293c41b90cbbcabc0a4a72dba0ada0f00d
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 <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 | #define MAX_DEVICES_SUPPORTED 2 |
56 | |
57 | static unsigned int gAmlScreenOpen = 0; |
58 | static android::Mutex gAmlScreenLock; |
59 | static android::vdin_screen_source* gScreenHals[MAX_DEVICES_SUPPORTED]; |
60 | |
61 | /*****************************************************************************/ |
62 | |
63 | static int aml_screen_device_open(const struct hw_module_t* module, const char* name, |
64 | struct hw_device_t** device); |
65 | |
66 | static struct hw_module_methods_t aml_screen_module_methods = { |
67 | open: aml_screen_device_open |
68 | }; |
69 | |
70 | aml_screen_module_t HAL_MODULE_INFO_SYM = { |
71 | common: { |
72 | tag: HARDWARE_MODULE_TAG, |
73 | version_major: 1, |
74 | version_minor: 0, |
75 | id: AML_SCREEN_HARDWARE_MODULE_ID, |
76 | name: "aml screen source module", |
77 | author: "Amlogic", |
78 | methods: &aml_screen_module_methods, |
79 | dso : NULL, |
80 | reserved : {0}, |
81 | } |
82 | }; |
83 | |
84 | /*****************************************************************************/ |
85 | |
86 | static int aml_screen_device_close(struct hw_device_t *dev) |
87 | { |
88 | android::vdin_screen_source* source = NULL; |
89 | aml_screen_device_t* ctx = (aml_screen_device_t*)dev; |
90 | android::Mutex::Autolock lock(gAmlScreenLock); |
91 | if (ctx) { |
92 | if (gScreenHals[ctx->device_id]) { |
93 | delete gScreenHals[ctx->device_id]; |
94 | gScreenHals[ctx->device_id] = NULL; |
95 | gAmlScreenOpen--; |
96 | } |
97 | free(ctx); |
98 | ctx = NULL; |
99 | } |
100 | return 0; |
101 | } |
102 | |
103 | int screen_source_start(struct aml_screen_device* dev) |
104 | { |
105 | return gScreenHals[dev->device_id]->start(); |
106 | } |
107 | |
108 | int screen_source_stop(struct aml_screen_device* dev) |
109 | { |
110 | return gScreenHals[dev->device_id]->stop(); |
111 | } |
112 | |
113 | int screen_source_pause(struct aml_screen_device* dev) |
114 | { |
115 | return gScreenHals[dev->device_id]->pause(); |
116 | } |
117 | |
118 | int screen_source_get_format(struct aml_screen_device* dev) |
119 | { |
120 | return gScreenHals[dev->device_id]->get_format(); |
121 | } |
122 | |
123 | int screen_source_set_format(struct aml_screen_device* dev, int width, int height, int pix_format) |
124 | { |
125 | if ((width > 0) && (height > 0) && ((pix_format == V4L2_PIX_FMT_NV21) || |
126 | (pix_format == V4L2_PIX_FMT_YUV420) || |
127 | (pix_format == V4L2_PIX_FMT_RGB24) || |
128 | (pix_format == V4L2_PIX_FMT_RGB565X) || |
129 | (pix_format == V4L2_PIX_FMT_RGB32))) { |
130 | return gScreenHals[dev->device_id]->set_format(width, height, pix_format); |
131 | } else { |
132 | return gScreenHals[dev->device_id]->set_format(); |
133 | } |
134 | } |
135 | |
136 | int screen_source_set_rotation(struct aml_screen_device* dev, int degree) |
137 | { |
138 | return gScreenHals[dev->device_id]->set_rotation(degree); |
139 | } |
140 | |
141 | int screen_source_set_crop(struct aml_screen_device* dev, int x, int y, int width, int height) |
142 | { |
143 | if ((x >= 0) && (y >= 0) && (width > 0) && (height > 0)) |
144 | return gScreenHals[dev->device_id]->set_crop(x, y, width, height); |
145 | |
146 | return android::BAD_VALUE; |
147 | } |
148 | |
149 | int screen_source_get_amlvideo2_crop(struct aml_screen_device* dev, int *x, int *y, int *width, int *height) |
150 | { |
151 | if ((x != NULL) && (y != NULL) && (width != NULL) && (height != NULL)) |
152 | return gScreenHals[dev->device_id]->get_amlvideo2_crop(x, y, width, height); |
153 | |
154 | return android::BAD_VALUE; |
155 | } |
156 | |
157 | int screen_source_set_amlvideo2_crop(struct aml_screen_device* dev, int x, int y, int width, int height) |
158 | { |
159 | if ((x >= 0) && (y >= 0) && (width > 0) && (height > 0)) |
160 | return gScreenHals[dev->device_id]->set_amlvideo2_crop(x, y, width, height); |
161 | |
162 | return android::BAD_VALUE; |
163 | } |
164 | |
165 | int screen_source_aquire_buffer(struct aml_screen_device* dev, aml_screen_buffer_info_t* buff_info) |
166 | { |
167 | return gScreenHals[dev->device_id]->aquire_buffer(buff_info); |
168 | } |
169 | |
170 | int screen_source_release_buffer(struct aml_screen_device* dev, long* ptr) |
171 | { |
172 | return gScreenHals[dev->device_id]->release_buffer(ptr); |
173 | } |
174 | |
175 | int screen_source_set_state_callback(struct aml_screen_device* dev, olStateCB callback) |
176 | { |
177 | return gScreenHals[dev->device_id]->set_state_callback(callback); |
178 | } |
179 | |
180 | int screen_source_set_preview_window(struct aml_screen_device* dev, ANativeWindow* window) |
181 | { |
182 | return gScreenHals[dev->device_id]->set_preview_window(window); |
183 | } |
184 | |
185 | int screen_source_set_data_callback(struct aml_screen_device* dev, app_data_callback callback, void* user) |
186 | { |
187 | return gScreenHals[dev->device_id]->set_data_callback(callback, user); |
188 | } |
189 | |
190 | int screen_source_set_frame_rate(struct aml_screen_device* dev, int frameRate) |
191 | { |
192 | return gScreenHals[dev->device_id]->set_frame_rate(frameRate); |
193 | } |
194 | |
195 | int screen_source_get_current_sourcesize(struct aml_screen_device* dev, int *w, int *h) |
196 | { |
197 | return gScreenHals[dev->device_id]->get_current_sourcesize(w, h); |
198 | } |
199 | |
200 | int screen_source_set_screen_mode(struct aml_screen_device* dev, int mode) |
201 | { |
202 | return gScreenHals[dev->device_id]->set_screen_mode(mode); |
203 | } |
204 | |
205 | int screen_source_start_v4l2_device(struct aml_screen_device* dev) |
206 | { |
207 | return gScreenHals[dev->device_id]->start_v4l2_device(); |
208 | } |
209 | |
210 | int screen_source_stop_v4l2_device(struct aml_screen_device* dev) |
211 | { |
212 | return gScreenHals[dev->device_id]->stop_v4l2_device(); |
213 | } |
214 | |
215 | int screen_source_get_port_type(struct aml_screen_device* dev) |
216 | { |
217 | return gScreenHals[dev->device_id]->get_port_type(); |
218 | } |
219 | /** |
220 | * set_port_type() parameter description: |
221 | portType is consisted by 32-bit binary. |
222 | bit 28 : start tvin service flag, 1 : enable, 0 : disable. |
223 | bit 24 : vdin device num : 0 or 1, which means use vdin0 or vdin1. |
224 | bit 15~0 : tvin port type --TVIN_PORT_VIU,TVIN_PORT_HDMI0... |
225 | (port type define in tvin.h) |
226 | */ |
227 | int screen_source_set_port_type(struct aml_screen_device* dev,unsigned int portType) |
228 | { |
229 | return gScreenHals[dev->device_id]->set_port_type(portType); |
230 | } |
231 | |
232 | int screen_source_set_mode(struct aml_screen_device* dev, int displayMode) |
233 | { |
234 | return gScreenHals[dev->device_id]->set_mode(displayMode); |
235 | } |
236 | |
237 | /* int screen_source_inc_buffer_refcount(struct aml_screen_device* dev, int* ptr) |
238 | { |
239 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
240 | return source->inc_buffer_refcount(ptr); |
241 | } */ |
242 | |
243 | /*****************************************************************************/ |
244 | |
245 | static int aml_screen_device_open(const struct hw_module_t* module, const char* name, |
246 | struct hw_device_t** device) |
247 | { |
248 | int deviceid; |
249 | int status = -EINVAL; |
250 | android::vdin_screen_source* source = NULL; |
251 | android::Mutex::Autolock lock(gAmlScreenLock); |
252 | |
253 | LOGV("aml_screen_device_open"); |
254 | |
255 | if (name != NULL) { |
256 | if (gAmlScreenOpen >= MAX_DEVICES_SUPPORTED) { |
257 | ALOGD("aml screen device already open"); |
258 | *device = NULL; |
259 | return -EINVAL; |
260 | } |
261 | |
262 | deviceid = atoi(name); |
263 | |
264 | if (deviceid >= MAX_DEVICES_SUPPORTED) { |
265 | ALOGD("provided device id out of bounds , deviceid = %d .\n" , deviceid); |
266 | *device = NULL; |
267 | return -EINVAL; |
268 | } |
269 | |
270 | aml_screen_device_t *dev = (aml_screen_device_t*)malloc(sizeof(aml_screen_device_t)); |
271 | |
272 | if (!dev) { |
273 | ALOGE("no memory for the screen source device"); |
274 | return -ENOMEM; |
275 | } |
276 | /* initialize handle here */ |
277 | memset(dev, 0, sizeof(*dev)); |
278 | |
279 | source = new android::vdin_screen_source; |
280 | if (!source) { |
281 | ALOGE("no memory for class of vdin_screen_source"); |
282 | free (dev); |
283 | return -ENOMEM; |
284 | } |
285 | |
286 | if (source->init(deviceid)!= 0) { |
287 | ALOGE("open vdin_screen_source failed!"); |
288 | free (dev); |
289 | delete source; |
290 | return -1; |
291 | } |
292 | |
293 | dev->priv = (void*)source; |
294 | |
295 | /* initialize the procs */ |
296 | dev->common.tag = HARDWARE_DEVICE_TAG; |
297 | dev->common.version = 0; |
298 | dev->common.module = const_cast<hw_module_t*>(module); |
299 | dev->common.close = aml_screen_device_close; |
300 | dev->ops.start = screen_source_start; |
301 | dev->ops.stop = screen_source_stop; |
302 | dev->ops.pause = screen_source_pause; |
303 | dev->ops.get_format = screen_source_get_format; |
304 | dev->ops.set_format = screen_source_set_format; |
305 | dev->ops.set_rotation = screen_source_set_rotation; |
306 | dev->ops.set_crop = screen_source_set_crop; |
307 | dev->ops.get_amlvideo2_crop = screen_source_get_amlvideo2_crop; |
308 | dev->ops.set_amlvideo2_crop = screen_source_set_amlvideo2_crop; |
309 | dev->ops.aquire_buffer = screen_source_aquire_buffer; |
310 | dev->ops.release_buffer = screen_source_release_buffer; |
311 | dev->ops.setStateCallBack = screen_source_set_state_callback; |
312 | dev->ops.setPreviewWindow = screen_source_set_preview_window; |
313 | dev->ops.setDataCallBack = screen_source_set_data_callback; |
314 | dev->ops.set_frame_rate = screen_source_set_frame_rate; |
315 | dev->ops.get_current_sourcesize = screen_source_get_current_sourcesize; |
316 | dev->ops.set_screen_mode = screen_source_set_screen_mode; |
317 | // dev->ops.inc_buffer_refcount = screen_source_inc_buffer_refcount; |
318 | dev->ops.start_v4l2_device = screen_source_start_v4l2_device; |
319 | dev->ops.stop_v4l2_device = screen_source_stop_v4l2_device; |
320 | dev->ops.get_port_type = screen_source_get_port_type; |
321 | dev->ops.set_port_type = screen_source_set_port_type; |
322 | dev->ops.set_mode = screen_source_set_mode; |
323 | dev->device_id = deviceid; |
324 | *device = &dev->common; |
325 | gScreenHals[deviceid] = source; |
326 | gAmlScreenOpen++; |
327 | status = 0; |
328 | |
329 | } |
330 | return status; |
331 | } |
332 |