blob: b7aa6e861f62fcf7f77031b020f809ababd7361f
1 | /* |
2 | * Copyright 2014 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_TAG "TvInput" |
18 | #include <fcntl.h> |
19 | #include <errno.h> |
20 | |
21 | #include <cutils/log.h> |
22 | #include <cutils/native_handle.h> |
23 | |
24 | #include <hardware/tv_input.h> |
25 | #include <tv/CTv.h> |
26 | #include <tvin/CTvin.h> |
27 | #include <tvserver/TvService.h> |
28 | /*****************************************************************************/ |
29 | |
30 | #define LOGD(...) \ |
31 | { \ |
32 | __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__); } |
33 | |
34 | |
35 | typedef struct tv_input_private |
36 | { |
37 | tv_input_device_t device; |
38 | |
39 | // Callback related data |
40 | const tv_input_callback_ops_t *callback; |
41 | void *callback_data; |
42 | //TvService* pTvService; |
43 | CTv *pTv; |
44 | } tv_input_private_t; |
45 | |
46 | static int notify_ATV_device_available(tv_input_private_t *priv) |
47 | { |
48 | tv_input_event_t event; |
49 | event.device_info.device_id = SOURCE_TV; |
50 | event.device_info.type = TV_INPUT_TYPE_TUNER; |
51 | event.type = TV_INPUT_EVENT_DEVICE_AVAILABLE; |
52 | event.device_info.audio_type = AUDIO_DEVICE_NONE; |
53 | priv->callback->notify(&priv->device, &event, priv->callback_data); |
54 | return 0; |
55 | } |
56 | |
57 | static int notify_ATV_stream_configurations_change(tv_input_private_t *priv) |
58 | { |
59 | tv_input_event_t event; |
60 | event.device_info.device_id = SOURCE_TV; |
61 | event.device_info.type = TV_INPUT_TYPE_TUNER; |
62 | event.type = TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED; |
63 | event.device_info.audio_type = AUDIO_DEVICE_NONE; |
64 | priv->callback->notify(&priv->device, &event, priv->callback_data); |
65 | return 0; |
66 | } |
67 | |
68 | static int notify_DTV_device_available(tv_input_private_t *priv) |
69 | { |
70 | tv_input_event_t event; |
71 | event.device_info.device_id = SOURCE_DTV; |
72 | event.device_info.type = TV_INPUT_TYPE_TUNER; |
73 | event.type = TV_INPUT_EVENT_DEVICE_AVAILABLE; |
74 | event.device_info.audio_type = AUDIO_DEVICE_NONE; |
75 | priv->callback->notify(&priv->device, &event, priv->callback_data); |
76 | return 0; |
77 | } |
78 | |
79 | static int notify_DTV_stream_configurations_change(tv_input_private_t *priv) |
80 | { |
81 | tv_input_event_t event; |
82 | event.device_info.device_id = SOURCE_DTV; |
83 | event.device_info.type = TV_INPUT_TYPE_TUNER; |
84 | event.type = TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED; |
85 | event.device_info.audio_type = AUDIO_DEVICE_NONE; |
86 | priv->callback->notify(&priv->device, &event, priv->callback_data); |
87 | return 0; |
88 | } |
89 | |
90 | static int notify_AV_device_available(tv_input_private_t *priv) |
91 | { |
92 | tv_input_event_t event; |
93 | event.device_info.device_id = SOURCE_AV1; |
94 | event.device_info.type = TV_INPUT_TYPE_COMPONENT; |
95 | event.type = TV_INPUT_EVENT_DEVICE_AVAILABLE; |
96 | event.device_info.audio_type = AUDIO_DEVICE_NONE; |
97 | priv->callback->notify(&priv->device, &event, priv->callback_data); |
98 | return 0; |
99 | } |
100 | |
101 | static int notify_AV_stream_configurations_change(tv_input_private_t *priv) |
102 | { |
103 | tv_input_event_t event; |
104 | event.device_info.device_id = SOURCE_AV1; |
105 | event.device_info.type = TV_INPUT_TYPE_COMPONENT; |
106 | event.type = TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED; |
107 | event.device_info.audio_type = AUDIO_DEVICE_NONE; |
108 | priv->callback->notify(&priv->device, &event, priv->callback_data); |
109 | return 0; |
110 | } |
111 | |
112 | static int notify_HDMI_device_available(tv_input_private_t *priv, int dev_id, uint32_t port_id) |
113 | { |
114 | tv_input_event_t event; |
115 | event.device_info.device_id = dev_id; |
116 | event.device_info.type = TV_INPUT_TYPE_HDMI; |
117 | event.type = TV_INPUT_EVENT_DEVICE_AVAILABLE; |
118 | event.device_info.hdmi.port_id = port_id; |
119 | event.device_info.audio_type = AUDIO_DEVICE_NONE; |
120 | priv->callback->notify(&priv->device, &event, priv->callback_data); |
121 | return 0; |
122 | } |
123 | |
124 | static int notify_HDMI_stream_configurations_change(tv_input_private_t *priv, int dev_id, uint32_t port_id) |
125 | { |
126 | tv_input_event_t event; |
127 | event.device_info.device_id = dev_id; |
128 | event.device_info.type = TV_INPUT_TYPE_HDMI; |
129 | event.type = TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED; |
130 | event.device_info.hdmi.port_id = port_id; |
131 | event.device_info.audio_type = AUDIO_DEVICE_NONE; |
132 | priv->callback->notify(&priv->device, &event, priv->callback_data); |
133 | return 0; |
134 | } |
135 | |
136 | #define NORMAL_STREAM_ID 1 |
137 | #define FRAME_CAPTURE_STREAM_ID 2 |
138 | static tv_stream_config_t mconfig[2]; |
139 | static int get_stream_configs(int dev_id, int *num_configurations, const tv_stream_config_t **configs) |
140 | { |
141 | switch (dev_id) |
142 | { |
143 | case SOURCE_TV: |
144 | mconfig[0].stream_id = NORMAL_STREAM_ID; |
145 | mconfig[0].type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ; |
146 | mconfig[0].max_video_width = 1920; |
147 | mconfig[0].max_video_height = 1080; |
148 | mconfig[1].stream_id = FRAME_CAPTURE_STREAM_ID; |
149 | mconfig[1].type = TV_STREAM_TYPE_BUFFER_PRODUCER ; |
150 | mconfig[1].max_video_width = 1920; |
151 | mconfig[1].max_video_height = 1080; |
152 | *num_configurations = 2; |
153 | *configs = mconfig; |
154 | break; |
155 | case SOURCE_DTV: |
156 | mconfig[0].stream_id = NORMAL_STREAM_ID; |
157 | mconfig[0].type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ; |
158 | mconfig[0].max_video_width = 1920; |
159 | mconfig[0].max_video_height = 1080; |
160 | mconfig[1].stream_id = FRAME_CAPTURE_STREAM_ID; |
161 | mconfig[1].type = TV_STREAM_TYPE_BUFFER_PRODUCER ; |
162 | mconfig[1].max_video_width = 1920; |
163 | mconfig[1].max_video_height = 1080; |
164 | *num_configurations = 2; |
165 | *configs = mconfig; |
166 | break; |
167 | case SOURCE_AV1: |
168 | mconfig[0].stream_id = NORMAL_STREAM_ID; |
169 | mconfig[0].type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ; |
170 | mconfig[0].max_video_width = 1920; |
171 | mconfig[0].max_video_height = 1080; |
172 | mconfig[1].stream_id = FRAME_CAPTURE_STREAM_ID; |
173 | mconfig[1].type = TV_STREAM_TYPE_BUFFER_PRODUCER ; |
174 | mconfig[1].max_video_width = 1920; |
175 | mconfig[1].max_video_height = 1080; |
176 | *num_configurations = 2; |
177 | *configs = mconfig; |
178 | break; |
179 | case SOURCE_HDMI1: |
180 | mconfig[0].stream_id = NORMAL_STREAM_ID; |
181 | mconfig[0].type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ; |
182 | mconfig[0].max_video_width = 1920; |
183 | mconfig[0].max_video_height = 1080; |
184 | mconfig[1].stream_id = FRAME_CAPTURE_STREAM_ID; |
185 | mconfig[1].type = TV_STREAM_TYPE_BUFFER_PRODUCER ; |
186 | mconfig[1].max_video_width = 1920; |
187 | mconfig[1].max_video_height = 1080; |
188 | *num_configurations = 2; |
189 | *configs = mconfig; |
190 | break; |
191 | case SOURCE_HDMI2: |
192 | mconfig[0].stream_id = NORMAL_STREAM_ID; |
193 | mconfig[0].type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ; |
194 | mconfig[0].max_video_width = 1920; |
195 | mconfig[0].max_video_height = 1080; |
196 | mconfig[1].stream_id = FRAME_CAPTURE_STREAM_ID; |
197 | mconfig[1].type = TV_STREAM_TYPE_BUFFER_PRODUCER ; |
198 | mconfig[1].max_video_width = 1920; |
199 | mconfig[1].max_video_height = 1080; |
200 | *num_configurations = 2; |
201 | *configs = mconfig; |
202 | break; |
203 | case SOURCE_HDMI3: |
204 | mconfig[0].stream_id = NORMAL_STREAM_ID; |
205 | mconfig[0].type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ; |
206 | mconfig[0].max_video_width = 1920; |
207 | mconfig[0].max_video_height = 1080; |
208 | mconfig[1].stream_id = FRAME_CAPTURE_STREAM_ID; |
209 | mconfig[1].type = TV_STREAM_TYPE_BUFFER_PRODUCER ; |
210 | mconfig[1].max_video_width = 1920; |
211 | mconfig[1].max_video_height = 1080; |
212 | *num_configurations = 2; |
213 | *configs = mconfig; |
214 | break; |
215 | default: |
216 | break; |
217 | } |
218 | return 0; |
219 | } |
220 | |
221 | static int get_tv_stream(tv_stream_t *stream) |
222 | { |
223 | if (stream->stream_id == NORMAL_STREAM_ID) { |
224 | native_handle *h = native_handle_create(0, 0); |
225 | if (!h) { |
226 | return -EINVAL; |
227 | } |
228 | stream->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE; |
229 | stream->sideband_stream_source_handle = h; |
230 | } |
231 | else if (stream->stream_id == NORMAL_STREAM_ID) { |
232 | stream->type = TV_STREAM_TYPE_BUFFER_PRODUCER; |
233 | } |
234 | return 0; |
235 | } |
236 | |
237 | static int tv_input_device_open(const struct hw_module_t *module, |
238 | const char *name, struct hw_device_t **device); |
239 | |
240 | static struct hw_module_methods_t tv_input_module_methods = |
241 | { |
242 | open: |
243 | tv_input_device_open |
244 | }; |
245 | |
246 | tv_input_module_t HAL_MODULE_INFO_SYM = |
247 | { |
248 | common: |
249 | { |
250 | tag: |
251 | HARDWARE_MODULE_TAG, |
252 | version_major: 0, |
253 | version_minor: 1, |
254 | id: |
255 | TV_INPUT_HARDWARE_MODULE_ID, |
256 | name: "TVInput module" |
257 | , |
258 | author: "Amlogic" |
259 | , |
260 | methods: |
261 | &tv_input_module_methods, |
262 | } |
263 | }; |
264 | |
265 | /*****************************************************************************/ |
266 | |
267 | static int tv_input_initialize(struct tv_input_device *dev, |
268 | const tv_input_callback_ops_t *callback, void *data) |
269 | { |
270 | if (dev == NULL || callback == NULL) |
271 | { |
272 | return -EINVAL; |
273 | } |
274 | tv_input_private_t *priv = (tv_input_private_t *)dev; |
275 | if (priv->callback != NULL) |
276 | { |
277 | return -EEXIST; |
278 | } |
279 | |
280 | priv->callback = callback; |
281 | priv->callback_data = data; |
282 | /* ATV_DEVICE_AVAILABLE */ |
283 | notify_ATV_device_available(priv); |
284 | notify_ATV_stream_configurations_change(priv); |
285 | /* DTV_DEVICE_AVAILABLE */ |
286 | notify_DTV_device_available(priv); |
287 | notify_DTV_stream_configurations_change(priv); |
288 | /* AV_DEVICE_AVAILABLE */ |
289 | notify_AV_device_available(priv); |
290 | notify_AV_stream_configurations_change(priv); |
291 | /* HDMI1_DEVICE_AVAILABLE */ |
292 | notify_HDMI_device_available(priv, SOURCE_HDMI1, 1); |
293 | notify_HDMI_stream_configurations_change(priv, SOURCE_HDMI1, 1); |
294 | /* HDMI2_DEVICE_AVAILABLE */ |
295 | notify_HDMI_device_available(priv, SOURCE_HDMI2, 1); |
296 | notify_HDMI_stream_configurations_change(priv, SOURCE_HDMI2, 1); |
297 | /* HDMI3_DEVICE_AVAILABLE */ |
298 | notify_HDMI_device_available(priv, SOURCE_HDMI3, 1); |
299 | notify_HDMI_stream_configurations_change(priv, SOURCE_HDMI3, 1); |
300 | |
301 | return 0; |
302 | } |
303 | |
304 | static int tv_input_get_stream_configurations(const struct tv_input_device *dev, |
305 | int device_id, int *num_configurations, |
306 | const tv_stream_config_t **configs) |
307 | { |
308 | if (get_stream_configs(device_id, num_configurations, configs) == 0) |
309 | { |
310 | return 0; |
311 | } |
312 | return -EINVAL; |
313 | } |
314 | |
315 | static int tv_input_open_stream(struct tv_input_device *dev, int device_id, |
316 | tv_stream_t *stream) |
317 | { |
318 | tv_input_private_t *priv = (tv_input_private_t *)dev; |
319 | if (priv) |
320 | { |
321 | if (get_tv_stream(stream) != 0) |
322 | { |
323 | return -EINVAL; |
324 | } |
325 | if (stream->stream_id == NORMAL_STREAM_ID) { |
326 | LOGD ( "%s, SetSourceSwitchInput id = %d\n", __FUNCTION__, device_id ); |
327 | priv->pTv->StartTvLock(); |
328 | priv->pTv->SetSourceSwitchInput((tv_source_input_t) device_id); |
329 | return 0; |
330 | } |
331 | else if (stream->stream_id == FRAME_CAPTURE_STREAM_ID) { |
332 | return 0; |
333 | } |
334 | } |
335 | return -EINVAL; |
336 | } |
337 | |
338 | static int tv_input_close_stream(struct tv_input_device *dev, int device_id, |
339 | int stream_id) |
340 | { |
341 | tv_input_private_t *priv = (tv_input_private_t *)dev; |
342 | if (priv) |
343 | { |
344 | LOGD ( "%s, SetSourceSwitchInput id = %d\n", __FUNCTION__, device_id ); |
345 | priv->pTv->StopTvLock(); |
346 | return 0; |
347 | } |
348 | return -EINVAL; |
349 | } |
350 | |
351 | static int tv_input_request_capture( |
352 | struct tv_input_device *, int, int, buffer_handle_t, uint32_t) |
353 | { |
354 | return -EINVAL; |
355 | } |
356 | |
357 | static int tv_input_cancel_capture(struct tv_input_device *, int, int, uint32_t) |
358 | { |
359 | return -EINVAL; |
360 | } |
361 | |
362 | /*****************************************************************************/ |
363 | |
364 | static int tv_input_device_close(struct hw_device_t *dev) |
365 | { |
366 | tv_input_private_t *priv = (tv_input_private_t *)dev; |
367 | if (priv->pTv != NULL) |
368 | { |
369 | delete priv->pTv; |
370 | } |
371 | if (priv) |
372 | { |
373 | free(priv); |
374 | } |
375 | return 0; |
376 | } |
377 | |
378 | /*****************************************************************************/ |
379 | |
380 | static int tv_input_device_open(const struct hw_module_t *module, |
381 | const char *name, struct hw_device_t **device) |
382 | { |
383 | int status = -EINVAL; |
384 | if (!strcmp(name, TV_INPUT_DEFAULT_DEVICE)) |
385 | { |
386 | tv_input_private_t *dev = (tv_input_private_t *)malloc(sizeof(*dev)); |
387 | |
388 | /* initialize our state here */ |
389 | memset(dev, 0, sizeof(*dev)); |
390 | /*intialize tv*/ |
391 | dev->pTv = new CTv(); |
392 | TvService::instantiate(dev->pTv); |
393 | dev->pTv->OpenTv(); |
394 | /* initialize the procs */ |
395 | dev->device.common.tag = HARDWARE_DEVICE_TAG; |
396 | dev->device.common.version = TV_INPUT_DEVICE_API_VERSION_0_1; |
397 | dev->device.common.module = const_cast<hw_module_t *>(module); |
398 | dev->device.common.close = tv_input_device_close; |
399 | |
400 | dev->device.initialize = tv_input_initialize; |
401 | dev->device.get_stream_configurations = |
402 | tv_input_get_stream_configurations; |
403 | dev->device.open_stream = tv_input_open_stream; |
404 | dev->device.close_stream = tv_input_close_stream; |
405 | dev->device.request_capture = tv_input_request_capture; |
406 | dev->device.cancel_capture = tv_input_cancel_capture; |
407 | |
408 | *device = &dev->device.common; |
409 | status = 0; |
410 | } |
411 | return status; |
412 | } |
413 |