summaryrefslogtreecommitdiff
path: root/tv_input.cpp (plain)
blob: d6eb13d53032e15e7846cab53145cf7c9877a45a
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{
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
46static 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
57static 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
68static 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
79static 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
90static 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
101static 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
112static 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
124static 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
136static int get_stream_configs(int dev_id, int *num_configurations, const tv_stream_config_t **configs)
137{
138 tv_stream_config_t *mconfig = (tv_stream_config_t *)malloc(sizeof(mconfig));
139 if (!mconfig)
140 {
141 return -1;
142 }
143 switch (dev_id)
144 {
145 case SOURCE_TV:
146 mconfig->stream_id = SOURCE_TV;
147 mconfig->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ;
148 mconfig->max_video_width = 1920;
149 mconfig->max_video_height = 1080;
150 *num_configurations = 1;
151 *configs = mconfig;
152 break;
153 case SOURCE_DTV:
154 mconfig->stream_id = SOURCE_DTV;
155 mconfig->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ;
156 mconfig->max_video_width = 1920;
157 mconfig->max_video_height = 1080;
158 *num_configurations = 1;
159 *configs = mconfig;
160 break;
161 case SOURCE_AV1:
162 mconfig->stream_id = SOURCE_AV1;
163 mconfig->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ;
164 mconfig->max_video_width = 1920;
165 mconfig->max_video_height = 1080;
166 *num_configurations = 1;
167 *configs = mconfig;
168 break;
169 case SOURCE_HDMI1:
170 mconfig->stream_id = SOURCE_HDMI1;
171 mconfig->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ;
172 mconfig->max_video_width = 1920;
173 mconfig->max_video_height = 1080;
174 *num_configurations = 1;
175 *configs = mconfig;
176 break;
177 case SOURCE_HDMI2:
178 mconfig->stream_id = SOURCE_HDMI2;
179 mconfig->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ;
180 mconfig->max_video_width = 1920;
181 mconfig->max_video_height = 1080;
182 *num_configurations = 1;
183 *configs = mconfig;
184 break;
185 case SOURCE_HDMI3:
186 mconfig->stream_id = SOURCE_HDMI3;
187 mconfig->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ;
188 mconfig->max_video_width = 1920;
189 mconfig->max_video_height = 1080;
190 *num_configurations = 1;
191 *configs = mconfig;
192 break;
193 default:
194 break;
195 }
196 return 0;
197}
198
199static int get_tv_stream(int device_id, tv_stream_t *stream)
200{
201 native_handle *h = native_handle_create(0, 0);
202 if (!h)
203 {
204 return -EINVAL;
205 }
206 switch (device_id)
207 {
208 case SOURCE_TV:
209 stream->stream_id = SOURCE_TV;
210 stream->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE;
211 stream->sideband_stream_source_handle = h;
212 break;
213 case SOURCE_DTV:
214 stream->stream_id = SOURCE_DTV;
215 stream->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE;
216 stream->sideband_stream_source_handle = h;
217 break;
218 case SOURCE_AV1:
219 stream->stream_id = SOURCE_AV1;
220 stream->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE;
221 stream->sideband_stream_source_handle = h;
222 break;
223 case SOURCE_HDMI1:
224 stream->stream_id = SOURCE_HDMI1;
225 stream->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE;
226 stream->sideband_stream_source_handle = h;
227 break;
228 case SOURCE_HDMI2:
229 stream->stream_id = SOURCE_HDMI2;
230 stream->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE;
231 stream->sideband_stream_source_handle = h;
232 break;
233 case SOURCE_HDMI3:
234 stream->stream_id = SOURCE_HDMI3;
235 stream->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE;
236 stream->sideband_stream_source_handle = h;
237 break;
238defualt:
239 break;
240 }
241 return 0;
242}
243
244static int tv_input_device_open(const struct hw_module_t *module,
245 const char *name, struct hw_device_t **device);
246
247static struct hw_module_methods_t tv_input_module_methods =
248{
249open:
250 tv_input_device_open
251};
252
253tv_input_module_t HAL_MODULE_INFO_SYM =
254{
255common:
256 {
257tag:
258 HARDWARE_MODULE_TAG,
259 version_major: 0,
260 version_minor: 1,
261id:
262 TV_INPUT_HARDWARE_MODULE_ID,
263name: "TVInput module"
264 ,
265author: "Amlogic"
266 ,
267methods:
268 &tv_input_module_methods,
269 }
270};
271
272/*****************************************************************************/
273
274static int tv_input_initialize(struct tv_input_device *dev,
275 const tv_input_callback_ops_t *callback, void *data)
276{
277 if (dev == NULL || callback == NULL)
278 {
279 return -EINVAL;
280 }
281 tv_input_private_t *priv = (tv_input_private_t *)dev;
282 if (priv->callback != NULL)
283 {
284 return -EEXIST;
285 }
286
287 priv->callback = callback;
288 priv->callback_data = data;
289 /* ATV_DEVICE_AVAILABLE */
290 notify_ATV_device_available(priv);
291 notify_ATV_stream_configurations_change(priv);
292 /* DTV_DEVICE_AVAILABLE */
293 notify_DTV_device_available(priv);
294 notify_DTV_stream_configurations_change(priv);
295 /* AV_DEVICE_AVAILABLE */
296 notify_AV_device_available(priv);
297 notify_AV_stream_configurations_change(priv);
298 /* HDMI1_DEVICE_AVAILABLE */
299 notify_HDMI_device_available(priv, SOURCE_HDMI1, 1);
300 notify_HDMI_stream_configurations_change(priv, SOURCE_HDMI1, 1);
301 /* HDMI2_DEVICE_AVAILABLE */
302 notify_HDMI_device_available(priv, SOURCE_HDMI2, 1);
303 notify_HDMI_stream_configurations_change(priv, SOURCE_HDMI2, 1);
304 /* HDMI3_DEVICE_AVAILABLE */
305 notify_HDMI_device_available(priv, SOURCE_HDMI3, 1);
306 notify_HDMI_stream_configurations_change(priv, SOURCE_HDMI3, 1);
307
308 return 0;
309}
310
311static int tv_input_get_stream_configurations(const struct tv_input_device *dev,
312 int device_id, int *num_configurations,
313 const tv_stream_config_t **configs)
314{
315 if (get_stream_configs(device_id, num_configurations, configs) == 0)
316 {
317 return 0;
318 }
319 return -EINVAL;
320}
321
322static int tv_input_open_stream(struct tv_input_device *dev, int device_id,
323 tv_stream_t *stream)
324{
325 tv_input_private_t *priv = (tv_input_private_t *)dev;
326 if (priv)
327 {
328 if (get_tv_stream(device_id, stream) != 0)
329 {
330 return -EINVAL;
331 }
332 LOGD ( "%s, SetSourceSwitchInput id = %d\n", __FUNCTION__, device_id );
333 priv->pTv->StartTvLock();
334 priv->pTv->SetSourceSwitchInput((tv_source_input_t) device_id);
335 return 0;
336 }
337 return -EINVAL;
338}
339
340static int tv_input_close_stream(struct tv_input_device *dev, int device_id,
341 int stream_id)
342{
343 tv_input_private_t *priv = (tv_input_private_t *)dev;
344 if (priv)
345 {
346 LOGD ( "%s\n", __FUNCTION__ );
347 priv->pTv->StopTvLock();
348 return 0;
349 }
350 return -EINVAL;
351}
352
353static int tv_input_request_capture(
354 struct tv_input_device *, int, int, buffer_handle_t, uint32_t)
355{
356 return -EINVAL;
357}
358
359static int tv_input_cancel_capture(struct tv_input_device *, int, int, uint32_t)
360{
361 return -EINVAL;
362}
363
364/*****************************************************************************/
365
366static int tv_input_device_close(struct hw_device_t *dev)
367{
368 tv_input_private_t *priv = (tv_input_private_t *)dev;
369 if (priv->pTv != NULL)
370 {
371 delete priv->pTv;
372 }
373 if (priv)
374 {
375 free(priv);
376 }
377 return 0;
378}
379
380/*****************************************************************************/
381
382static int tv_input_device_open(const struct hw_module_t *module,
383 const char *name, struct hw_device_t **device)
384{
385 int status = -EINVAL;
386 if (!strcmp(name, TV_INPUT_DEFAULT_DEVICE))
387 {
388 tv_input_private_t *dev = (tv_input_private_t *)malloc(sizeof(*dev));
389
390 /* initialize our state here */
391 memset(dev, 0, sizeof(*dev));
392 /*intialize tv*/
393 dev->pTv = new CTv();
394 TvService::instantiate(dev->pTv);
395 dev->pTv->OpenTv();
396 /* initialize the procs */
397 dev->device.common.tag = HARDWARE_DEVICE_TAG;
398 dev->device.common.version = TV_INPUT_DEVICE_API_VERSION_0_1;
399 dev->device.common.module = const_cast<hw_module_t *>(module);
400 dev->device.common.close = tv_input_device_close;
401
402 dev->device.initialize = tv_input_initialize;
403 dev->device.get_stream_configurations =
404 tv_input_get_stream_configurations;
405 dev->device.open_stream = tv_input_open_stream;
406 dev->device.close_stream = tv_input_close_stream;
407 dev->device.request_capture = tv_input_request_capture;
408 dev->device.cancel_capture = tv_input_cancel_capture;
409
410 *device = &dev->device.common;
411 status = 0;
412 }
413 return status;
414}
415