summaryrefslogtreecommitdiff
path: root/tv_input.cpp (plain)
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
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
136#define NORMAL_STREAM_ID 1
137#define FRAME_CAPTURE_STREAM_ID 2
138static tv_stream_config_t mconfig[2];
139static 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
221static 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
237static int tv_input_device_open(const struct hw_module_t *module,
238 const char *name, struct hw_device_t **device);
239
240static struct hw_module_methods_t tv_input_module_methods =
241{
242open:
243 tv_input_device_open
244};
245
246tv_input_module_t HAL_MODULE_INFO_SYM =
247{
248common:
249 {
250tag:
251 HARDWARE_MODULE_TAG,
252 version_major: 0,
253 version_minor: 1,
254id:
255 TV_INPUT_HARDWARE_MODULE_ID,
256name: "TVInput module"
257 ,
258author: "Amlogic"
259 ,
260methods:
261 &tv_input_module_methods,
262 }
263};
264
265/*****************************************************************************/
266
267static 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
304static 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
315static 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
338static 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
351static int tv_input_request_capture(
352 struct tv_input_device *, int, int, buffer_handle_t, uint32_t)
353{
354 return -EINVAL;
355}
356
357static int tv_input_cancel_capture(struct tv_input_device *, int, int, uint32_t)
358{
359 return -EINVAL;
360}
361
362/*****************************************************************************/
363
364static 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
380static 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