From a42d185d78c92c50ab00dba4c776b61cc918a857 Mon Sep 17 00:00:00 2001 From: Tellen Yu Date: Fri, 19 Jan 2018 07:53:23 +0000 Subject: tvinput: add porting tvinput to HIDL architecture [9/12] PD# 157786 need use hwbinder instead of binder for RPC since from O Change-Id: I766898fccbb7b7433bacc8c38efe73a292e86a30 --- diff --git a/Android.mk b/Android.mk index 80d297a..a4f7c8b 100644 --- a/Android.mk +++ b/Android.mk @@ -18,14 +18,23 @@ else endif LOCAL_MODULE_RELATIVE_PATH := hw -LOCAL_SHARED_LIBRARIES := libcutils libutils libtvbinder libbinder libui liblog libhardware +LOCAL_SHARED_LIBRARIES := \ + vendor.amlogic.hardware.tvserver@1.0_vendor \ + libcutils \ + libutils \ + libtvbinder \ + libbinder \ + libui \ + liblog \ + libhardware + LOCAL_REQUIRED_MODULES := libtvbinder LOCAL_CFLAGS += -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) LOCAL_SRC_FILES := \ tv_input.cpp \ - TvPlay.cpp + TvInputIntf.cpp LOCAL_MODULE := tv_input.amlogic LOCAL_MODULE_TAGS := optional @@ -42,9 +51,17 @@ LOCAL_C_INCLUDES += \ system/core/libion/kernel-headers \ hardware/amlogic/gralloc \ hardware/amlogic/screen_source \ + hardware/amlogic/audio/libTVaudio \ frameworks/native/libs/nativewindow/include \ $(GRALLOC_DIR) -LOCAL_C_INCLUDES += hardware/amlogic/audio/libTVaudio +LOCAL_C_INCLUDES += \ + external/libcxx/include + +LOCAL_CPPFLAGS += -std=c++14 + +ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK) +LOCAL_PROPRIETARY_MODULE := true +endif include $(BUILD_SHARED_LIBRARY) diff --git a/TvInputIntf.cpp b/TvInputIntf.cpp new file mode 100644 index 0000000..30ac335 --- a/dev/null +++ b/TvInputIntf.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * @author Tellen Yu + * @version 1.0 + * @date 2018/1/12 + * @par function description: + * - 1 tv_input hal to tvserver interface + */ + +#define LOG_TAG "TvInputIntf" + +#include +#include +#include "TvInputIntf.h" +#include "tvcmd.h" +#include + +using namespace android; + +TvInputIntf::TvInputIntf() : mpObserver(nullptr) { + mTvSession = TvServerHidlClient::connect(CONNECT_TYPE_HAL); + mTvSession->setListener(this); + + int hdmiPorts = getHdmiPorts(); + int count = 0; + while (hdmiPorts !=0) { + if (count > HDMI_MAX_SUPPORT_NUM - 1) { + ALOGE("max support num:%d, but now count:%d", HDMI_MAX_SUPPORT_NUM, count); + break; + } + + mHdmiPorts[count++] = (hdmiPorts%10); + hdmiPorts = hdmiPorts/10; + } + + ALOGI("get hdmi ports:%d, port count:%d", hdmiPorts, count); +} + +TvInputIntf::~TvInputIntf() +{ + mTvSession.clear(); +} + +int TvInputIntf::setTvObserver ( TvPlayObserver *ob ) +{ + //ALOGI("setTvObserver:%p", ob); + mpObserver = ob; + return 0; +} + +void TvInputIntf::notify(const tv_parcel_t &parcel) +{ + source_connect_t srcConnect; + srcConnect.msgType = parcel.msgType; + srcConnect.source = parcel.bodyInt[0]; + srcConnect.state = parcel.bodyInt[1]; + + //ALOGI("notify type:%d, %p", srcConnect.msgType, mpObserver); + if (mpObserver != NULL) + mpObserver->onTvEvent(srcConnect); +} + +int TvInputIntf::startTv() +{ + return mTvSession->startTv(); +} + +int TvInputIntf::stopTv() +{ + return mTvSession->stopTv(); +} + +int TvInputIntf::switchSourceInput(tv_source_input_t source_input) +{ + return mTvSession->switchInputSrc(source_input); +} + +int TvInputIntf::getSourceConnectStatus(tv_source_input_t source_input) +{ + return mTvSession->getInputSrcConnectStatus(source_input); +} + +int TvInputIntf::getCurrentSourceInput() +{ + return mTvSession->getCurrentInputSrc(); +} + +int TvInputIntf::getHdmiAvHotplugDetectOnoff() +{ + return mTvSession->getHdmiAvHotplugStatus(); +} + +int TvInputIntf::getSupportInputDevices(int *devices, int *count) +{ + std::string serverDevices = mTvSession->getSupportInputDevices(); + const char *input_list = serverDevices.c_str(); + ALOGD("getAllTvDevices input list = %s", input_list); + + int len = 0; + const char *seg = ","; + char *pT = strtok((char*)input_list, seg); + while (pT) { + len ++; + *devices = atoi(pT); + ALOGD("devices: %d: %d", len , *devices); + devices ++; + pT = strtok(NULL, seg); + } + *count = len; + return 0; + +} + +int TvInputIntf::getHdmiPorts() +{ + return mTvSession->getHdmiPorts(); +} + +int TvInputIntf::getHdmiPort(tv_source_input_t source_input) { + if (source_input > SOURCE_HDMI4) { + ALOGE("input source:%d > max hdmi source4: %d", (int)source_input , SOURCE_HDMI4); + return -1; + } + return mHdmiPorts[source_input - SOURCE_HDMI1]; +} + diff --git a/TvInputIntf.h b/TvInputIntf.h new file mode 100644 index 0000000..62809ec --- a/dev/null +++ b/TvInputIntf.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * @author Tellen Yu + * @version 1.0 + * @date 2018/1/12 + * @par function description: + * - 1 tv_input hal to tvserver interface + */ + +#ifndef _ANDROID_TV_INPUT_INTERFACE_H_ +#define _ANDROID_TV_INPUT_INTERFACE_H_ + +#include "TvServerHidlClient.h" + +using namespace android; + +#define HDMI_MAX_SUPPORT_NUM 4 + +typedef enum tv_source_input_e { + SOURCE_INVALID = -1, + SOURCE_TV = 0, + SOURCE_AV1, + SOURCE_AV2, + SOURCE_YPBPR1, + SOURCE_YPBPR2, + SOURCE_HDMI1, + SOURCE_HDMI2, + SOURCE_HDMI3, + SOURCE_HDMI4, + SOURCE_VGA, + SOURCE_MPEG, + SOURCE_DTV, + SOURCE_SVIDEO, + SOURCE_IPTV, + SOURCE_DUMMY, + SOURCE_SPDIF, + SOURCE_ADTV, + SOURCE_MAX, +} tv_source_input_t; + +typedef struct source_connect_s { + int msgType; + int source; + int state; +} source_connect_t; + +class TvPlayObserver { +public: + TvPlayObserver() {}; + virtual ~TvPlayObserver() {}; + virtual void onTvEvent (const source_connect_t &scrConnect) = 0; +}; + +class TvInputIntf : public TvListener { +public: + TvInputIntf(); + ~TvInputIntf(); + int startTv(); + int stopTv(); + int switchSourceInput(tv_source_input_t source_input); + int getSourceConnectStatus(tv_source_input_t source_input); + int getCurrentSourceInput(); + int getHdmiAvHotplugDetectOnoff(); + int setTvObserver (TvPlayObserver *ob); + int getSupportInputDevices(int *devices, int *count); + int getHdmiPorts(); + int getHdmiPort(tv_source_input_t source_input); + virtual void notify(const tv_parcel_t &parcel); + +private: + sp mTvSession; + TvPlayObserver *mpObserver; + + int mHdmiPorts[HDMI_MAX_SUPPORT_NUM];// the length of hdmi_port should be equal to max_port_num +}; + +#endif/*_ANDROID_TV_INPUT_INTERFACE_H_*/ diff --git a/TvPlay.cpp b/TvPlay.cpp deleted file mode 100644 index 4f2f714..0000000 --- a/TvPlay.cpp +++ b/dev/null @@ -1,145 +0,0 @@ -#define LOG_TAG "TvPlay" - -#include -#include -#include "TvPlay.h" -#include "tvcmd.h" -#include - -TvPlay::TvPlay() -{ - mpObserver = NULL; - tvSession = TvClient::connect(); - tvSession->setListener(this); - mHdmiPorts = getHdmiPorts(); - - if ( mHdmiPorts >= pow(10, (max_port_num-1))) - hdmi_port[3] = mHdmiPorts/pow(10, (max_port_num-1)); - else - hdmi_port[3] = 0;//in this case,there is only 3 hdmi_in ports - hdmi_port[2] = (mHdmiPorts -hdmi_port[3]*1000)/100; - hdmi_port[1] = (mHdmiPorts -hdmi_port[3]*1000-hdmi_port[2]*100)/10; - hdmi_port[0] = mHdmiPorts -hdmi_port[3]*1000-hdmi_port[2]*100-hdmi_port[1]*10; -} - -TvPlay::~TvPlay() -{ - tvSession.clear(); -} - -int TvPlay::setTvObserver ( TvPlayObserver *ob ) -{ - mpObserver = ob; - return 0; -} - -void TvPlay::notify(int32_t msgType, const Parcel &p) -{ - ALOGD("TvPlay-------notify-------"); - if (mpObserver != NULL) - mpObserver->onTvEvent(msgType, p); -} - -int TvPlay::StartTv() -{ - Parcel p, r; - p.writeInt32(START_TV); - tvSession->processCmd(p, &r); - return r.readInt32(); -} - -int TvPlay::StopTv() -{ - Parcel p, r; - p.writeInt32(STOP_TV); - tvSession->processCmd(p, &r); - return r.readInt32(); -} - -int TvPlay::SwitchSourceInput(tv_source_input_t source_input) -{ - Parcel p, r; - p.writeInt32(SET_SOURCE_INPUT); - p.writeInt32(source_input); - tvSession->processCmd(p, &r); - return r.readInt32(); -} - -int TvPlay::DoSuspend(int type) -{ - Parcel p, r; - p.writeInt32(DO_SUSPEND); - p.writeInt32(type); - tvSession->processCmd(p, &r); - return r.readInt32(); -} - -int TvPlay::DoResume(int type) -{ - Parcel p, r; - p.writeInt32(DO_RESUME); - p.writeInt32(type); - tvSession->processCmd(p, &r); - return r.readInt32(); -} - -int TvPlay::GetSourceConnectStatus(tv_source_input_t source_input) -{ - Parcel p, r; - p.writeInt32(GET_SOURCE_CONNECT_STATUS); - p.writeInt32(source_input); - tvSession->processCmd(p, &r); - return r.readInt32(); -} - -int TvPlay::GetCurrentSourceInput() -{ - Parcel p, r; - p.writeInt32(GET_CURRENT_SOURCE_INPUT_VIRTUAL); - tvSession->processCmd(p, &r); - return r.readInt32(); -} - -int TvPlay::GetHdmiAvHotplugDetectOnoff() -{ - Parcel p, r; - p.writeInt32(HDMIAV_HOTPLUGDETECT_ONOFF); - tvSession->processCmd(p, &r); - return r.readInt32(); -} - -int TvPlay::getAllTvDevices(int *devices, int *count) -{ - Parcel p, r; - p.writeInt32(GET_ALL_TV_DEVICES); - tvSession->processCmd(p, &r); - const char *input_list = r.readCString(); - ALOGD("input_list = %s", input_list); - - int len = 0; - const char *seg = ","; - char *pT = strtok((char*)input_list, seg); - while (pT) { - len ++; - *devices = atoi(pT); - ALOGD("devices: %d: %d", len , *devices); - devices ++; - pT = strtok(NULL, seg); - } - *count = len; - return 0; -} - -int TvPlay::getHdmiPorts() -{ - Parcel p, r; - p.writeInt32(GET_HDMI_PORTS); - tvSession->processCmd(p, &r); - - return r.readInt32(); -} - -int TvPlay::getHdmiPort(tv_source_input_t source_input) { - return mHdmiPorts == 0 ? 0 : hdmi_port[source_input - SOURCE_HDMI1]; -} - diff --git a/TvPlay.h b/TvPlay.h deleted file mode 100644 index 57493d6..0000000 --- a/TvPlay.h +++ b/dev/null @@ -1,76 +0,0 @@ -#ifndef _ANDROID_TV_PLAY_H_ -#define _ANDROID_TV_PLAY_H_ - -#ifdef __cplusplus -//extern "C" { -#endif - -#include - -typedef enum tv_source_input_e { - SOURCE_INVALID = -1, - SOURCE_TV = 0, - SOURCE_AV1, - SOURCE_AV2, - SOURCE_YPBPR1, - SOURCE_YPBPR2, - SOURCE_HDMI1, - SOURCE_HDMI2, - SOURCE_HDMI3, - SOURCE_HDMI4, - SOURCE_VGA, - SOURCE_MPEG, - SOURCE_DTV, - SOURCE_SVIDEO, - SOURCE_IPTV, - SOURCE_DUMMY, - SOURCE_SPDIF, - SOURCE_ADTV, - SOURCE_MAX, -} tv_source_input_t; - -typedef enum tv_source_type_e { - TYPE_REAL, - TYPE_VIRTUAL, -} tv_source_type_t; - -class TvPlayObserver { -public: - TvPlayObserver() {}; - virtual ~TvPlayObserver() {}; - virtual void onTvEvent (int32_t msgType, const Parcel &p) = 0; -}; - -class TvPlay : public TvListener { -public: - TvPlay(); - ~TvPlay(); - int StartTv(); - int StopTv(); - int SwitchSourceInput(tv_source_input_t source_input); - //type , 1 is instaboot suspend - int DoSuspend(int type); - int DoResume(int type); - int GetSourceConnectStatus(tv_source_input_t source_input); - int GetCurrentSourceInput(); - int GetHdmiAvHotplugDetectOnoff(); - int setTvObserver (TvPlayObserver *ob); - int getAllTvDevices(int *devices, int *count); - int getHdmiPorts(); - int getHdmiPort(tv_source_input_t source_input); - virtual void notify(int32_t msgType, const Parcel &p); - - sp tvSession; - -private: - TvPlayObserver *mpObserver; - int mHdmiPorts; - int max_port_num = 4; - int hdmi_port[4];// the length of hdmi_port should be equal to max_port_num -}; - -#ifdef __cplusplus -//} -#endif - -#endif/*_ANDROID_TV_PLAY_H_*/ diff --git a/tv_callback.h b/tv_callback.h deleted file mode 100644 index c024237..0000000 --- a/tv_callback.h +++ b/dev/null @@ -1,17 +0,0 @@ -#ifndef TV_CALLBACK -#define TV_CALLBACK -#include "TvPlay.h" -class TvCallback : public TvPlayObserver { -public: - TvCallback(void *data) - { - mPri = data; - } - ~TvCallback() {} - void onTvEvent (int32_t msgType, const Parcel &p); - -private: - void *mPri; -}; -#endif - 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 #include -#include "TvPlay.h" -#include "tv_callback.h" +#include "tv_input.h" #include #include #include @@ -35,62 +34,67 @@ #endif #include -#include #include #include -/*****************************************************************************/ -#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(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, + } +}; diff --git a/tv_input.h b/tv_input.h new file mode 100644 index 0000000..e48992c --- a/dev/null +++ b/tv_input.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * @author Tellen Yu + * @version 1.0 + * @date 2018/1/12 + * @par function description: + * - 1 tv input hal + */ + +#ifndef _ANDROID_TV_INPUT_HAL_H_ +#define _ANDROID_TV_INPUT_HAL_H_ + +#ifdef __cplusplus +//extern "C" { +#endif + +#include "TvInputIntf.h" +#include "aml_screen.h" + +#define LOGD(...) \ +{ \ +__android_log_print(ANDROID_LOG_DEBUG, "tv_input", __VA_ARGS__); } + +#ifndef container_of +#define container_of(ptr, type, member) \ + (type *)((char*)(ptr) - offsetof(type, member)) +#endif + +class EventCallback : public TvPlayObserver { +public: + EventCallback(void *data) { + mPri = data; + } + + ~EventCallback() {} + + void onTvEvent (const source_connect_t &scrConnect); +private: + void *mPri; +}; + +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; + TvInputIntf *mpTv; + EventCallback *eventCallback; +} tv_input_private_t; + +enum { + STREAM_ID_NORMAL = 1, + STREAM_ID_FRAME_CAPTURE = 2, +}; + +void channelControl(tv_input_private_t *priv, bool opsStart, int device_id); +int notifyDeviceStatus(tv_input_private_t *priv, tv_source_input_t inputSrc, int type); +void initTvDevices(tv_input_private_t *priv); + +#ifdef __cplusplus +//} +#endif + +#endif /*_ANDROID_TV_INPUT_HAL_H_*/ + -- cgit