blob: 560ff65b7584d517ed8e65806f83e7425eeb30ba
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_set_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 >= 0) && (y >= 0) && (width > 0) && (height > 0)) |
159 | return source->set_amlvideo2_crop(x, y, width, height); |
160 | |
161 | return android::BAD_VALUE; |
162 | } |
163 | |
164 | int screen_source_aquire_buffer(struct aml_screen_device* dev, aml_screen_buffer_info_t* buff_info) |
165 | { |
166 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
167 | |
168 | return source->aquire_buffer(buff_info); |
169 | } |
170 | |
171 | int screen_source_release_buffer(struct aml_screen_device* dev, long* ptr) |
172 | { |
173 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
174 | return source->release_buffer(ptr); |
175 | } |
176 | |
177 | int screen_source_set_state_callback(struct aml_screen_device* dev, olStateCB callback) |
178 | { |
179 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
180 | return source->set_state_callback(callback); |
181 | } |
182 | |
183 | int screen_source_set_preview_window(struct aml_screen_device* dev, ANativeWindow* window) |
184 | { |
185 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
186 | return source->set_preview_window(window); |
187 | } |
188 | |
189 | int screen_source_set_data_callback(struct aml_screen_device* dev, app_data_callback callback, void* user) |
190 | { |
191 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
192 | return source->set_data_callback(callback, user); |
193 | } |
194 | |
195 | int screen_source_set_frame_rate(struct aml_screen_device* dev, int frameRate) |
196 | { |
197 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
198 | return source->set_frame_rate(frameRate); |
199 | } |
200 | |
201 | int screen_source_set_source_type(struct aml_screen_device* dev, SOURCETYPE sourceType) |
202 | { |
203 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
204 | return source->set_source_type(sourceType); |
205 | } |
206 | |
207 | int screen_source_get_source_type(struct aml_screen_device* dev) |
208 | { |
209 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
210 | return source->get_source_type(); |
211 | } |
212 | |
213 | int screen_source_start_v4l2_device(struct aml_screen_device* dev) |
214 | { |
215 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
216 | return source->start_v4l2_device(); |
217 | } |
218 | |
219 | int screen_source_stop_v4l2_device(struct aml_screen_device* dev) |
220 | { |
221 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
222 | return source->stop_v4l2_device(); |
223 | } |
224 | |
225 | int screen_source_set_port_type(struct aml_screen_device* dev,int sourceType) |
226 | { |
227 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
228 | return source->set_port_type(sourceType); |
229 | } |
230 | |
231 | /* int screen_source_inc_buffer_refcount(struct aml_screen_device* dev, int* ptr) |
232 | { |
233 | android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv; |
234 | return source->inc_buffer_refcount(ptr); |
235 | } */ |
236 | |
237 | /*****************************************************************************/ |
238 | |
239 | static int aml_screen_device_open(const struct hw_module_t* module, const char* name, |
240 | struct hw_device_t** device) |
241 | { |
242 | int status = -EINVAL; |
243 | android::vdin_screen_source* source = NULL; |
244 | android::Mutex::Autolock lock(gAmlScreenLock); |
245 | |
246 | LOGV("aml_screen_device_open"); |
247 | |
248 | if (!strcmp(name, AML_SCREEN_SOURCE)) { |
249 | if(gAmlScreenOpen > 1){ |
250 | ALOGD("aml screen device already open"); |
251 | *device = NULL; |
252 | return -EINVAL; |
253 | } |
254 | |
255 | aml_screen_device_t *dev = (aml_screen_device_t*)malloc(sizeof(aml_screen_device_t)); |
256 | |
257 | if (!dev) { |
258 | LOGE("no memory for the screen source device"); |
259 | return -ENOMEM; |
260 | } |
261 | /* initialize handle here */ |
262 | memset(dev, 0, sizeof(*dev)); |
263 | |
264 | source = new android::vdin_screen_source; |
265 | if (!source) { |
266 | LOGE("no memory for class of vdin_screen_source"); |
267 | free (dev); |
268 | return -ENOMEM; |
269 | } |
270 | |
271 | if (source->init()!= 0) { |
272 | LOGE("open vdin_screen_source failed!"); |
273 | free (dev); |
274 | return -1; |
275 | } |
276 | |
277 | dev->priv = (void*)source; |
278 | |
279 | /* initialize the procs */ |
280 | dev->common.tag = HARDWARE_DEVICE_TAG; |
281 | dev->common.version = 0; |
282 | dev->common.module = const_cast<hw_module_t*>(module); |
283 | dev->common.close = aml_screen_device_close; |
284 | |
285 | dev->ops.start = screen_source_start; |
286 | dev->ops.stop = screen_source_stop; |
287 | dev->ops.pause = screen_source_pause; |
288 | dev->ops.get_format = screen_source_get_format; |
289 | dev->ops.set_format = screen_source_set_format; |
290 | dev->ops.set_rotation = screen_source_set_rotation; |
291 | dev->ops.set_crop = screen_source_set_crop; |
292 | dev->ops.set_amlvideo2_crop = screen_source_set_amlvideo2_crop; |
293 | dev->ops.aquire_buffer = screen_source_aquire_buffer; |
294 | dev->ops.release_buffer = screen_source_release_buffer; |
295 | dev->ops.setStateCallBack = screen_source_set_state_callback; |
296 | dev->ops.setPreviewWindow = screen_source_set_preview_window; |
297 | dev->ops.setDataCallBack = screen_source_set_data_callback; |
298 | dev->ops.set_frame_rate = screen_source_set_frame_rate; |
299 | dev->ops.set_source_type = screen_source_set_source_type; |
300 | dev->ops.get_source_type = screen_source_get_source_type; |
301 | // dev->ops.inc_buffer_refcount = screen_source_inc_buffer_refcount; |
302 | dev->ops.start_v4l2_device = screen_source_start_v4l2_device; |
303 | dev->ops.stop_v4l2_device = screen_source_stop_v4l2_device; |
304 | dev->ops.set_port_type = screen_source_set_port_type; |
305 | *device = &dev->common; |
306 | status = 0; |
307 | gAmlScreenOpen++; |
308 | } |
309 | return status; |
310 | } |
311 |