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