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