-rw-r--r-- | Android.mk | 23 | ||||
-rw-r--r-- | TvInputIntf.cpp | 138 | ||||
-rw-r--r-- | TvInputIntf.h | 89 | ||||
-rw-r--r-- | TvPlay.cpp | 145 | ||||
-rw-r--r-- | TvPlay.h | 76 | ||||
-rw-r--r-- | tv_callback.h | 17 | ||||
-rw-r--r-- | tv_input.cpp | 298 | ||||
-rw-r--r-- | tv_input.h | 83 |
8 files changed, 464 insertions, 405 deletions
diff --git a/tv_input.cpp b/tv_input.cpp index a8f7f87..3deeaee 100644 --- a/tv_input.cpp +++ b/tv_input.cpp @@ -22,8 +22,7 @@ #include <cutils/native_handle.h> #include <hardware/tv_input.h> -#include "TvPlay.h" -#include "tv_callback.h" +#include "tv_input.h" #include <tvcmd.h> #include <ui/GraphicBufferMapper.h> #include <ui/GraphicBuffer.h> @@ -35,62 +34,67 @@ #endif #include <hardware/hardware.h> -#include <aml_screen.h> #include <linux/videodev2.h> #include <android/native_window.h> -/*****************************************************************************/ -#define LOGD(...) \ -{ \ -__android_log_print(ANDROID_LOG_DEBUG, "tv_input", __VA_ARGS__); } +static const int SCREENSOURCE_GRALLOC_USAGE = ( + GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | + GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_NEVER); -#ifndef container_of -#define container_of(ptr, type, member) \ - (type *)((char*)(ptr) - offsetof(type, member)) -#endif - -struct sideband_handle_t { - native_handle_t nativeHandle; - int identflag; - int usage; -}; - -typedef struct tv_input_private { - tv_input_device_t device; - const tv_input_callback_ops_t *callback; - void *callback_data; - aml_screen_device_t *mDev; - TvPlay *mpTv; - TvCallback *tvcallback; -} tv_input_private_t; - -#define SCREENSOURCE_GRALLOC_USAGE ( GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_NEVER) -//static int capBufferSize ; static int capWidth; static int capHeight; -void TvIputHal_ChannelConl(tv_input_private_t *priv, int ops_type, int device_id) -{ +struct sideband_handle_t *pTvStream = nullptr; + +void EventCallback::onTvEvent (const source_connect_t &scrConnect) { + tv_input_private_t *priv = (tv_input_private_t *)(mPri); + + //ALOGI("callback::onTvEvent msgType = %d", scrConnect.msgType); + switch (scrConnect.msgType) { + case SOURCE_CONNECT_CALLBACK: { + tv_source_input_t source = (tv_source_input_t)scrConnect.source; + int connectState = scrConnect.state; + ALOGI("callback::onTvEvent source = %d, status = %d", source, connectState); + + if (source != SOURCE_HDMI1 && source != SOURCE_HDMI2 && source != SOURCE_HDMI3 + && source != SOURCE_HDMI4 && source != SOURCE_AV1 && source != SOURCE_AV2) + break; + + if (connectState == 1) { + notifyDeviceStatus(priv, source, TV_INPUT_EVENT_DEVICE_AVAILABLE); + notifyDeviceStatus(priv, source, TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED); + } else { + notifyDeviceStatus(priv, source, TV_INPUT_EVENT_DEVICE_UNAVAILABLE); + } + } + break; + + default: + break; + } +} + +void channelControl(tv_input_private_t *priv, bool opsStart, int device_id) { if (priv->mpTv) { - if (ops_type) { - LOGD ( "%s, OpenSourceSwitchInput id = %d\n", __FUNCTION__, device_id ); - priv->mpTv->StartTv(); - priv->mpTv->SwitchSourceInput((tv_source_input_t) device_id); - } else if (priv->mpTv->GetCurrentSourceInput() == device_id) { - LOGD ( "%s, StopSourceSwitchInput id = %d\n", __FUNCTION__, device_id ); - priv->mpTv->StopTv(); + ALOGI ("%s, device id:%d ,startTV:%d\n", __FUNCTION__, device_id, opsStart?1:0); + + if (opsStart) { + priv->mpTv->startTv(); + priv->mpTv->switchSourceInput((tv_source_input_t) device_id); + } else if (priv->mpTv->getCurrentSourceInput() == device_id) { + priv->mpTv->stopTv(); } } } -static int notify_tv_device_status(tv_input_private_t *priv, tv_source_input_t source_input, int type) +int notifyDeviceStatus(tv_input_private_t *priv, tv_source_input_t inputSrc, int type) { tv_input_event_t event; - event.device_info.device_id = source_input; + event.device_info.device_id = inputSrc; event.device_info.audio_type = AUDIO_DEVICE_NONE; event.device_info.audio_address = NULL; event.type = type; - switch (source_input) { + switch (inputSrc) { case SOURCE_TV: case SOURCE_DTV: case SOURCE_ADTV: @@ -105,7 +109,7 @@ static int notify_tv_device_status(tv_input_private_t *priv, tv_source_input_t s case SOURCE_HDMI3: case SOURCE_HDMI4: event.device_info.type = TV_INPUT_TYPE_HDMI; - event.device_info.hdmi.port_id = priv->mpTv->getHdmiPort(source_input); + event.device_info.hdmi.port_id = priv->mpTv->getHdmiPort(inputSrc); break; case SOURCE_SPDIF: event.device_info.type = TV_INPUT_TYPE_OTHER_HARDWARE; @@ -117,7 +121,7 @@ static int notify_tv_device_status(tv_input_private_t *priv, tv_source_input_t s return 0; } -static int notify_TV_Input_Capture_Succeeded(tv_input_private_t *priv, int device_id, int stream_id, uint32_t seq) +static int notifyCaptureSucceeded(tv_input_private_t *priv, int device_id, int stream_id, uint32_t seq) { tv_input_event_t event; event.type = TV_INPUT_EVENT_CAPTURE_SUCCEEDED; @@ -128,7 +132,7 @@ static int notify_TV_Input_Capture_Succeeded(tv_input_private_t *priv, int devic return 0; } -static int notify_TV_Input_Capture_Fail(tv_input_private_t *priv, int device_id, int stream_id, uint32_t seq) +static int notifyCaptureFail(tv_input_private_t *priv, int device_id, int stream_id, uint32_t seq) { tv_input_event_t event; event.type = TV_INPUT_EVENT_CAPTURE_FAILED; @@ -138,130 +142,74 @@ static int notify_TV_Input_Capture_Fail(tv_input_private_t *priv, int device_id, priv->callback->notify(&priv->device, &event, priv->callback_data); return 0; } -void TvCallback::onTvEvent (int32_t msgType, const Parcel &p) -{ - tv_input_private_t *priv = (tv_input_private_t *)(mPri); - switch (msgType) { - case SOURCE_CONNECT_CALLBACK: { - tv_source_input_t source = (tv_source_input_t)p.readInt32(); - int connectState = p.readInt32(); - LOGD("TvCallback::onTvEvent source = %d, status = %d", source, connectState); - - if (source != SOURCE_HDMI1 && source != SOURCE_HDMI2 && source != SOURCE_HDMI3 - && source != SOURCE_HDMI4 && source != SOURCE_AV1 && source != SOURCE_AV2) - break; - if (connectState == 1) { - notify_tv_device_status(priv, source, TV_INPUT_EVENT_DEVICE_AVAILABLE); - notify_tv_device_status(priv, source, TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED); - } else { - notify_tv_device_status(priv, source, TV_INPUT_EVENT_DEVICE_UNAVAILABLE); - } - break; - } - default: - break; - } -} - -#define NORMAL_STREAM_ID 1 -#define FRAME_CAPTURE_STREAM_ID 2 -static tv_stream_config_t mconfig[2]; -static int get_stream_configs(int dev_id __unused, int *num_configurations, const tv_stream_config_t **configs) +static bool getStreamConfigs(int dev_id __unused, int *num_configurations, const tv_stream_config_t **configs) { - mconfig[0].stream_id = NORMAL_STREAM_ID; + static tv_stream_config_t mconfig[2]; + mconfig[0].stream_id = STREAM_ID_NORMAL; mconfig[0].type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE ; mconfig[0].max_video_width = 1920; mconfig[0].max_video_height = 1080; - mconfig[1].stream_id = FRAME_CAPTURE_STREAM_ID; + mconfig[1].stream_id = STREAM_ID_FRAME_CAPTURE; mconfig[1].type = TV_STREAM_TYPE_BUFFER_PRODUCER ; mconfig[1].max_video_width = 1920; mconfig[1].max_video_height = 1080; *num_configurations = 2; *configs = mconfig; - return 0; + return true; } -static int get_tv_stream(tv_stream_t *stream) +static int getTvStream(tv_stream_t *stream) { - static struct sideband_handle_t *tvstream = NULL; - if (stream->stream_id == NORMAL_STREAM_ID) { - if ( !tvstream ) { - tvstream = (struct sideband_handle_t *)native_handle_create(0, 2); - if ( !tvstream ) { + if (stream->stream_id == STREAM_ID_NORMAL) { + if (pTvStream == nullptr) { + pTvStream = (struct sideband_handle_t *)native_handle_create(0, 2); + if (pTvStream == nullptr) { + ALOGE("tvstream can not be initialized"); return -EINVAL; } } - tvstream->identflag = 0xabcdcdef; //magic word - tvstream->usage = GRALLOC_USAGE_AML_VIDEO_OVERLAY; + pTvStream->identflag = 0xabcdcdef; //magic word + pTvStream->usage = GRALLOC_USAGE_AML_VIDEO_OVERLAY; stream->type = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE; - stream->sideband_stream_source_handle = (native_handle_t *)tvstream; - } else if (stream->stream_id == FRAME_CAPTURE_STREAM_ID) { + stream->sideband_stream_source_handle = (native_handle_t *)pTvStream; + } else if (stream->stream_id == STREAM_ID_FRAME_CAPTURE) { stream->type = TV_STREAM_TYPE_BUFFER_PRODUCER; } return 0; } -static void available_all_tv_device(tv_input_private_t *priv) +void initTvDevices(tv_input_private_t *priv) { - int tv_devices[15]; + int supportDevices[20]; int count = 0; - priv->mpTv->getAllTvDevices(tv_devices, &count); + priv->mpTv->getSupportInputDevices(supportDevices, &count); if (count == 0) { ALOGE("tv.source.input.ids.default is not set."); return; } - bool isHotplugDetectOn = priv->mpTv->GetHdmiAvHotplugDetectOnoff(); - + bool isHotplugDetectOn = priv->mpTv->getHdmiAvHotplugDetectOnoff(); + ALOGI("hdmi/av hotplug detect on: %s", isHotplugDetectOn?"YES":"NO"); if (isHotplugDetectOn) - priv->mpTv->setTvObserver(priv->tvcallback); + priv->mpTv->setTvObserver(priv->eventCallback); - for (int i=0; i < count; i++) { - tv_source_input_t source_input = (tv_source_input_t)tv_devices[i]; + for (int i = 0; i < count; i++) { + tv_source_input_t inputSrc = (tv_source_input_t)supportDevices[i]; bool status = true; - if (isHotplugDetectOn && SOURCE_AV1 <= source_input && source_input <= SOURCE_HDMI4) { - status = priv->mpTv->GetSourceConnectStatus(source_input); + if (isHotplugDetectOn && SOURCE_AV1 <= inputSrc && inputSrc <= SOURCE_HDMI4) { + status = priv->mpTv->getSourceConnectStatus(inputSrc); } if (status) { - notify_tv_device_status(priv, source_input, TV_INPUT_EVENT_DEVICE_AVAILABLE); - notify_tv_device_status(priv, source_input, TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED); + notifyDeviceStatus(priv, inputSrc, TV_INPUT_EVENT_DEVICE_AVAILABLE); + notifyDeviceStatus(priv, inputSrc, TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED); } } } -static int tv_input_device_open(const struct hw_module_t *module, - const char *name, struct hw_device_t **device); - -static struct hw_module_methods_t tv_input_module_methods = { -open: - tv_input_device_open -}; - -tv_input_module_t HAL_MODULE_INFO_SYM = { -common: - { -tag: - HARDWARE_MODULE_TAG, - version_major: 0, - version_minor: 1, -id: - TV_INPUT_HARDWARE_MODULE_ID, -name: "TVInput module" - , -author: "Amlogic" - , -methods: - &tv_input_module_methods, -dso: NULL, -reserved: {0}, - } -}; - -/*****************************************************************************/ static int tv_input_initialize(struct tv_input_device *dev, const tv_input_callback_ops_t *callback, void *data) { @@ -270,12 +218,13 @@ static int tv_input_initialize(struct tv_input_device *dev, } tv_input_private_t *priv = (tv_input_private_t *)dev; if (priv->callback != NULL) { + ALOGE("tv input had been init done, do not need init again"); return -EEXIST; } priv->callback = callback; priv->callback_data = data; - available_all_tv_device(priv); + initTvDevices(priv); return 0; } @@ -283,7 +232,7 @@ static int tv_input_get_stream_configurations(const struct tv_input_device *dev int device_id, int *num_configurations, const tv_stream_config_t **configs) { - if (get_stream_configs(device_id, num_configurations, configs) == 0) { + if (getStreamConfigs(device_id, num_configurations, configs)) { return 0; } return -EINVAL; @@ -294,20 +243,19 @@ static int tv_input_open_stream(struct tv_input_device *dev, int device_id, { tv_input_private_t *priv = (tv_input_private_t *)dev; if (priv) { - if (get_tv_stream(stream) != 0) { + if (getTvStream(stream) != 0) { return -EINVAL; } - if (stream->stream_id == NORMAL_STREAM_ID) { - TvIputHal_ChannelConl(priv, 1, device_id); - return 0; - } else if (stream->stream_id == FRAME_CAPTURE_STREAM_ID) { - aml_screen_module_t* mModule; - if (hw_get_module(AML_SCREEN_HARDWARE_MODULE_ID, - (const hw_module_t **)&mModule) < 0) { + if (stream->stream_id == STREAM_ID_NORMAL) { + channelControl(priv, true, device_id); + } + else if (stream->stream_id == STREAM_ID_FRAME_CAPTURE) { + aml_screen_module_t* screenModule; + if (hw_get_module(AML_SCREEN_HARDWARE_MODULE_ID, (const hw_module_t **)&screenModule) < 0) { ALOGE("can not get screen source module"); } else { - mModule->common.methods->open((const hw_module_t *)mModule, - AML_SCREEN_SOURCE, (struct hw_device_t**)&(priv->mDev)); + screenModule->common.methods->open((const hw_module_t *)screenModule, + AML_SCREEN_SOURCE, (struct hw_device_t**)&(priv->mDev)); //do test here, we can use ops of mDev to operate vdin source } @@ -320,8 +268,8 @@ static int tv_input_open_stream(struct tv_input_device *dev, int device_id, priv->mDev->ops.set_port_type(priv->mDev, (int)0x4000); //TVIN_PORT_HDMI0 = 0x4000 priv->mDev->ops.start_v4l2_device(priv->mDev); } - return 0; } + return 0; } return -EINVAL; } @@ -330,10 +278,10 @@ static int tv_input_close_stream(struct tv_input_device *dev, int device_id, int stream_id) { tv_input_private_t *priv = (tv_input_private_t *)dev; - if (stream_id == NORMAL_STREAM_ID) { - TvIputHal_ChannelConl(priv, 0, device_id); + if (stream_id == STREAM_ID_NORMAL) { + channelControl(priv, false, device_id); return 0; - } else if (stream_id == FRAME_CAPTURE_STREAM_ID) { + } else if (stream_id == STREAM_ID_FRAME_CAPTURE) { if (priv->mDev) { priv->mDev->ops.stop_v4l2_device(priv->mDev); } @@ -343,33 +291,29 @@ static int tv_input_close_stream(struct tv_input_device *dev, int device_id, } static int tv_input_request_capture( - struct tv_input_device *dev __unused, int device_id __unused, - int stream_id __unused, buffer_handle_t buffer __unused, uint32_t seq __unused) + struct tv_input_device *dev, int device_id, + int stream_id, buffer_handle_t buffer, uint32_t seq) { tv_input_private_t *priv = (tv_input_private_t *)dev; - int index; - aml_screen_buffer_info_t buff_info; - int mFrameWidth , mFrameHeight ; - int ret; - long *src = NULL; unsigned char *dest = NULL; - ANativeWindowBuffer *buf; if (priv->mDev) { - ret = priv->mDev->ops.aquire_buffer(priv->mDev, &buff_info); - if (ret != 0 || (buff_info.buffer_mem == 0)) { - LOGD("Get V4l2 buffer failed"); - notify_TV_Input_Capture_Fail(priv,device_id,stream_id,--seq); + aml_screen_buffer_info_t buffInfo; + int ret = priv->mDev->ops.aquire_buffer(priv->mDev, &buffInfo); + if (ret != 0 || (buffInfo.buffer_mem == nullptr)) { + ALOGE("Get V4l2 buffer failed"); + notifyCaptureFail(priv,device_id,stream_id,--seq); return -EWOULDBLOCK; } - src = (long *)buff_info.buffer_mem; - buf = container_of(buffer, ANativeWindowBuffer, handle); + long *src = (long *)buffInfo.buffer_mem; + + ANativeWindowBuffer *buf = container_of(buffer, ANativeWindowBuffer, handle); sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf->handle, GraphicBuffer::WRAP_HANDLE, buf->width, buf->height, buf->format, buf->layerCount, buf->usage, buf->stride)); graphicBuffer->lock(SCREENSOURCE_GRALLOC_USAGE, (void **)&dest); if (dest == NULL) { - LOGD("Invalid Gralloc Handle"); + ALOGE("Invalid Gralloc Handle"); return -EWOULDBLOCK; } memcpy(dest, src, capWidth*capHeight); @@ -377,7 +321,7 @@ static int tv_input_request_capture( graphicBuffer.clear(); priv->mDev->ops.release_buffer(priv->mDev, src); - notify_TV_Input_Capture_Succeeded(priv,device_id,stream_id,seq); + notifyCaptureSucceeded(priv, device_id, stream_id, seq); return 0; } return -EWOULDBLOCK; @@ -398,7 +342,6 @@ static int tv_input_set_capturesurface_size(struct tv_input_device *dev __unused return 1; } } -/*****************************************************************************/ static int tv_input_device_close(struct hw_device_t *dev) { @@ -406,17 +349,25 @@ static int tv_input_device_close(struct hw_device_t *dev) if (priv) { if (priv->mpTv) { delete priv->mpTv; + priv->mpTv = nullptr; } + if (priv->mDev) { delete priv->mDev; + priv->mDev = nullptr; + } + + if (priv->eventCallback) { + delete priv->eventCallback; + priv->eventCallback = nullptr; } free(priv); + + native_handle_delete((native_handle_t*)pTvStream); } return 0; } -/*****************************************************************************/ - static int tv_input_device_open(const struct hw_module_t *module, const char *name, struct hw_device_t **device) { @@ -425,8 +376,8 @@ static int tv_input_device_open(const struct hw_module_t *module, tv_input_private_t *dev = (tv_input_private_t *)malloc(sizeof(*dev)); /* initialize our state here */ memset(dev, 0, sizeof(*dev)); - dev->mpTv = new TvPlay(); - dev->tvcallback = new TvCallback(dev); + dev->mpTv = new TvInputIntf(); + dev->eventCallback = new EventCallback(dev); /* initialize the procs */ dev->device.common.tag = HARDWARE_DEVICE_TAG; dev->device.common.version = TV_INPUT_DEVICE_API_VERSION_0_1; @@ -447,3 +398,22 @@ static int tv_input_device_open(const struct hw_module_t *module, } return status; } + +static struct hw_module_methods_t tv_input_module_methods = { + .open = tv_input_device_open +}; + +/* + * The tv input Module + */ +tv_input_module_t HAL_MODULE_INFO_SYM = { + .common = { + .tag = HARDWARE_MODULE_TAG, + .version_major = 0, + .version_minor = 1, + .id = TV_INPUT_HARDWARE_MODULE_ID, + .name = "Amlogic tv input Module", + .author = "Amlogic Corp.", + .methods = &tv_input_module_methods, + } +}; |