author | Xindong Xu <xindong.xu@amlogic.com> | 2018-02-23 09:29:21 (GMT) |
---|---|---|
committer | Xindong Xu <xindong.xu@amlogic.com> | 2018-02-23 10:29:11 (GMT) |
commit | e9e90a1efcb1e2904ed38addb6ffe25445635829 (patch) | |
tree | 3ad708c474e48c4e57732f211f1b7803b5caca05 | |
parent | 16b9c77617237cf31075f3abea7c0ddf6b18926e (diff) | |
download | ampere-e9e90a1efcb1e2904ed38addb6ffe25445635829.zip ampere-e9e90a1efcb1e2904ed38addb6ffe25445635829.tar.gz ampere-e9e90a1efcb1e2904ed38addb6ffe25445635829.tar.bz2 |
tvserver: init from trunk 20180223 [1/1]
PD# NONE
init from trunk 20180223 793e93d3ca5ae906512d5687df47782b863b4eaa
Change-Id: I93c45cbecb139da67a9b1461e984cb58b5eaa32e
146 files changed, 50722 insertions, 0 deletions
diff --git a/tv/tvserver/Android.mk b/tv/tvserver/Android.mk new file mode 100644 index 0000000..6546204 --- a/dev/null +++ b/tv/tvserver/Android.mk @@ -0,0 +1,8 @@ +# Copyright (c) 2014 Amlogic, Inc. All rights reserved. +# +# This source code is subject to the terms and conditions defined in the +# file 'LICENSE' which is part of this source code package. +# +# Description: makefile + +include $(call all-subdir-makefiles) diff --git a/tv/tvserver/LICENSE b/tv/tvserver/LICENSE new file mode 100644 index 0000000..44c49b9 --- a/dev/null +++ b/tv/tvserver/LICENSE @@ -0,0 +1,23 @@ +// Copyright (C) 2014 Amlogic, Inc. All rights reserved. +// +// All information contained herein is Amlogic confidential. +// +// This software is provided to you pursuant to Software License +// Agreement (SLA) with Amlogic Inc ("Amlogic"). This software may be +// used only in accordance with the terms of this agreement. +// +// Redistribution and use in source and binary forms, with or without +// modification is strictly prohibited without prior written permission +// from Amlogic. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tv/tvserver/libtv/Android.mk b/tv/tvserver/libtv/Android.mk new file mode 100644 index 0000000..4ee13fa --- a/dev/null +++ b/tv/tvserver/libtv/Android.mk @@ -0,0 +1,242 @@ +# Copyright (c) 2014 Amlogic, Inc. All rights reserved. +# +# This source code is subject to the terms and conditions defined in the +# file 'LICENSE' which is part of this source code package. +# +# Description: makefile + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +DVB_PATH := $(wildcard external/dvb) +ifeq ($(DVB_PATH), ) + DVB_PATH := $(wildcard $(BOARD_AML_VENDOR_PATH)/external/dvb) +endif +ifeq ($(DVB_PATH), ) + DVB_PATH := $(wildcard $(BOARD_AML_VENDOR_PATH)/dvb) +endif + +LIB_ZVBI_PATH := $(wildcard external/libzvbi) +ifeq ($(LIB_ZVBI_PATH), ) + LIB_ZVBI_PATH := $(wildcard $(BOARD_AML_VENDOR_PATH)/external/libzvbi) +endif + +LIB_TV_UTILS := $(LOCAL_PATH)/../tvutils +LIB_TV_BINDER := $(LOCAL_PATH)/../../frameworks/libtvbinder + +AM_LIBPLAYER_PATH := $(wildcard $(BOARD_AML_VENDOR_PATH)/frameworks/av/LibPlayer) +LIB_SQLITE_PATH := $(wildcard external/sqlite) + +#support android and amaudio +BOARD_TV_AUDIO_TYPE := amaudio + +#support builtin and external +BOARD_TV_AUDIO_AMAUDIO_LIB_TYPE := external + + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + tv/CAutoPQparam.cpp \ + tv/AutoBackLight.cpp \ + tv/CBootvideoStatusDetect.cpp \ + tv/CTvEv.cpp \ + tv/CTvSubtitle.cpp \ + tv/CTvTime.cpp \ + tv/CTv.cpp \ + tv/CTvBooking.cpp \ + tv/CTvVchipCheck.cpp \ + tv/CTvScreenCapture.cpp \ + tv/CAv.cpp \ + tv/CTvDmx.cpp \ + tv/CTvFactory.cpp \ + tvin/CTvin.cpp \ + tvin/CDevicesPollStatusDetect.cpp \ + tvin/CHDMIRxManager.cpp \ + tvdb/CTvDimension.cpp \ + tv/CTvPlayer.cpp \ + tvdb/CTvChannel.cpp \ + tvdb/CTvEvent.cpp \ + tvdb/CTvGroup.cpp \ + tvdb/CTvProgram.cpp \ + tvdb/CTvRegion.cpp \ + tvdb/CTvDatabase.cpp \ + tv/CTvScanner.cpp \ + tv/CFrontEnd.cpp \ + tv/CTvEpg.cpp \ + tv/CTvRrt.cpp \ + tv/CTvEas.cpp \ + tv/CTvRecord.cpp \ + vpp/CVpp.cpp \ + audio/CTvAudio.cpp \ + audio/audio_effect.cpp \ + audio/audio_alsa.cpp \ + audio/CAudioCustomerCtrl.cpp \ + tvsetting/audio_cfg.cpp \ + tvsetting/CTvSetting.cpp \ + tvsetting/TvKeyData.cpp \ + version/version.cpp \ + fbcutils/CFbcCommunication.cpp \ + fbcutils/fbcutils.cpp \ + gpio/CTvGpio.cpp + +LOCAL_SHARED_LIBRARIES := \ + libui \ + libutils \ + libcutils \ + libnetutils \ + libsqlite \ + libmedia \ + libtinyxml \ + liblog \ + libaudioclient \ + libbinder + +LOCAL_SHARED_LIBRARIES += \ + libtvbinder \ + libsystemcontrolservice + +#DVB define +ifeq ($(BOARD_HAS_ADTV),true) +LOCAL_CFLAGS += -DSUPPORT_ADTV + +LOCAL_SHARED_LIBRARIES += \ + libzvbi \ + libntsc_decode \ + libam_mw \ + libam_adp \ + libam_ver + +LOCAL_C_INCLUDES += \ + $(DVB_PATH)/include/am_adp \ + $(DVB_PATH)/include/am_mw \ + $(DVB_PATH)/include/am_ver \ + $(DVB_PATH)/android/ndk/include \ + $(LIB_ZVBI_PATH)/ntsc_decode/include \ + $(LIB_ZVBI_PATH)/ntsc_decode/include/ntsc_dmx \ + $(LIB_ZVBI_PATH)/src + +endif + +ifeq ($(strip $(BOARD_TV_AUDIO_AMAUDIO_LIB_TYPE)), external) + LOCAL_SHARED_LIBRARIES += libTVaudio +endif + +ifeq ($(strip $(BOARD_ALSA_AUDIO)),tiny) + LOCAL_SHARED_LIBRARIES += libtinyalsa +else + LOCAL_SHARED_LIBRARIES += libasound +endif + +LOCAL_STATIC_LIBRARIES += \ + libz \ + libtv_utils \ + libjsoncpp + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../tvfbclinker/include \ + $(LIB_TV_UTILS)/include + +LOCAL_SHARED_LIBRARIES += libtv_linker + +LOCAL_CFLAGS := \ + -fPIC -fsigned-char -D_POSIX_SOURCE \ + -DALSA_CONFIG_DIR=\"/system/usr/share/alsa\" \ + -DALSA_PLUGIN_DIR=\"/system/usr/lib/alsa-lib\" \ + -DALSA_DEVICE_DIRECTORY=\"/dev/snd/\" + +LOCAL_CFLAGS += -DANDROID_PLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) + +ifeq ($(SOURCE_DEDTECT_ON),true) + LOCAL_CFLAGS += -DSOURCE_DETECT_ENABLE +endif + +ifeq ($(TARGET_SIMULATOR),true) + LOCAL_CFLAGS += -DSINGLE_PROCESS +endif + +ifeq ($(strip $(BOARD_ALSA_AUDIO)),tiny) + LOCAL_CFLAGS += -DBOARD_ALSA_AUDIO_TINY +endif + +ifeq ($(strip $(BOARD_TV_AUDIO_TYPE)),amaudio) + LOCAL_CFLAGS += -DCC_TV_AUDIO_TYPE_AMAUDIO=1 +endif + +ifeq ($(strip $(BOARD_TV_AUDIO_TYPE)),android) + LOCAL_SRC_FILES += audio/audio_android.cpp + LOCAL_CFLAGS += -DCC_TV_AUDIO_TYPE_ANDROID=1 +endif + +LOCAL_C_INCLUDES += \ + external/tinyxml \ + $(LIB_TV_BINDER)/include \ + $(LIB_SQLITE_PATH)/dist \ + system/media/audio_effects/include \ + $(BOARD_AML_VENDOR_PATH)/frameworks/services/systemcontrol/PQ/include + +ifeq ($(strip $(BOARD_TV_AUDIO_AMAUDIO_LIB_TYPE)), external) + LOCAL_C_INCLUDES += hardware/amlogic/audio/libTVaudio +endif + +ifeq ($(strip $(BOARD_ALSA_AUDIO)),tiny) + LOCAL_C_INCLUDES += external/tinyalsa/include +else + LOCAL_C_INCLUDES += external/alsa-lib/include +endif + +ifeq ($(wildcard hardware/amlogic/media),hardware/amlogic/media) +$(info "have hardware/amlogic/media") +AML_DEC_PATH := $(wildcard hardware/amlogic/media) +LOCAL_C_INCLUDES += \ + $(AML_DEC_PATH)/amadec/include \ + $(AML_DEC_PATH)/amcodec/include +else +AML_DEC_PATH := $(wildcard $(BOARD_AML_VENDOR_PATH)/frameworks/av/LibPlayer) +LOCAL_C_INCLUDES += \ + $(AML_DEC_PATH)/amadec/include \ + $(AML_DEC_PATH)/amcodec/include \ + $(AML_DEC_PATH)/amffmpeg \ + $(AML_DEC_PATH)/amplayer +endif + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/tvdb \ + $(LOCAL_PATH)/tv \ + $(LOCAL_PATH)/gpio \ + $(LOCAL_PATH)/include \ + external/jsoncpp/include + +LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog + +LOCAL_PRELINK_MODULE := false + +# version +ifeq ($(strip $(BOARD_TVAPI_NO_VERSION)),) + $(shell cd $(LOCAL_PATH);touch version/version.cpp) + LIBTVSERVICE_GIT_VERSION="$(shell cd $(LOCAL_PATH);git log | grep commit -m 1 | cut -d' ' -f 2)" + LIBTVSERVICE_GIT_UNCOMMIT_FILE_NUM=$(shell cd $(LOCAL_PATH);git diff | grep +++ -c) + LIBTVSERVICE_GIT_BRANCH="$(shell cd $(LOCAL_PATH);git branch | grep \* -m 1)" + LIBTVSERVICE_LAST_CHANGED="$(shell cd $(LOCAL_PATH);git log | grep Date -m 1)" + LIBTVSERVICE_BUILD_TIME=" $(shell date)" + LIBTVSERVICE_BUILD_NAME=" $(shell echo ${LOGNAME})" + + LOCAL_CFLAGS+=-DHAVE_VERSION_INFO + LOCAL_CFLAGS+=-DLIBTVSERVICE_GIT_VERSION=\"${LIBTVSERVICE_GIT_VERSION}${LIBTVSERVICE_GIT_DIRTY}\" + LOCAL_CFLAGS+=-DLIBTVSERVICE_GIT_UNCOMMIT_FILE_NUM=${LIBTVSERVICE_GIT_UNCOMMIT_FILE_NUM} + LOCAL_CFLAGS+=-DLIBTVSERVICE_GIT_BRANCH=\"${LIBTVSERVICE_GIT_BRANCH}\" + LOCAL_CFLAGS+=-DLIBTVSERVICE_LAST_CHANGED=\"${LIBTVSERVICE_LAST_CHANGED}\" + LOCAL_CFLAGS+=-DLIBTVSERVICE_BUILD_TIME=\"${LIBTVSERVICE_BUILD_TIME}\" + LOCAL_CFLAGS+=-DLIBTVSERVICE_BUILD_NAME=\"${LIBTVSERVICE_BUILD_NAME}\" + LOCAL_CFLAGS+=-DTVAPI_BOARD_VERSION=\"$(TVAPI_TARGET_BOARD_VERSION)\" +endif + +LOCAL_CFLAGS += -DTARGET_BOARD_$(strip $(TVAPI_TARGET_BOARD_VERSION)) +LOCAL_MODULE:= libtv +LOCAL_LDFLAGS := -shared + +ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK) +LOCAL_PROPRIETARY_MODULE := true +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/tv/tvserver/libtv/audio/CAudioCustomerCtrl.cpp b/tv/tvserver/libtv/audio/CAudioCustomerCtrl.cpp new file mode 100644 index 0000000..d41ab9a --- a/dev/null +++ b/tv/tvserver/libtv/audio/CAudioCustomerCtrl.cpp @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CAudioCustomerCtrl" + +#include "CAudioCustomerCtrl.h" +#include <dlfcn.h> +#include "CTvLog.h" +#include "tvsetting/audio_cfg.h" + +CAudioCustomerCtrl::CAudioCustomerCtrl() +{ + gExternalDacLibHandler = NULL; + mpDacMuteFun = NULL; + mpDacMainVolFun = NULL; + mpDacBalanceFun = NULL; + mpSetSourceTypeFun = NULL; +} + +CAudioCustomerCtrl::~CAudioCustomerCtrl() +{ + UnLoadExternalDacLib(); +} + +int CAudioCustomerCtrl::UnLoadExternalDacLib(void) +{ + if (gExternalDacLibHandler != NULL) { + dlclose(gExternalDacLibHandler); + gExternalDacLibHandler = NULL; + } + + mpDacMuteFun = NULL; + mpDacMainVolFun = NULL; + mpDacBalanceFun = NULL; + mpSetSourceTypeFun = NULL; + + return 0; +} + +int CAudioCustomerCtrl::LoadExternalDacLib(void) +{ + char *error; + + LOGD("%s, entering...\n", __FUNCTION__); + + if (gExternalDacLibHandler != NULL) { + return 0; + } + + const char *config_value = GetAudExtDacLibPath(); + gExternalDacLibHandler = dlopen(config_value, RTLD_NOW); + if (!gExternalDacLibHandler) { + LOGE("%s, failed to load external dac lib (%s)\n", __FUNCTION__, config_value); + goto Error; + } + + mpDacMuteFun = (int(*)(int))dlsym(gExternalDacLibHandler, "HandleDacMute"); + if (mpDacMuteFun == NULL) { + LOGE("%s, fail find fun mpDacMuteFun()\n", __FUNCTION__); + goto Error; + } + mpDacMainVolFun = (int(*)(int))dlsym(gExternalDacLibHandler, "HandleDacMainVolume"); + if (mpDacMainVolFun == NULL) { + LOGE("%s, fail find fun HandleDacMainVolume()\n", __FUNCTION__); + goto Error; + } + mpDacBalanceFun = (int(*)(int))dlsym(gExternalDacLibHandler, "HandleDacBalance"); + if (mpDacBalanceFun == NULL) { + LOGE("%s, fail find fun HandleDacBalance()\n", __FUNCTION__); + goto Error; + } + mpSetSourceTypeFun = (int(*)(int))dlsym(gExternalDacLibHandler, "HandleAudioSourceType"); + if (mpSetSourceTypeFun == NULL) { + LOGE("%s, fail find fun HandleAudioSourceType()\n", __FUNCTION__); + goto Error; + } + + return 0; + +Error: // + mpDacMuteFun = NULL; + mpDacMainVolFun = NULL; + mpDacBalanceFun = NULL; + mpSetSourceTypeFun = NULL; + + if (gExternalDacLibHandler != NULL) { + dlclose(gExternalDacLibHandler); + gExternalDacLibHandler = NULL; + } + return -1; +} + +// 0 mute, 1 unmute +int CAudioCustomerCtrl::SetMute(int mute) +{ + int ret = LoadExternalDacLib(); + if (mpDacMuteFun != NULL) { + ret = (*mpDacMuteFun)(mute); + } + return ret; +} + +int CAudioCustomerCtrl::SetVolumeBar(int vol) +{ + int ret = LoadExternalDacLib(); + if (mpDacMainVolFun != NULL) { + LOGD("%s, call external dac lib HandleDacMainVolume (para = %d).\n", __FUNCTION__, vol); + ret = (*mpDacMainVolFun)(vol); + } + return ret; +} + +int CAudioCustomerCtrl::SetBlance(int balance) +{ + int ret = LoadExternalDacLib(); + if (mpDacBalanceFun != NULL) { + LOGD("%s, call external dac lib HandleDacBalance (para = %d).\n", __FUNCTION__, balance); + ret = (*mpDacBalanceFun)(balance); + } + return ret; +} + +int CAudioCustomerCtrl::SetSource(int source) +{ + int ret = LoadExternalDacLib(); + if (mpSetSourceTypeFun != NULL) { + LOGD("%s, call external dac lib HandleAudioSourceType (para = %d).\n", __FUNCTION__, source); + ret = (*mpSetSourceTypeFun)(source); + } + return ret; +} diff --git a/tv/tvserver/libtv/audio/CAudioCustomerCtrl.h b/tv/tvserver/libtv/audio/CAudioCustomerCtrl.h new file mode 100644 index 0000000..e98fc82 --- a/dev/null +++ b/tv/tvserver/libtv/audio/CAudioCustomerCtrl.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __AUDIO_CUSTOMER_CTRL_H__ +#define __AUDIO_CUSTOMER_CTRL_H__ + +typedef int (*TYPE_DacMute_FUN)(int mute_state); +typedef int (*TYPE_DacMainVolume_FUN)(int vol); +typedef int (*TYPE_DacBalance_FUN)(int balance_val); +typedef int (*TYPE_AudioSourceType_FUN)(int source_type); + +class CAudioCustomerCtrl { +public: + static const int MUTE = 0; + static const int UNMUTE = 1; + + CAudioCustomerCtrl(); + ~CAudioCustomerCtrl(); + int LoadExternalDacLib(void); + int UnLoadExternalDacLib(void); + int SendCmdToOffBoardCustomerLibExternalDac(int, int); + int SetMute(int mute); + int SetVolumeBar(int vol); + int SetBlance(int balance); + int SetSource(int source); + +private: + void *gExternalDacLibHandler; + TYPE_DacMute_FUN mpDacMuteFun; + TYPE_DacMainVolume_FUN mpDacMainVolFun; + TYPE_DacBalance_FUN mpDacBalanceFun; + TYPE_AudioSourceType_FUN mpSetSourceTypeFun; +}; +#endif diff --git a/tv/tvserver/libtv/audio/CTvAudio.cpp b/tv/tvserver/libtv/audio/CTvAudio.cpp new file mode 100644 index 0000000..559cd32 --- a/dev/null +++ b/tv/tvserver/libtv/audio/CTvAudio.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvAudio" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <pthread.h> +#include <fcntl.h> + +#include <android/log.h> +#include <cutils/properties.h> + +#include "../tvsetting/CTvSetting.h" +#include <tvutils.h> +#include <CFile.h> +#include "audio_effect.h" +#include "CTvAudio.h" + +#include "CTvLog.h" + +CTvAudio::CTvAudio() +{ +} + +CTvAudio::~CTvAudio() +{ +} + diff --git a/tv/tvserver/libtv/audio/CTvAudio.h b/tv/tvserver/libtv/audio/CTvAudio.h new file mode 100644 index 0000000..8e4672b --- a/dev/null +++ b/tv/tvserver/libtv/audio/CTvAudio.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __TV_AUDIO_API_H__ +#define __TV_AUDIO_API_H__ + + +#include "tvsetting/audio_cfg.h" +#include "audio_alsa.h" +#include "audio_effect.h" +#include <audio_amaudio.h> +#include "CAudioCustomerCtrl.h" + +enum CC_AUDIO_SWITCH_STATUS { + CC_SWITCH_OFF, + CC_SWITCH_ON, +}; + +enum CC_AMAUDIO_OUT_MODE { + CC_AMAUDIO_OUT_MODE_DIRECT, + CC_AMAUDIO_OUT_MODE_INTER_MIX, + CC_AMAUDIO_OUT_MODE_DIRECT_MIX, +}; + +static const int CC_SPDIF_MODE_PCM = 0; +static const int CC_SPDIF_MODE_RAW = 1; + +static const int CC_MIN_SOUND_VOL = 0; +static const int CC_MAX_SOUND_VOL = 100; +static const int CC_DEF_SOUND_VOL = 10; +static const int CC_MIN_SUPPERBASS_VOL = 0; +static const int CC_MAX_SUPPERBASS_VOL = 100; +static const int CC_DEF_SUPPERBASS_VOL = 50; + +static const int CC_DEF_BASS_TREBLE_VOL = 50; +static const int CC_EQ_BASS_IND = 1; +static const int CC_EQ_TREBLE_IND = 3; +static const int CC_EQ_DEF_UI_MIN_GAIN = 0; +static const int CC_EQ_DEF_UI_MAX_GAIN = 100; +static const int CC_MIN_EQ_GAIN_VAL = -10; +static const int CC_MAX_EQ_GAIN_VAL = 10; + +static const int CC_LUT_BUF_MASTER = 0; +static const int CC_LUT_BUF_SUPPERBASS = 1; +static const int CC_LUT_BUF_SIZE = 101; +static const int CC_NO_LINE_POINTS_MAX_CNT = 101; + + +enum CC_AUD_SOUND_MODE { + CC_SOUND_MODE_START = 0, + CC_SOUND_MODE_STD = 0, + CC_SOUND_MODE_MUSIC, + CC_SOUND_MODE_NEWS, + CC_SOUND_MODE_THEATER, + CC_SOUND_MODE_USER, + CC_SOUND_MODE_END = CC_SOUND_MODE_USER +}; + +enum CC_AUD_EQ_MODE { + CC_EQ_MODE_START = 0, + CC_EQ_MODE_NOMAL = 0, + CC_EQ_MODE_POP, + CC_EQ_MODE_JAZZ, + CC_EQ_MODE_ROCK, + CC_EQ_MODE_CLASSIC, + CC_EQ_MODE_DANCE, + CC_EQ_MODE_PARTY, + CC_EQ_MODE_BASS, + CC_EQ_MODE_TREBLE, + CC_EQ_MODE_CUSTOM, + CC_EQ_MODE_END = CC_EQ_MODE_CUSTOM +}; + +class CTvAudio { +public: + CTvAudio(); + ~CTvAudio(); +}; +#endif //__TV_AUDIO_API_H__ diff --git a/tv/tvserver/libtv/audio/audio_alsa.cpp b/tv/tvserver/libtv/audio/audio_alsa.cpp new file mode 100644 index 0000000..a9dafd3 --- a/dev/null +++ b/tv/tvserver/libtv/audio/audio_alsa.cpp @@ -0,0 +1,878 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CAudioAlsa" +//#define LOG_NDEBUG 0 + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <getopt.h> +#include <pthread.h> +#include <stdarg.h> +#include <ctype.h> +#include <math.h> +#include <errno.h> +#include <assert.h> +#include <fcntl.h> +#include <tinyalsa/asoundlib.h> +#include "fbcutils/CFbcCommunication.h" +#include <sys/poll.h> +#include "tvsetting/audio_cfg.h" +#include "audio_alsa.h" +#include <cutils/properties.h> +#include "CTvLog.h" +#include "audio_amaudio.h" + +static const int DEFAULT_MAIN_DIGIT_LUT[] = { + // + 0, 40, 50, 60, 70, 87, 110, 120, 130, 140, // 0~9 + 150, 152, 155, 158, 161, 164, 167, 170, 173, 174, // 10~19 + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, // 20~29 + 191, 191, 192, 193, 194, 195, 196, 196, 197, 197, // 30~39 + 198, 198, 198, 199, 199, 200, 200, 201, 201, 201, // 40~49 + 202, 202, 202, 203, 203, 203, 203, 204, 204, 204, // 50~59 + 205, 205, 205, 205, 206, 206, 206, 206, 206, 207, // 60~69 + 207, 207, 207, 207, 207, 207, 207, 208, 208, 208, // 70~79 + 208, 208, 208, 208, 208, 208, 208, 208, 208, 209, // 80~89 + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, // 90~99 + 209, // 100 +}; + +static const int DEFAULT_SUPPER_BASS_DIGIT_LUT_BUF[] = { + // + 0, 122, 123, 124, 125, 126, 127, 128, 129, 130, // 0~9 + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, // 10~19 + 141, 142, 143, 144, 145, 147, 147, 148, 148, 149, // 20~29 + 149, 150, 150, 151, 151, 152, 152, 153, 153, 154, // 30~39 + 154, 155, 155, 156, 156, 157, 157, 158, 158, 159, // 40~49 + 160, 160, 160, 160, 161, 161, 161, 161, 162, 162, // 50~59 + 162, 163, 163, 163, 163, 164, 164, 164, 165, 165, // 60~69 + 165, 165, 166, 166, 166, 167, 168, 169, 170, 171, // 70~79 + 173, 174, 175, 176, 177, 179, 180, 181, 182, 183, // 80~89 + 185, 186, 187, 188, 189, 191, 192, 193, 194, 195, // 90~99 + 197 // 100 +}; + +CAudioAlsa::CAudioAlsa() +{ + int card_id; + card_id = get_aml_card(); + LOGV("[%s:%d] card_id:%d\n", __FUNCTION__, __LINE__, card_id); + mpMixer = mixer_open(card_id); + + card_id = get_USB_Audio_card(); + LOGV("[%s:%d] usb card_id:%d\n", __FUNCTION__, __LINE__, card_id); + mpUsbMixer = mixer_open(card_id); + mMainVolumeGainVal = 0; + mSupperBassVolumeGainVal = 0; + ArrayCopy(mMainDigitLutBuf, DEFAULT_MAIN_DIGIT_LUT, CC_VOL_TRANS_LUT_BUF_SIZE); + ArrayCopy(mSupperBassDigitLutBuf, DEFAULT_SUPPER_BASS_DIGIT_LUT_BUF, CC_VOL_TRANS_LUT_BUF_SIZE); +} + +CAudioAlsa::~CAudioAlsa() +{ + if (NULL != mpMixer) { + mixer_close(mpMixer); + } + + if (NULL != mpUsbMixer) { + mixer_close(mpUsbMixer); + } +} + +int CAudioAlsa::get_aml_card() +{ + int card = -1, err = 0; + int fd = -1; + char read_buf[512], *pd = NULL; + static const char *const SOUND_CARDS_PATH = "/proc/asound/cards"; + fd = open(SOUND_CARDS_PATH, O_RDONLY); + if (fd < 0) { + LOGE("ERROR: failed to open config file %s error: %d\n", SOUND_CARDS_PATH, errno); + close(fd); + return -EINVAL; + } + memset(read_buf, 0x0, 512); + err = read(fd, read_buf, 512); + if (fd < 0) { + LOGE("ERROR: failed to read config file %s error: %d\n", SOUND_CARDS_PATH, errno); + close(fd); + return -EINVAL; + } + pd = strstr(read_buf, "AML"); + card = *(pd - 3) - '0'; + close(fd); + return card; +} + +int CAudioAlsa::AudioControlSetValue(int val_count, int data_buf[], char *match_names) +{ + struct mixer_ctl *pctl; + unsigned int expected_val_count; + unsigned int value_index; + + if (NULL == mpMixer) { + LOGE("[%s:%d] Failed to open mixer\n", __FUNCTION__, __LINE__); + goto err_exit; + } + + pctl = mixer_get_ctl_by_name(mpMixer, match_names); + if (NULL == pctl) { + LOGE("[%s:%d] Failed to get mixer control for:%s\n", __FUNCTION__, __LINE__, match_names); + goto err_exit; + } + expected_val_count = mixer_ctl_get_num_values(pctl); + if (expected_val_count != (unsigned int)val_count) { + LOGE("[%s:%d] val_count != expected_val_count\n", __FUNCTION__, __LINE__); + goto err_exit; + } + for (value_index = 0; value_index < expected_val_count; value_index++) { + if (mixer_ctl_set_value(pctl, value_index, data_buf[value_index]) != 0) { + LOGE("[%s:%d] Failed to set value:%d\n", __FUNCTION__, __LINE__, value_index); + goto err_exit; + } + } + return 0; +err_exit: + return -1; +} + +int CAudioAlsa::AudioControlGetValue(int val_count, int ret_buf[], char *match_names) +{ + struct mixer_ctl *pctl; + unsigned int expected_val_count; + unsigned int value_index; + + if (NULL == mpMixer) { + LOGE("[%s:%d] Failed to open mixer\n", __FUNCTION__, __LINE__); + goto err_exit; + } + pctl = mixer_get_ctl_by_name(mpMixer, match_names); + if (NULL == pctl) { + LOGE("[%s:%d] Failed to get mixer control for:%s\n", __FUNCTION__, __LINE__, match_names); + goto err_exit; + } + expected_val_count = mixer_ctl_get_num_values(pctl); + if (expected_val_count != (unsigned int)val_count) { + LOGE("[%s:%d] val_count != expected_val_count\n", __FUNCTION__, __LINE__); + goto err_exit; + } + for (value_index = 0; value_index < expected_val_count; value_index++) { + ret_buf[value_index] = mixer_ctl_get_value(pctl, value_index); + } + return 0; +err_exit: + return -1; +} + +int CAudioAlsa::get_USB_Audio_card() +{ + int card = -1, err = 0; + int fd = -1; + char read_buf[512], *pd = NULL; + static const char *const SOUND_CARDS_PATH = "/proc/asound/cards"; + fd = open(SOUND_CARDS_PATH, O_RDONLY); + if (fd < 0) { + LOGE("ERROR: failed to open config file %s error: %d\n", SOUND_CARDS_PATH, errno); + close(fd); + return -EINVAL; + } + memset(read_buf, 0x0, 512); + err = read(fd, read_buf, 512); + if (fd < 0) { + LOGE("ERROR: failed to read config file %s error: %d\n", SOUND_CARDS_PATH, errno); + close(fd); + return -EINVAL; + } + pd = strstr(read_buf, "Receiver"); + if (pd == NULL) { + LOGE("ERROR: failed to read config file %s error: %d\n", SOUND_CARDS_PATH, errno); + close(fd); + return -EINVAL; + } + + card = *(pd - 3) - '0'; + close(fd); + return card; +} + +int CAudioAlsa::HandleUSBAudioControlValue(int val_count, int data_buf[], int match_count, char **match_names) +{ + + struct mixer_ctl *pctl; + unsigned int expected_val_count; + unsigned int match_index; + unsigned int value_index; + char card_id_str[9] = {0}; + + if (NULL == mpUsbMixer) { + LOGE("[%s:%d] Failed to open mixer\n", __FUNCTION__, __LINE__); + goto err_exit; + } + + for (match_index = 0; match_index < (unsigned int)match_count; match_index++) { + pctl = mixer_get_ctl_by_name(mpUsbMixer, match_names[match_index]); + if (NULL == pctl) { + LOGE("[%s:%d] Failed to get mixer control for:%s\n", __FUNCTION__, __LINE__, match_names[match_index]); + goto err_exit; + } + expected_val_count = mixer_ctl_get_num_values(pctl); + if (expected_val_count != (unsigned int)val_count) { + LOGE("[%s:%d] val_count != expected_val_count\n", __FUNCTION__, __LINE__); + goto err_exit; + } + for (value_index = 0; value_index < expected_val_count; value_index++) { + if (mixer_ctl_set_value(pctl, value_index, data_buf[value_index]) != 0) { + LOGE("[%s:%d] Failed to set value:%d\n", __FUNCTION__, __LINE__, value_index); + goto err_exit; + } + } + } + + return 0; +err_exit: + return -1; +} + +int CAudioAlsa::CheckVolume(int digit_vol, int digit_min __unused, int digit_max __unused, + int hd_min, int hd_max) +{ + if (digit_vol < hd_min) { + return hd_min; + } else if (digit_vol > hd_max) { + return hd_max; + } + + return digit_vol; +} + +int CAudioAlsa::GetTwoChannelVolume(int vol_buf[], + int l_min_vol __unused, int l_max_vol __unused, + int r_min_vol __unused, int r_max_vol __unused, + char *match_names, + int hd_min __unused, int hd_max __unused) +{ + vol_buf[0] = 0; + vol_buf[1] = 0; + return AudioControlGetValue(2, vol_buf, match_names); +} + +int CAudioAlsa::GetLineInMaxVol() +{ + return 127; +} + +int CAudioAlsa::GetLineOutMaxVol() +{ + return 255; +} + +#define CC_GET_ALSA_CTL_AUDIO_IN_SOURCE_NAME (0) +#define CC_GET_ALSA_CTL_INTERNAL_DAC_PGA_IN_GAIN (1) +#define CC_GET_ALSA_CTL_INTERNAL_DAC_ADC_DIGITAL_CAPTURE_VOLUME_NAME (2) +#define CC_GET_ALSA_CTL_INTERNAL_DAC_DAC_DIGITAL_PLAYBACK_VOLUME_NAME (3) +#define CC_GET_ALSA_CTL_INTERNAL_DAC_LEFT_LINEIN_SEL_NAME (4) +#define CC_GET_ALSA_CTL_INTERNAL_DAC_RIGHT_LINEIN_SEL_NAME (5) +#define CC_GET_ALSA_CTL_INTERNAL_DAC_LINEIN_CAPTURE_VOLUME_NAME (6) +#define CC_GET_ALSA_CTL_INTERNAL_DAC_LINEOUT_PLAYBACK_VOLUME_NAME (7) +#define CC_GET_ALSA_CTL_I2S_MUTE_NAME (8) +#define CC_GET_ALSA_CTL_SPDIF_MUTE_NAME (9) +#define CC_GET_ALSA_CTL_HW_RESAMPLE_NAME (10) +#define CC_GET_ALSA_CTL_EXTERNAL_DAC_MASTER_VOLUME_NAME (11) +#define CC_GET_ALSA_CTL_EXTERNAL_DAC_CH1_VOLUME_NAME (12) +#define CC_GET_ALSA_CTL_EXTERNAL_DAC_CH2_VOLUME_NAME (13) +#define CC_GET_ALSA_CTL_EXTERNAL_DAC_CH3_VOLUME_NAME (14) +#define CC_GET_ALSA_CTL_EXTERNAL_DAC_CH1_SWITCH_NAME (15) +#define CC_GET_ALSA_CTL_EXTERNAL_DAC_CH2_SWITCH_NAME (16) +#define CC_GET_ALSA_CTL_EXTERNAL_DAC_CH3_SWITCH_NAME (17) +#define CC_GET_ALSA_CTL_EXTERNAL_DAC_EQ_MODE_NAME (18) +#define CC_GET_ALSA_CTL_PCM_PLAYBACK_VOLUME (19) +#define CC_GET_ALSA_CTL_PCM_PLAYBACK_SWITCH (20) +#define CC_GET_ALSA_CTL_SETOUTPUT_SWAP (21) +#define CC_GET_ALSA_CTL_AUDIO_IN_SWITCH (22) +#define CC_SET_AUDIO_ARC_SWITCH (23) + +static char gG9AlsaNames[32][48] = { + {"Audio In Source"},//0 + {"PGA IN Gain"},//1 + {"ADC Digital Capture Volume"},//2 + {"DAC Digital Playback Volume"},//3 + {"Linein right switch"},//4 + {"Linein left switch"}, + {"ADC Digital Capture Volume"}, + {"DAC Digital Playback Volume"}, + {"Audio i2s mute"},//8 + {"Audio spdif mute"}, + {"Hardware resample enable"},//10 + {"AMP Master Volume"}, + {"AMP Ch1 Volume"},//12 + {"AMP Ch2 Volume"}, + {"AMP Ch3 Volume"}, + {"AMP Ch1 Switch"}, + {"AMP Ch2 Switch"}, + {"AMP Ch3 Switch"},//17 + {"AMP EQ Mode"}, + {"PCM Playback Volume"}, + {"PCM Playback Switch"}, + {"Output Swap"}, + {"AudioIn Switch"},//22 + {"HDMI ARC Switch"}, +}; + + +char *CAudioAlsa::GetAlsaControlName(int get_type) +{ + return gG9AlsaNames[get_type]; +} + + +int CAudioAlsa::SetAudioInSource(int source_type) +{ + int set_val = 0; + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_AUDIO_IN_SOURCE_NAME); + set_val = source_type; + return AudioControlSetValue(1, &set_val, match_names); +} + +int CAudioAlsa::GetAudioInSource(void) +{ + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_AUDIO_IN_SOURCE_NAME); + int source_type = 0; + AudioControlGetValue(1, &source_type, match_names); + return source_type; +} + +int CAudioAlsa::SetAudioInternalDacPGAInGain(int gain_l_val, int gain_r_val) +{ + int GainBuf[2] = {0, 0}; + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_PGA_IN_GAIN); + + GainBuf[0] = gain_l_val; + GainBuf[1] = gain_r_val; + if (gain_l_val < 0 || gain_l_val > 31) { + GainBuf[0] = 16; + } + if (gain_r_val < 0 || gain_r_val > 31) { + GainBuf[1] = 16; + } + + return AudioControlSetValue(2, GainBuf, match_names); +} + +int CAudioAlsa::GetAudioInternalDacPGAInGain(int *gain_l_val, int *gain_r_val) +{ + int GainBuf[2] = {0, 0}; + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_PGA_IN_GAIN); + + AudioControlGetValue(2, GainBuf, match_names); + + *gain_l_val = GainBuf[0]; + *gain_r_val = GainBuf[1]; + + return 0; +} + +int CAudioAlsa::SetAudioInternalDacADCDigitalCaptureVolume(int vol_l_val, int vol_r_val) +{ + int VolumeBuf[2] = {0, 0}; + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_ADC_DIGITAL_CAPTURE_VOLUME_NAME); + + VolumeBuf[0] = vol_l_val; + VolumeBuf[1] = vol_r_val; + if (vol_l_val < 0 || vol_l_val > 127) { + VolumeBuf[0] = 82; + } + if (vol_r_val < 0 || vol_r_val > 127) { + VolumeBuf[1] = 82; + } + + return AudioControlSetValue(2, VolumeBuf, match_names); +} + +int CAudioAlsa::GetAudioInternalDacADCDigitalCaptureVolume(int *vol_l_val, int *vol_r_val) +{ + int VolumeBuf[2] = {0, 0}; + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_ADC_DIGITAL_CAPTURE_VOLUME_NAME); + + AudioControlGetValue(2, VolumeBuf, match_names); + + *vol_l_val = VolumeBuf[0]; + *vol_r_val = VolumeBuf[1]; + + return 0; +} + +int CAudioAlsa::SetAudioInternalDacDACDigitalPlayBackVolume(int vol_l_val, int vol_r_val) +{ + int VolumeBuf[2] = {0, 0}; + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_DAC_DIGITAL_PLAYBACK_VOLUME_NAME); + + VolumeBuf[0] = vol_l_val; + VolumeBuf[1] = vol_r_val; + if (vol_l_val < 0 || vol_l_val > 255) { + VolumeBuf[0] = 255; + } + if (vol_r_val < 0 || vol_r_val > 255) { + VolumeBuf[1] = 255; + } + + return AudioControlSetValue(2, VolumeBuf, match_names); +} + +int CAudioAlsa::GetAudioInternalDacDACDigitalPlayBackVolume(int *vol_l_val, int *vol_r_val) +{ + int VolumeBuf[2] = {0, 0}; + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_DAC_DIGITAL_PLAYBACK_VOLUME_NAME); + + AudioControlGetValue(2, VolumeBuf, match_names); + + *vol_l_val = VolumeBuf[0]; + *vol_r_val = VolumeBuf[1]; + + return 0; +} + +int CAudioAlsa::SetInternalDacLineInSelectChannel(int line_in_number) +{ + int tmp_ret = 0; + char *match_names = NULL; + + if (line_in_number < 0 || line_in_number > 7) { + return -1; + } + + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_LEFT_LINEIN_SEL_NAME); + tmp_ret |= AudioControlSetValue(1, &line_in_number, match_names); + + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_RIGHT_LINEIN_SEL_NAME); + tmp_ret |= AudioControlSetValue(1, &line_in_number, match_names); + + return tmp_ret; +} + +int CAudioAlsa::SetInternalDacLineInCaptureVolume(int l_vol, int r_vol) +{ + int max_val = GetLineInMaxVol(); + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_LINEIN_CAPTURE_VOLUME_NAME); + int VolumeBuf[2]; + + VolumeBuf[0] = CheckVolume(l_vol, 0, max_val, 0, max_val); + VolumeBuf[1] = CheckVolume(r_vol, 0, max_val, 0, max_val); + + return AudioControlSetValue(2, VolumeBuf, match_names); +} + +int CAudioAlsa::GetInternalDacLineInCaptureVolume(int vol_buf[]) +{ + int max_val = GetLineInMaxVol(); + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_LINEIN_CAPTURE_VOLUME_NAME); + + return GetTwoChannelVolume(vol_buf, 0, max_val, 0, max_val, match_names, 0, max_val); +} + +int CAudioAlsa::SetInternalDacLineOutPlayBackVolume(int l_vol, int r_vol) +{ + int max_val = GetLineOutMaxVol(); + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_LINEOUT_PLAYBACK_VOLUME_NAME); + int VolumeBuf[2]; + + VolumeBuf[0] = CheckVolume(l_vol, 0, max_val, 0, max_val); + VolumeBuf[1] = CheckVolume(r_vol, 0, max_val, 0, max_val); + + return AudioControlSetValue(2, VolumeBuf, match_names); +} + +int CAudioAlsa::GetInternalDacLineOutPlayBackVolume(int vol_buf[]) +{ + int max_val = GetLineOutMaxVol(); + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_LINEOUT_PLAYBACK_VOLUME_NAME); + + return GetTwoChannelVolume(vol_buf, 0, max_val, 0, max_val, match_names, 0, max_val); +} + +int CAudioAlsa::SetAudioPcmPlaybackVolume(int vol) +{ + if (get_USB_Audio_card() == -EINVAL) return 0; + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_PCM_PLAYBACK_VOLUME); + return HandleUSBAudioControlValue(1, &vol, 1, &match_names); +} + +int CAudioAlsa::SetAudioPcmPlaybackSwitch(int vol) +{ + if (get_USB_Audio_card() == -EINVAL) return 0; + char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_PCM_PLAYBACK_SWITCH); + return HandleUSBAudioControlValue(1, &vol, 1, &match_names); +} + +int CAudioAlsa::SetExternalDacChannelSwitch(int chan_ind, int switch_val) +{ + char *match_names = NULL; + + if (chan_ind == 1) { + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_CH1_SWITCH_NAME); + } else if (chan_ind == 2) { + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_CH2_SWITCH_NAME); + } else if (chan_ind == 3) { + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_CH3_SWITCH_NAME); + } else { + return -1; + } + + return AudioControlSetValue(1, &switch_val, match_names); +} + +int CAudioAlsa::SetExternalDacChannelVolume(int chan_ind, int main_vol) +{ + int tmp_ret = 0; + char *match_names = NULL; + + if (chan_ind == 0) { + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_MASTER_VOLUME_NAME); + } else if (chan_ind == 1) { + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_CH1_VOLUME_NAME); + } else if (chan_ind == 2) { + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_CH2_VOLUME_NAME); + } else if (chan_ind == 3) { + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_CH3_VOLUME_NAME); + } else { + return -1; + } + + return AudioControlSetValue(1, &main_vol, match_names); +} +int CAudioAlsa::SetAudioSwitchIO(int value) +{ + char *match_names = gG9AlsaNames[CC_GET_ALSA_CTL_AUDIO_IN_SWITCH]; + + return AudioControlSetValue(1, &value, match_names); +} +int CAudioAlsa::SetOutput_Swap(int value) +{ + char *match_names = gG9AlsaNames[CC_GET_ALSA_CTL_SETOUTPUT_SWAP]; + + return AudioControlSetValue(1, &value, match_names); +} + +int CAudioAlsa::SetExternalDacEQMode(int mode_val) +{ + char *match_names = NULL; + + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_EQ_MODE_NAME); + return AudioControlSetValue(1, &mode_val, match_names); +} + +int CAudioAlsa::SetI2SMute(int mute_status) +{ + char *match_names = NULL; + + if (mute_status != CC_I2S_MUTE_ON && mute_status != CC_I2S_MUTE_OFF) { + LOGE("%s, I2S mute value (%d) error!\n", __FUNCTION__, mute_status); + return -1; + } + + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_I2S_MUTE_NAME); + return AudioControlSetValue(1, &mute_status, match_names); +} + +int CAudioAlsa::SetSPDIFMute(int mute_status) +{ + int set_val = 0; + char *match_names = NULL; + + if (mute_status == CC_AUDIO_MUTE) { + set_val = CC_SPDIF_MUTE_ON; + } else if (mute_status == CC_AUDIO_UNMUTE) { + set_val = CC_SPDIF_MUTE_OFF; + } else { + return -1; + } + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_SPDIF_MUTE_NAME); + return AudioControlSetValue(1, &mute_status, match_names); +} + +#define CC_SAMPLE_BUF_SIZE (32) + +enum CC_HW_RESAMPLE_TYPE { + CC_HW_RESAMPLE_DISABLE, + CC_HW_RESAMPLE_48K, + CC_HW_RESAMPLE_44K, + CC_HW_RESAMPLE_32K, +}; + +int CAudioAlsa::SetHardwareResample(int sr) +{ + int i = 0, set_val = 0, tmp_val = 0; + int diff_val = 0x7FFFFFFF, diff_ind = -1; + char *match_names = NULL; + int sample_buf[CC_SAMPLE_BUF_SIZE] = + {32000, 44100, 48000, 88200, 96000, 176400, 192000, -1}; + + if (sr < 0) { + set_val = 0; + } else { + for (i = 0; i < CC_SAMPLE_BUF_SIZE; i++) { + if (sample_buf[i] < 0) { + break; + } + + if (sample_buf[i] >= sr) { + tmp_val = sample_buf[i] - sr; + } else { + tmp_val = sr - sample_buf[i]; + } + + if (tmp_val <= diff_val) { + diff_val = tmp_val; + diff_ind = i; + } + } + + if (diff_ind < 0) { + set_val = 0; + } else { + set_val = diff_ind + 1; + } + } + + LOGD("%s, set_val = %d.\n", __FUNCTION__, set_val); + match_names = GetAlsaControlName(CC_GET_ALSA_CTL_HW_RESAMPLE_NAME); + return AudioControlSetValue(1, &set_val, match_names); +} + +int CAudioAlsa::SetMixerBypassSwitch(int switch_val) +{ + char match_names[48] = "Output Mixer Bypass Switch" ; + int ctl_buf[2]; + + if (switch_val != 0 && switch_val != 1) { + return -1; + } + + ctl_buf[0] = switch_val; + ctl_buf[1] = switch_val; + + return AudioControlSetValue(2, ctl_buf, match_names); +} + +int CAudioAlsa::GetMixerBypassSwitch(void) +{ + char match_names[48] = "Output Mixer Bypass Switch" ; + int ctl_buf[2]; + + AudioControlSetValue(2, ctl_buf, match_names); + + return ctl_buf[0]; +} + +int CAudioAlsa::SetMixerDacSwitch(int switch_val) +{ + char match_names[48] = "Output Mixer DAC Switch" ; + int ctl_buf[2]; + + if (switch_val != 0 && switch_val != 1) { + return -1; + } + + ctl_buf[0] = switch_val; + ctl_buf[1] = switch_val; + + return AudioControlSetValue(2, ctl_buf, match_names); +} + +int CAudioAlsa::GetMixerDacSwitch(void) +{ + int ctl_buf[2]; + AudioControlGetValue(2, ctl_buf, (char *)"Output Mixer DAC Switch"); + return ctl_buf[0]; +} + +int CAudioAlsa::TransVolumeBarVolToDigitalVol(int digit_lut_buf[], int digit_vol) +{ + return digit_lut_buf[digit_vol]; +} + +int CAudioAlsa::TransDigitalVolToVolumeBarVol(int digit_lut_buf[], int hd_vol, + int hd_min __unused, int hd_max __unused, + int digit_min __unused, int digit_max) +{ + int i = 0; + for (; i < CC_VOL_TRANS_LUT_BUF_SIZE - 1; i++) { + if (digit_lut_buf[i] >= hd_vol && digit_lut_buf[i + 1] < hd_vol) + break; + } + + if (i < CC_VOL_TRANS_LUT_BUF_SIZE - 1) + return i; + + return digit_max; +} + +void CAudioAlsa::SetMainVolDigitLutBuf(int digit_lut_buf[]) +{ + memcpy((void *) mMainDigitLutBuf, digit_lut_buf, + CC_VOL_TRANS_LUT_BUF_SIZE * sizeof(int)); +} + +int *CAudioAlsa::GetMainVolDigitLutBuf() +{ + return mMainDigitLutBuf; +} +void CAudioAlsa::SetSupperBassVolDigitLutBuf(int digit_lut_buf[]) +{ + memcpy((void *) mSupperBassDigitLutBuf, digit_lut_buf, + CC_VOL_TRANS_LUT_BUF_SIZE * sizeof(int)); +} + + +int CAudioAlsa::SetMainVolumeGain(int gain_val) +{ + mMainVolumeGainVal = gain_val; + return mMainVolumeGainVal; +} + +int CAudioAlsa::GetMainVolumeGain() +{ + return mMainVolumeGainVal; +} + +int CAudioAlsa::SetSupperBassVolumeGain(int gain_val) +{ + int tmp_val = 0; + tmp_val = mSupperBassVolumeGainVal; + mSupperBassVolumeGainVal = gain_val; + return tmp_val; +} + +int CAudioAlsa::GetSupperBassVolumeGain() +{ + int tmp_val = 0; + tmp_val = mSupperBassVolumeGainVal; + return tmp_val; +} + + +int CAudioAlsa::CalculateBalanceVol(int max_vol, int balance_val, int vol_buf[]) +{ + int bal_mid_vol = 0, bal_cal_len = 0; + int tmp_val = 0; + + vol_buf[0] = max_vol; + vol_buf[1] = max_vol; + + bal_mid_vol = (CC_MIN_SOUND_BALANCE_VAL + CC_MAX_SOUND_BALANCE_VAL) / 2; + bal_cal_len = (CC_MAX_SOUND_BALANCE_VAL - CC_MIN_SOUND_BALANCE_VAL) / 2; + + if (balance_val == bal_mid_vol) { + LOGD( + "%s, balance value = %d, bal_mid_vol = %d, vol_buf[0] = %d, vol_buf[1] = %d.\n", + __FUNCTION__, balance_val, bal_mid_vol, vol_buf[0], vol_buf[1]); + return 0; + } else if (balance_val < bal_mid_vol) { + vol_buf[1] = (bal_cal_len - (bal_mid_vol - balance_val)) * max_vol / bal_cal_len; + } else if (balance_val > bal_mid_vol) { + vol_buf[0] = (bal_cal_len - (balance_val - bal_mid_vol)) * max_vol / bal_cal_len; + } + + if (GetAudioAmplifierBalanceExchangeCFG() != 0) { + tmp_val = vol_buf[0]; + vol_buf[0] = vol_buf[1]; + vol_buf[1] = tmp_val; + } + + LOGD( + "%s, balance value = %d, bal_mid_vol = %d, vol_buf[0] = %d, vol_buf[1] = %d.\n", + __FUNCTION__, balance_val, bal_mid_vol, vol_buf[0], vol_buf[1]); + return 0; +} + + +int CAudioAlsa::SetInternalDacMute(int mute_state) +{ + int ret = 0; + if (mute_state == CC_AUDIO_MUTE) + ret = SetAudioInternalDacDACDigitalPlayBackVolume(0, 0); + else + ret = SetAudioInternalDacDACDigitalPlayBackVolume(255, 255); + return ret; +} + +int CAudioAlsa::setAudioPcmPlaybackMute(int mute_state) +{ + char prop[256]; + property_get("audio.output.double_output", prop, "null"); + if ( Get2d4gHeadsetEnable() == 1 && (strcmp(prop, "0") == 0 || strcmp(prop, "null") == 0)) { + SetAudioPcmPlaybackSwitch(mute_state); + } + return 0; +} + + +int CAudioAlsa::SetInternalDacMainVolume(int main_vol) +{ + int tmp_ret = 0, digit_vol = 0; + digit_vol = TransVolumeBarVolToDigitalVol(mMainDigitLutBuf, main_vol); + + return SetInternalDacLineOutPlayBackVolume(digit_vol, digit_vol); +} + + +static int gDigitalMuteStatus = CC_AUDIO_UNMUTE; +static int gDigitalLeftVol = 0; +static int gDigitalRightVol = 0; + +int CAudioAlsa::SetDigitalVolume(int l_val, int r_val) +{ + amAudioSetLeftGain(l_val); + amAudioSetRightGain(r_val); + LOGD("%s, l_val = %d, r_val = %d.\n", __FUNCTION__, l_val, r_val); + return 0; +} + +int CAudioAlsa::SetDigitalMainVolume(int l_vol, int r_vol) +{ + int tmp_ret = 0, l_val = 0, r_val = 0; + + //handle l&r channel volume for balance + l_val = TransVolumeBarVolToDigitalVol(mMainDigitLutBuf, l_vol); + r_val = TransVolumeBarVolToDigitalVol(mMainDigitLutBuf, r_vol); + + gDigitalLeftVol = l_val; + gDigitalRightVol = r_val; + if (gDigitalMuteStatus == CC_AUDIO_UNMUTE) { + SetDigitalVolume(l_val, r_val); + } + + return tmp_ret; +} + +int CAudioAlsa::SetDigitalMute(int mute_status) +{ + gDigitalMuteStatus = mute_status; + if (mute_status == CC_AUDIO_MUTE) { + SetDigitalVolume(0, 0); + } else if (mute_status == CC_AUDIO_UNMUTE) { + SetDigitalVolume(gDigitalLeftVol, gDigitalRightVol); + } + + return 0; +} + +int CAudioAlsa::SetAudioARCSwitch(int on_off) +{ + int status = 0; + char *match_names = GetAlsaControlName(CC_SET_AUDIO_ARC_SWITCH); + if (on_off != 0 && on_off != 1) { + return -1; + } + status = on_off; + return AudioControlSetValue(1, &status, match_names); +} + diff --git a/tv/tvserver/libtv/audio/audio_alsa.h b/tv/tvserver/libtv/audio/audio_alsa.h new file mode 100644 index 0000000..5cd6d34 --- a/dev/null +++ b/tv/tvserver/libtv/audio/audio_alsa.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __TV_AUDIO_ALSA_H__ +#define __TV_AUDIO_ALSA_H__ + +enum CC_AUD_I2S_MUTE { + CC_I2S_MUTE_OFF, + CC_I2S_MUTE_ON, +}; + +enum CC_AUDIO_MUTE_STATUS { + CC_MUTE_ON, + CC_MUTE_OFF, +}; +enum CC_AUD_SPDIF_MUTE { + CC_SPDIF_MUTE_OFF, + CC_SPDIF_MUTE_ON, +}; + +enum CC_AUD_IN_TYPE { + CC_AUDIO_IN_SOURCE_LINEIN, + CC_AUDIO_IN_SOURCE_ATV, + CC_AUDIO_IN_SOURCE_HDMI, + CC_AUDIO_IN_SOURCE_SPDIFIN, +}; + + +#define CC_MIN_DAC_VOLUME (0) +#define CC_MAX_DAC_VOLUME (255) +#define CC_MIN_DAC_SUB_WOOFER_VOLUME (0) +#define CC_MAX_DAC_SUB_WOOFER_VOLUME (255) + +#define CC_MIN_SOUND_BALANCE_VAL (0) +#define CC_MAX_SOUND_BALANCE_VAL (100) +#define CC_DEF_SOUND_BALANCE_VAL (50) + +#define CC_DAC_MUTE_TYPE_EXTERNAL (1) +#define CC_DAC_MUTE_TYPE_INTERNAL (2) + +#define CC_VOL_TRANS_LUT_BUF_SIZE (101) + +static const int CC_AUDIO_MUTE = 1; +static const int CC_AUDIO_UNMUTE = 0; + +enum CC_AUDIO_SOURCE_TYPE { + AUDIO_HDMI_SOURCE, + AUDIO_ATV_SOURCE, + AUDIO_AV_SOURCE, + AUDIO_MPEG_SOURCE, + AUDIO_MAX_SOURCE +}; + + +//use tinyalsa,is a like alsa-lib for android +class CAudioAlsa { +public: + CAudioAlsa(); + ~CAudioAlsa(); + int SetAudioInSource(int source_type); + int GetAudioInSource(void); + int SetAudioInternalDacPGAInGain(int gain_l_val, int gain_r_val); + int GetAudioInternalDacPGAInGain(int *gain_l_val, int *gain_r_val); + int SetAudioInternalDacADCDigitalCaptureVolume(int vol_l_val, int vol_r_val); + int GetAudioInternalDacADCDigitalCaptureVolume(int *vol_l_val, int *vol_r_val); + int SetAudioInternalDacDACDigitalPlayBackVolume(int vol_l_val, int vol_r_val); + int GetAudioInternalDacDACDigitalPlayBackVolume(int *vol_l_val, int *vol_r_val); + int SetInternalDacLineInSelectChannel(int line_in_number); + int SetInternalDacLineInCaptureVolume(int l_vol, int r_vol); + int GetInternalDacLineInCaptureVolume(int vol_buf[]); + int SetInternalDacLineOutPlayBackVolume(int l_vol, int r_vol); + int GetInternalDacLineOutPlayBackVolume(int vol_buf[]); + int SetExternalDacChannelSwitch(int chan_ind, int switch_val); + int SetExternalDacChannelVolume(int chan_ind, int main_vol); + int SetExternalDacEQMode(int mode_val); + int SetI2SMute(int mute_status); + int SetSPDIFMute(int mute_status); + int SetHardwareResample(int sr); + int SetAudioSwitchIO(int value); + int SetAudioPcmPlaybackVolume(int val); + int SetAudioPcmPlaybackSwitch(int vol); + + int SetOutput_Swap(int value); + + + int SetMixerBypassSwitch(int switch_val); + int GetMixerBypassSwitch(void); + int SetMixerDacSwitch(int switch_val); + int GetMixerDacSwitch(void); + //dac + void SetMainVolDigitLutBuf(int digit_lut_buf[]); + int *GetMainVolDigitLutBuf(); + void SetSupperBassVolDigitLutBuf(int digit_lut_buf[]); + int SetMainVolumeGain(int gain_val); + int GetMainVolumeGain(); + int SetSupperBassVolumeGain(int gain_val); + int GetSupperBassVolumeGain(); + int SetInternalDacMute(int); + int setAudioPcmPlaybackMute(int); + //end dac + int TransVolumeBarVolToDigitalVol(int *, int); + int TransDigitalVolToVolumeBarVol(int *, int, int, int, int, int); + int CalculateBalanceVol(int, int, int *); + int SetExternalDacMainVolume(int); + int SetInternalDacMainVolume(int); + int SetDigitalVolume(int, int); + int SetDigitalMainVolume(int, int); + int SetDigitalMute(int); + int SetAudioARCSwitch(int on_off); +private: + int get_aml_card(); + int AudioControlSetValue(int val_count, int data_buf[], char *match_names); + int AudioControlGetValue(int val_count, int ret_buf[], char *match_names); + int get_USB_Audio_card(); + int HandleUSBAudioControlValue(int val_count, int data_buf[], int match_count, char **match_names); + int CheckVolume(int digit_vol, int digit_min, int digit_max, int hd_min, int hd_max); + int GetTwoChannelVolume(int vol_buf[], int l_min_vol, int l_max_vol, int r_min_vol, int r_max_vol, char *match_names, int hd_min, int hd_max); + int GetLineInMaxVol(); + int GetLineOutMaxVol(); + char *GetAlsaControlName(int get_type); + // + // + //mem + struct mixer *mpMixer; + struct mixer *mpUsbMixer; + int mMainVolumeBalanceVal; + int mMainVolumeGainVal; + int mSupperBassVolumeGainVal; + int mMainDigitLutBuf[CC_VOL_TRANS_LUT_BUF_SIZE]; + int mSupperBassDigitLutBuf[CC_VOL_TRANS_LUT_BUF_SIZE]; +}; +#endif //__TV_AUDIO_ALSA_H__ diff --git a/tv/tvserver/libtv/audio/audio_effect.cpp b/tv/tvserver/libtv/audio/audio_effect.cpp new file mode 100644 index 0000000..47a47a9 --- a/dev/null +++ b/tv/tvserver/libtv/audio/audio_effect.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CAudioEffect" +#define UNUSED(x) (void)x + +#include <stdio.h> +#include <stdlib.h> +#include <malloc.h> +#include <unistd.h> +#include <pthread.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/poll.h> +#include <sys/ioctl.h> +#include <fcntl.h> + +#include "audio_amaudio.h" +#include "audio_effect.h" +#include "CTvLog.h" + +CAudioEffect::CAudioEffect() +{ +} + +CAudioEffect::~CAudioEffect() +{ +} + +int CAudioEffect::GetEQBandCount() +{ + return CC_BAND_ITEM_CNT; +} + +int CAudioEffect::SetEQSwitch(int switch_val) +{ + int tmp_ret = 0; + //tmp_ret |= amAudioSetEQEnable(switch_val); + return tmp_ret; +} + +int CAudioEffect::GetEQSwitch() +{ + int tmp_ret = 0; + return 0; +} + +int CAudioEffect::SetEQValue(int gain_val_buf[]) +{ + int tmp_ret = 0; + //tmp_ret |= amAudioSetEQGain(gain_val_buf, CC_BAND_ITEM_CNT); + return tmp_ret; +} + +int CAudioEffect::GetEQValue(int gain_val_buf[] __unused) +{ + return 0; +} + +int CAudioEffect::SetSrsSurroundSwitch(int switch_val) +{ + int tmp_ret = 0; + //tmp_ret |= amAudioSetSRSSurroundSwitch(switch_val); + return tmp_ret; +} + +int CAudioEffect::SetSrsSurroundGain(int gain_val) +{ + int tmp_ret = 0; + //tmp_ret |= amAudioSetSRSSurroundGain(gain_val); + return tmp_ret; +} + +int CAudioEffect::SetSrsInputOutputGain(int input_gain_val, int output_gain_val) +{ + int tmp_ret = 0; + //tmp_ret |= amAudioSetSRSGain(input_gain_val, output_gain_val); + return tmp_ret; +} + +int CAudioEffect::SetSrsTruBassSwitch(int switch_val) +{ + int tmp_ret = 0; + //tmp_ret |= amAudioSetSRSTrubassSwitch(switch_val); + return tmp_ret; +} + +int CAudioEffect::SetSrsTruBassGain(int gain_val) +{ + int tmp_ret = 0; + //tmp_ret |= amAudioSetSRSTrubassGain(gain_val); + return tmp_ret; +} + +int CAudioEffect::SetSrsDialogClaritySwitch(int switch_val) +{ + int tmp_ret = 0; + //tmp_ret |= amAudioSetSRSDialogClaritySwitch(switch_val); + return tmp_ret; +} + +int CAudioEffect::SetSrsDialogClarityGain(int gain_val) +{ + int tmp_ret = 0; + //tmp_ret |= amAudioSetSRSDialogClarityGain(gain_val); + return tmp_ret; +} + +int CAudioEffect::SetSrsDefinitionGain(int gain_val) +{ + int tmp_ret = 0; + //tmp_ret |= amAudioSetSRSDefinitionGain(gain_val); + return tmp_ret; +} + +int CAudioEffect::SetSrsTrubassSpeakerSize(int set_val) +{ + int tmp_ret = 0; + //tmp_ret |= amAudioSetSRSTrubassSpeakerSize(set_val); + return tmp_ret; +} + +int CAudioEffect::DbxTv_SetMode(int mode __unused, int son_value, int vol_value, int sur_value) +{ + //TODO + UNUSED(son_value); + UNUSED(vol_value); + UNUSED(sur_value); + + int ret = 0; +#ifdef TV_AUDIO_USE_DBX_TV + ret |= amAudioSetDBXTVParameter( son_value, vol_value, sur_value); +#endif + return ret; +} + +int CAudioEffect::SetAudioVirtualizer(int enable, int EffectLevel) +{ + return 0;//amAudioVirtualizer(enable, EffectLevel); +} diff --git a/tv/tvserver/libtv/audio/audio_effect.h b/tv/tvserver/libtv/audio/audio_effect.h new file mode 100644 index 0000000..2439e51 --- a/dev/null +++ b/tv/tvserver/libtv/audio/audio_effect.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __TV_AUDIO_EFFECT_H__ +#define __TV_AUDIO_EFFECT_H__ +#define CC_BAND_ITEM_CNT ( 6 ) +class CAudioEffect { +public: + CAudioEffect(); + ~CAudioEffect(); + int GetEQBandCount(); + int SetEQSwitch(int switch_val); + int GetEQSwitch(); + int SetEQValue(int gain_val_buf[]); + int GetEQValue(int gain_val_buf[]); + + int SetSrsSurroundSwitch(int switch_val); + int SetSrsInputOutputGain(int input_gain_val, int output_gain_val); + int SetSrsSurroundGain(int gain_val); + int SetSrsTruBassSwitch(int switch_val); + int SetSrsTruBassGain(int gain_val); + int SetSrsDialogClaritySwitch(int switch_val); + int SetSrsDialogClarityGain(int gain_val); + int SetSrsDefinitionGain(int gain_val); + int SetSrsTrubassSpeakerSize(int tmp_val); + int DbxTv_SetMode(int mode, int son_value, int vol_value, int sur_value); + int SetAudioVirtualizer(int enable, int EffectLevel); + +private: +}; +#endif //__TV_AUDIO_EFFECT_H__ diff --git a/tv/tvserver/libtv/fbcutils/CFbcCommunication.cpp b/tv/tvserver/libtv/fbcutils/CFbcCommunication.cpp new file mode 100644 index 0000000..b85526d --- a/dev/null +++ b/tv/tvserver/libtv/fbcutils/CFbcCommunication.cpp @@ -0,0 +1,913 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CFbcCommunication" +#define LOG_NDEBUG 0 + +#include "CFbcCommunication.h" +#include <tvconfig.h> +#include <tvutils.h> +#include <stdlib.h> +#include <string.h> +#include <CTvLog.h> + + +static CFbcCommunication *gSingletonFBC = NULL; +CFbcCommunication *GetSingletonFBC() +{ + if (gSingletonFBC == NULL) { + gSingletonFBC = new CFbcCommunication(); + } + + return gSingletonFBC; +} + +CFbcCommunication::CFbcCommunication(){} + +CFbcCommunication::~CFbcCommunication(){} + +int CFbcCommunication::cfbcSetValueInt(COMM_DEV_TYPE_E fromDev, int cmd_id, int value, int value_count) +{ + LOGV("%s, cmd_id=%d, value=%d, value_count=%d", __FUNCTION__, cmd_id, value, value_count); + if (value_count != 1 && value_count != 4) + return -1; + + unsigned char cmd_buf[7]; + memset(cmd_buf, 0, 7); + cmd_buf[0] = fromDev; + cmd_buf[1] = cmd_id; + if (value_count == 1) { + cmd_buf[2] = value; + } else { + cmd_buf[2] = (value >> 0) & 0xFF; + cmd_buf[3] = (value >> 8) & 0xFF; + cmd_buf[4] = (value >> 16) & 0xFF; + cmd_buf[5] = (value >> 24) & 0xFF; + } + + return sendCommandToFBC(cmd_buf, value_count+2, 0); +} + +int CFbcCommunication::cfbcGetValueInt(COMM_DEV_TYPE_E fromDev, int cmd_id, int *value, int value_count) +{ + LOGV("%s, cmd_id=%d, value_count=%d", __FUNCTION__, cmd_id, value_count); + int ret = -1; + unsigned char cmd_buf[7];//2 + 4 + 1 + memset(cmd_buf, 0, 7); + cmd_buf[0] = fromDev; + cmd_buf[1] = cmd_id; + + ret = sendCommandToFBC(cmd_buf, 2, 1); + if (ret > -1) { + if (value_count == 1) { + *value = cmd_buf[2]; + } else { + *value |= cmd_buf[2] & 0xFF; + *value |= (cmd_buf[3] & 0xFF) << 8; + *value |= (cmd_buf[4] & 0xFF) << 16; + *value |= (cmd_buf[5] & 0xFF) << 24; + } + } + return ret; +} + +int CFbcCommunication::cfbc_Set_Gain_Red(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_RED_GAIN_DEF, value, 1); +} + +int CFbcCommunication::cfbc_Get_Gain_Red(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_RED_GAIN_DEF | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Gain_Green(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_GREEN_GAIN_DEF, value, 1); +} + +int CFbcCommunication::cfbc_Get_Gain_Green(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_GREEN_GAIN_DEF | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Gain_Blue(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_BLUE_GAIN_DEF, value, 1); +} + +int CFbcCommunication::cfbc_Get_Gain_Blue(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_BLUE_GAIN_DEF | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Offset_Red(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_PRE_RED_OFFSET_DEF, value, 1); +} + +int CFbcCommunication::cfbc_Get_Offset_Red(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_PRE_RED_OFFSET_DEF | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Offset_Green(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_PRE_GREEN_OFFSET_DEF, value, 1); +} + +int CFbcCommunication::cfbc_Get_Offset_Green(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_PRE_GREEN_OFFSET_DEF | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Offset_Blue(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_PRE_BLUE_OFFSET_DEF, value, 1); +} + +int CFbcCommunication::cfbc_Get_Offset_Blue(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_PRE_BLUE_OFFSET_DEF | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_WB_Initial(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_WB, value, 1); +} + +int CFbcCommunication::cfbc_Get_WB_Initial(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_WB | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_ColorTemp_Mode(COMM_DEV_TYPE_E fromDev, int value) +{ + int fbcValue = value; + switch (value) { + case 0: //standard + fbcValue = 1; + break; + case 1: //warm + fbcValue = 2; + break; + case 2: //cold + fbcValue = 0; + break; + default: + break; + } + LOGD("before set fbcValue = %d", fbcValue); + + return cfbcSetValueInt(fromDev, VPU_CMD_COLOR_TEMPERATURE_DEF, fbcValue, 1); +} + +int CFbcCommunication::cfbc_Get_ColorTemp_Mode(COMM_DEV_TYPE_E fromDev, int *value) +{ + cfbcGetValueInt(fromDev, VPU_CMD_COLOR_TEMPERATURE_DEF | 0x80, value); + + switch (*value) { + case 0: //cold + *value = 2; + break; + case 1: //standard + *value = 0; + break; + case 2: //warm + *value = 1; + break; + default: + break; + } + + return 0; +} + +int CFbcCommunication::cfbc_Set_Test_Pattern(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_PATTEN_SEL, value, 1); +} + +int CFbcCommunication::cfbc_Get_Test_Pattern(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_PATTEN_SEL | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Picture_Mode(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_PICTURE_MODE, value, 1); +} + +int CFbcCommunication::cfbc_Get_Picture_Mode(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_PICTURE_MODE | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Contrast(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_CONTRAST_DEF, value, 1); +} + +int CFbcCommunication::cfbc_Get_Contrast(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_CONTRAST_DEF | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Brightness(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_BRIGHTNESS_DEF, value, 1); +} + +int CFbcCommunication::cfbc_Get_Brightness(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_BRIGHTNESS_DEF | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Saturation(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_COLOR_DEF, value, 1); +} + +int CFbcCommunication::cfbc_Get_Saturation(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_COLOR_DEF | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_HueColorTint(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_HUE_DEF, value, 1); +} + +int CFbcCommunication::cfbc_Get_HueColorTint(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_HUE_DEF | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Backlight(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_BACKLIGHT_DEF, value, 1); +} + +int CFbcCommunication::cfbc_Get_Backlight(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_BACKLIGHT_DEF | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Source(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_SOURCE, value, 1); +} + +int CFbcCommunication::cfbc_Get_Source(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_SOURCE | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Mute(COMM_DEV_TYPE_E fromDev, int value) +{ + LOGD("cfbc_Set_Mute = %d", value); + return cfbcSetValueInt(fromDev, AUDIO_CMD_SET_MUTE, value, 1); +} + +int CFbcCommunication::cfbc_Set_FBC_Audio_Source(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, AUDIO_CMD_SET_SOURCE, value, 1); +} + +int CFbcCommunication::cfbc_Get_Mute(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, AUDIO_CMD_GET_MUTE, value); +} + +int CFbcCommunication::cfbc_Set_Volume_Bar(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, AUDIO_CMD_SET_VOLUME_BAR, value, 1); +} + +int CFbcCommunication::cfbc_Get_Volume_Bar(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, AUDIO_CMD_GET_VOLUME_BAR, value); +} + +int CFbcCommunication::cfbc_Set_Balance(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, AUDIO_CMD_SET_BALANCE, value, 1); +} + +int CFbcCommunication::cfbc_Get_Balance(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, AUDIO_CMD_GET_BALANCE, value); +} + +int CFbcCommunication::cfbc_Set_Master_Volume(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, AUDIO_CMD_SET_MASTER_VOLUME, value, 1); +} + +int CFbcCommunication::cfbc_Get_Master_Volume(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, AUDIO_CMD_GET_MASTER_VOLUME, value); +} + +int CFbcCommunication::cfbc_Set_CM(COMM_DEV_TYPE_E fromDev, unsigned char value) +{ + unsigned char cmd[4]; + + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE; + cmd[2] = VPU_MODULE_CM2; + cmd[3] = value;//value:0~1 + return sendCommandToFBC(cmd, 4, 0); +} + +int CFbcCommunication::cfbc_Get_CM(COMM_DEV_TYPE_E fromDev, int *value) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE | 0x80; + cmd[2] = VPU_MODULE_CM2; + + sendCommandToFBC(cmd, 3, 1); + *value = cmd[3]; + return 0; +} +int CFbcCommunication::cfbc_Set_DNLP(COMM_DEV_TYPE_E fromDev, unsigned char value) +{ + unsigned char cmd[512]; + + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE; + cmd[2] = VPU_MODULE_DNLP; + cmd[3] = value;//value:0~1 + + return sendCommandToFBC(cmd, 4, 0); +} + +int CFbcCommunication::cfbc_Get_DNLP(COMM_DEV_TYPE_E fromDev, int *value) +{ + unsigned char cmd[512]; + + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE | 0x80; + cmd[2] = VPU_MODULE_DNLP; + + sendCommandToFBC(cmd, 3, 1); + *value = cmd[3]; + return 0; +} + +int CFbcCommunication::cfbc_Get_FBC_MAINCODE_Version(COMM_DEV_TYPE_E fromDev, char sw_ver[], char build_time[], char git_ver[], char git_branch[], char build_name[]) +{ + int rx_len = 0, tmp_ind = 0; + unsigned char cmd[512]; + + if (sw_ver == NULL || build_time == NULL || git_ver == NULL || git_branch == NULL || build_name == NULL) { + return -1; + } + + memset(cmd, 0, 512); + cmd[0] = fromDev; + cmd[1] = CMD_FBC_MAIN_CODE_VERSION; + rx_len = sendCommandToFBC(cmd, 2, 1); + + sw_ver[0] = 0; + build_time[0] = 0; + git_ver[0] = 0; + git_branch[0] = 0; + build_name[0] = 0; + + if (rx_len <= 0) { + return -1; + } + + if (cmd[0] != CMD_FBC_MAIN_CODE_VERSION || cmd[1] != 0x88 || cmd[2] != 0x99) { + return -1; + } + + tmp_ind = 3; + + strcpy(sw_ver, (char *)(cmd + tmp_ind)); + tmp_ind += strlen(sw_ver); + tmp_ind += 1; + + strcpy(build_time, (char *)(cmd + tmp_ind)); + tmp_ind += strlen(build_time); + tmp_ind += 1; + + strcpy(git_ver, (char *)(cmd + tmp_ind)); + tmp_ind += strlen(git_ver); + tmp_ind += 1; + + strcpy(git_branch, (char *)(cmd + tmp_ind)); + tmp_ind += strlen(git_branch); + tmp_ind += 1; + + strcpy(build_name, (char *)(cmd + tmp_ind)); + tmp_ind += strlen(build_name); + tmp_ind += 1; + LOGD("sw_ver=%s, buildt=%s, gitv=%s, gitb=%s,bn=%s", sw_ver, build_time, git_ver, git_branch, build_name); + return 0; +} + +int CFbcCommunication::cfbc_Set_FBC_Factory_SN(COMM_DEV_TYPE_E fromDev, const char *pSNval) +{ + unsigned char cmd[512]; + int len = strlen(pSNval); + cmd[0] = fromDev; + cmd[1] = CMD_SET_FACTORY_SN; + memcpy(cmd + 2, pSNval, len); + + LOGD("cmd : %s\n", cmd); + return sendCommandToFBC(cmd, len+2, 0); +} + +int CFbcCommunication::cfbc_Get_FBC_Factory_SN(COMM_DEV_TYPE_E fromDev, char FactorySN[]) +{ + int rx_len = 0; + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = CMD_GET_FACTORY_SN; + rx_len = sendCommandToFBC(cmd, 2, 1); + if (rx_len <= 0) { + return -1; + } + strncpy(FactorySN, (char *)(cmd+2), rx_len); + + LOGD("panelModel=%s", FactorySN); + return 0; +} + +int CFbcCommunication::cfbc_Get_FBC_Get_PANel_INFO(COMM_DEV_TYPE_E fromDev, char panel_model[]) +{ + int rx_len = 0; + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = CMD_DEVICE_ID; + rx_len = sendCommandToFBC(cmd, 2, 1); + if (rx_len <= 0) { + return -1; + } + strcpy(panel_model, (char *)(cmd + 2)); + + LOGD("panelModel=%s", panel_model); + return 0; +} + +int CFbcCommunication::cfbc_Set_FBC_panel_power_switch(COMM_DEV_TYPE_E fromDev, int switch_val) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = FBC_PANEL_POWER; + cmd[2] = switch_val; //0 is fbc panel power off, 1 is panel power on. + + return sendCommandToFBC(cmd, 3, 0); +} + +int CFbcCommunication::cfbc_Set_FBC_suspend(COMM_DEV_TYPE_E fromDev, int switch_val) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = FBC_SUSPEND_POWER; + cmd[2] = switch_val; //0 + + return sendCommandToFBC(cmd, 3, 0); +} + +int CFbcCommunication::cfbc_Set_FBC_User_Setting_Default(COMM_DEV_TYPE_E fromDev, int param) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = FBC_USER_SETTING_DEFAULT; + cmd[2] = param; //0 + return sendCommandToFBC(cmd, 3, 0); +} + +int CFbcCommunication::cfbc_SendRebootToUpgradeCmd(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, FBC_REBOOT_UPGRADE, value, 4); +} + +int CFbcCommunication::cfbc_FBC_Send_Key_To_Fbc(COMM_DEV_TYPE_E fromDev, int keycode __unused, int param __unused) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = CMD_ACTIVE_KEY; + cmd[2] = keycode; + return sendCommandToFBC(cmd, 3, 0); +} + +int CFbcCommunication::cfbc_Get_FBC_PANEL_REVERSE(COMM_DEV_TYPE_E fromDev, int *value) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = CMD_PANEL_INFO; + //0://panel reverse + //1://panel output_mode + //2://panel byte num + cmd[2] = 0; + + sendCommandToFBC(cmd, 3, 1); + //cmd[0] cmdid-PANEL-INFO + //cmd[1] param[0] - panel reverse + *value = cmd[3]; + + return 0; +} + +int CFbcCommunication::cfbc_Get_FBC_PANEL_OUTPUT(COMM_DEV_TYPE_E fromDev, int *value) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = CMD_PANEL_INFO; + //0://panel reverse + //1://panel output_mode + //2://panel byte num + cmd[2] = 1; + + sendCommandToFBC(cmd, 3, 1); + //cmd[0] cmdid-PANEL-INFO + //cmd[1] param[0] - panel reverse + *value = cmd[3]; + + return 0; +} + +int CFbcCommunication::cfbc_Set_FBC_project_id(COMM_DEV_TYPE_E fromDev, int prj_id) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = CMD_SET_PROJECT_SELECT; + cmd[2] = prj_id; + return sendCommandToFBC(cmd, 3, 0); +} + +int CFbcCommunication::cfbc_Get_FBC_project_id(COMM_DEV_TYPE_E fromDev, int *prj_id) +{ + return cfbcGetValueInt(fromDev, CMD_GET_PROJECT_SELECT, prj_id); +} + +int CFbcCommunication::fbcSetEyeProtection(COMM_DEV_TYPE_E fromDev, int mode) +{ + unsigned char cmd[3]; + cmd[0] = fromDev; + cmd[1] = VPU_CMD_EYE_PROTECTION; + cmd[2] = mode; + return sendCommandToFBC(cmd, 3, 0); +} + +int CFbcCommunication::fbcSetGammaValue(COMM_DEV_TYPE_E fromDev, int gamma_curve, int is_save) +{ + unsigned char cmd[4]; + cmd[0] = fromDev; + cmd[1] = VPU_CMD_USER_GAMMA; + cmd[2] = gamma_curve; + cmd[3] = is_save; + return sendCommandToFBC(cmd, 4, 0); +} + +int CFbcCommunication::fbcSetGammaPattern(COMM_DEV_TYPE_E fromDev, unsigned short gamma_r, unsigned short gamma_g, unsigned short gamma_b) +{ + unsigned char cmd[5]; + cmd[0] = fromDev; + cmd[1] = VPU_CMD_GAMMA_PATTERN; + cmd[2] = gamma_r; + cmd[3] = gamma_g; + cmd[4] = gamma_b; + return sendCommandToFBC(cmd, 5, 0); +} + +int CFbcCommunication::cfbc_Set_Gamma(COMM_DEV_TYPE_E fromDev, unsigned char value) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE; + cmd[2] = VPU_MODULE_GAMMA; + cmd[3] = value;//value:0~1 + return sendCommandToFBC(cmd, 4, 0); +} + +int CFbcCommunication::cfbc_Get_Gamma(COMM_DEV_TYPE_E fromDev, int *value) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE | 0x80; + cmd[2] = VPU_MODULE_GAMMA; + + sendCommandToFBC(cmd, 3, 1); + *value = cmd[3]; + return 0; +} + +int CFbcCommunication::cfbc_Set_VMute(COMM_DEV_TYPE_E fromDev, unsigned char value) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = VPU_CMD_USER_VMUTE; + cmd[2] = value; + LOGD("cfbc_Set_VMute=%d", cmd[2]); + + return sendCommandToFBC(cmd, 3, 0); +} + +int CFbcCommunication::cfbc_Set_WhiteBalance_OnOff(COMM_DEV_TYPE_E fromDev, unsigned char value) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE; + cmd[2] = VPU_MODULE_WB; + cmd[3] = value;//value:0~1 + return sendCommandToFBC(cmd, 4, 0); +} + +int CFbcCommunication::cfbc_Get_WhiteBalance_OnOff(COMM_DEV_TYPE_E fromDev, int *value) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE | 0x80; + cmd[2] = VPU_MODULE_WB; + + sendCommandToFBC(cmd, 3, 1); + *value = cmd[3]; + return 0; +} + +int CFbcCommunication::cfbc_Set_WB_Batch(COMM_DEV_TYPE_E fromDev, unsigned char mode, unsigned char r_gain, unsigned char g_gain, unsigned char b_gain, unsigned char r_offset, unsigned char g_offset, unsigned char b_offset) +{ + unsigned char cmd[9]; + cmd[0] = fromDev; + cmd[1] = VPU_CMD_WB_VALUE; + cmd[2] = mode; + cmd[3] = r_gain; + cmd[4] = g_gain; + cmd[5] = b_gain; + cmd[6] = r_offset; + cmd[7] = g_offset; + cmd[8] = b_offset; + + return sendCommandToFBC(cmd, 9, 0); +} + +int CFbcCommunication::cfbc_TestPattern_Select(COMM_DEV_TYPE_E fromDev, int value) +{ + int ret = -1; + unsigned char cmd[4]; + + LOGD("Call vpp 63 2 1\n"); + cmd[0] = fromDev; + cmd[1] = VPU_CMD_SRCIF; + cmd[2] = 2; + cmd[3] = 1; + ret = sendCommandToFBC(cmd, 4, 0);//close csc0 + if (ret == 0) { + LOGD("Call vpp 9 11 1\n"); + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE; + cmd[2] = 11; + cmd[3] = 1; + ret = sendCommandToFBC(cmd, 4, 0); + if (ret == 0) { + LOGD("Call vpp 42 1-17\n"); + cfbcSetValueInt(fromDev, VPU_CMD_PATTEN_SEL, value, 1); + } + } + + return ret; +} + +int CFbcCommunication::cfbc_WhiteBalance_GrayPattern_OnOff(COMM_DEV_TYPE_E fromDev, int onOff) +{ + int ret = -1; + unsigned char cmd[4]; + + if (onOff == 0) { //On + LOGD("Call vpp 63 2 1"); + cmd[0] = fromDev; + cmd[1] = VPU_CMD_SRCIF; + cmd[2] = 2; + cmd[3] = 1; + ret = sendCommandToFBC(cmd, 4, 0);//close csc0 + if (ret == 0) { + LOGD("Call vpp 9 9 0"); + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE; + cmd[2] = 9; + cmd[3] = 0; + ret = sendCommandToFBC(cmd, 4, 0);//close csc1 + if (ret == 0) { + LOGD("Call vpp 9 10 0"); + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE; + cmd[2] = 10; + cmd[3] = 0; + ret = sendCommandToFBC(cmd, 4, 0);//close dnlp + if (ret == 0) { + LOGD("Call vpp 9 8 0"); + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE; + cmd[2] = 8; + cmd[3] = 0; + ret = sendCommandToFBC(cmd, 4, 0);//close cm + } + } + } + } else { //Off + LOGD("Call vpp 63 2 2"); + cmd[0] = fromDev; + cmd[1] = VPU_CMD_SRCIF; + cmd[2] = 2; + cmd[3] = 2; + ret = sendCommandToFBC(cmd, 4, 0); + if (ret == 0) { + LOGD("Call vpp 9 9 1"); + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE; + cmd[2] = 9; + cmd[3] = 1; + ret = sendCommandToFBC(cmd, 4, 0);//open csc1 + if (ret == 0) { + LOGD("Call vpp 9 10 1"); + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE; + cmd[2] = 10; + cmd[3] = 1; + ret = sendCommandToFBC(cmd, 4, 0);//open dnlp + if (ret == 0) { + LOGD("Call vpp 9 8 1"); + cmd[0] = fromDev; + cmd[1] = VPU_CMD_ENABLE; + cmd[2] = 8; + cmd[3] = 1; + ret = sendCommandToFBC(cmd, 4, 0);//open cm + } + } + } + } + return ret; +} + +int CFbcCommunication::cfbc_WhiteBalance_SetGrayPattern(COMM_DEV_TYPE_E fromDev, unsigned char value) +{ + int ret = -1; + unsigned char cmd[5]; + cmd[0] = fromDev; + cmd[1] = VPU_CMD_GRAY_PATTERN; + cmd[2] = value; + cmd[3] = value; + cmd[4] = value; + ret = sendCommandToFBC(cmd, 5, 0); + return ret; +} + +int CFbcCommunication::cfbc_Set_Auto_Backlight_OnOff(COMM_DEV_TYPE_E fromDev, unsigned char value) +{ + unsigned char cmd[3]; + cmd[0] = fromDev; + cmd[1] = CMD_SET_AUTO_BACKLIGHT_ONFF; + cmd[2] = value; + LOGD("cfbc_Set_naturelight_onoff\n"); + return sendCommandToFBC(cmd, 3, 0); +} + +int CFbcCommunication::cfbc_Get_Auto_Backlight_OnOff(COMM_DEV_TYPE_E fromDev, int *value) +{ + LOGD("cfbc_get_naturelight_onoff\n"); + return cfbcGetValueInt(fromDev, CMD_GET_AUTO_BACKLIGHT_ONFF, value); +} + +int CFbcCommunication::cfbc_Get_WB_Batch(COMM_DEV_TYPE_E fromDev, unsigned char mode, + unsigned char *r_gain, unsigned char *g_gain, unsigned char *b_gain, + unsigned char *r_offset, unsigned char *g_offset, unsigned char *b_offset) +{ + unsigned char cmd[512] = {0}; + cmd[0] = fromDev; + cmd[1] = VPU_CMD_WB_VALUE | 0x80; + cmd[2] = mode; + + sendCommandToFBC(cmd, 3, 1); + //*mode = cmd[1]; + *r_gain = cmd[3]; + *g_gain = cmd[4]; + *b_gain = cmd[5]; + *r_offset = cmd[6]; + *g_offset = cmd[7]; + *b_offset = cmd[8]; + return 0; +} + +int CFbcCommunication::cfbc_Set_backlight_onoff(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, VPU_CMD_BACKLIGHT_EN, value, 1); +} + +int CFbcCommunication::cfbc_Get_backlight_onoff(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, VPU_CMD_BACKLIGHT_EN, value); +} + +int CFbcCommunication::cfbc_Set_LVDS_SSG_Set(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, CMD_LVDS_SSG_SET, value, 1); +} + +int CFbcCommunication::cfbc_Set_AUTO_ELEC_MODE(COMM_DEV_TYPE_E fromDev, int value) +{ + LOGD("%s cmd =0x%x, value=%d", __FUNCTION__, VPU_CMD_SET_ELEC_MODE, value); + return cfbcSetValueInt(fromDev, VPU_CMD_SET_ELEC_MODE, value, 1); +} + +int CFbcCommunication::cfbc_Set_Thermal_state(COMM_DEV_TYPE_E fromDev, int value) +{ + LOGD("%s cmd =0x%x, data%d\n", __FUNCTION__, CMD_HDMI_STAT, value); + return cfbcSetValueInt(fromDev, CMD_HDMI_STAT, value, 4); +} + +int CFbcCommunication::cfbc_Set_LightSensor_N310(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, 0x84, value, 1); +} + +int CFbcCommunication::cfbc_Set_Dream_Panel_N310(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, 0x83, value, 1); +} + +int CFbcCommunication::cfbc_Set_MULT_PQ_N310(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, 0x81, value, 1); +} + +int CFbcCommunication::cfbc_Set_MEMC_N310(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, 0x82, value, 1); +} + +int CFbcCommunication::cfbc_Set_Bluetooth_IIS_onoff(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, CMD_BLUETOOTH_I2S_STATUS, value, 1); +} + +int CFbcCommunication::cfbc_Get_Bluetooth_IIS_onoff(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, CMD_BLUETOOTH_I2S_STATUS | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Led_onoff(COMM_DEV_TYPE_E fromDev, int val_1, int val_2, int val_3) +{ + unsigned char cmd[512]; + cmd[0] = fromDev; + cmd[1] = CMD_SET_LED_MODE; + cmd[2] = val_1; + cmd[3] = val_2; + cmd[4] = val_3; + return sendCommandToFBC(cmd, 5, 0); +} + +int CFbcCommunication::cfbc_Set_LockN_state(COMM_DEV_TYPE_E fromDev, int value) +{ + LOGD("%s cmd =0x%x, data%d\n", __FUNCTION__, CMD_SET_LOCKN_DISABLE, value); + return cfbcSetValueInt(fromDev, CMD_SET_LOCKN_DISABLE, value, 1); +} + +int CFbcCommunication::cfbc_SET_SPLIT_SCREEN_DEMO(COMM_DEV_TYPE_E fromDev, int value) +{ + LOGD("%s,cmd[%#x], data[%d]\n", __FUNCTION__, CMD_SET_SPLIT_SCREEN_DEMO, value); + return cfbcSetValueInt(fromDev, CMD_SET_SPLIT_SCREEN_DEMO, value, 1); +} + +int CFbcCommunication::fbcSetPanelStatus(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, CMD_PANEL_ON_OFF, value, 1); +} + +int CFbcCommunication::fbcGetPanelStatus(COMM_DEV_TYPE_E fromDev, int *value) +{ + return cfbcGetValueInt(fromDev, CMD_PANEL_ON_OFF | 0x80, value); +} + +int CFbcCommunication::cfbc_Set_Fbc_Uboot_Stage(COMM_DEV_TYPE_E fromDev, int value) +{ + return cfbcSetValueInt(fromDev, CMD_SET_UBOOT_STAGE, value, 1); +} + +int CFbcCommunication::fbcStartUpgrade(char *file_name, int mode, int upgrade_blk_size) +{ + return startFBCUpgrade(file_name, upgrade_blk_size, mode); +} + +int CFbcCommunication::fbcRelease() +{ + return cfbcSetValueInt(COMM_DEV_SERIAL, CMD_FBC_RELEASE, 0, 0); +} + +int CFbcCommunication::cfbc_EnterPCMode(int value) +{ + return cfbcSetValueInt(COMM_DEV_SERIAL, CMD_SET_ENTER_PCMODE, value, 1); +} + diff --git a/tv/tvserver/libtv/fbcutils/CFbcCommunication.h b/tv/tvserver/libtv/fbcutils/CFbcCommunication.h new file mode 100644 index 0000000..a116687 --- a/dev/null +++ b/tv/tvserver/libtv/fbcutils/CFbcCommunication.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef C_FBC_COMMUNICATION_H +#define C_FBC_COMMUNICATION_H + +#include <CFbcHelper.h> + +typedef enum OUTPUT_MODE { + T_1080P50HZ = 0, + T_2160P50HZ420, + T_1080P50HZ44410BIT, + T_2160P50HZ42010BIT, + T_2160P50HZ42210BIT, + T_2160P50HZ444, +} OUTPUT_MODE_E; + +typedef enum vpu_modules_e { + VPU_MODULE_NULL = 0, + VPU_MODULE_VPU, //vpu unsigned int + VPU_MODULE_TIMGEN, + VPU_MODULE_PATGEN, + VPU_MODULE_GAMMA, + VPU_MODULE_WB, //WhiteBalance + VPU_MODULE_BC, //Brightness&Contrast + VPU_MODULE_BCRGB, //RGB Brightness&Contrast + VPU_MODULE_CM2, + VPU_MODULE_CSC1, + VPU_MODULE_DNLP, + VPU_MODULE_CSC0, + VPU_MODULE_OSD, + VPU_MODULE_BLEND, + VPU_MODULE_DEMURE, //15 + VPU_MODULE_OUTPUT, //LVDS/VX1 output + VPU_MODULE_OSDDEC, //OSD decoder + VPU_MODULE_MAX, +} vpu_modules_t; + +class CFbcCommunication { +public: + CFbcCommunication(); + ~CFbcCommunication(); + + int cfbc_Set_Gain_Red(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Gain_Red(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Gain_Green(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Gain_Green(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Gain_Blue(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Gain_Blue(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Offset_Red(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Offset_Red(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Offset_Green(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Offset_Green(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Offset_Blue(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Offset_Blue(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_WB_Initial(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_WB_Initial(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_ColorTemp_Mode(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_ColorTemp_Mode(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Test_Pattern(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Test_Pattern(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Picture_Mode(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Picture_Mode(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Contrast(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Contrast(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Brightness(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Brightness(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Saturation(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Saturation(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_HueColorTint(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_HueColorTint(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Backlight(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Backlight(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Source(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Source(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Mute(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Mute(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Volume_Bar(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Volume_Bar(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Balance(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Balance(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Master_Volume(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Master_Volume(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_CM(COMM_DEV_TYPE_E fromDev, unsigned char value); + int cfbc_Get_CM(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_DNLP(COMM_DEV_TYPE_E fromDev, unsigned char value); + int cfbc_Get_DNLP(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Gamma(COMM_DEV_TYPE_E fromDev, unsigned char value); + int cfbc_Get_Gamma(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_WhiteBalance_OnOff(COMM_DEV_TYPE_E fromDev, unsigned char value); + int cfbc_Get_WhiteBalance_OnOff(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Auto_Backlight_OnOff(COMM_DEV_TYPE_E fromDev, unsigned char value); + int cfbc_Get_Auto_Backlight_OnOff(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_WhiteBalance_GrayPattern_OnOff(COMM_DEV_TYPE_E fromDev, int onOff); + int cfbc_TestPattern_Select(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_WhiteBalance_SetGrayPattern(COMM_DEV_TYPE_E fromDev, unsigned char value); + int cfbc_Get_WB_Batch(COMM_DEV_TYPE_E fromDev, unsigned char mode, unsigned char *r_gain, unsigned char *g_gain, unsigned char *b_gain, unsigned char *r_offset, unsigned char *g_offset, unsigned char *b_offset); + int cfbc_Set_WB_Batch(COMM_DEV_TYPE_E fromDev, unsigned char mode, unsigned char r_gain, unsigned char g_gain, unsigned char b_gain, unsigned char r_offset, unsigned char g_offset, unsigned char b_offset); + int cfbc_Set_backlight_onoff(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_backlight_onoff(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_LVDS_SSG_Set(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Set_AUTO_ELEC_MODE(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_FBC_MAINCODE_Version(COMM_DEV_TYPE_E fromDev, char sw_ver[], char build_time[], char git_ver[], char git_branch[], char build_name[]); + int cfbc_Get_FBC_Get_PANel_INFO(COMM_DEV_TYPE_E fromDev, char panel_model[]); + int cfbc_Set_FBC_panel_power_switch(COMM_DEV_TYPE_E fromDev, int switch_val); + int cfbc_Set_FBC_suspend(COMM_DEV_TYPE_E fromDev, int switch_val); + int cfbc_FBC_Send_Key_To_Fbc(COMM_DEV_TYPE_E fromDev, int keycode, int param); + int cfbc_Get_FBC_PANEL_REVERSE(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Get_FBC_PANEL_OUTPUT(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_FBC_project_id(COMM_DEV_TYPE_E fromDev, int prj_id); + int cfbc_Get_FBC_project_id(COMM_DEV_TYPE_E fromDev, int *prj_id); + int cfbc_SendRebootToUpgradeCmd(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Set_FBC_User_Setting_Default(COMM_DEV_TYPE_E fromDev, int param); + int cfbc_Set_FBC_Factory_SN(COMM_DEV_TYPE_E fromDev, const char *pSNval) ; + int cfbc_Get_FBC_Factory_SN(COMM_DEV_TYPE_E fromDev, char FactorySN[]); + int cfbc_Set_FBC_Audio_Source(COMM_DEV_TYPE_E fromDev, int value); + + int cfbc_Set_Thermal_state(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Set_LightSensor_N310(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Set_Dream_Panel_N310(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Set_MULT_PQ_N310(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Set_MEMC_N310(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Set_LockN_state(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Set_VMute(COMM_DEV_TYPE_E fromDev, unsigned char value); + int cfbc_SET_SPLIT_SCREEN_DEMO(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Set_Bluetooth_IIS_onoff(COMM_DEV_TYPE_E fromDev, int value); + int cfbc_Get_Bluetooth_IIS_onoff(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Led_onoff(COMM_DEV_TYPE_E fromDev, int val_1, int val_2, int val_3); + int fbcSetPanelStatus(COMM_DEV_TYPE_E fromDev, int value); + int fbcGetPanelStatus(COMM_DEV_TYPE_E fromDev, int *value); + int cfbc_Set_Fbc_Uboot_Stage(COMM_DEV_TYPE_E fromDev, int value); + int fbcSetEyeProtection(COMM_DEV_TYPE_E fromDev, int mode); + int fbcSetGammaValue(COMM_DEV_TYPE_E fromDev, int gamma_curve, int is_save); + int fbcSetGammaPattern(COMM_DEV_TYPE_E fromDev, unsigned short gamma_r, unsigned short gamma_g, unsigned short gamma_b); + int fbcStartUpgrade(char *file_name, int mode, int blk_size); + int fbcRelease(); + int cfbc_EnterPCMode(int value); + +private: + int cfbcSetValueInt(COMM_DEV_TYPE_E fromDev, int cmd_id, int value, int value_count); + int cfbcGetValueInt(COMM_DEV_TYPE_E fromDev, int cmd_id, int *value, int value_count = 1); +}; + +extern CFbcCommunication *GetSingletonFBC(); + +#endif diff --git a/tv/tvserver/libtv/fbcutils/fbcutils.cpp b/tv/tvserver/libtv/fbcutils/fbcutils.cpp new file mode 100644 index 0000000..949ce30 --- a/dev/null +++ b/tv/tvserver/libtv/fbcutils/fbcutils.cpp @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "fbcutils" + +#include "fbcutils.h" +#include <tvconfig.h> +#include <tvutils.h> + +#include <ctype.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <CTvLog.h> + + +using namespace android; + +static int gFBCPrjInfoRDPass = 0; +static char gFBCPrjInfoBuf[1024] = {0}; + + +int rebootSystemByEdidInfo() +{ + int ret = -1; + int fd = -1; + int edid_info_len = 256; + unsigned char fbc_edid_info[edid_info_len]; + int env_different_as_cur = 0; + char outputmode_prop_value[256]; + char lcd_reverse_prop_value[256]; + + LOGD("get edid info from fbc!"); + memset(outputmode_prop_value, '\0', 256); + memset(lcd_reverse_prop_value, '\0', 256); + getBootEnv(UBOOTENV_OUTPUTMODE, outputmode_prop_value, "null" ); + getBootEnv(UBOOTENV_LCD_REVERSE, lcd_reverse_prop_value, "null" ); + + fd = open("/sys/class/amhdmitx/amhdmitx0/edid_info", O_RDWR); + if (fd < 0) { + LOGE("open edid node error"); + return -1; + } + ret = read(fd, fbc_edid_info, edid_info_len); + if (ret < 0) { + LOGE("read edid node error"); + return -1; + } + + if ((0xfb == (unsigned char)fbc_edid_info[250]) && (0x0c == (unsigned char)fbc_edid_info[251])) { + LOGD("RX is FBC!"); + // set outputmode env + ret = 0;//is Fbc + switch (fbc_edid_info[252] & 0x0f) { + case 0x0: + if (0 != strcmp(outputmode_prop_value, "1080p") + && 0 != strcmp(outputmode_prop_value, "1080p50hz")) { + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_OUTPUTMODE, "1080p"); + } + break; + case 0x1: + if (0 != strcmp(outputmode_prop_value, "4k2k60hz420") && + 0 != strcmp(outputmode_prop_value, "4k2k50hz420") + ) { + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_OUTPUTMODE, "4k2k60hz420"); + } + break; + case 0x2: + if (0 != strcmp(outputmode_prop_value, "1366*768")) { + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_OUTPUTMODE, "1366*768"); + } + break; + default: + break; + } + + // set RX 3D Info + //switch((fbc_edid_info[252]>>4)&0x0f) + + // set lcd_reverse env + switch (fbc_edid_info[253]) { + case 0x0: + if (0 != strcmp(lcd_reverse_prop_value, "0")) { + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_LCD_REVERSE, "0"); + } + break; + case 0x1: + if (0 != strcmp(lcd_reverse_prop_value, "1")) { + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_LCD_REVERSE, "1"); + } + break; + default: + break; + } + } + close(fd); + fd = -1; + //ret = -1; + if (1 == env_different_as_cur) { + LOGD("env change , reboot system"); + system("reboot"); + } + return ret; +} + +int rebootSystemByUartPanelInfo(CFbcCommunication *fbc) +{ + int ret = -1; + char outputmode_prop_value[256] = {0}; + char lcd_reverse_prop_value[256] = {0}; + int env_different_as_cur = 0; + int panel_reverse = -1; + int panel_outputmode = -1; + + char panel_model[64] = {0}; + + if (fbc == NULL) { + LOGE("there is no fbc!!!"); + return -1; + } + + fbc->cfbc_Get_FBC_Get_PANel_INFO(COMM_DEV_SERIAL, panel_model); + if (0 == panel_model[0]) { + LOGD("device is not fbc"); + return -1; + } + LOGD("device is fbc, get panel info from fbc!"); + getBootEnv(UBOOTENV_OUTPUTMODE, outputmode_prop_value, "null" ); + getBootEnv(UBOOTENV_LCD_REVERSE, lcd_reverse_prop_value, "null" ); + + fbc->cfbc_Get_FBC_PANEL_REVERSE(COMM_DEV_SERIAL, &panel_reverse); + fbc->cfbc_Get_FBC_PANEL_OUTPUT(COMM_DEV_SERIAL, &panel_outputmode); + LOGD("panel_reverse = %d, panel_outputmode = %d", panel_reverse, panel_outputmode); + LOGD("panel_output prop = %s, panel reverse prop = %s", outputmode_prop_value, lcd_reverse_prop_value); + switch (panel_outputmode) { + case T_1080P50HZ: + if ( NULL ==strstr (outputmode_prop_value, "1080p") ) { + LOGD("panel_output changed to 1080p50hz"); + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_OUTPUTMODE, "1080p50hz"); + setBootEnv(UBOOTENV_HDMIMODE, "1080p50hz"); + } + break; + case T_2160P50HZ420: + if ( (NULL == strstr(outputmode_prop_value, "2160p")) || (NULL == strstr(outputmode_prop_value, "420")) ) { + LOGD("panel_output changed to 2160p50hz420"); + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_OUTPUTMODE, "2160p50hz420"); + setBootEnv(UBOOTENV_HDMIMODE, "2160p50hz420"); + } + break; + case T_1080P50HZ44410BIT: + if ( (NULL == strstr(outputmode_prop_value, "1080p")) || (NULL == strstr(outputmode_prop_value, "44410bit")) ) { + LOGD("panel_output changed to 1080p50hz44410bit"); + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_OUTPUTMODE, "1080p50hz44410bit"); + setBootEnv(UBOOTENV_HDMIMODE, "1080p50hz44410bit"); + } + break; + case T_2160P50HZ42010BIT: + if ( (NULL == strstr(outputmode_prop_value, "2160p")) || (NULL == strstr(outputmode_prop_value, "42010bit")) ) { + LOGD("panel_output changed to 2160p50hz42010bit"); + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_OUTPUTMODE, "2160p50hz42010bit"); + setBootEnv(UBOOTENV_HDMIMODE, "2160p50hz42010bit"); + } + break; + case T_2160P50HZ42210BIT: + if ( (NULL == strstr(outputmode_prop_value, "2160p")) || (NULL == strstr(outputmode_prop_value, "42210bit")) ) { + LOGD("panel_output changed to 2160p50hz42210bit"); + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_OUTPUTMODE, "2160p50hz42210bit"); + setBootEnv(UBOOTENV_HDMIMODE, "2160p50hz42210bit"); + } + break; + case T_2160P50HZ444: + if ( (NULL == strstr(outputmode_prop_value, "2160p")) || (NULL == strstr(outputmode_prop_value, "444")) ) { + LOGD("panel_output changed to 2160p50hz444"); + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_OUTPUTMODE, "2160p50hz444"); + setBootEnv(UBOOTENV_HDMIMODE, "2160p50hz444"); + } + break; + default: + break; + } + + // set RX 3D Info + //switch((fbc_edid_info[252]>>4)&0x0f) + + // set lcd_reverse env + switch (panel_reverse) { + case 0x0: + if (0 != strcmp(lcd_reverse_prop_value, "0")) { + LOGD("panel_reverse changed to 0"); + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_LCD_REVERSE, "0"); + } + break; + case 0x1: + if (0 != strcmp(lcd_reverse_prop_value, "1")) { + if (0 == env_different_as_cur) { + env_different_as_cur = 1; + } + setBootEnv(UBOOTENV_LCD_REVERSE, "1"); + } + break; + default: + break; + } + + ret = -1; + if (1 == env_different_as_cur) { + LOGD("env change , reboot system"); + system("reboot"); + } + return 0; +} + +int GetPlatformProjectInfoSrc() +{ + const char *config_value; + + config_value = config_get_str(CFG_SECTION_TV, "platform.projectinfo.src", "null"); + if (strcmp(config_value, "null") == 0 || strcmp(config_value, "prop") == 0) { + return 0; + } else if (strcmp(config_value, "emmckey") == 0) { + return 1; + } else if (strcmp(config_value, "fbc_ver") == 0) { + return 2; + } + + return 0; +} + +unsigned int CalCRC32(unsigned int crc, const unsigned char *ptr, unsigned int buf_len) +{ + static const unsigned int s_crc32[16] = { + 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, + 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344, 0xd6d6a3e8, + 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c}; + unsigned int crcu32 = crc; + //if (buf_len < 0) + // return 0; + if (!ptr) return 0; + crcu32 = ~crcu32; + while (buf_len--) { + unsigned char b = *ptr++; + crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; + crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; + } + return ~crcu32; +} + +static int isProjectInfoValid(char *data_str, int chksum_head_len, int ver_len) +{ + int tmp_len = 0, tmp_ver = 0; + char *endp = NULL; + unsigned long src_chksum = 0, cal_chksum = 0; + char tmp_buf[129] = { 0 }; + + if (data_str != NULL) { + tmp_len = strlen(data_str); + if (tmp_len > chksum_head_len + ver_len) { + cal_chksum = CalCRC32(0, (unsigned char *)(data_str + chksum_head_len), tmp_len - chksum_head_len); + memcpy(tmp_buf, data_str, chksum_head_len); + tmp_buf[chksum_head_len] = 0; + src_chksum = strtoul(tmp_buf, &endp, 16); + if (cal_chksum == src_chksum) { + memcpy(tmp_buf, data_str + chksum_head_len, ver_len); + if ((tmp_buf[0] == 'v' || tmp_buf[0] == 'V') && isxdigit(tmp_buf[1]) && isxdigit(tmp_buf[2]) && isxdigit(tmp_buf[3])) { + tmp_ver = strtoul(tmp_buf + 1, &endp, 16); + if (tmp_ver <= 0) { + LOGD("%s, project_info data version error!!!", __FUNCTION__); + return -1; + } + } else { + LOGD("%s, project_info data version error!!!", __FUNCTION__); + return -1; + } + + return tmp_ver; + } else { + LOGD("%s, cal_chksum = %x", __FUNCTION__, (unsigned int)cal_chksum); + LOGD("%s, src_chksum = %x", __FUNCTION__, (unsigned int)src_chksum); + } + } + + LOGD("%s, project_info data error!!!", __FUNCTION__); + return -1; + } + + LOGD("%s, project_info data is NULL!!!", __FUNCTION__); + return -1; +} + +static int GetProjectInfoOriData(char data_str[], CFbcCommunication *fbcIns) +{ + int src_type = GetPlatformProjectInfoSrc(); + + if (src_type == 0) { + //memset(data_str, '\0', sizeof(data_str));//sizeof pointer has issue + getBootEnv(UBOOTENV_PROJECT_INFO, data_str, (char *)"null"); + if (strcmp(data_str, "null") == 0) { + LOGE("%s, get project info data error!!!", __FUNCTION__); + return -1; + } + + return 0; + } else if (src_type == 1) { + return -1; + } else if (src_type == 2) { + int i = 0, tmp_len = 0, tmp_val = 0, item_cnt = 0; + int tmp_rd_fail_flag = 0; + unsigned int cal_chksum = 0; + char sw_version[64]; + char build_time[64]; + char git_version[64]; + char git_branch[64]; + char build_name[64]; + char tmp_buf[512] = {0}; + + if (fbcIns != NULL) { + if (gFBCPrjInfoRDPass == 0) { + memset((void *)gFBCPrjInfoBuf, 0, sizeof(gFBCPrjInfoBuf)); + } + + if (gFBCPrjInfoRDPass == 1) { + strcpy(data_str, gFBCPrjInfoBuf); + LOGD("%s, rd once just return, data_str = %s", __FUNCTION__, data_str); + return 0; + } + + if (fbcIns->cfbc_Get_FBC_MAINCODE_Version(COMM_DEV_SERIAL, sw_version, build_time, git_version, git_branch, build_name) == 0) { + if (sw_version[0] == '1' || sw_version[0] == '2') { + strcpy(build_name, "2"); + + strcpy(tmp_buf, "v001,fbc_"); + strcat(tmp_buf, build_name); + strcat(tmp_buf, ",4k2k60hz420,no_rev,"); + strcat(tmp_buf, "HV550QU2-305"); + strcat(tmp_buf, ",8o8w,0,0"); + cal_chksum = CalCRC32(0, (unsigned char *)tmp_buf, strlen(tmp_buf)); + sprintf(data_str, "%08x,%s", cal_chksum, tmp_buf); + LOGD("%s, data_str = %s", __FUNCTION__, data_str); + } else { + tmp_val = 0; + if (fbcIns->cfbc_Get_FBC_project_id(COMM_DEV_SERIAL, &tmp_val) == 0) { + sprintf(build_name, "fbc_%d", tmp_val); + } else { + tmp_rd_fail_flag = 1; + strcpy(build_name, "fbc_0"); + LOGD("%s, get project id from fbc error!!!", __FUNCTION__); + } + + strcpy(tmp_buf, "v001,"); + strcat(tmp_buf, build_name); + strcat(tmp_buf, ",4k2k60hz420,no_rev,"); + + memset(git_branch, 0, sizeof(git_branch)); + if (fbcIns->cfbc_Get_FBC_Get_PANel_INFO(COMM_DEV_SERIAL, git_branch) == 0) { + strcat(tmp_buf, git_branch); + } else { + tmp_rd_fail_flag = 1; + strcat(tmp_buf, build_name); + LOGD("%s, get panel info from fbc error!!!", __FUNCTION__); + } + + strcat(tmp_buf, ",8o8w,0,0"); + cal_chksum = CalCRC32(0, (unsigned char *)tmp_buf, strlen(tmp_buf)); + sprintf(data_str, "%08x,%s", cal_chksum, tmp_buf); + LOGD("%s, data_str = %s", __FUNCTION__, data_str); + + if (tmp_rd_fail_flag == 0) { + gFBCPrjInfoRDPass = 1; + strcpy(gFBCPrjInfoBuf, data_str); + } + } + + return 0; + } + + return -1; + } + } + + return -1; +} + +static int handleProjectInfoByVersion(int ver, int item_ind, char *item_str, project_info_t *proj_info_ptr) +{ + if (ver == 1) { + if (item_ind == 0) { + strncpy(proj_info_ptr->version, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } else if (item_ind == 1) { + strncpy(proj_info_ptr->panel_type, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } else if (item_ind == 2) { + strncpy(proj_info_ptr->panel_outputmode, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } else if (item_ind == 3) { + strncpy(proj_info_ptr->panel_rev, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } else if (item_ind == 4) { + strncpy(proj_info_ptr->panel_name, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } else if (item_ind == 5) { + strncpy(proj_info_ptr->amp_curve_name, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } + } else { + if (item_ind == 0) { + strncpy(proj_info_ptr->version, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } else if (item_ind == 1) { + strncpy(proj_info_ptr->panel_type, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } else if (item_ind == 2) { + strncpy(proj_info_ptr->panel_name, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } else if (item_ind == 3) { + strncpy(proj_info_ptr->panel_outputmode, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } else if (item_ind == 4) { + strncpy(proj_info_ptr->panel_rev, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } else if (item_ind == 5) { + strncpy(proj_info_ptr->amp_curve_name, item_str, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } + } + + return 0; +} + +int GetProjectInfo(project_info_t *proj_info_ptr, CFbcCommunication *fbcIns) +{ + int i = 0, tmp_ret = 0, tmp_val = 0, tmp_len = 0; + int item_cnt = 0, handle_prj_info_data_flag = 0; + char *token = NULL; + const char *strDelimit = ","; + char tmp_buf[1024] = { 0 }; + char data_str[1024] = { 0 }; + + if (GetProjectInfoOriData(data_str, fbcIns) < 0) { + return -1; + } + + memset((void *)proj_info_ptr->version, 0, CC_PROJECT_INFO_ITEM_MAX_LEN); + memset((void *)proj_info_ptr->panel_type, 0, CC_PROJECT_INFO_ITEM_MAX_LEN); + memset((void *)proj_info_ptr->panel_outputmode, 0, CC_PROJECT_INFO_ITEM_MAX_LEN); + memset((void *)proj_info_ptr->panel_rev, 0, CC_PROJECT_INFO_ITEM_MAX_LEN); + memset((void *)proj_info_ptr->panel_name, 0, CC_PROJECT_INFO_ITEM_MAX_LEN); + memset((void *)proj_info_ptr->amp_curve_name, 0, CC_PROJECT_INFO_ITEM_MAX_LEN); + + //check project info data is valid + handle_prj_info_data_flag = isProjectInfoValid(data_str, CC_HEAD_CHKSUM_LEN, CC_VERSION_LEN); + + //handle project info data + if (handle_prj_info_data_flag > 0) { + item_cnt = 0; + memset((void *)tmp_buf, 0, sizeof(tmp_buf)); + strncpy(tmp_buf, data_str + CC_HEAD_CHKSUM_LEN, sizeof(tmp_buf) - 1); + token = strtok(tmp_buf, strDelimit); + while (token != NULL) { + handleProjectInfoByVersion(handle_prj_info_data_flag, item_cnt, token, proj_info_ptr); + + token = strtok(NULL, strDelimit); + item_cnt += 1; + } + + return 0; + } + + return -1; +} diff --git a/tv/tvserver/libtv/fbcutils/fbcutils.h b/tv/tvserver/libtv/fbcutils/fbcutils.h new file mode 100644 index 0000000..3f4ed40 --- a/dev/null +++ b/tv/tvserver/libtv/fbcutils/fbcutils.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _FBC_UTILS_H_ +#define _FBC_UTILS_H_ + +#include "CFbcCommunication.h" +#include <stdio.h> + +#define CC_HEAD_CHKSUM_LEN (9) +#define CC_VERSION_LEN (5) +#define CC_PROJECT_INFO_ITEM_MAX_LEN (64) + +typedef struct project_info_s { + char version[CC_PROJECT_INFO_ITEM_MAX_LEN]; + char panel_type[CC_PROJECT_INFO_ITEM_MAX_LEN]; + char panel_outputmode[CC_PROJECT_INFO_ITEM_MAX_LEN]; + char panel_rev[CC_PROJECT_INFO_ITEM_MAX_LEN]; + char panel_name[CC_PROJECT_INFO_ITEM_MAX_LEN]; + char amp_curve_name[CC_PROJECT_INFO_ITEM_MAX_LEN]; +} project_info_t; + +extern int rebootSystemByEdidInfo(); +extern int rebootSystemByUartPanelInfo(CFbcCommunication *fbc = NULL); +extern unsigned int CalCRC32(unsigned int crc, const unsigned char *ptr, unsigned int buf_len); +extern int GetProjectInfo(project_info_t *proj_info_ptr, CFbcCommunication *fbcIns = NULL); + +#endif diff --git a/tv/tvserver/libtv/gpio/CTvGpio.cpp b/tv/tvserver/libtv/gpio/CTvGpio.cpp new file mode 100644 index 0000000..22888e2 --- a/dev/null +++ b/tv/tvserver/libtv/gpio/CTvGpio.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_NDEBUG 0 + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvGpio" + +#include <CTvLog.h> +#include <stdlib.h> +#include <string.h> +#include <tvutils.h> + +#include "CTvGpio.h" + + +CTvGpio::CTvGpio() +{ + mGpioPinNum = 0; + memset(mGpioName, 0, 64); +} + +CTvGpio::~CTvGpio() +{ + if (mGpioPinNum > 0) + tvWriteSysfs(GPIO_UNEXPORT, mGpioPinNum); +} + +int CTvGpio::processCommand(const char *port_name, bool is_out, int edge) +{ + LOGV("%s, port_name=[%s], is_out=[%d], edge=[%d], gpio_pin=[%d]", __FUNCTION__, port_name, is_out, edge, mGpioPinNum); + if (strncmp(port_name, "GPIO", 4) != 0) + return -1; + + char pin_value[10] = {0}; + if (strcmp(mGpioName, port_name) != 0 && tvWriteSysfs(GPIO_NAME_TO_PIN, port_name)) { + strcpy(mGpioName, port_name); + tvReadSysfs(GPIO_NAME_TO_PIN, pin_value); + mGpioPinNum = atoi(pin_value); + } + LOGV("%s, port_name=[%s], is_out=[%d], edge=[%d], gpio_pin=[%d]", __FUNCTION__, port_name, is_out, edge, mGpioPinNum); + + int ret = -1; + if (mGpioPinNum > 0) { + if (is_out) { + ret = setGpioOutEdge(edge); + } else { + ret = getGpioInEdge(); + } + } + + return ret; +} + +int CTvGpio::setGpioOutEdge(int edge) +{ + LOGD("%s, gpio_pin=[%d], edge=[%d]", __FUNCTION__, mGpioPinNum, edge); + + char direction[128] = {0}; + char value[128] = {0}; + GPIO_DIRECTION(direction, mGpioPinNum); + GPIO_VALUE(value, mGpioPinNum); + LOGV("dirction path:[%s]", direction); + LOGV("value path:[%s]", value); + + if (needExportAgain(direction)) { + tvWriteSysfs(GPIO_EXPORT, mGpioPinNum); + } + tvWriteSysfs(direction, "out"); + tvWriteSysfs(value, edge); + + return 0; +} + +int CTvGpio::getGpioInEdge() +{ + LOGD("%s, gpio_pin=[%d]", __FUNCTION__, mGpioPinNum); + + char direction[128] = {0}; + char value[128] = {0}; + char edge[128] = {0}; + GPIO_DIRECTION(direction, mGpioPinNum); + GPIO_VALUE(value, mGpioPinNum); + LOGV("dirction path:[%s]", direction); + LOGV("value path:[%s]", value); + + if (needExportAgain(direction)) { + tvWriteSysfs(GPIO_EXPORT, mGpioPinNum); + } + tvWriteSysfs(direction, "in"); + tvReadSysfs(value, edge); + LOGD("edge:[%s]", edge); + + return atoi(edge); +} + +bool CTvGpio::needExportAgain(char *path) { + return !isFileExist(path); +} + diff --git a/tv/tvserver/libtv/gpio/CTvGpio.h b/tv/tvserver/libtv/gpio/CTvGpio.h new file mode 100644 index 0000000..6cffc68 --- a/dev/null +++ b/tv/tvserver/libtv/gpio/CTvGpio.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _C_TV_GPIO_H_ +#define _C_TV_GPIO_H_ + +#define GPIO_NAME_TO_PIN "/sys/class/aml_gpio/name_to_pin" +#define GPIO_EXPORT "/sys/class/gpio/export" +#define GPIO_UNEXPORT "/sys/class/gpio/unexport" +#define GPIO_DIRECTION(x, y) sprintf(x, "/sys/class/gpio/gpio%d/direction", y) +#define GPIO_VALUE(x, y) sprintf(x, "/sys/class/gpio/gpio%d/value", y) + + +class CTvGpio { +public: + CTvGpio(); + ~CTvGpio(); + /** + * @description set/get gpio status or level + * @param port_name name of gpio + * @param is_out true gpio out, false gpio in + * @param edge 1 high, 0 low + */ + int processCommand(const char *port_name, bool is_out, int edge); + +private: + int setGpioOutEdge(int edge); + int getGpioInEdge(); + bool needExportAgain(char *path); + + int mGpioPinNum; + char mGpioName[64]; +}; + +#endif diff --git a/tv/tvserver/libtv/tv/AutoBackLight.cpp b/tv/tvserver/libtv/tv/AutoBackLight.cpp new file mode 100644 index 0000000..2e200ca --- a/dev/null +++ b/tv/tvserver/libtv/tv/AutoBackLight.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "AutoBackLight" + +#include "AutoBackLight.h" +#include "../tvsetting/CTvSetting.h" +#include <tvconfig.h> +#include <tvutils.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> +#include <dlfcn.h> +#include <linux/fb.h> +#include <stdlib.h> +#include <cutils/properties.h> + +AutoBackLight::AutoBackLight() +{ + mAutoBacklightSource = SOURCE_TV; + mCur_source_default_backlight = 100; + mCur_sig_state == SIG_STATE_NOSIG; + mAutoBacklight_OnOff_Flag = false; + mCurrent_backlight = 100; + mCur_dest_backlight = 100; +} + +AutoBackLight::~AutoBackLight() +{ + mAutoBacklight_OnOff_Flag = false; +} + +bool AutoBackLight::isAutoBacklightOn() +{ + return mAutoBacklight_OnOff_Flag; +} + +void AutoBackLight::updateSigState(int state) +{ + mCur_sig_state = state; + LOGD("updateSigState = %d", mCur_sig_state); +} + +void AutoBackLight::startAutoBacklight( tv_source_input_t tv_source_input ) +{ + mAutoBacklightSource = tv_source_input; + mCur_source_default_backlight = CVpp::getInstance()->GetBacklight(tv_source_input); + mCurrent_backlight = mCur_source_default_backlight; + CVpp::getInstance()->SetBacklight(mCur_source_default_backlight, tv_source_input, 1); + + /* + mDefault_auto_bl_value = def_source_bl_value; + dynamicGamma = mDefault_auto_bl_value * mCur_source_default_backlight / 100; + // this if should not happen + if (dynamicGamma > mCur_source_default_backlight) { + dynamicGamma = mCur_source_default_backlight; + } + */ + + if (!mAutoBacklight_OnOff_Flag) { + mAutoBacklight_OnOff_Flag = true; + this->run("AutoBackLight"); + } +} + +void AutoBackLight::stopAutoBacklight() +{ + if (mAutoBacklight_OnOff_Flag) { + mAutoBacklight_OnOff_Flag = false; + CVpp::getInstance()->SetBacklight(mCur_source_default_backlight, mAutoBacklightSource, 1); + } +} + +/** + * @ description: tpv project + * @ return:value + * value <= 20: mCur_dest_backlight is 14 + * 20 < value <= 160: mCur_dest_backlight is 57 + *160 < value: mCur_dest_backlight is 100 + */ +void AutoBackLight::adjustDstBacklight() +{ + if (mCur_sig_state == SIG_STATE_STABLE) { + //the node is used to adjust current ts is static or dynamtic frame + char temp_str = 0; + int fd = open("/sys/module/di/parameters/frame_dynamic", O_RDWR); + if (fd <= 0) { + LOGE("open /sys/module/di/parameters/frame_dynamic ERROR!!\n"); + return; + } + + if (read(fd, &temp_str, 1) > 0) { + + if (temp_str == 'N') { + mCur_dest_backlight = mCur_source_default_backlight; + } else if (temp_str == 'Y') { + int pwm = HistogramGet_AVE(); + if (pwm <= 20) { + mCur_dest_backlight = 14; + } else if (pwm > 20 && pwm <= 160) { + mCur_dest_backlight = 57; + } else { + mCur_dest_backlight = 100; + } + //LOGD("pwm = %d, mCur_dest_backlight = %d", pwm, mCur_dest_backlight); + } + } + close(fd); + } else { + mCurrent_backlight = mCur_dest_backlight = mCur_source_default_backlight; + CVpp::getInstance()->SetBacklight(mCurrent_backlight, mAutoBacklightSource, 0); + } + + /* + if (pwm > 0) + pwm_max = pwm; + else + pwm_min = pwm; + pwm = 255 - pwm; + int average = (pwm_min + pwm_max) / 2; + dynamicGammaOffset = (pwm - average) / 10; + dynamicGammaOffset = dynamicGammaOffset * mDefault_auto_bl_value / 100; + + //the node is used to adjust current ts is static or dynamtic frame + char temp_str = 0; + int fd = open("/sys/module/di/parameters/frame_dynamic", O_RDWR); + if (fd <= 0) { + LOGE("open /sys/module/di/parameters/frame_dynamic ERROR!!\n"); + return; + } + + if (read(fd, &temp_str, 1) > 0) { + if (temp_str== 'N') { + mCur_dest_backlight = mCur_source_default_backlight; + } + else if (temp_str == 'Y') { + mCur_dest_backlight = dynamicGamma + dynamicGammaOffset; + + if (mCur_dest_backlight > mCur_source_default_backlight) { + mCur_dest_backlight = mCur_source_default_backlight; + } + else if (mCur_dest_backlight < 0) { + mCur_dest_backlight = 0; + } + } + } + close(fd); + */ +} + +void AutoBackLight::adjustBacklight() +{ + if (mCurrent_backlight == mCur_dest_backlight) { + return; + } else if ((mCurrent_backlight - mCur_dest_backlight) > -2 && (mCurrent_backlight - mCur_dest_backlight) < 2) { + mCurrent_backlight = mCur_dest_backlight; + CVpp::getInstance()->SetBacklight(mCurrent_backlight, mAutoBacklightSource, 0); + } else if (mCurrent_backlight < mCur_dest_backlight) { + mCurrent_backlight = mCurrent_backlight + 2; + CVpp::getInstance()->SetBacklight(mCurrent_backlight, mAutoBacklightSource, 0); + } else if (mCurrent_backlight > mCur_dest_backlight) { + mCurrent_backlight = mCurrent_backlight - 2; + CVpp::getInstance()->SetBacklight(mCurrent_backlight, mAutoBacklightSource, 0); + } + + //LOGD("mCurrent_backlight = %d", mCurrent_backlight); +} + +/** + * @ description: get current picture's average brightness + * @ return: 0~255,0 is darkest,255 is brightest + */ +int AutoBackLight::HistogramGet_AVE() +{ + int hist_ave = 0; + tvin_parm_t vdinParam; + if (0 == CTvin::getInstance()->VDIN_GetVdinParam(&vdinParam)) { + if (vdinParam.pixel_sum != 0) { + hist_ave = vdinParam.luma_sum / vdinParam.pixel_sum; + LOGD("[hist_ave][%d].", hist_ave); + return hist_ave; + } + LOGE("vdinParam.pixel_sum is zero, so the value is infinity\n"); + return -1; + } + LOGE("VDIN_GetVdinParam get data error!!!\n"); + return -1; +} + +bool AutoBackLight::threadLoop() +{ + int sleeptime = 50;//ms + int adjustBacklightCount = 0; + while ( mAutoBacklight_OnOff_Flag ) { + usleep ( sleeptime * 1000 ); + adjustBacklightCount++; + if (adjustBacklightCount == 24) { + adjustBacklightCount = 0; + adjustDstBacklight(); + } + adjustBacklight(); + } + + return false;//return true, run again, return false,not run. +} diff --git a/tv/tvserver/libtv/tv/AutoBackLight.h b/tv/tvserver/libtv/tv/AutoBackLight.h new file mode 100644 index 0000000..9ba23f2 --- a/dev/null +++ b/tv/tvserver/libtv/tv/AutoBackLight.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_AUTOBACKLIGHT_H) +#define _AUTOBACKLIGHT_H +#include "../tvin/CTvin.h" +#include <utils/Thread.h> +#include "../vpp/CVpp.h" + +class AutoBackLight: public Thread { +private: + tv_source_input_t mAutoBacklightSource; + int mCur_source_default_backlight; + int mCur_sig_state; + bool mAutoBacklight_OnOff_Flag; + int mCurrent_backlight; + int mCur_dest_backlight; + + void adjustDstBacklight(); + void adjustBacklight(); + int HistogramGet_AVE(); + bool threadLoop(); + +public: + enum SIG_STATE { + SIG_STATE_STABLE = 1, + SIG_STATE_NOSIG = 2, + }; + + AutoBackLight(); + ~AutoBackLight(); + void updateSigState(int state); + void startAutoBacklight( tv_source_input_t tv_source_input ); + void stopAutoBacklight(); + bool isAutoBacklightOn(); +}; +#endif diff --git a/tv/tvserver/libtv/tv/CAutoPQparam.cpp b/tv/tvserver/libtv/tv/CAutoPQparam.cpp new file mode 100644 index 0000000..2dc76f5 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CAutoPQparam.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CAutoPQparam" + +#include "../vpp/CVpp.h" +#include "CAutoPQparam.h" +#include "../tvsetting/CTvSetting.h" +#include <tvconfig.h> +#include <tvutils.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> +#include <dlfcn.h> +#include <linux/fb.h> +#include <stdlib.h> +#include <cutils/properties.h> + + +CAutoPQparam::CAutoPQparam() +{ + preFmtType = 0; + curFmtType = 0; + autofreq_checkcount = 0; + autofreq_checkflag = 0; + mAutoPQ_OnOff_Flag = false; +} + +CAutoPQparam::~CAutoPQparam() +{ + mAutoPQ_OnOff_Flag = false; +} + +bool CAutoPQparam::isAutoPQing() +{ + return mAutoPQ_OnOff_Flag; +} + +void CAutoPQparam::startAutoPQ( tv_source_input_t tv_source_input ) +{ +#ifndef CC_PROJECT_DISABLE_AUTO_PQ + mAutoPQSource = tv_source_input; + + LOGD("---------startAutoPQParameters --------mAutoPQ_OnOff_Flag = %d", mAutoPQ_OnOff_Flag); + if (!mAutoPQ_OnOff_Flag) { + mAutoPQ_OnOff_Flag = true; + this->run("CAutoPQparam"); + } +#else + LOGD("AutoPQparam disable.\n"); +#endif +} + +void CAutoPQparam::stopAutoPQ() +{ +#ifndef CC_PROJECT_DISABLE_AUTO_PQ + LOGD("---------stopAutoPQParameters -------- mAutoPQ_OnOff_Flag = %d", mAutoPQ_OnOff_Flag); + if (mAutoPQ_OnOff_Flag) { + mAutoPQ_OnOff_Flag = false; + } +#else + LOGD("AutoPQparam disable.\n"); +#endif +} + +/** +TVIN_SIG_FMT_HDMI_720X480P_60HZ = 0x402 nodeVal<900 +TVIN_SIG_FMT_HDMI_1920X1080P_60HZ = 0x40a 900<nodeVal<2000 +TVIN_SIG_FMT_HDMI_3840_2160_00HZ = 0x445 nodeVal>2000 +*/ +int CAutoPQparam::adjustPQparameters() +{ + int fd = -1; + int nodeVal = 0, ret = 0; + int new_frame_count = 0; + float frame_rate = 0; + float frame_rate_ave = 0; + char s[21]; + char str[10]; + tvin_sig_fmt_e sig_fmt; + is_3d_type_t _3d_type = INDEX_2D; + tvin_trans_fmt trans_fmt = TVIN_TFMT_2D; + + fd = open("/sys/module/amvideo/parameters/new_frame_count", O_RDONLY); + if (fd <= 0) { + LOGE("open /sys/module/amvideo/parameters/new_frame_count ERROR!!error = -%s- \n", strerror ( errno )); + return -1; + } + memset(s, 0, sizeof(s)); + read(fd, s, sizeof(s)); + close(fd); + new_frame_count = atoi(s); + + if (new_frame_count != 0) { + + fd = open(SYS_VIDEO_FRAME_HEIGHT, O_RDONLY); + if (fd <= 0) { + LOGE("open %s ERROR!!error = -%s- \n",SYS_VIDEO_FRAME_HEIGHT, strerror ( errno )); + return -1; + } + memset(s, 0, sizeof(s)); + read(fd, s, sizeof(s)); + close(fd); + nodeVal = atoi(s); + + if (nodeVal <= 576) { + curFmtType = 1; + sig_fmt = TVIN_SIG_FMT_HDMI_720X480P_60HZ; + } else if (nodeVal > 567 && nodeVal <= 1088) { + curFmtType = 2; + sig_fmt = TVIN_SIG_FMT_HDMI_1920X1080P_60HZ; + } else { + curFmtType = 3; + sig_fmt = TVIN_SIG_FMT_HDMI_3840_2160_00HZ; + } + + if (curFmtType != preFmtType) { + LOGD("adjustPQparameters: nodeVal = %d, sig_fmt = %d.", nodeVal, sig_fmt); + ret = CVpp::getInstance()->LoadVppSettings (mAutoPQSource, sig_fmt, _3d_type, trans_fmt); + } + + preFmtType = curFmtType; + + } else { + if (preFmtType != 0 || curFmtType != 0) { + preFmtType = 0; + curFmtType = 0; + } + } + return ret; +} + +bool CAutoPQparam::threadLoop() +{ + int sleeptime = 1000;//ms + while ( mAutoPQ_OnOff_Flag ) { + usleep ( sleeptime * 1000 ); + adjustPQparameters(); + } + + return false;//return true, run again, return false,not run. +} diff --git a/tv/tvserver/libtv/tv/CAutoPQparam.h b/tv/tvserver/libtv/tv/CAutoPQparam.h new file mode 100644 index 0000000..1910245 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CAutoPQparam.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CAUTOPQPARAM_H) +#define _CAUTOPQPARAM_H +#include "CAv.h" +#include <utils/Thread.h> +#include "../vpp/CVpp.h" +#include <tvconfig.h> + +class CAutoPQparam: public Thread { +private: + tv_source_input_t mAutoPQSource; + bool mAutoPQ_OnOff_Flag; + int preFmtType, curFmtType, autofreq_checkcount, autofreq_checkflag; + int adjustPQparameters(); + bool threadLoop(); + +public: + + CAutoPQparam(); + ~CAutoPQparam(); + void startAutoPQ( tv_source_input_t tv_source_input ); + void stopAutoPQ(); + bool isAutoPQing(); +}; +#endif diff --git a/tv/tvserver/libtv/tv/CAv.cpp b/tv/tvserver/libtv/tv/CAv.cpp new file mode 100644 index 0000000..1d6fd7f --- a/dev/null +++ b/tv/tvserver/libtv/tv/CAv.cpp @@ -0,0 +1,677 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CAv" + +#include "CAv.h" +#include <CFile.h> +#include <tvutils.h> +#include <tvconfig.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <amstream.h> + +CAv::CAv() +{ + mpObserver = NULL; + mTvPlayDevId = 0; + mVideoLayerState = VIDEO_LAYER_NONE; + mFdAmVideo = -1; +} + +CAv::~CAv() +{ +} + +int CAv::SetVideoWindow(int x, int y, int w, int h) +{ +#ifdef SUPPORT_ADTV + return AM_AV_SetVideoWindow (mTvPlayDevId, x, y, w, h ); +#else + return -1; +#endif +} + +int CAv::Open() +{ +#ifdef SUPPORT_ADTV + AM_AV_OpenPara_t para_av; + memset ( ¶_av, 0, sizeof ( AM_AV_OpenPara_t ) ); + int rt = AM_AV_Open ( mTvPlayDevId, ¶_av ); + if ( rt != DVB_SUCCESS ) { + LOGD ( "%s, dvbplayer_open fail %d %d\n!" , __FUNCTION__, mTvPlayDevId, rt ); + return -1; + } + + //open audio channle output + AM_AOUT_OpenPara_t aout_para; + memset ( &aout_para, 0, sizeof ( AM_AOUT_OpenPara_t ) ); + rt = AM_AOUT_Open ( mTvPlayDevId, &aout_para ); + if ( DVB_SUCCESS != rt ) { + LOGD ( "%s, BUG: CANN'T OPEN AOUT\n", __FUNCTION__); + } + + mFdAmVideo = open ( PATH_VIDEO_AMVIDEO, O_RDWR ); + if ( mFdAmVideo < 0 ) { + LOGE ( "mFdAmVideo < 0, error(%s)!\n", strerror ( errno ) ); + return -1; + } + /*Register events*/ + AM_EVT_Subscribe ( mTvPlayDevId, AM_AV_EVT_AV_NO_DATA, av_evt_callback, this ); + AM_EVT_Subscribe ( mTvPlayDevId, AM_AV_EVT_AV_DATA_RESUME, av_evt_callback, this ); + AM_EVT_Subscribe ( mTvPlayDevId, AM_AV_EVT_VIDEO_SCAMBLED, av_evt_callback, this ); + AM_EVT_Subscribe ( mTvPlayDevId, AM_AV_EVT_AUDIO_SCAMBLED, av_evt_callback, this ); + AM_EVT_Subscribe ( mTvPlayDevId, AM_AV_EVT_VIDEO_NOT_SUPPORT, av_evt_callback, this ); + AM_EVT_Subscribe ( mTvPlayDevId, AM_AV_EVT_VIDEO_AVAILABLE, av_evt_callback, this ); + AM_EVT_Subscribe ( mTvPlayDevId, AM_AV_EVT_PLAYER_UPDATE_INFO, av_evt_callback, this ); + + return rt; +#else + return -1; +#endif +} + +int CAv::Close() +{ + int iRet = -1; +#ifdef SUPPORT_ADTV + iRet = AM_AV_Close ( mTvPlayDevId ); + iRet = AM_AOUT_Close ( mTvPlayDevId ); + if (mFdAmVideo > 0) { + close(mFdAmVideo); + mFdAmVideo = -1; + } +#endif + return iRet; +} + +int CAv::GetVideoStatus(int *w, int *h, int *fps, int *interlace) +{ +#ifdef SUPPORT_ADTV + AM_AV_VideoStatus_t status; + int ret = AM_AV_GetVideoStatus(mTvPlayDevId, &status); + *w = status.src_w; + *h = status.src_h; + *fps = status.fps; + *interlace = status.interlaced; + return ret; + +#else + return -1; +#endif +} + +int CAv::GetAudioStatus( int fmt[2], int sample_rate[2], int resolution[2], int channels[2], + int lfepresent[2], int *frames, int *ab_size, int *ab_data, int *ab_free) +{ +#ifdef SUPPORT_ADTV + AM_AV_AudioStatus_t status; + int ret = AM_AV_GetAudioStatus(mTvPlayDevId, &status); + if (fmt) { + fmt[0] = status.aud_fmt; + fmt[1] = status.aud_fmt_orig; + } + if (sample_rate) { + sample_rate[0] = status.sample_rate; + sample_rate[1] = status.sample_rate_orig; + } + if (resolution) { + resolution[0] = status.resolution; + resolution[1] = status.resolution_orig; + } + if (channels) { + channels[0] = status.channels; + channels[1] = status.channels_orig; + } + if (lfepresent) { + lfepresent[0] = status.lfepresent; + lfepresent[1] = status.lfepresent_orig; + } + if (frames) + *frames = status.frames; + if (ab_size) + *ab_size = status.ab_size; + if (ab_data) + *ab_data = status.ab_data; + if (ab_free) + *ab_free = status.ab_free; + + return ret; +#else + return -1; +#endif +} + +int CAv::SwitchTSAudio(int apid, int afmt) +{ +#ifdef SUPPORT_ADTV + return AM_AV_SwitchTSAudio (mTvPlayDevId, ( unsigned short ) apid, ( AM_AV_AFormat_t ) afmt ); +#else + return -1; +#endif +} + +int CAv::ResetAudioDecoder() +{ +#ifdef SUPPORT_ADTV + return AM_AV_ResetAudioDecoder ( mTvPlayDevId ); +#else + return -1; +#endif +} + +int CAv::SetADAudio(unsigned int enable, int apid, int afmt) +{ +#ifdef SUPPORT_ADTV + return AM_AV_SetAudioAd(mTvPlayDevId, enable, apid, afmt); +#else + return -1; +#endif +} + +int CAv::SetTSSource(int ts_source) +{ +#ifdef SUPPORT_ADTV + return AM_AV_SetTSSource ( mTvPlayDevId, ts_source ); +#else + return -1; +#endif +} + +int CAv::StartTS(unsigned short vpid, unsigned short apid, unsigned short pcrid, int vfmt, int afmt) +{ +#ifdef SUPPORT_ADTV + return AM_AV_StartTSWithPCR ( mTvPlayDevId, vpid, apid, pcrid, ( AM_AV_VFormat_t ) vfmt, ( AM_AV_AFormat_t ) afmt ); +#else + return -1; +#endif +} + +int CAv::StopTS() +{ +#ifdef SUPPORT_ADTV + return AM_AV_StopTS (mTvPlayDevId); +#else + return -1; +#endif +} + +int CAv::AudioGetOutputMode(int *mode) +{ +#ifdef SUPPORT_ADTV + return AM_AOUT_GetOutputMode ( mTvPlayDevId, mode ); +#else + return -1; +#endif +} + +int CAv::AudioSetOutputMode(int mode) +{ +#ifdef SUPPORT_ADTV + return AM_AOUT_SetOutputMode ( mTvPlayDevId, mode ); +#else + return -1; +#endif +} + +int CAv::AudioSetPreGain(float pre_gain) +{ +#ifdef SUPPORT_ADTV + return AM_AOUT_SetPreGain(0, pre_gain); +#else + return -1; +#endif + +} + +int CAv::AudioGetPreGain(float *gain) +{ +#ifdef SUPPORT_ADTV + return AM_AOUT_GetPreGain(0, gain); +#else + return -1; +#endif + +} + +int CAv::AudioSetPreMute(unsigned int mute) +{ +#ifdef SUPPORT_ADTV + return AM_AOUT_SetPreMute(0, mute); +#else + return -1; +#endif + +} + +int CAv::AudioGetPreMute(unsigned int *mute) +{ + int ret = -1; +#ifdef SUPPORT_ADTV + bool btemp_mute = 0; + ret = AM_AOUT_GetPreMute(0, &btemp_mute); + *mute = btemp_mute ? 1 : 0; +#endif + return ret; +} + +int CAv::EnableVideoBlackout() +{ +#ifdef SUPPORT_ADTV + return AM_AV_EnableVideoBlackout(mTvPlayDevId); +#else + return -1; +#endif + +} + +int CAv::DisableVideoBlackout() +{ +#ifdef SUPPORT_ADTV + return AM_AV_DisableVideoBlackout(mTvPlayDevId); +#else + return -1; +#endif + +} + +int CAv::DisableVideoWithBlueColor() +{ + LOGD("DisableVideoWithBlueColor"); + if (mVideoLayerState == VIDEO_LAYER_DISABLE_BLUE) { + LOGD("video is disable with blue, return"); + return 0; + } + mVideoLayerState = VIDEO_LAYER_DISABLE_BLUE; + SetVideoScreenColor ( 0, 41, 240, 110 ); // Show blue with vdin0, postblending disabled +#ifdef SUPPORT_ADTV + return AM_AV_DisableVideo(mTvPlayDevId); +#else + return -1; +#endif + +} + +int CAv::DisableVideoWithBlackColor() +{ + LOGD("DisableVideoWithBlackColor"); + if (mVideoLayerState == VIDEO_LAYER_DISABLE_BLACK) { + LOGD("video is disable with black, return"); + return 0; + } + + mVideoLayerState = VIDEO_LAYER_DISABLE_BLACK; + SetVideoScreenColor ( 0, 16, 128, 128 ); // Show black with vdin0, postblending disabled + +#ifdef SUPPORT_ADTV + return AM_AV_DisableVideo(mTvPlayDevId); +#else + return -1; +#endif +} + +//just enable video +int CAv::EnableVideoNow(bool IsShowTestScreen) +{ + LOGD("EnableVideoNow"); + + if (mVideoLayerState == VIDEO_LAYER_ENABLE) { + LOGW("video is enabled"); + return 0; + } + mVideoLayerState = VIDEO_LAYER_ENABLE; + if ( IsShowTestScreen ) { + LOGD("DisableVideoWithBlackColor"); + SetVideoScreenColor ( 0, 16, 128, 128 ); + } + +#ifdef SUPPORT_ADTV + return AM_AV_EnableVideo(mTvPlayDevId); +#else + return -1; +#endif +} + +//call disable video 2 +int CAv::ClearVideoBuffer() +{ + LOGD("ClearVideoBuffer"); + +#ifdef SUPPORT_ADTV + return AM_AV_ClearVideoBuffer(mTvPlayDevId); +#else + return -1; +#endif +} + +int CAv::startTimeShift(void *para) +{ + LOGD("startTimeShift"); + +#ifdef SUPPORT_ADTV + return AM_AV_StartTimeshift(mTvPlayDevId, (AM_AV_TimeshiftPara_t *)para); +#else + return -1; +#endif +} + +int CAv::stopTimeShift() +{ + LOGD ("stopTimeShift"); + +#ifdef SUPPORT_ADTV + return AM_AV_StopTimeshift(mTvPlayDevId); +#else + return -1; +#endif +} + +int CAv::pauseTimeShift() +{ + LOGD ( "pauseTimeShift"); + +#ifdef SUPPORT_ADTV + return AM_AV_PauseTimeshift (mTvPlayDevId); +#else + return -1; +#endif +} + +int CAv::resumeTimeShift() +{ + LOGD ( "resumeTimeShift"); + +#ifdef SUPPORT_ADTV + return AM_AV_ResumeTimeshift (mTvPlayDevId); +#else + return -1; +#endif +} + +int CAv::seekTimeShift(int pos, bool start) +{ + LOGD ( "seekTimeShift [pos:%d start:%d]", pos, start); + +#ifdef SUPPORT_ADTV + return AM_AV_SeekTimeshift (mTvPlayDevId, pos, start); +#else + return -1; +#endif +} + +int CAv::setTimeShiftSpeed(int speed) +{ + LOGD ( "setTimeShiftSpeed [%d]", speed); + int ret = 0; +#ifdef SUPPORT_ADTV + if (speed < 0) + ret = AM_AV_FastBackwardTimeshift(mTvPlayDevId, -speed); + else + ret = AM_AV_FastForwardTimeshift(mTvPlayDevId, speed); +#endif + return ret; +} + +int CAv::switchTimeShiftAudio(int apid, int afmt) +{ + LOGD ( "switchTimeShiftAudio [pid:%d, fmt:%d]", apid, afmt); +#ifdef SUPPORT_ADTV + return AM_AV_SwitchTimeshiftAudio (mTvPlayDevId, apid, afmt); +#else + return -1; +#endif +} + +int CAv::playTimeShift() +{ + LOGD ( "playTimeShift"); + +#ifdef SUPPORT_ADTV + return AM_AV_PlayTimeshift (mTvPlayDevId); +#else + return -1; +#endif +} + +//auto enable, +int CAv::EnableVideoAuto() +{ + LOGD("EnableVideoAuto"); + if (mVideoLayerState == VIDEO_LAYER_ENABLE) { + LOGW("video is enable"); + return 0; + } + mVideoLayerState = VIDEO_LAYER_ENABLE; + LOGD("DisableVideoWithBlackColor"); + SetVideoScreenColor ( 0, 16, 128, 128 ); // Show black with vdin0, postblending disabled + ClearVideoBuffer();//disable video 2 + return 0; +} + +int CAv::WaittingVideoPlaying(int minFrameCount , int waitTime ) +{ + static const int COUNT_FOR_TIME = 20; + int times = waitTime / COUNT_FOR_TIME; + + for (int i = 0; i < times; i++) { + if (videoIsPlaying(minFrameCount)) { + return 0; + } + } + + LOGW("EnableVideoWhenVideoPlaying time out"); + return -1; +} + +int CAv::EnableVideoWhenVideoPlaying(int minFrameCount, int waitTime) +{ + int ret = WaittingVideoPlaying(minFrameCount, waitTime); + if (ret == 0) { //ok to playing + EnableVideoNow( true ); + } + return ret; +} + +bool CAv::videoIsPlaying(int minFrameCount) +{ + int value[2] = {0}; + value[0] = getVideoFrameCount(); + usleep(20 * 1000); + value[1] = getVideoFrameCount(); + LOGD("videoIsPlaying framecount =%d = %d", value[0], value[1]); + + if (value[1] >= minFrameCount && (value[1] > value[0])) + return true; + + return false; +} + +int CAv::getVideoFrameCount() +{ + char buf[32] = {0}; + + tvReadSysfs(PATH_FRAME_COUNT, buf); + return atoi(buf); +} + +tvin_sig_fmt_t CAv::getVideoResolutionToFmt() +{ + char buf[32] = {0}; + tvin_sig_fmt_e sig_fmt = TVIN_SIG_FMT_HDMI_1920X1080P_60HZ; + + tvReadSysfs(SYS_VIDEO_FRAME_HEIGHT, buf); + int height = atoi(buf); + if (height <= 576) { + sig_fmt = TVIN_SIG_FMT_HDMI_720X480P_60HZ; + } else if (height > 576 && height <= 720) { + sig_fmt = TVIN_SIG_FMT_HDMI_1280X720P_60HZ; + } else if (height > 720 && height <= 1088) { + sig_fmt = TVIN_SIG_FMT_HDMI_1920X1080P_60HZ; + } else { + sig_fmt = TVIN_SIG_FMT_HDMI_3840_2160_00HZ; + } + return sig_fmt; +} + +int CAv::SetVideoScreenColor ( int vdin_blending_mask, int y, int u, int v ) +{ + unsigned long value = vdin_blending_mask << 24; + value |= ( unsigned int ) ( y << 16 ) | ( unsigned int ) ( u << 8 ) | ( unsigned int ) ( v ); + + LOGD("%s, vdin_blending_mask:%d,y:%d,u:%d,v:%d", __FUNCTION__, vdin_blending_mask, y, u, v); + + char val[64] = {0}; + sprintf(val, "0x%lx", ( unsigned long ) value); + tvWriteSysfs(VIDEO_TEST_SCREEN, val); + return 0; +} + +int CAv::SetVideoLayerDisable ( int value ) +{ + LOGD("%s, value = %d" , __FUNCTION__, value); + + char val[64] = {0}; + sprintf(val, "%d", value); + tvWriteSysfs(VIDEO_DISABLE_VIDEO, val); + return 0; +} + +int CAv::setVideoScreenMode ( int value ) +{ + LOGD("setVideoScreenMode, value = %d" , value); + + char val[64] = {0}; + sprintf(val, "%d", value); + tvWriteSysfs(VIDEO_SCREEN_MODE, val); + return 0; +} + +/** + * @function: set test pattern on video layer. + * @param r,g,b int 0~255. + */ +int CAv::setRGBScreen(int r, int g, int b) +{ + int value = ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); + return tvWriteSysfs(VIDEO_RGB_SCREEN, value, 16); +} + +int CAv::getRGBScreen() +{ + char value[32] = {0}; + tvReadSysfs(VIDEO_RGB_SCREEN, value); + return strtol(value, NULL, 10); +} + + +int CAv::setVideoAxis ( int h, int v, int width, int height ) +{ + LOGD("%s, %d %d %d %d", __FUNCTION__, h, v, width, height); + + char value[64] = {0}; + sprintf(value, "%d %d %d %d", h, v, width, height); + tvWriteSysfs(VIDEO_AXIS, value); + return 0; +} + +video_display_resolution_t CAv::getVideoDisplayResolution() +{ + video_display_resolution_t resolution; + char attrV[SYS_STR_LEN] = {0}; + + tvReadSysfs(VIDEO_DEVICE_RESOLUTION, attrV); + + if (strncasecmp(attrV, "1366x768", strlen ("1366x768")) == 0) { + resolution = VPP_DISPLAY_RESOLUTION_1366X768; + } else if (strncasecmp(attrV, "3840x2160", strlen ("3840x2160")) == 0) { + resolution = VPP_DISPLAY_RESOLUTION_3840X2160; + } else if (strncasecmp(attrV, "1920x1080", strlen ("1920x1080")) == 0) { + resolution = VPP_DISPLAY_RESOLUTION_1920X1080; + } else { + LOGW("video display resolution is = (%s) not define , default it", attrV); + resolution = VPP_DISPLAY_RESOLUTION_1920X1080; + } + + return resolution; +} + +void CAv::av_evt_callback ( long dev_no, int event_type, void *param, void *user_data ) +{ + CAv *pAv = ( CAv * ) user_data; + if (NULL == pAv ) { + LOGD ( "%s, ERROR : av_evt_callback NULL == pTv\n", __FUNCTION__ ); + return ; + } + if ( pAv->mpObserver == NULL ) { + LOGD ( "%s, ERROR : mpObserver NULL == mpObserver\n", __FUNCTION__ ); + return; + } +#ifdef SUPPORT_ADTV + switch ( event_type ) { + case AM_AV_EVT_AV_NO_DATA: + pAv->mCurAvEvent.type = AVEvent::EVENT_AV_STOP; + pAv->mCurAvEvent.param = ( long )param; + pAv->mpObserver->onEvent(pAv->mCurAvEvent); + break; + case AM_AV_EVT_AV_DATA_RESUME: + pAv->mCurAvEvent.type = AVEvent::EVENT_AV_RESUEM; + pAv->mCurAvEvent.param = ( long )param; + pAv->mpObserver->onEvent(pAv->mCurAvEvent); + break; + case AM_AV_EVT_VIDEO_SCAMBLED: + case AM_AV_EVT_AUDIO_SCAMBLED: + pAv->mCurAvEvent.type = AVEvent::EVENT_AV_SCAMBLED; + pAv->mCurAvEvent.param = ( long )param; + pAv->mpObserver->onEvent(pAv->mCurAvEvent); + break; + case AM_AV_EVT_VIDEO_NOT_SUPPORT: { + pAv->mCurAvEvent.type = AVEvent::EVENT_AV_UNSUPPORT; + pAv->mCurAvEvent.param = ( long )param; + pAv->mpObserver->onEvent(pAv->mCurAvEvent); + break; + } + case AM_AV_EVT_VIDEO_AVAILABLE: { + pAv->mCurAvEvent.type = AVEvent::EVENT_AV_VIDEO_AVAILABLE; + pAv->mCurAvEvent.param = ( long )param; + pAv->mpObserver->onEvent(pAv->mCurAvEvent); + break; + } + case AM_AV_EVT_PLAYER_UPDATE_INFO: { + AM_AV_TimeshiftInfo_t *info = (AM_AV_TimeshiftInfo_t*)param; + if (info) { + pAv->mCurAvEvent.type = AVEvent::EVENT_PLAY_UPDATE; + pAv->mCurAvEvent.param = info->current_time; + pAv->mCurAvEvent.status = info->status; + pAv->mpObserver->onEvent(pAv->mCurAvEvent); + } + break; + } + default: + break; + } +#endif + LOGD ( "%s, av_evt_callback : dev_no %ld type %d param = %d\n", + __FUNCTION__, dev_no, pAv->mCurAvEvent.type , (long)param); +} + +int CAv::setLookupPtsForDtmb(int enable) +{ + LOGD ( "setLookupPtsForDtmb %d" , enable); + + char value[64] = {0}; + sprintf(value, "%d", enable); + tvWriteSysfs(PATH_MEPG_DTMB_LOOKUP_PTS_FLAG, value); + return 0; +} + diff --git a/tv/tvserver/libtv/tv/CAv.h b/tv/tvserver/libtv/tv/CAv.h new file mode 100644 index 0000000..c26f88e --- a/dev/null +++ b/tv/tvserver/libtv/tv/CAv.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _C_AV_H +#define _C_AV_H + +#ifdef SUPPORT_ADTV +#include "am_av.h" +#include "am_aout.h" +#endif +#include "CTvEv.h" +#include "CTvLog.h" +#include "../tvin/CTvin.h" + +static const char *PATH_FRAME_COUNT_DI = "/sys/module/di/parameters/frame_count"; +static const char *PATH_FRAME_COUNT_VIDEO = "/sys/module/amvideo/parameters/new_frame_count"; +static const char *PATH_FRAME_COUNT = PATH_FRAME_COUNT_VIDEO; + +static const char *PATH_VIDEO_AMVIDEO = "/dev/amvideo"; +static const char *PATH_MEPG_DTMB_LOOKUP_PTS_FLAG = "/sys/module/amvdec_mpeg12/parameters/dtmb_flag"; + +#define VIDEO_RGB_SCREEN "/sys/class/video/rgb_screen" +#define VIDEO_TEST_SCREEN "/sys/class/video/test_screen" +#define VIDEO_DISABLE_VIDEO "/sys/class/video/disable_video" +#define VIDEO_SCREEN_MODE "/sys/class/video/screen_mode" +#define VIDEO_AXIS "/sys/class/video/axis" +#define VIDEO_DEVICE_RESOLUTION "/sys/class/video/device_resolution" + +//must sync with am_aout.h +enum +{ + TV_AOUT_OUTPUT_STEREO, /**< Stereo output*/ + TV_AOUT_OUTPUT_DUAL_LEFT, /**< Left audio output to dual channel*/ + TV_AOUT_OUTPUT_DUAL_RIGHT, /**< Right audio output to dual channel*/ + TV_AOUT_OUTPUT_SWAP /**< Swap left and right channel*/ +}; + +enum +{ + TV_AV_TS_SRC_TS0, /**< TS input port 0*/ + TV_AV_TS_SRC_TS1, /**< TS input port 1*/ + TV_AV_TS_SRC_TS2, /**< TS input port 2*/ + TV_AV_TS_SRC_HIU, /**< HIU port (file input)*/ + TV_AV_TS_SRC_DMX0, /**< Demux 0*/ + TV_AV_TS_SRC_DMX1, /**< Demux 1*/ + TV_AV_TS_SRC_DMX2 /**< Demux 2*/ +}; +//end + +enum { + VIDEO_LAYER_NONE = -1, + VIDEO_LAYER_ENABLE = 0, + VIDEO_LAYER_DISABLE_BLACK = 1, + VIDEO_LAYER_DISABLE_BLUE = 2 +}; + +typedef enum video_display_resolution_e { + VPP_DISPLAY_RESOLUTION_1366X768, + VPP_DISPLAY_RESOLUTION_1920X1080, + VPP_DISPLAY_RESOLUTION_3840X2160, + VPP_DISPLAY_RESOLUTION_MAX, +} video_display_resolution_t; + + +class CAv { +public: + CAv(); + ~CAv(); + //video screen_mode + static const int VIDEO_WIDEOPTION_NORMAL = 0; + static const int VIDEO_WIDEOPTION_FULL_STRETCH = 1; + static const int VIDEO_WIDEOPTION_4_3 = 2; + static const int VIDEO_WIDEOPTION_16_9 = 3; + static const int VIDEO_WIDEOPTION_NONLINEAR = 4; + static const int VIDEO_WIDEOPTION_NORMAL_NOSCALEUP = 5; + static const int VIDEO_WIDEOPTION_CROP_FULL = 6; + static const int VIDEO_WIDEOPTION_CROP = 7; + // + class AVEvent : public CTvEv { + public: + AVEvent(): CTvEv(CTvEv::TV_EVENT_AV) + { + + }; + ~AVEvent() + {}; + static const int EVENT_AV_STOP = 1; + static const int EVENT_AV_RESUEM = 2; + static const int EVENT_AV_SCAMBLED = 3; + static const int EVENT_AV_UNSUPPORT = 4; + static const int EVENT_AV_VIDEO_AVAILABLE = 5; + static const int EVENT_PLAY_UPDATE = 6; + std::string player; + int type; + long param; + int status; + }; + + class IObserver { + public: + IObserver() {}; + virtual ~IObserver() {}; + virtual void onEvent(const AVEvent &ev) = 0; + }; + //1 VS n + //int addObserver(IObserver* ob); + //int removeObserver(IObserver* ob); + + //1 VS 1 + int setObserver(IObserver *ob) + { + mpObserver = ob; + return 0; + } + + int Open(); + int Close(); + int SetVideoWindow(int x, int y, int w, int h); + int GetVideoStatus(int *w, int *h, int *fps, int *interlace); + int GetAudioStatus( int fmt[2], int sample_rate[2], int resolution[2], int channels[2], + int lfepresent[2], int *frames, int *ab_size, int *ab_data, int *ab_free); + int SwitchTSAudio(int apid, int afmt); + int ResetAudioDecoder(); + int SetADAudio(unsigned int enable, int apid, int afmt); + int SetTSSource(int ts_source); + int StartTS(unsigned short vpid, unsigned short apid, unsigned short pcrid, int vfmt, int afmt); + int StopTS(); + int AudioGetOutputMode(int *mode); + int AudioSetOutputMode(int mode); + + /*TimeShifting*/ + int startTimeShift(void *para); + int stopTimeShift(); + int playTimeShift(); + int pauseTimeShift(); + int resumeTimeShift(); + int seekTimeShift(int pos, bool start); + int setTimeShiftSpeed(int speed); + int switchTimeShiftAudio(int apid, int afmt); + + int AudioSetPreGain(float pre_gain); + int AudioGetPreGain(float *gain); + int AudioSetPreMute(unsigned int mute); + int AudioGetPreMute(unsigned int *mute); + int SetVideoScreenColor (int vdin_blending_mask, int y, int u, int v); + int DisableVideoWithBlueColor(); + int DisableVideoWithBlackColor(); + int EnableVideoAuto(); + int EnableVideoNow(bool IsShowTestScreen); + int EnableVideoWhenVideoPlaying(int minFrameCount = 8, int waitTime = 5000); + int WaittingVideoPlaying(int minFrameCount = 8, int waitTime = 5000); + int EnableVideoBlackout(); + int DisableVideoBlackout(); + int SetVideoLayerDisable ( int value ); + int ClearVideoBuffer(); + bool videoIsPlaying(int minFrameCount = 8); + int setVideoScreenMode ( int value ); + int setVideoAxis ( int h, int v, int width, int height ); + video_display_resolution_t getVideoDisplayResolution(); + int setRGBScreen(int r, int g, int b); + int getRGBScreen(); + + int setLookupPtsForDtmb(int enable); + tvin_sig_fmt_t getVideoResolutionToFmt(); + +private: + static void av_evt_callback ( long dev_no, int event_type, void *param, void *user_data ); + int getVideoFrameCount(); + int mTvPlayDevId; + IObserver *mpObserver; + AVEvent mCurAvEvent; + int mVideoLayerState; + + int mFdAmVideo; +}; +#endif diff --git a/tv/tvserver/libtv/tv/CBootvideoStatusDetect.cpp b/tv/tvserver/libtv/tv/CBootvideoStatusDetect.cpp new file mode 100644 index 0000000..516a54f --- a/dev/null +++ b/tv/tvserver/libtv/tv/CBootvideoStatusDetect.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#include <CTvLog.h> +#include <cutils/properties.h> +#include "CBootvideoStatusDetect.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#define LOG_TAG "CBootvideoStatusDetect" +#endif + +CBootvideoStatusDetect::CBootvideoStatusDetect() +{ + LOGD("%s", __FUNCTION__); + mpObserver = NULL; + mIsRunning = false; +} + +CBootvideoStatusDetect::~CBootvideoStatusDetect() {} + +int CBootvideoStatusDetect::startDetect() +{ + LOGD("%s", __FUNCTION__); + if (!mIsRunning) + this->run("CBootvideoStatusDetect"); + + return 0; +} + +int CBootvideoStatusDetect::stopDetect() +{ + LOGD("%s", __FUNCTION__); + requestExit(); + mIsRunning = false; + + return 0; +} + + +bool CBootvideoStatusDetect::isBootvideoStopped() { + char prop_bootvideo_type[PROPERTY_VALUE_MAX]; + char prop_bootvideo[PROPERTY_VALUE_MAX]; + char prop_bootanim[PROPERTY_VALUE_MAX]; + + memset(prop_bootvideo_type, '\0', PROPERTY_VALUE_MAX); + memset(prop_bootvideo, '\0', PROPERTY_VALUE_MAX); + memset(prop_bootanim, '\0', PROPERTY_VALUE_MAX); + + // 1: boot video; other: boot animation + property_get("service.bootvideo", prop_bootvideo_type, "null"); + // stopped: bootvideo stopped; running: bootvideo is running + property_get("init.svc.bootvideo", prop_bootvideo, "null"); + // 1: boot animation exited; 0: boot animation is running + property_get("service.bootanim.exit", prop_bootanim, "null"); + + if ((strcmp(prop_bootvideo_type, "1") == 0 && strcmp(prop_bootvideo, "stopped") == 0) || + (strcmp(prop_bootvideo_type, "1") != 0 && strcmp(prop_bootanim, "1") == 0)) + return true; + else + return false; +} + +bool CBootvideoStatusDetect::threadLoop() +{ + if ( mpObserver == NULL ) { + return false; + } + while (!exitPending()) { + if (isBootvideoStopped()) { + mpObserver->onBootvideoStopped(); + } else { + mpObserver->onBootvideoRunning(); + } + usleep(500 * 1000); + } + + LOGD("%s, exiting...\n", "CBootvideoStatusDetect"); + return false; +} + + diff --git a/tv/tvserver/libtv/tv/CBootvideoStatusDetect.h b/tv/tvserver/libtv/tv/CBootvideoStatusDetect.h new file mode 100644 index 0000000..8a379fa --- a/dev/null +++ b/tv/tvserver/libtv/tv/CBootvideoStatusDetect.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef C_BOOT_VIDEO_STATUS_DETECT_H +#define C_BOOT_VIDEO_STATUS_DETECT_H +#include <utils/Thread.h> + +using namespace android; +class CBootvideoStatusDetect: public Thread { +public: + CBootvideoStatusDetect(); + ~CBootvideoStatusDetect(); + int startDetect(); + int stopDetect(); + bool isBootvideoStopped(); + + class IBootvideoStatusObserver { + public: + IBootvideoStatusObserver() {}; + virtual ~IBootvideoStatusObserver() {}; + virtual void onBootvideoRunning() {}; + virtual void onBootvideoStopped() {}; + }; + void setObserver (IBootvideoStatusObserver *pOb) + { + mpObserver = pOb; + }; + +private: + bool threadLoop(); + + IBootvideoStatusObserver *mpObserver; + bool mIsRunning; +}; +#endif + diff --git a/tv/tvserver/libtv/tv/CFrontEnd.cpp b/tv/tvserver/libtv/tv/CFrontEnd.cpp new file mode 100644 index 0000000..db04197 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CFrontEnd.cpp @@ -0,0 +1,981 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CFrontEnd" + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <stdlib.h> +#include <malloc.h> +#include <sys/types.h> +#include <dlfcn.h> +#include <time.h> +#include "CFrontEnd.h" +#include "util.h" +#include "tvin/CTvin.h" +#include "CTvScanner.h" + +#include <string> +#include <map> + +#ifdef SUPPORT_ADTV +#include "am_misc.h" +#include "am_debug.h" + +extern "C" { +#include "am_av.h" +#include "am_dmx.h" +#include "linux/videodev2.h" +#include "am_fend_ctrl.h" +} +#endif + +CFrontEnd *CFrontEnd::mInstance; + +CFrontEnd *CFrontEnd::getInstance() +{ + if (NULL == mInstance) mInstance = new CFrontEnd(); + return mInstance; +} + +CFrontEnd::CFrontEnd() +{ + mFrontDevID = FE_DEV_ID; + mpObserver = NULL; + mCurFineFreq = 0; + mCurMode = -1; + mCurFreq = -1; + mCurPara1 = -1; + mCurPara2 = -1; + mbFEOpened = false; +} + +CFrontEnd::~CFrontEnd() +{ +#ifdef SUPPORT_ADTV + AM_EVT_Unsubscribe(mFrontDevID, AM_FEND_EVT_STATUS_CHANGED, dmd_fend_callback, NULL); + if (mFrontDevID == FE_DEV_ID) + AM_FEND_Close(mFrontDevID); + mFrontDevID = -1; +#endif +} + +int CFrontEnd::Open(int mode) +{ +#ifdef SUPPORT_ADTV + AutoMutex _l( mLock ); + + AM_FEND_OpenPara_t para; + int rc = 0; + + LOGD("FE Open [%d->%d]", mCurMode, mode); + + if (mbFEOpened && (mCurMode == mode || mode == TV_FE_AUTO)) { + LOGD("FrontEnd already opened, return"); + return 0; + } + + if (mbFEOpened) + AM_FEND_Close(mFrontDevID); + + memset(¶, 0, sizeof(AM_FEND_OpenPara_t)); + para.mode = mode; + rc = AM_FEND_Open(mFrontDevID, ¶); + if ((rc != AM_FEND_ERR_BUSY) && (rc != 0)) { + LOGD("%s,frontend dev open failed! dvb error id is %d\n", __FUNCTION__, rc); + return -1; + } + + AM_EVT_Subscribe(mFrontDevID, AM_FEND_EVT_STATUS_CHANGED, dmd_fend_callback, this); + LOGD("%s,frontend dev open success!\n", __FUNCTION__); + mbFEOpened = true; + mCurMode = mode; + mCurFreq = -1; + mCurPara1 = -1; + mCurPara2 = -1; +#endif + return 0; +} + +int CFrontEnd::Close() +{ +#ifdef SUPPORT_ADTV + AutoMutex _l( mLock ); + + int rc = 0; + + LOGD("FE Close"); + + if (!mbFEOpened) { + LOGD("FrontEnd already closed."); + } + + mbFEOpened = false; + mCurMode = -1; + mCurFreq = -1; + mCurPara1 = -1; + mCurPara2 = -1; + mFEParas.setFrequency(-1); + + rc = AM_FEND_Close(mFrontDevID); + if (rc != 0) { + LOGD("%s,frontend_close fail! dvb error id is %d\n", __FUNCTION__, rc); + return -1; + } +#endif + LOGD("%s,close frontend is ok\n", __FUNCTION__); + return 0; +} + +int CFrontEnd::setMode(int mode) +{ +#ifdef SUPPORT_ADTV + AutoMutex _l( mLock ); + + int rc = 0; + if (mCurMode == mode) return 0; + rc = AM_FEND_SetMode(mFrontDevID, mode); + if (rc != 0) { + LOGD("%s,front dev set mode failed! dvb error id is %d\n", __FUNCTION__, rc); + return -1; + } +#endif + mCurMode = mode; + return 0; +} + +int CFrontEnd::setProp(int cmd, int val) +{ + AutoMutex _l( mLock ); + return setPropLocked(cmd, val); +} + +int CFrontEnd::setPropLocked(int cmd, int val) +{ +#ifdef SUPPORT_ADTV + struct dtv_properties props; + struct dtv_property prop; + + memset(&props, 0, sizeof(props)); + memset(&prop, 0, sizeof(prop)); + + prop.cmd = cmd; + prop.u.data = val; + + props.num = 1; + props.props = ∝ + + return AM_FEND_SetProp(mFrontDevID, &props); +#else + return -1; +#endif +} + +int CFrontEnd::convertParas(char *paras, int mode, int freq1, int freq2, int para1, int para2) +{ + char p[128] = {0}; + sprintf(paras, "{\"mode\":%d,\"freq\":%d,\"freq2\":%d", mode, freq1, freq2); + switch (FEMode(mode).getBase()) + { + case TV_FE_DTMB: + case TV_FE_OFDM: + sprintf(p, ",\"bw\":%d}", para1); + break; + case TV_FE_QAM: + sprintf(p, ",\"sr\":%d,\"mod\":%d}", para1, para2); + break; + case TV_FE_ATSC: + sprintf(p, ",\"mod\":%d}", para1); + break; + case TV_FE_ANALOG: + sprintf(p, ",\"vtd\":%d,\"atd\":%d,\"afc\":%d}", + stdAndColorToVideoEnum(para1), + stdAndColorToAudioEnum(para1), + para2); + break; + case TV_FE_ISDBT: + sprintf(p, ",\"bw\":%d,\"lyr\":%d}", para1, para2); + break; + default: + sprintf(p, "}"); + break; + } + strcat(paras, p); + return 0; +} + +void CFrontEnd::saveCurrentParas(FEParas ¶s) +{ + mFEParas = paras; + + /*for compatible*/ + mCurMode = mFEParas.getFEMode().getBase(); + mCurFreq = mFEParas.getFrequency(); + mCurPara1 = mCurPara2 = 0; + switch (mFEParas.getFEMode().getBase()) + { + case TV_FE_DTMB: + case TV_FE_OFDM: + mCurPara1 = mFEParas.getBandwidth(); + break; + case TV_FE_QAM: + mCurPara1 = mFEParas.getSymbolrate(); + mCurPara2 = mFEParas.getModulation(); + break; + case TV_FE_ATSC: + mCurPara1 = mFEParas.getModulation(); + break; + case TV_FE_ANALOG: + mCurPara1 = enumToStdAndColor(mFEParas.getVideoStd(), mFEParas.getAudioStd()); + mCurPara2 = mFEParas.getAfc(); + break; + case TV_FE_ISDBT: + mCurPara1 = mFEParas.getBandwidth(); + mCurPara2 = mFEParas.getLayer(); + break; + default: + break; + } +} + +int CFrontEnd::setPara(int mode, int freq, int para1, int para2) +{ + char paras[128]; + convertParas(paras, mode, freq, freq, para1, para2); + return setPara(paras); +} + +int CFrontEnd::setPara(const char *paras) +{ + return setPara(paras, false); +} + +int CFrontEnd::setPara(const char *paras, bool force ) +{ +#ifdef SUPPORT_ADTV + AutoMutex _l( mLock ); + int ret = 0; + FEParas feparas(paras); + + LOGD("[source_switch_time]: %fs, fe setpara [%s]", getUptimeSeconds(), paras); + if (mFEParas == feparas && !force) { + LOGD("fe setpara is same return"); + return 0; + } + + saveCurrentParas(feparas); + + AM_FENDCTRL_DVBFrontendParameters_t dvbfepara; + memset(&dvbfepara, 0, sizeof(AM_FENDCTRL_DVBFrontendParameters_t)); + + dvbfepara.m_type = mFEParas.getFEMode().getBase(); + switch (dvbfepara.m_type) { + case TV_FE_OFDM: + dvbfepara.terrestrial.para.frequency = mFEParas.getFrequency(); + dvbfepara.terrestrial.para.u.ofdm.bandwidth = (fe_bandwidth_t)mFEParas.getBandwidth(); + dvbfepara.terrestrial.para.u.ofdm.ofdm_mode = (fe_ofdm_mode_t)mFEParas.getFEMode().getGen(); + break; + case TV_FE_DTMB: + dvbfepara.dtmb.para.frequency = mFEParas.getFrequency(); + dvbfepara.dtmb.para.u.ofdm.bandwidth = (fe_bandwidth_t)mFEParas.getBandwidth(); + break; + case TV_FE_ATSC: + dvbfepara.atsc.para.frequency = mFEParas.getFrequency(); + dvbfepara.atsc.para.u.vsb.modulation = (fe_modulation_t)mFEParas.getModulation(); + break; + case TV_FE_QAM: + dvbfepara.cable.para.frequency = mFEParas.getFrequency(); + dvbfepara.cable.para.u.qam.symbol_rate = mFEParas.getSymbolrate(); + dvbfepara.cable.para.u.qam.modulation = (fe_modulation_t)mFEParas.getModulation(); + break; + case TV_FE_ISDBT: + dvbfepara.isdbt.para.frequency = mFEParas.getFrequency(); + dvbfepara.isdbt.para.u.ofdm.bandwidth = (fe_bandwidth_t)mFEParas.getBandwidth(); + break; + case TV_FE_ANALOG: { + int buff_size = 32; + char VideoStdBuff[buff_size]; + char audioStdBuff[buff_size]; + /*para2 is finetune data */ + dvbfepara.analog.para.frequency = mFEParas.getFrequency(); + dvbfepara.analog.para.u.analog.std = enumToStdAndColor(mFEParas.getVideoStd(), mFEParas.getAudioStd()); + dvbfepara.analog.para.u.analog.afc_range = AFC_RANGE; + if (mFEParas.getAfc() == 0) { + dvbfepara.analog.para.u.analog.flag |= ANALOG_FLAG_ENABLE_AFC; + } else { + dvbfepara.analog.para.u.analog.flag &= ~ANALOG_FLAG_ENABLE_AFC; + dvbfepara.analog.para.u.analog.afc_range = 0; + } + printAudioStdStr(dvbfepara.analog.para.u.analog.std, audioStdBuff, buff_size); + printVideoStdStr(dvbfepara.analog.para.u.analog.std, VideoStdBuff, buff_size); + LOGD("%s,freq = %dHz, video_std = %s, audio_std = %s, afc = %d\n", __FUNCTION__, + dvbfepara.analog.para.frequency, VideoStdBuff, audioStdBuff, mFEParas.getAfc()); + } + break; + } + + ret = AM_FENDCTRL_SetPara(mFrontDevID, &dvbfepara); + if (ret != 0) { + LOGD("%s,fend set para failed! dvb error id is %d\n", __FUNCTION__, ret); + return -1; + } + + if (mFEParas.getFEMode().getBase() == TV_FE_OFDM + && mFEParas.getFEMode().getGen()) { + ret = setPropLocked(DTV_DVBT2_PLP_ID, mFEParas.getPlp()); + if (ret != 0) + return -1; + } + if (dvbfepara.m_type == TV_FE_ISDBT) { + ret = setPropLocked(DTV_ISDBT_LAYER_ENABLED, mFEParas.getLayer()); + if (ret != 0) + return -1; + } +#endif + return 0; +} + +int CFrontEnd::fineTune(int fineFreq) +{ + return fineTune(fineFreq, false); +} + +int CFrontEnd::fineTune(int fineFreq, bool force) +{ +#ifdef SUPPORT_ADTV + AutoMutex _l( mLock ); + + int ret = 0; + if (mCurFineFreq == fineFreq && !force) return -1; + + mCurFineFreq = fineFreq; + ret = AM_FEND_FineTune(FE_DEV_ID, fineFreq); + + if (ret != 0) { + LOGD("%s, fail! dvb error id is %d", __FUNCTION__, ret); + return -1; + } +#endif + return 0; +} + +void CFrontEnd::dmd_fend_callback(long dev_no __unused, int event_type __unused, void *param, void *user_data) +{ +#ifdef SUPPORT_ADTV + CFrontEnd *pFront = (CFrontEnd *)user_data; + if (NULL == pFront) { + LOGD("%s,warnning : dmd_fend_callback NULL == pFront\n", __FUNCTION__); + return ; + } + if (pFront->mpObserver == NULL) { + LOGD("%s,warnning : mpObserver NULL == mpObserver\n", __FUNCTION__); + return; + } + struct dvb_frontend_event *evt = (struct dvb_frontend_event *) param; + if (!evt) + return; + + LOGD("fend callback: status[0x%x]\n", evt->status); + if (evt->status & TV_FE_HAS_LOCK) { + pFront->mCurSigEv.mCurSigStaus = FEEvent::EVENT_FE_HAS_SIG; + pFront->mCurSigEv.mCurFreq = evt->parameters.frequency; + pFront->mpObserver->onEvent(pFront->mCurSigEv); + } else if (evt->status & TV_FE_TIMEDOUT) { + pFront->mCurSigEv.mCurSigStaus = FEEvent::EVENT_FE_NO_SIG; + pFront->mCurSigEv.mCurFreq = evt->parameters.frequency; + pFront->mpObserver->onEvent(pFront->mCurSigEv); + } +#endif +} + +int CFrontEnd::stdAndColorToAudioEnum(int data) +{ + atv_audio_std_t std = CC_ATV_AUDIO_STD_DK; +#ifdef SUPPORT_ADTV + if (((data & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) || + ((data & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK)) { + std = CC_ATV_AUDIO_STD_DK; + } else if ((data & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) { + std = CC_ATV_AUDIO_STD_I; + } else if (((data & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) || + ((data & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) || + ((data & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G )) { + std = CC_ATV_AUDIO_STD_BG; + } else if (((data & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) || + ((data & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M)) { + std = CC_ATV_AUDIO_STD_M; + } else if ((data & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) { + std = CC_ATV_AUDIO_STD_L; + } +#endif + return std ; +} + +int CFrontEnd::stdAndColorToVideoEnum(int std) +{ + atv_video_std_t video_standard = CC_ATV_VIDEO_STD_PAL; + if ((std & V4L2_COLOR_STD_PAL) == V4L2_COLOR_STD_PAL) { + video_standard = CC_ATV_VIDEO_STD_PAL; + } else if ((std & V4L2_COLOR_STD_NTSC) == V4L2_COLOR_STD_NTSC) { + video_standard = CC_ATV_VIDEO_STD_NTSC; + } else if ((std & V4L2_COLOR_STD_SECAM) == V4L2_COLOR_STD_SECAM) { + video_standard = CC_ATV_VIDEO_STD_SECAM; + } + return video_standard; +} + +bool CFrontEnd::stdIsColorAuto(int std) +{ + return ((std & V4L2_COLOR_STD_AUTO) == V4L2_COLOR_STD_AUTO) ? true : false; +} + +int CFrontEnd::addColorAutoFlag(int std) +{ + return std | V4L2_COLOR_STD_AUTO; +} + +unsigned long CFrontEnd::enumToStdAndColor(int videoStd, int audioStd) +{ + unsigned long tmpTunerStd = 0; +#ifdef SUPPORT_ADTV + if (videoStd == CC_ATV_VIDEO_STD_PAL) { + tmpTunerStd |= V4L2_COLOR_STD_PAL; + if (audioStd == CC_ATV_AUDIO_STD_DK) { + tmpTunerStd |= V4L2_STD_PAL_DK; + } else if (audioStd == CC_ATV_AUDIO_STD_I) { + tmpTunerStd |= V4L2_STD_PAL_I; + } else if (audioStd == CC_ATV_AUDIO_STD_BG) { + tmpTunerStd |= V4L2_STD_PAL_BG; + } else if (audioStd == CC_ATV_AUDIO_STD_M) { + tmpTunerStd |= V4L2_STD_PAL_M; + } + } else if (videoStd == CC_ATV_VIDEO_STD_NTSC) { + tmpTunerStd |= V4L2_COLOR_STD_NTSC; + if (audioStd == CC_ATV_AUDIO_STD_DK) { + tmpTunerStd |= V4L2_STD_PAL_DK; + } else if (audioStd == CC_ATV_AUDIO_STD_I) { + tmpTunerStd |= V4L2_STD_PAL_I; + } else if (audioStd == CC_ATV_AUDIO_STD_BG) { + tmpTunerStd |= V4L2_STD_PAL_BG; + } else if (audioStd == CC_ATV_AUDIO_STD_M) { + tmpTunerStd |= V4L2_STD_NTSC_M; + } + } else if (videoStd == CC_ATV_VIDEO_STD_SECAM) { + tmpTunerStd |= V4L2_COLOR_STD_SECAM; + if (audioStd == CC_ATV_AUDIO_STD_DK) { + tmpTunerStd |= V4L2_STD_SECAM_DK; + } else if (audioStd == CC_ATV_AUDIO_STD_I) { + tmpTunerStd |= V4L2_STD_PAL_I; + } else if (audioStd == CC_ATV_AUDIO_STD_BG) { + tmpTunerStd |= (V4L2_STD_SECAM_B | V4L2_STD_SECAM_G); + } else if (audioStd == CC_ATV_AUDIO_STD_M) { + tmpTunerStd |= V4L2_STD_NTSC_M; + } else if (audioStd == CC_ATV_AUDIO_STD_L) { + tmpTunerStd |= V4L2_STD_SECAM_L; + } + } +#endif + return tmpTunerStd; +} + +int CFrontEnd::getPara(int *mode, int *freq, int *para1, int *para2) +{ +#ifdef SUPPORT_ADTV + struct dvb_frontend_parameters para; + memset(¶, 0, sizeof(struct dvb_frontend_parameters)); + /*if((ret1=AM_FEND_GetPara(mFrontDevID, ¶))<0) { + LOGD("%s,getPara faiture\n", __FUNCTION__ ); + return -1; + + //fpara->mode = fend_mode ; + + }*/ +#endif + *mode = mCurMode; + *freq = mCurFreq; + *para1 = mCurPara1; + *para2 = mCurPara2; + return 0; +} + +int CFrontEnd::getSNR() +{ + int snr = 0; +#ifdef SUPPORT_ADTV + AM_FEND_GetSNR(mFrontDevID, &snr); +#endif + return snr; +} + +int CFrontEnd::getBER() +{ + int ber = 0; +#ifdef SUPPORT_ADTV + AM_FEND_GetBER(mFrontDevID, &ber); +#endif + return ber; +} + +int CFrontEnd::getStrength() +{ + int Strength = 0; +#ifdef SUPPORT_ADTV + AM_FEND_GetStrength(mFrontDevID, &Strength); +#endif + return Strength; +} + +int CFrontEnd::formatATVFreq(int tmp_freq) +{ + const int ATV_1MHZ = 1000000; + const int ATV_50KHZ = 50 * 1000; + const int ATV_25KHZ = 25 * 1000; + int mastar = (tmp_freq / ATV_50KHZ) * ATV_50KHZ; + int follow = tmp_freq % ATV_50KHZ; + if (follow >= ATV_25KHZ) { + follow = ATV_50KHZ; + } else { + follow = 0; + } + return mastar + follow; +} + +int CFrontEnd::printVideoStdStr(int compStd, char strBuffer[], int buff_size) +{ + memset(strBuffer, 0, buff_size); + int videoStd = stdAndColorToVideoEnum(compStd); + switch (videoStd) { + case CC_ATV_VIDEO_STD_AUTO: + strcpy(strBuffer, "AUTO"); + break; + case CC_ATV_VIDEO_STD_PAL: + strcpy(strBuffer, "PAL"); + break; + case CC_ATV_VIDEO_STD_NTSC: + strcpy(strBuffer, "NTSC"); + break; + case CC_ATV_VIDEO_STD_SECAM: + strcpy(strBuffer, "SECAM"); + break; + default: + strcpy(strBuffer, "UnkownVideo"); + break; + } + + return 0; +} + +int CFrontEnd::printAudioStdStr(int compStd, char strBuffer[], int buff_size) +{ + memset(strBuffer, 0, buff_size); + int audioStd = stdAndColorToAudioEnum(compStd); + switch (audioStd) { + case CC_ATV_AUDIO_STD_DK: + strcpy(strBuffer, "DK"); + break; + case CC_ATV_AUDIO_STD_I: + strcpy(strBuffer, "I"); + break; + case CC_ATV_AUDIO_STD_BG: + strcpy(strBuffer, "BG"); + break; + case CC_ATV_AUDIO_STD_M: + strcpy(strBuffer, "M"); + break; + case CC_ATV_AUDIO_STD_L: + strcpy(strBuffer, "L"); + break; + case CC_ATV_AUDIO_STD_AUTO: + strcpy(strBuffer, "AUTO"); + break; + default: + strcpy(strBuffer, "UnkownAudio"); + break; + } + + return 0; +} + +int CFrontEnd::autoLoadFE() +{ + FILE *fp = NULL; + int ret = -1; + + fp = fopen ( "/sys/class/amlfe/setting", "w" ); + + if ( fp == NULL ) { + LOGW ( "Open /sys/class/amlfe/setting error(%s)!\n", strerror ( errno ) ); + return -1; + } + + ret = fprintf ( fp, "%s", "autoload" ); + + if ( ret < 0 ) { + LOGW ( "autoload FE error(%s)!\n", strerror ( errno ) ); + } + LOGD("autoLoadFE"); + fclose ( fp ); + fp = NULL; + + return ret; +} + +int CFrontEnd::setCvbsAmpOut(int tmp) +{ + int rc = DVB_SUCCESS; +#ifdef SUPPORT_ADTV + rc = AM_FEND_SetCvbsAmpOut(mFrontDevID, tmp); + if (rc == DVB_SUCCESS) { + LOGD("%s, sucessful!", __FUNCTION__); + rc = 0; + } else { + LOGD("%s, fail!", __FUNCTION__); + rc = -1; + } +#endif + return rc; +} + +int CFrontEnd::setThreadDelay(int delay) +{ + int rc = DVB_SUCCESS; +#ifdef SUPPORT_ADTV + rc = AM_FEND_SetThreadDelay(mFrontDevID, delay); + if (rc == DVB_SUCCESS) { + LOGD("frontend_setThreadDelay sucessful!\n"); + return 0; + } +#endif + LOGD("frontend_setThreadDelay fail! %d\n\n", rc); + return -1; +} + +int CFrontEnd::lock(int frequency, int symbol_rate, int modulation, int bandwidth __unused) +{ + int rt = -1; +#ifdef SUPPORT_ADTV + struct dvb_frontend_parameters fparam; + struct dvb_frontend_info finfo; + + memset(&fparam, 0, sizeof(struct dvb_frontend_parameters)); + memset(&finfo, 0, sizeof(struct dvb_frontend_info)); + + AM_FEND_GetInfo(mFrontDevID, &finfo); + + if (frequency == 0) + return -1; + fparam.frequency = frequency; + + switch (finfo.type) { + + case TV_FE_QAM: + default: + + if (symbol_rate == 0) + return -1; + fparam.u.qam.symbol_rate = symbol_rate; + + + if (modulation == 0) + return -1; + fparam.u.qam.modulation = (fe_modulation_t)modulation; + + LOGD("mFrontDevID = %d;fre=%d;sym=%d;qam=%d ", + mFrontDevID, fparam.frequency, fparam.u.qam.symbol_rate, fparam.u.qam.modulation); + break; + case TV_FE_OFDM: + case TV_FE_ATSC: + LOGD("mFrontDevID = %d;fre=%d;bw=%d\n ", + mFrontDevID, fparam.frequency, fparam.u.ofdm.bandwidth); + break; + case TV_FE_QPSK: + LOGD("QPSK are not supported.\n "); + break; + case TV_FE_ANALOG: + LOGD("ANALOG is supported.\n "); + fparam.u.analog.std = V4L2_STD_PAL_I; + break; + } + + fe_status_t status; + + rt = AM_FEND_Lock(FE_DEV_ID, &fparam, &status); + + if ((!rt) && (status & TV_FE_HAS_LOCK)) { + LOGD("frontend_lock sucessful!\n"); + return true; + } +#endif + LOGD("frontend_lock fail %d!\n", rt); + return false; +} + +int CFrontEnd::getInfo() +{ +#ifdef SUPPORT_ADTV + struct dvb_frontend_info finfo; + + AM_FEND_GetInfo(mFrontDevID, &finfo); +#endif + //return fend_info; noitfy FrontEnd message + return 0; +} + +int CFrontEnd::setTunerAfc(int afc) +{ +#ifdef SUPPORT_ADTV + AM_FEND_SetAfc(FE_DEV_ID, afc); +#endif + return 0; +} + +int CFrontEnd::getStatus() +{ +#ifdef SUPPORT_ADTV + fe_status_t status; + AM_FEND_GetStatus(mFrontDevID, &status); + + return status; +#else + return -1; +#endif +} + +int CFrontEnd::checkStatusOnce() +{ +#ifdef SUPPORT_ADTV + fe_status_t status; + AM_FEND_GetStatus(mFrontDevID, &status); + LOGD("%s,get status = %x", __FUNCTION__, status); + if (status & TV_FE_HAS_LOCK) { + mCurSigEv.mCurSigStaus = FEEvent::EVENT_FE_HAS_SIG; + mCurSigEv.mCurFreq = 0; + mpObserver->onEvent(mCurSigEv); + } else if (status & TV_FE_TIMEDOUT) { + mCurSigEv.mCurSigStaus = FEEvent::EVENT_FE_NO_SIG; + mCurSigEv.mCurFreq = 0; + mpObserver->onEvent(mCurSigEv); + } +#endif + return 0; +} + +int CFrontEnd::stdEnumToCvbsFmt (int videoStd, int audioStd) +{ + tvin_sig_fmt_e cvbs_fmt = TVIN_SIG_FMT_NULL; + + if ( videoStd == CC_ATV_VIDEO_STD_PAL ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_PAL_I; + if ( audioStd == CC_ATV_AUDIO_STD_DK ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_PAL_I; + } else if ( audioStd == CC_ATV_AUDIO_STD_I ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_PAL_I; + } else if ( audioStd == CC_ATV_AUDIO_STD_BG ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_PAL_I; + } else if ( audioStd == CC_ATV_AUDIO_STD_M ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_PAL_M; + } + } else if ( videoStd == CC_ATV_VIDEO_STD_NTSC ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_NTSC_M; + if ( audioStd == CC_ATV_AUDIO_STD_DK ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_NTSC_M; + } else if ( audioStd == CC_ATV_AUDIO_STD_I ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_NTSC_M; + } else if ( audioStd == CC_ATV_AUDIO_STD_BG ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_NTSC_M; + } else if ( audioStd == CC_ATV_AUDIO_STD_M ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_NTSC_M; + } + } else if ( videoStd == CC_ATV_VIDEO_STD_SECAM ) { + if ( audioStd == CC_ATV_AUDIO_STD_DK ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_SECAM; + } else if ( audioStd == CC_ATV_AUDIO_STD_I ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_SECAM; + } else if ( audioStd == CC_ATV_AUDIO_STD_BG ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_SECAM; + } else if ( audioStd == CC_ATV_AUDIO_STD_M ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_SECAM; + } else if ( audioStd == CC_ATV_AUDIO_STD_L ) { + cvbs_fmt = TVIN_SIG_FMT_CVBS_SECAM; + } + } + return cvbs_fmt; +} + +int CFrontEnd::ClearAnalogFrontEnd() +{ +#ifdef SUPPORT_ADTV + return this->setPara ( TV_FE_ANALOG, 44250000, V4L2_COLOR_STD_PAL | V4L2_STD_PAL_DK, 0 ); +#else + return -1; +#endif +} + +/*to control afc function*/ +int CFrontEnd::SetAnalogFrontEndTimerSwitch(int onOff) +{ + FILE *fp = NULL; + int ret = -1; + + fp = fopen ( "/sys/module/aml_fe/parameters/aml_timer_en", "w" ); + + if ( fp == NULL ) { + LOGW ( "Open /sys/module/aml_fe/parameters/aml_timer_en error(%s)!\n", strerror ( errno ) ); + return -1; + } + if (onOff) + ret = fprintf(fp, "%s", "1"); + else + ret = fprintf(fp, "%s", "0"); + if ( ret < 0 ) { + LOGW ( "set aml_timer_en error(%s)!\n", strerror ( errno ) ); + } + LOGD("SetAnalogFrontEndTimerSwitch %d", onOff); + fclose ( fp ); + fp = NULL; + + return ret; +} + +int CFrontEnd::SetAnalogFrontEndSearhSlowMode(int onOff) +{ + FILE *fp = NULL; + int ret = -1; + + fp = fopen ( "/sys/module/aml_fe/parameters/slow_mode", "w" ); + + if ( fp == NULL ) { + LOGW ( "Open /sys/module/aml_fe/parameters/slow_mode error(%s)!\n", strerror ( errno ) ); + return -1; + } + if (onOff) + ret = fprintf(fp, "%s", "1"); + else + ret = fprintf(fp, "%s", "0"); + if ( ret < 0 ) { + LOGW ( "set aml_timer_en error(%s)!\n", strerror ( errno ) ); + } + LOGD("SetAnalogFrontEndSearhSlowMode %d", onOff); + fclose ( fp ); + fp = NULL; + + return ret; +} + +CFrontEnd::FEMode& CFrontEnd::FEMode::set8(int n, int v) +{ + mMode = ((mMode & ~(0xff << (8 * n))) | ((v & 0xff) << (8 * n))); + return *this; +} + +int CFrontEnd::FEMode::get8(int n) const +{ + return (mMode >> (8 * n)) & 0xff; +} + +bool CFrontEnd::FEMode::operator == (const FEMode &femode) const +{ + return ((getBase() == femode.getBase()) && (getGen() == femode.getGen())); +} + + +const char* CFrontEnd::FEParas::FEP_MODE = "mode"; +const char* CFrontEnd::FEParas::FEP_FREQ = "freq"; +const char* CFrontEnd::FEParas::FEP_FREQ2 = "freq2"; +const char* CFrontEnd::FEParas::FEP_BW = "bw"; +const char* CFrontEnd::FEParas::FEP_SR = "sr"; +const char* CFrontEnd::FEParas::FEP_MOD = "mod"; +const char* CFrontEnd::FEParas::FEP_PLP = "plp"; +const char* CFrontEnd::FEParas::FEP_LAYR = "layr"; +const char* CFrontEnd::FEParas::FEP_VSTD = "vtd"; +const char* CFrontEnd::FEParas::FEP_ASTD = "atd"; +const char* CFrontEnd::FEParas::FEP_AFC = "afc"; + +bool CFrontEnd::FEParas::operator == (const FEParas &fep) const +{ + if (!(getFEMode() == fep.getFEMode())) + return false; + if (getFrequency() != fep.getFrequency()) + return false; + if (getFEMode().getGen() && (getPlp() != fep.getPlp())) + return false; + + switch (getFEMode().getBase()) { + case TV_FE_DTMB: + case TV_FE_OFDM: + if (getBandwidth() != fep.getBandwidth()) + return false; + break; + case TV_FE_QAM: + if (getSymbolrate() != fep.getSymbolrate() || getModulation() != fep.getModulation()) + return false; + break; + case TV_FE_ATSC: + if (getModulation() != fep.getModulation()) + return false; + break; + case TV_FE_ISDBT: + if (getModulation() != fep.getModulation() || getLayer() != fep.getLayer()) + return false; + break; + case TV_FE_ANALOG: + if (getVideoStd() != fep.getVideoStd() || getAudioStd() != fep.getAudioStd() || getAfc() != fep.getAfc()) + return false; + break; + default: + return false; + break; + } + return true; +} + +#ifdef SUPPORT_ADTV +int CFrontEnd::GetTSSource(AM_DMX_Source_t *src) +{ + AM_FEND_GetTSSource(mFrontDevID, src); + return 0; +} + +CFrontEnd::FEParas& CFrontEnd::FEParas::fromDVBParameters(const CFrontEnd::FEMode& mode, + const struct dvb_frontend_parameters *dvb) +{ + setFEMode(mode).setFrequency(dvb->frequency); + switch (mode.getBase()) { + case TV_FE_OFDM: + case TV_FE_DTMB: + default: + setBandwidth(dvb->u.ofdm.bandwidth); + break; + case TV_FE_QAM: + setSymbolrate(dvb->u.qam.symbol_rate); + setModulation(dvb->u.qam.modulation); + break; + case TV_FE_ATSC: + setModulation(dvb->u.vsb.modulation); + break; + case TV_FE_ANALOG: + setVideoStd(stdAndColorToVideoEnum(dvb->u.analog.std)); + setAudioStd(stdAndColorToAudioEnum(dvb->u.analog.std)); + break; + } + return *this; +} + +CFrontEnd::FEParas& CFrontEnd::FEParas::fromFENDCTRLParameters(const CFrontEnd::FEMode& mode, + const AM_FENDCTRL_DVBFrontendParameters_t *fendctrl) +{ + return fromDVBParameters(mode, (struct dvb_frontend_parameters *)fendctrl); +} +#endif + diff --git a/tv/tvserver/libtv/tv/CFrontEnd.h b/tv/tvserver/libtv/tv/CFrontEnd.h new file mode 100644 index 0000000..329069b --- a/dev/null +++ b/tv/tvserver/libtv/tv/CFrontEnd.h @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef ANDROID_FRONTEND_H +#define ANDROID_FRONTEND_H +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include "CTvLog.h" +#include "CTvEv.h" + +#include "tvutils.h" + +#include <map> +#include <string> + +#ifdef SUPPORT_ADTV +extern "C" { +#include "am_fend.h" +#include "am_vout.h" +#include "linux/dvb/frontend.h" +#include "am_fend_ctrl.h" +} +#endif + +#define TV_FE_AUTO (-1) /**< Do not care the mode*/ +#define TV_FE_UNKNOWN (-2) /**< Set mode to unknown, something like reset*/ + +//for app +typedef enum atv_audo_std_s { + CC_ATV_AUDIO_STD_START = 0, + CC_ATV_AUDIO_STD_DK = 0, + CC_ATV_AUDIO_STD_I, + CC_ATV_AUDIO_STD_BG, + CC_ATV_AUDIO_STD_M, + CC_ATV_AUDIO_STD_L, + CC_ATV_AUDIO_STD_AUTO, + CC_ATV_AUDIO_STD_END = CC_ATV_AUDIO_STD_AUTO, + CC_ATV_AUDIO_STD_MUTE, +} atv_audio_std_t; +//for app +typedef enum atv_video_std_s { + CC_ATV_VIDEO_STD_START = 0, + CC_ATV_VIDEO_STD_AUTO = 0, + CC_ATV_VIDEO_STD_PAL, + CC_ATV_VIDEO_STD_NTSC, + CC_ATV_VIDEO_STD_SECAM, + CC_ATV_VIDEO_STD_END = CC_ATV_VIDEO_STD_SECAM, +} atv_video_std_t; + + +//from kernel +/*COLOR MODULATION TYPE*/ +static const unsigned long V4L2_COLOR_STD_PAL = ((unsigned long)0x04000000); +static const unsigned long V4L2_COLOR_STD_NTSC = ((unsigned long)0x08000000); +static const unsigned long V4L2_COLOR_STD_SECAM = ((unsigned long)0x10000000); +//virtual +static const unsigned long V4L2_COLOR_STD_AUTO = ((unsigned long)0x02000000); + +typedef struct frontend_para_set_s { +#ifdef SUPPORT_ADTV + fe_type_t mode; +#endif + int freq; + atv_video_std_t videoStd; + atv_audio_std_t audioStd; + int para1; + int para2; +} frontend_para_set_t; + +typedef struct atv_channel_info_s { + int finefreq; + atv_video_std_t videoStd; + atv_audio_std_t audioStd; + int isAutoStd; +} atv_channel_info_t; + +typedef struct dtv_channel_info_s { + int strength; + int quality; + int ber; +} dtv_channel_info_t; + +typedef struct channel_info_s { + int freq; + union { + atv_channel_info_t atvChanInfo; + dtv_channel_info_t dtvChanInfo; + } uInfo; +} channel_info_t; + +class CFrontEnd { +public: + + static const int FE_DEV_ID = 0; + static const int AFC_RANGE = 1000000; + + CFrontEnd(); + ~CFrontEnd(); + + int Open(int mode); + int Close(); + int setMode(int mode); + int fineTune(int freq); + int fineTune(int fineFreq, bool force); + static int formatATVFreq(int freq); +#ifdef SUPPORT_ADTV + int GetTSSource(AM_DMX_Source_t *src); +#endif + int setPara(int mode, int freq, int para1, int para2); + int setPara(const char *); + int setPara(const char *paras, bool force ); + int setProp(int cmd, int val); + int ClearAnalogFrontEnd(); + int autoLoadFE(); + int SetAnalogFrontEndTimerSwitch(int onOff); + int SetAnalogFrontEndSearhSlowMode(int onOff); + + static int stdAndColorToAudioEnum(int std); + static int stdAndColorToVideoEnum(int std); + static bool stdIsColorAuto(int std); + static int addColorAutoFlag(int std); + static int printVideoStdStr(int videoStd, char strBuffer[], int buff_size); + static int printAudioStdStr(int audioStd, char strBuffer[], int buff_size); + static unsigned long enumToStdAndColor(int videoStd, int audioStd); + static int stdEnumToCvbsFmt (int videoStd, int audioStd); + + static CFrontEnd *getInstance(); + + class FEEvent: public CTvEv { + public: + //static const int EVENT_FE_HAS_SIG = 0X01; /* found something above the noise level */ + //static const int EVENT_FE_HAS_CARRIER = 0x02; /* found a DVB signal */ + //static const int EVENT_FE_HAS_VITERBI = 0X04; /* FEC is stable */ + //static const int EVENT_FE_HAS_SYNC = 0X08; /* found sync bytes */ + // static const int EVENT_FE_HAS_LOCK = 0X10; /* everything's working... */ + //static const int EVENT_FE_HAS_TIMEOUT = 0X20; /* no lock within the last ~2 seconds */ + //static const int EVENT_FE_REINIT = 0X40; /* frontend was reinitialized, */ + static const int EVENT_FE_HAS_SIG = 0x01; + static const int EVENT_FE_NO_SIG = 0x02; + static const int EVENT_FE_INIT = 0x03; + + FEEvent(): CTvEv(CTvEv::TV_EVENT_SIGLE_DETECT) + { + } + ~FEEvent() + { + } + int mCurSigStaus; + int mCurFreq; + }; + + class IObserver { + public: + IObserver() {}; + virtual ~IObserver() {}; + virtual void onEvent(const FEEvent &ev) = 0; + }; + + int setObserver(IObserver *ob) + { + mpObserver = ob; + return 0; + } + + int getSNR(); + int getBER(); + int getInfo(); + int getStatus(); + int checkStatusOnce(); + int getStrength(); + int setCvbsAmpOut(int amp); + int setThreadDelay(int delay) ; + int getPara(int *mode, int *freq, int *para1, int *para2); + int lock(int frequency, int symbol_rate, int modulation, int bandwidth); + int setTunerAfc(int afc); + + class FEMode { + private: + int mMode; + + public: + FEMode() {} + FEMode(int mode) { mMode = mode; } + FEMode(const FEMode &femode):mMode(femode.mMode) {} + /* + fe mode:0xaabbccdd + aa - reserved + bb - scanlist/contury etc. + cc - t/t2 s/s2 c/c2 identifier + dd - femode FE_XXXX + */ + /*mode*/ + int getMode() const { return mMode; } + /*dd*/ + int getBase() const { return get8(0); } + /*cc*/ + int getGen() const { return get8(1); } + /*bb*/ + int getList() const { return get8(2); } + /*aa*/ + int getExt() const { return get8(3); } + + void setBase(int v) { set8(0, v); } + void setGen(int v) { set8(1, v); } + void setList(int v) { set8(2, v); } + void setExt(int v) { set8(3, v); } + + bool operator == (const FEMode &femode) const; + + private: + FEMode& set8(int n, int v); + int get8(int n) const; + }; + + class FEParas : public Paras { + + public: + FEParas() : Paras() { } + FEParas(const char *paras) : Paras(paras) { } + + FEMode getFEMode() const { return FEMode(getInt(FEP_MODE, -1)); } + FEParas& setFEMode(const FEMode &fem) { setInt(FEP_MODE, fem.getMode()); return *this; } + int getFrequency() const { return getInt(FEP_FREQ, -1); } + FEParas& setFrequency(int f) { setInt(FEP_FREQ, f); return *this; } + int getFrequency2() const { return getInt(FEP_FREQ2, -1); } + FEParas& setFrequency2(int f) { setInt(FEP_FREQ2, f); return *this; } + int getBandwidth() const { return getInt(FEP_BW, -1); } + FEParas& setBandwidth(int b) { setInt(FEP_BW, b); return *this; } + int getSymbolrate() const { return getInt(FEP_SR, -1); } + FEParas& setSymbolrate(int s) { setInt(FEP_SR, s); return *this; } + int getModulation() const { return getInt(FEP_MOD, -1); } + FEParas& setModulation(int m) { setInt(FEP_MOD, m); return *this; } + int getPlp() const { return getInt(FEP_PLP, -1); } + FEParas& setPlp(int p) { setInt(FEP_PLP, p); return *this; } + int getLayer() const { return getInt(FEP_LAYR, -1); } + FEParas& setLayer(int l) { setInt(FEP_LAYR, l); return *this; } + int getAudioStd() const { return getInt(FEP_ASTD, 0); } + FEParas& setAudioStd(int s) { setInt(FEP_ASTD, s); return *this; } + int getVideoStd() const { return getInt(FEP_VSTD, 0); } + FEParas& setVideoStd(int s) { setInt(FEP_VSTD, s); return *this; } + int getAfc() const { return getInt(FEP_AFC, -1); } + FEParas& setAfc(int a) { setInt(FEP_AFC, a); return *this; } + +#ifdef SUPPORT_ADTV + FEParas& fromDVBParameters(const FEMode& mode, const struct dvb_frontend_parameters *dvb); + FEParas& fromFENDCTRLParameters(const FEMode& mode, const AM_FENDCTRL_DVBFrontendParameters_t *fendctrl); +#endif + FEParas& operator = (const FEParas &fep) { mparas = fep.mparas; return *this; }; + bool operator == (const FEParas &fep) const; + + public: + static const char* FEP_MODE; + static const char* FEP_FREQ; + static const char* FEP_FREQ2; + static const char* FEP_BW; + static const char* FEP_SR; + static const char* FEP_MOD; + static const char* FEP_PLP; + static const char* FEP_LAYR; + static const char* FEP_VSTD; + static const char* FEP_ASTD; + static const char* FEP_AFC; + }; + + /* freq: freq1==freq2 for single, else for range */ + static int convertParas(char *paras, int mode, int freq1, int freq2, int para1, int para2); + +private: + static CFrontEnd *mInstance; + + int mFrontDevID; + int mDemuxDevID; + int mTvPlayDevID; + int mCurFineFreq; + IObserver *mpObserver; + FEEvent mCurSigEv; + int mCurMode; + int mCurFreq; + int mCurPara1; + int mCurPara2; + bool mbFEOpened; + FEParas mFEParas; + static void dmd_fend_callback(long dev_no, int event_type, void *param, void *user_data); + void saveCurrentParas(FEParas ¶s); + int setPropLocked(int cmd, int val); + +protected: + mutable Mutex mLock; +}; +#endif // ANDROID_FRONTEND_H + diff --git a/tv/tvserver/libtv/tv/CTv.cpp b/tv/tvserver/libtv/tv/CTv.cpp new file mode 100644 index 0000000..dd950a5 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTv.cpp @@ -0,0 +1,5824 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTv" +#define UNUSED(x) (void)x + +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <dirent.h> +#include <stdlib.h> +#include <string.h> +#include <malloc.h> +#include <pthread.h> +#include <sys/types.h> +#include <errno.h> +#include <dlfcn.h> +#include <cutils/properties.h> +#include <cutils/android_reboot.h> +#include <utils/threads.h> +#include <time.h> +#include <sys/prctl.h> +#include <getopt.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdlib.h> +#ifdef ANDROID +#include <termios.h> +#endif +#include <string.h> +#include <signal.h> +#include <hardware_legacy/power.h> +#include <media/AudioSystem.h> +#include <sys/wait.h> + +#include <tvutils.h> +#include <tvconfig.h> +#include <CFile.h> +#include <serial_operate.h> +#include <CFbcHelper.h> + +#include "CTvDatabase.h" +#include "../version/version.h" +#include "../tvsetting/CTvSetting.h" + +#include <hardware_legacy/power.h> + +#ifdef SUPPORT_ADTV +#include <am_epg.h> +#include <am_mem.h> + +extern "C" { +#include "am_ver.h" +#include "am_misc.h" +#include "am_debug.h" +#include "am_fend.h" +} +#endif + +#include <math.h> +#include <sys/ioctl.h> + +#include "CTv.h" + +using namespace android; + +static const int WALL_EFFECT_VALUE[CC_BAND_ITEM_CNT] = { 0, 0, 1, 2, 2, 0 }; + +bool CTv::insertedFbcDevice() +{ + bool ret = false; + + if (hdmiOutWithFbc()) { + CFbcCommunication *fbc = GetSingletonFBC(); + char panel_model[64] = {0}; + + if (fbc == NULL) { + LOGD ("%s, there is no fbc!!!", __func__); + } + else { + fbc->cfbc_Get_FBC_Get_PANel_INFO(COMM_DEV_SERIAL, panel_model); + + if (0 == panel_model[0]) { + LOGD ("%s, device is not fbc", __func__); + } + else { + LOGD ("%s, get panel info from fbc is %s", __func__, panel_model); + ret = true; + } + } + } + + return ret; +} + +CTv::CTv():mTvDmx(0), mTvDmx1(1), mTvDmx2(2), mTvMsgQueue(this) +{ + mAudioMuteStatusForTv = CC_AUDIO_UNMUTE; + mAudioMuteStatusForSystem = CC_AUDIO_UNMUTE; + + //copy file to param + char buf[PROPERTY_VALUE_MAX] = {0}; + int len = property_get("tv.tvconfig.force_copy", buf, "true"); + + if (isFileExist(TV_CONFIG_FILE_SYSTEM_PATH)) { + if ( !isFileExist(TV_CONFIG_FILE_PARAM_PATH) ) { + CFile file ( TV_CONFIG_FILE_SYSTEM_PATH ); + + if ( file.copyTo ( TV_CONFIG_FILE_PARAM_PATH ) != 0 ) { + LOGE ( "%s, copy file = %s , error", __FUNCTION__, TV_CONFIG_FILE_PARAM_PATH ); + } + else { + LOGD ("%s copy from %s to %s success.", __func__, TV_CONFIG_FILE_SYSTEM_PATH, TV_CONFIG_FILE_PARAM_PATH); + } + } + } + + if (isFileExist(TV_CHANNEL_LIST_SYSTEM_PATH)) { + if (!isFileExist(TV_CHANNEL_LIST_PARAM_PATH)) { + CFile file ( TV_CHANNEL_LIST_SYSTEM_PATH ); + + if ( file.copyTo ( TV_CHANNEL_LIST_PARAM_PATH ) != 0 ) { + LOGE ( "%s, copy file = %s , error", __FUNCTION__, TV_CHANNEL_LIST_PARAM_PATH ); + } + } + } + if (isFileExist(TV_RRT_DEFINE_SYSTEM_PATH)) { + if (!isFileExist(TV_RRT_DEFINE_PARAM_PATH)) { + CFile file ( TV_RRT_DEFINE_SYSTEM_PATH ); + + if ( file.copyTo ( TV_RRT_DEFINE_PARAM_PATH ) != 0 ) { + LOGE ( "%s, copy file = %s , error", __FUNCTION__, TV_RRT_DEFINE_PARAM_PATH ); + } + + char sysCmd[1024]; + sprintf(sysCmd, "chmod 644 %s", TV_RRT_DEFINE_PARAM_PATH); + if (system(sysCmd)) { + LOGE("exec cmd:%s fail\n", sysCmd); + } + } + } + +#ifdef SUPPORT_ADTV + AM_EVT_Init(); +#endif + mpObserver = NULL; + fbcIns = NULL; + mAutoSetDisplayFreq = false; + mPreviewEnabled = false; + + mFrontDev = CFrontEnd::getInstance(); + mpTvin = CTvin::getInstance(); + mTvScanner = CTvScanner::getInstance(); + mTvRrt = CTvRrt::getInstance(); + mTvRrt->setObserver(&mTvMsgQueue); + tv_config_load (TV_CONFIG_FILE_PATH); + sqlite3_config (SQLITE_CONFIG_SERIALIZED); + sqlite3_soft_heap_limit(8 * 1024 * 1024); + // Initialize SQLite. + sqlite3_initialize(); + CTvDatabase::GetTvDb()->InitTvDb ( TV_DB_PATH ); + + if ( CTvDimension::isDimensionTblExist() == false ) { + CTvDimension::builtinAtscDimensions(); + } + + mFactoryMode.init(); + mDtvScanRunningStatus = DTV_SCAN_RUNNING_NORMAL; + + mHdmiOutFbc = insertedFbcDevice(); + + mSetHdmiEdid = false; + + mBootvideoStatusDetectThread = new CBootvideoStatusDetect(); + mBootvideoStatusDetectThread->setObserver(this); + + m_hdmi_audio_data = 0; + mHDMIAudioCheckThread.setObserver(this); + mDevicesPollStatusDetectThread.setObserver ( this ); + mFrontDev->setObserver ( &mTvMsgQueue ); + mTvEas = CTvEas::GetInstance(); + mTvEas->setObserver(&mTvMsgQueue); + if (mHdmiOutFbc) { + fbcIns = GetSingletonFBC(); + setUpgradeFbcObserver(this); + fbcIns->cfbc_Set_DNLP(COMM_DEV_SERIAL, 0);//disable dnlp for fbc project. + } + mSubtitle.setObserver(this); + mHeadSet.setObserver(this); + mAv.setObserver(&mTvMsgQueue); + mMainVolLutTableExtraName[0] = '\0'; + //----------------------------------------------------------- + mCurAudioMasterVolume = CC_DEF_SOUND_VOL; + mCurAudioBalance = CC_DEF_SOUND_BALANCE_VAL; + mCurAudioSupperBassVolume = CC_DEF_SUPPERBASS_VOL; + mCurAudioSupperBassSwitch = CC_SWITCH_OFF; + mCurAudioSRSSurround = CC_SWITCH_OFF; + mCurAudioSrsDialogClarity = CC_SWITCH_OFF; + mCurAudioSrsTruBass = CC_SWITCH_OFF; + mCurAudioSPDIFSwitch = CC_SWITCH_ON; + mCurAudioSPDIFMode = CC_SPDIF_MODE_PCM; + mCurAudioBassVolume = CC_DEF_BASS_TREBLE_VOL; + mCurAudioTrebleVolume = CC_DEF_BASS_TREBLE_VOL; + mCurAudioSoundMode = CC_SOUND_MODE_END; + mCurAudioWallEffect = CC_SWITCH_OFF; + mCurAudioEQMode = CC_EQ_MODE_START; + mCustomAudioMasterVolume = CC_DEF_SOUND_VOL; + mCustomAudioBalance = CC_DEF_SOUND_BALANCE_VAL; + mCustomAudioSupperBassVolume = CC_DEF_SUPPERBASS_VOL; + mCustomAudioSupperBassSwitch = CC_SWITCH_OFF; + mCustomAudioSRSSurround = CC_SWITCH_OFF; + mCustomAudioSrsDialogClarity = CC_SWITCH_OFF; + mCustomAudioSrsTruBass = CC_SWITCH_OFF; + mCustomAudioBassVolume = CC_DEF_BASS_TREBLE_VOL; + mCustomAudioTrebleVolume = CC_DEF_BASS_TREBLE_VOL; + mCustomAudioSoundMode = CC_SOUND_MODE_END; + mCustomAudioWallEffect = CC_SWITCH_OFF; + mCustomAudioEQMode = CC_EQ_MODE_START; + mCustomAudioSoundEnhancementSwitch = CC_SWITCH_OFF; + mVolumeCompensationVal = 0; + + mMainVolumeBalanceVal = 0; + for (int i = 0; i < CC_BAND_ITEM_CNT; i++) { + mCustomEQGainBuf[i] = 0; + mCurEQGainBuf[i] = 0; + mCurEQGainChBuf[i] = 0; + } + + mTvAction &= TV_ACTION_NULL; + mTvStatus = TV_INIT_ED; + pGpio = new CTvGpio(); + print_version_info(); +} + +CTv::~CTv() +{ + mpObserver = NULL; + CTvDatabase::deleteTvDb(); + tv_config_unload(); + mAv.Close(); + mTvStatus = TV_INIT_ED; + mFrontDev->Close(); + + if (fbcIns != NULL) { + fbcIns->fbcRelease(); + delete fbcIns; + fbcIns = NULL; + } + + if (pGpio != NULL) { + delete pGpio; + pGpio = NULL; + } +} + +void CTv::onEvent ( const CTvScanner::ScannerEvent &ev ) +{ + LOGD ( "%s, CTv::onEvent lockStatus = %d type = %d\n", __FUNCTION__, ev.mLockedStatus, ev.mType ); + + if ( mDtvScanRunningStatus == DTV_SCAN_RUNNING_ANALYZE_CHANNEL ) { + if ( ev.mType == CTvScanner::ScannerEvent::EVENT_SCAN_END ) { + CMessage msg; + msg.mType = CTvMsgQueue::TV_MSG_STOP_ANALYZE_TS; + msg.mpData = this; + mTvMsgQueue.sendMsg ( msg ); + } else if ( ev.mType == CTvScanner::ScannerEvent::EVENT_STORE_END ) { + CTvEpg::EpgEvent epgev; + epgev.type = CTvEpg::EpgEvent::EVENT_CHANNEL_UPDATE_END; + mDtvScanRunningStatus = DTV_SCAN_RUNNING_NORMAL; + sendTvEvent ( epgev ); + } + } else { + sendTvEvent ( ev ); + } +} + +void CTv::onEvent ( const CTvEas::EasEvent &ev ) +{ + sendTvEvent(ev); +} + +void CTv::onEvent ( const CFrontEnd::FEEvent &ev ) +{ + const char *config_value = NULL; + LOGD ( "[source_switch_time]: %fs, %s, FE event type = %d tvaction=%x", getUptimeSeconds(), __FUNCTION__, ev.mCurSigStaus, mTvAction); + if (mTvAction & TV_ACTION_SCANNING) return; + + + if ( ev.mCurSigStaus == CFrontEnd::FEEvent::EVENT_FE_HAS_SIG ) { + LOGD("[source_switch_time]: %fs, fe lock", getUptimeSeconds()); + if (/*m_source_input == SOURCE_TV || */m_source_input == SOURCE_DTV && (mTvAction & TV_ACTION_PLAYING)) { //atv and other tvin source not to use it, and if not playing, not use have sig + TvEvent::SignalInfoEvent ev; + ev.mStatus = TVIN_SIG_STATUS_STABLE; + ev.mTrans_fmt = TVIN_TFMT_2D; + ev.mFmt = TVIN_SIG_FMT_NULL; + ev.mReserved = 0; + sendTvEvent ( ev ); + } + } else if ( ev.mCurSigStaus == CFrontEnd::FEEvent::EVENT_FE_NO_SIG ) { + LOGD("[source_switch_time]: %fs, fe unlock", getUptimeSeconds()); + if ((!(mTvAction & TV_ACTION_STOPING)) && m_source_input == SOURCE_DTV && (mTvAction & TV_ACTION_PLAYING)) { //just playing + TvEvent::SignalInfoEvent ev; + ev.mStatus = TVIN_SIG_STATUS_NOSIG; + ev.mTrans_fmt = TVIN_TFMT_2D; + ev.mFmt = TVIN_SIG_FMT_NULL; + ev.mReserved = 0; + sendTvEvent ( ev ); + } + } +} + +void CTv::onEvent ( const CTvEpg::EpgEvent &ev ) +{ + switch ( ev.type ) { + case CTvEpg::EpgEvent::EVENT_TDT_END: + LOGD ( "%s, CTv::onEvent epg time = %ld", __FUNCTION__, ev.time ); + mTvTime.setTime ( ev.time ); + break; + + case CTvEpg::EpgEvent::EVENT_CHANNEL_UPDATE: { + LOGD ( "%s, CTv:: onEvent channel update", __FUNCTION__ ); + CMessage msg; + msg.mType = CTvMsgQueue::TV_MSG_START_ANALYZE_TS; + msg.mpData = this; + mCurAnalyzeTsChannelID = ev.channelID; + mTvMsgQueue.sendMsg ( msg ); + break; + } + + default: + break; + } + + sendTvEvent ( ev ); +} + +void CTv::onEvent(const CTvRecord::RecEvent &ev) +{ + LOGD ( "RecEvent = %d", ev.type); + switch ( ev.type ) { + case CTvRecord::RecEvent::EVENT_REC_START: { + TvEvent::RecorderEvent RecorderEvent; + RecorderEvent.mStatus = TvEvent::RecorderEvent::EVENT_RECORD_START; + RecorderEvent.mError = (int)ev.error; + sendTvEvent(RecorderEvent); + }break; + case CTvRecord::RecEvent::EVENT_REC_STOP: { + TvEvent::RecorderEvent RecorderEvent; + RecorderEvent.mStatus = TvEvent::RecorderEvent::EVENT_RECORD_STOP; + RecorderEvent.mError = (int)ev.error; + RecorderEvent.mId = String8(ev.id.c_str()); + sendTvEvent(RecorderEvent); + }break; + default: + break; + } +} + +void CTv::onEvent (const CTvRrt::RrtEvent &ev) +{ + sendTvEvent ( ev ); +} + +void CTv::onEvent(const CAv::AVEvent &ev) +{ + LOGD ( "[source_switch_time]: %fs, AVEvent = %d", getUptimeSeconds(), ev.type); + switch ( ev.type ) { + case CAv::AVEvent::EVENT_AV_STOP: { + if ( mTvAction & TV_ACTION_STOPING ) { + LOGD("tv stopping, no need CAv::AVEvent::EVENT_AV_STOP"); + break; + } + if ( iSBlackPattern ) { + mAv.DisableVideoWithBlackColor(); + } else { + mAv.DisableVideoWithBlueColor(); + } + SetAudioMuteForTv ( CC_AUDIO_MUTE ); + + TvEvent::SignalInfoEvent ev; + ev.mStatus = TVIN_SIG_STATUS_NOSIG; + ev.mTrans_fmt = TVIN_TFMT_2D; + ev.mFmt = TVIN_SIG_FMT_NULL; + ev.mReserved = 0; + sendTvEvent ( ev ); + break; + } + + case CAv::AVEvent::EVENT_AV_RESUEM: { + TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_PLAYBACK_RESUME; + AvPlayBackEvt.mProgramId = (int)ev.param; + sendTvEvent(AvPlayBackEvt); + if (m_source_input == SOURCE_DTV && (mTvAction & TV_ACTION_PLAYING)) { //atv and other tvin source not to use it, and if not playing, not use have sig + LOGD("[EVENT_AV_RESUEM]"); + SetAudioMuteForTv(CC_AUDIO_UNMUTE); + Tv_SetAudioInSource(SOURCE_DTV); + } + break; + } + + case CAv::AVEvent::EVENT_AV_SCAMBLED: { + if ( iSBlackPattern ) { + mAv.DisableVideoWithBlackColor(); + } else { + mAv.DisableVideoWithBlueColor(); + } + TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_SCAMBLED; + AvPlayBackEvt.mProgramId = (int)ev.param; + sendTvEvent(AvPlayBackEvt); + break; + } + case CAv::AVEvent::EVENT_AV_VIDEO_AVAILABLE: { + LOGD("[source_switch_time]: %fs, EVENT_AV_VIDEO_AVAILABLE, video available", getUptimeSeconds()); + if (m_source_input == SOURCE_DTV && (mTvAction & TV_ACTION_PLAYING)) { //atv and other tvin source not to use it, and if not playing, not use have sig + if ( m_win_mode == PREVIEW_WONDOW ) { + mAv.setVideoScreenMode ( CAv::VIDEO_WIDEOPTION_FULL_STRETCH ); + } + if (mAutoSetDisplayFreq && !mPreviewEnabled) { + mpTvin->VDIN_SetDisplayVFreq(50, mHdmiOutFbc); + } + SetDisplayMode(CVpp::getInstance()->GetDisplayMode(m_source_input), + m_source_input, + mAv.getVideoResolutionToFmt()); + //usleep(50 * 1000); + mAv.EnableVideoNow(true); + LOGD("[source_switch_time]: %fs, EVENT_AV_VIDEO_AVAILABLE, video available ok", getUptimeSeconds()); + SetAudioMuteForTv(CC_AUDIO_UNMUTE); + Tv_SetAudioInSource(SOURCE_DTV); + } + + TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_VIDEO_AVAILABLE; + AvPlayBackEvt.mProgramId = (int)ev.param; + sendTvEvent(AvPlayBackEvt); + break; + } + case CAv::AVEvent::EVENT_AV_UNSUPPORT: { + LOGD("To AVS or AVS+ format");//just avs format, not unsupport, and avs avs+ + break; + } + case CAv::AVEvent::EVENT_PLAY_UPDATE: { + //fix me: get the player, [only one player can run concurrently] + //the av event should be handled by player.. + //need refactoring here + CDTVTvPlayer *player = (CDTVTvPlayer *)PlayerManager::getInstance().getFirstDevWithIdContains("atsc"); + if (player) + player->onPlayUpdate(ev); + else { + LOGD("no atsc player found"); + } + break; + } + + default: + break; + } +} + +CTv::CTvMsgQueue::CTvMsgQueue(CTv *tv) +{ + mpTv = tv; +} + +CTv::CTvMsgQueue::~CTvMsgQueue() +{ +} + +void CTv::CTvMsgQueue::handleMessage ( CMessage &msg ) +{ + LOGD ("%s, CTv::CTvMsgQueue::handleMessage type = %d", __FUNCTION__, msg.mType); + + switch ( msg.mType ) { + case TV_MSG_COMMON: + break; + + case TV_MSG_STOP_ANALYZE_TS: + //mpTv->Tv_Stop_Analyze_Ts(); + break; + + case TV_MSG_START_ANALYZE_TS: + //mpTv->Tv_Start_Analyze_Ts ( pTv->mCurAnalyzeTsChannelID ); + break; + + case TV_MSG_CHECK_FE_DELAY: { + mpTv->mFrontDev->checkStatusOnce(); + break; + } + + case TV_MSG_AV_EVENT: { + mpTv->onEvent(*((CAv::AVEvent *)(msg.mpPara))); + break; + } + + case TV_MSG_FE_EVENT: { + mpTv->onEvent(*((CFrontEnd::FEEvent *)(msg.mpPara))); + break; + } + + case TV_MSG_SCAN_EVENT: { + mpTv->onEvent(*((CTvScanner::ScannerEvent *)(msg.mpPara))); + break; + } + + case TV_MSG_EPG_EVENT: { + mpTv->onEvent(*((CTvEpg::EpgEvent *)(msg.mpPara))); + break; + } + + case TV_MSG_HDMI_SR_CHANGED: { + int sr = ((int *)(msg.mpPara))[0]; + mpTv->onHdmiSrChanged(sr, (((int *)(msg.mpPara))[1] == 0) ? true : false); + mpTv->setAudioPreGain(mpTv->m_source_input); + break; + } + + case TV_MSG_ENABLE_VIDEO_LATER: { + int fc = msg.mpPara[0]; + mpTv->onEnableVideoLater(fc); + break; + } + + case TV_MSG_VIDEO_AVAILABLE_LATER: { + int fc = msg.mpPara[0]; + mpTv->onVideoAvailableLater(fc); + break; + } + + case TV_MSG_RECORD_EVENT: { + mpTv->onEvent(*((CTvRecord::RecEvent *)(msg.mpPara))); + break; + } + + case TV_MSG_RRT_EVENT: { + mpTv->onEvent(*((CTvRrt::RrtEvent *)(msg.mpPara))); + break; + } + + case TV_MSG_EAS_EVENT: { + mpTv->onEvent(*((CTvEas::EasEvent *)(msg.mpPara))); + break; + } + + default: + break; + } +} + +void CTv::CTvMsgQueue::onEvent ( const CTvScanner::ScannerEvent &ev ) +{ + CMessage msg; + msg.mDelayMs = 0; + msg.mType = CTvMsgQueue::TV_MSG_SCAN_EVENT; + memcpy(msg.mpPara, (void*)&ev, sizeof(ev)); + this->sendMsg ( msg ); +} + +void CTv::CTvMsgQueue::onEvent ( const CFrontEnd::FEEvent &ev ) +{ + CMessage msg; + msg.mDelayMs = 0; + msg.mType = CTvMsgQueue::TV_MSG_FE_EVENT; + memcpy(msg.mpPara, (void*)&ev, sizeof(ev)); + this->sendMsg ( msg ); +} + +void CTv::CTvMsgQueue::onEvent ( const CTvEpg::EpgEvent &ev ) +{ + CMessage msg; + msg.mDelayMs = 0; + msg.mType = CTvMsgQueue::TV_MSG_EPG_EVENT; + memcpy(msg.mpPara, (void*)&ev, sizeof(ev)); + this->sendMsg ( msg ); +} + +void CTv::CTvMsgQueue::onEvent(const CAv::AVEvent &ev) +{ + CMessage msg; + msg.mDelayMs = 0; + msg.mType = CTvMsgQueue::TV_MSG_AV_EVENT; + memcpy(msg.mpPara, (void*)&ev, sizeof(ev)); + this->sendMsg ( msg ); +} + +void CTv::CTvMsgQueue::onEvent(const CTvRecord::RecEvent &ev) +{ + CMessage msg; + msg.mDelayMs = 0; + msg.mType = CTvMsgQueue::TV_MSG_RECORD_EVENT; + memcpy(msg.mpPara, (void*)&ev, sizeof(ev)); + this->sendMsg ( msg ); +} + +void CTv::CTvMsgQueue::onEvent ( const CTvRrt::RrtEvent &ev ) +{ + CMessage msg; + msg.mDelayMs = 0; + msg.mType = CTvMsgQueue::TV_MSG_RRT_EVENT; + memcpy(msg.mpPara, (void*)&ev, sizeof(ev)); + this->sendMsg ( msg ); +} + +void CTv::CTvMsgQueue::onEvent ( const CTvEas::EasEvent &ev ) +{ + CMessage msg; + msg.mDelayMs = 0; + msg.mType = CTvMsgQueue::TV_MSG_EAS_EVENT; + LOGD("event size = %d\n",sizeof(ev)); + memcpy(msg.mpPara, (void*)&ev, sizeof(ev)); + this->sendMsg ( msg ); +} + +void CTv::onHdmiSrChanged(int sr, bool bInit) +{ + if (bInit) { + LOGD ( "%s, Init HDMI audio, sampling rate:%d", __FUNCTION__, sr ); + sr = HanldeAudioInputSr(sr); + InitTvAudio (sr, CC_IN_USE_SPDIF_DEVICE); + } else { + LOGD ( "%s, Reset HDMI sampling rate to %d", __FUNCTION__, sr ); + AudioChangeSampleRate ( sr ); + } +} + +void CTv::onHMDIAudioStatusChanged(int status) +{ + if (status == 0) {//change to no audio data + SetAudioMuteForTv ( CC_AUDIO_MUTE ); + } else if (status == 1) {//change to audio data come + Tv_SetAudioInSource(m_source_input); + usleep(200 * 1000); + SetAudioMuteForTv ( CC_AUDIO_UNMUTE ); + } +} + +int CTv::setTvObserver ( TvIObserver *ob ) +{ + mpObserver = ob; + return 0; +} + +void CTv::sendTvEvent ( const CTvEv &ev ) +{ + /* send sigstate to AutoBackLight */ + if (ev.getEvType() == CTvEv::TV_EVENT_SIGLE_DETECT) { + TvEvent::SignalInfoEvent *pEv = (TvEvent::SignalInfoEvent *)(&ev); + if (pEv->mStatus == TVIN_SIG_STATUS_STABLE) { + mAutoBackLight.updateSigState(mAutoBackLight.SIG_STATE_STABLE); + } else { + mAutoBackLight.updateSigState(mAutoBackLight.SIG_STATE_NOSIG); + } + } + + LOGD ( "%s, tvaction=%x", __FUNCTION__, mTvAction); + if ((mTvAction & TV_ACTION_SCANNING) && (ev.getEvType() == CTvEv::TV_EVENT_SIGLE_DETECT)) { + LOGD("%s, when scanning, not send sig detect event", __FUNCTION__); + return; + } + if ( mpObserver != NULL ) { + mpObserver->onTvEvent ( ev ); + } +} + +int CTv::ClearAnalogFrontEnd() +{ + return mFrontDev->ClearAnalogFrontEnd (); +} + +int CTv::clearFrontEnd(int para) +{ + return mFrontDev->setPara(para, 470000000, 0, 0); +} + +int CTv::Scan(const char *feparas, const char *scanparas) { + AutoMutex _l(mLock); + m_source_input = SOURCE_INVALID; + SetAudioMuteForTv ( CC_AUDIO_MUTE ); + mTvAction = mTvAction | TV_ACTION_SCANNING; + LOGD("mTvAction = %#x, %s", mTvAction, __FUNCTION__); + LOGD("fe[%s], scan[%s] %s", feparas, scanparas, __FUNCTION__); + + mHDMIAudioCheckThread.requestAndWaitPauseCheck(); + mAv.StopTS(); + mpTvin->Tvin_StopDecoder(); + if ( iSBlackPattern ) { + mAv.DisableVideoWithBlackColor(); + } else { + mAv.DisableVideoWithBlueColor(); + } + + CTvScanner::ScanParas sp(scanparas); + CFrontEnd::FEParas fp(feparas); + + if (sp.getAtvMode() & TV_SCAN_ATVMODE_AUTO) + CTvProgram::CleanAllProgramBySrvType ( CTvProgram::TYPE_ATV ); + if (sp.getDtvMode() & TV_SCAN_DTVMODE_MANUAL) { + CTvChannel::DeleteBetweenFreq(sp.getDtvFrequency1(), sp.getDtvFrequency2()); + } else { + CTvProgram::CleanAllProgramBySrvType ( CTvProgram::TYPE_DTV ); + CTvProgram::CleanAllProgramBySrvType ( CTvProgram::TYPE_RADIO ); + CTvEvent::CleanAllEvent(); + } + + mTvScanner->setObserver(&mTvMsgQueue); + mDtvScanRunningStatus = DTV_SCAN_RUNNING_NORMAL; + + mFrontDev->Open(TV_FE_AUTO); + + return mTvScanner->Scan(fp, sp); +} + +int CTv::dtvScan(int mode, int scan_mode, int beginFreq, int endFreq, int para1, int para2) { + AutoMutex _l(mLock); + mTvAction = mTvAction | TV_ACTION_SCANNING; + LOGD("mTvAction = %#x, %s", mTvAction, __FUNCTION__); + LOGD("mode[%#x], scan_mode[%#x], freq[%d-%d], para[%d,%d] %s", + mode, scan_mode, beginFreq, endFreq, para1, para2, __FUNCTION__); + //mTvEpg.leaveChannel(); + mAv.StopTS(); + + if ( iSBlackPattern ) { + mAv.DisableVideoWithBlackColor(); + } else { + mAv.DisableVideoWithBlueColor(); + } + + if (scan_mode == TV_SCAN_DTVMODE_MANUAL) { + CTvChannel::DeleteBetweenFreq(beginFreq, endFreq); + } else { + CTvProgram::CleanAllProgramBySrvType ( CTvProgram::TYPE_DTV ); + CTvProgram::CleanAllProgramBySrvType ( CTvProgram::TYPE_RADIO ); + CTvEvent::CleanAllEvent(); + } + mTvScanner->setObserver(&mTvMsgQueue); + mDtvScanRunningStatus = DTV_SCAN_RUNNING_NORMAL; + + return mTvScanner->dtvScan(mode, scan_mode, beginFreq, endFreq, para1, para2); +} + +int CTv::dtvMode(const char *mode) +{ + if ( strcmp ( mode, DTV_DTMB_MODE ) == 0 ) + return (TV_FE_DTMB); + else if ( strcmp ( mode, DTV_DVBC_MODE ) == 0 ) + return (TV_FE_QAM); + else if ( strcmp ( mode, DTV_DVBS_MODE ) == 0 ) + return (TV_FE_QPSK); + else if ( strcmp ( mode, DTV_ATSC_MODE ) == 0 ) + return (TV_FE_ATSC); + else if ( strcmp ( mode, DTV_DVBT_MODE ) == 0 ) + return (TV_FE_OFDM); + else if ( strcmp ( mode, DTV_ISDBT_MODE ) == 0 ) + return (TV_FE_ISDBT); + + return (TV_FE_DTMB); +} + +int CTv::dtvAutoScan() +{ + const char *dtv_mode = config_get_str ( CFG_SECTION_TV, CFG_DTV_MODE, DTV_DTMB_MODE); + return dtvScan(dtvMode(dtv_mode), TV_SCAN_DTVMODE_ALLBAND, 0, 0, -1, -1); +} + +int CTv::dtvCleanProgramByFreq ( int freq ) +{ + int iOutRet = 0; + CTvChannel channel; + iOutRet = CTvChannel::SelectByFreq ( freq, channel ); + if ( -1 == iOutRet ) { + LOGD("%s, Warnning: Current Freq not have program info in the ts_table\n", __FUNCTION__); + } + + iOutRet == CTvProgram::deleteChannelsProgram ( channel ); + return iOutRet; +} + +int CTv::dtvManualScan (int beginFreq, int endFreq, int modulation) +{ + const char *dtv_mode = config_get_str ( CFG_SECTION_TV, CFG_DTV_MODE, "dtmb"); + return dtvScan(dtvMode(dtv_mode), TV_SCAN_DTVMODE_MANUAL, beginFreq, endFreq, modulation, -1); + +} + +//searchType 0:not 256 1:is 256 Program +int CTv::atvAutoScan(int videoStd __unused, int audioStd __unused, int searchType, int procMode) +{ + int minScanFreq, maxScanFreq, vStd, aStd; + AutoMutex _l( mLock ); + if ( !mATVDisplaySnow ) + mAv.DisableVideoWithBlueColor(); + mTvAction |= TV_ACTION_SCANNING; + stopPlaying(false); + mTvScanner->setObserver ( &mTvMsgQueue ); + SetAudioMuteForTv ( CC_AUDIO_MUTE ); + getATVMinMaxFreq (&minScanFreq, &maxScanFreq ); + if ( minScanFreq == 0 || maxScanFreq == 0 || minScanFreq > maxScanFreq ) { + LOGE ( "%s, auto scan freq set is error min=%d, max=%d", __FUNCTION__, minScanFreq, maxScanFreq ); + return -1; + } + if ( !mATVDisplaySnow ) { + mpTvin->Tvin_StopDecoder(); + } else { + mpTvin->SwitchSnow( true ); + } + + vStd = CC_ATV_VIDEO_STD_PAL; + aStd = CC_ATV_AUDIO_STD_DK; + tvin_port_t source_port = mpTvin->Tvin_GetSourcePortBySourceInput(SOURCE_TV); + mpTvin->VDIN_OpenPort ( source_port ); + unsigned long stdAndColor = mFrontDev->enumToStdAndColor(vStd, aStd); + + int fmt = CFrontEnd::stdEnumToCvbsFmt (vStd, aStd); + mpTvin->AFE_SetCVBSStd ( ( tvin_sig_fmt_t ) TVIN_SIG_FMT_NULL ); + + if (searchType == 0) { + CTvProgram::CleanAllProgramBySrvType ( CTvProgram::TYPE_ATV ); + } else if (searchType == 1) { //type for skyworth, and insert 256 prog, and just update ts table + } + minScanFreq = mFrontDev->formatATVFreq ( minScanFreq ); + maxScanFreq = mFrontDev->formatATVFreq ( maxScanFreq ); + LOGD("%s, atv auto scan vstd=%d, astd=%d stdandcolor=%lld", __FUNCTION__, vStd, aStd, stdAndColor); + + mTvScanner->autoAtvScan ( minScanFreq, maxScanFreq, stdAndColor, searchType, procMode); + return 0; +} + +int CTv::atvAutoScan(int videoStd __unused, int audioStd __unused, int searchType) +{ + return atvAutoScan(videoStd, audioStd, searchType, 0); +} + +int CTv::clearAllProgram(int arg0 __unused) +{ + CTvProgram::CleanAllProgramBySrvType ( CTvProgram::TYPE_ATV ); + CTvProgram::CleanAllProgramBySrvType ( CTvProgram::TYPE_TV ); + CTvProgram::CleanAllProgramBySrvType ( CTvProgram::TYPE_DTV ); + CTvProgram::CleanAllProgramBySrvType ( CTvProgram::TYPE_RADIO); + return 0; +} + +int CTv::atvMunualScan ( int startFreq, int endFreq, int videoStd, int audioStd, + int store_Type , int channel_num ) +{ + int minScanFreq, maxScanFreq, vStd, aStd; + + minScanFreq = mFrontDev->formatATVFreq ( startFreq ); + maxScanFreq = mFrontDev->formatATVFreq ( endFreq ); + if ( minScanFreq == 0 || maxScanFreq == 0 ) { + LOGE ( "%s, munual scan freq set is error min=%d, max=%d", __FUNCTION__, minScanFreq, maxScanFreq ); + return -1; + } + + //if set std null AUTO, use default PAL/DK + //if(videoStd == CC_ATV_VIDEO_STD_AUTO) { + // vStd = CC_ATV_VIDEO_STD_PAL; + // aStd = CC_ATV_AUDIO_STD_DK; + // } else { + vStd = videoStd; + aStd = audioStd; + // } + + AutoMutex _l( mLock ); + if ( !mATVDisplaySnow ) + mAv.DisableVideoWithBlueColor(); + mTvAction |= TV_ACTION_SCANNING; + mTvScanner->setObserver ( &mTvMsgQueue ); + SetAudioMuteForTv ( CC_AUDIO_MUTE ); + unsigned long stdAndColor = mFrontDev->enumToStdAndColor(vStd, aStd); + + tvin_port_t source_port = mpTvin->Tvin_GetSourcePortBySourceInput(SOURCE_TV); + mpTvin->VDIN_OpenPort ( source_port ); + + int fmt = CFrontEnd::stdEnumToCvbsFmt (vStd, aStd); + mpTvin->AFE_SetCVBSStd ( ( tvin_sig_fmt_t ) TVIN_SIG_FMT_NULL ); + LOGD("%s, atv manual scan vstd=%d, astd=%d stdandcolor=%lld", __FUNCTION__, vStd, aStd, stdAndColor); + + return mTvScanner->ATVManualScan ( minScanFreq, maxScanFreq, stdAndColor, store_Type, channel_num); +} + +int CTv::getVideoFormatInfo ( int *pWidth, int *pHeight, int *pFPS, int *pInterlace ) +{ + int iOutRet = -1; + do { + if ( NULL == pWidth || NULL == pHeight || NULL == pFPS || NULL == pInterlace ) { + break; + } + + iOutRet = mAv.GetVideoStatus (pWidth, pHeight, pFPS, pInterlace); + + if ( DVB_SUCCESS != iOutRet ) { + LOGD ( "%s, ERROR: Cann't Get video format info\n", __FUNCTION__); + break; + } + //LOGD("%s, w : %d h : %d fps : %d interlaced: %d\n", __FUNCTION__, video_status.src_w,video_status.src_h,video_status.fps,video_status.interlaced); + } while ( false ); + return iOutRet; +} + +int CTv::getAudioFormatInfo ( int fmt[2], int sample_rate[2], int resolution[2], int channels[2], + int lfepresent[2], int *frames, int *ab_size, int *ab_data, int *ab_free) +{ + int iOutRet = -1; + + do { + iOutRet = mAv.GetAudioStatus (fmt, sample_rate, resolution, channels, lfepresent, frames, ab_size, ab_data, ab_free); + if ( DVB_SUCCESS != iOutRet ) { + LOGD ( "%s, ERROR: Cann't Get audio format info\n", __FUNCTION__); + break; + } + } while ( false ); + + return iOutRet; +} + +int CTv::stopScanLock() +{ + AutoMutex _l( mLock ); + return stopScan(); +} + +int CTv::stopScan() +{ + if (!(mTvAction & TV_ACTION_SCANNING)) { + LOGD("%s, tv not scanning ,return\n", __FUNCTION__); + return 0; + } + + LOGD("%s, tv scanning , stop it\n", __FUNCTION__); + if ( ( SOURCE_TV == m_source_input) && mATVDisplaySnow ) { + mpTvin->Tvin_StopDecoder(); + mpTvin->SwitchSnow( false ); + if ( iSBlackPattern ) { + mAv.DisableVideoWithBlackColor(); + } else { + mAv.DisableVideoWithBlueColor(); + } + } else { + if ( iSBlackPattern ) { + mAv.DisableVideoWithBlackColor(); + } else { + mAv.DisableVideoWithBlueColor(); + } + } + mHDMIAudioCheckThread.requestAndWaitPauseCheck(); + mHDMIAudioCheckThread.setObserver(this); + //mTvEpg.leaveChannel(); + mTvScanner->stopScan(); + mFrontDev->Close(); + mTvAction &= ~TV_ACTION_SCANNING; + return 0; +} + +int CTv::pauseScan() +{ + if (!(mTvAction & TV_ACTION_SCANNING)) { + LOGD("%s, tv not scanning ,return\n", __FUNCTION__); + return 0; + } + return mTvScanner->pauseScan(); +} + +int CTv::resumeScan() +{ + if (!(mTvAction & TV_ACTION_SCANNING)) { + LOGD("%s, tv not scanning ,return\n", __FUNCTION__); + return 0; + } + return mTvScanner->resumeScan(); +} + +int CTv::getScanStatus() +{ + int status; + if (!(mTvAction & TV_ACTION_SCANNING)) { + LOGD("%s, tv not scanning ,return\n", __FUNCTION__); + return 0; + } + mTvScanner->getScanStatus(&status); + return status; +} +void CTv::operateDeviceForScan(int type) +{ + LOGD("%s : type:%d\n", __FUNCTION__, type); + if (type & OPEN_DEV_FOR_SCAN_ATV) { + mFrontDev->Open(TV_FE_ANALOG); + mFrontDev->SetAnalogFrontEndTimerSwitch(1); + }else if (type & OPEN_DEV_FOR_SCAN_DTV) { + mFrontDev->Open(TV_FE_AUTO); + mFrontDev->SetAnalogFrontEndTimerSwitch(0); + }else if (type & CLOSE_DEV_FOR_SCAN) { + mFrontDev->SetAnalogFrontEndTimerSwitch(0); + } +} +void CTv::setDvbTextCoding(char *coding) +{ +#ifdef SUPPORT_ADTV + if (!strcmp(coding, "standard")) { + AM_SI_SetDefaultDVBTextCoding(""); + } else { + AM_SI_SetDefaultDVBTextCoding(coding); + } +#endif +} + +int CTv::playDvbcProgram ( int progId ) +{ + LOGD("%s, progId = %d\n", __FUNCTION__, progId ); + + CTvProgram prog; + int ret = CTvProgram::selectByID ( progId, prog ); + if ( ret != 0 ) { + return -1; + } + + LOGD("%s, prog name = %s\n", __FUNCTION__, prog.getName().string() ); + CTvChannel channel; + prog.getChannel ( channel ); + + mFrontDev->setPara ( channel.getMode(), channel.getFrequency(), channel.getSymbolRate(), channel.getModulation() ); + + int vpid = 0x1fff, apid = 0x1fff, vfmt = -1, afmt = -1; + + CTvProgram::Video *pV = prog.getVideo(); + if ( pV != NULL ) { + vpid = pV->getPID(); + vfmt = pV->getFormat(); + } + + int aindex = prog.getCurrentAudio ( String8 ( "eng" ) ); + if ( aindex >= 0 ) { + CTvProgram::Audio *pA = prog.getAudio ( aindex ); + if ( pA != NULL ) { + apid = pA->getPID(); + afmt = pA->getFormat(); + } + } + mTvEpg.leaveProgram(); + mTvEpg.leaveChannel(); + startPlayTv ( SOURCE_DTV, vpid, apid, prog.getPcrId(), vfmt, afmt ); + + mTvEpg.enterChannel ( channel.getID() ); + mTvEpg.enterProgram ( prog.getID() ); + return 0; +} + +int CTv::getAudioTrackNum ( int progId ) +{ + int iRet, iOutCnt = 0; + CTvProgram prog; + + do { + if ( 0 > progId ) { + break; + } + + iRet = CTvProgram::selectByID ( progId, prog ); + if ( 0 != iRet ) { + break; + } + + iOutCnt = prog.getAudioTrackSize(); + } while ( false ); + + return iOutCnt; +} + +int CTv::getAudioInfoByIndex ( int progId, int idx, int *pAFmt, String8 &lang ) +{ + int iRet, iOutRet = -1; + CTvProgram prog; + CTvProgram::Audio *pA = NULL; + + do { + if ( NULL == pAFmt || idx < 0 ) { + break; + } + + iRet = CTvProgram::selectByID ( progId, prog ); + if ( 0 != iRet ) { + break; + } + + if ( idx >= prog.getAudioTrackSize() ) { + break; + } + + pA = prog.getAudio ( idx ); + if ( NULL == pA ) { + break; + } + + *pAFmt = pA->getFormat(); + lang = pA->getLang(); + } while ( false ); + + return iOutRet; +} + +int CTv::switchAudioTrack (int aPid, int aFmt, int aParam __unused) +{ + int iOutRet = 0; + do { + if ( aPid < 0 || aFmt < 0 ) { + break; + } + + iOutRet = mAv.SwitchTSAudio (( unsigned short ) aPid, aFmt ); + LOGD ("%s, iOutRet = %d AM_AV_SwitchTSAudio\n", __FUNCTION__, iOutRet ); + } while ( false ); + + return iOutRet; +} + +int CTv::switchAudioTrack ( int progId, int idx ) +{ + int iOutRet = 0; + CTvProgram prog; + CTvProgram::Audio *pAudio = NULL; + int aPid = -1; + int aFmt = -1; + + do { + if ( idx < 0 ) { + break; + } + + iOutRet = CTvProgram::selectByID ( progId, prog ); + if ( 0 != iOutRet ) { + break; + } + /*if (prog.getAudioTrackSize() <= 1) { + LOGD("%s, just one audio track, not to switch", __FUNCTION__); + break; + }*/ + if ( idx >= prog.getAudioTrackSize() ) { + break; + } + + pAudio = prog.getAudio ( idx ); + if ( NULL == pAudio ) { + break; + } + + aPid = pAudio->getPID(); + aFmt = pAudio->getFormat(); + if ( aPid < 0 || aFmt < 0 ) { + break; + } + + iOutRet = mAv.SwitchTSAudio (( unsigned short ) aPid, aFmt ); + LOGD ( "%s, iOutRet = %d AM_AV_SwitchTSAudio\n", __FUNCTION__, iOutRet ); + } while ( false ); + + return iOutRet; +} + +int CTv::ResetAudioDecoderForPCMOutput() +{ + int iOutRet = mAv.ResetAudioDecoder (); + LOGD ( "%s, iOutRet = %d AM_AV_ResetAudioDecoder\n", __FUNCTION__, iOutRet ); + return iOutRet; +} + +int CTv::setAudioAD (int enable, int aPid, int aFmt) +{ + int iOutRet = 0; + if ( aPid < 0 || aFmt < 0 ) { + return iOutRet; + } + + iOutRet = mAv.SetADAudio (enable, ( unsigned short ) aPid, aFmt ); + LOGD ("%s, iOutRet = %d (%d,%d,%d)\n", __FUNCTION__, iOutRet, enable, aPid, aFmt ); + + return iOutRet; +} + +int CTv::playDtvProgramUnlocked (const char *feparas, int mode, int freq, int para1, int para2, + int vpid, int vfmt, int apid, int afmt, int pcr, int audioCompetation) +{ + int ret = 0; + + SetSourceSwitchInputLocked(m_source_input_virtual, SOURCE_DTV); + if (mBlackoutEnable) + mAv.EnableVideoBlackout(); + else + mAv.DisableVideoBlackout(); + //mAv.ClearVideoBuffer(); + + mFrontDev->Open(TV_FE_AUTO); + if (!(mTvAction & TV_ACTION_SCANNING)) { + if (!feparas) { + if ( SOURCE_ADTV == m_source_input_virtual ) { + mFrontDev->setPara (TV_FE_ATSC, freq, para1, para2); + } else { + mFrontDev->setPara (mode, freq, para1, para2); + } + } else { + mFrontDev->setPara(feparas); + } + } + mTvAction |= TV_ACTION_PLAYING; + ret = startPlayTv ( SOURCE_DTV, vpid, apid, pcr, vfmt, afmt ); + + CMessage msg; + msg.mDelayMs = 2000; + msg.mType = CTvMsgQueue::TV_MSG_CHECK_FE_DELAY; + mTvMsgQueue.sendMsg ( msg ); + + SetCurProgramAudioVolumeCompensationVal ( audioCompetation ); + return 0; +} + +int CTv::playDtvProgram (const char *feparas, int mode, int freq, int para1, int para2, + int vpid, int vfmt, int apid, int afmt, int pcr, int audioCompetation) +{ + AutoMutex _l( mLock ); + return playDtvProgramUnlocked(feparas, mode, freq, para1, para2, + vpid, vfmt, apid, afmt, pcr, audioCompetation); +} + +int CTv::playDtvProgramUnlocked(int mode, int freq, int para1, int para2, int vpid, int vfmt, int apid, + int afmt, int pcr, int audioCompetation) { + return playDtvProgramUnlocked(NULL, mode, freq, para1, para2, vpid, vfmt, apid, afmt, pcr, audioCompetation); +} +int CTv::playDtvProgram(int mode, int freq, int para1, int para2, int vpid, int vfmt, int apid, + int afmt, int pcr, int audioCompetation) { + return playDtvProgram(NULL, mode, freq, para1, para2, vpid, vfmt, apid, afmt, pcr, audioCompetation); +} +int CTv::playDtvProgramUnlocked(const char* feparas, int vpid, int vfmt, int apid, + int afmt, int pcr, int audioCompetation) { + return playDtvProgramUnlocked(feparas, 0, 0, 0, 0, vpid, vfmt, apid, afmt, pcr, audioCompetation); +} +int CTv::playDtvProgram(const char* feparas, int vpid, int vfmt, int apid, + int afmt, int pcr, int audioCompetation) { + return playDtvProgram(feparas, 0, 0, 0, 0, vpid, vfmt, apid, afmt, pcr, audioCompetation); +} + + +int CTv::playDtvTimeShiftUnlocked (const char *feparas, void *para, int audioCompetation) +{ + int ret = 0; + + SetSourceSwitchInputLocked(m_source_input_virtual, SOURCE_DTV); + if (mBlackoutEnable) + mAv.EnableVideoBlackout(); + else + mAv.DisableVideoBlackout(); + + mAv.ClearVideoBuffer(); + + if (feparas) { + mFrontDev->Open(TV_FE_AUTO); + if (!(mTvAction & TV_ACTION_SCANNING)) { + mFrontDev->setPara(feparas); + } + } + + mTvAction |= TV_ACTION_PLAYING; + tvWriteSysfs ( DEVICE_CLASS_TSYNC_AV_THRESHOLD_MIN, AV_THRESHOLD_MIN_MS ); + ret = mAv.startTimeShift(para); + + SetCurProgramAudioVolumeCompensationVal ( audioCompetation ); + + return ret; +} + +int CTv::playDtvTimeShift (const char *feparas, void *para, int audioCompetation) +{ + AutoMutex _l( mLock ); + return playDtvTimeShiftUnlocked(feparas, para, audioCompetation); +} + +int CTv::playDtmbProgram ( int progId ) +{ + CTvProgram prog; + CTvChannel channel; + int vpid = 0x1fff, apid = 0x1fff, vfmt = -1, afmt = -1; + int aindex; + CTvProgram::Audio *pA; + CTvProgram::Video *pV; + int ret = CTvProgram::selectByID ( progId, prog ); + SetAudioMuteForTv ( CC_AUDIO_MUTE ); + saveDTVProgramID ( progId ); + prog.getChannel ( channel ); + int chanVolCompValue = 0; + chanVolCompValue = GetAudioVolumeCompensationVal(progId); + SetCurProgramAudioVolumeCompensationVal ( chanVolCompValue ); + + mFrontDev->setPara ( channel.getMode(), channel.getFrequency(), channel.getBandwidth(), 0 ); + + pV = prog.getVideo(); + if ( pV != NULL ) { + vpid = pV->getPID(); + vfmt = pV->getFormat(); + } + + aindex = prog.getCurrAudioTrackIndex(); + if ( -1 == aindex ) { //db is default + aindex = prog.getCurrentAudio ( String8 ( "eng" ) ); + if ( aindex >= 0 ) { + prog.setCurrAudioTrackIndex ( progId, aindex ); + } + } + + if ( aindex >= 0 ) { + pA = prog.getAudio ( aindex ); + if ( pA != NULL ) { + apid = pA->getPID(); + afmt = pA->getFormat(); + } + } + + mTvEpg.leaveProgram(); + mTvEpg.leaveChannel(); + startPlayTv ( SOURCE_DTV, vpid, apid, prog.getPcrId(), vfmt, afmt ); + mTvEpg.enterChannel ( channel.getID() ); + mTvEpg.enterProgram ( prog.getID() ); + return 0; +} + +int CTv::playAtvProgram (int freq, int videoStd, int audioStd, int fineTune __unused, int audioCompetation) +{ + SetSourceSwitchInputLocked(m_source_input_virtual, SOURCE_TV); + mTvAction |= TV_ACTION_PLAYING; + if ( mBlackoutEnable ) { + mAv.EnableVideoBlackout(); + } else { + mAv.DisableVideoBlackout(); + } + SetAudioMuteForTv ( CC_AUDIO_MUTE ); + //image selecting channel + mHDMIAudioCheckThread.requestAndWaitPauseCheck(); + mpTvin->Tvin_StopDecoder(); + mFrontDev->Open(TV_FE_ANALOG); + //set CVBS + int fmt = CFrontEnd::stdEnumToCvbsFmt (videoStd, audioStd); + mpTvin->AFE_SetCVBSStd ( ( tvin_sig_fmt_t ) fmt ); + + unsigned long stdAndColor = mFrontDev->enumToStdAndColor (videoStd, audioStd); + //set TUNER + mFrontDev->setPara (TV_FE_ANALOG, freq, stdAndColor, 1); + + mHDMIAudioCheckThread.setObserver(this); + mHDMIAudioCheckThread.initCheckState(); + mHDMIAudioCheckThread.resumeCheck(1000); + + SetCurProgramAudioVolumeCompensationVal ( audioCompetation ); + return 0; +} + +int CTv::resetFrontEndPara ( frontend_para_set_t feParms ) +{ + LOGD("mTvAction = %#x, %s", mTvAction, __FUNCTION__); +#ifdef SUPPORT_ADTV + if (mTvAction & TV_ACTION_SCANNING) { + return -1; + } + + if ( feParms.mode == TV_FE_ANALOG ) { + int progID = -1; + int tmpFreq = feParms.freq; + int tmpfineFreq = feParms.para2; + int mode = feParms.mode; + + //get tunerStd from videoStd and audioStd + unsigned long stdAndColor = mFrontDev->enumToStdAndColor (feParms.videoStd, feParms.audioStd); + + LOGD("%s, resetFrontEndPara- vstd=%d astd=%d stdandcolor=%lld", __FUNCTION__, feParms.videoStd, feParms.audioStd, stdAndColor); + + //set frontend parameters to tuner dev + mHDMIAudioCheckThread.requestAndWaitPauseCheck(); + mpTvin->Tvin_StopDecoder(); + + //set CVBS + int fmt = CFrontEnd::stdEnumToCvbsFmt (feParms.videoStd, feParms.audioStd ); + mpTvin->AFE_SetCVBSStd ( ( tvin_sig_fmt_t ) fmt ); + + //set TUNER + //usleep(400 * 1000); + mFrontDev->Open(TV_FE_ANALOG); + mFrontDev->setPara ( TV_FE_ANALOG, tmpFreq, stdAndColor, 1 ); + //usleep(400 * 1000); + if ( tmpfineFreq != 0 ) { + mFrontDev->fineTune ( tmpfineFreq / 1000 ); + } + + mHDMIAudioCheckThread.initCheckState(); + mHDMIAudioCheckThread.resumeCheck(); + } else { + mFrontDev->Open(feParms.mode); + mFrontDev->setPara ( feParms.mode, feParms.freq, feParms.para1, feParms.para2 ); + } +#endif + return 0; +} + +int CTv::setFrontEnd ( const char *paras, bool force ) +{ + AutoMutex _l( mLock ); + LOGD("mTvAction = %#x, %s, paras = %s", mTvAction, __FUNCTION__, paras); + if (mTvAction & TV_ACTION_SCANNING) { + return -1; + } + + CFrontEnd::FEParas fp(paras); + + if (!mATVDisplaySnow) { + if (iSBlackPattern) { + mAv.DisableVideoWithBlackColor(); + } else { + mAv.DisableVideoWithBlueColor(); + } + } + + if ( fp.getFEMode().getBase() == TV_FE_ANALOG ) { + if (SOURCE_DTV == m_source_input) { + //mAv.DisableVideoBlackout(); + stopPlaying(false); + } + int tmpFreq = fp.getFrequency(); + int tmpfineFreq = fp.getFrequency2(); + + //get tunerStd from videoStd and audioStd + unsigned long stdAndColor = mFrontDev->enumToStdAndColor (fp.getVideoStd(), fp.getAudioStd()); + + LOGD("%s: vstd=%d astd=%d stdandcolor=%lld", __FUNCTION__, fp.getVideoStd(), fp.getAudioStd(), stdAndColor); + SetAudioMuteForTv ( CC_AUDIO_MUTE); + //set frontend parameters to tuner dev + mHDMIAudioCheckThread.requestAndWaitPauseCheck(); + mpTvin->Tvin_StopDecoder(); + + //set CVBS + int fmt = CFrontEnd::stdEnumToCvbsFmt (fp.getVideoStd(), fp.getAudioStd() ); + mpTvin->AFE_SetCVBSStd ( ( tvin_sig_fmt_t ) fmt ); + + //set TUNER + //usleep(400 * 1000); + mFrontDev->Open(TV_FE_AUTO); + mFrontDev->setPara ( paras, force ); + //usleep(400 * 1000); + if ( tmpfineFreq != 0 ) { + mFrontDev->fineTune ( tmpfineFreq / 1000, force ); + } + + mHDMIAudioCheckThread.initCheckState(); + mHDMIAudioCheckThread.resumeCheck(); + } else { + if (SOURCE_ADTV == m_source_input_virtual) { + if (SOURCE_TV == m_source_input) { + //mAv.DisableVideoBlackout(); + mHDMIAudioCheckThread.requestAndWaitPauseCheck(); + mpTvin->Tvin_StopDecoder(); + if ( (SOURCE_TV == m_source_input) && mATVDisplaySnow ) { + mpTvin->SwitchSnow( false ); + } + } + } + mFrontDev->Open(TV_FE_AUTO); + mFrontDev->setPara ( paras, force ); + } + + int mode, freq, para1, para2; + mFrontDev->getPara(&mode, &freq, ¶1, ¶2); + Tv_RrtUpdate(freq, mode, 0); + Tv_Easupdate(); + return 0; +} + +int CTv::resetDmxAndAvSource() +{ +#ifdef SUPPORT_ADTV + AM_DMX_Source_t curdmxSource; + mFrontDev->GetTSSource ( &curdmxSource ); + LOGD ( "%s, AM_FEND_GetTSSource %d", __FUNCTION__, curdmxSource ); + mTvDmx.Close(); + AM_DMX_OpenPara_t para; + memset ( ¶, 0, sizeof ( para ) ); + mTvDmx.Open (para); + mTvDmx.SetSource(curdmxSource ); + mTvDmx1.Open(para); + mTvDmx1.SetSource(curdmxSource); + mTvDmx2.Open(para); + mTvDmx2.SetSource(curdmxSource); + int ts_source = ( int ) curdmxSource; + mAv.SetTSSource (ts_source ); +#endif + return 0; +} + +int CTv::SetCurProgramAudioVolumeCompensationVal ( int tmpVal ) +{ + SetAudioVolumeCompensationVal ( tmpVal ); + SetAudioMasterVolume (GetAudioMasterVolume() ); + + LOGD ( "%s, VolumeCompensationVal = %d, id = -1\n", __FUNCTION__, tmpVal ); + CTvProgram prog; + if ( CTvProgram::selectByID ( -1, prog ) != 0 ) { + LOGE ( "[ctv]%s, atv progID is not matching the db's ret = 0\n", __FUNCTION__ ); + return -1; + } + + if (prog.updateVolComp ( -1, tmpVal ) != 0 ) { + LOGE ( "[ctv]%s, atv progID is not matching the db's\n", __FUNCTION__); + return -1; + } + return 0; +} + +int CTv::GetAudioVolumeCompensationVal(int progxxId __unused) +{ + int tmpVolValue = 0; + CTvProgram prog; + if ( CTvProgram::selectByID ( -1, prog ) != 0 ) { + LOGE ( "%s, atv progID is not matching the db's ret = 0\n", __FUNCTION__ ); + return tmpVolValue; + } + tmpVolValue = prog.getChanVolume (); + LOGD ( "%s,progid = -1 CompensationVal = %d\n", __FUNCTION__, tmpVolValue ); + if (tmpVolValue > 20 || tmpVolValue < -20) tmpVolValue = 0; + return tmpVolValue; +} + +int CTv::startPlayTv ( int source, int vid, int aid, int pcrid, int vfat, int afat ) +{ + if ( source == SOURCE_DTV ) { + tvWriteSysfs ( DEVICE_CLASS_TSYNC_AV_THRESHOLD_MIN, AV_THRESHOLD_MIN_MS ); + setDvbLogLevel(); + LOGD ( "%s, startPlayTv", __FUNCTION__); + return mAv.StartTS (vid, aid, pcrid, vfat, afat ); + } + return -1; +} + +int CTv::stopPlayingLock() +{ + AutoMutex _l( mLock ); + if (mSubtitle.sub_switch_status() == 1) + mSubtitle.sub_stop_dvb_sub(); + return stopPlaying(true); +} + +int CTv::stopPlaying(bool isShowTestScreen) { + return stopPlaying(isShowTestScreen, true); +} + +int CTv::stopPlaying(bool isShowTestScreen, bool resetFE) +{ + if (!(mTvAction & TV_ACTION_PLAYING)) { + LOGD("%s, stopplay cur action = %x not playing , return", __FUNCTION__, mTvAction); + return 0; + } + + LOGD("%s, isShowTestScreen = %d, resetFE = %d", __FUNCTION__, isShowTestScreen, resetFE); + + if (m_source_input == SOURCE_TV) { + //first mute + SetAudioMuteForTv(CC_AUDIO_MUTE); + if (resetFE) + ClearAnalogFrontEnd(); + } else if (m_source_input == SOURCE_DTV) { + mHDMIAudioCheckThread.requestAndWaitPauseCheck(); + if (mBlackoutEnable == true) { + mAv.EnableVideoBlackout(); + } + mAv.StopTS (); + } + if ( SOURCE_TV != m_source_input && mBlackoutEnable == true) { + if ( true == isShowTestScreen ) { + if ( iSBlackPattern ) { + mAv.DisableVideoWithBlackColor(); + } else { + mAv.DisableVideoWithBlueColor(); + } + } + } + mTvAction &= ~TV_ACTION_PLAYING; + return 0; +} + +int CTv::getAudioChannel() +{ + int iRet = -1; + int audioChanneleMod; + do { + iRet = mAv.AudioGetOutputMode (&audioChanneleMod ); + if ( DVB_SUCCESS != iRet ) { + LOGD ( "%s, audio GetOutputMode is FAILED %d\n", __FUNCTION__, iRet ); + break; + } + LOGD ( "%s, jianfei.lan getAudioChannel iRet : %d audioChanneleMod %d\n", __FUNCTION__, iRet, audioChanneleMod ); + } while ( 0 ); + return audioChanneleMod; +} + +int CTv::setAudioChannel ( int channelIdx ) +{ + int iOutRet = 0; + int audioChanneleMod; + LOGD ( "%s, channelIdx : %d\n", __FUNCTION__, channelIdx ); + audioChanneleMod = ( int ) channelIdx; + iOutRet = mAv.AudioSetOutputMode (audioChanneleMod ); + int aud_ch = 1; + if (audioChanneleMod == TV_AOUT_OUTPUT_STEREO) { + aud_ch = 1; + } else if (audioChanneleMod == TV_AOUT_OUTPUT_DUAL_LEFT) { + aud_ch = 2; + } else if (audioChanneleMod == TV_AOUT_OUTPUT_DUAL_RIGHT) { + aud_ch = 3; + } + CTvProgram::updateAudioChannel(-1, aud_ch); + if ( DVB_SUCCESS != iOutRet) { + LOGD ( "%s, TV AM_AOUT_SetOutputMode device is FAILED %d\n", __FUNCTION__, iOutRet ); + } + return 0; +} + +int CTv::getFrontendSignalStrength() +{ + return mFrontDev->getStrength(); +} + +int CTv::getFrontendSNR() +{ + return mFrontDev->getSNR(); +} + +int CTv::getFrontendBER() +{ + return mFrontDev->getBER(); +} + +int CTv::getChannelInfoBydbID ( int dbID, channel_info_t &chan_info ) +{ + CTvProgram prog; + CTvChannel channel; + Vector<sp<CTvProgram> > out; + memset ( &chan_info, sizeof ( chan_info ), 0 ); + chan_info.freq = 44250000; + chan_info.uInfo.atvChanInfo.videoStd = CC_ATV_VIDEO_STD_PAL; + chan_info.uInfo.atvChanInfo.audioStd = CC_ATV_AUDIO_STD_DK; + static const int CVBS_ID = -1; + if (dbID == CVBS_ID) { + unsigned char std; + SSMReadCVBSStd(&std); + chan_info.uInfo.atvChanInfo.videoStd = (atv_video_std_t)std; + chan_info.uInfo.atvChanInfo.audioStd = CC_ATV_AUDIO_STD_DK; + chan_info.uInfo.atvChanInfo.isAutoStd = (std == CC_ATV_VIDEO_STD_AUTO) ? 1 : 0; + return 0; + } + + int ret = CTvProgram::selectByID ( dbID, prog ); + if ( ret != 0 ) { + LOGD ( "getChannelinfo , select dbid=%d,is not exist", dbID); + return -1; + } + prog.getChannel ( channel ); + + if ( CTvProgram::TYPE_ATV == prog.getProgType() ) { + chan_info.freq = channel.getFrequency(); + chan_info.uInfo.atvChanInfo.finefreq = channel.getAfcData(); + LOGD("%s, get channel std = %d", __FUNCTION__, channel.getStd()); + chan_info.uInfo.atvChanInfo.videoStd = + ( atv_video_std_t ) CFrontEnd::stdAndColorToVideoEnum ( channel.getStd() ); + chan_info.uInfo.atvChanInfo.audioStd = + ( atv_audio_std_t ) CFrontEnd::stdAndColorToAudioEnum ( channel.getStd() ); + chan_info.uInfo.atvChanInfo.isAutoStd = ((channel.getStd() & V4L2_COLOR_STD_AUTO) == V4L2_COLOR_STD_AUTO) ? 1 : 0; + } else if ( CTvProgram::TYPE_DTV == prog.getProgType() || CTvProgram::TYPE_RADIO == prog.getProgType()) { + chan_info.freq = channel.getFrequency(); + chan_info.uInfo.dtvChanInfo.strength = getFrontendSignalStrength(); + chan_info.uInfo.dtvChanInfo.quality = getFrontendSNR(); + chan_info.uInfo.dtvChanInfo.ber = getFrontendBER(); + } + + return 0; +} + +bool CTv::Tv_Start_Analyze_Ts ( int channelID ) +{ + int freq, ret; + CTvChannel channel; + + AutoMutex _l( mLock ); + mAv.StopTS (); + mAv.DisableVideoWithBlueColor(); + ret = CTvChannel::selectByID ( channelID, channel ); + if ( ret != 0 ) { + LOGD ( "%s, CTv tv_updatats can not get freq by channel ID", __FUNCTION__ ); + return false; + } + + mTvAction |= TV_ACTION_SCANNING; + freq = channel.getFrequency(); + LOGD ( "%s, the freq = %d", __FUNCTION__, freq ); + mDtvScanRunningStatus = DTV_SCAN_RUNNING_ANALYZE_CHANNEL; + mTvScanner->setObserver ( &mTvMsgQueue ); + mTvScanner->manualDtmbScan ( freq, freq ); //dtmb + return true; +} + +bool CTv::Tv_Stop_Analyze_Ts() +{ + stopScanLock(); + return true; +} + +int CTv::saveATVProgramID ( int dbID ) +{ + config_set_int ( CFG_SECTION_TV, "atv.get.program.id", dbID ); + return 0; +} + +int CTv::getATVProgramID ( void ) +{ + return config_get_int ( CFG_SECTION_TV, "atv.get.program.id", -1 ); +} + +int CTv::saveDTVProgramID ( int dbID ) +{ + config_set_int ( CFG_SECTION_TV, "dtv.get.program.id", dbID ); + return 0; +} + +int CTv::getDTVProgramID ( void ) +{ + return config_get_int ( CFG_SECTION_TV, "dtv.get.program.id", -1 ); +} + +int CTv::saveRadioProgramID ( int dbID ) +{ + config_set_int ( CFG_SECTION_TV, "radio.get.program.id", dbID ); + return 0; +} + +int CTv::getRadioProgramID ( void ) +{ + return config_get_int ( CFG_SECTION_TV, "radio.get.program.id", -1 ); +} + + +int CTv::getATVMinMaxFreq ( int *scanMinFreq, int *scanMaxFreq ) +{ + const char *strDelimit = ","; + char *token = NULL; + + *scanMinFreq = 44250000; + *scanMaxFreq = 868250000; + + const char *freqList = config_get_str ( CFG_SECTION_ATV, CFG_ATV_FREQ_LIST, "null" ); + if ( strcmp ( freqList, "null" ) == 0 ) { + LOGE( "[ctv]%s, atv freq list is null \n", __FUNCTION__ ); + return -1; + } + + char data_str[512] = {0}; + strncpy ( data_str, freqList, sizeof ( data_str ) - 1 ); + + char *pSave; + token = strtok_r ( data_str, strDelimit, &pSave); + sscanf ( token, "%d", scanMinFreq ); + token = strtok_r ( NULL, strDelimit , &pSave); + if ( token != NULL ) { + sscanf ( token, "%d", scanMaxFreq ); + } + return 0; +} + +int CTv::IsDVISignal() +{ + return ( ( TVIN_SIG_FMT_NULL != m_cur_sig_info.fmt) && + ( m_cur_sig_info.reserved & 0x1 ) ); +} + +int CTv::getHDMIFrameRate() +{ + int ConstRate[5] = {24, 25, 30, 50, 60}; + float ConstRateDiffHz[5] = {0.5, 0.5, 0.5, 2, 2}; + int fps = m_cur_sig_info.fps; + for (int i = 0; i < 5; i++) { + if (abs(ConstRate[i] - fps) < ConstRateDiffHz[i]) + fps = ConstRate[i]; + } + return fps; +} + +tv_source_input_t CTv::GetLastSourceInput ( void ) +{ + return m_last_source_input; +} + +int CTv::isVgaFmtInHdmi ( void ) +{ + if ( CTvin::Tvin_SourceInputToSourceInputType(m_source_input) != SOURCE_TYPE_HDMI ) { + return -1; + } + return CTvin::isVgaFmtInHdmi (m_cur_sig_info.fmt); +} + +void CTv::print_version_info ( void ) +{ + // print tvapi version info + LOGD ( "libtvservice git branch:%s\n", tvservice_get_git_branch_info() ); + LOGD ( "libtvservice git version:%s\n", tvservice_get_git_version_info() ); + LOGD ( "libtvservice Last Changed:%s\n", tvservice_get_last_chaned_time_info() ); + LOGD ( "libtvservice Last Build:%s\n", tvservice_get_build_time_info() ); + LOGD ( "libtvservice Builer Name:%s\n", tvservice_get_build_name_info() ); + LOGD ( "libtvservice board version:%s\n", tvservice_get_board_version_info() ); + LOGD ( "\n\n"); +#ifdef SUPPORT_ADTV + // print dvb version info + LOGD ( "libdvb git branch:%s\n", dvb_get_git_branch_info() ); + LOGD ( "libdvb git version:%s\n", dvb_get_git_version_info() ); + LOGD ( "libdvb Last Changed:%s\n", dvb_get_last_chaned_time_info() ); + LOGD ( "libdvb Last Build:%s\n", dvb_get_build_time_info() ); + LOGD ( "libdvb Builer Name:%s\n", dvb_get_build_name_info() ); +#endif +} + +int CTv::Tvin_GetTvinConfig ( void ) +{ + const char *config_value; + + config_value = config_get_str ( CFG_SECTION_TV, CFG_TVIN_KERNELPET_DISABLE, "null" ); + if ( strcmp ( config_value, "disable" ) == 0 ) { + gTvinConfig.kernelpet_disable = true; + } else { + gTvinConfig.kernelpet_disable = false; + } + + config_value = config_get_str ( CFG_SECTION_TV, CFG_TVIN_KERNELPET_TIMEROUT, "null" ); + gTvinConfig.userpet_timeout = ( unsigned int ) strtol ( config_value, NULL, 10 ); + + if ( gTvinConfig.kernelpet_timeout <= 0 || gTvinConfig.kernelpet_timeout > 40 ) { + gTvinConfig.kernelpet_timeout = 10; + } + + config_value = config_get_str ( CFG_SECTION_TV, CFG_TVIN_USERPET, "null" ); + if ( strcmp ( config_value, "enable" ) == 0 ) { + gTvinConfig.userpet = true; + } else { + gTvinConfig.userpet = false; + } + + config_value = config_get_str ( CFG_SECTION_TV, CFG_TVIN_USERPET_TIMEROUT, "null" ); + gTvinConfig.userpet_timeout = ( unsigned int ) strtol ( config_value, NULL, 10 ); + + if ( gTvinConfig.userpet_timeout <= 0 || gTvinConfig.userpet_timeout > 100 ) { + gTvinConfig.userpet_timeout = 10; + } + + config_value = config_get_str ( CFG_SECTION_TV, CFG_TVIN_USERPET_RESET, "null" ); + if ( strcmp ( config_value, "disable" ) == 0 ) { + gTvinConfig.userpet_reset = 0; + } else { + gTvinConfig.userpet_reset = 1; + } + return 0; +} + +TvRunStatus_t CTv::GetTvStatus() +{ + AutoMutex _l( mLock ); + return mTvStatus; +} + +int CTv::OpenTv ( void ) +{ + const char * value; + value = config_get_str ( CFG_SECTION_TV, CFG_TVIN_ATV_DISPLAY_SNOW, "null" ); + if (strcmp(value, "enable") == 0 ) { + mATVDisplaySnow = true; + } else { + mATVDisplaySnow = false; + } + + value = config_get_str ( CFG_SECTION_TV, CFG_BLUE_SCREEN_COLOR, "null" ); + if ( strcmp ( value, "black" ) == 0 ) { + iSBlackPattern = true; + } else { + iSBlackPattern = false; + } + + value = config_get_str ( CFG_SECTION_TV, CFG_FBC_PANEL_INFO, "null" ); + LOGD("open tv, get fbc panel info:%s\n", value); + if (strcmp(value, "edid") == 0 ) { + rebootSystemByEdidInfo(); + } else if (strcmp(value, "uart") == 0 ) { + rebootSystemByUartPanelInfo(fbcIns); + } + + mpTvin->Tvin_LoadSourceInputToPortMap(); + + //tv ssm check + SSMHandlePreCopying(); + + SSM_status_t SSM_status = (SSM_status_t)(CVpp::getInstance()->VPP_GetSSMStatus()); + LOGD ("Ctv-SSM status= %d\n", SSM_status); + + if ( SSMDeviceMarkCheck() < 0 || SSM_status == SSM_HEADER_INVALID) { + LOGD ("Restore SSMData file"); + Tv_SSMRestoreDefaultSetting(); + }else if (SSM_status == SSM_HEADER_STRUCT_CHANGE) { + CVpp::getInstance()->TV_SSMRecovery(); + } + + mpTvin->OpenTvin(); + mpTvin->Tv_init_afe(); + + CVpp::getInstance()->Vpp_Init(mHdmiOutFbc); + TvAudioOpen(); + SetAudioVolDigitLUTTable(SOURCE_MPEG); + + SSMSetHDCPKey(); + system ( "/vendor/bin/dec" ); + + value = config_get_str ( CFG_SECTION_TV, CFG_TVIN_DISPLAY_FREQ_AUTO, "null" ); + if ( strcmp ( value, "enable" ) == 0 ) { + mAutoSetDisplayFreq = true; + } else { + mAutoSetDisplayFreq = false; + } + + mHDMIRxManager.SetHdmiPortCecPhysicAddr(); + Tv_HandeHDMIEDIDFilePathConfig(); + SSMSetHDMIEdid(1); + mHDMIRxManager.HdmiRxEdidUpdate(); + + Tvin_GetTvinConfig(); + m_last_source_input = SOURCE_INVALID; + m_source_input = SOURCE_INVALID; + m_hdmi_sampling_rate = 0; + + int8_t enable; + SSMReadBlackoutEnable(&enable); + mBlackoutEnable = ((enable==1)?true:false); + + mFrontDev->Open(TV_FE_AUTO); + mFrontDev->autoLoadFE(); + mAv.Open(); + resetDmxAndAvSource(); + //mDevicesPollStatusDetectThread.startDetect(); + //ClearAnalogFrontEnd(); + InitCurrenSignalInfo(); + + mTvStatus = TV_OPEN_ED; + return 0; +} + +int CTv::CloseTv ( void ) +{ + mHDMIAudioCheckThread.stopCheck(); + mpTvin->Tv_uninit_afe(); + mpTvin->uninit_vdin(); + TvMisc_DisableWDT ( gTvinConfig.userpet ); + mTvStatus = TV_CLOSE_ED; + return 0; +} + +int CTv::StartTvLock () +{ + LOGD ( "[source_switch_time]: %fs, StartTvLock status = %d", getUptimeSeconds(), mTvStatus); + if (mTvStatus == TV_START_ED) + return 0; + + AutoMutex _l( mLock ); + //tvWriteSysfs("/sys/power/wake_lock", "tvserver.run"); + + setDvbLogLevel(); + //mAv.ClearVideoBuffer(); + mAv.SetVideoLayerDisable(1); + SwitchAVOutBypass(0); + InitSetTvAudioCard(); + SetAudioMuteForTv(CC_AUDIO_MUTE); + mHDMIAudioCheckThread.startCheck(); + mTvMsgQueue.startMsgQueue(); + SetDisplayMode ( CVpp::getInstance()->GetDisplayMode ( m_source_input ), m_source_input, m_cur_sig_info.fmt); + TvMisc_EnableWDT ( gTvinConfig.kernelpet_disable, gTvinConfig.userpet, gTvinConfig.kernelpet_timeout, gTvinConfig.userpet_timeout, gTvinConfig.userpet_reset ); + mpTvin->TvinApi_SetCompPhaseEnable ( 1 ); + mpTvin->VDIN_EnableRDMA ( 1 ); + + mAv.SetVideoWindow (0, 0, 0, 0); + mTvStatus = TV_START_ED; + LOGD ( "[source_switch_time]: %fs, StartTvLock end", getUptimeSeconds()); + MnoNeedAutoSwitchToMonitorMode = false; + return 0; +} + +int CTv::startTvDetect() +{ + mDevicesPollStatusDetectThread.startDetect(); + return 0; +} + +int CTv::DoSuspend(int type) +{ + return 0; +} + +int CTv::DoResume(int type) +{ + return 0; +} + +int CTv::StopTvLock ( void ) +{ + LOGD("%s, call Tv_Stop status = %d \n", __FUNCTION__, mTvStatus); + mHDMIAudioCheckThread.requestAndWaitPauseCheck(); + AutoMutex _l( mLock ); + mTvAction |= TV_ACTION_STOPING; + mAv.DisableVideoWithBlackColor(); + tryReleasePlayer(false, m_source_input); + stopPlaying(false); + mpTvin->Tvin_StopDecoder(); + if ( (SOURCE_TV == m_source_input) && mATVDisplaySnow ) { + mpTvin->SwitchSnow( false ); + } + mpTvin->VDIN_ClosePort(); + mTvAction &= ~TV_ACTION_IN_VDIN; + //stop scan if scanning + stopScan(); + mFrontDev->SetAnalogFrontEndTimerSwitch(0); + // + setAudioChannel(TV_AOUT_OUTPUT_STEREO); + mpTvin->setMpeg2Vdin(0); + mAv.setLookupPtsForDtmb(0); + SwitchAVOutBypass(0); + tv_audio_channel_e audio_channel = mpTvin->Tvin_GetInputSourceAudioChannelIndex (SOURCE_MPEG); + AudioLineInSelectChannel( audio_channel ); + AudioCtlUninit(); + SetAudioVolDigitLUTTable(SOURCE_MPEG); + Tv_SetAudioInSource(SOURCE_MPEG); + SetDisplayMode ( CVpp::getInstance()->GetDisplayMode ( SOURCE_MPEG ), SOURCE_MPEG, m_cur_sig_info.fmt); + RefreshAudioMasterVolume ( SOURCE_MPEG ); + m_last_source_input = SOURCE_INVALID; + m_source_input = SOURCE_INVALID; + m_source_input_virtual = SOURCE_INVALID; + + tv_source_input_type_t source_type = mpTvin->Tvin_SourceInputToSourceInputType(m_source_input); + tvin_port_t source_port = mpTvin->Tvin_GetSourcePortBySourceType(source_type); + int ret = tvSetCurrentSourceInfo(m_source_input, source_type, source_port, TVIN_SIG_FMT_NULL, INDEX_2D, TVIN_TFMT_2D); + if (ret < 0) { + LOGE("%s Set CurrentSourceInfo error!\n"); + } + + mFrontDev->Close(); + mTvAction &= ~TV_ACTION_STOPING; + mTvStatus = TV_STOP_ED; + MnoNeedAutoSwitchToMonitorMode = false; + if ( Get2d4gHeadsetEnable() == 1 ) { + property_set("audio.tv_open.flg", "0"); + } + if (mBlackoutEnable) { + mAv.DisableVideoWithBlackColor(); + mAv.EnableVideoBlackout(); + } + mAv.ClearVideoBuffer(); + SetAudioMuteForTv ( CC_AUDIO_UNMUTE ); + return 0; +} + +int CTv::Tv_MiscSetBySource ( tv_source_input_t source_input ) +{ + int ret = -1; + + switch ( source_input ) { + case SOURCE_TV: + CVpp::getInstance()->VPP_SetScalerPathSel(1); + ret = tvWriteSysfs ( SYS_VECM_DNLP_ADJ_LEVEL, "4" ); + break; + + case SOURCE_HDMI1: + case SOURCE_HDMI2: + case SOURCE_HDMI3: + case SOURCE_HDMI4: + CVpp::getInstance()->VPP_SetScalerPathSel(0); + //ret = CVpp::getInstance()->Tv_SavePanoramaMode ( VPP_PANORAMA_MODE_FULL, SOURCE_TYPE_HDMI ); + ret |= tvWriteSysfs ( SYS_VECM_DNLP_ADJ_LEVEL, "5" ); + break; + + case SOURCE_DTV: + CVpp::getInstance()->VPP_SetScalerPathSel(0); + + case SOURCE_AV1: + case SOURCE_AV2: + case SOURCE_VGA: + CVpp::getInstance()->VPP_SetScalerPathSel(1); + ret |= tvWriteSysfs ( SYS_VECM_DNLP_ADJ_LEVEL, "5" ); + break; + + case SOURCE_SVIDEO: + case SOURCE_IPTV: + CVpp::getInstance()->VPP_SetScalerPathSel(1); + default: + CVpp::getInstance()->VPP_SetScalerPathSel(0); + ret |= tvWriteSysfs ( SYS_VECM_DNLP_ADJ_LEVEL, "5" ); + break; + } + return ret; +} + +bool CTv::isVirtualSourceInput(tv_source_input_t source_input) { + switch (source_input) { + case SOURCE_ADTV: + return true; + default: + return false; + } + return false; +} + +int CTv::tryReleasePlayer(bool isEnter, tv_source_input_t si) +{ + if ((isEnter && si != SOURCE_ADTV && si != SOURCE_TV && si != SOURCE_DTV) + ||(!isEnter && (si == SOURCE_ADTV || si == SOURCE_TV || si == SOURCE_DTV))){ + LOGD("remove all Player & Recorder"); + PlayerManager::getInstance().releaseAll(); + RecorderManager::getInstance().releaseAll(); + } + return 0; +} + +int CTv::SetSourceSwitchInput(tv_source_input_t source_input) +{ + AutoMutex _l( mLock ); + + LOGD ( "%s, source input = %d", __FUNCTION__, source_input ); + + tryReleasePlayer(true, source_input); + + m_source_input_virtual = source_input; + + if (isVirtualSourceInput(source_input)) + return 0;//defer real source setting. + + return SetSourceSwitchInputLocked(m_source_input_virtual, source_input); +} + +int CTv::SetSourceSwitchInput(tv_source_input_t virtual_input, tv_source_input_t source_input) { + AutoMutex _l( mLock ); + return SetSourceSwitchInputLocked(virtual_input, source_input); +} + +int CTv::SetSourceSwitchInputLocked(tv_source_input_t virtual_input, tv_source_input_t source_input) +{ + tvin_port_t cur_port; + + LOGD ( "[source_switch_time]: %fs, %s, virtual source input = %d source input = %d m_source_input = %d", + getUptimeSeconds(), __FUNCTION__, virtual_input, source_input, m_source_input ); + + m_source_input_virtual = virtual_input; + + Tv_SetDDDRCMode(source_input); + if (source_input == m_source_input ) { + LOGW ( "[ctv]%s,same source input, return", __FUNCTION__ ); + return 0; + } + stopPlaying(false, !(source_input == SOURCE_DTV && m_source_input == SOURCE_TV)); + KillMediaServerClient(); + //if HDMI, need to set EDID of each port + if (mSetHdmiEdid) { + int tmp_ret = 0; + switch ( source_input ) { + case SOURCE_HDMI1: + tmp_ret = SSMSetHDMIEdid(1); + break; + case SOURCE_HDMI2: + tmp_ret = SSMSetHDMIEdid(2); + break; + case SOURCE_HDMI3: + tmp_ret = SSMSetHDMIEdid(3); + break; + case SOURCE_HDMI4: + tmp_ret = SSMSetHDMIEdid(4); + break; + default: + tmp_ret = -1; + break; + } + if (tmp_ret < 0) + LOGE ( "[ctv]%s, do not set hdmi port%d edid.ret=%d", __FUNCTION__, source_input - 4, tmp_ret ); + } + mTvAction |= TV_ACTION_SOURCE_SWITCHING; + + SetAudioMuteForTv(CC_AUDIO_MUTE); + mHDMIAudioCheckThread.requestAndWaitPauseCheck(); + //if BlackoutEnable is false, no need to disable video and enable blackout + + if (mBlackoutEnable == true) { + mAv.DisableVideoWithBlackColor(); + //enable blackout, when play,disable it + mAv.EnableVideoBlackout(); + } + //set front dev mode + if ( source_input == SOURCE_TV ) { + mFrontDev->Open(TV_FE_ANALOG); + mFrontDev->SetAnalogFrontEndTimerSwitch(1); + } else if ( source_input == SOURCE_DTV ) { + mFrontDev->Open(TV_FE_AUTO); + mFrontDev->SetAnalogFrontEndTimerSwitch(0); + } else { + mFrontDev->Close(); + mFrontDev->SetAnalogFrontEndTimerSwitch(0); + } + + //ok + m_last_source_input = m_source_input; + m_source_input = source_input; + SSMSaveSourceInput ( source_input ); + + SetAudioVolumeCompensationVal ( 0 ); + + if ( source_input == SOURCE_DTV ) { + resetDmxAndAvSource(); + + //we should stop audio first for audio mute. + SwitchAVOutBypass(0); + tv_audio_channel_e audio_channel = mpTvin->Tvin_GetInputSourceAudioChannelIndex (SOURCE_MPEG); + AudioLineInSelectChannel( audio_channel ); + AudioCtlUninit(); + SetAudioVolDigitLUTTable(SOURCE_MPEG); + // + mpTvin->Tvin_StopDecoder(); + mpTvin->VDIN_ClosePort(); + mpTvin->Tvin_WaitPathInactive ( TV_PATH_TYPE_DEFAULT ); + + //double confirm we set the main volume lut buffer to mpeg + RefreshAudioMasterVolume ( SOURCE_MPEG ); + RefreshSrsEffectAndDacGain(); + SetCustomEQGain(); + LoadAudioVirtualizer(); + mpTvin->setMpeg2Vdin(1); + mAv.setLookupPtsForDtmb(1); + tv_source_input_type_t source_type = mpTvin->Tvin_SourceInputToSourceInputType(m_source_input); + tvin_port_t source_port = mpTvin->Tvin_GetSourcePortBySourceType(source_type); + int ret = tvSetCurrentSourceInfo(m_source_input, source_type, source_port, TVIN_SIG_FMT_HDMI_1920X1080P_60HZ, + INDEX_2D, TVIN_TFMT_2D); + if (ret < 0) { + LOGE("%s Set CurrentSourceInfo error!\n"); + } + + CVpp::getInstance()->LoadVppSettings(SOURCE_DTV, TVIN_SIG_FMT_HDMI_1920X1080P_60HZ, INDEX_2D, TVIN_TFMT_2D); + + Tv_SetAudioInSource ( source_input ); + } else { + mpTvin->setMpeg2Vdin(0); + mAv.setLookupPtsForDtmb(0); + } + + cur_port = mpTvin->Tvin_GetSourcePortBySourceInput ( source_input ); + Tv_MiscSetBySource ( source_input ); + + if (source_input != SOURCE_DTV) { + // Uninit data + UnInitTvAudio(); + if (source_input == SOURCE_HDMI1 || source_input == SOURCE_HDMI2 || source_input == SOURCE_HDMI3 || + source_input == SOURCE_HDMI4 || source_input == SOURCE_MPEG || source_input == SOURCE_DTV) { + SwitchAVOutBypass(0); + } else { + SwitchAVOutBypass(1); + } + + tv_audio_channel_e audio_channel = mpTvin->Tvin_GetInputSourceAudioChannelIndex (source_input); + AudioLineInSelectChannel( audio_channel ); + + Tv_SetAudioInSource ( source_input ); + if ( source_input == SOURCE_HDMI1 || source_input == SOURCE_HDMI2 || source_input == SOURCE_HDMI3 + || source_input == SOURCE_HDMI4) { + m_hdmi_sampling_rate = 0; + m_hdmi_audio_data = 0; + } else if (source_input == SOURCE_SPDIF) { + InitTvAudio(48000, CC_IN_USE_SPDIF_DEVICE); + HanldeAudioInputSr(48000); + } + + if (mpTvin->SwitchPort ( cur_port ) == 0) { //ok + if (source_input != SOURCE_SPDIF) + { + unsigned char std; + SSMReadCVBSStd(&std); + int fmt = CFrontEnd::stdEnumToCvbsFmt (std, CC_ATV_AUDIO_STD_AUTO); + mpTvin->AFE_SetCVBSStd ( ( tvin_sig_fmt_t ) fmt ); + + //for HDMI source connect detect + mpTvin->VDIN_OpenHDMIPinMuxOn(true); + CVpp::getInstance()->Vpp_ResetLastVppSettingsSourceType(); + } + m_sig_spdif_nums = 0; + mHDMIAudioCheckThread.setObserver(this); + mHDMIAudioCheckThread.initCheckState(); + + if (source_input != SOURCE_SPDIF) { + mHDMIAudioCheckThread.setHDMIAudioCheckEnable(true); + } else { + mHDMIAudioCheckThread.setHDMIAudioCheckEnable(false); + } + mHDMIAudioCheckThread.resumeCheck(0); + } + } + + Tv_SetAudioSourceType(source_input); + RefreshAudioMasterVolume(source_input); + Tv_SetAudioOutputSwap_Type(source_input); + Tv_SetAVOutPut_Input_gain(source_input); + + mTvAction &= ~ TV_ACTION_SOURCE_SWITCHING; + mTvAction |= TV_ACTION_IN_VDIN; + return 0; +} + +void CTv::onSigToStable() +{ + LOGD ( "[source_switch_time]: %fs, onSigToStable start", getUptimeSeconds()); + + tv_source_input_type_t source_type = mpTvin->Tvin_SourceInputToSourceInputType(m_source_input); + tvin_port_t source_port = mpTvin->Tvin_GetSourcePortBySourceType(source_type); + int ret = tvSetCurrentSourceInfo(m_source_input, source_type, source_port, m_cur_sig_info.fmt, + INDEX_2D, m_cur_sig_info.trans_fmt); + if (ret < 0) { + LOGE("%s Set CurrentSourceInfo error!\n"); + } + + if (SOURCE_TV <= m_source_input && m_source_input <= SOURCE_AV2) { + InitTvAudio(48000, CC_IN_USE_I2S_DEVICE); + HanldeAudioInputSr(-1); + } + + CVpp::getInstance()->LoadVppSettings(m_source_input, m_cur_sig_info.fmt, INDEX_2D, + m_cur_sig_info.trans_fmt); + + + if (mAutoSetDisplayFreq && !mPreviewEnabled) { + int freq = 60; + if (CTvin::Tvin_SourceInputToSourceInputType(m_source_input) == SOURCE_TYPE_HDMI ) { + int fps = getHDMIFrameRate(); + LOGD("onSigToStable HDMI fps = %d", fps); + if ((30 == fps) || (60 == fps)) { + freq = 60; + } else { + freq = 50; + } + + if (CVpp::getInstance()->Vpp_GetAutoSwitchPCModeFlag() == 1) { + MnoNeedAutoSwitchToMonitorMode = false; + } else { + MnoNeedAutoSwitchToMonitorMode = true; + } + autoSwitchToMonitorMode(); + + } else if ( CTvin::Tvin_is50HzFrameRateFmt ( m_cur_sig_info.fmt ) ) { + freq = 50; + } + + mpTvin->VDIN_SetDisplayVFreq ( freq, mHdmiOutFbc ); + LOGD ( "%s, SetDisplayVFreq %dHZ.", __FUNCTION__, freq); + } + //showbo mark hdmi auto 3d, tran fmt is 3d, so switch to 3d + + if ( m_win_mode == PREVIEW_WONDOW ) { + mAv.setVideoAxis(m_win_pos.x1, m_win_pos.y1, m_win_pos.x2, m_win_pos.y2); + mAv.setVideoScreenMode ( CAv::VIDEO_WIDEOPTION_FULL_STRETCH ); + } else { + SetDisplayMode ( CVpp::getInstance()->GetDisplayMode ( m_source_input ), m_source_input, m_cur_sig_info.fmt); + } + LOGD ( "[source_switch_time]: %fs, onSigToStable end", getUptimeSeconds()); +} + +void CTv::onSigStillStable() +{ + if ( !(mTvAction & TV_ACTION_SCANNING) ) { + LOGD("still stable , to start decoder"); + if ( (SOURCE_TV == m_source_input) && mATVDisplaySnow && mpTvin->getSnowStatus()) { + mpTvin->Tvin_StopDecoder(); + mpTvin->SwitchSnow( false ); + } + int startdec_status = mpTvin->Tvin_StartDecoder ( m_cur_sig_info ); + if ( startdec_status == 0 ) { //showboz codes from start decode fun + const char *value = config_get_str ( CFG_SECTION_TV, CFG_TVIN_DB_REG, "null" ); + if ( strcmp ( value, "enable" ) == 0 ) { + usleep ( 20 * 1000 ); + Tvin_SetPLLValues (); + usleep ( 20 * 1000 ); + SetCVD2Values (); + } + } + } + if ( 1 ) { + LOGD("still stable , to unmute audio/video"); + setAudioPreGain(m_source_input); + CMessage msg; + msg.mDelayMs = 0; + msg.mType = CTvMsgQueue::TV_MSG_ENABLE_VIDEO_LATER; + msg.mpPara[0] = 2; + mTvMsgQueue.sendMsg ( msg ); + m_hdmi_audio_data = 0; + } + if ( 1 ) { + //tvin_info_t info = m_cur_sig_info; + TvEvent::SignalInfoEvent ev; + ev.mTrans_fmt = m_cur_sig_info.trans_fmt; + ev.mFmt = m_cur_sig_info.fmt; + ev.mStatus = m_cur_sig_info.status; + ev.mReserved = getHDMIFrameRate(); + sendTvEvent ( ev ); + } + +} + +bool CTv::isTvViewBlocked() { + char prop_value[PROPERTY_VALUE_MAX]; + memset(prop_value, '\0', PROPERTY_VALUE_MAX); + property_get("persist.sys.tvview.blocked", prop_value, "false"); + LOGD("%s, persist.sys.tvview.blocked = %s", __FUNCTION__, prop_value); + return (strcmp(prop_value, "true") == 0) ? true : false; +} + +void CTv::onEnableVideoLater(int framecount) +{ + LOGD ( "[source_switch_time]: %fs, onEnableVideoLater start, wait %d video frame come out", getUptimeSeconds(), framecount); + mAv.EnableVideoWhenVideoPlaying(framecount); + if (CTvin::Tvin_SourceInputToSourceInputType(m_source_input) != SOURCE_TYPE_HDMI ) { + if (isTvViewBlocked()) { + SetAudioMuteForTv ( CC_AUDIO_MUTE ); + } else { + SetAudioMuteForTv ( CC_AUDIO_UNMUTE ); + } + Tv_SetAudioInSource(m_source_input); + } + LOGD ( "[source_switch_time]: %fs, onEnableVideoLater end, show source on screen", getUptimeSeconds()); +} + +void CTv::onVideoAvailableLater(int framecount) +{ + LOGD("[ctv]onVideoAvailableLater framecount = %d", framecount); + int ret = mAv.WaittingVideoPlaying(framecount); + if (ret == 0) { //video available + TvEvent::SignalInfoEvent ev; + ev.mStatus = TVIN_SIG_STATUS_STABLE; + ev.mTrans_fmt = TVIN_TFMT_2D; + ev.mFmt = TVIN_SIG_FMT_NULL; + ev.mReserved = 1;/*<< VideoAvailable flag here*/ + sendTvEvent ( ev ); + } +} + +void CTv::Tv_SetAVOutPut_Input_gain(tv_source_input_t source_input) +{ + int nPgaValueIndex = 0; + int nAdcValueIndex = 0; + int nDdcValueIndex = 0; + int tmpAvoutBufPtr[9]; + + if (GetAvOutGainBuf_Cfg(tmpAvoutBufPtr) != 0) { + GetDefaultAvOutGainBuf(tmpAvoutBufPtr); + } + + switch (source_input) { + case SOURCE_AV1: + case SOURCE_AV2: + nPgaValueIndex = 0; + nAdcValueIndex = 1; + nDdcValueIndex = 2; + break; + case SOURCE_HDMI1: + case SOURCE_HDMI2: + case SOURCE_HDMI3: + case SOURCE_HDMI4: + case SOURCE_DTV: + case SOURCE_MPEG: + nPgaValueIndex = 3; + nAdcValueIndex = 4; + nDdcValueIndex = 5; + break; + case SOURCE_TV: + nPgaValueIndex = 6; + nAdcValueIndex = 7; + nDdcValueIndex = 8; + break; + default: + break; + } + + SetPGA_IN_Value(tmpAvoutBufPtr[nPgaValueIndex]); + SetADC_Digital_Capture_Volume(tmpAvoutBufPtr[nAdcValueIndex]); + SetDAC_Digital_PlayBack_Volume(tmpAvoutBufPtr[nDdcValueIndex]); +} + +void CTv::onSigToUnstable() +{ + LOGD ( "%s, signal to Unstable\n", __FUNCTION__); + SetAudioMuteForTv(CC_AUDIO_MUTE); +/* + if ( (SOURCE_TV == m_source_input) && mATVDisplaySnow ) { + mpTvin->SwitchSnow( true ); + mpTvin->Tvin_StartDecoder ( m_cur_sig_info ); + mAv.EnableVideoNow( false ); + } else { + mAv.DisableVideoWithBlackColor(); + mpTvin->Tvin_StopDecoder(); + } +*/ + if (SOURCE_TV != m_source_input) { + mAv.DisableVideoWithBlackColor(); + mpTvin->Tvin_StopDecoder(); + } +} + +void CTv::onSigToUnSupport() +{ + LOGD ( "%s, signal to UnSupport\n", __FUNCTION__); + SetAudioMuteForTv(CC_AUDIO_MUTE); + if ( (SOURCE_TV == m_source_input) && mATVDisplaySnow ) { + mpTvin->SwitchSnow( true ); + mpTvin->Tvin_StartDecoder ( m_cur_sig_info ); + mAv.EnableVideoNow( false ); + } else { + if ( iSBlackPattern ) { + mAv.DisableVideoWithBlackColor(); + } else { + mAv.DisableVideoWithBlueColor(); + } + mpTvin->Tvin_StopDecoder(); + } + + if (!(mTvAction & TV_ACTION_SCANNING)) { + //tvin_info_t info = m_cur_sig_info; + TvEvent::SignalInfoEvent ev; + ev.mTrans_fmt = m_cur_sig_info.trans_fmt; + ev.mFmt = m_cur_sig_info.fmt; + ev.mStatus = m_cur_sig_info.status; + ev.mReserved = m_cur_sig_info.reserved; + sendTvEvent ( ev ); + } +} + +void CTv::onSigToNoSig() +{ + LOGD ( "%s, signal to NoSignal\n", __FUNCTION__); + SetAudioMuteForTv(CC_AUDIO_MUTE); + if ( (SOURCE_TV == m_source_input) && mATVDisplaySnow ) { + mpTvin->SwitchSnow( true ); + mpTvin->Tvin_StartDecoder ( m_cur_sig_info ); + mAv.EnableVideoNow( false ); + } else { + if ( iSBlackPattern ) { + mAv.DisableVideoWithBlackColor(); + } else { + mAv.DisableVideoWithBlueColor(); + } + mpTvin->Tvin_StopDecoder(); + } + + if (!(mTvAction & TV_ACTION_SCANNING)) { + //tvin_info_t info = m_cur_sig_info; + TvEvent::SignalInfoEvent ev; + ev.mTrans_fmt = m_cur_sig_info.trans_fmt; + ev.mFmt = m_cur_sig_info.fmt; + ev.mStatus = m_cur_sig_info.status; + ev.mReserved = m_cur_sig_info.reserved; + sendTvEvent ( ev ); + } +} + +void CTv::onHDMIAudioCheckLoop() +{ + if (( CTvin::Tvin_SourceInputToSourceInputType(m_source_input) == SOURCE_TYPE_HDMI ) ) { + int sr = mpTvin->get_hdmi_sampling_rate(); + if ( ( sr > 0 ) && ( sr != m_hdmi_sampling_rate ) ) { + LOGD("HDMI SR CHANGED"); + CMessage msg; + msg.mDelayMs = 0; + msg.mType = CTvMsgQueue::TV_MSG_HDMI_SR_CHANGED; + ((int *)(msg.mpPara))[0] = sr; + ((int *)(msg.mpPara))[1] = m_hdmi_sampling_rate; + mTvMsgQueue.sendMsg ( msg ); + m_hdmi_sampling_rate = sr; + } + + //m_hdmi_audio_data init is 0, not audio data , when switch to HDMI + int hdmi_audio_data = mpTvin->TvinApi_GetHDMIAudioStatus(); + if (hdmi_audio_data != m_hdmi_audio_data && sr > 0) { + LOGD("HDMI auds_rcv_sts CHANGED = %d", hdmi_audio_data); + m_hdmi_audio_data = hdmi_audio_data; + onHMDIAudioStatusChanged(hdmi_audio_data); + } + }else if (( CTvin::Tvin_SourceInputToSourceInputType(m_source_input) == SOURCE_TYPE_SPDIF ) ) { + if ( ( mAudioMuteStatusForTv == CC_AUDIO_MUTE ) && ( m_sig_spdif_nums ++ > 3 ) ) + { + SetAudioMuteForSystem(CC_AUDIO_UNMUTE); + SetAudioMuteForTv(CC_AUDIO_UNMUTE); + LOGD("SPDIF UNMUTE"); + } + } +} + +void CTv::onBootvideoRunning() { + //LOGD("%s,boot video is running", __FUNCTION__); +} + +void CTv::onBootvideoStopped() { + LOGD("%s,boot video has stopped", __FUNCTION__); + SetAudioMasterVolume( GetAudioMasterVolume()); + mBootvideoStatusDetectThread->stopDetect(); + if (mpTvin->Tvin_RemovePath (TV_PATH_TYPE_TVIN) > 0) { + mpTvin->VDIN_AddVideoPath(TV_PATH_VDIN_AMLVIDEO2_PPMGR_DEINTERLACE_AMVIDEO); + } +} + +void CTv::onSourceConnect(int source_type, int connect_status) +{ + TvEvent::SourceConnectEvent ev; + ev.mSourceInput = source_type; + ev.connectionState = connect_status; + sendTvEvent(ev); +} + +int CTv::GetSourceConnectStatus(tv_source_input_t source_input) +{ + return mDevicesPollStatusDetectThread.GetSourceConnectStatus((tv_source_input_t)source_input); +} + +tv_source_input_t CTv::GetCurrentSourceInputLock ( void ) +{ + AutoMutex _l( mLock ); + return m_source_input; +} + +tv_source_input_t CTv::GetCurrentSourceInputVirtualLock ( void ) +{ + AutoMutex _l( mLock ); + return m_source_input_virtual; +} + +//dtv and tvin +void CTv::InitCurrenSignalInfo ( void ) +{ + m_cur_sig_info.trans_fmt = TVIN_TFMT_2D; + m_cur_sig_info.fmt = TVIN_SIG_FMT_NULL; + m_cur_sig_info.status = TVIN_SIG_STATUS_NULL; + m_cur_sig_info.reserved = 0; +} + +tvin_info_t CTv::GetCurrentSignalInfo ( void ) +{ + tvin_trans_fmt det_fmt = TVIN_TFMT_2D; + tvin_sig_status_t signalState = TVIN_SIG_STATUS_NULL; + //tvin_info_t signal_info = m_cur_sig_info; + + int feState = mFrontDev->getStatus(); + if ( (CTvin::Tvin_SourceInputToSourceInputType(m_source_input) == SOURCE_TYPE_DTV ) ) { + det_fmt = mpTvin->TvinApi_Get3DDectMode(); + if ((feState & TV_FE_HAS_LOCK) == TV_FE_HAS_LOCK) { + m_cur_sig_info.status = TVIN_SIG_STATUS_STABLE; + } else if ((feState & TV_FE_TIMEDOUT) == TV_FE_TIMEDOUT) { + m_cur_sig_info.status = TVIN_SIG_STATUS_NOSIG; + } + if ( det_fmt != TVIN_TFMT_2D ) { + m_cur_sig_info.trans_fmt = det_fmt; + } + m_cur_sig_info.fmt = mAv.getVideoResolutionToFmt(); + } + LOGD("%s, m_source_input = %d, trans_fmt is %d,fmt is %d, status is %d", __FUNCTION__, + m_source_input, m_cur_sig_info.trans_fmt, m_cur_sig_info.fmt, m_cur_sig_info.status); + return m_cur_sig_info; +} + +int CTv::Tvin_SetPLLValues () +{ + tvin_sig_fmt_t sig_fmt = m_cur_sig_info.fmt; + tvin_port_t source_port = CTvin::Tvin_GetSourcePortBySourceInput(m_source_input); + + return CVpp::getInstance()->VPP_SetPLLValues(m_source_input, source_port, sig_fmt); +} + +int CTv::SetCVD2Values () +{ + tvin_sig_fmt_t sig_fmt = m_cur_sig_info.fmt; + tvin_port_t source_port = CTvin::Tvin_GetSourcePortBySourceInput(m_source_input); + return CVpp::getInstance()->VPP_SetCVD2Values(m_source_input, source_port, sig_fmt); +} + +int CTv::setPreviewWindowMode(bool mode) +{ + mPreviewEnabled = mode; + return 0; +} + +int CTv::SetPreviewWindow ( tvin_window_pos_t pos ) +{ + m_win_pos.x1 = pos.x1; + m_win_pos.y1 = pos.y1; + m_win_pos.x2 = pos.x2; + m_win_pos.y2 = pos.y2; + LOGD ( "%s, SetPreviewWindow x = %d y=%d", __FUNCTION__, pos.x2, pos.y2 ); + + tvin_window_pos_t def_pos; + Vpp_GetDisplayResolutionInfo(&def_pos); + + if (pos.x1 != 0 || pos.y1 != 0 || pos.x2 != def_pos.x2 || pos.y2 != def_pos.y2) { + m_win_mode = PREVIEW_WONDOW; + } else { + m_win_mode = NORMAL_WONDOW; + } + + return mAv.setVideoAxis(m_win_pos.x1, m_win_pos.y1, m_win_pos.x2, m_win_pos.y2); +} + +/*********************** Audio start **********************/ +int CTv::SetAudioVolDigitLUTTable ( tv_source_input_t source_input ) +{ + int tmpDefDigitLutBuf[CC_LUT_BUF_SIZE] = { 0 }; + int lut_table_index = 0; + if (source_input == SOURCE_TV) { + lut_table_index = CC_GET_LUT_TV; + } else if (source_input == SOURCE_AV1 || source_input == SOURCE_AV2) { + lut_table_index = CC_GET_LUT_AV; + } else if (source_input == SOURCE_YPBPR1 || source_input == SOURCE_YPBPR2) { + lut_table_index = CC_GET_LUT_COMP; + } else if (source_input == SOURCE_VGA) { + lut_table_index = CC_GET_LUT_VGA; + } else if (source_input == SOURCE_HDMI1 || source_input == SOURCE_HDMI2 || source_input == SOURCE_HDMI3 + || source_input == SOURCE_HDMI4) { + lut_table_index = CC_GET_LUT_HDMI; + } else if ( source_input == SOURCE_MPEG ) { + lut_table_index = CC_GET_LUT_MPEG; + } else if ( source_input == SOURCE_DTV ) { + lut_table_index = CC_GET_LUT_MPEG; + } else if ( source_input == SOURCE_MAX) { + return 0; + } + char MainVolLutTableName[128]; + const char *baseName = GetAudioAmpMainvolTableBaseName(lut_table_index); + strcpy(MainVolLutTableName, baseName); + const char *dName = "."; + strcat(MainVolLutTableName, dName); + strcat(MainVolLutTableName, mMainVolLutTableExtraName); + if ( GetAudioAmpMainvolBuf(MainVolLutTableName, tmpDefDigitLutBuf) == 0) { + AudioSetVolumeDigitLUTBuf ( lut_table_index, tmpDefDigitLutBuf); + } + return 0; +} + +void CTv::RefreshAudioMasterVolume ( tv_source_input_t source_input ) +{ + if (source_input == SOURCE_HDMI1 || source_input == SOURCE_HDMI2 || source_input == SOURCE_HDMI3 + || source_input == SOURCE_HDMI4) { + if ( GetAudioDVISupportEnable() == 1 ) { + if ( IsDVISignal() ) { + SetAudioVolDigitLUTTable ( SOURCE_MPEG ); + SetAudioMasterVolume ( GetAudioMasterVolume() ); + return; + } + } + } + + SetAudioVolDigitLUTTable ( source_input ); + SetAudioMasterVolume ( GetAudioMasterVolume() ); +} + +int CTv::Tv_SetAudioInSource (tv_source_input_t source_input) +{ + int vol = 255; + switch (source_input) { + case SOURCE_TV: + if (mpTvin->Tvin_GetAudioInSourceType(source_input) == TV_AUDIO_IN_SOURCE_TYPE_ATV) { + AudioSetAudioInSource(CC_AUDIO_IN_SOURCE_ATV); + vol = GetAudioInternalDACDigitalPlayBackVolume_Cfg(CC_AUDIO_IN_SOURCE_ATV); + } else { + AudioSetAudioInSource(CC_AUDIO_IN_SOURCE_LINEIN); + vol = GetAudioInternalDACDigitalPlayBackVolume_Cfg(CC_AUDIO_IN_SOURCE_LINEIN); + } + break; + case SOURCE_SPDIF: + AudioSetAudioInSource(CC_AUDIO_IN_SOURCE_SPDIFIN); + vol = GetAudioInternalDACDigitalPlayBackVolume_Cfg(CC_AUDIO_IN_SOURCE_SPDIFIN); + break; + case SOURCE_AV1: + case SOURCE_AV2: + case SOURCE_YPBPR1: + case SOURCE_YPBPR2: + case SOURCE_VGA: + AudioSetAudioInSource(CC_AUDIO_IN_SOURCE_LINEIN); + vol = GetAudioInternalDACDigitalPlayBackVolume_Cfg(CC_AUDIO_IN_SOURCE_LINEIN); + break; + case SOURCE_HDMI1: + case SOURCE_HDMI2: + case SOURCE_HDMI3: + case SOURCE_HDMI4: + case SOURCE_MPEG: + case SOURCE_DTV: + AudioSetAudioInSource(CC_AUDIO_IN_SOURCE_HDMI); + vol = GetAudioInternalDACDigitalPlayBackVolume_Cfg(CC_AUDIO_IN_SOURCE_HDMI); + break; + default: + break; + } + LOGD("%s, we have read SetDAC_Digital_PlayBack_Volume = %d of source [%d].\n", __FUNCTION__, vol, source_input); + return 0; +} + +int CTv::Tv_SetAudioSourceType (tv_source_input_t source_input) +{ + int audio_source = -1; + + if (source_input == SOURCE_TV) { + audio_source = AUDIO_ATV_SOURCE; + } else if (source_input == SOURCE_AV1 || source_input == SOURCE_AV2) { + audio_source = AUDIO_AV_SOURCE; + } else if (source_input == SOURCE_HDMI1 || source_input == SOURCE_HDMI2 || + source_input == SOURCE_HDMI3 || source_input == SOURCE_HDMI4) { + audio_source = AUDIO_HDMI_SOURCE; + } else if (source_input == SOURCE_YPBPR1 || source_input == SOURCE_YPBPR2 || + source_input == SOURCE_VGA) { + audio_source = AUDIO_AV_SOURCE; + } else if (source_input == SOURCE_DTV) { + audio_source = AUDIO_MPEG_SOURCE; + } else { + audio_source = AUDIO_MPEG_SOURCE; + } + + return AudioSetAudioSourceType(audio_source); +} + +void CTv::Tv_SetAudioOutputSwap_Type (tv_source_input_t source_input) +{ + int sw_status = GetAudioOutputSwapStatus(source_input); + SetOutput_Swap(sw_status); +} +/*********************** Audio end **********************/ + +unsigned int CTv::Vpp_GetDisplayResolutionInfo(tvin_window_pos_t *win_pos) +{ + int display_resolution = mAv.getVideoDisplayResolution(); + int width = 0, height = 0; + switch (display_resolution) { + case VPP_DISPLAY_RESOLUTION_1366X768: + width = CC_RESOLUTION_1366X768_W; + height = CC_RESOLUTION_1366X768_H; + break; + case VPP_DISPLAY_RESOLUTION_1920X1080: + width = CC_RESOLUTION_1920X1080_W; + height = CC_RESOLUTION_1920X1080_H; + break; + case VPP_DISPLAY_RESOLUTION_3840X2160: + width = CC_RESOLUTION_3840X2160_W; + height = CC_RESOLUTION_3840X2160_H; + break; + default: + width = CC_RESOLUTION_3840X2160_W; + height = CC_RESOLUTION_3840X2160_H; + break; + } + + if (win_pos != NULL) { + win_pos->x1 = 0; + win_pos->y1 = 0; + win_pos->x2 = width - 1; + win_pos->y2 = height - 1; + } + return 0; +} + +int CTv::setBlackoutEnable(int enable) +{ + mBlackoutEnable = ((enable==1)?true:false); + return SSMSaveBlackoutEnable(enable); +} + +int CTv::getSaveBlackoutEnable() +{ + int8_t enable; + SSMReadBlackoutEnable(&enable); + return enable; +} + +int CTv::setAutoBackLightStatus(int status) +{ + if (mHdmiOutFbc) { + return mFactoryMode.fbcSetAutoBacklightOnOff(status); + } + + return tvWriteSysfs(BL_LOCAL_DIMING_FUNC_ENABLE, status); +} + +int CTv::getAutoBackLightStatus() +{ + if (mHdmiOutFbc) { + return mFactoryMode.fbcGetAutoBacklightOnOff(); + } + + char str_value[3] = {0}; + tvReadSysfs(BL_LOCAL_DIMING_FUNC_ENABLE, str_value); + int value = atoi(str_value); + return (value < 0) ? -1 : value; +} + +int CTv::getAverageLuma() +{ + return mpTvin->VDIN_Get_avg_luma(); +} + +int CTv::setAutobacklightData(const char *value) +{ + const char *KEY = "haier.autobacklight.mp.data"; + + const char *keyValue = config_get_str(CFG_SECTION_TV, KEY, "null"); + if (strcmp(keyValue, value) != 0) { + config_set_str(CFG_SECTION_TV, KEY, value); + LOGD("%s, config string now set as: %s \n", __FUNCTION__, keyValue); + } else { + LOGD("%s, config string has been set as: %s \n", __FUNCTION__, keyValue); + } + return 0; +} + +int CTv::getAutoBacklightData(int *data) +{ + char datas[512] = {0}; + char delims[] = ","; + char *result = NULL; + const char *KEY = "haier.autobacklight.mp.data"; + int i = 0; + + if (NULL == data) { + LOGE("[ctv]%s, data is null", __FUNCTION__); + return -1; + } + + const char *keyValue = config_get_str(CFG_SECTION_TV, KEY, (char *) "null"); + if (strcmp(keyValue, "null") == 0) { + LOGE("[ctv]%s, value is NULL\n", __FUNCTION__); + return -1; + } + + strncpy(datas, keyValue, sizeof(datas) - 1); + result = strtok( datas, delims ); + while ( result != NULL ) { + char *pd = strstr(result, ":"); + if (pd != NULL) { + data[i] = strtol(pd + 1, NULL, 10 ); + i++; + } + result = strtok( NULL, delims ); + } + return i; +} + +int CTv::setLcdEnable(bool enable) +{ + int ret = -1; + if (mHdmiOutFbc) { + ret = fbcIns->fbcSetPanelStatus(COMM_DEV_SERIAL, enable ? 1 : 0); + } else { + ret = tvWriteSysfs(LCD_ENABLE, enable ? 1 : 0); + } + + return ret; +} + +/*********************** SSM start **********************/ +int CTv::Tv_SSMRestoreDefaultSetting() +{ + SSMRestoreDeviceMarkValues(); + AudioSSMRestoreDefaultSetting(); + CVpp::getInstance()->VPPSSMFacRestoreDefault(); + MiscSSMRestoreDefault(); + ReservedSSMRestoreDefault(); + SSMSaveCVBSStd ( 0 ); + SSMSaveLastSelectSourceInput ( SOURCE_TV ); + SSMSavePanelType ( 0 ); + //tvconfig default + saveDTVProgramID ( -1 ); + saveATVProgramID ( -1 ); + SSMSaveStandbyMode( 0 ); + SSMHDMIEdidRestoreDefault(); + return 0; +} + +int CTv::clearDbAllProgramInfoTable() +{ + return CTvDatabase::GetTvDb()->clearDbAllProgramInfoTable(); +} + +int CTv::Tv_SSMFacRestoreDefaultSetting() +{ + CVpp::getInstance()->VPPSSMFacRestoreDefault(); + AudioSSMRestoreDefaultSetting(); + MiscSSMFacRestoreDefault(); + return 0; +} +/*********************** SSM End **********************/ + +//not in CTv, not use lock +void CTv::setSourceSwitchAndPlay() +{ + int progID = 0; + CTvProgram prog; + LOGD ( "%s\n", __FUNCTION__ ); + static const int POWERON_SOURCE_TYPE_NONE = 0;//not play source + static const int POWERON_SOURCE_TYPE_LAST = 1;//play last save source + static const int POWERON_SOURCE_TYPE_SETTING = 2;//play ui set source + int to_play_source = -1; + int powerup_type = SSMReadPowerOnOffChannel(); + LOGD("read power on source type = %d", powerup_type); + if (powerup_type == POWERON_SOURCE_TYPE_NONE) { + return ; + } else if (powerup_type == POWERON_SOURCE_TYPE_LAST) { + to_play_source = SSMReadSourceInput(); + } else if (powerup_type == POWERON_SOURCE_TYPE_SETTING) { + to_play_source = SSMReadLastSelectSourceInput(); + } + SetSourceSwitchInput (( tv_source_input_t ) to_play_source ); + if ( to_play_source == SOURCE_TV ) { + progID = getATVProgramID(); + } else if ( to_play_source == SOURCE_DTV ) { + progID = getDTVProgramID(); + } +} + +//==============vchip end================================ + +int CTv::GetHdmiHdcpKeyKsvInfo(int data_buf[]) +{ + int ret = -1; + if (m_source_input != SOURCE_HDMI1 && m_source_input != SOURCE_HDMI2 && m_source_input != SOURCE_HDMI3 + &&m_source_input != SOURCE_HDMI4) { + return -1; + } + + struct _hdcp_ksv msg; + ret = mHDMIRxManager.GetHdmiHdcpKeyKsvInfo(&msg); + memset((void *)data_buf, 0, 2); + data_buf[0] = msg.bksv0; + data_buf[1] = msg.bksv1; + return ret; +} + +bool CTv::hdmiOutWithFbc() +{ + const char *value = config_get_str(CFG_SECTION_TV, CFG_FBC_USED, "true"); + if (strcmp(value, "true") == 0) { + return true; + } + + return false; +} + +void CTv::onUpgradeStatus(int state, int param) +{ + TvEvent::UpgradeFBCEvent ev; + ev.mState = state; + ev.param = param; + sendTvEvent(ev); +} + +int CTv::StartUpgradeFBC(char *file_name, int mode, int upgrade_blk_size) +{ + return fbcIns->fbcStartUpgrade(file_name, mode, upgrade_blk_size); +} + +int CTv::StartHeadSetDetect() +{ + mHeadSet.startDetect(); + return 0; +} + +void CTv::onHeadSetDetect(int state, int para) +{ + TvEvent::HeadSetOf2d4GEvent ev; + if (state == 1) + property_set("audio.headset_plug.enable", "1"); + else + property_set("audio.headset_plug.enable", "0"); + ev.state = state; + ev.para = para; + sendTvEvent(ev); +} + +void CTv::onThermalDetect(int state) +{ + const char *value; + int val = 0; + static int preValue = -1; + + value = config_get_str ( CFG_SECTION_TV, CFG_TVIN_THERMAL_THRESHOLD_ENABLE, "null" ); + if ( strcmp ( value, "enable" ) == 0 ) { + value = config_get_str ( CFG_SECTION_TV, CFG_TVIN_THERMAL_THRESHOLD_VALUE, "null" ); + int threshold = atoi(value); + LOGD ( "%s, threshold value: %d\n", __FUNCTION__, threshold); + + if (state > threshold) { + const char *valueNormal = config_get_str ( CFG_SECTION_TV, CFG_TVIN_THERMAL_FBC_NORMAL_VALUE, "null" ); + val = atoi(valueNormal); + if (val == 0) { + val = 0x4210000; //normal default + } + LOGD ( "%s, current temp: %d set 1\n", __FUNCTION__, state); + } else { + const char *valueCold = config_get_str ( CFG_SECTION_TV, CFG_TVIN_THERMAL_FBC_COLD_VALUE, "null" ); + val = atoi(valueCold); + if (val == 0) { + val = 0x8210000; //cold default + } + LOGD ( "%s, current temp: 0x%x set 0\n", __FUNCTION__, state); + } + + if (preValue != val) { + LOGD ( "%s, pre value :0x%x, new value :0x%x, bypass\n", __FUNCTION__, preValue, val); + preValue = val; + mFactoryMode.fbcSetThermalState(val); + } + } else { + LOGD ( "%s, tvin thermal threshold disable\n", __FUNCTION__); + } +} + +int CTv::Tv_GetProjectInfo(project_info_t *ptrInfo) +{ + return GetProjectInfo(ptrInfo, fbcIns); +} + +int CTv::Tv_GetPlatformType() +{ + return mHdmiOutFbc ? 1 : 0; +} + +int CTv::Tv_HDMIEDIDFileSelect(tv_hdmi_port_id_t port, tv_hdmi_edid_version_t version) +{ + char edid_path[100] = {0}; + char edid_path_cfg[100] = {0}; + + config_set_str(CFG_SECTION_TV, CS_HDMI_EDID_USE_CFG, "customer_edid"); + if ( HDMI_EDID_VER_14== version ) { + sprintf(edid_path, "/vendor/etc/port_%d.bin", 14); + } else if (HDMI_EDID_VER_20== version) { + sprintf(edid_path, "/vendor/etc/port_%d.bin", 20); + } else { + LOGE("%s HDMI EDID VERSION error!\n", __FUNCTION__); + sprintf(edid_path, "/vendor/etc/port_%d.bin", 14); + } + sprintf(edid_path_cfg, "ssm.handle.hdmi.port%d.edid.file.path", port); + if (access(edid_path, 0) < 0) { + config_set_str(CFG_SECTION_TV, CS_HDMI_EDID_USE_CFG, "hdmi_edid"); + } + config_set_str(CFG_SECTION_TV, edid_path_cfg, edid_path); + return 0; +} + +int CTv::Tv_HandeHDMIEDIDFilePathConfig() +{ + if (1 == GetSSMHandleHDMIEdidByCustomerEnableCFG()) { + //set file's path for hdmi edid of each port + for (int i = 1; i <= SSM_HDMI_PORT_MAX; i++) { + Tv_HDMIEDIDFileSelect((tv_hdmi_port_id_t)i, SSMReadHDMIEdidVersion((tv_hdmi_port_id_t)i)); + } + } + mSetHdmiEdid = true; + return 0; +} + +int CTv::Tv_SetDDDRCMode(tv_source_input_t source_input) +{ + if (source_input == SOURCE_DTV) { + if (GetPlatformHaveDDFlag() == 1) { + tvWriteSysfs(SYS_AUIDO_DSP_AC3_DRC, (char *)"drcmode 3"); + } + } else { + if (GetPlatformHaveDDFlag() == 1) { + tvWriteSysfs(SYS_AUIDO_DSP_AC3_DRC, (char *)"drcmode 2"); + } + } + return 0; +} + +//PQ +int CTv::Tv_SetBrightness ( int brightness, tv_source_input_t tv_source_input, int is_save ) +{ + return CVpp::getInstance()->SetBrightness(brightness, tv_source_input, + m_cur_sig_info.fmt, + m_cur_sig_info.trans_fmt, INDEX_2D, is_save); +} + +int CTv::Tv_GetBrightness ( tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->GetBrightness(tv_source_input); +} + +int CTv::Tv_SaveBrightness ( int brightness, tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->SaveBrightness(brightness, tv_source_input); +} + +int CTv::Tv_SetContrast ( int contrast, tv_source_input_t tv_source_input, int is_save ) +{ + return CVpp::getInstance()->SetContrast(contrast, tv_source_input, + m_cur_sig_info.fmt, m_cur_sig_info.trans_fmt, INDEX_2D, is_save); +} + +int CTv::Tv_GetContrast ( tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->GetContrast(tv_source_input); +} + +int CTv::Tv_SaveContrast ( int contrast, tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->SaveContrast(contrast, tv_source_input); +} + +int CTv::Tv_SetSaturation ( int satuation, tv_source_input_t tv_source_input, tvin_sig_fmt_t fmt, int is_save ) +{ + return CVpp::getInstance()->SetSaturation(satuation, tv_source_input, + (tvin_sig_fmt_t)fmt, m_cur_sig_info.trans_fmt, INDEX_2D, is_save); +} + +int CTv::Tv_GetSaturation ( tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->GetSaturation(tv_source_input); +} + +int CTv::Tv_SaveSaturation ( int satuation, tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->SaveSaturation(satuation, tv_source_input); +} + +int CTv::Tv_SetHue ( int hue, tv_source_input_t tv_source_input, tvin_sig_fmt_t fmt, int is_save ) +{ + return CVpp::getInstance()->SetHue(hue, (tv_source_input_t)tv_source_input, (tvin_sig_fmt_t)fmt, + m_cur_sig_info.trans_fmt, INDEX_2D, is_save); +} + +int CTv::Tv_GetHue ( tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->GetHue(tv_source_input); +} + +int CTv::Tv_SaveHue ( int hue, tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->SaveHue(hue, tv_source_input); +} + +int CTv::Tv_SetPQMode ( vpp_picture_mode_t mode, tv_source_input_t tv_source_input, int is_save ) +{ + return CVpp::getInstance()->SetPQMode((vpp_picture_mode_t)mode, (tv_source_input_t)tv_source_input, + m_cur_sig_info.fmt, m_cur_sig_info.trans_fmt, INDEX_2D, is_save, 0); + +} + +vpp_picture_mode_t CTv::Tv_GetPQMode ( tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->GetPQMode((tv_source_input_t)tv_source_input); +} + +int CTv::Tv_SavePQMode ( vpp_picture_mode_t mode, tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->SavePQMode ( mode, tv_source_input ); +} + +int CTv::Tv_SetSharpness ( int value, tv_source_input_t tv_source_input, int en, int is_save ) +{ + return CVpp::getInstance()->SetSharpness(value, + (tv_source_input_t)tv_source_input, en, + INDEX_2D, + m_cur_sig_info.fmt, + m_cur_sig_info.trans_fmt, + is_save); +} + +int CTv::Tv_GetSharpness ( tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->GetSharpness((tv_source_input_t)tv_source_input); +} + +int CTv::Tv_SaveSharpness ( int value, tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->SaveSharpness(value, tv_source_input); +} + +int CTv::Tv_SetBacklight ( int value, tv_source_input_t tv_source_input, int is_save ) +{ + return CVpp::getInstance()->SetBacklight(value, (tv_source_input_t)tv_source_input, is_save); +} + +int CTv::Tv_GetBacklight ( tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->GetBacklight((tv_source_input_t)tv_source_input); +} + +int CTv::Tv_SaveBacklight ( int value, tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->SaveBacklight ( value, tv_source_input ); +} + +int CTv::Tv_SetBacklight_Switch ( int value ) +{ + if (mHdmiOutFbc) { + return mFactoryMode.fbcBacklightOnOffSet(value); + } else { + return CVpp::getInstance()->VPP_SetBackLight_Switch(value); + } +} + +int CTv::Tv_GetBacklight_Switch ( void ) +{ + if (mHdmiOutFbc) { + return mFactoryMode.fbcBacklightOnOffGet(); + } else { + return CVpp::getInstance()->VPP_GetBackLight_Switch(); + } +} + +int CTv::Tv_SetColorTemperature ( vpp_color_temperature_mode_t mode, tv_source_input_t tv_source_input, int is_save ) +{ + return CVpp::getInstance()->SetColorTemperature((vpp_color_temperature_mode_t)mode, (tv_source_input_t)tv_source_input, is_save); +} + +vpp_color_temperature_mode_t CTv::Tv_GetColorTemperature ( tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->GetColorTemperature((tv_source_input_t)tv_source_input); +} + +int CTv::Tv_SaveColorTemperature ( vpp_color_temperature_mode_t mode, tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->SaveColorTemperature ( mode, tv_source_input ); +} + +int CTv::Tv_SetDisplayMode ( vpp_display_mode_t mode, tv_source_input_t tv_source_input, tvin_sig_fmt_t fmt, int is_save ) +{ + int ret = SetDisplayMode((vpp_display_mode_t)mode, tv_source_input, GetCurrentSignalInfo().fmt); + + if (ret == 0) { + if (is_save == 1) { + ret = ret | SSMSaveDisplayMode ( tv_source_input, (int)mode ); + } + } + return ret; +} + +int CTv::SetDisplayMode ( vpp_display_mode_t display_mode, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt ) +{ + tv_source_input_type_t source_type; + source_type = CTvin::Tvin_SourceInputToSourceInputType(tv_source_input); + LOGD("SetDisplayMode, display_mode = %d, source_type = %d sigfmt = %d tranfmt = %d\n", + display_mode, source_type, sig_fmt, m_cur_sig_info.trans_fmt); + + tvin_cutwin_t cutwin = CVpp::getInstance()->GetOverscan(tv_source_input, sig_fmt, + INDEX_2D, m_cur_sig_info.trans_fmt); + LOGD("SetDisplayMode , get crop %d %d %d %d \n", cutwin.vs, cutwin.hs, cutwin.ve, cutwin.he); + + int video_screen_mode = CAv::VIDEO_WIDEOPTION_16_9; + tvin_window_pos_t win_pos; + int display_resolution = Vpp_GetDisplayResolutionInfo(&win_pos); + + switch ( display_mode ) { + case VPP_DISPLAY_MODE_169: + video_screen_mode = CAv::VIDEO_WIDEOPTION_16_9; + break; + case VPP_DISPLAY_MODE_MODE43: + video_screen_mode = CAv::VIDEO_WIDEOPTION_4_3; + break; + case VPP_DISPLAY_MODE_NORMAL: + video_screen_mode = CAv::VIDEO_WIDEOPTION_NORMAL; + break; + case VPP_DISPLAY_MODE_FULL: + video_screen_mode = CAv::VIDEO_WIDEOPTION_NONLINEAR; + CVpp::getInstance()->VPP_SetNonLinearFactor ( 20 ); + break; + case VPP_DISPLAY_MODE_CROP_FULL: + cutwin.vs = 0; + cutwin.hs = 0; + cutwin.ve = 0; + cutwin.he = 0; + break; + case VPP_DISPLAY_MODE_NOSCALEUP: + video_screen_mode = CAv::VIDEO_WIDEOPTION_NORMAL_NOSCALEUP; + break; + case VPP_DISPLAY_MODE_FULL_REAL: + video_screen_mode = CAv::VIDEO_WIDEOPTION_16_9; //added for N360 by haifeng.liu + break; + case VPP_DISPLAY_MODE_PERSON: + video_screen_mode = CAv::VIDEO_WIDEOPTION_FULL_STRETCH; + cutwin.vs = cutwin.vs + 20; + cutwin.ve = cutwin.ve + 20; + break; + case VPP_DISPLAY_MODE_MOVIE: + video_screen_mode = CAv::VIDEO_WIDEOPTION_FULL_STRETCH; + cutwin.vs = cutwin.vs + 40; + cutwin.ve = cutwin.ve + 40; + break; + case VPP_DISPLAY_MODE_CAPTION: + video_screen_mode = CAv::VIDEO_WIDEOPTION_FULL_STRETCH; + cutwin.vs = cutwin.vs + 55; + cutwin.ve = cutwin.ve + 55; + break; + case VPP_DISPLAY_MODE_ZOOM: + video_screen_mode = CAv::VIDEO_WIDEOPTION_FULL_STRETCH; + cutwin.vs = cutwin.vs + 70; + cutwin.ve = cutwin.ve + 70; + break; + default: + break; + } + if (source_type == SOURCE_TYPE_DTV) { + cutwin.vs = cutwin.vs + 12; + cutwin.ve = cutwin.ve + 12; + cutwin.hs = cutwin.hs + 12; + cutwin.he = cutwin.he + 12; + } + if (source_type == SOURCE_TYPE_HDMI) { + if ((IsDVISignal()) + || (mpTvin->GetITContent() == 1) + || (display_mode == VPP_DISPLAY_MODE_FULL_REAL) + || (CVpp::getInstance()->GetPQMode(tv_source_input) == VPP_PICTURE_MODE_MONITOR)) { + cutwin.vs = 0; + cutwin.hs = 0; + cutwin.ve = 0; + cutwin.he = 0; + } + } + + mAv.setVideoScreenMode(video_screen_mode); + CVpp::getInstance()->VPP_SetVideoCrop(cutwin.vs, cutwin.hs, cutwin.ve, cutwin.he); + return 0; +} + +vpp_display_mode_t CTv::Tv_GetDisplayMode ( tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->GetDisplayMode((tv_source_input_t)tv_source_input); +} + +int CTv::Tv_SaveDisplayMode ( vpp_display_mode_t mode, tv_source_input_t tv_source_input ) +{ + return SSMSaveDisplayMode ( tv_source_input, (int)mode ); +} + +int CTv::setAudioPreGain(tv_source_input_t source_input) +{ + float pre_gain = getAudioPreGain(source_input); + if (pre_gain > -100.000001 && pre_gain < -99.999999) { + return -1; + } + + return setAmAudioPreGain(pre_gain); +} + +float CTv::getAudioPreGain(tv_source_input_t source_input) +{ + float pre_gain = -100;//default value is -100, if value of gain is -100, don't set it to AMAUDIO. + switch (source_input) { + case SOURCE_AV1: + case SOURCE_AV2: + pre_gain = config_get_float(CFG_SECTION_TV, CFG_AUDIO_PRE_GAIN_FOR_AV, -100); + break; + case SOURCE_HDMI1: + case SOURCE_HDMI2: + case SOURCE_HDMI3: + case SOURCE_HDMI4: + pre_gain = config_get_float(CFG_SECTION_TV, CFG_AUDIO_PRE_GAIN_FOR_HDMI, -100); + break; + case SOURCE_DTV: + pre_gain = config_get_float(CFG_SECTION_TV, CFG_AUDIO_PRE_GAIN_FOR_DTV, -100); + break; + case SOURCE_MPEG: + pre_gain = 0; + break; + case SOURCE_TV: + pre_gain = config_get_float(CFG_SECTION_TV, CFG_AUDIO_PRE_GAIN_FOR_ATV, -100); + break; + default: + break; + } + return pre_gain; +} + +int CTv::setEyeProtectionMode(int enable) +{ + int ret = -1; + if (getEyeProtectionMode() == enable) + return ret; + + return CVpp::getInstance()->SetEyeProtectionMode( + m_source_input, enable); +} + +int CTv::getEyeProtectionMode() +{ + return CVpp::getInstance()->GetEyeProtectionMode(); +} + +int CTv::setGamma(vpp_gamma_curve_t gamma_curve, int is_save) +{ + if (mHdmiOutFbc) { + return mFactoryMode.fbcSetGammaValue(gamma_curve, is_save); + } else { + return CVpp::getInstance()->SetGammaValue(gamma_curve, is_save); + } +} + +int CTv::Tv_SetNoiseReductionMode ( vpp_noise_reduction_mode_t mode, tv_source_input_t tv_source_input, int is_save ) +{ + return CVpp::getInstance()->SetNoiseReductionMode((vpp_noise_reduction_mode_t)mode, + (tv_source_input_t)tv_source_input, + m_cur_sig_info.fmt, + INDEX_2D, + m_cur_sig_info.trans_fmt, is_save); +} + +int CTv::Tv_SaveNoiseReductionMode ( vpp_noise_reduction_mode_t mode, tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->SaveNoiseReductionMode ( mode, tv_source_input ); +} + +vpp_noise_reduction_mode_t CTv::Tv_GetNoiseReductionMode ( tv_source_input_t tv_source_input ) +{ + return CVpp::getInstance()->GetNoiseReductionMode((tv_source_input_t)tv_source_input); +} + +int CTv::Tv_Easupdate() +{ + int ret = 0; + if (mTvEas->mEasScanHandle != NULL) { + ret = mTvEas->StopEasUpdate(); + if (ret < 0) { + LOGD("StopEasUpdate error!\n"); + return ret; + } + } + + return mTvEas->StartEasUpdate(); +} + +//audio +void CTv::TvAudioOpen() +{ + SetAudioAVOutMute(CC_AUDIO_UNMUTE); + SetAudioSPDIFMute(CC_AUDIO_UNMUTE); + project_info_t tmp_info; + if (GetProjectInfo(&tmp_info) == 0) { + strncpy(mMainVolLutTableExtraName, tmp_info.amp_curve_name, CC_PROJECT_INFO_ITEM_MAX_LEN - 1); + } + openTvAudio(); +} + +void CTv::AudioCtlUninit() +{ + int oldMuteStatus = mAudioMuteStatusForTv; + SetAudioMuteForTv(CC_AUDIO_MUTE); + + AudioSetAudioInSource (CC_AUDIO_IN_SOURCE_HDMI); + SetDAC_Digital_PlayBack_Volume(255); + AudioSetAudioSourceType (AUDIO_MPEG_SOURCE); + UnInitTvAudio(); + SetAudioVolumeCompensationVal(0); + SetAudioMasterVolume(GetAudioMasterVolume()); + UnInitSetTvAudioCard(); + + SetAudioMuteForTv(oldMuteStatus); +} + +//audio +int CTv::SetAudioMuteForSystem(int muteOrUnmute) +{ + int ret = 0; + LOGD("SetAudioMuteForSystem sysMuteStats=%d, tvMuteStatus=%d, toMute=%d", + mAudioMuteStatusForSystem, mAudioMuteStatusForTv, muteOrUnmute); + mAudioMuteStatusForSystem = muteOrUnmute; + ret |= SetDacMute(mAudioMuteStatusForSystem, CC_DAC_MUTE_TYPE_EXTERNAL); + ret |= SetAudioI2sMute(mAudioMuteStatusForSystem | mAudioMuteStatusForTv); + return ret; +} + +int CTv::GetAudioMuteForSystem() +{ + return mAudioMuteStatusForSystem; +} + +int CTv::SetAudioMuteForTv(int muteOrUnmute) +{ + int ret = 0; + mAudioMuteStatusForTv = muteOrUnmute; + LOGD("SetAudioMuteForTv sysMuteStats=%d, tvMuteStatus=%d, toMute=%d", + mAudioMuteStatusForSystem, mAudioMuteStatusForTv, muteOrUnmute); + ret |= SetDacMute(mAudioMuteStatusForSystem | mAudioMuteStatusForTv, CC_DAC_MUTE_TYPE_EXTERNAL | CC_DAC_MUTE_TYPE_INTERNAL); + ret |= SetAudioI2sMute(mAudioMuteStatusForTv); + ret |= SetAudioSPDIFMute(mAudioMuteStatusForTv); + ret |= mAudioAlsa.SetAudioARCSwitch(!mAudioMuteStatusForTv); + //AudioSystem::setStreamMute(AUDIO_STREAM_MUSIC, mAudioMuteStatusForTv); + return ret; +} + +int CTv::GetAudioMuteForTv() +{ + return mAudioMuteStatusForTv; +} + +int CTv::SetAudioSPDIFSwitch(int tmp_val) +{ + int muteStatus = CC_AUDIO_UNMUTE; + + SaveCurAudioSPDIFSwitch(tmp_val); + + if (tmp_val == CC_SWITCH_OFF /*|| mAudioMuteStatusForSystem == CC_AUDIO_MUTE || mAudioMuteStatusForTv == CC_AUDIO_MUTE*/) { + muteStatus = CC_AUDIO_MUTE; + } else { + muteStatus = CC_AUDIO_UNMUTE; + } + + SetAudioSPDIFMute(muteStatus); + return 0; +} + +void CTv::updateSubtitle(int pic_width, int pic_height) +{ + TvEvent::SubtitleEvent ev; + ev.pic_width = pic_width; + ev.pic_height = pic_height; + sendTvEvent(ev); +} +//-------------------------------------------------- + + +//Audio Mute +int CTv::SetAudioI2sMute(int muteStatus) +{ + int aud_arch_type = GetAudioArchitectureTypeCFG(); + + if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_ON_BOARD) + return 0; + + int vol = 256; + if (muteStatus == CC_AUDIO_MUTE) { + vol = 0; + } else { + vol = 256; + } + CFile::setFileAttrValue(SYS_AUIDO_DIRECT_RIGHT_GAIN, vol); + CFile::setFileAttrValue(SYS_AUIDO_DIRECT_LEFT_GAIN, vol); + return 0; +} + +int CTv::SetDacMute(int muteStatus, int mute_type) +{ + int tmp_ret = 0; + if (mute_type & CC_DAC_MUTE_TYPE_INTERNAL) { + tmp_ret |= mAudioAlsa.SetInternalDacMute(muteStatus); + } + + if (mute_type & CC_DAC_MUTE_TYPE_EXTERNAL) { + int set_val = 0; + int aud_arch_type = GetAudioArchitectureTypeCFG(); + + if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_ON_BOARD) { + if (muteStatus == CC_AUDIO_MUTE) { + set_val = CC_MUTE_ON; + } else if (muteStatus == CC_AUDIO_UNMUTE) { + set_val = CC_MUTE_OFF; + } else { + return -1; + } + + mAudioAlsa.SetExternalDacChannelSwitch(1, set_val); + mAudioAlsa.SetExternalDacChannelSwitch(2, set_val); + //showboz: can disable it + mAudioAlsa.SetExternalDacChannelSwitch(3, set_val); + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_OFF_BOARD_FBC) { + SendCmdToOffBoardFBCExternalDac(AUDIO_CMD_SET_MUTE, muteStatus); + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_CUSTOMER_LIB) { + mCustomerCtrl.SetMute((muteStatus == CC_AUDIO_MUTE) ? CAudioCustomerCtrl::MUTE : CAudioCustomerCtrl::UNMUTE); + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_DIGITAL) { + mAudioAlsa.SetDigitalMute(muteStatus); + } + mAudioAlsa.setAudioPcmPlaybackMute(muteStatus); + } + return tmp_ret; +} + +int CTv::SetAudioAVOutMute(int muteStatus) +{ + SSMSaveAudioAVOutMuteVal(muteStatus); + return mAudioAlsa.SetInternalDacMute(muteStatus); +} + +int CTv::GetAudioAVOutMute() +{ + int8_t tmp_ch = 0; + SSMReadAudioAVOutMuteVal(&tmp_ch); + return tmp_ch; +} + +int CTv::SetAudioSPDIFMute(int muteStatus) +{ + if (GetCurAudioSPDIFSwitch() == CC_SWITCH_OFF) { + muteStatus = CC_AUDIO_MUTE; + } + + SSMSaveAudioSPIDFMuteVal(muteStatus); + return mAudioAlsa.SetSPDIFMute(muteStatus); +} + +int CTv::GetAudioSPDIFMute() +{ + int8_t tmp_ch = 0; + SSMReadAudioSPIDFMuteVal(&tmp_ch); + return tmp_ch; +} + +int CTv::GetCurAudioSPDIFSwitch() +{ + return mCurAudioSPDIFSwitch; +} + +int CTv::SaveCurAudioSPDIFSwitch(int tmp_val) +{ + mCurAudioSPDIFSwitch = tmp_val; + SSMSaveAudioSPDIFSwitchVal(tmp_val); + return tmp_val; +} + +int CTv::LoadCurAudioSPDIFSwitch() +{ + int8_t tmp_ch = 0; + SSMReadAudioSPDIFSwitchVal(&tmp_ch); + mCurAudioSPDIFSwitch = tmp_ch; + if (mCurAudioSPDIFSwitch != CC_SWITCH_ON + && mCurAudioSPDIFSwitch != CC_SWITCH_OFF) { + SaveCurAudioSPDIFSwitch (CC_SWITCH_ON); + } + return mCurAudioSPDIFSwitch; +} + +//Audio SPDIF Mode +int CTv::SetAudioSPDIFMode(int tmp_val) +{ + LOGD("%s : val = %d\n", __FUNCTION__, tmp_val); + mCurAudioSPDIFMode = tmp_val; + SetSPDIFMode(tmp_val); + return 0; +} + +int CTv::GetCurAudioSPDIFMode() +{ + return mCurAudioSPDIFMode; +} + +int CTv::SaveCurAudioSPDIFMode(int tmp_val) +{ + mCurAudioSPDIFMode = tmp_val; + SSMSaveAudioSPDIFModeVal(tmp_val); + return tmp_val; +} + +int CTv::LoadCurAudioSPDIFMode() +{ + int8_t tmp_ch = 0; + SSMReadAudioSPDIFModeVal(&tmp_ch); + mCurAudioSPDIFMode = tmp_ch; + if (mCurAudioSPDIFMode != CC_SPDIF_MODE_PCM + && mCurAudioSPDIFMode != CC_SPDIF_MODE_RAW) { + SaveCurAudioSPDIFMode (CC_SPDIF_MODE_PCM); + } + return mCurAudioSPDIFMode; +} + +int CTv::SetAudioMasterVolume(int tmp_vol) +{ + LOGD("%s, tmp_vol = %d", __FUNCTION__, tmp_vol); + mCustomAudioMasterVolume = tmp_vol; + if (!isBootvideoStopped()) { + mBootvideoStatusDetectThread->startDetect(); + return 0; + } + if (GetUseAndroidVolEnable()) { + int master_vol; + master_vol = config_get_int(CFG_SECTION_TV, CFG_AUDIO_MASTER_VOL, 150); + mAudioAlsa.SetExternalDacChannelVolume(0, master_vol); + return 0; + } + + //Volume Compensation + tmp_vol += mVolumeCompensationVal; + + if (tmp_vol > CC_MAX_SOUND_VOL) { + tmp_vol = CC_MAX_SOUND_VOL; + } + + if (tmp_vol < CC_MIN_SOUND_VOL) { + tmp_vol = CC_MIN_SOUND_VOL; + } + + int tmp_ret = 0; + int aud_arch_type = GetAudioArchitectureTypeCFG(); + + if (aud_arch_type == CC_DAC_G9TV_INTERNAL_DAC) { + tmp_ret = mAudioAlsa.SetInternalDacMainVolume(tmp_vol); + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_ON_BOARD) { + int digit_vol = 0; + int vol_gain_val = 0; + int vol_buf[2] = {0, 0}; + + //handle l&r channel volume for balance + mAudioAlsa.CalculateBalanceVol(255, mMainVolumeBalanceVal, vol_buf); + + tmp_ret |= mAudioAlsa.SetExternalDacChannelVolume(1, vol_buf[0]); + tmp_ret |= mAudioAlsa.SetExternalDacChannelVolume(2, vol_buf[1]); + + //handle master channel volume + digit_vol = mAudioAlsa.TransVolumeBarVolToDigitalVol(mAudioAlsa.GetMainVolDigitLutBuf(), tmp_vol); + + vol_gain_val = mAudioAlsa.GetMainVolumeGain(); + digit_vol += vol_gain_val; + tmp_ret |= mAudioAlsa.SetExternalDacChannelVolume(0, digit_vol); + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_OFF_BOARD_FBC) { + tmp_ret = SendCmdToOffBoardFBCExternalDac(AUDIO_CMD_SET_VOLUME_BAR, tmp_vol); + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_CUSTOMER_LIB) { + tmp_ret = mCustomerCtrl.SetVolumeBar(tmp_vol); + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_DIGITAL) { + int vol_buf[2] = {0, 0}; + mAudioAlsa.CalculateBalanceVol(tmp_vol, mMainVolumeBalanceVal, vol_buf); + tmp_ret = mAudioAlsa.SetDigitalMainVolume(vol_buf[0], vol_buf[1]); + } + if ( Get2d4gHeadsetEnable() == 1 ) { + setAudioPcmPlaybackVolume(tmp_vol); + } + return 0; +} + +int CTv::GetAudioMasterVolume() +{ + return mCustomAudioMasterVolume; +} + +int CTv::GetCurAudioMasterVolume() +{ + return mCurAudioMasterVolume; +} + +int CTv::SaveCurAudioMasterVolume(int tmp_vol) +{ + mCurAudioMasterVolume = tmp_vol; + SSMSaveAudioMasterVolume(tmp_vol); + return tmp_vol; +} + +int CTv::LoadCurAudioMasterVolume() +{ + int8_t tmp_ch = 0; + SSMReadAudioMasterVolume(&tmp_ch); + mCurAudioMasterVolume = tmp_ch; + if (mCurAudioMasterVolume < CC_MIN_SOUND_VOL + || mCurAudioMasterVolume > CC_MAX_SOUND_VOL) { + SaveCurAudioMasterVolume (CC_DEF_SOUND_VOL); + } + mCustomAudioMasterVolume = mCurAudioMasterVolume; + + return mCurAudioMasterVolume; +} + +int CTv::SetAudioBalance(int tmp_val) +{ + mCustomAudioBalance = tmp_val; + + int aud_arch_type = GetAudioArchitectureTypeCFG(); + int max_vol = config_get_int(CFG_SECTION_TV, CFG_AUDIO_BALANCE_MAX_VOL, 255); + + mMainVolumeBalanceVal = tmp_val; + + if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_OFF_BOARD_FBC) { + SendCmdToOffBoardFBCExternalDac(AUDIO_CMD_SET_BALANCE, mMainVolumeBalanceVal); + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_CUSTOMER_LIB) { + mCustomerCtrl.SetBlance(mMainVolumeBalanceVal); + } else { + int tmp_ret = 0; + int vol_buf[2] = {0, 0}; + mAudioAlsa.CalculateBalanceVol(max_vol, mMainVolumeBalanceVal, vol_buf); + + tmp_ret |= mAudioAlsa.SetExternalDacChannelVolume(1, vol_buf[0]); + tmp_ret |= mAudioAlsa.SetExternalDacChannelVolume(2, vol_buf[1]); + } + return 0; +} + +int CTv::GetAudioBalance() +{ + return mCustomAudioBalance; +} + +int CTv::GetCurAudioBalance() +{ + return mCurAudioBalance; +} + +int CTv::SaveCurAudioBalance(int tmp_val) +{ + mCurAudioBalance = tmp_val; + SSMSaveAudioBalanceVal(tmp_val); + return tmp_val; +} + +int CTv::LoadCurAudioBalance() +{ + int8_t tmp_ch = 0; + SSMReadAudioBalanceVal(&tmp_ch); + mCurAudioBalance = tmp_ch; + if (mCurAudioBalance < CC_MIN_SOUND_BALANCE_VAL + || mCurAudioBalance > CC_MAX_SOUND_BALANCE_VAL) { + SaveCurAudioBalance (CC_DEF_SOUND_BALANCE_VAL); + } + + mCustomAudioBalance = mCurAudioBalance; + + return mCurAudioBalance; +} + +int CTv::SetAudioVolumeCompensationVal(int tmp_vol_comp_val) +{ + mVolumeCompensationVal = tmp_vol_comp_val; + LOGD("%s, new vol comp value = %d.\n", __FUNCTION__, tmp_vol_comp_val); + return mVolumeCompensationVal; +} + +int CTv::SetAudioSupperBassVolume(int tmp_vol) +{ + mCustomAudioSupperBassVolume = tmp_vol; + + int aud_arch_type = GetAudioArchitectureTypeCFG(); + int tmp_ret = 0; + + if (aud_arch_type == CC_DAC_G9TV_INTERNAL_DAC) { + return 0; + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_ON_BOARD) { + int digit_vol = 0; + int vol_gain_val = 0; + + digit_vol = mAudioAlsa.TransVolumeBarVolToDigitalVol(mAudioAlsa.GetMainVolDigitLutBuf(), tmp_vol); + + vol_gain_val = mAudioAlsa.GetSupperBassVolumeGain(); + digit_vol += vol_gain_val; + if (digit_vol < CC_MIN_DAC_SUB_WOOFER_VOLUME) { + digit_vol = CC_MIN_DAC_SUB_WOOFER_VOLUME; + } else if (digit_vol > CC_MAX_DAC_SUB_WOOFER_VOLUME) { + digit_vol = CC_MAX_DAC_SUB_WOOFER_VOLUME; + } + + tmp_ret = mAudioAlsa.SetExternalDacChannelVolume(3, digit_vol); + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_OFF_BOARD_FBC) { + tmp_ret = SendCmdToOffBoardFBCExternalDac(AUDIO_CMD_SET_SUBCHANNEL_VOLUME, tmp_vol); + } + + return tmp_ret; +} + +int CTv::GetAudioSupperBassVolume() +{ + return mCustomAudioSupperBassVolume; +} + +int CTv::GetCurAudioSupperBassVolume() +{ + return mCurAudioSupperBassVolume; +} + +int CTv::SaveCurAudioSupperBassVolume(int tmp_vol) +{ + mCurAudioSupperBassVolume = tmp_vol; + SSMSaveAudioSupperBassVolume(tmp_vol); + + return tmp_vol; +} + +int CTv::LoadCurAudioSupperBassVolume() +{ + int8_t tmp_ch = 0; + SSMReadAudioSupperBassVolume(&tmp_ch); + mCurAudioSupperBassVolume = tmp_ch; + if (mCurAudioSupperBassVolume < CC_MIN_SUPPERBASS_VOL + || mCurAudioSupperBassVolume > CC_MAX_SUPPERBASS_VOL) { + SaveCurAudioSupperBassVolume (CC_DEF_SUPPERBASS_VOL); + } + mCustomAudioSupperBassVolume = mCurAudioSupperBassVolume; + + return mCurAudioSupperBassVolume; +} + +int CTv::SetAudioSupperBassSwitch(int tmp_val) +{ + mCustomAudioSupperBassSwitch = tmp_val; + + if (GetAudioSupperBassSwitch() == CC_SWITCH_OFF) { + return SetAudioSupperBassVolume(CC_MIN_SUPPERBASS_VOL); + } + + return SetAudioSupperBassVolume(GetAudioSupperBassVolume()); +} + +int CTv::GetAudioSupperBassSwitch() +{ + if (GetAudioSupperBassSwitchDisableCFG() != 0) { + return CC_SWITCH_ON; + } + + return mCustomAudioSupperBassSwitch; +} + +int CTv::GetCurAudioSupperBassSwitch() +{ + if (GetAudioSupperBassSwitchDisableCFG() != 0) { + return CC_SWITCH_ON; + } + + return mCurAudioSupperBassSwitch; +} + +int CTv::SaveCurAudioSupperBassSwitch(int tmp_val) +{ + mCurAudioSupperBassSwitch = tmp_val; + SSMSaveAudioSupperBassSwitch(tmp_val); + SetSupperBassSRSSpeakerSize(); + return tmp_val; +} + +int CTv::LoadCurAudioSupperBassSwitch() +{ + int8_t tmp_ch = 0; + SSMReadAudioSupperBassSwitch(&tmp_ch); + mCurAudioSupperBassSwitch = tmp_ch; + if (mCurAudioSupperBassSwitch != CC_SWITCH_ON + && mCurAudioSupperBassSwitch != CC_SWITCH_OFF) { + SaveCurAudioSupperBassSwitch (CC_SWITCH_OFF); + } + mCustomAudioSupperBassSwitch = mCurAudioSupperBassSwitch; + + return mCurAudioSupperBassSwitch; +} + +void CTv::SetSupperBassSRSSpeakerSize() +{ + int tmp_speakersize = -1; + + if (GetAudioSrsTruBass() == CC_SWITCH_ON) { + tmp_speakersize = GetAudioSRSSupperBassTrubassSpeakerSizeCfg(); + if (tmp_speakersize >= 0) { + mAudioEffect.SetSrsTrubassSpeakerSize(tmp_speakersize); + } + } +} + +int CTv::SetAudioSRSSurround(int tmp_val) +{ + mCustomAudioSRSSurround = tmp_val; + RefreshSrsEffectAndDacGain(); + return 0; +} + +int CTv::GetAudioSRSSurround() +{ + return mCustomAudioSRSSurround; +} + +int CTv::GetCurAudioSRSSurround() +{ + return mCurAudioSRSSurround; +} + +int CTv::SaveCurAudioSrsSurround(int tmp_val) +{ + mCurAudioSRSSurround = tmp_val; + SSMSaveAudioSRSSurroundSwitch(tmp_val); + return tmp_val; +} + +int CTv::LoadCurAudioSrsSurround() +{ + int8_t tmp_ch = 0; + + SSMReadAudioSRSSurroundSwitch(&tmp_ch); + mCurAudioSRSSurround = tmp_ch; + if (mCurAudioSRSSurround != CC_SWITCH_ON + && mCurAudioSRSSurround != CC_SWITCH_OFF) { + SaveCurAudioSrsSurround (CC_SWITCH_OFF); + } + mCustomAudioSRSSurround = mCurAudioSRSSurround; + + return mCurAudioSRSSurround; +} + +int CTv::SetAudioSrsDialogClarity(int tmp_val) +{ + mCustomAudioSrsDialogClarity = tmp_val; + RefreshSrsEffectAndDacGain(); + return 0; +} + +int CTv::GetAudioSrsDialogClarity() +{ + return mCustomAudioSrsDialogClarity; +} + +int CTv::GetCurAudioSrsDialogClarity() +{ + return mCurAudioSrsDialogClarity; +} + +int CTv::SaveCurAudioSrsDialogClarity(int tmp_val) +{ + mCurAudioSrsDialogClarity = tmp_val; + SSMSaveAudioSRSDialogClaritySwitch(tmp_val); + return tmp_val; +} + +int CTv::LoadCurAudioSrsDialogClarity() +{ + int8_t tmp_ch = 0; + + SSMReadAudioSRSDialogClaritySwitch(&tmp_ch); + mCurAudioSrsDialogClarity = tmp_ch; + if (mCurAudioSrsDialogClarity != CC_SWITCH_ON + && mCurAudioSrsDialogClarity != CC_SWITCH_OFF) { + SaveCurAudioSrsDialogClarity (CC_SWITCH_OFF); + } + mCustomAudioSrsDialogClarity = mCurAudioSrsDialogClarity; + + return mCurAudioSrsDialogClarity; +} + +int CTv::SetAudioSrsTruBass(int tmp_val) +{ + mCustomAudioSrsTruBass = tmp_val; + RefreshSrsEffectAndDacGain(); + return 0; +} + +int CTv::GetAudioSrsTruBass() +{ + return mCustomAudioSrsTruBass; +} + +int CTv::GetCurAudioSrsTruBass() +{ + return mCurAudioSrsTruBass; +} + +int CTv::SaveCurAudioSrsTruBass(int tmp_val) +{ + mCurAudioSrsTruBass = tmp_val; + SSMSaveAudioSRSTruBassSwitch(tmp_val); + return tmp_val; +} + +int CTv::LoadCurAudioSrsTruBass() +{ + int8_t tmp_ch = 0; + + SSMReadAudioSRSTruBassSwitch(&tmp_ch); + mCurAudioSrsTruBass = tmp_ch; + if (mCurAudioSrsTruBass != CC_SWITCH_ON + && mCurAudioSrsTruBass != CC_SWITCH_OFF) { + SaveCurAudioSrsTruBass (CC_SWITCH_OFF); + } + mCustomAudioSrsTruBass = mCurAudioSrsTruBass; + + return mCurAudioSrsTruBass; +} + +void CTv::RefreshSrsEffectAndDacGain() +{ + int tmp_gain_val = 0; + int surround_switch = CC_SWITCH_OFF; + int trubass_switch = CC_SWITCH_OFF; + int dialogclarity_switch = CC_SWITCH_OFF; + trubass_switch = GetAudioSrsTruBass(); + dialogclarity_switch = GetAudioSrsDialogClarity(); + surround_switch = GetAudioSRSSurround(); + + if (GetAudioSRSSourroundEnableCFG() == 0) { + return; + } + + if (surround_switch == CC_SWITCH_ON) { + mAudioEffect.SetSrsSurroundSwitch(CC_SWITCH_ON); + tmp_gain_val = GetAudioSRSGainCfg(CFG_AUDIO_SRS_SOURROUND_GAIN, 50); + mAudioEffect.SetSrsSurroundGain(tmp_gain_val); + + int input_gain_val = GetAudioSRSGainCfg(CFG_AUDIO_SRS_INPUT_GAIN, 50); + int out_gain_val = GetAudioSRSGainCfg(CFG_AUDIO_SRS_OUTPUT_GAIN, 50); + mAudioEffect.SetSrsInputOutputGain(input_gain_val, out_gain_val); + + if (trubass_switch == CC_SWITCH_ON + && dialogclarity_switch == CC_SWITCH_OFF) { + + mAudioEffect.SetSrsTruBassSwitch (CC_SWITCH_ON); + tmp_gain_val = GetAudioSRSGainCfg(CFG_AUDIO_SRS_TRUBASS_GAIN, 50); + mAudioEffect.SetSrsTruBassGain(tmp_gain_val); + tmp_gain_val = GetAudioSRSGainCfg(CFG_AUDIO_SRS_TRUBASS_SPEAKERSIZE, 2); + mAudioEffect.SetSrsTrubassSpeakerSize(tmp_gain_val); + + mAudioEffect.SetSrsDialogClaritySwitch (CC_SWITCH_OFF); + + } else if (trubass_switch == CC_SWITCH_OFF + && dialogclarity_switch == CC_SWITCH_ON) { + + mAudioEffect.SetSrsDialogClaritySwitch (CC_SWITCH_ON); + tmp_gain_val = GetAudioSRSGainCfg(CFG_AUDIO_SRS_CLARITY_GAIN, 30); + mAudioEffect.SetSrsDialogClarityGain(tmp_gain_val); + tmp_gain_val = GetAudioSRSGainCfg(CFG_AUDIO_SRS_DEFINITION_GAIN, 20); + mAudioEffect.SetSrsDefinitionGain(tmp_gain_val); + + mAudioEffect.SetSrsTruBassSwitch (CC_SWITCH_OFF); + + } else if (trubass_switch == CC_SWITCH_ON + && dialogclarity_switch == CC_SWITCH_ON) { + + mAudioEffect.SetSrsTruBassSwitch (CC_SWITCH_ON); + tmp_gain_val = GetAudioSRSGainCfg(CFG_AUDIO_SRS_TRUBASS_GAIN, 50); + mAudioEffect.SetSrsTruBassGain(tmp_gain_val); + tmp_gain_val = GetAudioSRSGainCfg(CFG_AUDIO_SRS_TRUBASS_SPEAKERSIZE, 2); + mAudioEffect.SetSrsTrubassSpeakerSize(tmp_gain_val); + + mAudioEffect.SetSrsDialogClaritySwitch(CC_SWITCH_ON); + tmp_gain_val = GetAudioSRSGainCfg(CFG_AUDIO_SRS_CLARITY_GAIN, 30); + mAudioEffect.SetSrsDialogClarityGain(tmp_gain_val); + tmp_gain_val = GetAudioSRSGainCfg(CFG_AUDIO_SRS_DEFINITION_GAIN, 20); + mAudioEffect.SetSrsDefinitionGain(tmp_gain_val); + + } else if (trubass_switch == CC_SWITCH_OFF + && dialogclarity_switch == CC_SWITCH_OFF) { + mAudioEffect.SetSrsTruBassSwitch (CC_SWITCH_OFF); + mAudioEffect.SetSrsDialogClaritySwitch(CC_SWITCH_OFF); + } + SetSupperBassSRSSpeakerSize(); + } else { + mAudioEffect.SetSrsSurroundSwitch (CC_SWITCH_OFF); + mAudioEffect.SetSrsTruBassSwitch(CC_SWITCH_OFF); + mAudioEffect.SetSrsDialogClaritySwitch(CC_SWITCH_OFF); + } + //Refesh DAC gain + int main_gain_val = 0; + if (surround_switch == CC_SWITCH_ON) { + main_gain_val = GetAudioEffectAmplifierGainCfg(CFG_AUDIO_SRS_SOURROUND_MASTER_GAIN, 6, 24); + if (dialogclarity_switch == CC_SWITCH_ON + && trubass_switch == CC_SWITCH_OFF) { + main_gain_val = GetAudioEffectAmplifierGainCfg(CFG_AUDIO_SRS_CLARITY_MASTER_GAIN, 6, 24); + } else if (dialogclarity_switch == CC_SWITCH_OFF + && trubass_switch == CC_SWITCH_ON) { + main_gain_val = GetAudioEffectAmplifierGainCfg(CFG_AUDIO_SRS_TRUBASS_MASTER_GAIN, 6, 24); + } else if (dialogclarity_switch == CC_SWITCH_ON + && trubass_switch == CC_SWITCH_ON) { + main_gain_val = GetAudioEffectAmplifierGainCfg(CFG_AUDIO_SRS_TRUBASS_CLARITY_MASTER_GAIN, 6, 24); + } + } + mAudioAlsa.SetMainVolumeGain(main_gain_val); +} + +int CTv::SetAudioVirtualizer(int enable, int EffectLevel) +{ + config_set_int(CFG_SECTION_TV, CFG_AUDIO_VIRTUAL_ENABLE, enable); + config_set_int(CFG_SECTION_TV, CFG_AUDIO_VIRTUAL_LEVEL, EffectLevel); + return mAudioEffect.SetAudioVirtualizer(enable, EffectLevel); +} + +int CTv::GetAudioVirtualizerEnable() +{ + return config_get_int(CFG_SECTION_TV, CFG_AUDIO_VIRTUAL_ENABLE, 0); +} + +int CTv::GetAudioVirtualizerLevel() +{ + return config_get_int(CFG_SECTION_TV, CFG_AUDIO_VIRTUAL_LEVEL, 100); +} + +int CTv::LoadAudioVirtualizer() +{ + return SetAudioVirtualizer(GetAudioVirtualizerEnable(), GetAudioVirtualizerLevel()); +} + +int CTv::SetAudioBassVolume(int tmp_vol) { + int nMinBassVol = 0, nMaxBassVol = 0; + + nMinBassVol = GetBassUIMinGainVal(); + nMaxBassVol = GetBassUIMaxGainVal(); + + if (tmp_vol < nMinBassVol || tmp_vol > nMaxBassVol) { + tmp_vol = (nMaxBassVol + nMinBassVol) / 2; + } + + mCustomAudioBassVolume = tmp_vol; + tmp_vol = MappingTrebleBassAndEqualizer(GetAudioBassVolume(), 0, + nMinBassVol, nMaxBassVol); + return SetSpecialIndexEQGain(CC_EQ_BASS_IND, tmp_vol); +} + +int CTv::GetAudioBassVolume() +{ + return mCustomAudioBassVolume; +} + +int CTv::GetCurAudioBassVolume() +{ + return mCurAudioBassVolume; +} + +int CTv::SaveCurAudioBassVolume(int tmp_vol) +{ + int nMinBassVol = 0, nMaxBassVol = 0; + + nMinBassVol = GetBassUIMinGainVal(); + nMaxBassVol = GetBassUIMaxGainVal(); + + if (tmp_vol < nMinBassVol || tmp_vol > nMaxBassVol) { + tmp_vol = (nMaxBassVol + nMinBassVol) / 2; + } + + RealSaveCurAudioBassVolume(tmp_vol, 1); + + tmp_vol = MappingTrebleBassAndEqualizer(GetCurAudioBassVolume(), 0, + nMinBassVol, nMaxBassVol); + return SaveSpecialIndexEQGain(CC_EQ_BASS_IND, tmp_vol); +} + +int CTv::RealSaveCurAudioBassVolume(int tmp_vol, int sound_mode_judge) +{ + mCurAudioBassVolume = tmp_vol; + SSMSaveAudioBassVolume(tmp_vol); + + if (sound_mode_judge == 1) { + if (GetAudioSoundMode() != CC_SOUND_MODE_USER) { + SaveCurAudioSoundMode (CC_SOUND_MODE_USER); + mCustomAudioSoundMode = mCurAudioSoundMode; + } + } + return mCurAudioBassVolume; +} + +int CTv::LoadCurAudioBassVolume() +{ + int nMinBassVol = 0, nMaxBassVol = 0; + int8_t tmp_ch = 0; + + nMinBassVol = GetBassUIMinGainVal(); + nMaxBassVol = GetBassUIMaxGainVal(); + + SSMReadAudioBassVolume(&tmp_ch); + mCurAudioBassVolume = tmp_ch; + if (mCurAudioBassVolume < nMinBassVol + || mCurAudioBassVolume > nMaxBassVol) { + RealSaveCurAudioBassVolume((nMaxBassVol + nMinBassVol) / 2, 0); + } + + mCustomAudioBassVolume = mCurAudioBassVolume; + return mCurAudioBassVolume; +} + +int CTv::SetAudioTrebleVolume(int tmp_vol) +{ + int nMinTrebleVol = 0, nMaxTrebleVol = 0; + + nMinTrebleVol = GetTrebleUIMinGainVal(); + nMaxTrebleVol = GetTrebleUIMaxGainVal(); + + if (tmp_vol < nMinTrebleVol || tmp_vol > nMaxTrebleVol) { + tmp_vol = (nMaxTrebleVol + nMinTrebleVol) / 2; + } + + mCustomAudioTrebleVolume = tmp_vol; + + tmp_vol = MappingTrebleBassAndEqualizer(GetAudioTrebleVolume(), 0, + nMinTrebleVol, nMaxTrebleVol); + return SetSpecialIndexEQGain(CC_EQ_TREBLE_IND, tmp_vol); +} + +int CTv::GetAudioTrebleVolume() +{ + return mCustomAudioTrebleVolume; +} + +int CTv::GetCurAudioTrebleVolume() +{ + return mCurAudioTrebleVolume; +} + +int CTv::SaveCurAudioTrebleVolume(int tmp_vol) +{ + int nMinTrebleVol = 0, nMaxTrebleVol = 0; + + nMinTrebleVol = GetTrebleUIMinGainVal(); + nMaxTrebleVol = GetTrebleUIMaxGainVal(); + + if (tmp_vol < nMinTrebleVol || tmp_vol > nMaxTrebleVol) { + tmp_vol = (nMaxTrebleVol + nMinTrebleVol) / 2; + } + + RealSaveCurAudioTrebleVolume(tmp_vol, 1); + + tmp_vol = MappingTrebleBassAndEqualizer(GetCurAudioTrebleVolume(), 0, + nMinTrebleVol, nMaxTrebleVol); + return SaveSpecialIndexEQGain(CC_EQ_TREBLE_IND, tmp_vol); +} + +int CTv::RealSaveCurAudioTrebleVolume(int tmp_vol, int sound_mode_judge) +{ + mCurAudioTrebleVolume = tmp_vol; + SSMSaveAudioTrebleVolume(tmp_vol); + + if (sound_mode_judge == 1) { + if (GetAudioSoundMode() != CC_SOUND_MODE_USER) { + SaveCurAudioSoundMode (CC_SOUND_MODE_USER); + mCustomAudioSoundMode = mCurAudioSoundMode; + } + } + + return mCurAudioTrebleVolume; +} + +int CTv::LoadCurAudioTrebleVolume() +{ + int nMinTrebleVol = 0, nMaxTrebleVol = 0; + int8_t tmp_ch = 0; + + nMinTrebleVol = GetTrebleUIMinGainVal(); + nMaxTrebleVol = GetTrebleUIMaxGainVal(); + + SSMReadAudioTrebleVolume(&tmp_ch); + mCurAudioTrebleVolume = tmp_ch; + if (mCurAudioTrebleVolume < nMinTrebleVol + || mCurAudioTrebleVolume > nMaxTrebleVol) { + RealSaveCurAudioTrebleVolume((nMaxTrebleVol + nMinTrebleVol) / 2, 0); + } + + mCustomAudioTrebleVolume = mCurAudioTrebleVolume; + return mCurAudioTrebleVolume; +} + +int CTv::SetAudioSoundMode(int tmp_val) +{ + mCustomAudioSoundMode = tmp_val; + SetSpecialModeEQGain(mCustomAudioSoundMode); + + HandleTrebleBassVolume(); + return 0; +} + +int CTv::GetAudioSoundMode() +{ + return mCustomAudioSoundMode; +} + +int CTv::GetCurAudioSoundMode() +{ + return mCurAudioSoundMode; +} + +int CTv::SaveCurAudioSoundMode(int tmp_val) +{ + mCurAudioSoundMode = tmp_val; + SSMSaveAudioSoundModeVal(tmp_val); + return tmp_val; +} + +int CTv::LoadCurAudioSoundMode() +{ + int8_t tmp_ch = 0; + SSMReadAudioSoundModeVal(&tmp_ch); + mCurAudioSoundMode = tmp_ch; + if (mCurAudioSoundMode < CC_SOUND_MODE_START + || mCurAudioSoundMode > CC_SOUND_MODE_END) { + SaveCurAudioSoundMode (CC_SOUND_MODE_STD); + } + mCustomAudioSoundMode = mCurAudioSoundMode; + return mCurAudioSoundMode; +} + +int CTv::HandleTrebleBassVolume() +{ + int tmp_vol = 0; + int tmpEQGainBuf[128] = { 0 }; + int8_t tmp_ch = 0; + + GetCustomEQGain(tmpEQGainBuf); + + tmp_vol = MappingTrebleBassAndEqualizer(tmpEQGainBuf[CC_EQ_TREBLE_IND], 1, + GetTrebleUIMinGainVal(), GetTrebleUIMaxGainVal()); + mCustomAudioTrebleVolume = tmp_vol; + mCurAudioTrebleVolume = mCustomAudioTrebleVolume; + tmp_ch = mCustomAudioTrebleVolume; + SSMSaveAudioTrebleVolume(tmp_ch); + + tmp_vol = MappingTrebleBassAndEqualizer(tmpEQGainBuf[CC_EQ_BASS_IND], 1, + GetBassUIMinGainVal(), GetBassUIMaxGainVal()); + mCustomAudioBassVolume = tmp_vol; + mCurAudioBassVolume = mCustomAudioBassVolume; + tmp_ch = mCustomAudioBassVolume; + SSMSaveAudioBassVolume(tmp_ch); + return 0; +} + +int CTv::SetAudioWallEffect(int tmp_val) +{ + int tmp_treble_val; + int tmp_type = 0; + + mCustomAudioWallEffect = tmp_val; + + tmp_type = GetAudioWallEffectTypeCfg(); + if (tmp_type == 0) { + SetCustomEQGain(); + } else if (tmp_type == 1) { + int aud_arch_type = GetAudioArchitectureTypeCFG(); + if (aud_arch_type == CC_DAC_G9TV_INTERNAL_DAC) { + return 0; + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_ON_BOARD) { + mAudioAlsa.SetExternalDacEQMode(tmp_val); + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_OFF_BOARD_FBC) { + SendCmdToOffBoardFBCExternalDac(AUDIO_CMD_SET_EQ_MODE, tmp_val); + } + } + return 0; +} + +int CTv::GetAudioWallEffect() +{ + return mCustomAudioWallEffect; +} + +int CTv::GetCurAudioWallEffect() +{ + return mCurAudioWallEffect; +} + +int CTv::SaveCurAudioWallEffect(int tmp_val) +{ + mCurAudioWallEffect = tmp_val; + SSMSaveAudioWallEffectSwitch(tmp_val); + return tmp_val; +} + +int CTv::LoadCurAudioWallEffect() +{ + int8_t tmp_ch = 0; + SSMReadAudioWallEffectSwitch(&tmp_ch); + mCurAudioWallEffect = tmp_ch; + if (mCurAudioWallEffect != CC_SWITCH_ON + && mCurAudioWallEffect != CC_SWITCH_OFF) { + SaveCurAudioWallEffect (CC_SWITCH_OFF); + } + + mCustomAudioWallEffect = mCurAudioWallEffect; + return mCurAudioWallEffect; +} + +int CTv::SetAudioEQMode(int tmp_val) +{ + mCustomAudioEQMode = tmp_val; + return 0; +} + +int CTv::GetAudioEQMode() +{ + return mCustomAudioEQMode; +} + +int CTv::GetCurAudioEQMode() +{ + return mCurAudioEQMode; +} + +int CTv::SaveCurAudioEQMode(int tmp_val) +{ + mCurAudioEQMode = tmp_val; + SSMSaveAudioEQModeVal(tmp_val); + + return tmp_val; +} + +int CTv::LoadCurAudioEQMode() +{ + int8_t tmp_ch = 0; + SSMReadAudioEQModeVal(&tmp_ch); + mCurAudioEQMode = tmp_ch; + if (mCurAudioEQMode < CC_EQ_MODE_START + || mCurAudioEQMode > CC_EQ_MODE_END) { + SaveCurAudioEQMode (CC_EQ_MODE_START); + } + mCustomAudioEQMode = mCurAudioEQMode; + + return mCurAudioEQMode; +} + +int CTv::GetAudioEQRange(int range_buf[]) +{ + range_buf[0] = CC_MIN_EQ_GAIN_VAL; + range_buf[1] = CC_MAX_EQ_GAIN_VAL; + return 0; +} + +int CTv::GetAudioEQBandCount() +{ + return mAudioEffect.GetEQBandCount(); +} + +int CTv::SetAudioEQGain(int gain_buf[]) +{ + return AudioSetEQGain(gain_buf); +} + +int CTv::GetAudioEQGain(int gain_buf[]) +{ + return GetCustomEQGain(gain_buf); +} + +int CTv::GetCurAudioEQGain(int gain_buf[]) +{ + RealReadCurAudioEQGain(gain_buf); + return 0; +} + +int CTv::SaveCurAudioEQGain(int gain_buf[]) +{ + return RealSaveCurAudioEQGain(gain_buf, 1); +} + +int CTv::RealReadCurAudioEQGain(int gain_buf[]) +{ + ArrayCopy(gain_buf, mCurEQGainBuf, GetAudioEQBandCount()); + return 0; +} + +int CTv::RealSaveCurAudioEQGain(int gain_buf[], int sound_mode_judge) +{ + ArrayCopy(mCurEQGainBuf, gain_buf, GetAudioEQBandCount()); + ArrayCopy(mCurEQGainChBuf, gain_buf, GetAudioEQBandCount()); + SSMSaveAudioEQGain(0, GetAudioEQBandCount(), mCurEQGainChBuf); + + if (sound_mode_judge == 1) { + HandleTrebleBassVolume(); + SaveCurAudioSoundMode (CC_SOUND_MODE_USER); + mCustomAudioSoundMode = mCurAudioSoundMode; + } + + return 0; +} + +int CTv::LoadCurAudioEQGain() +{ + SSMReadAudioEQGain(0, GetAudioEQBandCount(), mCurEQGainChBuf); + ArrayCopy(mCurEQGainBuf, mCurEQGainChBuf, GetAudioEQBandCount()); + + for (int i = 0; i < GetAudioEQBandCount(); i++) { + if (mCurEQGainBuf[i] & 0x80) { + mCurEQGainBuf[i] = mCurEQGainBuf[i] - 256; + } + } + return 0; +} + +int CTv::SetAudioEQSwitch(int switch_val) +{ + return mAudioEffect.SetEQSwitch(switch_val); +} + +int CTv::GetBassUIMinGainVal() +{ + return 0; +} + +int CTv::GetBassUIMaxGainVal() +{ + return 100; +} + +int CTv::GetTrebleUIMinGainVal() +{ + return 0; +} + +int CTv::GetTrebleUIMaxGainVal() +{ + return 100; +} + +int CTv::MappingLine(int map_val, int src_min, int src_max, int dst_min, int dst_max) +{ + if (dst_min < 0) { + return (map_val - (src_max + src_min) / 2) * (dst_max - dst_min) + / (src_max - src_min); + } else { + return (map_val - src_min) * (dst_max - dst_min) / (src_max - src_min); + } +} + +int CTv::MappingTrebleBassAndEqualizer(int tmp_vol, int direct, int tb_min, int tb_max) +{ + int tmp_ret = 0; + + if (direct == 0) { + tmp_ret = MappingLine(tmp_vol, tb_min, tb_max, CC_EQ_DEF_UI_MIN_GAIN, CC_EQ_DEF_UI_MAX_GAIN); + } else { + tmp_ret = MappingLine(tmp_vol, CC_EQ_DEF_UI_MIN_GAIN, CC_EQ_DEF_UI_MAX_GAIN, tb_min, tb_max); + } + + LOGD("%s, tmp_vol = %d, direct = %d, tmp_ret = %d\n", __FUNCTION__, tmp_vol, + direct, tmp_ret); + + return tmp_ret; +} + +int CTv::MappingEQGain(int src_gain_buf[], int dst_gain_buf[], int direct) +{ + int i = 0; + int nMinUIVal = 0, nMaxUIVal = 0, nMinVal = 0, nMaxVal = 0; + + nMinUIVal = CC_EQ_DEF_UI_MIN_GAIN; + nMaxUIVal = CC_EQ_DEF_UI_MAX_GAIN; + nMinVal = CC_MIN_EQ_GAIN_VAL; + nMaxVal = CC_MAX_EQ_GAIN_VAL; + + if (nMinUIVal >= nMinVal && nMaxUIVal <= nMaxVal) { + for (i = 0; i < GetAudioEQBandCount(); i++) { + dst_gain_buf[i] = src_gain_buf[i]; + } + } else { + for (i = 0; i < GetAudioEQBandCount(); i++) { + if (direct == 0) { + dst_gain_buf[i] = MappingLine(src_gain_buf[i], nMinUIVal, + nMaxUIVal, nMinVal, nMaxVal); + } else { + dst_gain_buf[i] = MappingLine(src_gain_buf[i], nMinVal, nMaxVal, + nMinUIVal, nMaxUIVal); + } + } + } + return 0; +} + +int CTv::RestoreToAudioDefEQGain(int gain_buf[]) +{ + int i = 0; + + for (i = 0; i < GetAudioEQBandCount(); i++) { + gain_buf[i] = (CC_EQ_DEF_UI_MAX_GAIN + CC_EQ_DEF_UI_MIN_GAIN) / 2; + } + + ArrayCopy(mCurEQGainBuf, gain_buf, GetAudioEQBandCount()); + ArrayCopy(mCurEQGainChBuf, gain_buf, GetAudioEQBandCount()); + SSMSaveAudioEQGain(0, GetAudioEQBandCount(), mCurEQGainChBuf); + + HandleTrebleBassVolume(); + SaveCurAudioSoundMode (CC_SOUND_MODE_STD); + mCustomAudioSoundMode = mCurAudioSoundMode; + return 0; +} + +int CTv::GetCustomEQGain(int gain_buf[]) +{ + ArrayCopy(gain_buf, mCustomEQGainBuf, GetAudioEQBandCount()); + return 0; +} + +int CTv::SetCustomEQGain() +{ + int tmpEQGainBuf[128] = { 0 }; + + if (MappingEQGain(mCustomEQGainBuf, tmpEQGainBuf, 0) < 0) { + return -1; + } + + return RealSetEQGain(tmpEQGainBuf); +} + +int CTv::AudioSetEQGain(int gain_buf[]) +{ + int tmpEQGainBuf[128] = { 0 }; + + ArrayCopy(mCustomEQGainBuf, gain_buf, GetAudioEQBandCount()); + + if (MappingEQGain(mCustomEQGainBuf, tmpEQGainBuf, 0) < 0) { + return -1; + } + + return RealSetEQGain(tmpEQGainBuf); +} + +int CTv::handleEQGainBeforeSet(int src_buf[], int dst_buf[]) +{ + int i = 0, nMinGain, nMaxGain; + + nMinGain = CC_MIN_EQ_GAIN_VAL; + nMaxGain = CC_MAX_EQ_GAIN_VAL; + + if (GetAudioWallEffect() == CC_SWITCH_ON && GetAudioWallEffectTypeCfg() == 0) { + for (i = 0; i < GetAudioEQBandCount(); i++) { + dst_buf[i] = WALL_EFFECT_VALUE[i] + src_buf[i]; + + if (dst_buf[i] < nMinGain) { + dst_buf[i] = nMinGain; + } + + if (dst_buf[i] > nMaxGain) { + dst_buf[i] = nMaxGain; + } + } + } else { + for (i = 0; i < GetAudioEQBandCount(); i++) { + dst_buf[i] = src_buf[i]; + } + } + + return 0; +} + +int CTv::RealSetEQGain(int gain_buf[]) +{ + if (GetAudioWallEffect() == CC_SWITCH_ON && GetAudioWallEffectTypeCfg() == 0) { + for (int i = 0; i < GetAudioEQBandCount(); i++) { + gain_buf[i] = WALL_EFFECT_VALUE[i] + gain_buf[i]; + + if (gain_buf[i] < CC_MIN_EQ_GAIN_VAL) { + gain_buf[i] = CC_MIN_EQ_GAIN_VAL; + } + + if (gain_buf[i] > CC_MAX_EQ_GAIN_VAL) { + gain_buf[i] = CC_MAX_EQ_GAIN_VAL; + } + } + } + + mAudioEffect.SetEQValue(gain_buf); + return 0; +} + +int CTv::SetAtvInGain(int gain_val) +{ + char set_str[32] = {0}; + + sprintf ( set_str, "audio_gain_set %x", gain_val ); + return tvWriteSysfs ( SYS_ATV_DEMOD_DEBUG, set_str ); +} + +int CTv::SetSpecialModeEQGain(int tmp_val) +{ + int tmpEQPresetBufPtr[24]; + if (GetAudioEQPresetBufferPtr(tmpEQPresetBufPtr) != 0) { + GetDefault_EQGain_Table(tmpEQPresetBufPtr); + } + int tmpEQGainBuf[128] = { 0 }; + + if (tmp_val == CC_SOUND_MODE_USER) { + RealReadCurAudioEQGain(tmpEQGainBuf); + } else { + ArrayCopy(tmpEQGainBuf, + tmpEQPresetBufPtr + tmp_val * GetAudioEQBandCount(), + GetAudioEQBandCount()); + } + + AudioSetEQGain(tmpEQGainBuf); + return tmp_val; +} + +int CTv::SetSpecialIndexEQGain(int buf_index, int w_val) +{ + int tmpEQGainBuf[128] = { 0 }; + + if (buf_index >= 0 && buf_index < GetAudioEQBandCount()) { + RealReadCurAudioEQGain(tmpEQGainBuf); + tmpEQGainBuf[buf_index] = w_val; + + return AudioSetEQGain(tmpEQGainBuf); + } + return -1; +} + +int CTv::SaveSpecialIndexEQGain(int buf_index, int w_val) +{ + int tmpEQGainBuf[128] = { 0 }; + + if (buf_index >= 0 && buf_index < GetAudioEQBandCount()) { + RealReadCurAudioEQGain(tmpEQGainBuf); + tmpEQGainBuf[buf_index] = w_val; + + return RealSaveCurAudioEQGain(tmpEQGainBuf, 0); + } + + return 0; +} + +// amAudio +int CTv::OpenAmAudio(unsigned int sr, int input_device, int output_device) +{ + LOGD("OpenAmAudio input_device = %d", input_device); + return amAudioOpen(sr, input_device, output_device); +} + +int CTv::CloseAmAudio(void) +{ + return amAudioClose(); +} + +int CTv::setAmAudioPreMute(int mute) +{ + int ret = -1; + if (m_source_input == SOURCE_DTV) { + ret = mAv.AudioSetPreMute(mute); + } else { + ret = amAudioSetPreMute(mute); + } + return ret; +} + +int CTv::getAmAudioPreMute() +{ + unsigned int mute = -1; + if (m_source_input == SOURCE_DTV) { + mAv.AudioGetPreMute(&mute); + } else { + amAudioGetPreMute(&mute); + } + return mute; +} + +int CTv::setAmAudioVolume(float volume) +{ + float gain = 0; + gain = 20 * log10f(volume / 100); + + return setAmAudioPreGain(gain); +} + +float CTv::getAmAudioVolume() +{ + float volume = getAmAudioPreGain(); + volume = powf(10, volume / 20); + + return volume * 100; +} + +int CTv::saveAmAudioVolume(int volume, int source) +{ + return SSMSaveAmAudioVal(volume, source); +} + +int CTv::getSaveAmAudioVolume(int source) +{ + int volume = 0; + SSMReadAmAudioVal(&volume, source); + + return volume; +} + +int CTv::setAmAudioPreGain(float pre_gain) +{ + int ret = -1; + if (m_source_input == SOURCE_DTV) { + ret = mAv.AudioSetPreGain(pre_gain); + } else { + ret = amAudioSetPreGain(pre_gain); + } + return ret; +} + +float CTv::getAmAudioPreGain() +{ + float pre_gain = -1; + if (m_source_input == SOURCE_DTV) { + mAv.AudioGetPreGain(&pre_gain); + } else { + amAudioGetPreGain(&pre_gain); + } + return pre_gain; +} + +int CTv::SetAmAudioInputSr(unsigned int sr, int output_device) +{ + LOGD("SetAmAudioInputSr"); + return amAudioSetInputSr(sr, CC_IN_USE_SPDIF_DEVICE, output_device); +} + +int CTv::SetAmAudioOutputMode(int mode) +{ + if (mode != CC_AMAUDIO_OUT_MODE_DIRECT && mode != CC_AMAUDIO_OUT_MODE_INTER_MIX + && mode != CC_AMAUDIO_OUT_MODE_DIRECT_MIX) { + LOGE("[ctv]%s, mode error, it should be mix or direct!\n", __FUNCTION__); + return -1; + } + + return amAudioSetOutputMode(mode); +} + +int CTv::SetAmAudioMusicGain(int gain) +{ + return amAudioSetMusicGain(gain); +} + +int CTv::SetAmAudioLeftGain(int gain) +{ + return amAudioSetLeftGain(gain); +} + +int CTv::SetAmAudioRightGain(int gain) +{ + return amAudioSetRightGain(gain); +} + +int CTv::SetAudioDumpDataFlag(int tmp_flag) +{ + return amAudioSetDumpDataFlag(tmp_flag); +} + +int CTv::GetAudioDumpDataFlag() +{ + return amAudioGetDumpDataFlag(); +} + +void CTv::AudioSetVolumeDigitLUTBuf(int lut_table_index, int *MainVolLutBuf) +{ + int tmpDefDigitLutBuf[CC_LUT_BUF_SIZE] = { 0 }; + mAudioAlsa.SetMainVolDigitLutBuf(MainVolLutBuf); + + GetAudioAmpSupbassvolBuf(lut_table_index, tmpDefDigitLutBuf); + mAudioAlsa.SetSupperBassVolDigitLutBuf(tmpDefDigitLutBuf); +} + +int CTv::InitTvAudio(int sr, int input_device) +{ + OpenAmAudio(sr, input_device, CC_OUT_USE_AMAUDIO); + + RefreshSrsEffectAndDacGain(); + SetCustomEQGain(); + LoadAudioVirtualizer(); + return 0; +} + +int CTv::UnInitTvAudio() +{ + return CloseAmAudio(); +} + +int CTv::AudioChangeSampleRate(int sr) +{ + sr = HanldeAudioInputSr(sr); + + if (SetAmAudioInputSr(sr, CC_OUT_USE_AMAUDIO) != 0) { + return -1; + } + + RefreshSrsEffectAndDacGain(); + SetCustomEQGain(); + return 0; +} + +int CTv::AudioSetAudioInSource(int audio_src_in_type) +{ + return mAudioAlsa.SetAudioInSource(audio_src_in_type); +} + +int CTv::AudioSetAudioSourceType(int source_type) +{ + int aud_arch_type = GetAudioArchitectureTypeCFG(); + + if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_ON_BOARD) { + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_OFF_BOARD_FBC) { + SendCmdToOffBoardFBCExternalDac(AUDIO_CMD_SET_SOURCE, source_type); + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_CUSTOMER_LIB) { + mCustomerCtrl.SetSource(source_type); + } else if (aud_arch_type == CC_DAC_G9TV_EXTERNAL_DAC_DIGITAL) { + } + return 0; +} + +int CTv::AudioLineInSelectChannel(int audio_channel) +{ + LOGD ("%s, audio_channel = %d", __FUNCTION__, audio_channel); + mAudioAlsa.SetInternalDacLineInSelectChannel(audio_channel); + return 0; +} + +int CTv::AudioSetLineInCaptureVolume(int l_vol, int r_vol) +{ + mAudioAlsa.SetInternalDacLineInCaptureVolume(l_vol, r_vol); + return 0; +} + +int CTv::openTvAudio() +{ + int tmp_val = 0; + + LOGD("%s, entering...\n", __FUNCTION__); + UnInitSetTvAudioCard(); + + tmp_val = GetAudioDumpDataEnableFlagCfg(); + SetAudioDumpDataFlag(tmp_val); + + tmp_val = GetAudioInternalDacPGAInGain_Cfg(); + mAudioAlsa.SetAudioInternalDacPGAInGain(tmp_val, tmp_val); + + mAudioAlsa.SetMixerBypassSwitch (CC_SWITCH_OFF); + mAudioAlsa.SetMixerDacSwitch (CC_SWITCH_ON); + + LoadAudioCtl(); + + RefreshSrsEffectAndDacGain(); + InitSetAudioCtl(); + return 0; +} + +void CTv::LoadAudioCtl() +{ + // Get Current Audio Volume + LoadCurAudioMasterVolume(); + + // Get Current Audio Balance + LoadCurAudioBalance(); + + // Get Current Supper Bass Switch + LoadCurAudioSupperBassSwitch(); + + // Get Current Supper Bass Volume + LoadCurAudioSupperBassVolume(); + + // Get Current SRSSurround + LoadCurAudioSrsSurround(); + + // Get Current SRS DialogClarity + LoadCurAudioSrsDialogClarity(); + + // Get Current SRS TruBass + LoadCurAudioSrsTruBass(); + + // Get Current Audio Sound Mode + LoadCurAudioSoundMode(); + + // Get Current Audio Bass and Treble + LoadCurAudioBassVolume(); + LoadCurAudioTrebleVolume(); + + // Get Current Wall Effect + LoadCurAudioWallEffect(); + + // Get Current spdif switch + LoadCurAudioSPDIFSwitch(); + + // Get Current spdif mode + LoadCurAudioSPDIFMode(); + + // Get Current EQ mode + LoadCurAudioEQMode(); + + // Get Current EQ Gain + LoadCurAudioEQGain(); + + //Get Current Virtual Effect status + LoadAudioVirtualizer(); +} + +bool CTv::isBootvideoStopped() { + return mBootvideoStatusDetectThread == NULL + || mBootvideoStatusDetectThread->isBootvideoStopped(); +} + +void CTv::InitSetAudioCtl() +{ + // Set Current Audio balance value + SetAudioBalance(GetAudioBalance()); + + // Set Current Audio Volume + SetAudioMasterVolume(GetAudioMasterVolume()); + + // Set Current Supper Bass Volume + SetAudioSupperBassVolume(GetAudioSupperBassVolume()); + + // Set Current Audio Sound Mode + SetAudioSoundMode(GetAudioSoundMode()); + + // Set Current Audio SPDIF Switch + SetAudioSPDIFSwitch(GetCurAudioSPDIFSwitch()); + + // Set Current Audio SPDIF mode + SetAudioSPDIFMode(GetCurAudioSPDIFMode()); +} + +int CTv::SetADC_Digital_Capture_Volume(int value) +{ + return mAudioAlsa.SetAudioInternalDacADCDigitalCaptureVolume( value, value); +} + +int CTv::SetPGA_IN_Value(int value) +{ + return mAudioAlsa.SetAudioInternalDacPGAInGain( value, value); +} + +int CTv::SetDAC_Digital_PlayBack_Volume(int value) +{ + return mAudioAlsa.SetAudioInternalDacDACDigitalPlayBackVolume( value, value); +} + +int CTv::setAudioPcmPlaybackVolume(int val) +{ + int pcm_volume = 0; + pcm_volume = val / 2; + if (pcm_volume > 24) pcm_volume = 24; + //return SetAudioPcmPlaybackVolume(pcm_volume); + return 0; +} + +int CTv::HanldeAudioInputSr(unsigned int sr) +{ + int tmp_cfg = 0; + + tmp_cfg = GetAudioResampleTypeCFG(); + if (tmp_cfg & CC_AUD_RESAMPLE_TYPE_HW) { + mAudioAlsa.SetHardwareResample(sr); + } else { + mAudioAlsa.SetHardwareResample(-1); + } + + if (!(tmp_cfg & CC_AUD_RESAMPLE_TYPE_SW)) { + sr = 48000; + } + + return sr; +} + +int CTv::AudioSSMRestoreDefaultSetting() +{ + int i = 0, tmp_val = 0; + int nMinUIVol = 0, nMaxUIVol = 0; + int *tmp_ptr = NULL; + int tmpEQGainBuf[128] = { 0 }; + unsigned char tmp_buf[CC_NO_LINE_POINTS_MAX_CNT] = { 0 }; + + // Save Current Audio Volume + SaveCurAudioMasterVolume (CC_DEF_SOUND_VOL); + + // Save Current Audio Balance + SaveCurAudioBalance (CC_DEF_SOUND_BALANCE_VAL); + + // Save Current Supper Bass Switch + SaveCurAudioSupperBassSwitch (CC_SWITCH_OFF); + + // Save Current Supper Bass Volume + SaveCurAudioSupperBassVolume (CC_DEF_SUPPERBASS_VOL); + + // Save Current SRSSurround + SaveCurAudioSrsSurround(CC_SWITCH_OFF); + + // Save Current SRS DialogClarity + SaveCurAudioSrsDialogClarity(CC_SWITCH_OFF); + + // Save Current SRS TruBass + SaveCurAudioSrsTruBass(CC_SWITCH_OFF); + + // Save Current Audio Sound Mode + SaveCurAudioSoundMode (CC_SOUND_MODE_STD); + + // Save Current Wall Effect + SaveCurAudioWallEffect(CC_SWITCH_OFF); + + // Save Current spdif switch + SaveCurAudioSPDIFSwitch (CC_SWITCH_ON); + + // Save Current spdif mode + SaveCurAudioSPDIFMode (CC_SPDIF_MODE_PCM); + + // Save Current avout and spidif mute state + SSMSaveAudioSPIDFMuteVal(CC_AUDIO_MUTE); + SSMSaveAudioAVOutMuteVal(CC_AUDIO_MUTE); + + // Save Current EQ mode + SaveCurAudioEQMode (CC_EQ_MODE_NOMAL); + + // Save Current EQ Gain + RestoreToAudioDefEQGain(tmpEQGainBuf); + + // Save Current Audio Bass and Treble + nMinUIVol = GetBassUIMinGainVal(); + nMaxUIVol = GetBassUIMaxGainVal(); + RealSaveCurAudioBassVolume((nMinUIVol + nMaxUIVol) / 2, 0); + + nMinUIVol = GetTrebleUIMinGainVal(); + nMaxUIVol = GetTrebleUIMaxGainVal(); + RealSaveCurAudioTrebleVolume((nMinUIVol + nMaxUIVol) / 2, 0); + return 0; +} + +int CTv::InitSetTvAudioCard() +{ + int captureIdx = -1; + char buf[32] = { 0 }; + char propValue[PROPERTY_VALUE_MAX]; + +#ifndef BOARD_ALSA_AUDIO_TINY + snd_card_refresh_info(); +#endif + + if (GetTvAudioCardNeedSet()) { + int totleNum = 0; + char cardName[64] = { 0 }; + + GetTvAudioCardName(cardName); + /* + memset(propValue, '\0', PROPERTY_VALUE_MAX); + property_get(PROP_AUDIO_CARD_NUM, propValue, "0"); + + totleNum = strtoul(propValue, NULL, 10); + LOGD("%s, totle number = %d\n", __FUNCTION__, totleNum); + */ + totleNum = 8; + + for (int i = 0; i < totleNum; i++) { + sprintf(buf, "snd.card.%d.name", i); + memset(propValue, '\0', PROPERTY_VALUE_MAX); + property_get(buf, propValue, "null"); + + LOGD("%s, key string \"%s\", value string \"%s\".\n", __FUNCTION__, buf, propValue); + if (strcmp(propValue, cardName) == 0) { + captureIdx = i; + break; + } + } + } + + sprintf(buf, "%d", captureIdx); + property_set(PROP_DEF_CAPTURE_NAME, buf); + LOGD("%s, set \"%s\" as \"%s\".\n", __FUNCTION__, PROP_DEF_CAPTURE_NAME, buf); + return 0; +} + +int CTv::UnInitSetTvAudioCard() +{ +#ifndef BOARD_ALSA_AUDIO_TINY + snd_card_refresh_info(); +#endif + property_set(PROP_DEF_CAPTURE_NAME, "-1"); + LOGD("%s, set [%s]:[-1]\n", __FUNCTION__, PROP_DEF_CAPTURE_NAME); + return 0; +} + +int CTv::SetSPDIFMode(int mode_val) +{ + tvWriteSysfs(SYS_SPDIF_MODE_DEV_PATH, mode_val); + return 0; +} + +int CTv::SwitchAVOutBypass(int sw) +{ + if (sw == 0 ) { + mAudioAlsa.SetMixerBypassSwitch ( CC_SWITCH_OFF ); + mAudioAlsa.SetMixerDacSwitch ( CC_SWITCH_ON ); + } else { + mAudioAlsa.SetMixerBypassSwitch ( CC_SWITCH_ON ); + mAudioAlsa.SetMixerDacSwitch ( CC_SWITCH_OFF ); + } + return 0; +} + +int CTv::SetAudioSwitchIO(int value) +{ + return mAudioAlsa.SetAudioSwitchIO( value); +} + +int CTv::SetOutput_Swap(int value) +{ + return mAudioAlsa.SetOutput_Swap( value); +} + +int CTv::SendCmdToOffBoardFBCExternalDac(int cmd, int para) +{ + int set_val = 0; + CFbcCommunication *pFBC = GetSingletonFBC(); + if (pFBC != NULL) { + if (cmd == AUDIO_CMD_SET_MUTE) { + if (para == CC_AUDIO_MUTE) { + set_val = CC_MUTE_ON; + } else if (para == CC_AUDIO_UNMUTE) { + set_val = CC_MUTE_OFF; + } else { + return -1; + } + + return pFBC->cfbc_Set_Mute(COMM_DEV_SERIAL, set_val); + } else if (cmd == AUDIO_CMD_SET_VOLUME_BAR) { + LOGD("%s, send AUDIO_CMD_SET_VOLUME_BAR (para = %d) to fbc.\n", __FUNCTION__, para); + return pFBC->cfbc_Set_Volume_Bar(COMM_DEV_SERIAL, para); + } else if (cmd == AUDIO_CMD_SET_BALANCE) { + LOGD("%s, send AUDIO_CMD_SET_BALANCE (para = %d) to fbc.\n", __FUNCTION__, para); + return pFBC->cfbc_Set_Balance(COMM_DEV_SERIAL, para); + } else if (cmd == AUDIO_CMD_SET_SOURCE) { + LOGD("%s, send AUDIO_CMD_SET_SOURCE (para = %d) to fbc.\n", __FUNCTION__, para); + return pFBC->cfbc_Set_FBC_Audio_Source(COMM_DEV_SERIAL, para); + } + } + return 0; +} + +int CTv::GetHdmiAvHotplugDetectOnoff() +{ + const char *value = config_get_str ( CFG_SECTION_TV, CFG_SSM_HDMI_AV_DETECT, "null" ); + if ( strtoul(value, NULL, 10) == 1 ) { + return 1; + } + + return 0; +} + +int CTv::SetHdmiEdidVersion(tv_hdmi_port_id_t port, tv_hdmi_edid_version_t version) +{ + SetAudioMuteForTv ( CC_AUDIO_MUTE ); + mHDMIAudioCheckThread.requestAndWaitPauseCheck(); + mAv.DisableVideoWithBlackColor(); + mpTvin->Tvin_StopDecoder(); + Tv_HDMIEDIDFileSelect(port, version); + SSMSetHDMIEdid(port); + mHDMIRxManager.HdmiRxEdidUpdate(); + mHDMIAudioCheckThread.initCheckState(); + mHDMIAudioCheckThread.resumeCheck(); + return 0; +} + +int CTv::SetHdmiHDCPSwitcher(tv_hdmi_hdcpkey_enable_t enable) +{ + mHDMIRxManager.HdmiRxHdcpOnOff(enable); + return 0; +} + +int CTv::SetHdmiColorRangeMode(tv_hdmi_color_range_t range_mode) +{ + return mHDMIRxManager.SetHdmiColorRangeMode(range_mode); +} + +tv_hdmi_color_range_t CTv::GetHdmiColorRangeMode() +{ + return mHDMIRxManager.GetHdmiColorRangeMode(); +} + +int CTv::SetVideoAxis(int x, int y, int width, int heigth) +{ + return mAv.setVideoAxis(x, y, width, heigth); +} + +int CTv::handleGPIO(const char *port_name, bool is_out, int edge) +{ + return pGpio->processCommand(port_name, is_out, edge); +} + +int CTv::KillMediaServerClient() +{ + char buf[PROPERTY_VALUE_MAX] = { 0 }; + int len = property_get("media.player.pid", buf, ""); + if (len > 0) { + char* end; + int pid = strtol(buf, &end, 0); + if (end != buf) { + LOGD("[ctv] %s, remove video path, but video decorder has used, kill it:%d\n", + __FUNCTION__, pid); + kill(pid, SIGKILL); + property_set("media.player.pid", ""); + } + } + return 0; +} + +int CTv::autoSwitchToMonitorMode() +{ + LOGD("%s, CurSigInfo.cfmt is %d , CurSigInfo.fmt is %x \n", __FUNCTION__, m_cur_sig_info.cfmt, m_cur_sig_info.fmt); + int ret = -1; + if (!MnoNeedAutoSwitchToMonitorMode) { + if ((m_cur_sig_info.cfmt == TVIN_YUV444) + || (m_cur_sig_info.cfmt == TVIN_RGB444) + || (1 == IsDVISignal())//iS DVI + || (1 == mpTvin->GetITContent()) + || (m_cur_sig_info.fmt == TVIN_SIG_FMT_HDMI_1440X240P_60HZ) + || (m_cur_sig_info.fmt == TVIN_SIG_FMT_HDMI_2880X240P_60HZ) + || (m_cur_sig_info.fmt == TVIN_SIG_FMT_HDMI_1440X288P_50HZ) + || (m_cur_sig_info.fmt == TVIN_SIG_FMT_HDMI_2880X288P_50HZ) + || ((m_cur_sig_info.fmt >= TVIN_SIG_FMT_HDMI_800X600_00HZ) + && (m_cur_sig_info.fmt <= TVIN_SIG_FMT_HDMI_1680X1050_00HZ))){ + LOGD("switch to monitor mode!\n"); + ret = CVpp::getInstance()->SetPQMode(VPP_PICTURE_MODE_MONITOR, m_source_input, m_cur_sig_info.fmt, + m_cur_sig_info.trans_fmt, INDEX_2D, 1, 1); + } else if (CVpp::getInstance()->GetPQMode(m_source_input) == VPP_PICTURE_MODE_MONITOR) { + LOGD("switch to standard mode!\n"); + ret = CVpp::getInstance()->SetPQMode(VPP_PICTURE_MODE_STANDARD, m_source_input, m_cur_sig_info.fmt, + m_cur_sig_info.trans_fmt, INDEX_2D, 1, 1); + } else { + LOGD("%s, Signal don't match autoswitch condition!\n", __FUNCTION__); + } + }else { + LOGD("%s, PQ mode set by user!\n", __FUNCTION__); + } + return ret; +} + +void CTv::onVdinSignalChange() +{ + if (!(mTvAction & TV_ACTION_IN_VDIN) || (mTvAction & TV_ACTION_SCANNING) || (SOURCE_SPDIF == m_source_input)) { + return; + } + + AutoMutex _l( mLock ); + int ret = mpTvin->VDIN_GetSignalInfo ( &m_cur_sig_info ); + if (ret < 0) { + LOGD("Get Signal Info error!\n"); + m_cur_sig_info.status = TVIN_SIG_STATUS_NULL; + } + + LOGD("%s,trans_fmt is %d,fmt is %d, status is %d", __FUNCTION__, m_cur_sig_info.trans_fmt, + m_cur_sig_info.fmt, m_cur_sig_info.status); + if ( m_cur_sig_info.status == TVIN_SIG_STATUS_STABLE ) { + onSigToStable(); + onSigStillStable(); + } else if ( m_cur_sig_info.status == TVIN_SIG_STATUS_UNSTABLE ) { + onSigToUnstable(); + } else if ( m_cur_sig_info.status == TVIN_SIG_STATUS_NOTSUP ) { + onSigToUnSupport(); + } else if ( m_cur_sig_info.status == TVIN_SIG_STATUS_NOSIG ) { + onSigToNoSig(); + } else { + InitCurrenSignalInfo(); + } +} + +void CTv::onSetPQPCMode(int source, int status) +{ + LOGD("source = %d, m_source_input = %d, status = %d\n",source, m_source_input, status); + if (( CTvin::Tvin_SourceInputToSourceInputType(m_source_input) == SOURCE_TYPE_HDMI ) ) { + if ((source == -1 ) || (source == (int)m_source_input)) { + SetAudioMuteForTv(CC_AUDIO_MUTE); + + if (status == 0) { + CVpp::getInstance()->enableMonitorMode(false); + }else { + CVpp::getInstance()->enableMonitorMode(true); + } + + tvin_port_t cur_port = mpTvin->Tvin_GetSourcePortBySourceInput(m_source_input); + mHDMIAudioCheckThread.requestAndWaitPauseCheck(); + mpTvin->SwitchPort(cur_port); + CVpp::getInstance()->Vpp_ResetLastVppSettingsSourceType(); + mHDMIAudioCheckThread.initCheckState(); + mHDMIAudioCheckThread.resumeCheck(1000); + } + } +} + +CTvRecord *CTv::getRecorder(const char *id, const char *param) { + CTvRecord *recorder = RecorderManager::getInstance().getDev(id); + if (recorder) { + recorder->stop(NULL); + recorder->setupDefault(param); + return recorder; + } + recorder = new CTvRecord(); + recorder->setupDefault(param); + recorder->setId(id); + int err = RecorderManager::getInstance().addDev(*recorder); + if (err) { + LOGE("create Recorder(%s) fail(%d)", toReadable(id), err); + delete recorder; + recorder = NULL; + } + return recorder; +} + +int CTv::prepareRecording(const char *id, const char *param) +{ + //validate param + if (!getRecorder(id, param)) + return -1; + return 0; +} + +int CTv::startRecording(const char *id, const char *param, CTvRecord::IObserver *observer) +{ + CTvRecord *recorder = NULL; + int ret = -1; + if (!(recorder = getRecorder(id, param))) { + LOGD("recorder(%s) not found", toReadable(id)); + return -1; + } + recorder->setObserver(observer); + ret = recorder->start(param); + if (ret != 0) + RecorderManager::getInstance().removeDev(id); + return ret; +} + +int CTv::stopRecording(const char *id, const char *param) +{ + CTvRecord *recorder = NULL; + if (!(recorder = RecorderManager::getInstance().getDev(id))) { + LOGD("recorder(%s) not found", toReadable(id)); + return -1; + } + recorder->stop(param); + recorder->setObserver(NULL); + RecorderManager::getInstance().removeDev(id); + return 0; +} + +int CTv::doRecordingCommand(int cmd, const char *id, const char *param) +{ + LOGD("doRec(cmd:%d, id:%s, para:%s)", cmd, id, param); + AutoMutex _l(mLock); + int ret = -10; + setDvbLogLevel(); + switch (cmd) { + case RECORDING_CMD_PREPARE: + ret = prepareRecording(id, param); + break; + case RECORDING_CMD_START: + ret = startRecording(id, param, &mTvMsgQueue); + break; + case RECORDING_CMD_STOP: + ret = stopRecording(id, param); + break; + } + return ret; +} + +CTvPlayer *CTv::getPlayer(const char *id, const char *param) { + CTvPlayer *player = PlayerManager::getInstance().getDev(id); + if (player) { + player->setupDefault(param); + player->stop(param); + return player; + } + + if (PlayerManager::singleMode) + PlayerManager::getInstance().releaseAll(); + + std::string type = paramGetString(param, NULL, "type", "dtv"); + if (type.compare("dtv") == 0) + player = new CDTVTvPlayer(this); + else if (type.compare("atv") == 0) + player = new CATVTvPlayer(this); + + if (player) { + player->setupDefault(param); + player->setId(id); + int err = PlayerManager::getInstance().addDev(*player); + if (err) { + LOGE("create Player(%s) fail(%d)", toReadable(id), err); + delete player; + player = NULL; + } + } + return player; +} + +int CTv::startPlay(const char *id, const char *param) +{ + int ret = -1; + CTvPlayer *player = NULL; + if (!(player = getPlayer(id, param))) { + LOGD("player(%s) not found", toReadable(id)); + return -1; + } + ret = player->start(param); + if (ret != 0) + RecorderManager::getInstance().removeDev(id); + return ret; +} + +int CTv::stopPlay(const char *id, const char *param) +{ + CTvPlayer *player = NULL; + if (!(player = PlayerManager::getInstance().getDev(id))) { + LOGD("player(%s) not found", toReadable(id)); + return -1; + } + player->stop(param); + PlayerManager::getInstance().removeDev(id); + return 0; +} + +int CTv::pausePlay(const char *id, const char *param) +{ + CTvPlayer *player = NULL; + if (!(player = PlayerManager::getInstance().getDev(id))) { + LOGD("player(%s) not found", toReadable(id)); + return -1; + } + return player->pause(param); +} + +int CTv::resumePlay(const char *id, const char *param) +{ + CTvPlayer *player = NULL; + if (!(player = PlayerManager::getInstance().getDev(id))) { + LOGD("player(%s) not found", toReadable(id)); + return -1; + } + return player->resume(param); +} + +int CTv::seekPlay(const char *id, const char *param) +{ + CTvPlayer *player = NULL; + if (!(player = PlayerManager::getInstance().getDev(id))) { + LOGD("player(%s) not found", toReadable(id)); + return -1; + } + return player->seek(param); +} + +int CTv::setPlayParam(const char *id, const char *param) +{ + CTvPlayer *player = NULL; + if (!(player = PlayerManager::getInstance().getDev(id))) { + LOGD("player(%s) not found", toReadable(id)); + return -1; + } + return player->set(param); +} + +int CTv::doPlayCommand(int cmd, const char *id, const char *param) +{ + LOGD("doPlay(cmd:%d, id:%s, para:%s)", cmd, id, param); + AutoMutex _l(mLock); + int ret = -10; + setDvbLogLevel(); + switch (cmd) { + case PLAY_CMD_START: + ret = startPlay(id, param); + break; + case PLAY_CMD_STOP: + ret = stopPlay(id, param); + break; + case PLAY_CMD_PAUSE: + ret = pausePlay(id, param); + break; + case PLAY_CMD_RESUME: + ret = resumePlay(id, param); + break; + case PLAY_CMD_SEEK: + ret = seekPlay(id, param); + break; + case PLAY_CMD_SETPARAM: + ret = setPlayParam(id, param); + break; + } + return ret; +} + +ANDROID_SINGLETON_STATIC_INSTANCE(RecorderManager); +ANDROID_SINGLETON_STATIC_INSTANCE(PlayerManager); + +int CTv::Tv_RrtUpdate(int freq, int modulation, int mode) +{ + int ret = 0; +#ifdef SUPPORT_ADTV + if (mTvRrt->mRrtScanHandle != NULL) { + ret = mTvRrt->StopRrtUpdate(); + if (ret < 0) { + LOGD("Tv_RrtUpdate error!\n"); + return 0; + } + } + + if (mode == RRT_MANU_SEARCH) {//manual + fe_status_t status = (fe_status_t)mFrontDev->getStatus(); + if (status & TV_FE_HAS_LOCK) { + return mTvRrt->StartRrtUpdate(RRT_MANU_SEARCH); + }else { + mFrontDev->setPara(TV_FE_ATSC, freq, modulation, 0); + return mTvRrt->StartRrtUpdate(RRT_MANU_SEARCH); + } + } else {//auto + return mTvRrt->StartRrtUpdate(RRT_AUTO_SEARCH); + } +#endif + return ret; +} + +int CTv::Tv_RrtSearch(int rating_region_id, int dimension_id, int value_id, rrt_select_info_t *rrt_select_info) +{ + int ret = 0; +#ifdef SUPPORT_ADTV + rrt_select_info_t tmp; + memset(&tmp, 0, sizeof(rrt_select_info_t)); + ret = mTvRrt->GetRRTRating(rating_region_id, dimension_id, value_id, &tmp); + if (ret < 0) { + LOGD("Tv_RrtSearch error!\n"); + } + + *rrt_select_info = tmp; +#endif + return ret; +} + +void CTv::setDvbLogLevel() { +#ifdef SUPPORT_ADTV + AM_DebugSetLogLevel(property_get_int32("tv.dvb.loglevel", 1)); +#endif +} + +void CTv::dump(String8 &result) +{ + result.appendFormat("\naction = %x\n", mTvAction); + result.appendFormat("status = %d\n", mTvStatus); + result.appendFormat("current source input = %d\n", m_source_input); + result.appendFormat("last source input = %d\n", m_last_source_input); + result.appendFormat("hdmi out with fbc = %d\n\n", mHdmiOutFbc); + + result.appendFormat("tvserver git branch:%s\n", tvservice_get_git_branch_info()); + result.appendFormat("tvserver git version:%s\n", tvservice_get_git_version_info()); + result.appendFormat("tvserver Last Changed:%s\n", tvservice_get_last_chaned_time_info()); + result.appendFormat("tvserver Last Build:%s\n", tvservice_get_build_time_info()); + result.appendFormat("tvserver Builer Name:%s\n", tvservice_get_build_name_info()); + result.appendFormat("tvserver board version:%s\n\n", tvservice_get_board_version_info()); + +#ifdef SUPPORT_ADTV + result.appendFormat("libdvb git branch:%s\n", dvb_get_git_branch_info()); + result.appendFormat("libdvb git version:%s\n", dvb_get_git_version_info()); + result.appendFormat("libdvb Last Changed:%s\n", dvb_get_last_chaned_time_info()); + result.appendFormat("libdvb Last Build:%s\n", dvb_get_build_time_info()); + result.appendFormat("libdvb Builer Name:%s\n\n", dvb_get_build_name_info()); +#endif +} + diff --git a/tv/tvserver/libtv/tv/CTv.h b/tv/tvserver/libtv/tv/CTv.h new file mode 100644 index 0000000..a8c2aa4 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTv.h @@ -0,0 +1,745 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CDTV_H) +#define _CDTV_H +#include <stdint.h> +#include <string.h> +#include <sys/time.h> +#include <utils/threads.h> +#include "CTvProgram.h" +#include "CTvEpg.h" +#include "CTvRrt.h" +#include "CTvEas.h" +#include "CTvLog.h" +#include "CTvTime.h" +#include "CTvEvent.h" +#include "CTvEv.h" +#include "CTvBooking.h" +#include "../vpp/CVpp.h" +#include "../tvin/CTvin.h" +#include "../tvin/CHDMIRxManager.h" +#include <CMsgQueue.h> +#include <serial_operate.h> +#include "CTvRecord.h" +#include "CTvSubtitle.h" +#include "CAv.h" +#include "CTvDmx.h" +#include "../audio/CTvAudio.h" +#include "AutoBackLight.h" +#include "CAutoPQparam.h" +#include "CBootvideoStatusDetect.h" +#include "tvin/CDevicesPollStatusDetect.h" +#include "fbcutils/fbcutils.h" +#include "CTvGpio.h" +#ifdef SUPPORT_ADTV +#include <am_epg.h> +#include <am_mem.h> +#endif +#include "CTvScanner.h" +#include "CFrontEnd.h" + + +#include <CTvFactory.h> + +#include "CTvPlayer.h" + +using namespace android; + +static const char *TV_CONFIG_FILE_PATH = "/param/tvconfig.conf"; +static const char *TV_DB_PATH = "/param/dtv.db"; +static const char *TV_CONFIG_FILE_SYSTEM_PATH = "/vendor/etc/tvconfig.conf"; +static const char *TV_CONFIG_FILE_PARAM_PATH = "/param/tvconfig.conf"; +static const char *TV_CHANNEL_LIST_SYSTEM_PATH = "/vendor/etc/tv_default.xml"; +static const char *TV_CHANNEL_LIST_PARAM_PATH = "/param/tv_default.xml"; +static const char *TV_RRT_DEFINE_SYSTEM_PATH = "/vendor/etc/tv_rrt_define.xml"; + +#define LCD_ENABLE "/sys/class/lcd/enable" +#define BL_LOCAL_DIMING_FUNC_ENABLE "/sys/class/aml_ldim/func_en" +#define DEVICE_CLASS_TSYNC_AV_THRESHOLD_MIN "/sys/class/tsync/av_threshold_min" +#define AV_THRESHOLD_MIN_MS "540000" //6S = 6*90000 + +#define DTV_DTMB_MODE "dtmb" +#define DTV_DVBC_MODE "dvbc" +#define DTV_DVBS_MODE "dvbs" +#define DTV_ATSC_MODE "atsc" +#define DTV_DVBT_MODE "dvbt" +#define DTV_ISDBT_MODE "isdbt" + + +typedef enum tv_window_mode_e { + NORMAL_WONDOW, + PREVIEW_WONDOW, +} tv_window_mode_t; + +typedef enum tv_dtv_scan_running_status_e { + DTV_SCAN_RUNNING_NORMAL, + DTV_SCAN_RUNNING_ANALYZE_CHANNEL, +} tv_dtv_scan_running_status_t; + +typedef struct tv_config_s { + bool kernelpet_disable; + unsigned int kernelpet_timeout; + bool userpet; + unsigned int userpet_timeout; + unsigned int userpet_reset; + bool memory512m; +} tv_config_t; + +typedef enum TvRunStatus_s { + TV_INIT_ED = -1, + TV_OPEN_ED = 0, + TV_START_ED , + TV_RESUME_ED, + TV_PAUSE_ED, + TV_STOP_ED, + TV_CLOSE_ED, +} TvRunStatus_t; + +class CTvPlayer; +class CDTVTvPlayer; +class CATVTvPlayer; + +class CTv : public CTvin::CHDMIAudioCheck::IHDMIAudioCheckObserver, + public CDevicesPollStatusDetect::ISourceConnectObserver, + public IUpgradeFBCObserver, + public CTvSubtitle::IObserver, + public CBootvideoStatusDetect::IBootvideoStatusObserver, + public CTv2d4GHeadSetDetect::IHeadSetObserver, + public CTvRecord::IObserver { + +public: + static const int TV_ACTION_NULL = 0x0000; + static const int TV_ACTION_IN_VDIN = 0x0001; + static const int TV_ACTION_STOPING = 0x0002; + static const int TV_ACTION_SCANNING = 0x0004; + static const int TV_ACTION_PLAYING = 0x0008; + static const int TV_ACTION_RECORDING = 0x0010; + static const int TV_ACTION_SOURCE_SWITCHING = 0x0020; + + static const int OPEN_DEV_FOR_SCAN_ATV = 1; + static const int OPEN_DEV_FOR_SCAN_DTV = 2; + static const int CLOSE_DEV_FOR_SCAN = 3; + tvin_info_t m_cur_sig_info; + + static const int RECORDING_CMD_STOP = 0; + static const int RECORDING_CMD_PREPARE = 1; + static const int RECORDING_CMD_START = 2; + + static const int PLAY_CMD_STOP = 0; + static const int PLAY_CMD_START = 1; + static const int PLAY_CMD_PAUSE = 2; + static const int PLAY_CMD_RESUME = 3; + static const int PLAY_CMD_SEEK = 4; + static const int PLAY_CMD_SETPARAM = 5; + +public: + class TvIObserver { + public: + TvIObserver() {}; + virtual ~TvIObserver() {}; + virtual void onTvEvent ( const CTvEv &ev ) = 0; + }; + //main + CTv(); + virtual ~CTv(); + virtual int OpenTv ( void ); + virtual int CloseTv ( void ); + virtual int StartTvLock (); + virtual int StopTvLock ( void ); + virtual int DoSuspend(int type); + virtual int DoResume(int type); + virtual int startTvDetect(); + + virtual TvRunStatus_t GetTvStatus(); + virtual int ClearAnalogFrontEnd(); + virtual tv_source_input_t GetLastSourceInput (void); + virtual int SetSourceSwitchInput (tv_source_input_t source_input ); + virtual int SetSourceSwitchInput(tv_source_input_t virtual_input, tv_source_input_t source_input); + virtual int SetSourceSwitchInputLocked(tv_source_input_t virtual_input, tv_source_input_t source_input); + virtual tv_source_input_t GetCurrentSourceInputLock ( void ); + virtual tv_source_input_t GetCurrentSourceInputVirtualLock ( void ); + bool isVirtualSourceInput(tv_source_input_t source_input); + virtual void InitCurrenSignalInfo ( void ); + virtual tvin_info_t GetCurrentSignalInfo ( void ); + int setPreviewWindowMode(bool mode); + virtual int SetPreviewWindow ( tvin_window_pos_t pos ); + virtual int dtvAutoScan(); + virtual int dtvManualScan (int beginFreq, int endFreq, int modulation = -1); + virtual int atvAutoScan(int videoStd, int audioStd, int searchType); + virtual int atvAutoScan(int videoStd, int audioStd, int searchType, int procMode); + virtual int dtvScan(int mode, int scan_mode, int beginFreq, int endFreq, int para1, int para2); + virtual int dtvMode(const char *mode); + virtual int clearFrontEnd(int para); + virtual int pauseScan(); + virtual int resumeScan(); + virtual int getScanStatus(); + virtual void operateDeviceForScan(int type); + virtual void setDvbTextCoding(char *coding); + virtual int Scan(const char *feparas, const char *scanparas); + virtual int setFrontEnd ( const char *paras, bool force ); + + virtual int clearAllProgram(int arg0); + virtual int clearDbAllProgramInfoTable(); + virtual void setSourceSwitchAndPlay(); + virtual int atvMunualScan ( int startFreq, int endFreq, int videoStd, int audioStd, int store_Type = 0, int channel_num = 0 ); + virtual int stopScanLock(); + virtual int playDvbcProgram ( int progId ); + virtual int playDtmbProgram ( int progId ); + virtual int playAtvProgram ( int, int, int, int, int); + virtual int playDtvProgram ( int, int, int, int, int, int, int, int, int, int); + virtual int playDtvProgramUnlocked( int, int, int, int, int, int, int, int, int, int); + virtual int playDtvProgram(const char *, int, int, int, int, int, int, int, int, int, int); + virtual int playDtvProgramUnlocked(const char *, int, int, int, int, int, int, int, int, int, int); + virtual int playDtvProgram(const char *, int, int, int, int, int, int); + virtual int playDtvProgramUnlocked(const char *, int, int, int, int, int, int); + virtual int playDtvTimeShift (const char *feparas, void *para, int audioCompetation); + virtual int playDtvTimeShiftUnlocked(const char *feparas, void *para, int audioCompetation); + virtual int stopPlayingLock(); + virtual int resetFrontEndPara ( frontend_para_set_t feParms ); + virtual int SetDisplayMode ( vpp_display_mode_t display_mode, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt ); + virtual void onHdmiSrChanged(int sr, bool bInit); + virtual void onHMDIAudioStatusChanged(int status); + int SetCurProgramAudioVolumeCompensationVal ( int tmpVal ); + int GetAudioVolumeCompensationVal(int progDbId); + //dtv audio track info + int getAudioTrackNum ( int progId ); + int getAudioInfoByIndex ( int progId, int idx, int *pAFmt, String8 &lang ); + int switchAudioTrack ( int progId, int idx ); + int switchAudioTrack ( int aPid, int aFmt, int aParam ); + int setAudioAD(int enable, int aPid, int aFmt); + int getVideoFormatInfo ( int *pWidth, int *pHeight, int *pFPS, int *pInterlace ); + int getAudioFormatInfo ( int fmt[2], int sample_rate[2], int resolution[2], int channels[2], + int lfepresent[2], int *frames, int *ab_size, int *ab_data, int *ab_free ); + int ResetAudioDecoderForPCMOutput(); + int setAudioChannel ( int channelIdx ); + int getAudioChannel(); + int setTvObserver (TvIObserver *ob); + int getAtscAttenna(); + long getTvTime() + { + return mTvTime.getTime(); + }; + int getFrontendSignalStrength(); + int getFrontendSNR(); + int getFrontendBER(); + int getChannelInfoBydbID ( int dbID, channel_info_t &chan_info ); + int setBlackoutEnable(int enable); + int getSaveBlackoutEnable(); + int saveATVProgramID ( int dbID ); + int getATVProgramID ( void ); + int saveDTVProgramID ( int dbID ); + int getDTVProgramID ( void ); + int saveRadioProgramID ( int dbID ); + int getRadioProgramID ( void ); + + int getATVMinMaxFreq ( int *scanMinFreq, int *scanMaxFreq ); + + int doRecordingCommand(int cmd, const char *id, const char *param); + int doPlayCommand(int cmd, const char *id, const char *param); + + int getAverageLuma(); + int setAutobacklightData(const char *value); + int getAutoBacklightData(int *data); + int getAutoBackLightStatus(); + int setAutoBackLightStatus(int status); + + virtual int Tv_SSMRestoreDefaultSetting(); + + int handleGPIO(const char *port_name, bool is_out, int edge); + int setLcdEnable(bool enable); + + int GetSourceConnectStatus(tv_source_input_t source_input); + int IsDVISignal(); + int isVgaFmtInHdmi(); + + int getHDMIFrameRate ( void ); + void RefreshAudioMasterVolume ( tv_source_input_t source_input ); + + int Tvin_SetPLLValues (); + int SetCVD2Values (); + unsigned int Vpp_GetDisplayResolutionInfo(tvin_window_pos_t *win_pos); + //SSM + virtual int Tv_SSMFacRestoreDefaultSetting(); + int StartHeadSetDetect(); + virtual void onHeadSetDetect(int state, int para); + + CTvFactory mFactoryMode; + CTvin::CHDMIAudioCheck mHDMIAudioCheckThread; + CDevicesPollStatusDetect mDevicesPollStatusDetectThread; + CBootvideoStatusDetect *mBootvideoStatusDetectThread; + CHDMIRxManager mHDMIRxManager; + + CTvSubtitle mSubtitle; + CTv2d4GHeadSetDetect mHeadSet; + + int SendHDMIRxCECCustomMessage(unsigned char data_buf[]); + int SendHDMIRxCECCustomMessageAndWaitReply(unsigned char data_buf[], unsigned char reply_buf[], int WaitCmd, int timeout); + int SendHDMIRxCECBoradcastStandbyMessage(); + int SendHDMIRxCECGiveCECVersionMessage(tv_source_input_t source_input, unsigned char data_buf[]); + int SendHDMIRxCECGiveDeviceVendorIDMessage(tv_source_input_t source_input, unsigned char data_buf[]); + int SendHDMIRxCECGiveOSDNameMessage(tv_source_input_t source_input, unsigned char data_buf[]); + + int GetHdmiHdcpKeyKsvInfo(int data_buf[]); + virtual bool hdmiOutWithFbc(); + int StartUpgradeFBC(char *file_name, int mode, int upgrade_blk_size); + + int Tv_GetProjectInfo(project_info_t *ptrInfo); + int Tv_GetPlatformType(); + int Tv_HDMIEDIDFileSelect(tv_hdmi_port_id_t port, tv_hdmi_edid_version_t version); + int Tv_HandeHDMIEDIDFilePathConfig(); + int Tv_SetDDDRCMode(tv_source_input_t source_input); + int Tv_SetAudioSourceType (tv_source_input_t source_input); + + //PQ + virtual int Tv_SetBrightness ( int brightness, tv_source_input_t tv_source_input, int is_save ); + virtual int Tv_GetBrightness ( tv_source_input_t tv_source_input ); + virtual int Tv_SaveBrightness ( int brightness, tv_source_input_t tv_source_input ); + virtual int Tv_SetContrast ( int contrast, tv_source_input_t tv_source_input, int is_save ); + virtual int Tv_GetContrast ( tv_source_input_t tv_source_input ); + virtual int Tv_SaveContrast ( int contrast, tv_source_input_t tv_source_input ); + virtual int Tv_SetSaturation ( int satuation, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, int is_save ); + virtual int Tv_GetSaturation ( tv_source_input_t tv_source_input ); + virtual int Tv_SaveSaturation ( int satuation, tv_source_input_t tv_source_input ); + virtual int Tv_SetHue ( int hue, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, int is_save ); + virtual int Tv_GetHue ( tv_source_input_t tv_source_input ); + virtual int Tv_SaveHue ( int hue, tv_source_input_t tv_source_input ); + virtual int Tv_SetPQMode ( vpp_picture_mode_t mode, tv_source_input_t tv_source_input, int is_save ); + virtual vpp_picture_mode_t Tv_GetPQMode ( tv_source_input_t tv_source_input ); + virtual int Tv_SavePQMode ( vpp_picture_mode_t mode, tv_source_input_t tv_source_input ); + virtual int Tv_SetSharpness ( int value, tv_source_input_t tv_source_input, int en, int is_save ); + virtual int Tv_GetSharpness ( tv_source_input_t tv_source_input ); + virtual int Tv_SaveSharpness ( int value, tv_source_input_t tv_source_input ); + virtual int Tv_SetBacklight ( int value, tv_source_input_t tv_source_input, int is_save ); + virtual int Tv_GetBacklight ( tv_source_input_t tv_source_input ); + virtual int Tv_SaveBacklight ( int value, tv_source_input_t tv_source_input ); + int Tv_SetBacklight_Switch ( int value ); + int Tv_GetBacklight_Switch ( void ); + int Tv_SetColorTemperature ( vpp_color_temperature_mode_t mode, tv_source_input_t tv_source_input, int is_save ); + vpp_color_temperature_mode_t Tv_GetColorTemperature ( tv_source_input_t tv_source_input ); + virtual int Tv_SetDisplayMode ( vpp_display_mode_t mode, tv_source_input_t tv_source_input, tvin_sig_fmt_t fmt, int is_save ); + virtual int Tv_SaveDisplayMode ( vpp_display_mode_t mode, tv_source_input_t tv_source_input ); + virtual int Tv_SaveColorTemperature ( vpp_color_temperature_mode_t mode, tv_source_input_t tv_source_input ); + virtual vpp_display_mode_t Tv_GetDisplayMode ( tv_source_input_t tv_source_input ); + virtual int Tv_SetNoiseReductionMode ( vpp_noise_reduction_mode_t mode, tv_source_input_t tv_source_input, int is_save ); + virtual vpp_noise_reduction_mode_t Tv_GetNoiseReductionMode ( tv_source_input_t tv_source_input ); + virtual int Tv_SaveNoiseReductionMode ( vpp_noise_reduction_mode_t mode, tv_source_input_t tv_source_input ); + int setEyeProtectionMode(int enable); + int getEyeProtectionMode(); + int SetHdmiColorRangeMode(tv_hdmi_color_range_t range_mode); + tv_hdmi_color_range_t GetHdmiColorRangeMode(); + int setGamma(vpp_gamma_curve_t gamma_curve, int is_save); + + //audio + virtual void updateSubtitle(int, int); + + //audio + virtual void TvAudioOpen(); + virtual void AudioCtlUninit(); + virtual int SetAudioMuteForSystem(int muteOrUnmute); + virtual int GetAudioMuteForSystem(); + virtual int SetAudioMuteForTv(int muteOrUnmute); + virtual int GetAudioMuteForTv(); + int SetAudioAVOutMute(int muteStatus); + int GetAudioAVOutMute(); + int SetAudioSPDIFMute(int muteStatus); + int GetAudioSPDIFMute(); + int SetDacMute(int muteStatus, int mute_type); + int SetAudioI2sMute(int); + int SetAudioMasterVolume(int tmp_vol); + int GetAudioMasterVolume(); + int SaveCurAudioMasterVolume(int tmp_vol); + int GetCurAudioMasterVolume(); + int SetAudioBalance(int tmp_val); + int GetAudioBalance(); + int SaveCurAudioBalance(int tmp_val); + int GetCurAudioBalance(); + int SetAudioSupperBassVolume(int tmp_vol); + int GetAudioSupperBassVolume(); + int SaveCurAudioSupperBassVolume(int tmp_vol); + int GetCurAudioSupperBassVolume(); + int SetAudioSupperBassSwitch(int tmp_val); + int GetAudioSupperBassSwitch(); + int SaveCurAudioSupperBassSwitch(int tmp_val); + int GetCurAudioSupperBassSwitch(); + int SetAudioSRSSurround(int tmp_val); + int GetAudioSRSSurround(); + int SaveCurAudioSrsSurround(int tmp_val); + int GetCurAudioSRSSurround(); + int SetAudioSrsDialogClarity(int tmp_val); + int GetAudioSrsDialogClarity(); + int SaveCurAudioSrsDialogClarity(int tmp_val); + int GetCurAudioSrsDialogClarity(); + int SetAudioSrsTruBass(int tmp_val); + int GetAudioSrsTruBass(); + int SaveCurAudioSrsTruBass(int tmp_val); + int GetCurAudioSrsTruBass(); + int SetAudioSPDIFSwitch(int tmp_val); + int GetCurAudioSPDIFSwitch(); + int SaveCurAudioSPDIFSwitch(int tmp_val); + int SetAudioVirtualizer(int enable, int EffectLevel); + int GetAudioVirtualizerEnable(); + int GetAudioVirtualizerLevel(); + int LoadAudioVirtualizer(); + + //Audio SPDIF Mode + int SetAudioSPDIFMode(int tmp_val); + int GetCurAudioSPDIFMode(); + int SaveCurAudioSPDIFMode(int tmp_val); + int SetAudioBassVolume(int tmp_vol); + int GetAudioBassVolume(); + int SaveCurAudioBassVolume(int tmp_vol); + int GetCurAudioBassVolume(); + int SetAudioTrebleVolume(int tmp_vol); + int GetAudioTrebleVolume(); + int SaveCurAudioTrebleVolume(int tmp_vol); + int GetCurAudioTrebleVolume(); + int SetAudioSoundMode(int tmp_val); + int GetAudioSoundMode(); + int SaveCurAudioSoundMode(int tmp_val); + int GetCurAudioSoundMode(); + int SetAudioWallEffect(int tmp_val); + int GetAudioWallEffect(); + int SaveCurAudioWallEffect(int tmp_val); + int GetCurAudioWallEffect(); + int SetAudioEQMode(int tmp_val); + int GetAudioEQMode(); + int SaveCurAudioEQMode(int tmp_val); + int GetCurAudioEQMode(); + int GetAudioEQRange(int range_buf[]); + int GetAudioEQBandCount(); + int SetAudioEQGain(int gain_buf[]); + int GetAudioEQGain(int gain_buf[]); + int GetCurAudioEQGain(int gain_buf[]); + int SaveCurAudioEQGain(int gain_buf[]); + int SetAudioEQSwitch(int switch_val); + int OpenAmAudio(unsigned int sr, int input_device, int output_device); + int CloseAmAudio(void); + int SetAmAudioInputSr(unsigned int sr, int output_device); + int SetAmAudioOutputMode(int mode); + int SetAmAudioMusicGain(int gain); + int SetAmAudioLeftGain(int gain); + int SetAmAudioRightGain(int gain); + int SetAudioVolumeCompensationVal(int tmp_vol_comp_val); + int AudioLineInSelectChannel(int audio_channel); + int AudioSetLineInCaptureVolume(int l_vol, int r_vol); + int setAudioPcmPlaybackVolume(int val); + int setAmAudioVolume(float volume); + float getAmAudioVolume(); + int saveAmAudioVolume(int volume, int source); + int getSaveAmAudioVolume(int volume); + int setAmAudioPreGain(float pre_gain); + float getAmAudioPreGain(); + int setAmAudioPreMute(int mute); + int getAmAudioPreMute(); + + int openTvAudio(); + + int InitTvAudio(int sr, int input_device); + int UnInitTvAudio(); + int AudioChangeSampleRate(int sr); + int AudioSetAudioInSource(int audio_src_in_type); + int AudioSetAudioSourceType(int source_type); + int AudioSSMRestoreDefaultSetting(); + int SetAudioDumpDataFlag(int tmp_flag); + int GetAudioDumpDataFlag(); + int SetAudioLeftRightMode(unsigned int mode); + unsigned int GetAudioLeftRightMode(); + int SwitchAVOutBypass (int); + int SetAudioSwitchIO(int value); + int SetOutput_Swap(int value); + int HanldeAudioInputSr(unsigned int); + void AudioSetVolumeDigitLUTBuf(int lut_sel_flag, int *MainVolLutBuf); + int SetADC_Digital_Capture_Volume(int value); + int SetPGA_IN_Value(int value); + int SetDAC_Digital_PlayBack_Volume(int value); + int InitSetTvAudioCard(); + int UnInitSetTvAudioCard(); + void RefreshSrsEffectAndDacGain(); + int SetCustomEQGain(); + int SetAtvInGain(int gain_val); + int GetHdmiAvHotplugDetectOnoff(); + int SetHdmiEdidVersion(tv_hdmi_port_id_t port, tv_hdmi_edid_version_t version); + int SetHdmiHDCPSwitcher(tv_hdmi_hdcpkey_enable_t enable); + int SetVideoAxis(int x, int y, int width, int heigth); + int Tv_RrtUpdate(int freq, int modulation, int mode); + int Tv_RrtSearch(int rating_region_id, int dimension_id, int value_id, rrt_select_info_t *rrt_select_info); + int Tv_Easupdate(); + void dump(String8 &result); +private: + int SendCmdToOffBoardFBCExternalDac(int, int); + int LoadCurAudioSPDIFMode(); + int LoadCurAudioMasterVolume(); + int LoadCurAudioBalance(); + int LoadCurAudioSupperBassVolume(); + int LoadCurAudioSupperBassSwitch(); + int LoadCurAudioSrsSurround(); + int LoadCurAudioSrsDialogClarity(); + int LoadCurAudioSPDIFSwitch(); + void SetSupperBassSRSSpeakerSize(); + int LoadCurAudioSoundMode(); + int LoadCurAudioEQMode(); + int LoadCurAudioSrsTruBass(); + int RealSaveCurAudioBassVolume(int, int); + int LoadCurAudioBassVolume(); + int RealSaveCurAudioTrebleVolume(int, int); + int LoadCurAudioTrebleVolume(); + int HandleTrebleBassVolume(); + int LoadCurAudioWallEffect(); + int RealReadCurAudioEQGain(int *); + int RealSaveCurAudioEQGain(int *, int); + int LoadCurAudioEQGain(); + int MappingEQGain(int *, int *, int); + int RestoreToAudioDefEQGain(int *); + int GetCustomEQGain(int *); + int AudioSetEQGain(int *); + int handleEQGainBeforeSet(int *, int *); + int RealSetEQGain(int *); + int SetSpecialModeEQGain(int); + int SetSpecialIndexEQGain(int, int); + int SaveSpecialIndexEQGain(int, int); + void LoadAudioCtl(); + void InitSetAudioCtl(); + int GetBassUIMinGainVal(); + int GetBassUIMaxGainVal(); + int GetTrebleUIMinGainVal(); + int GetTrebleUIMaxGainVal(); + int MappingLine(int, int, int, int, int); + int MappingTrebleBassAndEqualizer(int, int, int, int); + int SetSPDIFMode(int mode_val); + int setAudioPreGain(tv_source_input_t source_input); + float getAudioPreGain(tv_source_input_t source_input); + int KillMediaServerClient(); + bool insertedFbcDevice(); + + bool isBootvideoStopped(); + + int autoSwitchToMonitorMode(); + + static int prepareRecording(const char *id, const char *param); + static int startRecording(const char *id, const char *param, CTvRecord::IObserver *observer); + static int stopRecording(const char *id, const char *param); + + static CTvRecord *getRecorder(const char *id, const char *param); + + int startPlay(const char *id, const char *param); + int stopPlay(const char *id, const char *param); + int pausePlay(const char *id, const char *param); + int resumePlay(const char *id, const char *param); + int seekPlay(const char *id, const char *param); + int setPlayParam(const char *id, const char *param); + + CTvPlayer *getPlayer(const char *id, const char *param); + + int tryReleasePlayer(bool isEnter, tv_source_input_t si); + + void setDvbLogLevel(); + + CAudioAlsa mAudioAlsa; + CAudioEffect mAudioEffect; + + CAudioCustomerCtrl mCustomerCtrl; + int mCurAudioMasterVolume; + int mCurAudioBalance; + int mCurAudioSupperBassVolume; + int mCurAudioSupperBassSwitch; + int mCurAudioSRSSurround; + int mCurAudioSrsDialogClarity; + int mCurAudioSrsTruBass; + int mCurAudioSPDIFSwitch; + int mCurAudioSPDIFMode; + int mCurAudioBassVolume; + int mCurAudioTrebleVolume; + int mCurAudioSoundMode; + int mCurAudioWallEffect; + int mCurAudioEQMode; + int mCustomAudioMasterVolume; + int mCustomAudioBalance; + int mCustomAudioSupperBassVolume; + int mCustomAudioSupperBassSwitch; + int mCustomAudioSRSSurround; + int mCustomAudioSrsDialogClarity; + int mCustomAudioSrsTruBass; + int mCustomAudioBassVolume; + int mCustomAudioTrebleVolume; + int mCustomAudioSoundMode; + int mCustomAudioWallEffect; + int mCustomAudioEQMode; + int mCustomAudioSoundEnhancementSwitch; + int mCustomEQGainBuf[CC_BAND_ITEM_CNT]; + int mCurEQGainBuf[CC_BAND_ITEM_CNT] ; + int8_t mCurEQGainChBuf[CC_BAND_ITEM_CNT]; + int mVolumeCompensationVal; + int mMainVolumeBalanceVal; + //end audio + bool mATVDisplaySnow; + bool iSBlackPattern; + bool MnoNeedAutoSwitchToMonitorMode; + +protected: + class CTvMsgQueue: public CMsgQueueThread, public CAv::IObserver + , public CTvScanner::IObserver , public CTvEpg::IObserver, public CFrontEnd::IObserver + , public CTvRecord::IObserver, public CTvRrt::IObserver, public CTvEas::IObserver + { + public: + static const int TV_MSG_COMMON = 0; + static const int TV_MSG_STOP_ANALYZE_TS = 1; + static const int TV_MSG_START_ANALYZE_TS = 2; + static const int TV_MSG_CHECK_FE_DELAY = 3; + static const int TV_MSG_AV_EVENT = 4; + static const int TV_MSG_FE_EVENT = 5; + static const int TV_MSG_SCAN_EVENT = 6; + static const int TV_MSG_EPG_EVENT = 7; + static const int TV_MSG_HDMI_SR_CHANGED = 8; + static const int TV_MSG_ENABLE_VIDEO_LATER = 9; + static const int TV_MSG_SCANNING_FRAME_STABLE = 10; + static const int TV_MSG_VIDEO_AVAILABLE_LATER = 11; + static const int TV_MSG_RECORD_EVENT = 12; + static const int TV_MSG_RRT_EVENT = 13; + static const int TV_MSG_EAS_EVENT = 14; + + CTvMsgQueue(CTv *tv); + ~CTvMsgQueue(); + //scan observer + void onEvent ( const CTvScanner::ScannerEvent &ev ); + //epg observer + void onEvent ( const CTvEpg::EpgEvent &ev ); + //FE observer + void onEvent ( const CFrontEnd::FEEvent &ev ); + //Record + void onEvent(const CTvRecord::RecEvent &ev); + //rrt observer + void onEvent (const CTvRrt::RrtEvent &ev); + //eas observer + void onEvent (const CTvEas::EasEvent &ev); + //AV + void onEvent(const CAv::AVEvent &ev); + private: + virtual void handleMessage ( CMessage &msg ); + CTv *mpTv; + }; + + bool isTvViewBlocked(); + void onEnableVideoLater(int framecount); + void onVideoAvailableLater(int framecount); + int resetDmxAndAvSource(); + int stopScan(); + int stopPlaying(bool isShowTestScreen); + int stopPlaying(bool isShowTestScreen, bool resetFE); + void sendTvEvent ( const CTvEv &ev ); + int startPlayTv ( int source, int vid, int aid, int pcrid, int vfat, int afat ); + //scan observer + void onEvent ( const CTvScanner::ScannerEvent &ev ); + //epg observer + void onEvent ( const CTvEpg::EpgEvent &ev ); + //FE observer + void onEvent ( const CFrontEnd::FEEvent &ev ); + + //Record + void onEvent(const CTvRecord::RecEvent &ev); + //rrt observer + void onEvent (const CTvRrt::RrtEvent &ev); + //eas observer + void onEvent (const CTvEas::EasEvent &ev); + //AV + void onEvent(const CAv::AVEvent &ev); + + bool Tv_Start_Analyze_Ts ( int channelID ); + bool Tv_Stop_Analyze_Ts(); + int Tvin_Stop ( void ); + int Tvin_GetTvinConfig(); + int Tv_init_audio(); + int Tv_MiscSetBySource ( tv_source_input_t ); + void print_version_info ( void ); + int dtvCleanProgramByFreq ( int freq ); + /*********************** Audio start **********************/ + int SetAudioVolDigitLUTTable ( tv_source_input_t source_input ); + virtual int Tv_SetAudioInSource (tv_source_input_t source_input); + void Tv_SetAudioOutputSwap_Type (tv_source_input_t source_input); + void Tv_SetAVOutPut_Input_gain(tv_source_input_t source_input); + /*********************** Audio end **********************/ + + void onSigToStable(); + void onSigToUnstable(); + void onSigToUnSupport(); + void onSigToNoSig(); + void onSigStillStable(); + void onHDMIAudioCheckLoop(); + + virtual void onSourceConnect(int source_type, int connect_status); + virtual void onVdinSignalChange(); + virtual void onSetPQPCMode(int source, int status); + virtual void onUpgradeStatus(int status, int progress); + virtual void onThermalDetect(int state); + + virtual void onBootvideoRunning(); + virtual void onBootvideoStopped(); + + CTvEpg mTvEpg; + CTvRrt *mTvRrt; + CTvScanner *mTvScanner; + CTvRecord mTvRec; + CFrontEnd *mFrontDev; + CTvEas *mTvEas; + + mutable Mutex mLock; + CTvTime mTvTime; + + CTvDimension mTvVchip; + CTvSubtitle mTvSub; + CAv mAv; + CTvDmx mTvDmx; + CTvDmx mTvDmx1; + CTvDmx mTvDmx2; + CTvMsgQueue mTvMsgQueue; + AutoBackLight mAutoBackLight; + // + volatile int mTvAction; + volatile TvRunStatus_t mTvStatus; + volatile tv_source_input_t m_source_input; + volatile tv_source_input_t m_last_source_input; + volatile tv_source_input_t m_source_input_virtual; + + /* for tvin window mode and pos*/ + tvin_window_pos_t m_win_pos; + tv_window_mode_t m_win_mode; + bool mBlackoutEnable;// true: enable false: disable + bool mHdmiOutFbc; + CFbcCommunication *fbcIns; + + //friend class CTvMsgQueue; + int mCurAnalyzeTsChannelID; + TvIObserver *mpObserver; + tv_dtv_scan_running_status_t mDtvScanRunningStatus; + volatile tv_config_t gTvinConfig; + bool mAutoSetDisplayFreq; + int m_sig_spdif_nums; + bool mSetHdmiEdid; + /** for HDMI-in sampling detection. **/ + int m_hdmi_sampling_rate; + int m_hdmi_audio_data; + /** for display mode to bottom **/ + + //audio mute + int mAudioMuteStatusForTv; + int mAudioMuteStatusForSystem; + char mMainVolLutTableExtraName[CC_PROJECT_INFO_ITEM_MAX_LEN]; + + CTvin *mpTvin; + CTvGpio *pGpio; + + bool mPreviewEnabled; + +public: + friend CTvPlayer; + friend CDTVTvPlayer; + friend CATVTvPlayer; +}; + +#endif //_CDTV_H diff --git a/tv/tvserver/libtv/tv/CTvBooking.cpp b/tv/tvserver/libtv/tv/CTvBooking.cpp new file mode 100644 index 0000000..89a4033 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvBooking.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvBooking" + +#include "CTvBooking.h" +#include "CTvDatabase.h" + +int CTvBooking::InitFromCursor(CTvDatabase::Cursor &c) +{ + int col; + + col = c.getColumnIndex("db_id"); + this->id = c.getInt(col); + + col = c.getColumnIndex("db_srv_id"); + this->programId = c.getInt(col); + + col = c.getColumnIndex("db_evt_id"); + this->eventId = c.getInt(col); + + col = c.getColumnIndex("flag"); + this->flag = c.getInt(col); + + col = c.getColumnIndex("status"); + this->status = c.getInt(col); + + col = c.getColumnIndex("repeat"); + this->repeat = c.getInt(col); + + col = c.getColumnIndex("start"); + this->start = (long)c.getInt(col); + + col = c.getColumnIndex("duration"); + this->duration = (long)c.getInt(col) ; + + col = c.getColumnIndex("srv_name"); + this->progName = c.getString(col); + + col = c.getColumnIndex("evt_name"); + this->evtName = c.getString(col); + + return 0; +} + +int CTvBooking::selectByID(int id, CTvBooking &CtvBook) +{ + CTvDatabase::Cursor c; + String8 sql; + + sql = String8("select * from booking_table where booking_table.db_evt_id = ") + String8::format("%d", id); + CTvDatabase::GetTvDb()->select(sql.string(), c); + if (c.moveToFirst()) { + CtvBook.InitFromCursor(c); + } else { + c.close(); + return -1; + } + + c.close(); + return 0; +} + +int CTvBooking::getBookedEventList(Vector<sp<CTvBooking> > &vBv) +{ + String8 cmd; + + cmd = String8("select * from booking_table order by start"); + + CTvDatabase::Cursor c; + int ret = CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + do { + vBv.add(new CTvBooking(c)); + } while (c.moveToNext()); + + + } else { + c.close(); + return -1; + } + + c.close(); + return 0; + +} + +int CTvBooking::bookProgram(CTvProgram &prog, CTvEvent &evt) +{ + String8 cmd; + String8 progName = String8(prog.getName()); + String8 evtName = String8(evt.getName()); + + + /*book this program*/ + cmd = String8("insert into booking_table(db_srv_id, db_evt_id, srv_name, evt_name,") + + String8("start,duration,flag,status,file_name,vid_pid,vid_fmt,aud_pids,aud_fmts,aud_languages,") + + String8("sub_pids,sub_types,sub_composition_page_ids,sub_ancillary_page_ids,sub_languages,") + + String8("ttx_pids,ttx_types,ttx_magazine_numbers,ttx_page_numbers,ttx_languages, other_pids,from_storage,repeat)") + + String8("values(") + String8::format("%d,", prog.getID()) + String8::format("%d,", evt.getEventId()) + progName.string() + String8(",") + evtName.string() + + String8::format("%ld,", evt.getStartTime()) + String8::format("%ld,", evt.getEndTime() - evt.getStartTime()) + String8::format("%d,", flag) + + String8::format("%d,", status) + String8(",") + String8::format("%d,", prog.getVideo()->getPID()) + String8::format("%d,", prog.getVideo()->getFormat()) + + String8::format("%d,", prog.getAudio(0)->getPID()) + String8::format("%d,", prog.getAudio(0)->getFormat()) + prog.getAudio(0)->getLang().string() + + String8(" , , , , , , , , , , , , ,)"); + + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + + return 0; +} + +int CTvBooking::deleteBook(int evtIdFlag) +{ + String8 cmd; + + cmd = String8("delete from booking_table where db_evt_id=") + + String8::format("%d", evtIdFlag); + + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + + return 0; +} + +int CTvBooking::bookEvent(int evtId, bool bBookFlag) +{ + String8 cmd; + + cmd = String8("update evt_table set sub_flag=") + String8::format("%d", bBookFlag) + + String8(" where db_id=") + String8::format("%d", evtId); + + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + + if (true == bBookFlag) { + CTvEvent evt; + CTvEvent::selectByID(evtId, evt); + + CTvProgram prog; + CTvProgram::selectByID(evt.getProgramId(), prog); + + bookProgram(prog, evt); + } else { + deleteBook(evtId); + } + + return 0; + +} + +CTvBooking::CTvBooking(CTvDatabase::Cursor &c) +{ + InitFromCursor(c); +} + +CTvBooking::CTvBooking() +{ +} + +CTvBooking::~CTvBooking() +{ +} + + diff --git a/tv/tvserver/libtv/tv/CTvBooking.h b/tv/tvserver/libtv/tv/CTvBooking.h new file mode 100644 index 0000000..51881cf --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvBooking.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CTVBOOKING_H) +#define _CTVBOOKING_H + +#include "CTvDatabase.h" +#include "CTvProgram.h" +#include "CTvEvent.h" +#include <utils/String8.h> +#include <utils/RefBase.h> +#include <stdlib.h> +#include "CTvLog.h" + +class CTvBooking : public LightRefBase<CTvBooking> { +public: + CTvBooking(CTvDatabase::Cursor &c); + CTvBooking(); + ~CTvBooking(); + + static int selectByID(int id, CTvBooking &CtvBook); + + int bookEvent(int evtId, bool bBookFlag); + int getBookedEventList(Vector<sp<CTvBooking> > &vBv); + + int getBookId() + { + return id; + }; + int getProgramId() + { + return programId; + }; + int getEventId() + { + return eventId; + }; + int getStartTime() + { + return start; + }; + int getDurationTime() + { + return duration; + }; + String8 &getProgName() + { + return progName; + }; + String8 &getEvtName() + { + return evtName; + }; + +private: + int deleteBook(int evtIdFlag) ; + int bookProgram(CTvProgram &prog, CTvEvent &evt); + int InitFromCursor(CTvDatabase::Cursor &c); +private: + int id; + int programId; + int eventId; + int flag; + int status; + int repeat; + long start; + long duration; + String8 progName; + String8 evtName; +}; + +#endif //_CTVBOOKING_H diff --git a/tv/tvserver/libtv/tv/CTvDmx.cpp b/tv/tvserver/libtv/tv/CTvDmx.cpp new file mode 100644 index 0000000..cfe202c --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvDmx.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvDmx" + +#include "CTvDmx.h" +CTvDmx::CTvDmx(int id) +{ + mDmxDevId = id; +} + +CTvDmx::~CTvDmx() +{ +} + +#ifdef SUPPORT_ADTV +int CTvDmx::Open(AM_DMX_OpenPara_t ¶) +{ + return AM_DMX_Open ( mDmxDevId, ¶ ); +} + +int CTvDmx::Close() +{ + return AM_DMX_Close ( mDmxDevId ); +} + +int CTvDmx::SetSource(AM_DMX_Source_t source) +{ + return AM_DMX_SetSource ( mDmxDevId, source ); +} +#endif + diff --git a/tv/tvserver/libtv/tv/CTvDmx.h b/tv/tvserver/libtv/tv/CTvDmx.h new file mode 100644 index 0000000..014c09e --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvDmx.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _C_TV_DMX_H +#define _C_TV_DMX_H +#include "CTvEv.h" +#include "CTvLog.h" +#ifdef SUPPORT_ADTV +#include "am_dmx.h" +#endif + +class CTvDmx { +public: + CTvDmx(int id); + ~CTvDmx(); +#ifdef SUPPORT_ADTV + int Open(AM_DMX_OpenPara_t ¶); + int Close(); + int SetSource(AM_DMX_Source_t source); +#endif +private: + int mDmxDevId; +}; +#endif diff --git a/tv/tvserver/libtv/tv/CTvEas.cpp b/tv/tvserver/libtv/tv/CTvEas.cpp new file mode 100644 index 0000000..8afb58b --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvEas.cpp @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvEas" + +#include "CTvEas.h" + +CTvEas *CTvEas::mInstance; +CTvEas *CTvEas::GetInstance() +{ + LOGD("start eas action!\n"); + if (mInstance == NULL) { + mInstance = new CTvEas(); + } + + return mInstance; +} + +CTvEas::CTvEas() +{ + mpObserver = NULL; + mDmxId = INVALID_ID; +} + +CTvEas::~CTvEas() +{ + if (mInstance != NULL) { + delete mInstance; + mInstance = NULL; + } +} + +/** + * @Function: StartEasUpdate + * @Description: Start Update EAS info + * @Param: + * @Return:0 success, -1 fail + */ +int CTvEas::StartEasUpdate() +{ +#ifdef SUPPORT_ADTV + int val = 0; + val = EasCreate(0, 2, 0, NULL); //2 is demux id which according to DVB moudle! + if (val < 0) { + LOGD("EasCreate failed!\n"); + return -1; + } + + AM_ErrorCode_t ret; + ret = AM_EPG_ChangeMode(mEasScanHandle, MODE_ADD, SCAN_PSIP_CEA); + if (ret != DVB_SUCCESS) { + LOGD("StartEasUpdate failed!\n"); + return -1; + } +#endif + LOGD("StartEasUpdate success!\n"); + return 0; +} + +/** + * @Function: StopEasUpdate + * @Description: Stop Update EAS info + * @Param: + * @Return: 0 success, -1 fail + */ +int CTvEas::StopEasUpdate() +{ +#ifdef SUPPORT_ADTV + AM_ErrorCode_t ret; + ret = AM_EPG_ChangeMode(mEasScanHandle, MODE_REMOVE, SCAN_PSIP_CEA); + if (ret != DVB_SUCCESS) { + LOGD("StopEasUpdate failed!\n"); + } else { + LOGD("StopEasUpdate success!\n"); + } + + int val = 0; + val = EasDestroy(); + if (val < 0) { + LOGD("EasDestroy failed!\n"); + return -1; + } +#endif + return 0; +} + +/** + * @Function: EasCreate + * @Description: open dev for EAS and set EAS event + * @Param: fend_id: fend dev id; + dmx_id: demux dev id; + src: source; + textLangs:language; + * @Return: 0 success, -1 fail + */ +int CTvEas::EasCreate(int fend_id, int dmx_id, int src, char *textLangs) +{ +#ifdef SUPPORT_ADTV + AM_EPG_CreatePara_t para; + AM_ErrorCode_t ret; + AM_DMX_OpenPara_t dmx_para; + + LOGD("Opening demux%d ...", dmx_id); + mDmxId = dmx_id; + memset(&dmx_para, 0, sizeof(dmx_para)); + ret = AM_DMX_Open(dmx_id, &dmx_para); + if (ret != DVB_SUCCESS) { + LOGD("AM_DMX_Open failed"); + return - 1; + } + + para.fend_dev = fend_id; + para.dmx_dev = dmx_id; + para.source = src; + para.hdb = NULL; + + snprintf(para.text_langs, sizeof(para.text_langs), "%s", textLangs); + + ret = AM_EPG_Create(¶, &mEasScanHandle); + if (ret != DVB_SUCCESS) { + LOGD("AM_EPG_Create failed!\n"); + return -1; + } + + AM_EVT_Subscribe((long)mEasScanHandle, AM_EPG_EVT_NEW_CEA, EasEvtCallback, NULL); + + ret = AM_EPG_SetUserData(mEasScanHandle, (void *)this); + if (ret != DVB_SUCCESS) { + LOGD("AM_EPG_SetUserData failed!\n"); + return -1; + } +#endif + return 0; +} + +/** + * @Function: EasDestroy + * @Description: close dev for EAS and reset EAS event + * @Param: + * @Return: 0 success, -1 fail + */ +int CTvEas::EasDestroy() +{ +#ifdef SUPPORT_ADTV + AM_ErrorCode_t ret; + if (mEasScanHandle != NULL) { + /*unregister eit events notifications*/ + AM_EVT_Unsubscribe((long)mEasScanHandle, AM_EPG_EVT_NEW_CEA, EasEvtCallback, NULL); + + ret = AM_EPG_Destroy(mEasScanHandle); + mEasScanHandle = NULL; + } + + if (mDmxId != INVALID_ID) { + AM_DMX_Close(mDmxId); + mDmxId = INVALID_ID; + } + + if (ret != DVB_SUCCESS) { + LOGD("AM_EPG_SetUserData failed!\n"); + return -1; + } +#endif + return 0; +} + +/** + * @Function: EasEvtCallback + * @Description: EAS event callback function + * @Param:dev_no: dev id + event_type:RRT event type + param:callback data + user_data: + * @Return: + */ +void CTvEas::EasEvtCallback(long dev_no, int event_type, void *param, void *user_data __unused) +{ +#ifdef SUPPORT_ADTV + CTvEas *pEas; + + AM_EPG_GetUserData((void *)dev_no, (void **)&pEas); + + if ((pEas == NULL) || (pEas->mpObserver == NULL)) { + return; + } + + switch (event_type) { + case AM_EPG_EVT_NEW_CEA: { + dvbpsi_atsc_cea_t *tmp = (dvbpsi_atsc_cea_t *)param; + + int SectionCount = 0; + int MultistrCount = 0; + int DescriptorCount = 0; + int i , j; + SectionCount = mInstance->GetSectionCount(tmp); + pEas->mCurEasEv.eas_section_count = SectionCount; + dvbpsi_atsc_cea_t *tmp2 = (dvbpsi_atsc_cea_t *)param; + if (tmp2 != NULL) { + pEas->mCurEasEv.table_id = tmp2->i_table_id; + pEas->mCurEasEv.extension = tmp2->i_extension; + pEas->mCurEasEv.version = tmp2->i_version; + pEas->mCurEasEv.current_next = tmp2->b_current_next; + pEas->mCurEasEv.sequence_num = tmp2->i_sequence_num; + pEas->mCurEasEv.protocol_version = tmp2->i_protocol_version; + pEas->mCurEasEv.eas_event_id = tmp2->i_eas_event_id; + for (i=0;i<3;i++) { + pEas->mCurEasEv.eas_orig_code[i]= tmp2->i_eas_orig_code[i]; + } + + pEas->mCurEasEv.eas_event_code_len = tmp2->i_eas_event_code_len; + for (i=0;i<tmp2->i_eas_event_code_len;i++) { + pEas->mCurEasEv.eas_event_code[i] = tmp2->i_eas_event_code[i]; + } + + pEas->mCurEasEv.alert_message_time_remaining = tmp2->i_alert_message_time_remaining; + pEas->mCurEasEv.event_start_time = tmp2->i_event_start_time; + pEas->mCurEasEv.event_duration = tmp2->i_event_duration; + pEas->mCurEasEv.alert_priority = tmp2->i_alert_priority; + pEas->mCurEasEv.details_OOB_source_ID = tmp2->i_details_OOB_source_ID; + pEas->mCurEasEv.details_major_channel_number = tmp2->i_details_major_channel_number; + pEas->mCurEasEv.details_minor_channel_number = tmp2->i_details_minor_channel_number; + pEas->mCurEasEv.audio_OOB_source_ID = tmp2->i_audio_OOB_source_ID; + pEas->mCurEasEv.location_count = tmp2->i_location_count; + for (i=0;i<tmp2->i_location_count;i++) { + pEas->mCurEasEv.location[i].i_state_code = tmp2->location[i].i_state_code; + pEas->mCurEasEv.location[i].i_country_subdiv = tmp2->location[i].i_country_subdiv; + pEas->mCurEasEv.location[i].i_country_code = tmp2->location[i].i_country_code; + } + + pEas->mCurEasEv.exception_count = tmp2->i_exception_count; + for (i=0;i<tmp2->i_exception_count;i++) { + pEas->mCurEasEv.exception[i].i_in_band_refer = tmp2->exception[i].i_in_band_refer; + pEas->mCurEasEv.exception[i].i_exception_major_channel_number = tmp2->exception[i].i_exception_major_channel_number; + pEas->mCurEasEv.exception[i].i_exception_minor_channel_number = tmp2->exception[i].i_exception_minor_channel_number; + pEas->mCurEasEv.exception[i].exception_OOB_source_ID = tmp2->exception[i].exception_OOB_source_ID; + } + + dvbpsi_atsc_cea_multi_str_t *TempMulti1 = tmp2->p_first_multi_text; + dvbpsi_atsc_cea_multi_str_t *TempMulti2 = tmp2->p_first_multi_text; + if (TempMulti2 != NULL) { + MultistrCount = mInstance->GetMultiCount(TempMulti1); + } + pEas->mCurEasEv.multi_text_count = MultistrCount; + for (i=0;i<MultistrCount;i++) { + while (TempMulti2 != NULL) { + for (j=0;j<3;j++) { + pEas->mCurEasEv.multi_text[i].lang[j] = TempMulti2->lang[j]; + } + pEas->mCurEasEv.multi_text[i].i_type = TempMulti2->i_type; + pEas->mCurEasEv.multi_text[i].i_compression_type = TempMulti2->i_compression_type; + pEas->mCurEasEv.multi_text[i].i_mode = TempMulti2->i_mode; + pEas->mCurEasEv.multi_text[i].i_number_bytes = TempMulti2->i_number_bytes; + for (j=0;j<TempMulti2->i_number_bytes;j++) { + pEas->mCurEasEv.multi_text[i].compressed_str[j] = TempMulti2->compressed_str[j]; + } + TempMulti2 = TempMulti2->p_next; + } + } + + dvbpsi_descriptor_t *TempDesc1 = tmp2->p_first_descriptor; + dvbpsi_descriptor_t *TempDesc2 = tmp2->p_first_descriptor; + + if (TempMulti1 != NULL) { + DescriptorCount = mInstance->GetDescCount(TempDesc1); + } + pEas->mCurEasEv.descriptor_text_count = DescriptorCount; + + for (i=0;i<DescriptorCount;i++) { + while (TempDesc2 != NULL) { + pEas->mCurEasEv.descriptor[i].i_tag = TempDesc2->i_tag; + pEas->mCurEasEv.descriptor[i].i_length = TempDesc2->i_length; + memcpy(pEas->mCurEasEv.descriptor[i].p_data, TempDesc2->p_data, TempDesc2->i_length); + TempDesc2 = TempDesc2->p_next; + } + } + + pEas->mpObserver->onEvent(pEas->mCurEasEv); + //tmp2 = tmp2->p_next; + } + break; + } + default: + break; + } +#endif +} + +#ifdef SUPPORT_ADTV +/** + * @Function: GetSectionCount + * @Description: Get EAS Section Count + * @Param:pData:Address of atsc eas string which need to check count + * @Return:count result + */ +int CTvEas::GetSectionCount(dvbpsi_atsc_cea_t *pData) +{ + int count = 0; + while (pData != NULL) { + count ++; + pData = pData->p_next; + } + LOGD("section: count = %d\n", count); + return count; +} + +/** + * @Function: GetDescCount + * @Description: Get EAS descriptor string Count + * @Param:pData:Address of atsc eas descriptor string which need to check count + * @Return:count result + */ +int CTvEas::GetDescCount(dvbpsi_descriptor_t *pData) +{ + int count = 0; + while (pData != NULL) { + count ++; + pData = pData->p_next; + } + LOGD("descriptor: count = %d\n", count); + return count; +} + +/** + * @Function: GetMultiCount + * @Description: Get EAS multi string Count + * @Param:pData:Address of atsc eas multi string which need to check count + * @Return:count result + */ +int CTvEas::GetMultiCount(dvbpsi_atsc_cea_multi_str_t *pData) +{ + int count = 0; + while (pData != NULL) { + count ++; + pData = pData->p_next; + } + LOGD("multi: count = %d\n", count); + return count; +} +#endif + diff --git a/tv/tvserver/libtv/tv/CTvEas.h b/tv/tvserver/libtv/tv/CTvEas.h new file mode 100644 index 0000000..8ae2b88 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvEas.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifdef SUPPORT_ADTV +#include <am_debug.h> +#include <am_epg.h> +#endif +#include "CTvLog.h" +#include "CTvEv.h" +#if !defined(_CDTVEAS_H) +#define _CDTVEAS_H + +typedef struct cea_location_code_s +{ + int i_state_code; + int i_country_subdiv; /**<the language of mlti str*/ + int i_country_code; + +} cea_location_code_t; + +typedef struct cea_exception_code_s +{ + int i_in_band_refer; + int i_exception_major_channel_number; /**<the exception major channel num*/ + int i_exception_minor_channel_number; /**<the exception minor channel num*/ + int exception_OOB_source_ID; /**<the exception oob source id*/ +} cea_exception_code_t; + +typedef struct cea_multi_str_s +{ + int lang[3]; /**<the language of mlti str*/ + int i_type; /**<the str type, alert or nature*/ + int i_compression_type; /*!< compression type */ + int i_mode; /*!< mode */ + int i_number_bytes; /*!< number bytes */ + int compressed_str[64]; /**<the compressed str*/ +} cea_multi_str_t; + +typedef struct descriptor_s +{ + int i_tag; /*!< descriptor_tag */ + int i_length; /*!< descriptor_length */ + int p_data[64]; /*!< content */ +} descriptor_t; + +class CTvEas { +public : + static const int MODE_ADD = 0; + static const int MODE_REMOVE = 1; + static const int MODE_SET = 2; + + static const int SCAN_PSIP_CEA = 0x10000; + + static const int INVALID_ID = -1; + + class EasEvent : public CTvEv { + public: + EasEvent(): CTvEv(CTvEv::TV_EVENT_EAS) + { + + }; + ~EasEvent() + { + + }; + + int eas_section_count; /*!< eas struct count */ + int table_id; /*!< table id */ + int extension; /*!< subtable id */ + int version; /*!< version_number */ + int current_next; /*!< current_next_indicator */ + int sequence_num; /*!< sequence version*/ + int protocol_version; /*!< protocol version*/ + int eas_event_id; /*!< eas event id */ + int eas_orig_code[3]; /*!< eas event orig code */ + int eas_event_code_len; /*!< eas event code len */ + int eas_event_code[64]; /*!< eas event code */ + int alert_message_time_remaining; /*!< alert msg remain time */ + int event_start_time; /*!< eas event start time */ + int event_duration; /*!< event dur */ + int alert_priority; /*!< alert priority */ + int details_OOB_source_ID; /*!< details oob source id */ + int details_major_channel_number; /*!< details major channel num */ + int details_minor_channel_number; /*!< details minor channel num */ + int audio_OOB_source_ID; /*!< audio oob source id */ + int location_count; /*!< location count */ + cea_location_code_t location[64]; /*!< location info */ + int exception_count; /*!< exception count */ + cea_exception_code_t exception[64]; /*!< exception info */ + int multi_text_count; /*!< multi_text count */ + cea_multi_str_t multi_text[2]; /*!< nature and alert multi str information structure. */ + int descriptor_text_count; /*!< descriptor text count. */ + descriptor_t descriptor[2]; /*!< descriptor structure. */ + }; + + class IObserver { + public: + IObserver() {}; + virtual ~IObserver() {}; + virtual void onEvent(const EasEvent &ev) = 0; + }; + + int setObserver(IObserver *ob) + { + mpObserver = ob; + return 0; + } + + static CTvEas *GetInstance(); + CTvEas(); + ~CTvEas(); + int StartEasUpdate(); + int StopEasUpdate(); + + static CTvEas *mInstance; + void * mEasScanHandle = nullptr; + + +private: + int EasCreate(int fend_id, int dmx_id, int src, char *textLangs); + int EasDestroy(); + static void EasEvtCallback(long dev_no, int event_type, void *param, void *user_data); +#ifdef SUPPORT_ADTV + int GetSectionCount(dvbpsi_atsc_cea_t *pData); + int GetDescCount(dvbpsi_descriptor_t *pData); + int GetMultiCount(dvbpsi_atsc_cea_multi_str_t *pData); +#endif + + IObserver *mpObserver; + int mDmxId ; + EasEvent mCurEasEv; +}; +#endif //_CDTVEAS_H diff --git a/tv/tvserver/libtv/tv/CTvEpg.cpp b/tv/tvserver/libtv/tv/CTvEpg.cpp new file mode 100644 index 0000000..2ed248b --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvEpg.cpp @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvEpg" + +#include "CTvEpg.h" +#include "CTvChannel.h" + +void CTvEpg::epg_evt_callback(long dev_no, int event_type, void *param, void *user_data __unused) +{ +#ifdef SUPPORT_ADTV + CTvEpg *pEpg; + + AM_EPG_GetUserData((void *)dev_no, (void **)&pEpg); + + if (pEpg == NULL) return; + + if (pEpg->mpObserver == NULL) { + return; + } + switch (event_type) { + case AM_EPG_EVT_NEW_TDT: + case AM_EPG_EVT_NEW_STT: { + int utc_time; + AM_EPG_GetUTCTime(&utc_time); + pEpg->mCurEpgEv.type = EpgEvent::EVENT_TDT_END; + pEpg->mCurEpgEv.time = (long)utc_time; + pEpg->mpObserver->onEvent(pEpg->mCurEpgEv); + } + break; + case AM_EPG_EVT_UPDATE_EVENTS: + pEpg->mCurEpgEv.type = EpgEvent::EVENT_PROGRAM_EVENTS_UPDATE; + pEpg->mCurEpgEv.programID = (long)param; + pEpg->mpObserver->onEvent(pEpg->mCurEpgEv); + break; + case AM_EPG_EVT_UPDATE_PROGRAM_AV: + pEpg->mCurEpgEv.type = EpgEvent::EVENT_PROGRAM_AV_UPDATE; + pEpg->mCurEpgEv.programID = (long)param; + pEpg->mpObserver->onEvent(pEpg->mCurEpgEv); + break; + case AM_EPG_EVT_UPDATE_PROGRAM_NAME: + pEpg->mCurEpgEv.type = EpgEvent::EVENT_PROGRAM_NAME_UPDATE; + pEpg->mCurEpgEv.programID = (long)param; + pEpg->mpObserver->onEvent(pEpg->mCurEpgEv); + break; + case AM_EPG_EVT_UPDATE_TS: + pEpg->mCurEpgEv.type = EpgEvent::EVENT_CHANNEL_UPDATE; + pEpg->mCurEpgEv.channelID = (long)param; + pEpg->mpObserver->onEvent(pEpg->mCurEpgEv); + break; + default: + break; + } +#endif +} + +void CTvEpg::Init(int fend, int dmx, int fend_mod, char *textLanguages, char *dvb_text_coding) +{ + mFend_dev_id = fend; + mDmx_dev_id = dmx; + mFend_mod = fend_mod; + epg_create(fend, dmx, fend_mod, textLanguages); + epg_set_dvb_text_coding(dvb_text_coding); +} + +void CTvEpg::epg_create(int fend_id, int dmx_id, int src, char *textLangs) +{ +#ifdef SUPPORT_ADTV + AM_EPG_CreatePara_t para; + AM_ErrorCode_t ret; + AM_FEND_OpenPara_t fend_para; + AM_DMX_OpenPara_t dmx_para; + + LOGD("Opening demux%d ...", dmx_id); + memset(&dmx_para, 0, sizeof(dmx_para)); + AM_DMX_Open(dmx_id, &dmx_para); + + para.fend_dev = fend_id; + para.dmx_dev = dmx_id; + para.source = src; + para.hdb = NULL; + + snprintf(para.text_langs, sizeof(para.text_langs), "%s", textLangs); + + ret = AM_EPG_Create(¶, &mEpgScanHandle); + if (ret != DVB_SUCCESS) { + LOGD("AM_EPG_Create failed"); + return; + } + + /*register eit events notifications*/ + AM_EVT_Subscribe((long)mEpgScanHandle, AM_EPG_EVT_NEW_TDT, epg_evt_callback, NULL); + AM_EVT_Subscribe((long)mEpgScanHandle, AM_EPG_EVT_NEW_STT, epg_evt_callback, NULL); + AM_EVT_Subscribe((long)mEpgScanHandle, AM_EPG_EVT_UPDATE_EVENTS, epg_evt_callback, NULL); + AM_EVT_Subscribe((long)mEpgScanHandle, AM_EPG_EVT_UPDATE_PROGRAM_AV, epg_evt_callback, NULL); + AM_EVT_Subscribe((long)mEpgScanHandle, AM_EPG_EVT_UPDATE_PROGRAM_NAME, epg_evt_callback, NULL); + AM_EVT_Subscribe((long)mEpgScanHandle, AM_EPG_EVT_UPDATE_TS, epg_evt_callback, NULL); + AM_EPG_SetUserData(mEpgScanHandle, (void *)this); +#endif +} + +void CTvEpg::epg_destroy() +{ +#ifdef SUPPORT_ADTV + if (mEpgScanHandle != NULL) { + /*unregister eit events notifications*/ + AM_EVT_Unsubscribe((long)mEpgScanHandle, AM_EPG_EVT_NEW_TDT, epg_evt_callback, NULL); + AM_EVT_Unsubscribe((long)mEpgScanHandle, AM_EPG_EVT_NEW_STT, epg_evt_callback, NULL); + AM_EVT_Unsubscribe((long)mEpgScanHandle, AM_EPG_EVT_UPDATE_EVENTS, epg_evt_callback, NULL); + AM_EVT_Unsubscribe((long)mEpgScanHandle, AM_EPG_EVT_UPDATE_PROGRAM_AV, epg_evt_callback, NULL); + AM_EVT_Unsubscribe((long)mEpgScanHandle, AM_EPG_EVT_UPDATE_PROGRAM_NAME, epg_evt_callback, NULL); + AM_EVT_Unsubscribe((long)mEpgScanHandle, AM_EPG_EVT_UPDATE_TS, epg_evt_callback, NULL); + AM_EPG_Destroy(mEpgScanHandle); + } + + if (mDmx_dev_id != INVALID_ID) + AM_DMX_Close(mDmx_dev_id); +#endif +} + +void CTvEpg::epg_change_mode(int op, int mode) +{ +#ifdef SUPPORT_ADTV + AM_ErrorCode_t ret; + ret = AM_EPG_ChangeMode(mEpgScanHandle, op, mode); + if (ret != DVB_SUCCESS) + LOGD("AM_EPG_ChangeMode failed"); +#endif +} + +void CTvEpg::epg_monitor_service(int srv_id) +{ +#ifdef SUPPORT_ADTV + int ret = AM_EPG_MonitorService(mEpgScanHandle, srv_id); + if (ret != DVB_SUCCESS) + LOGD("AM_EPG_MonitorService failed"); +#endif +} + +void CTvEpg::epg_set_dvb_text_coding(char *coding) +{ +#ifdef SUPPORT_ADTV + if (!strcmp(coding, "standard")) { + AM_SI_SetDefaultDVBTextCoding(""); + } else { + AM_SI_SetDefaultDVBTextCoding(coding); + } +#endif +} + +/*Start scan the sections.*/ +void CTvEpg::startScan(int mode) +{ + epg_change_mode(MODE_ADD, mode); +} + +/*Stop scan the sections.*/ +void CTvEpg::stopScan(int mode) +{ + epg_change_mode(MODE_REMOVE, mode); +} + +/*Enter a channel.*/ +void CTvEpg::enterChannel(int chan_id) +{ + + if (chan_id == mCurScanChannelId) + return; + //already enter,leave it + if (mCurScanChannelId != INVALID_ID) { + leaveChannel(); + } + + if (mFend_mod == CTvChannel::MODE_ATSC) { + startScan(SCAN_PSIP_ETT | SCAN_PSIP_EIT | SCAN_MGT | SCAN_VCT | SCAN_RRT | SCAN_STT); + } else { + startScan(SCAN_EIT_ALL | SCAN_SDT | SCAN_NIT | SCAN_TDT | SCAN_CAT); + } + + mCurScanChannelId = chan_id; +} + +/*Leave the channel.*/ +void CTvEpg::leaveChannel() +{ + + stopScan(SCAN_ALL); + mCurScanChannelId = INVALID_ID; +} + +/*Enter the program.*/ +void CTvEpg::enterProgram(int prog_id) +{ + if (prog_id == mCurScanProgramId) + return; + + if (mCurScanProgramId != INVALID_ID) { + leaveProgram(); + } + + mCurScanProgramId = prog_id; + epg_monitor_service(mCurScanProgramId);//---------db_id + startScan(SCAN_PAT | SCAN_PMT); +} + +/*Leave the program.*/ +void CTvEpg::leaveProgram() +{ + if (mCurScanProgramId == INVALID_ID) + return; + + stopScan(SCAN_PAT | SCAN_PMT); + epg_monitor_service(-1); + mCurScanProgramId = INVALID_ID; +} diff --git a/tv/tvserver/libtv/tv/CTvEpg.h b/tv/tvserver/libtv/tv/CTvEpg.h new file mode 100644 index 0000000..ac1b75f --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvEpg.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifdef SUPPORT_ADTV +#include <am_debug.h> +#include <am_scan.h> +#include <am_epg.h> +#include <am_mem.h> +#endif + +#include <utils/Log.h> +#include "CTvEv.h" +#if !defined(_CDTVEPG_H) +#define _CDTVEPG_H +class CTvEpg { +public : + static const int MODE_ADD = 0; + static const int MODE_REMOVE = 1; + static const int MODE_SET = 2; + + static const int SCAN_PAT = 0x01; + static const int SCAN_PMT = 0x02; + static const int SCAN_CAT = 0x04; + static const int SCAN_SDT = 0x08; + static const int SCAN_NIT = 0x10; + static const int SCAN_TDT = 0x20; + static const int SCAN_EIT_PF_ACT = 0x40; + static const int SCAN_EIT_PF_OTH = 0x80; + static const int SCAN_EIT_SCHE_ACT = 0x100; + static const int SCAN_EIT_SCHE_OTH = 0x200; + static const int SCAN_MGT = 0x400; + static const int SCAN_VCT = 0x800; + static const int SCAN_STT = 0x1000; + static const int SCAN_RRT = 0x2000; + static const int SCAN_PSIP_EIT = 0x4000; + static const int SCAN_PSIP_ETT = 0x8000; + static const int SCAN_EIT_PF_ALL = SCAN_EIT_PF_ACT | SCAN_EIT_PF_OTH; + static const int SCAN_EIT_SCHE_ALL = SCAN_EIT_SCHE_ACT | SCAN_EIT_SCHE_OTH; + static const int SCAN_EIT_ALL = SCAN_EIT_PF_ALL | SCAN_EIT_SCHE_ALL; + static const int SCAN_ALL = SCAN_PAT | SCAN_PMT | SCAN_CAT | SCAN_SDT | SCAN_NIT | SCAN_TDT | SCAN_EIT_ALL | + SCAN_MGT | SCAN_VCT | SCAN_STT | SCAN_RRT | SCAN_PSIP_EIT | SCAN_PSIP_ETT; + + static const int INVALID_ID = -1; + + //egp notify + /*static const int EVENT_PF_EIT_END = 1; + static const int EVENT_SCH_EIT_END = 2; + static const int EVENT_PMT_END = 3; + static const int EVENT_SDT_END = 4; + static const int EVENT_TDT_END = 5; + static const int EVENT_NIT_END = 6; + static const int EVENT_PROGRAM_AV_UPDATE = 7; + static const int EVENT_PROGRAM_NAME_UPDATE = 8; + static const int EVENT_PROGRAM_EVENTS_UPDATE = 9; + static const int EVENT_CHANNEL_UPDATE = 10;*/ + // + class EpgEvent : public CTvEv { + public: + EpgEvent(): CTvEv(CTvEv::TV_EVENT_EPG) + { + + }; + ~EpgEvent() + { + }; + static const int EVENT_PF_EIT_END = 1; + static const int EVENT_SCH_EIT_END = 2; + static const int EVENT_PMT_END = 3; + static const int EVENT_SDT_END = 4; + static const int EVENT_TDT_END = 5; + static const int EVENT_NIT_END = 6; + static const int EVENT_PROGRAM_AV_UPDATE = 7; + static const int EVENT_PROGRAM_NAME_UPDATE = 8; + static const int EVENT_PROGRAM_EVENTS_UPDATE = 9; + static const int EVENT_CHANNEL_UPDATE = 10; + static const int EVENT_CHANNEL_UPDATE_END = 11; + + int type; + int channelID; + long programID; + int dvbOrigNetID; + int dvbTSID; + int dvbServiceID; + long time; + int dvbVersion; + }; + + class IObserver { + public: + IObserver() {}; + virtual ~IObserver() {}; + virtual void onEvent(const EpgEvent &ev) = 0; + }; + //1 VS n + //int addObserver(IObserver* ob); + //int removeObserver(IObserver* ob); + + //1 VS 1 + int setObserver(IObserver *ob) + { + mpObserver = ob; + return 0; + } + + CTvEpg() + { + mCurScanChannelId = INVALID_ID; + mCurScanProgramId = INVALID_ID; + mpObserver = NULL; + mDmx_dev_id = INVALID_ID; + } + void Init(int fend, int dmx, int fend_mod, char *textLanguages, char *dvb_text_coding); + + ~CTvEpg() + { + epg_destroy(); + } + + /*Enter a channel.*/ + void enterChannel(int chan_id); + /*Leave the channel.*/ + void leaveChannel(); + /*Enter the program.*/ + void enterProgram(int prog_id); + /*Leave the program.*/ + void leaveProgram(); + +private: + // + void epg_create(int fend_id, int dmx_id, int src, char *textLangs); + void epg_destroy(); + void epg_change_mode(int op, int mode); + void epg_monitor_service(int srv_id); + void epg_set_dvb_text_coding(char *coding); + + + /*Start scan the sections.*/ + void startScan(int mode); + /*Stop scan the sections.*/ + void stopScan(int mode); + + static void epg_evt_callback(long dev_no, int event_type, void *param, void *user_data); + + // + IObserver *mpObserver; + +#ifdef SUPPORT_ADTV + void * mEpgScanHandle; +#endif + int mFend_dev_id; + int mDmx_dev_id ; + int mFend_mod; + int mCurScanChannelId ; + int mCurScanProgramId ; + + // + EpgEvent mCurEpgEv; +}; +#endif //_CDTVEPG_H diff --git a/tv/tvserver/libtv/tv/CTvEv.cpp b/tv/tvserver/libtv/tv/CTvEv.cpp new file mode 100644 index 0000000..b48a04b --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvEv.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" + +#include "CTvEv.h" +CTvEv::CTvEv(int type) +{ + mEvType = type; +} diff --git a/tv/tvserver/libtv/tv/CTvEv.h b/tv/tvserver/libtv/tv/CTvEv.h new file mode 100644 index 0000000..7db81e4 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvEv.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _CTVEV_H_ +#define _CTVEV_H_ + +#include <utils/String8.h> +#define CC_MAX_SERIAL_RD_BUF_LEN (1200) + +using namespace android; + +class CTvEv { +public: + static const int TV_EVENT_COMMOM = 0; + static const int TV_EVENT_SCANNER = 1; + static const int TV_EVENT_EPG = 2;//EPG + static const int TV_EVENT_SOURCE_SWITCH = 3; + static const int TV_EVENT_SIGLE_DETECT = 4; + static const int TV_EVENT_ADC_CALIBRATION = 5; + static const int TV_EVENT_VGA = 6;//VGA + static const int TV_EVENT_3D_STATE = 7;//3D + static const int TV_EVENT_AV_PLAYBACK = 8;//PLAYBACK EVENT MSG + static const int TV_EVENT_SERIAL_COMMUNICATION = 9; + static const int TV_EVENT_SOURCE_CONNECT = 10; + static const int TV_EVENT_HDMIRX_CEC = 11; + static const int TV_EVENT_BLOCK = 12; + static const int TV_EVENT_CC = 13; //close caption + static const int TV_EVENT_VCHIP = 14; //VCHIP + static const int TV_EVENT_HDMI_IN_CAP = 15; + static const int TV_EVENT_UPGRADE_FBC = 16; + static const int TV_EVENT_2d4G_HEADSET = 17; + static const int TV_EVENT_AV = 18; + static const int TV_EVENT_SUBTITLE = 19; + static const int TV_EVENT_SCANNING_FRAME_STABLE = 20; + static const int TV_EVENT_FRONTEND = 21; + static const int TV_EVENT_RECORDER = 22; + static const int TV_EVENT_RRT = 23;//RRT + static const int TV_EVENT_EAS = 24;//EAS + + CTvEv(int type); + virtual ~CTvEv() {}; + int getEvType() const { + return mEvType; + }; +private: + int mEvType; +}; + +namespace TvEvent { + //events + class SignalInfoEvent: public CTvEv { + public: + SignalInfoEvent() : CTvEv ( CTvEv::TV_EVENT_SIGLE_DETECT ) {} + ~SignalInfoEvent() {} + int mTrans_fmt; + int mFmt; + int mStatus; + int mReserved; + }; + + class VGAEvent: public CTvEv { + public: + VGAEvent() : CTvEv ( CTvEv::TV_EVENT_VGA ) {} + ~VGAEvent() {} + int mState; + }; + + class ADCCalibrationEvent: public CTvEv { + public: + ADCCalibrationEvent() : CTvEv ( CTvEv::TV_EVENT_ADC_CALIBRATION ) {} + ~ADCCalibrationEvent() {} + int mState; + }; + + class SerialCommunicationEvent: public CTvEv { + public: + SerialCommunicationEvent(): CTvEv(CTvEv::TV_EVENT_SERIAL_COMMUNICATION) {} + ~SerialCommunicationEvent() {} + + int mDevId; + int mDataCount; + unsigned char mDataBuf[CC_MAX_SERIAL_RD_BUF_LEN]; + }; + + class SourceConnectEvent: public CTvEv { + public: + SourceConnectEvent() : CTvEv ( CTvEv::TV_EVENT_SOURCE_CONNECT ) {} + ~SourceConnectEvent() {} + int mSourceInput; + int connectionState; + }; + + class HDMIRxCECEvent: public CTvEv { + public: + HDMIRxCECEvent() : CTvEv ( CTvEv::TV_EVENT_HDMIRX_CEC ) {} + ~HDMIRxCECEvent() {} + int mDataCount; + int mDataBuf[32]; + }; + + class AVPlaybackEvent: public CTvEv { + public: + AVPlaybackEvent() : CTvEv ( CTvEv::TV_EVENT_AV_PLAYBACK ) {} + ~AVPlaybackEvent() {} + static const int EVENT_AV_PLAYBACK_NODATA = 1; + static const int EVENT_AV_PLAYBACK_RESUME = 2; + static const int EVENT_AV_SCAMBLED = 3; + static const int EVENT_AV_UNSUPPORT = 4; + static const int EVENT_AV_VIDEO_AVAILABLE = 5; + + static const int EVENT_AV_TIMESHIFT_REC_FAIL = 6; + static const int EVENT_AV_TIMESHIFT_PLAY_FAIL = 7; + static const int EVENT_AV_TIMESHIFT_START_TIME_CHANGED = 8; + static const int EVENT_AV_TIMESHIFT_CURRENT_TIME_CHANGED = 9; + + int mMsgType; + int mProgramId; + }; + + class BlockEvent: public CTvEv { + public: + BlockEvent() : CTvEv ( CTvEv::TV_EVENT_BLOCK ) {} + ~BlockEvent() {} + + bool block_status; + int programBlockType; + String8 vchipDimension; + String8 vchipAbbrev; + String8 vchipAbbtext; + }; + + class UpgradeFBCEvent: public CTvEv { + public: + UpgradeFBCEvent() : CTvEv ( CTvEv::TV_EVENT_UPGRADE_FBC ) {} + ~UpgradeFBCEvent() {} + int mState; + int param; + }; + + class HeadSetOf2d4GEvent: public CTvEv { + public: + HeadSetOf2d4GEvent(): CTvEv(CTvEv::TV_EVENT_2d4G_HEADSET) {} + ~HeadSetOf2d4GEvent() {} + + int state; + int para; + }; + + class SubtitleEvent: public CTvEv { + public: + SubtitleEvent(): CTvEv(CTvEv::TV_EVENT_SUBTITLE) {} + ~SubtitleEvent() {} + int pic_width; + int pic_height; + }; + + class ScanningFrameStableEvent: public CTvEv { + public: + ScanningFrameStableEvent(): CTvEv(CTvEv::TV_EVENT_SCANNING_FRAME_STABLE) {} + ~ScanningFrameStableEvent() {} + int CurScanningFreq; + }; + + class FrontendEvent: public CTvEv { + public: + FrontendEvent() : CTvEv ( CTvEv::TV_EVENT_FRONTEND ) {} + ~FrontendEvent() {} + static const int EVENT_FE_HAS_SIG = 0x01; + static const int EVENT_FE_NO_SIG = 0x02; + static const int EVENT_FE_INIT = 0x03; + + int mStatus; + int mFrequency; + int mParam1; + int mParam2; + int mParam3; + int mParam4; + int mParam5; + int mParam6; + int mParam7; + int mParam8; + }; + + class RecorderEvent: public CTvEv { + public: + RecorderEvent() : CTvEv ( CTvEv::TV_EVENT_RECORDER) {} + ~RecorderEvent() {} + static const int EVENT_RECORD_START = 0x01; + static const int EVENT_RECORD_STOP = 0x02; + + String8 mId; + int mStatus; + int mError; + }; + +}; +#endif + diff --git a/tv/tvserver/libtv/tv/CTvFactory.cpp b/tv/tvserver/libtv/tv/CTvFactory.cpp new file mode 100644 index 0000000..d718758 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvFactory.cpp @@ -0,0 +1,1339 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvFactory" + +#include <CTvFactory.h> +#include <tvconfig.h> +#include <tvutils.h> +#include "../tvsetting/CTvSetting.h" + +CTvFactory::CTvFactory() + :mHdmiOutFbc(false), + mFbcObj(NULL) +{ +} + +void CTvFactory::init() +{ + const char *value = config_get_str(CFG_SECTION_TV, CFG_FBC_USED, "true"); + if (strcmp(value, "true") == 0) { + mHdmiOutFbc = true; + mFbcObj = GetSingletonFBC(); + } +} + +int CTvFactory::setPQModeBrightness (int sourceType __unused, int pqMode, int brightness) +{ + return CVpp::getInstance()->FactorySetPQMode_Brightness(pqMode, pqMode, brightness); +} + +int CTvFactory::getPQModeBrightness (int tv_source_input, int pqMode) +{ + return CVpp::getInstance()->FactoryGetPQMode_Brightness(tv_source_input, pqMode); +} + +int CTvFactory::setPQModeContrast (int tv_source_input, int pqMode, int contrast) +{ + return CVpp::getInstance()->FactorySetPQMode_Contrast(tv_source_input, pqMode, contrast); +} + +int CTvFactory::getPQModeContrast (int tv_source_input, int pqMode) +{ + return CVpp::getInstance()->FactoryGetPQMode_Contrast(tv_source_input, pqMode); +} + +int CTvFactory::setPQModeSaturation ( int tv_source_input, int pqMode, int saturation ) +{ + return CVpp::getInstance()->FactorySetPQMode_Saturation(tv_source_input, pqMode, saturation); +} + +int CTvFactory::getPQModeSaturation ( int tv_source_input, int pqMode ) +{ + return CVpp::getInstance()->FactoryGetPQMode_Saturation(tv_source_input, pqMode); +} + +int CTvFactory::setPQModeHue ( int tv_source_input, int pqMode, int hue ) +{ + return CVpp::getInstance()->FactorySetPQMode_Hue(tv_source_input, pqMode, hue); +} + +int CTvFactory::getPQModeHue ( int tv_source_input, int pqMode ) +{ + return CVpp::getInstance()->FactoryGetPQMode_Hue(tv_source_input, pqMode); +} + +int CTvFactory::setPQModeSharpness ( int tv_source_input, int pqMode, int sharpness ) +{ + return CVpp::getInstance()->FactorySetPQMode_Sharpness(tv_source_input, pqMode, sharpness); +} + +int CTvFactory::getPQModeSharpness ( int tv_source_input, int pqMode ) +{ + return CVpp::getInstance()->FactoryGetPQMode_Sharpness(tv_source_input, pqMode); +} + +int CTvFactory::resetPQMode () +{ + return CVpp::getInstance()->FactoryResetPQMode(); +} + +int CTvFactory::replacePQDb(const char *newFilePath) +{ + return 0; +} + +int CTvFactory::setGamma(tcon_gamma_table_t gamma_r, tcon_gamma_table_t gamma_g, tcon_gamma_table_t gamma_b) +{ + if (mHdmiOutFbc) { + return mFbcObj->fbcSetGammaPattern(COMM_DEV_SERIAL, gamma_r.data[0], gamma_g.data[0], gamma_b.data[0]); + } else { + return CVpp::getInstance()->FactorySetGamma(gamma_r, gamma_g, gamma_b); + } +} + +int CTvFactory::getColorTemperatureParams ( vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t *params ) +{ + if (mHdmiOutFbc) { + int ret = colorTempBatchGet((vpp_color_temperature_mode_t)Tempmode, params); + params->r_gain = formatOutputGainParams(params->r_gain); + params->g_gain = formatOutputGainParams(params->g_gain); + params->b_gain = formatOutputGainParams(params->b_gain); + params->r_post_offset = formatOutputOffsetParams(params->r_post_offset); + params->g_post_offset = formatOutputOffsetParams(params->g_post_offset); + params->b_post_offset = formatOutputOffsetParams(params->b_post_offset); + return ret; + } else { + return CVpp::getInstance()->GetColorTemperatureParams(Tempmode, params); + } +} + +int CTvFactory::setTestPattern ( int pattern ) +{ + switch ( pattern ) { + case VPP_TEST_PATTERN_NONE: + mAv.SetVideoScreenColor ( 3, 16, 128, 128 ); + break; + + case VPP_TEST_PATTERN_RED: + mAv.SetVideoScreenColor ( 0, 81, 90, 240 ); + break; + + case VPP_TEST_PATTERN_GREEN: + mAv.SetVideoScreenColor ( 0, 145, 54, 34 ); + break; + + case VPP_TEST_PATTERN_BLUE: + mAv.SetVideoScreenColor ( 0, 41, 240, 110 ); + break; + + case VPP_TEST_PATTERN_WHITE: + mAv.SetVideoScreenColor ( 0, 235, 128, 128 ); + break; + + case VPP_TEST_PATTERN_BLACK: + mAv.SetVideoScreenColor ( 0, 16, 128, 128 ); + break; + + default: + return -1; + } + return SSMSaveTestPattern ( pattern ); +} + +int CTvFactory::getTestPattern () +{ + return CVpp::getInstance()->FactoryGetTestPattern(); +} + +int CTvFactory::setRGBPattern (int r, int g, int b) +{ + return mAv.setRGBScreen(r, g, b); +} + +int CTvFactory::getRGBPattern() +{ + return mAv.getRGBScreen(); +} + +int CTvFactory::setScreenColor ( int vdinBlendingMask, int y, int u, int v ) +{ + return mAv.SetVideoScreenColor ( vdinBlendingMask, y, u, v ); +} + +int CTvFactory::resetColorTemp () +{ + return CVpp::getInstance()->FactoryResetColorTemp(); +} + +int CTvFactory::setParamsDefault () +{ + return CVpp::getInstance()->FactorySetParamsDefault(); +} + +int CTvFactory::setDDRSSC ( int step ) +{ + return CVpp::getInstance()->FactorySetDDRSSC(step); +} + +int CTvFactory::getDDRSSC () +{ + return CVpp::getInstance()->FactoryGetDDRSSC(); +} + +int CTvFactory::setLVDSSSC ( int step ) +{ + return CVpp::getInstance()->FactorySetLVDSSSC(step); +} + +int CTvFactory::getLVDSSSC () +{ + return CVpp::getInstance()->FactoryGetLVDSSSC(); +} + +int CTvFactory::setNolineParams ( int nolineParamstype, int tv_source_input, noline_params_t nolineParams ) +{ + return CVpp::getInstance()->FactorySetNolineParams(nolineParamstype, tv_source_input, nolineParams); +} + +noline_params_t CTvFactory::getNolineParams ( int nolineParamstype, int tv_source_input ) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + + return CVpp::getInstance()->FactoryGetNolineParams(nolineParamstype, sourceType); +} + +int CTvFactory::setOverscan ( int tv_source_input, int fmt, int transFmt, tvin_cutwin_t cutwin ) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + CVpp::getInstance()->FactorySetOverscan(sourceType, fmt, transFmt, cutwin); +#if 0 + char val_buf[256]; + memset(val_buf, '\0', 256); + LOGD("%s,%d: %d,%d,%d,%d", __FUNCTION__, __LINE__, ( int ) cutwin.vs, ( int ) cutwin.hs, ( int ) cutwin.ve, ( int ) cutwin.he); + sprintf(val_buf, "%d,%d,%d,%d", ( int ) cutwin.vs, ( int ) cutwin.hs, ( int ) cutwin.ve, ( int ) cutwin.he ); + config_set_str(CFG_SECTION_TV, "vpp.overscan.dtv", val_buf); + //} +#endif + return CVpp::getInstance()->VPP_SetVideoCrop ( ( int ) cutwin.vs, ( int ) cutwin.hs, ( int ) cutwin.ve, ( int ) cutwin.he ); +} + +tvin_cutwin_t CTvFactory::getOverscan ( int tv_source_input, int fmt, int transFmt ) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + return CVpp::getInstance()->FactoryGetOverscan(sourceType, fmt, INDEX_2D, transFmt); +} + +int CTvFactory::fbcSetBrightness ( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Brightness(COMM_DEV_SERIAL, value); + return 0; + } + return -1; +} + +int CTvFactory::fbcGetBrightness () +{ + int value = 0; + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Brightness(COMM_DEV_SERIAL, &value); + return value; + } + return 0; +} + +int CTvFactory::fbcSetContrast ( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Contrast(COMM_DEV_SERIAL, value); + return 0; + } + return -1; +} + +int CTvFactory::fbcGetContrast () +{ + int data = 0; + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Contrast(COMM_DEV_SERIAL, &data); + return data; + } + return 0; +} + +int CTvFactory::fbcSetSaturation ( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Saturation(COMM_DEV_SERIAL, value); + return 0; + } + return -1; +} + +int CTvFactory::fbcGetSaturation () +{ + int data = 0; + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Saturation(COMM_DEV_SERIAL, &data); + return data; + } + return 0; +} + +int CTvFactory::fbcSetHueColorTint ( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_HueColorTint(COMM_DEV_SERIAL, value); + return 0; + } + return -1; +} + +int CTvFactory::fbcGetHueColorTint () +{ + int data = 0; + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_HueColorTint(COMM_DEV_SERIAL, &data); + return data; + } + return 0; +} + +int CTvFactory::fbcSetBacklight ( int value ) +{ + int temp_value = value; + if (mFbcObj != NULL) { + temp_value = temp_value * 255 / 100; + mFbcObj->cfbc_Set_Backlight(COMM_DEV_SERIAL, temp_value); + return 0; + } + return -1; +} + +int CTvFactory::fbcGetBacklight () +{ + int temp_value = 0; + int data = 0; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Backlight(COMM_DEV_SERIAL, &temp_value); + if (temp_value * 100 % 255 == 0) + temp_value = temp_value * 100 / 255; + else + temp_value = temp_value * 100 / 255 + 1; + data = temp_value; + return data; + } + + return 0; +} + +int CTvFactory::fbcSetAutoBacklightOnOff( unsigned char status) +{ + if (mFbcObj != NULL) { + return mFbcObj->cfbc_Set_Auto_Backlight_OnOff(COMM_DEV_SERIAL, status); + } + + return -1; +} + +int CTvFactory::fbcGetAutoBacklightOnOff( void ) +{ + int temp_status = 0; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Auto_Backlight_OnOff(COMM_DEV_SERIAL, &temp_status); + return temp_status; + } + return 0; +} + +int CTvFactory::fbcSetElecMode( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_AUTO_ELEC_MODE(COMM_DEV_SERIAL, value); + SSMSaveFBCELECmodeVal(value); + return 0; + } + return -1; +} + +int CTvFactory::fbcGetElecMode( void ) +{ + int val = 0; + SSMReadFBCELECmodeVal(&val); + return val; +} + +int CTvFactory::fbcSetBacklightN360( int value ) +{ + SSMSaveFBCELECmodeVal(value); + return -1; +} + +int CTvFactory::fbcGetBacklightN360( void ) +{ + int val = 0; + SSMReadFBCELECmodeVal(&val); + return val; +} + +int CTvFactory::fbcSetThermalState( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Thermal_state(COMM_DEV_SERIAL, value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcSetPictureMode ( int mode ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Picture_Mode(COMM_DEV_SERIAL, mode); + return 0; + } + + return -1; +} + +int CTvFactory::fbcGetPictureMode () +{ + int mode = 0; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Picture_Mode(COMM_DEV_SERIAL, &mode); + return mode; + } + return 0; +} + +int CTvFactory::fbcSetTestPattern ( int mode ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Test_Pattern(COMM_DEV_SERIAL, mode); + return 0; + } + + return -1; +} + +int CTvFactory::fbcGetTestPattern () +{ + int mode = 0; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Test_Pattern(COMM_DEV_SERIAL, &mode); + return mode; + } + + return 0; +} + +int CTvFactory::fbcSelectTestPattern(int value) +{ + int ret = -1; + if (mFbcObj != NULL) { + LOGD("%s, value is %d\n", __FUNCTION__, value); + ret = mFbcObj->cfbc_TestPattern_Select(COMM_DEV_SERIAL, value); + } + + return ret; +} + +int CTvFactory::fbcSetGammaValue(vpp_gamma_curve_t gamma_curve, int is_save) +{ + if (mFbcObj != NULL) { + mFbcObj->fbcSetGammaValue(COMM_DEV_SERIAL, (int)gamma_curve, is_save); + return 0; + } + return -1; +} + +int CTvFactory::fbcSetGainRed( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Gain_Red(COMM_DEV_SERIAL, value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcGetGainRed () +{ + int value = 0; + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Gain_Red(COMM_DEV_SERIAL, &value); + return value; + } + + return 0; +} + +int CTvFactory::fbcSetGainGreen( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Gain_Green(COMM_DEV_SERIAL, value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcGetGainGreen () +{ + int value = 0; + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Gain_Green(COMM_DEV_SERIAL, &value); + //value 0 ~ 2047 + return value; + } + + return 0; +} + +int CTvFactory::fbcGetVideoMute () +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_VMute(COMM_DEV_SERIAL, 1); + } + + return 0; +} + +int CTvFactory::fbcSetGainBlue( int value ) +{ + //value 0 ~ 2047 + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Gain_Blue(COMM_DEV_SERIAL, value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcGetGainBlue () +{ + int value = 0; + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Gain_Blue(COMM_DEV_SERIAL, &value); + //value 0 ~ 2047 + return value; + } + + return 0; +} + +int CTvFactory::fbcSetOffsetRed( int value ) +{ + //value -1024~+1023 + int temp_value = 0; + + //temp_value = (value+1024)*255/2047; + temp_value = value; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Offset_Red(COMM_DEV_SERIAL, temp_value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcGetOffsetRed () +{ + int temp_value = 0, value = 0; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Offset_Red(COMM_DEV_SERIAL, &temp_value); + //value -1024~+1023 + //value = (temp_value*2047)/255 - 1024; + value = temp_value; + + return value; + } + + return 0; +} + +int CTvFactory::fbcSetOffsetGreen( int value ) +{ + //value -1024~+1023 + int temp_value = 0; + + //temp_value = (value+1024)*255/2047; + temp_value = value; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Offset_Green(COMM_DEV_SERIAL, temp_value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcGetOffsetGreen () +{ + int temp_value = 0, value = 0; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Offset_Green(COMM_DEV_SERIAL, &temp_value); + //value -1024~+1023 + //value = (temp_value*2047)/255 - 1024; + value = temp_value; + + return value; + } + + return 0; +} + +int CTvFactory::fbcSetOffsetBlue( int value ) +{ + //value -1024~+1023 + int temp_value = 0; + + //temp_value = (value+1024)*255/2047; + temp_value = value; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Offset_Blue(COMM_DEV_SERIAL, value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcGetOffsetBlue () +{ + int temp_value = 0, value = 0; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_Offset_Blue(COMM_DEV_SERIAL, &temp_value); + //value -1024~+1023 + //value = (temp_value*2047)/255 - 1024; + value = temp_value; + + return value; + } + + return 0; +} + +int CTvFactory::whiteBalanceGainRedGet(int tv_source_input, int colortemp_mode) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + int ret = -1; + if (!mHdmiOutFbc) { // not use fbc store the white balance params + LOGD("--------- call none fbc method ---------"); + ret = CVpp::getInstance()->FactoryGetColorTemp_Rgain(sourceType, colortemp_mode); + } else { //use fbc store the white balance params + LOGD("--------- call fbc method ---------"); + ret = getItemFromBatch((vpp_color_temperature_mode_t)colortemp_mode, 0); + } + return ret; +} + +int CTvFactory::whiteBalanceGainRedSet(int tv_source_input, int colortemp_mode, int value) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + + int ret = -1; + if (value < 0) { + value = 0; + } else if (value > 2047) { + value = 2047; + } + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->FactorySetColorTemp_Rgain(sourceType, colortemp_mode, value); + if (ret != -1) { + LOGD("save the red gain to flash"); + ret = CVpp::getInstance()->FactorySaveColorTemp_Rgain(sourceType, colortemp_mode, value); + } + } else { //use fbc store the white balance params + value = formatInputGainParams(value); + ret = fbcSetGainRed(value); + } + return ret; +} + +int CTvFactory::whiteBalanceGainGreenGet(int tv_source_input, int colortemp_mode) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + + int ret = -1; + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->FactoryGetColorTemp_Ggain(sourceType, colortemp_mode); + } else { //use fbc store the white balance params + ret = getItemFromBatch((vpp_color_temperature_mode_t)colortemp_mode, 1); + } + return ret; +} + +int CTvFactory::whiteBalanceGainGreenSet(int tv_source_input, int colortemp_mode, int value) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + int ret = -1; + if (value < 0) { + value = 0; + } else if (value > 2047) { + value = 2047; + } + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->FactorySetColorTemp_Ggain(sourceType, colortemp_mode, value); + if (ret != -1) { + LOGD("save the green gain to flash"); + ret = CVpp::getInstance()->FactorySaveColorTemp_Ggain(sourceType, colortemp_mode, value); + } + } else { //use fbc store the white balance params + value = formatInputGainParams(value); + ret = fbcSetGainGreen(value); + } + return ret; +} + +int CTvFactory::whiteBalanceGainBlueGet(int tv_source_input, int colortemp_mode) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + + int ret = -1; + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->FactoryGetColorTemp_Bgain(sourceType, colortemp_mode); + } else { //use fbc store the white balance params + ret = getItemFromBatch((vpp_color_temperature_mode_t)colortemp_mode, 2); + } + return ret; +} + +int CTvFactory::whiteBalanceGainBlueSet(int tv_source_input, int colortemp_mode, int value) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + + int ret = -1; + if (value < 0) { + value = 0; + } else if (value > 2047) { + value = 2047; + } + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->FactorySetColorTemp_Bgain(sourceType, colortemp_mode, value); + if (ret != -1) { + LOGD("save the blue gain to flash"); + ret = CVpp::getInstance()->FactorySaveColorTemp_Bgain(sourceType, colortemp_mode, value); + } + } else { //use fbc store the white balance params + value = formatInputGainParams(value); + ret = fbcSetGainBlue(value); + } + return ret; +} + +int CTvFactory::whiteBalanceOffsetRedGet(int tv_source_input, int colortemp_mode) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + + int ret = -1; + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->FactoryGetColorTemp_Roffset(sourceType, colortemp_mode); + } else { //use fbc store the white balance params + ret = getItemFromBatch((vpp_color_temperature_mode_t)colortemp_mode, 3); + } + return ret; +} + +int CTvFactory::whiteBalanceOffsetRedSet(int tv_source_input, int colortemp_mode, int value) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + int ret = -1; + if (value < -1024) { + value = -1024; + } else if (value > 1023) { + value = 1023; + } + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->FactorySetColorTemp_Roffset(sourceType, colortemp_mode, value); + if (ret != -1) { + LOGD("save the red offset to flash"); + ret = CVpp::getInstance()->FactorySaveColorTemp_Roffset(sourceType, colortemp_mode, value); + } + } else { //use fbc store the white balance params + value = formatInputOffsetParams(value); + ret = fbcSetOffsetRed(value); + } + return ret; +} + +int CTvFactory::whiteBalanceOffsetGreenGet(int tv_source_input, int colortemp_mode) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + + int ret = -1; + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->FactoryGetColorTemp_Goffset(sourceType, colortemp_mode); + } else { //use fbc store the white balance params + ret = getItemFromBatch((vpp_color_temperature_mode_t)colortemp_mode, 4); + } + return ret; +} + +int CTvFactory::whiteBalanceOffsetGreenSet(int tv_source_input, int colortemp_mode, int value) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + + int ret = -1; + if (value < -1024) { + value = -1024; + } else if (value > 1023) { + value = 1023; + } + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->FactorySetColorTemp_Goffset(sourceType, colortemp_mode, value); + if (ret != -1) { + LOGD("save the green offset to flash"); + ret = CVpp::getInstance()->FactorySaveColorTemp_Goffset(sourceType, colortemp_mode, value); + } + } else { //use fbc store the white balance params + value = formatInputOffsetParams(value); + ret = fbcSetOffsetGreen(value); + } + return ret; +} + +int CTvFactory::whiteBalanceOffsetBlueGet(int tv_source_input, int colortemp_mode) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + + int ret = -1; + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->FactoryGetColorTemp_Boffset(sourceType, colortemp_mode); + } else { //use fbc store the white balance params + ret = getItemFromBatch((vpp_color_temperature_mode_t)colortemp_mode, 5); + } + return ret; +} + +int CTvFactory::whiteBalanceOffsetBlueSet(int tv_source_input, int colortemp_mode, int value) +{ + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + + int ret = -1; + if (value < -1024) { + value = -1024; + } else if (value > 1023) { + value = 1023; + } + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->FactorySetColorTemp_Boffset(sourceType, colortemp_mode, value); + if (ret != -1) { + LOGD("save the blue offset to flash"); + ret = CVpp::getInstance()->FactorySaveColorTemp_Boffset(sourceType, colortemp_mode, value); + } + } else { //use fbc store the white balance params + value = formatInputOffsetParams(value); + ret = fbcSetOffsetBlue(value); + } + return ret; +} + +int CTvFactory::whiteBalanceColorTempModeSet(int tv_source_input, int colortemp_mode, int is_save) +{ + int ret = -1; + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->SetColorTemperature((vpp_color_temperature_mode_t)colortemp_mode, (tv_source_input_t)tv_source_input, is_save); + } else { //use fbc store the white balance params + ret = fbcColorTempModeSet(colortemp_mode); + } + return ret; +} + +int CTvFactory::whiteBalanceColorTempModeGet(int tv_source_input ) +{ + int ret = -1; + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->GetColorTemperature((tv_source_input_t)tv_source_input); + } else { //use fbc store the white balance params + ret = fbcColorTempModeGet(); + } + return ret; +} + +int CTvFactory::whiteBalancePramSave(int tv_source_input, int tempmode, int r_gain, int g_gain, int b_gain, int r_offset, int g_offset, int b_offset) +{ + int ret = 0; + tv_source_input_type_t sourceType; + sourceType = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + + if (!mHdmiOutFbc) { // not use fbc store the white balance params + CVpp::getInstance()->SaveColorTemperature((vpp_color_temperature_mode_t) tempmode, (tv_source_input_t) tv_source_input); + CVpp::getInstance()->FactorySaveColorTemp_Rgain(sourceType, tempmode, r_gain); + CVpp::getInstance()->FactorySaveColorTemp_Ggain(sourceType, tempmode, g_gain); + CVpp::getInstance()->FactorySaveColorTemp_Bgain(sourceType, tempmode, b_gain); + CVpp::getInstance()->FactorySaveColorTemp_Roffset(sourceType, tempmode, r_offset); + CVpp::getInstance()->FactorySaveColorTemp_Goffset(sourceType, tempmode, g_offset); + CVpp::getInstance()->FactorySaveColorTemp_Boffset(sourceType, tempmode, b_offset); + } else { //use fbc store the white balance params + tcon_rgb_ogo_t params; + + params.r_gain = formatInputGainParams(r_gain); + params.g_gain = formatInputGainParams(g_gain); + params.b_gain = formatInputGainParams(b_gain); + params.r_post_offset = formatInputOffsetParams(r_offset); + params.g_post_offset = formatInputOffsetParams(g_offset); + params.b_post_offset = formatInputOffsetParams(b_offset); + ret = colorTempBatchSet((vpp_color_temperature_mode_t)tempmode, params); + } + return ret; +} + +int CTvFactory::whiteBalanceGrayPatternClose() +{ + int useFbc = 0; + int ret = -1; + if (!mHdmiOutFbc) { // not use fbc store the white balance params + ret = CVpp::getInstance()->VPP_SetGrayPattern(0); + } else { //use fbc store the white balance params + ret = fbcGrayPatternClose(); + } + return ret; +} + +int CTvFactory::whiteBalanceGrayPatternOpen() +{ + int ret = 0; + if (mHdmiOutFbc) { //use fbc store the white balance params + ret = fbcGrayPatternOpen(); + } + return ret; +} + +int CTvFactory::whiteBalanceGrayPatternSet(int value) +{ + int ret = -1; + if (!mHdmiOutFbc) { + ret = CVpp::getInstance()->VPP_SetGrayPattern(value); + } else { + ret = fbcGrayPatternSet(value); + } + return ret; +} + +int CTvFactory:: whiteBalanceGrayPatternGet() +{ + int ret = -1; + if (!mHdmiOutFbc) { + ret = CVpp::getInstance()->VPP_GetGrayPattern(); + } + return ret; +} + +int CTvFactory::fbcGrayPatternSet(int value) +{ + int ret = -1; + unsigned char grayValue = 0; + if (value > 255) { + grayValue = 255; + } else if (value < 0) { + grayValue = 0; + } else { + grayValue = (unsigned char)(0xFF & value); + } + if (mFbcObj != NULL) { + ret = mFbcObj->cfbc_WhiteBalance_SetGrayPattern(COMM_DEV_SERIAL, grayValue); + } + return ret; +} + +int CTvFactory::fbcGrayPatternOpen() +{ + int ret = -1; + if (mFbcObj != NULL) { + ret = mFbcObj->cfbc_WhiteBalance_GrayPattern_OnOff(COMM_DEV_SERIAL, 0); + } + return ret; +} + +int CTvFactory::fbcGrayPatternClose() +{ + int ret = -1; + if (mFbcObj != NULL) { + ret = mFbcObj->cfbc_WhiteBalance_GrayPattern_OnOff(COMM_DEV_SERIAL, 1); + } + return ret; +} + +int CTvFactory::fbcColorTempModeSet( int mode ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_ColorTemp_Mode(COMM_DEV_SERIAL, mode); + return 0; + } + + return -1; +} + +int CTvFactory::fbcColorTempModeGet () +{ + int temp_mode = 0; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_ColorTemp_Mode(COMM_DEV_SERIAL, &temp_mode); + return temp_mode; + } + + return -1; +} + +int CTvFactory::fbcColorTempModeN360Set( int mode ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_ColorTemp_Mode(COMM_DEV_SERIAL, mode); + SSMSaveFBCN360ColorTempVal(mode); + return 0; + } + + return -1; +} + +int CTvFactory::fbcColorTempModeN360Get () +{ + int temp_mode = 0; + SSMReadFBCN360ColorTempVal(&temp_mode); + return temp_mode; +} + +int CTvFactory::fbcWBInitialSet( int status ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_WB_Initial(COMM_DEV_SERIAL, status); + return 0; + } + + return -1; +} + +int CTvFactory::fbcWBInitialGet () +{ + int temp_status = 0; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_WB_Initial(COMM_DEV_SERIAL, &temp_status); + return temp_status; + } + + return 0; +} + +int CTvFactory::fbcBacklightOnOffSet(int value) +{ + if (mFbcObj != NULL) { + value = value ? 0 : 1; + mFbcObj->cfbc_Set_backlight_onoff(COMM_DEV_SERIAL, value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcBacklightOnOffGet() +{ + int temp_value = 0; + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_backlight_onoff(COMM_DEV_SERIAL, &temp_value); + temp_value = temp_value ? 0 : 1; + return temp_value; + } + + return 0; +} + +int CTvFactory::fbcLvdsSsgSet( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_LVDS_SSG_Set(COMM_DEV_SERIAL, value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcLightSensorStatusN310Set ( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_LightSensor_N310(COMM_DEV_SERIAL, value); + SSMSaveFBCN310LightsensorVal(value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcLightSensorStatusN310Get () +{ + int data = 0; + if (mFbcObj != NULL) { + SSMReadFBCN310LightsensorVal(&data); + return data; + } + + return 0; +} + +int CTvFactory::fbcDreamPanelStatusN310Set ( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_Dream_Panel_N310(COMM_DEV_SERIAL, value); + SSMSaveFBCN310Dream_PanelVal(value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcDreamPanelStatusN310Get () +{ + int data = 0; + if (mFbcObj != NULL) { + SSMReadFBCN310Dream_PanelVal(&data); + return data; + } + + return 0; +} + +int CTvFactory::fbcMultPQStatusN310Set ( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_MULT_PQ_N310(COMM_DEV_SERIAL, value); + SSMSaveFBCN310MULT_PQVal(value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcMultPQStatusN310Get () +{ + int data = 0; + + if (mFbcObj != NULL) { + SSMReadFBCN310MULT_PQVal(&data); + return data; + } + + return 0; +} + +int CTvFactory::fbcMemcStatusN310Set ( int value ) +{ + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_MEMC_N310(COMM_DEV_SERIAL, value); + SSMSaveFBCN310MEMCVal(value); + return 0; + } + + return -1; +} + +int CTvFactory::fbcMemcStatusN310Get () +{ + int data = 0; + if (mFbcObj != NULL) { + SSMReadFBCN310MEMCVal(&data); + return data; + } + + return -1; +} + +int CTvFactory::getItemFromBatch(vpp_color_temperature_mode_t colortemp_mode, int item) +{ + tcon_rgb_ogo_t params; + int ret = 0; + + colorTempBatchGet((vpp_color_temperature_mode_t)colortemp_mode, ¶ms); + switch (item) { + case 0: + ret = formatOutputGainParams(params.r_gain); + break; + case 1: + ret = formatOutputGainParams(params.g_gain); + break; + case 2: + ret = formatOutputGainParams(params.b_gain); + break; + case 3: + ret = formatOutputOffsetParams(params.r_post_offset); + break; + case 4: + ret = formatOutputOffsetParams(params.g_post_offset); + break; + case 5: + ret = formatOutputOffsetParams(params.b_post_offset); + break; + default: + ret = 0; + } + return ret; +} + +int CTvFactory::formatInputGainParams(int value) +{ + int ret = 1024; + if (value < 0) { + ret = 0; + } else if (value > 2047) { + ret = 2047; + } else { + ret = value; + } + ret = ret >> 3; + return ret; +} + +int CTvFactory::formatInputOffsetParams(int value) +{ + int ret = 0; + if (value < -1024) { + ret = -1024; + } else if (value > 1023) { + ret = 1023; + } else { + ret = value; + } + ret += 1024; + ret = ret >> 3; + return ret; +} + +int CTvFactory::formatOutputOffsetParams(int value) +{ + if (value == 255) { + value = 1023; + } else { + value = value << 3; + value -= 1024; + } + return value; +} + +int CTvFactory::formatOutputGainParams(int value) +{ + value = value << 3; + if (value < 0) { + value = 0; + } else if (value > 2047) { + value = 2047; + } + return value; +} + +int CTvFactory::fbcSetColorTemperature(vpp_color_temperature_mode_t temp_mode) +{ + int ret = -1; + if (CVpp::getInstance()->GetEyeProtectionMode()) { + tcon_rgb_ogo_t rgb_ogo; + colorTempBatchGet(temp_mode, &rgb_ogo); + rgb_ogo.b_gain /= 2; + ret = colorTempBatchSet(temp_mode, rgb_ogo); + } else { + ret = fbcColorTempModeSet(temp_mode); + } + return ret; +} + +int CTvFactory::colorTempBatchSet(vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t params) +{ + unsigned char mode = 0, r_gain, g_gain, b_gain, r_offset, g_offset, b_offset; + switch (Tempmode) { + case VPP_COLOR_TEMPERATURE_MODE_STANDARD: + mode = 1; //COLOR_TEMP_STD + break; + case VPP_COLOR_TEMPERATURE_MODE_WARM: + mode = 2; //COLOR_TEMP_WARM + break; + case VPP_COLOR_TEMPERATURE_MODE_COLD: + mode = 0; //COLOR_TEMP_COLD + break; + case VPP_COLOR_TEMPERATURE_MODE_USER: + mode = 3; //COLOR_TEMP_USER + break; + default: + break; + } + r_gain = (params.r_gain * 255) / 2047; // u1.10, range 0~2047, default is 1024 (1.0x) + g_gain = (params.g_gain * 255) / 2047; + b_gain = (params.b_gain * 255) / 2047; + r_offset = (params.r_post_offset + 1024) * 255 / 2047; // s11.0, range -1024~+1023, default is 0 + g_offset = (params.g_post_offset + 1024) * 255 / 2047; + b_offset = (params.b_post_offset + 1024) * 255 / 2047; + LOGD ( "~colorTempBatchSet##%d,%d,%d,%d,%d,%d,##", r_gain, g_gain, b_gain, r_offset, g_offset, b_offset ); + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Set_WB_Batch(COMM_DEV_SERIAL, mode, r_gain, g_gain, b_gain, r_offset, g_offset, b_offset); + return 0; + } + + return -1; +} + +int CTvFactory::colorTempBatchGet ( vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t *params ) +{ + unsigned char mode = 0, r_gain, g_gain, b_gain, r_offset, g_offset, b_offset; + switch (Tempmode) { + case VPP_COLOR_TEMPERATURE_MODE_STANDARD: + mode = 1; //COLOR_TEMP_STD + break; + case VPP_COLOR_TEMPERATURE_MODE_WARM: + mode = 2; //COLOR_TEMP_WARM + break; + case VPP_COLOR_TEMPERATURE_MODE_COLD: + mode = 0; //COLOR_TEMP_COLD + break; + case VPP_COLOR_TEMPERATURE_MODE_USER: + mode = 3; //COLOR_TEMP_USER + break; + default: + break; + } + + if (mFbcObj != NULL) { + mFbcObj->cfbc_Get_WB_Batch(COMM_DEV_SERIAL, mode, &r_gain, &g_gain, &b_gain, &r_offset, &g_offset, &b_offset); + LOGD ( "~colorTempBatchGet##%d,%d,%d,%d,%d,%d,##", r_gain, g_gain, b_gain, r_offset, g_offset, b_offset ); + + params->r_gain = (r_gain * 2047) / 255; + params->g_gain = (g_gain * 2047) / 255; + params->b_gain = (b_gain * 2047) / 255; + params->r_post_offset = (r_offset * 2047) / 255 - 1024; + params->g_post_offset = (g_offset * 2047) / 255 - 1024; + params->b_post_offset = (b_offset * 2047) / 255 - 1024; + return 0; + } + + return -1; +} diff --git a/tv/tvserver/libtv/tv/CTvFactory.h b/tv/tvserver/libtv/tv/CTvFactory.h new file mode 100644 index 0000000..4e617e2 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvFactory.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _CTV_FACTORY_H_ +#define _CTV_FACTORY_H_ + +#include <utils/String8.h> +#include "CAv.h" +#include "../vpp/CVpp.h" +#include "../tvin/CTvin.h" +#include "fbcutils/CFbcCommunication.h" + +using namespace android; + +class CTvFactory { +public: + CTvFactory(); + virtual ~CTvFactory() {}; + + void init(); + int setPQModeBrightness (int sourceType, int pqMode, int brightness); + int getPQModeBrightness (int tv_source_input, int pqMode); + int setPQModeContrast (int sourceType, int pqMode, int contrast); + int getPQModeContrast (int tv_source_input, int pqMode); + int setPQModeSaturation ( int tv_source_input, int pqMode, int saturation ); + int getPQModeSaturation ( int tv_source_input, int pqMode ); + int setPQModeHue ( int tv_source_input, int pqMode, int hue ); + int getPQModeHue ( int tv_source_input, int pqMode ); + int setPQModeSharpness ( int tv_source_input, int pqMode, int sharpness ); + int getPQModeSharpness ( int tv_source_input, int pqMode ); + + int getColorTemperatureParams ( vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t *params ); + int setTestPattern ( int pattern ); + int getTestPattern (); + int setScreenColor ( int vdinBlendingMask, int y, int u, int v ); + int resetPQMode (); + int resetColorTemp (); + int setParamsDefault (); + int setDDRSSC ( int step ); + int getDDRSSC (); + int setLVDSSSC ( int step ); + int getLVDSSSC (); + int setNolineParams ( int nolineParamstype, int tv_source_input, noline_params_t nolineParams ); + noline_params_t getNolineParams ( int nolineParamstype, int tv_source_input ); + int setOverscan ( int tv_source_input, int fmt, int transFmt, tvin_cutwin_t cutwin ); + tvin_cutwin_t getOverscan ( int tv_source_input, int fmt, int transFmt ); + int replacePQDb(const char *newFilePath = NULL); + int setGamma(tcon_gamma_table_t gamma_r, tcon_gamma_table_t gamma_g, tcon_gamma_table_t gamma_b); + int setRGBPattern(int r, int g, int b); + int getRGBPattern(); + + //end PQ + + //TV TO FBC + int fbcSetBrightness ( int value ); + int fbcGetBrightness (); + int fbcSetContrast( int value ); + int fbcGetContrast (); + int fbcSetSaturation( int value ); + int fbcGetSaturation (); + int fbcSetHueColorTint( int value ); + int fbcGetHueColorTint (); + virtual int fbcSetBacklight ( int value ); + virtual int fbcGetBacklight (); + int Tv_FactorySet_FBC_Backlight_N360 ( int value ); + int Tv_FactoryGet_FBC_Backlight_N360 (); + int fbcSetElecMode( int value ); + int fbcGetElecMode( void ); + int fbcSetBacklightN360( int value ); + int fbcGetBacklightN360( void ); + int fbcSetPictureMode ( int mode ); + int fbcGetPictureMode (); + int fbcSetTestPattern ( int mode ); + int fbcGetTestPattern (); + int fbcSelectTestPattern(int value); + int fbcSetGainRed( int value ); + int fbcGetGainRed (); + int fbcSetGainGreen( int value ); + int fbcGetGainGreen( void ); + int fbcSetGainBlue( int value ); + int fbcGetGainBlue (); + int fbcSetOffsetRed( int value ); + int fbcGetOffsetRed (); + int fbcSetOffsetGreen( int value ); + int fbcGetOffsetGreen( void ); + int fbcSetOffsetBlue( int value ); + int fbcGetOffsetBlue (); + int fbcSetGammaValue(vpp_gamma_curve_t gamma_curve, int is_save); + int whiteBalanceGainRedGet(int tv_source_input, int colortemp_mode); + int whiteBalanceGainGreenGet(int tv_source_input, int colortemp_mode); + int whiteBalanceGainBlueGet(int tv_source_input, int colortemp_mode); + int whiteBalanceOffsetRedGet(int tv_source_input, int colortemp_mode); + int whiteBalanceOffsetGreenGet(int tv_source_input, int colortemp_mode); + int whiteBalanceOffsetBlueGet(int tv_source_input, int colortemp_mode); + int whiteBalanceGainRedSet(int tv_source_input, int colortemp_mode, int value); + int whiteBalanceGainGreenSet(int tv_source_input, int colortemp_mode, int value); + int whiteBalanceGainBlueSet(int tv_source_input, int colortemp_mode, int value); + int whiteBalanceOffsetRedSet(int tv_source_input, int colortemp_mode, int value); + int whiteBalanceOffsetGreenSet(int tv_source_input, int colortemp_mode, int value); + int whiteBalanceOffsetBlueSet(int tv_source_input, int colortemp_mode, int value); + int whiteBalanceColorTempModeSet(int tv_source_input, int colortemp_mode, int is_save); + int whiteBalanceColorTempModeGet(int sourceType ); + + int whiteBalancePramSave(int tv_source_input, int tempmode, int r_gain, int g_gain, int b_gain, int r_offset, int g_offset, int b_offset); + int whiteBalanceGrayPatternClose(); + int whiteBalanceGrayPatternOpen(); + int whiteBalanceGrayPatternSet(int value); + int whiteBalanceGrayPatternGet(); + + int fbcColorTempModeSet( int mode ); + int fbcColorTempModeGet (); + int fbcColorTempModeN360Set( int mode ); + int fbcColorTempModeN360Get (); + int fbcWBInitialSet( int status ); + int fbcWBInitialGet (); + int fbcSetColorTemperature(vpp_color_temperature_mode_t temp_mode); + + int fbcSetThermalState( int value ); + int fbcBacklightOnOffSet(int value); + int fbcBacklightOnOffGet (); + int fbcSetAutoBacklightOnOff(unsigned char status); + int fbcGetAutoBacklightOnOff (); + int fbcGetVideoMute (); + int fbcLvdsSsgSet( int value ); + int fbcLightSensorStatusN310Set ( int value ); + int fbcLightSensorStatusN310Get (); + int fbcDreamPanelStatusN310Set ( int value ); + int fbcDreamPanelStatusN310Get (); + int fbcMultPQStatusN310Set ( int value ); + int fbcMultPQStatusN310Get (); + int fbcMemcStatusN310Set ( int value ); + int fbcMemcStatusN310Get (); + //end TV TO FBC +private: + int getItemFromBatch(vpp_color_temperature_mode_t colortemp_mode, int item); + int formatInputGainParams(int value); + int formatInputOffsetParams(int value); + int formatOutputOffsetParams(int value); + int formatOutputGainParams(int value); + + int colorTempBatchGet ( vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t *params ); + int colorTempBatchSet(vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t params); + + int fbcGrayPatternSet(int value); + int fbcGrayPatternOpen(); + int fbcGrayPatternClose(); + + bool mHdmiOutFbc; + CFbcCommunication *mFbcObj; + CAv mAv; +}; + +#endif/*_CTV_FACTORY_H_*/ + diff --git a/tv/tvserver/libtv/tv/CTvManager.h b/tv/tvserver/libtv/tv/CTvManager.h new file mode 100644 index 0000000..676aacc --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvManager.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CTVMANAGER_H_) +#define _CTVMANAGER_H_ + +#include <string.h> +#include <utils/Mutex.h> +#include <utils/Singleton.h> + +#include "CTvPlayer.h" +#include "CTvRecord.h" + + +using namespace android; + +template<typename T, int MAX> +class DevManager { + private: + T *mDevs[MAX]; + mutable Mutex mLock; + + static DevManager *mInstance; + + public: + DevManager(){ + memset(mDevs, 0, MAX * sizeof(T*)); + } + ~DevManager(){ + for (int i = 0; i < MAX; i++) { + if (!mDevs[i]) { + mDevs[i]->stop(NULL); + delete mDevs[i]; + } + } + } + T *getDev(const char *id) { + AutoMutex _l( mLock ); + T *dev = NULL; + for (int i = 0; i < MAX; i++) + if (mDevs[i] + && mDevs[i]->getId() + && (strcmp(mDevs[i]->getId(), id) == 0)) + return mDevs[i]; + return dev; + } + + int addDev(T &dev) { + AutoMutex _l( mLock ); + for (int i = 0; i < MAX; i++) { + if (mDevs[i] && mDevs[i]->equals(dev)) + return 1; + } + for (int i = 0; i < MAX; i++) { + if (!mDevs[i]) { + mDevs[i] = &dev; + return 0; + } + } + return -1; + } + + void removeDev(const char *id) { + AutoMutex _l( mLock ); + for (int i = 0; i < MAX; i++) { + if (mDevs[i] + && mDevs[i]->getId() + && (strcmp(mDevs[i]->getId(), id) == 0)) { + delete mDevs[i]; + mDevs[i] = NULL; + } + } + } + + void releaseAll() { + AutoMutex _l( mLock ); + for (int i = 0; i < MAX; i++) { + if (mDevs[i]) { + mDevs[i]->stop(NULL); + delete mDevs[i]; + mDevs[i] = NULL; + } + } + } + + T *getFirstDevWithIdContains(const char *pattern) { + AutoMutex _l( mLock ); + T *dev = NULL; + for (int i = 0; i < MAX; i++) + if (mDevs[i] + && mDevs[i]->getId() + && (strstr(mDevs[i]->getId(), pattern) != 0)) + return mDevs[i]; + return dev; + } + +}; + +class CTvRecord; + +class RecorderManager : public DevManager<CTvRecord, 2>, public Singleton<RecorderManager> { + + friend class Singleton<RecorderManager>; + + public: + RecorderManager(){} + ~RecorderManager(){} +}; + +class CTvPlayer; + +class PlayerManager : public DevManager<CTvPlayer, 1>, public Singleton<PlayerManager> { + + friend class Singleton<PlayerManager>; + + public: + PlayerManager(){} + ~PlayerManager(){} + + static const bool singleMode = true; +}; + +#endif //_CTVMANAGER_H_ + diff --git a/tv/tvserver/libtv/tv/CTvPlayer.cpp b/tv/tvserver/libtv/tv/CTvPlayer.cpp new file mode 100644 index 0000000..ff06514 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvPlayer.cpp @@ -0,0 +1,746 @@ +#include <string.h> + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvPlayer" + +#include "CTvLog.h" +#include <cutils/properties.h> +#include "CTvPlayer.h" + +CTvPlayer::CTvPlayer (CTv *tv) { + mId = NULL; + pTv = tv; +} +CTvPlayer::~CTvPlayer() { + if (mId) + free((void*)mId); +} +void CTvPlayer::sendTvEvent ( const CTvEv &ev ) { + if (pTv) + pTv->sendTvEvent(ev); +} + +CDTVTvPlayer::CDTVTvPlayer(CTv *tv) : CTvPlayer(tv) { + mMode = PLAY_MODE_LIVE; + mFEParam = NULL; + mVpid = -1; + mVfmt = -1; + mVparam = NULL; + mApid = -1; + mAfmt = -1; + mAparam = NULL; + mPpid = -1; + mPparam = NULL; + mParam = NULL; + mSourceChanged = true; + mDisableTimeShifting = propertyGetBool("tv.dtv.tf.disable", false); +} +CDTVTvPlayer::~CDTVTvPlayer() { + if (mFEParam) + free((void*)mFEParam); + if (mVparam) + free((void*)mVparam); + if (mAparam) + free((void*)mAparam); + if (mPparam) + free((void*)mPparam); + if (mParam) + free((void*)mParam); + CTvRecord *recorder = RecorderManager::getInstance().getDev("timeshifting"); + if (recorder) + recorder->stop(NULL); + tryCloseTFile(); +} + +int CDTVTvPlayer::setFEParam(const char *param) { + LOGD("setFE(%s)", toReadable(param)); + if (mFEParam) + free((void*)mFEParam); + mFEParam = param? strdup(param) : NULL; + mSourceChanged = true; + return 0; +} +int CDTVTvPlayer::setVideo(int pid, int format, const char *param) { + LOGD("setVideo(%d:%d:%s)", pid, format, toReadable(param)); + mVpid = pid; + mVfmt = format; + if (mVparam) + free((void*)mVparam); + mVparam = param? strdup(param) : NULL; + mSourceChanged = true; + return 0; +} +int CDTVTvPlayer::setAudio(int pid, int format, const char *param) { + LOGD("setAudio(%d:%d:%s)", pid, format, toReadable(param)); + mApid = pid; + mAfmt = format; + if (mAparam) + free((void*)mAparam); + mAparam = param? strdup(param) : NULL; + return 0; +} +int CDTVTvPlayer::setPcr(int pid, const char *param) { + LOGD("setPcr(%d:%s)", pid, toReadable(param)); + mPpid = pid; + if (mPparam) + free((void*)mPparam); + mPparam = param? strdup(param) : NULL; + mSourceChanged = true; + return 0; +} +int CDTVTvPlayer::setParam(const char *param) { + LOGD("setParam(%s)", toReadable(param)); + if (mParam) + free((void*)mParam); + mParam = param? strdup(param) : NULL; + mMode = paramGetInt(mParam, NULL, "mode", PLAY_MODE_LIVE); + mSourceChanged = true; + //DO NOT use this param, use prop:tv.dtv.tf.disable instead + //mDisableTimeShifting = paramGetInt(mParam, NULL, "disableTimeShifting", 0) ? true : false; + return 0; +} + + +int CDTVTvPlayer::start(const char *param) { + LOGD("start(%s:%s) current mode(%d)", toReadable(getId()), toReadable(param), mMode); + int ret = -1; +#ifdef SUPPORT_ADTV + switch (mMode) { + case PLAY_MODE_LIVE: {//start play live and rec in the backgroud + if (!mDisableTimeShifting) { + mDisableTimeShifting = propertyGetBool("tv.dtv.tf.disable", false); + LOGD("prop tv.dtv.tf.disable:%s", mDisableTimeShifting? "true":"false"); + } + + if (bStartInTimeShift) + ret = startLiveTryTimeShift(param); + else + ret = startLiveTryRecording(param); + }break; + + case PLAY_MODE_TIMESHIFT: {//return to play live + ret = pTv->playDtvProgramUnlocked(mFEParam, mVpid, mVfmt, mApid, mAfmt, mPpid, paramGetInt(mAparam, NULL, "AudComp", 0)); + if (ret == 0) + mMode = PLAY_MODE_LIVE; + }break; + + case PLAY_MODE_REC: {//start play rec + AM_AV_TimeshiftPara_t para; + memset(¶, 0, sizeof(para)); + para.dmx_id = 0; + para.mode = AM_AV_TIMESHIFT_MODE_PLAYBACK; + strncpy(para.file_path, paramGetString(mParam, NULL, "file", "").c_str(), sizeof(para.file_path)-1); + para.file_path[sizeof(para.file_path)-1] = '\0'; + readMediaInfoFromFile(para.file_path, ¶.media_info); + LOGD("recplay start"); +/* AM_AV_TimeshiftMediaInfo_t *pminfo = ¶.media_info; + pminfo->vid_pid = mVpid; + pminfo->vid_fmt = mVfmt; + pminfo->aud_cnt = 1; + pminfo->audios[0].pid = mApid; + pminfo->audios[0].fmt = mAfmt; + pminfo->sub_cnt = 0; + pminfo->ttx_cnt = 0; + pminfo->duration = 0; + pminfo->program_name[0] = '\0';*/ + ret = pTv->playDtvTimeShiftUnlocked(NULL, (void *)¶, paramGetInt(mAparam, NULL, "AudComp", 0)); + }break; + } + mSourceChanged = false; +#endif + return ret; +} + +int CDTVTvPlayer::stop(const char *param) { + LOGD("CDTVTvPlayer stop(%s:%s)", toReadable(getId()), toReadable(param)); + + int ret; + + if (!mDisableTimeShifting) { + ret = pTv->stopRecording("timeshifting", NULL); + if (ret != 0) { + LOGD("stop recording(timeshifting) fail(%#x)", ret); + } + } + + ret = pTv->stopPlaying(true, false); + ret = pTv->mAv.stopTimeShift(); + + if (ret == 0) + tryCloseTFile(); + + LOGD("stop(%s)=%d", toReadable(param), ret); + return ret; +} + +int CDTVTvPlayer::pause(const char *param) { + LOGD("pause(%s:%s)", toReadable(getId()), toReadable(param)); + int ret = -1; +#ifdef SUPPORT_ADTV + switch (mMode) { + case PLAY_MODE_LIVE: { + if (mDisableTimeShifting) + break; + CTvRecord *recorder = RecorderManager::getInstance().getDev("timeshifting"); + if (!recorder) { + LOGD("recorder(timeshifting not found)"); + TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_TIMESHIFT_PLAY_FAIL; + pTv->sendTvEvent(AvPlayBackEvt); + return -1; + } + mOffset = recorder->getWritePosition(); + + AM_AV_TimeshiftPara_t para; + para.dmx_id = 0; + para.mode = AM_AV_TIMESHIFT_MODE_TIMESHIFTING; + para.file_path[0] = '\0'; + para.tfile = mTfile; + para.offset_ms = mOffset; + para.start_paused = true; + AM_AV_TimeshiftMediaInfo_t *pminfo = ¶.media_info; + pminfo->vid_pid = mVpid; + pminfo->vid_fmt = mVfmt; + pminfo->aud_cnt = 1; + pminfo->audios[0].pid = mApid; + pminfo->audios[0].fmt = mAfmt; + pminfo->sub_cnt = 0; + pminfo->ttx_cnt = 0; + pminfo->duration = paramGetInt(mParam, NULL, "dur", 120); + pminfo->program_name[0] = '\0'; + ret = pTv->mAv.startTimeShift(¶); + if (ret == 0) + mMode = PLAY_MODE_TIMESHIFT; + }break; + + case PLAY_MODE_REC: + case PLAY_MODE_TIMESHIFT: { + ret = pTv->mAv.pauseTimeShift(); + }break; + } +#endif + return ret; +} + +int CDTVTvPlayer::resume(const char *param) { + LOGD("resume(%s:%s)", toReadable(getId()), toReadable(param)); + int ret = -1; + switch (mMode) { + case PLAY_MODE_LIVE: { + }break; + case PLAY_MODE_REC: + case PLAY_MODE_TIMESHIFT:{ + pTv->mAv.resumeTimeShift(); + }break; + } + return ret; +} + +int CDTVTvPlayer::seek(const char *param) +{ + LOGD("seek(%s:%s)", toReadable(getId()), toReadable(param)); + int ret = -1; + switch (mMode) { + case PLAY_MODE_LIVE: { + }break; + case PLAY_MODE_REC: + case PLAY_MODE_TIMESHIFT:{ + int pos = paramGetInt(param, "", "offset", 0); + pTv->mAv.seekTimeShift(pos, true); + }break; + } + return ret; +} +int CDTVTvPlayer::set(const char *param) +{ + LOGD("set(%s:%s)", toReadable(getId()), toReadable(param)); + int ret = -1; + switch (mMode) { + case PLAY_MODE_LIVE: { + }break; + case PLAY_MODE_REC: + case PLAY_MODE_TIMESHIFT:{ + int speed = paramGetInt(param, NULL, "speed", 0); + if (speed == 1 || speed == -1) + speed = 0; + pTv->mAv.setTimeShiftSpeed(speed); + }break; + } + return ret; +} + +int CDTVTvPlayer::setupDefault(const char *param) +{ + std::string type = paramGetString(param, NULL, "type", "dtv"); + if (type.compare("dtv") == 0) { + setFEParam(paramGetString(param, NULL, "fe", "").c_str()); + setParam(paramGetString(param, NULL, "para", "").c_str()); + setVideo(paramGetInt(param, "v", "pid", -1), paramGetInt(param, "v", "fmt", -1), paramGetString(param, "v", "para", "").c_str()); + setAudio(paramGetInt(param, "a", "pid", -1), paramGetInt(param, "a", "fmt", -1), paramGetString(param, "a", "para", "").c_str()); + setPcr(paramGetInt(param, "p", "pid", -1), paramGetString(param, "p", "para", "").c_str()); + } + return 0; +} + +int CDTVTvPlayer::tryCloseTFile() +{ +#ifdef SUPPORT_ADTV + if (mTfile) { + int ret; + AM_EVT_Unsubscribe((long)mTfile, AM_TFILE_EVT_START_TIME_CHANGED, tfile_evt_callback, (void*)getId()); + AM_EVT_Unsubscribe((long)mTfile, AM_TFILE_EVT_END_TIME_CHANGED, tfile_evt_callback, (void*)getId()); + ret = AM_TFile_Close(mTfile); + LOGD("close tfile=%d", ret); + } +#endif + return 0; +} + +int CDTVTvPlayer::startLive(const char *param __unused) +{ + int ret = -1; + ret = pTv->playDtvProgramUnlocked(mFEParam, mVpid, mVfmt, mApid, mAfmt, mPpid, paramGetInt(mAparam, NULL, "AudComp", 0)); + mMode = PLAY_MODE_LIVE; + return ret; +} + +int CDTVTvPlayer::startLiveTryRecording(const char *param) +{ + int ret = -1; +#ifdef SUPPORT_ADTV + if (!mDisableTimeShifting && mSourceChanged) { + pTv->stopRecording("timeshifting", NULL); + tryCloseTFile(); + } + + //AM_EVT_Subscribe(0, AM_AV_EVT_PLAYER_UPDATE_INFO, player_info_callback, (void*)getId()); + + LOGD("player(%s) startLive, in live mode", getId()); + ret = startLive(param); + + if (!mDisableTimeShifting && mSourceChanged) { + char buf[256]; + sprintf(buf, + "{\"timeshift\":1,\"dvr\":1,\"path\":\"%s\",\"prefix\":\"TimeShifting\",\"v\":{\"pid\":%d,\"fmt\":%d},\"a\":{\"pid\":%d,\"fmt\":%d},\"max\":%s}", + paramGetString(mParam, NULL, "path", "/storage").c_str(), + mVpid, mVfmt, mApid, mAfmt, + paramGetString(mParam, NULL, "max", "{\"time\":15}").c_str()); + ret = pTv->startRecording("timeshifting", buf, this); + if (ret != 0) { + TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_TIMESHIFT_REC_FAIL; + pTv->sendTvEvent(AvPlayBackEvt); + } + } + + CTvRecord *recorder = RecorderManager::getInstance().getDev("timeshifting"); + if (recorder) { + mTfile = recorder->detachFileHandler(); + if (mTfile) { + AM_EVT_Subscribe((long)mTfile, AM_TFILE_EVT_START_TIME_CHANGED, tfile_evt_callback, (void*)getId()); + AM_EVT_Subscribe((long)mTfile, AM_TFILE_EVT_END_TIME_CHANGED, tfile_evt_callback, (void*)getId()); + AM_TFile_TimeStart(mTfile); + } + } else { + LOGD("player(%s) rec(tf) fail, in live(no rec) mode", getId()); + mMode = PLAY_MODE_LIVE_WITHOUT_TIMESHIFT; + } +#endif + return ret; +} + +int CDTVTvPlayer::startLiveTryTimeShift(const char *param) +{ + int ret = -1; +#ifdef SUPPORT_ADTV + if (!mDisableTimeShifting && mSourceChanged) { + pTv->stopRecording("timeshifting", NULL); + tryCloseTFile(); + + char buf[256]; + sprintf(buf, + "{\"timeshift\":1,\"dvr\":1,\"path\":\"%s\",\"prefix\":\"TimeShifting\",\"v\":{\"pid\":%d,\"fmt\":%d},\"a\":{\"pid\":%d,\"fmt\":%d},\"max\":%s}", + paramGetString(mParam, NULL, "path", "/storage").c_str(), + mVpid, mVfmt, mApid, mAfmt, + paramGetString(mParam, NULL, "max", "{\"time\":15}").c_str()); + ret = pTv->startRecording("timeshifting", buf, this); + if (ret != 0) { + LOGD("start timeshifting rec fail"); + TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_TIMESHIFT_REC_FAIL; + pTv->sendTvEvent(AvPlayBackEvt); + } + } + + CTvRecord *recorder = RecorderManager::getInstance().getDev("timeshifting"); + if (!recorder) { + LOGD("recorder(timeshifting not found)"); + TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_TIMESHIFT_PLAY_FAIL; + pTv->sendTvEvent(AvPlayBackEvt); + + LOGD("player(%s) in live mode", getId()); + ret = startLive(param); + + mMode = PLAY_MODE_LIVE_WITHOUT_TIMESHIFT; + + } else { + + if (!mDisableTimeShifting) { + mOffset = recorder->getWritePosition(); + mTfile = recorder->detachFileHandler(); + + if (mTfile) { + AM_EVT_Subscribe((long)mTfile, AM_TFILE_EVT_START_TIME_CHANGED, tfile_evt_callback, (void*)getId()); + AM_EVT_Subscribe((long)mTfile, AM_TFILE_EVT_END_TIME_CHANGED, tfile_evt_callback, (void*)getId()); + AM_TFile_TimeStart(mTfile); + } + + AM_AV_TimeshiftPara_t para; + para.dmx_id = 0; + para.mode = AM_AV_TIMESHIFT_MODE_TIMESHIFTING; + para.file_path[0] = '\0'; + para.tfile = mTfile; + para.offset_ms = mOffset; + para.start_paused = false; + AM_AV_TimeshiftMediaInfo_t *pminfo = ¶.media_info; + pminfo->vid_pid = mVpid; + pminfo->vid_fmt = mVfmt; + pminfo->aud_cnt = 1; + pminfo->audios[0].pid = mApid; + pminfo->audios[0].fmt = mAfmt; + pminfo->sub_cnt = 0; + pminfo->ttx_cnt = 0; + pminfo->duration = paramGetInt(mParam, "max", "time", 0); + pminfo->program_name[0] = '\0'; + LOGD("play Dtv TimeShift"); + ret = pTv->playDtvTimeShiftUnlocked(mFEParam, (void *)¶, paramGetInt(mAparam, NULL, "AudComp", 0)); + if (ret == 0) { + //LOGD("subscribe update, %s", getId()); + //AM_EVT_Subscribe(0, AM_AV_EVT_PLAYER_UPDATE_INFO, player_info_callback, (void*)getId()); + + LOGD("player(%s) in timeshift mode", getId()); + mMode = PLAY_MODE_TIMESHIFT; + } else { + LOGD("player(%s) timeshift play fail, in live mode", getId()); + ret = startLive(param); + mMode = PLAY_MODE_LIVE_WITHOUT_TIMESHIFT; + } + } else { + LOGD("player(%s) force in live mode", getId()); + ret = startLive(param); + mMode = PLAY_MODE_LIVE_WITHOUT_TIMESHIFT; + } + } +#endif + return ret; +} + +void CDTVTvPlayer::tfile_evt_callback ( long dev_no, int event_type, void *param, void *user_data ) +{ +#ifdef SUPPORT_ADTV + switch (event_type) { + case AM_TFILE_EVT_START_TIME_CHANGED: { + LOGD("player(%s) : start time(%d)", (char*)user_data, (int)(long)param ); + TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_TIMESHIFT_START_TIME_CHANGED; + AvPlayBackEvt.mProgramId = (int)(long)param; + CTvPlayer *player = PlayerManager::getInstance().getDev((char *)user_data); + if (player) + player->sendTvEvent(AvPlayBackEvt); + } + break; + case AM_TFILE_EVT_END_TIME_CHANGED: + LOGD("player(%s) : end time(%d)", (char*)user_data, (int)(long)param ); + /*TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_TIMESHIFT_END_TIME_CHANGED; + AvPlayBackEvt.mProgramId = (int)(long)param; + CTvPlayer *player = PlayerManager::getInstance().getDev((char *)user_data); + if (player) + player->sendTvEvent(AvPlayBackEvt);*/ + break; + default: + break; + } +#endif +} + +void CDTVTvPlayer::onPlayUpdate(const CAv::AVEvent &ev) +{ + if (ev.type == CAv::AVEvent::EVENT_PLAY_UPDATE) + { + /*typedef enum + { + AV_TIMESHIFT_STAT_STOP, + AV_TIMESHIFT_STAT_PLAY, + AV_TIMESHIFT_STAT_PAUSE, + AV_TIMESHIFT_STAT_FFFB, + AV_TIMESHIFT_STAT_EXIT, + AV_TIMESHIFT_STAT_INITOK, + AV_TIMESHIFT_STAT_SEARCHOK, + } AV_TimeshiftState_t; + */ + LOGD("player(%s) update status:%d, para:%d", getId(), ev.status, ev.param); + switch (ev.status) { + case 1: + case 2: + case 3: + { + if (mMode == PLAY_MODE_REC && ev.param == 0) {// play back need a time start + TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_TIMESHIFT_START_TIME_CHANGED; + AvPlayBackEvt.mProgramId = ev.param; + sendTvEvent(AvPlayBackEvt); + LOGD("player(%s) : start time(%d)", getId(), AvPlayBackEvt.mProgramId); + } + TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_TIMESHIFT_CURRENT_TIME_CHANGED; + AvPlayBackEvt.mProgramId = ev.param; + sendTvEvent(AvPlayBackEvt); + LOGD("player(%s) : current time(%d)", getId(), AvPlayBackEvt.mProgramId); + }break; + } + } +} + +void CDTVTvPlayer::player_info_callback(long dev_no, int event_type, void *param, void *data) +{ +#ifdef SUPPORT_ADTV + if (event_type == AM_AV_EVT_PLAYER_UPDATE_INFO) + { + /*typedef enum + { + AV_TIMESHIFT_STAT_STOP, + AV_TIMESHIFT_STAT_PLAY, + AV_TIMESHIFT_STAT_PAUSE, + AV_TIMESHIFT_STAT_FFFB, + AV_TIMESHIFT_STAT_EXIT, + AV_TIMESHIFT_STAT_INITOK, + AV_TIMESHIFT_STAT_SEARCHOK, + } AV_TimeshiftState_t; + */ + AM_AV_TimeshiftInfo_t *info = (AM_AV_TimeshiftInfo_t*)param; + if (info == NULL) + return; + switch (info->status) { + case 5: + //EVENT_PLAYBACK_START; + break; + case 4: + //EVENT_PLAYBACK_END; + break; + case 1: + case 2: + case 3: { + LOGD("player(%s) : current time(%d)", (char*)data, info->current_time); + TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_TIMESHIFT_CURRENT_TIME_CHANGED; + AvPlayBackEvt.mProgramId = info->current_time; + CTvPlayer *player = PlayerManager::getInstance().getDev((char *)data); + if (player) + player->sendTvEvent(AvPlayBackEvt); + } + } + } +#endif +} + +void CDTVTvPlayer::onEvent(const CTvRecord::RecEvent &ev) { + if (ev.id.compare("timeshifting") != 0) + return; + + LOGD ( "on RecEvent = %d", ev.type); + switch ( ev.type ) { + case CTvRecord::RecEvent::EVENT_REC_START: { + }break; + case CTvRecord::RecEvent::EVENT_REC_STOP: { + if (ev.error != 0) { + LOGD("player(%s) : rec stop, current err(%d)", getId(), ev.error); + TvEvent::AVPlaybackEvent AvPlayBackEvt; + AvPlayBackEvt.mMsgType = TvEvent::AVPlaybackEvent::EVENT_AV_TIMESHIFT_REC_FAIL; + AvPlayBackEvt.mProgramId = ev.error; + sendTvEvent(AvPlayBackEvt); + } + }break; + default: + break; + } +} + +#ifdef SUPPORT_ADTV +int CDTVTvPlayer::readMediaInfoFromFile(const char *file_path, AM_AV_TimeshiftMediaInfo_t *info) +{ + uint8_t buffer[2][sizeof(AM_REC_MediaInfo_t) + 4*(sizeof(AM_REC_MediaInfo_t)/188 + 1)]; + uint8_t *buf = buffer[0]; + uint8_t *pkt_buf = buffer[1]; + int pos = 0, info_len, i, fd, name_len, data_len; + +#define READ_INT(_i)\ + AM_MACRO_BEGIN\ + if ((info_len-pos) >= 4) {\ + (_i) = ((int)buf[pos]<<24) | ((int)buf[pos+1]<<16) | ((int)buf[pos+2]<<8) | (int)buf[pos+3];\ + pos += 4;\ + } else {\ + goto read_error;\ + }\ + AM_MACRO_END + + fd = open(file_path, O_RDONLY, 0666); + if (fd < 0) { + LOGE("Cannot open file '%s'", file_path); + return -1; + } + + info_len = read(fd, pkt_buf, sizeof(buffer[1])); + + data_len = 0; + /*skip the packet headers*/ + for (i=0; i<info_len; i++) { + if ((i%188) > 3) { + buf[data_len++] = pkt_buf[i]; + } + } + + info_len = data_len; + + READ_INT(info->duration); + + name_len = sizeof(info->program_name); + if ((info_len-pos) >= name_len) { + memcpy(info->program_name, buf+pos, name_len); + info->program_name[name_len - 1] = 0; + pos += name_len; + } else { + goto read_error; + } + READ_INT(info->vid_pid); + READ_INT(info->vid_fmt); + + READ_INT(info->aud_cnt); + LOGD("audio count %d", info->aud_cnt); + for (i=0; i<info->aud_cnt; i++) { + READ_INT(info->audios[i].pid); + READ_INT(info->audios[i].fmt); + memcpy(info->audios[i].lang, buf+pos, 4); + pos += 4; + } + READ_INT(info->sub_cnt); + LOGD("subtitle count %d", info->sub_cnt); + for (i=0; i<info->sub_cnt; i++) { + READ_INT(info->subtitles[i].pid); + READ_INT(info->subtitles[i].type); + READ_INT(info->subtitles[i].composition_page); + READ_INT(info->subtitles[i].ancillary_page); + READ_INT(info->subtitles[i].magzine_no); + READ_INT(info->subtitles[i].page_no); + memcpy(info->subtitles[i].lang, buf+pos, 4); + pos += 4; + } + READ_INT(info->ttx_cnt); + LOGD("teletext count %d", info->ttx_cnt); + for (i=0; i<info->ttx_cnt; i++) { + READ_INT(info->teletexts[i].pid); + READ_INT(info->teletexts[i].magzine_no); + READ_INT(info->teletexts[i].page_no); + memcpy(info->teletexts[i].lang, buf+pos, 4); + pos += 4; + } + close(fd); + return 0; + +read_error: + LOGE("Read media info from file error, len %d, pos %d", info_len, pos); + close(fd); + + return -1; +} +#endif + +CATVTvPlayer::CATVTvPlayer(CTv *tv) : CTvPlayer(tv) { + mFEParam = NULL; + mVparam = NULL; + mAparam = NULL; + mParam = NULL; +} + +CATVTvPlayer::~CATVTvPlayer() { + if (mFEParam) + free((void*)mFEParam); + if (mVparam) + free((void*)mVparam); + if (mAparam) + free((void*)mAparam); + if (mParam) + free((void*)mParam); +} + +int CATVTvPlayer::setFEParam(const char *param) { + LOGD("setFE(%s)", toReadable(param)); + if (mFEParam) + free((void*)mFEParam); + mFEParam = param? strdup(param) : NULL; + return 0; +} + +int CATVTvPlayer::setVideo(const char *param) { + LOGD("setVideo(%s)", toReadable(param)); + if (mVparam) + free((void*)mVparam); + mVparam = param? strdup(param) : NULL; + return 0; +} +int CATVTvPlayer::setAudio(const char *param) { + LOGD("setAudio(%s)", toReadable(param)); + if (mAparam) + free((void*)mAparam); + mAparam = param? strdup(param) : NULL; + return 0; +} + +int CATVTvPlayer::setParam(const char *param) { + LOGD("setParam(%s)", toReadable(param)); + if (mParam) + free((void*)mParam); + mParam = param? strdup(param) : NULL; + return 0; +} + +int CATVTvPlayer::start(const char *param) { + LOGD("start(%s:%s) current mode(%d)", toReadable(getId()), toReadable(param)); + int ret = -1; + ret = pTv->playAtvProgram(paramGetInt(mFEParam, NULL, "freq", 44250000), + paramGetInt(mFEParam, NULL, "vtd", 1), + paramGetInt(mFEParam, NULL, "atd", 0), + 0, + paramGetInt(mAparam, NULL, "AudComp", 0)); + return ret; +} + +int CATVTvPlayer::stop(const char *param) { + LOGD("CATVTvPlayer stop(%s:%s)", toReadable(getId()), toReadable(param)); + int ret = -1; + + ret = pTv->stopPlaying(true, false); + + LOGD("stop(%s)=%d", toReadable(param), ret); + return ret; +} + +int CATVTvPlayer::set(const char *param) +{ + LOGD("set(%s:%s)", toReadable(getId()), toReadable(param)); + int ret = 0; + return ret; +} + +int CATVTvPlayer::setupDefault(const char *param) +{ + std::string type = paramGetString(param, NULL, "type", "dtv"); + if (type.compare("atv") == 0) { + setFEParam(paramGetString(param, NULL, "fe", "").c_str()); + setAudio(paramGetString(param, "a", "para", "").c_str()); + setParam(paramGetString(param, NULL, "para", "").c_str()); + } + return 0; +} + diff --git a/tv/tvserver/libtv/tv/CTvPlayer.h b/tv/tvserver/libtv/tv/CTvPlayer.h new file mode 100644 index 0000000..d60e721 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvPlayer.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CTVPLAYER_H_) +#define _CTVPLAYER_H_ + +#include <string.h> + +#ifdef SUPPORT_ADTV +#include "am_misc.h" +#endif +#include "CTv.h" +#include "CTvRecord.h" +#include "CTvManager.h" +#include "tvutils.h" + + +using namespace android; + +class CTv; + +class CTvPlayer { + public: + CTvPlayer(CTv *tv); + virtual ~CTvPlayer(); + + void setId(const char *id) { if(mId) free((void*)mId); mId = strdup(id); } + const char * getId() { return mId; } + bool equals(CTvPlayer &player __unused) { return true;/*support only one player now.*/ } + void sendTvEvent ( const CTvEv &ev ); + + virtual int start(const char *param) = 0; + virtual int stop(const char *param) = 0; + virtual int pause(const char *param) = 0 ; + virtual int resume(const char *param) = 0 ; + virtual int seek(const char *param) = 0; + virtual int set(const char *param) = 0; + virtual int setupDefault(const char *param) = 0; + + protected: + CTv *pTv; + + private: + const char *mId; +}; + +class CDTVTvPlayer : public CTvPlayer, public CTvRecord::IObserver { + + static const bool bStartInTimeShift = true; + + public: + CDTVTvPlayer(CTv *tv) ; + ~CDTVTvPlayer() ; + + int start(const char *param); + int stop(const char *param); + int pause(const char *param) ; + int resume(const char *param) ; + int seek(const char *param); + int set(const char *param); + int setupDefault(const char *param); + + int setFEParam(const char *param) ; + int setVideo(int pid, int format, const char *param) ; + int setAudio(int pid, int format, const char *param) ; + int setPcr(int pid, const char *param) ; + int setParam(const char *param) ; + + void onEvent(const CTvRecord::RecEvent &ev) ; + void onPlayUpdate(const CAv::AVEvent &ev); + + + private: + + static const int PLAY_MODE_LIVE = 0; + static const int PLAY_MODE_REC = 1; + static const int PLAY_MODE_TIMESHIFT = 2; + static const int PLAY_MODE_LIVE_WITHOUT_TIMESHIFT = 3; + int mMode; + + bool mDisableTimeShifting; + + const char *mFEParam; + + int mVpid; + int mVfmt; + const char *mVparam; + int mApid; + int mAfmt; + const char *mAparam; + int mPpid; + const char *mPparam; + + const char *mParam; + + int mOffset; + + bool mSourceChanged; +#ifdef SUPPORT_ADTV + static int readMediaInfoFromFile(const char *file_path, AM_AV_TimeshiftMediaInfo_t *info); + AM_TFile_t mTfile = nullptr; +#endif + + int tryCloseTFile(); + + int startLive(const char *param); + int startLiveTryTimeShift(const char *param); + int startLiveTryRecording(const char *param); + + static void tfile_evt_callback(long dev_no, int event_type, void *param, void *data); + static void player_info_callback(long dev_no, int event_type, void *param, void *data); + +}; + +class CATVTvPlayer : public CTvPlayer { + public: + CATVTvPlayer(CTv *tv) ; + ~CATVTvPlayer() ; + + int start(const char *param); + int stop(const char *param); + int pause(const char *param __unused) { return 0; }; + int resume(const char *param __unused) { return 0; }; + int seek(const char *param __unused) { return 0; }; + int set(const char *param); + int setupDefault(const char *param); + + int setFEParam(const char *param) ; + int setVideo(const char *param) ; + int setAudio(const char *param) ; + int setParam(const char *param) ; + + private: + + const char *mFEParam; + const char *mVparam; + const char *mAparam; + + const char *mParam; + +}; + + +#endif //_CTVPLAYER_H_ + diff --git a/tv/tvserver/libtv/tv/CTvRecord.cpp b/tv/tvserver/libtv/tv/CTvRecord.cpp new file mode 100644 index 0000000..e4e6704 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvRecord.cpp @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvRecord" + +#include <tvutils.h> +#include "CTvRecord.h" +#include "CTvLog.h" + +#define FEND_DEV_NO 0 +#define DVR_DEV_NO 0 +#define DVR_BUF_SIZE 1024*1024 +#define DVR_DEV_COUNT (2) + +CTvRecord::CTvRecord() +{ +#ifdef SUPPORT_ADTV + memset(&mCreateParam, 0, sizeof(mCreateParam)); + memset(&mRecParam, 0, sizeof(mRecParam)); + memset(&mRecInfo, 0, sizeof(mRecInfo)); + mCreateParam.fend_dev = FEND_DEV_NO; + mCreateParam.dvr_dev = DVR_DEV_NO; + mCreateParam.async_fifo_id = 0; + mRec = NULL; +#endif +} + +CTvRecord::~CTvRecord() +{ + if (mId) + free((void*)mId); +#ifdef SUPPORT_ADTV + if (mRec) { + AM_REC_Destroy(mRec); + mRec = NULL; + } +#endif +} + +int CTvRecord::setFilePath(const char *name) +{ + LOGD("setFilePath(%s)", toReadable(name)); +#ifdef SUPPORT_ADTV + strncpy(mCreateParam.store_dir, name, AM_REC_PATH_MAX); + mCreateParam.store_dir[AM_REC_PATH_MAX-1] = 0; +#endif + return 0; +} + +int CTvRecord::setFileName(const char *prefix, const char *suffix) +{ + LOGD("setFileName(%s,%s)", toReadable(prefix), toReadable(suffix)); +#ifdef SUPPORT_ADTV + strncpy(mRecParam.prefix_name, prefix, AM_REC_NAME_MAX); + mRecParam.prefix_name[AM_REC_NAME_MAX-1] = 0; + strncpy(mRecParam.suffix_name, suffix, AM_REC_SUFFIX_MAX); + mRecParam.suffix_name[AM_REC_SUFFIX_MAX-1] = 0; +#endif + return 0; +} + +#ifdef SUPPORT_ADTV +int CTvRecord::setMediaInfo(AM_REC_MediaInfo_t *info) +{ + LOGD("setMediaInfo()" ); + memcpy(&mRecParam.media_info, info, sizeof(AM_REC_MediaInfo_t)); + return 0; +} + +int CTvRecord::getInfo(AM_REC_RecInfo_t *info) +{ + if (!mRec || !info) + return -1; + return AM_REC_GetRecordInfo(mRec, info); +} + +AM_TFile_t CTvRecord::getFileHandler() +{ + if (!mRec) + return NULL; + + AM_TFile_t file = NULL; + AM_ErrorCode_t err = DVB_SUCCESS; + err = AM_REC_GetTFile(mRec, &file, NULL); + if (err != DVB_SUCCESS) + return NULL; + return file; +} + +AM_TFile_t CTvRecord::detachFileHandler() +{ + if (!mRec) + return NULL; + + AM_TFile_t file = NULL; + int flag; + AM_ErrorCode_t err = DVB_SUCCESS; + err = AM_REC_GetTFile(mRec, &file, &flag); + if (err != DVB_SUCCESS) { + LOGD("get tfile fail(%d)", err); + return NULL; + } + AM_REC_SetTFile(mRec, file, flag |REC_TFILE_FLAG_DETACH); + return file; +} +#endif + +int CTvRecord::setMediaInfoExt(int type, int val) +{ + LOGD("setMediaInfoExt(%d,%d)", type, val ); +#ifdef SUPPORT_ADTV + switch (type) { + case REC_EXT_TYPE_PMTPID: + mRecParam.program.i_pid = val; + break; + case REC_EXT_TYPE_PN: + mRecParam.program.i_number = val; + break; + case REC_EXT_TYPE_ADD_PID: + mExtPids.add(val); + case REC_EXT_TYPE_REMOVE_PID: + mExtPids.add(val); + default: + return -1; + break; + } +#endif + return 0; +} + +int CTvRecord::setTimeShiftMode(bool enable, int duration, int size) +{ + LOGD("setTimeShiftMode(%d, duration:%d - size:%d)", enable, duration, size ); +#ifdef SUPPORT_ADTV + mRecParam.is_timeshift = enable? true : false; + mRecParam.total_time = enable ? duration : 0; + mRecParam.total_size = enable ? size : 0; +#endif + return 0; +} + +int CTvRecord::setDev(int type, int id) +{ + LOGD("setDev(%d,%d)", type, id ); +#ifdef SUPPORT_ADTV + switch (type) { + case REC_DEV_TYPE_FE: + mCreateParam.fend_dev = id; + break; + case REC_DEV_TYPE_DVR: + mCreateParam.dvr_dev = id; + break; + case REC_DEV_TYPE_FIFO: + mCreateParam.async_fifo_id = id; + break; + default: + return -1; + break; + } +#endif + return 0; +} + +void CTvRecord::rec_evt_cb(long dev_no, int event_type, void *param, void *data) +{ + CTvRecord *rec; +#ifdef SUPPORT_ADTV + AM_REC_GetUserData((AM_REC_Handle_t)dev_no, (void**)&rec); + if (!rec) + return; + + switch (event_type) { + case AM_REC_EVT_RECORD_END :{ + AM_REC_RecEndPara_t *endpara = (AM_REC_RecEndPara_t*)param; + rec->mEvent.type = RecEvent::EVENT_REC_STOP; + rec->mEvent.id = std::string((const char*)data); + rec->mEvent.error = endpara->error_code; + rec->mEvent.size = endpara->total_size; + rec->mEvent.time = endpara->total_time; + rec->mpObserver->onEvent(rec->mEvent); + }break; + case AM_REC_EVT_RECORD_START: { + rec->mEvent.type = RecEvent::EVENT_REC_START; + rec->mEvent.id = std::string((const char*)data); + rec->mpObserver->onEvent(rec->mEvent); + }break; + default: + break; + } +#endif + LOGD ( "rec_evt_callback : dev_no %ld type %d param = %ld\n", + dev_no, event_type, (long)param); +} + +int CTvRecord::start(const char *param) +{ + int ret = -1; + LOGD("start(%s:%s)", toReadable(mId), toReadable(param)); +#ifdef SUPPORT_ADTV + ret = AM_REC_Create(&mCreateParam, &mRec); + if (ret != DVB_SUCCESS) { + LOGD("create fail(%d)", ret); + mRec = NULL; + return ret; + } + AM_REC_SetUserData(mRec, this); + AM_EVT_Subscribe((long)mRec, AM_REC_EVT_RECORD_START, rec_evt_cb, (void*)getId()); + AM_EVT_Subscribe((long)mRec, AM_REC_EVT_RECORD_END, rec_evt_cb, (void*)getId()); + + AM_REC_SetTFile(mRec, NULL, REC_TFILE_FLAG_AUTO_CREATE); + ret = AM_REC_StartRecord(mRec, &mRecParam); + if (ret != DVB_SUCCESS) { + LOGD("start fail(%d)", ret); + AM_EVT_Unsubscribe((long)mRec, AM_REC_EVT_RECORD_START, rec_evt_cb, (void*)getId()); + AM_EVT_Unsubscribe((long)mRec, AM_REC_EVT_RECORD_END, rec_evt_cb, (void*)getId()); + AM_REC_Destroy(mRec); + mRec = NULL; + } else { + LOGD("start ok."); + } +#endif + return ret; +} + +int CTvRecord::stop(const char *param) +{ + LOGD("stop(%s:%s)", toReadable(mId), toReadable(param)); +#ifdef SUPPORT_ADTV + if (!mRec) + return -1; + + AM_EVT_Subscribe((long)mRec, AM_REC_EVT_RECORD_START, rec_evt_cb, (void*)getId()); + AM_EVT_Subscribe((long)mRec, AM_REC_EVT_RECORD_END, rec_evt_cb, (void*)getId()); + + return AM_REC_StopRecord(mRec); +#else + return -1; +#endif +} + +int CTvRecord::setRecCurTsOrCurProgram(int sel) +{ + LOGD("setRecCurTsOrCurProgram(%s:%d)", toReadable(mId), sel); +#ifdef SUPPORT_ADTV + char buf[64]; + memset(buf, 0, sizeof(buf)); + snprintf(buf, sizeof(buf), "/sys/class/stb/dvr%d_mode", mCreateParam.dvr_dev); + if (sel) + tvWriteSysfs(buf, "ts"); + else + tvWriteSysfs(buf, "pid"); +#endif + return 0; +} + +bool CTvRecord::equals(CTvRecord &recorder) +{ +#ifdef SUPPORT_ADTV + return mCreateParam.fend_dev == recorder.mCreateParam.fend_dev + && mCreateParam.dvr_dev == recorder.mCreateParam.dvr_dev + && mCreateParam.async_fifo_id == recorder.mCreateParam.async_fifo_id; +#else + return false; +#endif +} + +int CTvRecord::getStartPosition() +{ +#ifdef SUPPORT_ADTV + if (!mRec) + return 0; +#endif + return 0; +} + +int CTvRecord::getWritePosition() +{ + return 0; +} + +int CTvRecord::setupDefault(const char *param) +{ +#ifdef SUPPORT_ADTV + setDev(CTvRecord::REC_DEV_TYPE_FE, paramGetInt(param, NULL, "fe", 0)); + setDev(CTvRecord::REC_DEV_TYPE_DVR, paramGetInt(param, NULL, "dvr", 0)); + setDev(CTvRecord::REC_DEV_TYPE_FIFO, paramGetInt(param, NULL, "fifo", 0)); + setFilePath(paramGetString(param, NULL, "path", "/storage").c_str()); + setFileName(paramGetString(param, NULL, "prefix", "REC").c_str(), paramGetString(param, NULL, "suffix", "ts").c_str()); + AM_REC_MediaInfo_t info; + info.duration = 0; + info.vid_pid = paramGetInt(param, "v", "pid", -1); + info.vid_fmt = paramGetInt(param, "v", "fmt", -1); + info.aud_cnt = 1; + info.audios[0].pid = paramGetInt(param, "a", "pid", -1); + info.audios[0].fmt = paramGetInt(param, "a", "fmt", -1); + info.sub_cnt = 0; + info.ttx_cnt = 0; + memset(info.program_name, 0, sizeof(info.program_name)); + setMediaInfo(&info); + setTimeShiftMode( + paramGetInt(param, NULL, "timeshift", 0) ? true : false, + paramGetInt(param, "max", "time", 60), + paramGetInt(param, "max", "size", -1)); +#endif + return 0; +} + diff --git a/tv/tvserver/libtv/tv/CTvRecord.h b/tv/tvserver/libtv/tv/CTvRecord.h new file mode 100644 index 0000000..eba6189 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvRecord.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ +#if !defined(_CTVRECORD_H_) +#define _CTVRECORD_H_ + +#ifdef SUPPORT_ADTV +#include "am_rec.h" +#endif +#include "CTvEv.h" + +#include <utils/Vector.h> + +using namespace android; + +class CTvRecord { +public: + CTvRecord(); + ~CTvRecord(); + + void setId(const char* id) { mId = strdup(id); } + const char* getId() { return mId; } + + int setFilePath(const char *name); + + int setFileName(const char *prefix, const char *suffix); + + static const int REC_EXT_TYPE_PMTPID = 0; + static const int REC_EXT_TYPE_PN = 1; + static const int REC_EXT_TYPE_ADD_PID = 2; + static const int REC_EXT_TYPE_REMOVE_PID = 3; + int setMediaInfoExt(int type, int val); + + int setTimeShiftMode(bool enable, int duration, int size); + + static const int REC_DEV_TYPE_FE = 0; + static const int REC_DEV_TYPE_DVR = 1; + static const int REC_DEV_TYPE_FIFO = 2; + int setDev(int type, int id); + + int setupDefault(const char *param); + + int start(const char *param); + + int stop(const char *param); + + int setRecCurTsOrCurProgram(int sel); // 1: all program in the Ts; 0:current program + + //for timeshifting + int getStartPosition(); + int getWritePosition(); + + bool equals(CTvRecord &recorder); + + class RecEvent : public CTvEv { + public: + RecEvent(): CTvEv(CTvEv::TV_EVENT_RECORDER) { } + ~RecEvent() {} + static const int EVENT_REC_START=1; + static const int EVENT_REC_STOP=2; + static const int EVENT_REC_STARTPOSITION_CHANGED=3; + std::string id; + int type; + int error; + int size; + long time; + }; + + class IObserver { + public: + IObserver() {}; + virtual ~IObserver() {}; + virtual void onEvent(const RecEvent &ev) = 0; + }; + + int setObserver(IObserver *ob) { + mpObserver = ob; + return 0; + } + +#ifdef SUPPORT_ADTV + int setMediaInfo(AM_REC_MediaInfo_t *info); + int getInfo(AM_REC_RecInfo_t *info); + AM_TFile_t getFileHandler(); + AM_TFile_t detachFileHandler(); + + AM_REC_CreatePara_t mCreateParam; +#endif +private : + + char *mId; +#ifdef SUPPORT_ADTV + AM_REC_Handle_t mRec; + AM_REC_RecPara_t mRecParam; + AM_REC_RecInfo_t mRecInfo; +#endif + Vector<int> mExtPids; + IObserver *mpObserver; + RecEvent mEvent; + + static void rec_evt_cb(long dev_no, int event_type, void *param, void *data); + +}; + +#endif //_CTVRECORD_H_ diff --git a/tv/tvserver/libtv/tv/CTvRrt.cpp b/tv/tvserver/libtv/tv/CTvRrt.cpp new file mode 100644 index 0000000..1149aff --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvRrt.cpp @@ -0,0 +1,639 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvRrt" + +#include <tinyxml.h> +#include "CTvRrt.h" + +pthread_mutex_t rrt_search_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t rrt_update_mutex = PTHREAD_MUTEX_INITIALIZER; + +/** + * @Function: GetElementPointerByName + * @Description: search data from RRT file for save RRT data + * @Param: pRootElement: Root element of RRT xml file; + ElementName: name of TiXmlElement need been search + * @Return: the TiXmlElement which has been search + */ +TiXmlElement *GetElementPointerByName(TiXmlElement* pRootElement, char *ElementName) +{ + if (strcmp(ElementName, pRootElement->Value()) == 0) { + return pRootElement; + } + + TiXmlElement* pElement = NULL; + TiXmlElement* pRetElement = NULL; + for (pElement=pRootElement->FirstChildElement();pElement;pElement = pElement->NextSiblingElement()) { + pRetElement = GetElementPointerByName(pElement, ElementName); + } + + if (pRetElement != NULL) { + LOGD("GetNodePointerByName: %s", pRetElement->Value()); + return pRetElement; + } else { + return NULL; + } +} + +/** + * @Function: OpenXmlFile + * @Description: Open XML file + * @Param: + * @Return: The pRRTFile which has been opened + */ +TiXmlDocument *OpenXmlFile(void) +{ + // define TiXmlDocument + TiXmlDocument *pRRTFile = new TiXmlDocument(); + pRRTFile->LoadFile(); + if (NULL == pRRTFile) { + LOGD("create RRTFile error!\n"); + return NULL; + } + + //add Declaration + LOGD("start create Declaration!\n"); + TiXmlDeclaration *pNewDeclaration = new TiXmlDeclaration("1.0","utf-8",""); + if (NULL == pNewDeclaration) { + LOGD("create Declaration error!\n"); + return NULL; + } + pRRTFile->LinkEndChild(pNewDeclaration); + + //add root element + LOGD("start create RootElement!\n"); + TiXmlElement *pRootElement = new TiXmlElement("rating-system-definitions"); + if (NULL == pRootElement) { + LOGD("create RootElement error!\n"); + return NULL; + } + pRRTFile->LinkEndChild(pRootElement); + pRootElement->SetAttribute("xmlns:android", "http://schemas.android.com/apk/res/android"); + pRootElement->SetAttribute("android:versionCode", "2"); + + return pRRTFile; +} + +/** + * @Function: SaveDataToXml + * @Description: Save data to XML file + * @Param:pRRTFile:The pRRTFile which has been opened + rrt_info:Charge for GetRRTRating + * @Return: true:save success; false:save failed + */ +bool SaveDataToXml(TiXmlDocument *pRRTFile, rrt_info_t rrt_info) +{ + if (pRRTFile == NULL) { + LOGE("xml file don't open!\n"); + return false; + } + pthread_mutex_lock(&rrt_update_mutex); + + TiXmlElement *pRootElement = pRRTFile->RootElement(); + if (pRootElement->FirstChildElement() == NULL) { + TiXmlElement *pRatingSystemElement = new TiXmlElement("rating-system-definition"); + if (NULL == pRatingSystemElement) { + LOGD("create pRatingSystemElement error!\n"); + pthread_mutex_unlock(&rrt_update_mutex); + return false; + } + pRootElement->LinkEndChild(pRatingSystemElement); + pRatingSystemElement->SetAttribute("android:name", rrt_info.dimensions_name); + pRatingSystemElement->SetAttribute("android:rating", rrt_info.rating_region); + pRatingSystemElement->SetAttribute("android:country",rrt_info.rating_region_name); + pRatingSystemElement->SetAttribute("android:dimension_id",rrt_info.dimensions_id); + + TiXmlElement *pNewElement = new TiXmlElement("rating-definition"); + if (NULL == pNewElement) { + pthread_mutex_unlock(&rrt_update_mutex); + return false; + } + pRatingSystemElement->LinkEndChild(pNewElement); + pNewElement->SetAttribute("android:title",rrt_info.abbrev_rating_value_text); + pNewElement->SetAttribute("android:description",rrt_info.rating_value_text); + pNewElement->SetAttribute("android:rating_id",rrt_info.rating_value_id); + + } else { + TiXmlElement *pTmpElement = GetElementPointerByName(pRootElement, "rating-system-definition"); + if ((strcmp(pTmpElement->FirstAttribute()->Value(), rrt_info.dimensions_name) == 0) && + (strcmp(pTmpElement->FirstAttribute()->Next()->Next()->Value(), rrt_info.rating_region_name) == 0) && + (pTmpElement->LastAttribute()->IntValue() == rrt_info.dimensions_id)) { + LOGD("add new rating-definition to rating-system-definition!\n"); + TiXmlElement *pNewElement = new TiXmlElement("rating-definition"); + if (NULL == pNewElement) { + pthread_mutex_unlock(&rrt_update_mutex); + return false; + } + pTmpElement->LinkEndChild(pNewElement); + pNewElement->SetAttribute("android:title",rrt_info.abbrev_rating_value_text); + pNewElement->SetAttribute("android:description",rrt_info.rating_value_text); + pNewElement->SetAttribute("android:rating_id",rrt_info.rating_value_id); + } else { + LOGD("create new rating-system-definition!\n"); + TiXmlElement *pRatingSystemElement = new TiXmlElement("rating-system-definition"); + if (NULL == pRatingSystemElement) { + LOGD("create pRatingSystemElement error!\n"); + pthread_mutex_unlock(&rrt_update_mutex); + return false; + } + pRootElement->LinkEndChild(pRatingSystemElement); + pRatingSystemElement->SetAttribute("android:name", rrt_info.dimensions_name); + pRatingSystemElement->SetAttribute("android:rating", rrt_info.rating_region); + pRatingSystemElement->SetAttribute("android:country",rrt_info.rating_region_name); + pRatingSystemElement->SetAttribute("android:dimension_id",rrt_info.dimensions_id); + + TiXmlElement *pNewElement = new TiXmlElement("rating-definition"); + if (NULL == pNewElement) { + pthread_mutex_unlock(&rrt_update_mutex); + return false; + } + pRatingSystemElement->LinkEndChild(pNewElement); + pNewElement->SetAttribute("android:title",rrt_info.abbrev_rating_value_text); + pNewElement->SetAttribute("android:description",rrt_info.rating_value_text); + pNewElement->SetAttribute("android:rating_id",rrt_info.rating_value_id); + } + } + + if (!pRRTFile->SaveFile(TV_RRT_DEFINE_PARAM_PATH)) { + LOGD("save error!\n"); + pthread_mutex_unlock(&rrt_update_mutex); + return false; + } + + pthread_mutex_unlock(&rrt_update_mutex); + return true; +} + +CTvRrt *CTvRrt::mInstance; +CTvRrt *CTvRrt::getInstance() +{ + LOGD("start rrt action!\n"); + if (NULL == mInstance) { + mInstance = new CTvRrt(); + } + + return mInstance; +} + +CTvRrt::CTvRrt() +{ + mRrtScanStatus = INVALID_ID; + mDmx_id = INVALID_ID; + mLastRatingRegion = INVALID_ID; + mLastDimensionsDefined = INVALID_ID; + mLastVersion = INVALID_ID; + mScanResult = 0; +} + +CTvRrt::~CTvRrt() +{ + if (mInstance != NULL) { + delete mInstance; + mInstance = NULL; + } +} + +/** + * @Function: StartRrtUpdate + * @Description: Start Update rrt info + * @Param:mode:RRT_AUTO_SEARCH:auto search; RRT_MANU_SEARCH:manual search + * @Return: 0 success, -1 fail + */ +int CTvRrt::StartRrtUpdate(rrt_search_mode_t mode) +{ + int ret; + pthread_mutex_lock(&rrt_search_mutex); + + ret = RrtCreate(0, 2, 0, NULL); //2 is demux id which according to DVB moudle! + if (ret < 0) { + LOGD("RrtCreate failed!\n"); + pthread_mutex_unlock(&rrt_search_mutex); + return 0; + } + + ret = RrtScanStart(); + if (ret < 0) { + LOGD("RrtScanStart failed!\n"); + pthread_mutex_unlock(&rrt_search_mutex); + return 0; + } else { + if (mode == RRT_MANU_SEARCH) {//manual + mRrtScanStatus = RrtEvent::EVENT_RRT_SCAN_SCANING; + sleep(5);//scan 5s + mRrtScanStatus = RrtEvent::EVENT_RRT_SCAN_END; + LOGD("ScanResult = %d!\n", mScanResult); + pthread_mutex_unlock(&rrt_search_mutex); + return mScanResult; + } else {//auto + pthread_mutex_unlock(&rrt_search_mutex); + return 1; + } + } +} + +/** + * @Function: StopRrtUpdate + * @Description: Stop Update rrt info + * @Param: + * @Return: 0 success, -1 fail + */ +int CTvRrt::StopRrtUpdate(void) +{ + int ret = -1; + + ret = RrtScanStop(); + if (ret < 0) { + LOGD("RrtScanStop failed!\n"); + } + + ret = RrtDestroy(); + if (ret < 0) { + LOGE("RrtDestroy failed!\n"); + } + + return ret; +} + +/** + * @Function: GetRRTRating + * @Description: search data for livetv from RRT file + * @Param: rating_region_id: rating region id; + dimension_id: dimension id; + value_id: value id; + ret:search results + * @Return: 0 success, -1 fail + */ +int CTvRrt::GetRRTRating(int rating_region_id, int dimension_id, int value_id, rrt_select_info_t *ret) +{ + int r = -1; + + LOGD("rating_region_id = %d, dimension_id = %d, value_id = %d\n",rating_region_id, dimension_id, value_id); + + //check rrt_define_file exist + struct stat tmp_st; + if (stat(TV_RRT_DEFINE_PARAM_PATH, &tmp_st) != 0) { + LOGD("file don't exist!\n"); + return -1; + } + + TiXmlDocument *pRRTFile = new TiXmlDocument(TV_RRT_DEFINE_PARAM_PATH); + if (!pRRTFile->LoadFile()) { + LOGD("load %s error!\n", TV_RRT_DEFINE_PARAM_PATH); + return -1; + } + + memset(ret, 0, sizeof(rrt_select_info_t)); + TiXmlElement* pTmpElement = pRRTFile->RootElement()->FirstChildElement(); + if (pTmpElement != NULL) { + do { + if ((pTmpElement->FirstAttribute()->Next()->IntValue() ==rating_region_id) && + (pTmpElement->LastAttribute()->IntValue() == dimension_id )) { + LOGD("%s\n",pTmpElement->FirstAttribute()->Next()->Next()->Value()); + int RationSize = strlen(pTmpElement->FirstAttribute()->Next()->Next()->Value()); + ret->rating_region_name_count = RationSize; + const char *rating_region_name = pTmpElement->FirstAttribute()->Next()->Next()->Value(); + memcpy(ret->rating_region_name, rating_region_name, RationSize+1); + LOGD("%s\n",pTmpElement->FirstAttribute()->Value()); + int DimensionSize = strlen(pTmpElement->FirstAttribute()->Value()); + ret->dimensions_name_count = DimensionSize; + memcpy(ret->dimensions_name, pTmpElement->FirstAttribute()->Value(), DimensionSize+1); + + TiXmlElement* pElement = NULL; + for (pElement=pTmpElement->FirstChildElement();pElement;pElement = pElement->NextSiblingElement()) { + if (pElement->LastAttribute()->IntValue() == value_id ) { + int ValueSize = strlen(pElement->FirstAttribute()->Value()); + ret->rating_value_text_count = ValueSize; + LOGD("%s\n",pElement->FirstAttribute()->Value()); + memcpy(ret->rating_value_text, pElement->FirstAttribute()->Value(), ValueSize+1); + r = 0; + goto end; + } + } + } + } while(pTmpElement = pTmpElement->NextSiblingElement()); + LOGD("Don't find value !\n"); + } else { + LOGD("XML file is NULL!\n"); + } + +end: + if (pRRTFile) + delete pRRTFile; + + return r; +} + +/** + * @Function: RrtCreate + * @Description: open dev for RRT and set RRT event + * @Param: fend_id: fend dev id; + dmx_id: demux dev id; + src: source; + textLangs:language; + * @Return: 0 success, -1 fail + */ +int CTvRrt::RrtCreate(int fend_id, int dmx_id, int src, char * textLangs) +{ +#ifdef SUPPORT_ADTV + AM_EPG_CreatePara_t para; + AM_ErrorCode_t ret; + AM_DMX_OpenPara_t dmx_para; + mDmx_id = dmx_id; + + memset(&dmx_para, 0, sizeof(dmx_para)); + LOGD("Opening demux%d ...", dmx_id); + ret = AM_DMX_Open(mDmx_id, &dmx_para); + if (ret != DVB_SUCCESS) { + LOGD("AM_DMX_Open failed"); + return - 1; + } + + para.fend_dev = fend_id; + para.dmx_dev = dmx_id; + para.source = src; + para.hdb = NULL; + snprintf(para.text_langs, sizeof(para.text_langs), "%s", textLangs); + + ret = AM_EPG_Create(¶, &mRrtScanHandle); + + if (ret != DVB_SUCCESS) { + LOGD("AM_EPG_Create failed"); + return - 1; + } + + /*disable internal default table procedure*/ + ret = AM_EPG_DisableDefProc(mRrtScanHandle, true); + if (ret != DVB_SUCCESS) { + LOGD("AM_EPG_DisableDefProc failed"); + return - 1; + } + + /*handle tables directly by user*/ + ret = AM_EPG_SetTablesCallback(mRrtScanHandle, AM_EPG_TAB_RRT, RrtTableCallback, NULL); + if (ret != DVB_SUCCESS) { + LOGD("AM_EPG_SetTablesCallback failed"); + return - 1; + } +#endif + return 0; +} + +/** + * @Function: RrtDestroy + * @Description: close dev for RRT and reset RRT event + * @Param: + * @Return: 0 success, -1 fail + */ +int CTvRrt::RrtDestroy() +{ +#ifdef SUPPORT_ADTV + AM_ErrorCode_t ret; + + if (mRrtScanHandle != NULL) { + ret = AM_EPG_Destroy(mRrtScanHandle); + if (ret != DVB_SUCCESS) { + LOGD("AM_EPG_Destroy failed"); + return - 1; + } + mRrtScanHandle = NULL; + } + + if (mDmx_id != INVALID_ID) { + ret = AM_DMX_Close(mDmx_id); + + if (ret != DVB_SUCCESS) { + LOGD("AM_DMX_Close failed"); + return - 1; + } + mDmx_id = INVALID_ID; + } +#endif + return 0; +} + +/** + * @Function: RrtChangeMode + * @Description: change epg mode + * @Param: op: epg modul; + mode: epg mode; + * @Return: 0 success, -1 fail + */ +int CTvRrt::RrtChangeMode(int op, int mode) +{ +#ifdef SUPPORT_ADTV + AM_ErrorCode_t ret; + + ret = AM_EPG_ChangeMode(mRrtScanHandle, op, mode); + if (ret != DVB_SUCCESS) { + LOGD("AM_EPG_ChangeMode failed"); + return - 1; + } +#endif + return 0; +} + +/** + * @Function: RrtScanStart + * @Description: start scan RRT info + * @Param: + * @Return: 0 success, -1 fail + */ +int CTvRrt::RrtScanStart(void) +{ + int ret = -1; + ret = RrtChangeMode(MODE_ADD, SCAN_RRT); + + return ret; +} + +/** + * @Function: RrtScanStop + * @Description: stop scan RRT info + * @Param: + * @Return: 0 success, -1 fail + */ +int CTvRrt::RrtScanStop(void) +{ + int ret = -1; + ret = RrtChangeMode(MODE_REMOVE, SCAN_RRT); + return ret; +} + +/** + * @Function: RrtTableCallback + * @Description: RRT event callback function + * @Param:void *: dev handle + event_type:RRT event type + param:callback data + user_data: + * @Return: + */ +void CTvRrt::RrtTableCallback(void * handle, int event_type, void *param, void *user_data) +{ +#ifdef SUPPORT_ADTV + if (mInstance == NULL) { + LOGD("rrt mInstance is NULL!\n"); + return; + } + + if (mInstance->mpObserver == NULL) { + LOGD("rrt mpObserver is NULL!\n"); + return; + } + + if (!param) { + LOGD("rrt data is NULL!\n"); + if (mInstance->mRrtScanStatus == RrtEvent::EVENT_RRT_SCAN_SCANING) { + mInstance->mScanResult = 0; + } + + return; + } + + switch (event_type) { + case AM_EPG_TAB_RRT: { + if (mInstance->mRrtScanStatus == RrtEvent::EVENT_RRT_SCAN_SCANING) { + mInstance->mScanResult = 1; + } + + mInstance->mCurRrtEv.satus = CTvRrt::RrtEvent::EVENT_RRT_SCAN_START; + mInstance->mpObserver->onEvent(mInstance->mCurRrtEv); + + mInstance->RrtDataUpdate(handle, event_type, param, user_data); + + mInstance->mCurRrtEv.satus = CTvRrt::RrtEvent::EVENT_RRT_SCAN_END; + mInstance->mpObserver->onEvent(mInstance->mCurRrtEv); + + break; + } + default: + break; + } +#endif +} + +/** + * @Function: RrtDataUpdate + * @Description: RRT data parser + * @Param:dev_no: dev id + event_type:RRT event type + param:callback data + user_data: + * @Return: + */ +void CTvRrt::RrtDataUpdate(void * dev_no, int event_type, void *param, void *user_data) +{ +#ifdef SUPPORT_ADTV + switch (event_type) { + case AM_EPG_TAB_RRT: { + INT8U i, j; + rrt_info_t rrt_info; + memset(&rrt_info, 0, sizeof(rrt_info_t)); + + rrt_section_info_t * pNewRrt = (rrt_section_info_t *)param; + + //open xml file + TiXmlDocument *pRRTFile = OpenXmlFile(); + if (pRRTFile == NULL) { + LOGD("open xml file failed!\n"); + return; + } + + while (pNewRrt != NULL) { + LOGD("T [RRT:0x%02x][rr:0x%04x][dd:0x%04x] v[0x%x]\n", pNewRrt->i_table_id, pNewRrt->rating_region, + pNewRrt->dimensions_defined, pNewRrt->version_number); + + //save rating_region + rrt_info.rating_region = pNewRrt->rating_region; + rrt_info.dimensions_id = 0; + + //parser rating_region_name + MultipleStringParser(pNewRrt->rating_region_name, rrt_info.rating_region_name); + + //parser dimensions_info + rrt_dimensions_info *dimensions_info = pNewRrt->dimensions_info; + + while (dimensions_info != NULL) { + //parser dimensions_name + MultipleStringParser(dimensions_info->dimensions_name, rrt_info.dimensions_name); + LOGD("graduated_scale[%d] values_defined[%d]\n", pNewRrt->dimensions_info->graduated_scale,pNewRrt->dimensions_info->values_defined); + + //paser and save data to xml + for (j=1;j<dimensions_info->values_defined;j++) { + //save rating_id + rrt_info.rating_value_id = j; + MultipleStringParser(dimensions_info->rating_value[j].abbrev_rating_value_text, rrt_info.abbrev_rating_value_text); + MultipleStringParser(dimensions_info->rating_value[j].rating_value_text, rrt_info.rating_value_text); + + bool ret = SaveDataToXml(pRRTFile, rrt_info); + if (!ret) { + LOGD("Save XML element error!\n"); + } + } + //save dimensions_id + rrt_info.dimensions_id ++ ; + + dimensions_info = dimensions_info->p_next; + } + pNewRrt = pNewRrt->p_next; + } + + delete pRRTFile; + break; + } + default: + break; + } +#endif +} + +#if 0 +/** + * @Function: MultipleStringParser + * @Description: Multiple string data parser + * @Param:atsc_multiple_string: Multiple string data + ret: data after parser + * @Return: + */ +void CTvRrt::MultipleStringParser(atsc_multiple_string_t atsc_multiple_string, char *ret) +{ + int i; + for (i=0;i<atsc_multiple_string.i_string_count;i++) { + int size = strlen((char *)atsc_multiple_string.string[0].string); + if (ret != NULL) { + memcpy(ret, atsc_multiple_string.string[0].string, size+1); + } + } + + return; +} +#endif + +/** + * @Function: RrtUpdataCheck + * @Description: Check RRT xml file need update or not + * @Param:atsc_multiple_string: Multiple string data + ret: data after parser + * @Return: + */ + +bool CTvRrt::RrtUpdataCheck(int rating_region, int dimensions_defined, int version_number) +{ + if ((mLastRatingRegion == rating_region) + && (mLastDimensionsDefined == dimensions_defined) + && (mLastVersion == version_number)){ + return true; + } else { + mLastRatingRegion = rating_region; + mLastDimensionsDefined = dimensions_defined; + mLastVersion =version_number; + return false; + } +} diff --git a/tv/tvserver/libtv/tv/CTvRrt.h b/tv/tvserver/libtv/tv/CTvRrt.h new file mode 100644 index 0000000..7c2679e --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvRrt.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ +#include <stdio.h> +#include <string> +#include <sys/stat.h> +#ifdef SUPPORT_ADTV +#include <am_epg.h> +#endif +#include "CTvEv.h" +#include "CTvLog.h" + +#if !defined(_CDTVRRT_H) +#define _CDTVRRT_H + +#define TV_RRT_DEFINE_PARAM_PATH "/param/tv_rrt_define.xml" + +typedef struct rrt_info +{ + unsigned short rating_region; + int dimensions_id; + int rating_value_id; + char rating_region_name[2048]; + char dimensions_name[2048]; + char abbrev_rating_value_text[2048]; + char rating_value_text[2048]; +} rrt_info_t; + +typedef struct rrt_select_info_s +{ + int rating_region_name_count; + char rating_region_name[2048]; + int dimensions_name_count; + char dimensions_name[2048]; + int rating_value_text_count; + char rating_value_text[2048]; +} rrt_select_info_t; + +typedef enum rrt_search_mode_e +{ + RRT_AUTO_SEARCH = 0, + RRT_MANU_SEARCH, +} rrt_search_mode_t; + +class CTvRrt +{ +public: + static const int MODE_ADD = 0; + static const int MODE_REMOVE = 1; + + static const int SCAN_RRT = 0x2000; + static const int INVALID_ID = -1; + + class RrtEvent : public CTvEv { + public: + RrtEvent(): CTvEv(CTvEv::TV_EVENT_RRT) + { + + }; + ~RrtEvent() + { + }; + + static const int EVENT_RRT_SCAN_START = 1; + static const int EVENT_RRT_SCAN_SCANING = 2; + static const int EVENT_RRT_SCAN_END = 3; + + int satus; + }; + + class IObserver { + public: + IObserver() {}; + virtual ~IObserver() {}; + virtual void onEvent(const RrtEvent &ev) = 0; + }; + + int setObserver(IObserver *ob) + { + mpObserver = ob; + return 0; + } + +public: + static CTvRrt *getInstance(); + CTvRrt(); + ~CTvRrt(); + int StartRrtUpdate(rrt_search_mode_t mode); + int StopRrtUpdate(void); + int GetRRTRating(int rating_region_id, int dimension_id, int value_id, rrt_select_info_t *ret); + + int mRrtScanStatus; + int mScanResult; + int mDmx_id ; + int mLastRatingRegion; + int mLastDimensionsDefined; + int mLastVersion; + void * mRrtScanHandle = nullptr; + +private: + int RrtCreate(int fend_id, int dmx_id, int src, char * textLangs); + int RrtDestroy(); + int RrtChangeMode(int op, int mode); + int RrtScanStart(void); + int RrtScanStop(void); + + static void RrtTableCallback(void * dev_no, int event_type, void *param, void *user_data); + void RrtDataUpdate(void * dev_no, int event_type, void *param, void *user_data); + + bool RrtUpdataCheck(int rating_region, int dimensions_defined, int version_number); + static CTvRrt *mInstance; + IObserver *mpObserver; + RrtEvent mCurRrtEv; +}; + + +#endif //_CDTVRRT_H + diff --git a/tv/tvserver/libtv/tv/CTvSatellite.h b/tv/tvserver/libtv/tv/CTvSatellite.h new file mode 100644 index 0000000..db6bb35 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvSatellite.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CTVSATELLITE_H) +#define _CTVSATELLITE_H + + +class CTvSatellite { +}; + +#endif //_CTVSATELLITE_H diff --git a/tv/tvserver/libtv/tv/CTvScanner.cpp b/tv/tvserver/libtv/tv/CTvScanner.cpp new file mode 100644 index 0000000..69ee387 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvScanner.cpp @@ -0,0 +1,2302 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvScanner" + +#include "CTvScanner.h" +#include "CTvChannel.h" +#include "CTvProgram.h" +#include "CTvRegion.h" +#include "CFrontEnd.h" + +#include <tvconfig.h> + +#ifdef SUPPORT_ADTV +#define dvb_fend_para(_p) ((struct dvb_frontend_parameters*)(&_p)) +#define IS_DVBT2_TS(_para) (_para.m_type == TV_FE_OFDM && _para.terrestrial.para.u.ofdm.ofdm_mode == OFDM_DVBT2) +#define IS_ISDBT_TS(_para) (_para.m_type == TV_FE_ISDBT) +#endif + +CTvScanner *CTvScanner::mInstance; +CTvScanner::ScannerEvent CTvScanner::mCurEv; +CTvScanner::service_list_t CTvScanner::service_list_dummy; + +CTvScanner *CTvScanner::getInstance() +{ + if (NULL == mInstance) mInstance = new CTvScanner(); + return mInstance; +} + +CTvScanner::CTvScanner() +{ + mbScanStart = false; + mpObserver = NULL; + mSource = 0xff; + mMinFreq = 1; + mMaxFreq = 100; + mCurScanStartFreq = 1; + mCurScanEndFreq = 100; + mVbi = NULL; +} + +CTvScanner::~CTvScanner() +{ +#ifdef SUPPORT_ADTV + AM_EVT_Unsubscribe((long)mScanHandle, AM_SCAN_EVT_PROGRESS, evtCallback, NULL); + AM_EVT_Unsubscribe((long)mScanHandle, AM_SCAN_EVT_SIGNAL, evtCallback, NULL); +#endif +} + +int CTvScanner::Scan(char *feparas, char *scanparas) { + CFrontEnd::FEParas fe(feparas); + ScanParas sp(scanparas); + return Scan(fe, sp); +} + +int CTvScanner::Scan(CFrontEnd::FEParas &fp, ScanParas &sp) { + #ifdef SUPPORT_ADTV + stopScan(); + + if (mbScanStart) { + LOGW("scan is scanning, need first stop it"); + return -1; + } + + AM_SCAN_CreatePara_t para; + AM_DMX_OpenPara_t dmx_para; + void* handle =nullptr; + int i; + + LOGD("Scan fe[%s] scan[%s]", fp.toString().c_str(), sp.toString().c_str()); + + mFEParas = fp; + mScanParas = sp; + + /*for convenient use*/ + mCurScanStartFreq = sp.getAtvFrequency1(); + mCurScanEndFreq = sp.getAtvFrequency2(); + + //reset scanner status + mCurEv.reset(); + mFEType = -1; + + mAtvIsAtsc = 0; + // Create the scan + memset(¶, 0, sizeof(para)); + para.fend_dev_id = 0;//default + para.mode = sp.getMode(); + para.proc_mode = sp.getProc(); + if (createAtvParas(para.atv_para, fp, sp) != 0) + return -1; + if (createDtvParas(para.dtv_para, fp, sp) != 0) { + freeAtvParas(para.atv_para); + return -1; + } + const char *db_mode = config_get_str ( CFG_SECTION_TV, SYS_SCAN_TO_PRIVATE_DB, "false"); + if (!strcmp(db_mode, "true")) { + para.store_cb = NULL; + } else { + para.store_cb = storeScanHelper; + } + + // Start Scan + memset(&dmx_para, 0, sizeof(dmx_para)); + AM_DMX_Open(para.dtv_para.dmx_dev_id, &dmx_para); + /*get scramble prop value,default value 0 is ca des*/ + int mode = config_get_int(CFG_SECTION_TV, CFG_DTV_CHECK_SCRAMBLE_MODE, 0); + if (mode == 1) { + para.dtv_para.mode |= TV_SCAN_DTVMODE_SCRAMB_TSHEAD; + } + //para.dtv_para.mode |= TV_SCAN_DTVMODE_FTA; + //para.dtv_para.mode |= TV_SCAN_DTVMODE_NOVCT; + // if (TV_FE_ATSC == fp.getFEMode().getBase()) { + // para.store_mode |= AM_SCAN_ATV_STOREMODE_NOPAL; + // para.store_mode |= AM_SCAN_DTV_STOREMODE_NOSECAM; + // LOGD("not srote pal and secam type programs"); + // } + + if (AM_SCAN_Create(¶, &handle) != DVB_SUCCESS) { + LOGD("SCAN CREATE fail"); + handle = NULL; + } else { + AM_SCAN_Helper_t ts_type_helper; + ts_type_helper.id = AM_SCAN_HELPER_ID_FE_TYPE_CHANGE; + ts_type_helper.user = (void*)this; + ts_type_helper.cb = FETypeHelperCBHelper; + AM_SCAN_SetHelper(handle, &ts_type_helper); + mScanHandle = handle; + AM_SCAN_SetUserData(handle, (void *)this); + AM_EVT_Subscribe((long)handle, AM_SCAN_EVT_PROGRESS, evtCallback, NULL); + AM_EVT_Subscribe((long)handle, AM_SCAN_EVT_SIGNAL, evtCallback, NULL); + if (AM_SCAN_Start(handle) != DVB_SUCCESS) { + AM_SCAN_Destroy(handle, false); + AM_EVT_Unsubscribe((long)handle, AM_SCAN_EVT_PROGRESS, evtCallback, NULL); + AM_EVT_Unsubscribe((long)handle, AM_SCAN_EVT_SIGNAL, evtCallback, NULL); + handle = NULL; + } + } + + freeAtvParas(para.atv_para); + freeDtvParas(para.dtv_para); + + if (handle == NULL) { + return -1; + } + mbScanStart = true;//start call ok + #endif + return 0; +} + +int CTvScanner::pauseScan() +{ + LOGD("pauseScan scan started:%d", mbScanStart); + #ifdef SUPPORT_ADTV + if (mbScanStart) { //if start ok and not stop + int ret = AM_SCAN_Pause(mScanHandle); + LOGD("pauseScan , ret=%d", ret); + return ret; + } + #endif + return 0; +} + +int CTvScanner::resumeScan() +{ + LOGD("resumeScan scan started:%d", mbScanStart); + #ifdef SUPPORT_ADTV + if (mbScanStart) { //if start ok and not stop + int ret = AM_SCAN_Resume(mScanHandle); + LOGD("resumeScan , ret=%d", ret); + return ret; + } + #endif + return 0; +} + +int CTvScanner::stopScan() +{ + LOGD("StopScan is started:%d", mbScanStart); + #ifdef SUPPORT_ADTV + if (mbScanStart) { //if start ok and not stop + if (needVbiAssist()) + stopVBI(); + int ret = AM_SCAN_Destroy(mScanHandle, true); + AM_EVT_Unsubscribe((long)mScanHandle, AM_SCAN_EVT_PROGRESS, evtCallback, NULL); + AM_EVT_Unsubscribe((long)mScanHandle, AM_SCAN_EVT_SIGNAL, evtCallback, NULL); + AM_SEC_Cache_Reset(0); + //stop loop + mbScanStart = false;//stop ok + } + #endif + return 0; +} + +int CTvScanner::getScanStatus(int *status) +{ + LOGD("getScanStatus scan started:%d", mbScanStart); + #ifdef SUPPORT_ADTV + if (mbScanStart && status) { //if start ok and not stop + int ret = AM_SCAN_GetStatus(mScanHandle, status); + LOGD("getScanStatus = [%d], ret=%d", *status, ret); + return ret; + } + #endif + return 0; +} + + +int CTvScanner::getParamOption(char *para) { + int forcePara = -1; + char paraForce[64]; + snprintf(paraForce, sizeof(paraForce), "dtv.scan.%s", para); + const char *paraForced = config_get_str ( CFG_SECTION_TV, paraForce, "null"); + if (sscanf(paraForced, "%i", &forcePara)) { + LOGD("option %s: %d", para, forcePara); + } + return forcePara; +} + +int CTvScanner::insertLcnList(lcn_list_t &llist, ScannerLcnInfo *lcn, int idx) +{ + int found = 0; + + for (lcn_list_t::iterator p=llist.begin(); p != llist.end(); p++) { + ScannerLcnInfo *pl = *p; + //LOGD("list size:%d, pl:%#x", llist.size(), pl); + + if ((pl->net_id == lcn->net_id) + && (pl->ts_id == lcn->ts_id) + && (pl->service_id == lcn->service_id)) { + pl->lcn[idx] = lcn->lcn[idx]; + pl->visible[idx] = lcn->visible[idx]; + pl->valid[idx] = lcn->valid[idx]; + found = 1; + } + } + if (!found) { + llist.push_back(lcn); + } + return found ? 1 : 0; //found = insert fail. +} + +void CTvScanner::notifyLcn(ScannerLcnInfo *lcn) +{ + mCurEv.clear(); + mCurEv.mType = ScannerEvent::EVENT_LCN_INFO_DATA; + mCurEv.mLcnInfo = *lcn; + + getInstance()->sendEvent(mCurEv); +} + +void CTvScanner::notifyService(SCAN_ServiceInfo_t *srv) +{ + if (!srv->tsinfo) { + LOGE("service with no tsinfo."); + return; + } + +#ifdef SUPPORT_ADTV + mCurEv.reset(); + mCurEv.mFEParas = srv->tsinfo->fe; + mCurEv.mFrequency = mCurEv.mFEParas.getFrequency(); + + strncpy(mCurEv.mVct, srv->tsinfo->vct, sizeof(mCurEv.mVct)); + + int feType = mCurEv.mFEParas.getFEMode().getBase(); + if (feType != TV_FE_ANALOG) { + mCurEv.mServiceId = srv->srv_id; + mCurEv.mONetId = srv->tsinfo->nid; + mCurEv.mTsId = srv->tsinfo->tsid; + strncpy(mCurEv.mProgramName, srv->name, 1024); + mCurEv.mprogramType = srv->srv_type; + mCurEv.mVid = srv->vid; + mCurEv.mVfmt = srv->vfmt; + mCurEv.mAcnt = srv->aud_info.audio_count; + for (int i = 0; i < srv->aud_info.audio_count; i++) { + mCurEv.mAid[i] = srv->aud_info.audios[i].pid; + mCurEv.mAfmt[i] = srv->aud_info.audios[i].fmt; + strncpy(mCurEv.mAlang[i], srv->aud_info.audios[i].lang, 10); + mCurEv.mAtype[i] = srv->aud_info.audios[i].audio_type; + mCurEv.mAExt[i] = srv->aud_info.audios[i].audio_exten; + } + mCurEv.mPcr = srv->pcr_pid; + + if (srv->tsinfo->dtvstd == TV_SCAN_DTV_STD_ATSC) { + mCurEv.mAccessControlled = srv->access_controlled; + mCurEv.mHidden = srv->hidden; + mCurEv.mHideGuide = srv->hide_guide; + mCurEv.mSourceId = srv->source_id; + mCurEv.mMajorChannelNumber = srv->major_chan_num; + mCurEv.mMinorChannelNumber = srv->minor_chan_num; + mCurEv.mVctType = srv->vct_type; + + mCurEv.mScnt = srv->cap_info.caption_count; + for (int i = 0; i < srv->cap_info.caption_count; i++) { + //all captions parsed from tables are treated as dtv cc. + mCurEv.mStype[i] = TYPE_DTV_CC; //srv->cap_info.captions[i].type ? TYPE_DTV_CC : TYPE_ATV_CC; + mCurEv.mSid[i] = srv->cap_info.captions[i].service_number + + (srv->cap_info.captions[i].type ? (AM_CC_CAPTION_SERVICE1-1) : (AM_CC_CAPTION_CC1)); + mCurEv.mSstype[i] = srv->cap_info.captions[i].type ? TYPE_DTV_CC : TYPE_ATV_CC; + mCurEv.mSid1[i] = srv->cap_info.captions[i].pid_or_line21; + mCurEv.mSid2[i] = srv->cap_info.captions[i].flags; + strncpy(mCurEv.mSlang[i], srv->cap_info.captions[i].lang, 10); + } + + } else { + mCurEv.mScnt = srv->sub_info.subtitle_count; + for (int i = 0; i < srv->sub_info.subtitle_count; i++) { + mCurEv.mStype[i] = TYPE_DVB_SUBTITLE; + mCurEv.mSid[i] = srv->sub_info.subtitles[i].pid; + mCurEv.mSstype[i] = srv->sub_info.subtitles[i].type; + mCurEv.mSid1[i] = srv->sub_info.subtitles[i].comp_page_id; + mCurEv.mSid2[i] = srv->sub_info.subtitles[i].anci_page_id; + strncpy(mCurEv.mSlang[i], srv->sub_info.subtitles[i].lang, 10); + } + int scnt = mCurEv.mScnt; + for (int i = 0; i < srv->ttx_info.teletext_count; i++) { + if (srv->ttx_info.teletexts[i].type == 0x2 || + srv->ttx_info.teletexts[i].type == 0x5) { + if (scnt >= (int)(sizeof(mCurEv.mStype) / sizeof(int))) + break; + mCurEv.mStype[scnt] = TYPE_DTV_TELETEXT; + mCurEv.mSid[scnt] = srv->ttx_info.teletexts[i].pid; + mCurEv.mSstype[scnt] = srv->ttx_info.teletexts[i].type; + mCurEv.mSid1[scnt] = srv->ttx_info.teletexts[i].magazine_no; + mCurEv.mSid2[scnt] = srv->ttx_info.teletexts[i].page_no; + strncpy(mCurEv.mSlang[scnt], srv->ttx_info.teletexts[i].lang, 10); + scnt++; + } + } + mCurEv.mScnt = scnt; + + mCurEv.mFEParas.setPlp(srv->plp_id); + } + + mCurEv.mFree_ca = srv->free_ca; + mCurEv.mScrambled = srv->scrambled_flag; + mCurEv.mSdtVer = srv->sdt_version; + + mCurEv.mType = ScannerEvent::EVENT_DTV_PROG_DATA; + LOGD("notifyService freq:%d, sid:%d", mCurEv.mFrequency, srv->srv_id); + + } else {//analog + + mCurEv.mVideoStd = mCurEv.mFEParas.getVideoStd(); + mCurEv.mAudioStd = mCurEv.mFEParas.getAudioStd(); + mCurEv.mIsAutoStd = ((mCurEv.mVideoStd & V4L2_COLOR_STD_AUTO) == V4L2_COLOR_STD_AUTO) ? 1 : 0; + + if (mAtvIsAtsc) { + mCurEv.mAccessControlled = srv->access_controlled; + mCurEv.mHidden = srv->hidden; + mCurEv.mHideGuide = srv->hide_guide; + mCurEv.mSourceId = srv->source_id; + mCurEv.mMajorChannelNumber = srv->major_chan_num; + mCurEv.mMinorChannelNumber = srv->minor_chan_num; + + LOGD("add cc info [%d]", srv->cap_info.caption_count); + mCurEv.mScnt = srv->cap_info.caption_count; + for (int i = 0; i < srv->cap_info.caption_count; i++) { + mCurEv.mStype[i] = srv->cap_info.captions[i].type ? TYPE_DTV_CC : TYPE_ATV_CC; + mCurEv.mSid[i] = srv->cap_info.captions[i].service_number; + mCurEv.mSstype[i] = srv->cap_info.captions[i].type; + mCurEv.mSid1[i] = srv->cap_info.captions[i].pid_or_line21; + mCurEv.mSid2[i] = srv->cap_info.captions[i].flags; + strncpy(mCurEv.mSlang[i], srv->cap_info.captions[i].lang, 10); + } + + } + + mCurEv.mType = ScannerEvent::EVENT_ATV_PROG_DATA; + LOGD("notifyService freq:%d, vstd:%x astd:%x", + mCurEv.mFrequency, mCurEv.mFEParas.getVideoStd(), mCurEv.mFEParas.getAudioStd()); + } + + if ((feType == TV_FE_ANALOG) || (mCurEv.mVid != 0x1fff) || mCurEv.mAcnt) + getInstance()->sendEvent(mCurEv); +#endif +} + +void CTvScanner::sendEvent(ScannerEvent &evt) +{ + if (mpObserver) { + strcpy(mCurEv.mParas, "{"); + //fe para + snprintf(mCurEv.mParas, sizeof(mCurEv.mParas), "%s\"fe\":", mCurEv.mParas); + snprintf(mCurEv.mParas, sizeof(mCurEv.mParas), "%s%s", + mCurEv.mParas, mCurEv.mFEParas.toString().c_str()); + //other para + if (mCurEv.mVctType) { + // service para + snprintf(mCurEv.mParas, sizeof(mCurEv.mParas), "%s,\"srv\":{\"vct\":%d}", + mCurEv.mParas, mCurEv.mVctType); + } + snprintf(mCurEv.mParas, sizeof(mCurEv.mParas), "%s}", mCurEv.mParas); + LOGD("Paras:%s", mCurEv.mParas); + + mpObserver->onEvent(evt); + } +} + +#ifdef SUPPORT_ADTV +void CTvScanner::getLcnInfo(AM_SCAN_Result_t *result, AM_SCAN_TS_t *sts, lcn_list_t &llist) +{ + dvbpsi_nit_t *nits = ((sts->type == AM_SCAN_TS_ANALOG) || (result->start_para->dtv_para.standard == TV_SCAN_DTV_STD_ATSC)) ? + NULL : sts->digital.nits; + dvbpsi_nit_ts_t *ts; + dvbpsi_descriptor_t *dr; + dvbpsi_nit_t *nit; + ScannerLcnInfo *plcninfo; + + UNUSED(result); + + AM_SI_LIST_BEGIN(nits, nit) + AM_SI_LIST_BEGIN(nit->p_first_ts, ts) + AM_SI_LIST_BEGIN(ts->p_first_descriptor, dr) + if (dr->p_decoded && (dr->i_tag == AM_SI_DESCR_LCN_83)) { + dvbpsi_logical_channel_number_83_dr_t *lcn_dr = (dvbpsi_logical_channel_number_83_dr_t*)dr->p_decoded; + dvbpsi_logical_channel_number_83_t *lcn = lcn_dr->p_logical_channel_number; + int j; + for (j=0; j<lcn_dr->i_logical_channel_numbers_number; j++) { + plcninfo = (ScannerLcnInfo*)calloc(sizeof(ScannerLcnInfo),1); + plcninfo->net_id = ts->i_orig_network_id; + plcninfo->ts_id = ts->i_ts_id; + plcninfo->service_id = lcn->i_service_id; + plcninfo->lcn[0] = lcn->i_logical_channel_number; + plcninfo->visible[0] = lcn->i_visible_service_flag; + plcninfo->valid[0] = 1; + LOGD("sd lcn for service [%d:%d:%d] ---> l:%d v:%d", + plcninfo->net_id, plcninfo->ts_id, plcninfo->service_id, + plcninfo->lcn[0], plcninfo->visible[0]); + if (insertLcnList(llist, plcninfo, 0)) { + free(plcninfo); + LOGD("lcn exists 0."); + } + lcn++; + } + } else if (dr->p_decoded && dr->i_tag==AM_SI_DESCR_LCN_88) { + dvbpsi_logical_channel_number_88_dr_t *lcn_dr = (dvbpsi_logical_channel_number_88_dr_t*)dr->p_decoded; + dvbpsi_logical_channel_number_88_t *lcn = lcn_dr->p_logical_channel_number; + int j; + for (j=0; j<lcn_dr->i_logical_channel_numbers_number; j++) { + plcninfo = (ScannerLcnInfo*)calloc(sizeof(ScannerLcnInfo), 1); + plcninfo->net_id = ts->i_orig_network_id; + plcninfo->ts_id = ts->i_ts_id; + plcninfo->service_id = lcn->i_service_id; + plcninfo->lcn[1] = lcn->i_logical_channel_number; + plcninfo->visible[1] = lcn->i_visible_service_flag; + plcninfo->valid[1] = 1; + LOGD("hd lcn for service [%d:%d:%d] ---> l:%d v:%d", + plcninfo->net_id, plcninfo->ts_id, plcninfo->service_id, + plcninfo->lcn[1], plcninfo->visible[1]); + if (insertLcnList(llist, plcninfo, 1)) { + free(plcninfo); + LOGD("lcn exists 1."); + } + lcn++; + } + } + AM_SI_LIST_END() + AM_SI_LIST_END() + AM_SI_LIST_END() +} + +void CTvScanner::processTsInfo(AM_SCAN_Result_t *result, AM_SCAN_TS_t *ts, SCAN_TsInfo_t *ts_info) +{ + dvbpsi_nit_t *nit; + dvbpsi_descriptor_t *descr; + + ts_info->nid = -1; + ts_info->tsid = -1; + ts_info->vct[0] = 0; + + if (ts->type == AM_SCAN_TS_ANALOG) { + CFrontEnd::FEMode mode(mFEParas.getFEMode()); + mode.setBase(TV_FE_ANALOG); + ts_info->fe.clear(); + ts_info->fe.setFEMode(mode).setFrequency(ts->analog.freq) + .setVideoStd(CFrontEnd::stdAndColorToVideoEnum(ts->analog.std)) + .setAudioStd(CFrontEnd::stdAndColorToAudioEnum(ts->analog.std)); + } else { + /*tsid*/ + dvbpsi_pat_t *pats = getValidPats(ts); + if (pats != NULL && !ts->digital.use_vct_tsid) { + ts_info->tsid = pats->i_ts_id; + if (ts->digital.sdts) + ts_info->tsid = ts->digital.sdts->i_ts_id; + else if (IS_DVBT2_TS(ts->digital.fend_para) && ts->digital.dvbt2_data_plp_num > 0 && ts->digital.dvbt2_data_plps[0].sdts) + ts_info->tsid = ts->digital.dvbt2_data_plps[0].sdts->i_ts_id; + } else if (ts->digital.vcts != NULL) { + ts_info->tsid = ts->digital.vcts->i_extension; + } + + /*nid*/ + if (result->start_para->dtv_para.standard != TV_SCAN_DTV_STD_ATSC ) { + if (ts->digital.sdts) + ts_info->nid = ts->digital.sdts->i_network_id; + else if (IS_DVBT2_TS(ts->digital.fend_para) && ts->digital.dvbt2_data_plp_num > 0 && ts->digital.dvbt2_data_plps[0].sdts) + ts_info->nid = ts->digital.dvbt2_data_plps[0].sdts->i_network_id; + } + + CFrontEnd::FEMode mode(mFEParas.getFEMode()); + mode.setBase(ts->digital.fend_para.m_type); + ts_info->fe.clear(); + ts_info->fe.fromFENDCTRLParameters(mode, &ts->digital.fend_para); + } + ts_info->dtvstd = result->start_para->dtv_para.standard; + + /* Build VCT string.*/ + if (ts_info->dtvstd == TV_SCAN_DTV_STD_ATSC) { + dvbpsi_atsc_vct_t *vct; + dvbpsi_atsc_vct_channel_t *vcinfo; + char *ptr = ts_info->vct; + int left = sizeof(ts_info->vct) - 1; + int r; + LOGD("vct buffer set start"); + AM_SI_LIST_BEGIN(ts->digital.vcts, vct) + AM_SI_LIST_BEGIN(vct->p_first_channel, vcinfo) + r = snprintf(ptr, left, (ptr == ts_info->vct) ? "%d:%d-%d" : ",%d:%d-%d", vcinfo->i_source_id, vcinfo->i_major_number, vcinfo->i_minor_number); + if (r >= left) { + LOGD("vct buffer is too small"); + } else { + ptr += r; + left -= r; + } + AM_SI_LIST_END() + AM_SI_LIST_END() + LOGD("vct buffer set end [%s]", ts_info->vct); + *ptr = 0; + } +} + +dvbpsi_pat_t *CTvScanner::getValidPats(AM_SCAN_TS_t *ts) +{ + dvbpsi_pat_t *valid_pat = NULL; + if (!IS_DVBT2_TS(ts->digital.fend_para)) { + valid_pat = ts->digital.pats; + } else if (IS_ISDBT_TS(ts->digital.fend_para)) { + /* process for isdbt one-seg inserted PAT, which ts_id is 0xffff */ + valid_pat = ts->digital.pats; + while (valid_pat != NULL && valid_pat->i_ts_id == 0xffff) { + valid_pat = valid_pat->p_next; + } + + if (valid_pat == NULL && ts->digital.pats != NULL) { + valid_pat = ts->digital.pats; + + if (ts->digital.sdts != NULL) + valid_pat->i_ts_id = ts->digital.sdts->i_ts_id; + } + } else { + for (int plp = 0; plp < ts->digital.dvbt2_data_plp_num; plp++) { + if (ts->digital.dvbt2_data_plps[plp].pats != NULL) { + valid_pat = ts->digital.dvbt2_data_plps[plp].pats; + break; + } + } + } + + return valid_pat; +} + +int CTvScanner::getPmtPid(dvbpsi_pat_t *pats, int program_number) +{ + dvbpsi_pat_t *pat; + dvbpsi_pat_program_t *prog; + + AM_SI_LIST_BEGIN(pats, pat) + AM_SI_LIST_BEGIN(pat->p_first_program, prog) + if (prog->i_number == program_number) + return prog->i_pid; + AM_SI_LIST_END() + AM_SI_LIST_END() + + return 0x1fff; +} + +void CTvScanner::extractCaScrambledFlag(dvbpsi_descriptor_t *p_first_descriptor, int *flag) +{ + dvbpsi_descriptor_t *descr; + + AM_SI_LIST_BEGIN(p_first_descriptor, descr) + if (descr->i_tag == AM_SI_DESCR_CA && ! *flag) { + LOGD( "Found CA descr, set scrambled flag to 1"); + *flag = 1; + break; + } + AM_SI_LIST_END() +} + +void CTvScanner::extractSrvInfoFromSdt(AM_SCAN_Result_t *result, dvbpsi_sdt_t *sdts, SCAN_ServiceInfo_t *srv_info) +{ + dvbpsi_sdt_service_t *srv; + dvbpsi_sdt_t *sdt; + dvbpsi_descriptor_t *descr; + const uint8_t split = 0x80; + const int name_size = (int)sizeof(srv_info->name); + int curr_name_len = 0, tmp_len; + char name[AM_DB_MAX_SRV_NAME_LEN + 1]; + + UNUSED(result); + +#define COPY_NAME(_s, _slen)\ + AM_MACRO_BEGIN\ + int copy_len = ((curr_name_len+_slen)>=name_size) ? (name_size-curr_name_len) : _slen;\ + if (copy_len > 0) {\ + memcpy(srv_info->name+curr_name_len, _s, copy_len);\ + curr_name_len += copy_len;\ + }\ + AM_MACRO_END + + + AM_SI_LIST_BEGIN(sdts, sdt) + AM_SI_LIST_BEGIN(sdt->p_first_service, srv) + + if (srv->i_service_id == srv_info->srv_id) { + LOGD("SDT for service %d found!", srv_info->srv_id); + srv_info->eit_sche = (uint8_t)srv->b_eit_schedule; + srv_info->eit_pf = (uint8_t)srv->b_eit_present; + srv_info->rs = srv->i_running_status; + srv_info->free_ca = (uint8_t)srv->b_free_ca; + srv_info->sdt_version = sdt->i_version; + + AM_SI_LIST_BEGIN(srv->p_first_descriptor, descr) + if (descr->p_decoded && descr->i_tag == AM_SI_DESCR_SERVICE) { + dvbpsi_service_dr_t *psd = (dvbpsi_service_dr_t *)descr->p_decoded; + if (psd->i_service_name_length > 0) { + name[0] = 0; + AM_SI_ConvertDVBTextCode((char *)psd->i_service_name, psd->i_service_name_length, \ + name, AM_DB_MAX_SRV_NAME_LEN); + name[AM_DB_MAX_SRV_NAME_LEN] = 0; + LOGD("found name [%s]", name); + + /*3bytes language code, using xxx to simulate*/ + COPY_NAME("xxx", 3); + /*following by name text*/ + tmp_len = strlen(name); + COPY_NAME(name, tmp_len); + } + + srv_info->srv_type = psd->i_service_type; + /*service type 0x16 and 0x19 is user defined, as digital television service*/ + /*service type 0xc0 is type of partial reception service in ISDBT*/ + if ((srv_info->srv_type == 0x16) || (srv_info->srv_type == 0x19) || (srv_info->srv_type == 0xc0)) { + srv_info->srv_type = 0x1; + } + break; + } + AM_SI_LIST_END() + + /* store multilingual service name */ + AM_SI_LIST_BEGIN(srv->p_first_descriptor, descr) + if (descr->p_decoded && descr->i_tag == AM_SI_DESCR_MULTI_SERVICE_NAME) { + int i; + dvbpsi_multi_service_name_dr_t *pmsnd = (dvbpsi_multi_service_name_dr_t *)descr->p_decoded; + + for (i = 0; i < pmsnd->i_name_count; i++) { + name[0] = 0; + AM_SI_ConvertDVBTextCode((char *)pmsnd->p_service_name[i].i_service_name, + pmsnd->p_service_name[i].i_service_name_length, + name, AM_DB_MAX_SRV_NAME_LEN); + name[AM_DB_MAX_SRV_NAME_LEN] = 0; + LOGD("found name [%s]", name); + + if (curr_name_len > 0) { + /*extra split mark*/ + COPY_NAME(&split, 1); + } + /*3bytes language code*/ + COPY_NAME(pmsnd->p_service_name[i].i_iso_639_code, 3); + /*following by name text*/ + tmp_len = strlen(name); + COPY_NAME(name, tmp_len); + } + } + AM_SI_LIST_END() + + /* set the ending null byte */ + if (curr_name_len >= name_size) + srv_info->name[name_size - 1] = 0; + else + srv_info->name[curr_name_len] = 0; + + break; + } + AM_SI_LIST_END() + AM_SI_LIST_END() +} + +void CTvScanner::extractSrvInfoFromVc(AM_SCAN_Result_t *result, dvbpsi_atsc_vct_channel_t *vcinfo, SCAN_ServiceInfo_t *srv_info) +{ + char name[22] = {0}; + + UNUSED(result); + + srv_info->major_chan_num = vcinfo->i_major_number; + srv_info->minor_chan_num = vcinfo->i_minor_number; + + srv_info->chan_num = (vcinfo->i_major_number<<16) | (vcinfo->i_minor_number&0xffff); + srv_info->hidden = vcinfo->b_hidden; + srv_info->hide_guide = vcinfo->b_hide_guide; + srv_info->source_id = vcinfo->i_source_id; + memcpy(srv_info->name, "xxx", 3); + + char const *coding = "utf-16"; + if (AM_SI_ConvertToUTF8((char*)vcinfo->i_short_name, 14, name, 22, (char*)coding) != DVB_SUCCESS) + strcpy(name, "No Name"); + memcpy(srv_info->name+3, name, sizeof(name)); + srv_info->name[sizeof(name)+3] = 0; + srv_info->srv_type = vcinfo->i_service_type; + + LOGD("Program(%d)('%s':%d-%d) in current TSID(%d) found!", + srv_info->srv_id, srv_info->name, + srv_info->major_chan_num, srv_info->minor_chan_num, + vcinfo->i_channel_tsid); +} + +void CTvScanner::updateServiceInfo(AM_SCAN_Result_t *result, SCAN_ServiceInfo_t *srv_info) +{ +#define str(i) (char*)(strings + i) + + static char strings[14][256]; + + if (srv_info->src != TV_FE_ANALOG) { + int standard = result->start_para->dtv_para.standard; + int mode = result->start_para->dtv_para.mode; + + /* Transform service types for different dtv standards */ + if (standard != TV_SCAN_DTV_STD_ATSC) { + if (srv_info->srv_type == 0x1) + srv_info->srv_type = AM_SCAN_SRV_DTV; + else if (srv_info->srv_type == 0x2) + srv_info->srv_type = AM_SCAN_SRV_DRADIO; + } else { + if (srv_info->srv_type == 0x2) + srv_info->srv_type = AM_SCAN_SRV_DTV; + else if (srv_info->srv_type == 0x3) + srv_info->srv_type = AM_SCAN_SRV_DRADIO; + } + + /* if video valid, set this program to tv type, + * if audio valid, but video not found, set it to radio type, + * if both invalid, but service_type found in SDT/VCT, set to unknown service, + * this mechanism is OPTIONAL + */ + if (srv_info->vid < 0x1fff) { + srv_info->srv_type = AM_SCAN_SRV_DTV; + } else if (srv_info->aud_info.audio_count > 0) { + srv_info->srv_type = AM_SCAN_SRV_DRADIO; + } else if (srv_info->srv_type == AM_SCAN_SRV_DTV || + srv_info->srv_type == AM_SCAN_SRV_DRADIO) { + srv_info->srv_type = AM_SCAN_SRV_UNKNOWN; + } + /* Skip program for FTA mode */ + if (srv_info->scrambled_flag && (mode & TV_SCAN_DTVMODE_FTA)) { + LOGD( "Skip program '%s' vid:[%d]for FTA mode", srv_info->name, srv_info->vid); + return; + } + + /* Skip program for service_type mode */ + if (srv_info->srv_type == AM_SCAN_SRV_DTV && (mode & TV_SCAN_DTVMODE_NOTV)) { + LOGD( "Skip program '%s' for NO-TV mode", srv_info->name); + return; + } + if (srv_info->srv_type == AM_SCAN_SRV_DRADIO && (mode & TV_SCAN_DTVMODE_NORADIO)) { + LOGD( "Skip program '%s' for NO-RADIO mode", srv_info->name); + return; + } + + /* Set default name to tv/radio program if no name specified */ + if (!strcmp(srv_info->name, "") && + (srv_info->srv_type == AM_SCAN_SRV_DTV || + srv_info->srv_type == AM_SCAN_SRV_DRADIO)) { + strcpy(srv_info->name, "xxxNo Name"); + } + } +} + +void CTvScanner::addFixedATSCCaption(AM_SI_CaptionInfo_t *cap_info, int service, int cc, int text, int is_digital_cc) +{ + #define DEFAULT_SERVICE_MAX 6 + #define DEFAULT_CC_MAX 4 + #define DEFAULT_TEXT_MAX 4 + + if (service) { + /*service1 ~ service6*/ + int start = cap_info->caption_count; + int cnt = (service == -1 || service > DEFAULT_SERVICE_MAX)? DEFAULT_SERVICE_MAX : service; + for (int i = 0; i < cnt; i++) { + cap_info->captions[start+i].type = 1; + cap_info->captions[start+i].service_number = AM_CC_CAPTION_SERVICE1 + i; + sprintf(cap_info->captions[start+i].lang, "CS%d", i+1); + } + cap_info->caption_count += cnt; + } + + if (cc) { + /*cc1 ~ cc4*/ + int start = cap_info->caption_count; + int cnt = (cc == -1 || cc > DEFAULT_CC_MAX)? DEFAULT_CC_MAX : cc; + for (int i = 0; i < cnt; i++) { + cap_info->captions[start+i].type = is_digital_cc; + cap_info->captions[start+i].service_number = AM_CC_CAPTION_CC1 + i; + sprintf(cap_info->captions[start+i].lang, "CC%d", i+1); + } + cap_info->caption_count += cnt; + } + + if (text) { + /*text1 ~ text4*/ + int start = cap_info->caption_count; + int cnt = (text == -1 || text > DEFAULT_TEXT_MAX)? DEFAULT_TEXT_MAX : text; + for (int i = 0; i < cnt; i++) { + cap_info->captions[start+i].type = is_digital_cc; + cap_info->captions[start+i].service_number = AM_CC_CAPTION_TEXT1 + i; + sprintf(cap_info->captions[start+i].lang, "TX%d", i+1); + } + cap_info->caption_count += cnt; + } +} + +void CTvScanner::processDvbTs(AM_SCAN_Result_t *result, AM_SCAN_TS_t *ts, service_list_t &slist) +{ + LOGD("processDvbTs"); + + dvbpsi_pmt_t *pmt; + dvbpsi_pmt_es_t *es; + int src = result->start_para->dtv_para.source; + dvbpsi_pat_t *valid_pat = NULL; + uint8_t plp_id; + SCAN_ServiceInfo_t *psrv_info; + + valid_pat = getValidPats(ts); + if (valid_pat == NULL) { + LOGD("No PAT found in ts"); + return; + } + + LOGD(" TS: src %d", src); + + if (ts->digital.pmts || (IS_DVBT2_TS(ts->digital.fend_para) && ts->digital.dvbt2_data_plp_num > 0)) { + int loop_count, lc; + dvbpsi_sdt_t *sdt_list; + dvbpsi_pmt_t *pmt_list; + dvbpsi_pat_t *pat_list; + + /* For DVB-T2, search for each PLP, else search in current TS*/ + loop_count = IS_DVBT2_TS(ts->digital.fend_para) ? ts->digital.dvbt2_data_plp_num : 1; + LOGD("plp num %d", loop_count); + + for (lc = 0; lc < loop_count; lc++) { + pat_list = IS_DVBT2_TS(ts->digital.fend_para) ? ts->digital.dvbt2_data_plps[lc].pats : ts->digital.pats; + pmt_list = IS_DVBT2_TS(ts->digital.fend_para) ? ts->digital.dvbt2_data_plps[lc].pmts : ts->digital.pmts; + sdt_list = IS_DVBT2_TS(ts->digital.fend_para) ? ts->digital.dvbt2_data_plps[lc].sdts : ts->digital.sdts; + plp_id = IS_DVBT2_TS(ts->digital.fend_para) ? ts->digital.dvbt2_data_plps[lc].id : -1; + LOGD("plp_id %d", plp_id); + + AM_SI_LIST_BEGIN(pmt_list, pmt) { + if (!(psrv_info = getServiceInfo())) + return; + psrv_info->srv_id = pmt->i_program_number; + psrv_info->src = src; + psrv_info->pmt_pid = getPmtPid(pat_list, pmt->i_program_number); + psrv_info->pcr_pid = pmt->i_pcr_pid; + psrv_info->plp_id = plp_id; + + /* looking for CA descr */ + if (! psrv_info->scrambled_flag) { + extractCaScrambledFlag(pmt->p_first_descriptor, &psrv_info->scrambled_flag); + } + + AM_SI_LIST_BEGIN(pmt->p_first_es, es) { + AM_SI_ExtractAVFromES(es, &psrv_info->vid, &psrv_info->vfmt, &psrv_info->aud_info); + AM_SI_ExtractDVBSubtitleFromES(es, &psrv_info->sub_info); + AM_SI_ExtractDVBTeletextFromES(es, &psrv_info->ttx_info); + AM_SI_ExtractATSCCaptionFromES(es, &psrv_info->cap_info); + if (! psrv_info->scrambled_flag) + extractCaScrambledFlag(es->p_first_descriptor, &psrv_info->scrambled_flag); + } AM_SI_LIST_END() + + extractSrvInfoFromSdt(result, sdt_list, psrv_info); + + /*Store this service*/ + updateServiceInfo(result, psrv_info); + + slist.push_back(psrv_info); + } AM_SI_LIST_END() + + /* All programs in PMTs added, now trying the programs in SDT but NOT in PMT */ + dvbpsi_sdt_service_t *srv; + dvbpsi_sdt_t *sdt; + + AM_SI_LIST_BEGIN(sdt_list, sdt) { + AM_SI_LIST_BEGIN(sdt->p_first_service, srv) { + bool found_in_pmt = false; + + /* Is already added in PMT? */ + AM_SI_LIST_BEGIN(pmt_list, pmt){ + if (srv->i_service_id == pmt->i_program_number) { + found_in_pmt = true; + break; + } + }AM_SI_LIST_END() + + if (found_in_pmt) + continue; + + if (!(psrv_info = getServiceInfo())) + return; + psrv_info->srv_id = srv->i_service_id; + psrv_info->src = src; + + extractSrvInfoFromSdt(result, sdt_list, psrv_info); + + updateServiceInfo(result, psrv_info); + + /*as no pmt for this srv, set type to data for invisible*/ + psrv_info->srv_type = 0; + + slist.push_back(psrv_info); + } + AM_SI_LIST_END() + } + AM_SI_LIST_END() + } + } +} + +void CTvScanner::processAnalogTs(AM_SCAN_Result_t *result, AM_SCAN_TS_t *ts, SCAN_TsInfo_t *tsinfo, service_list_t &slist) +{ + LOGD("processAnalogTs"); + + SCAN_ServiceInfo_t *psrv_info; + + UNUSED(ts); + + if (!(psrv_info=getServiceInfo())) + return; + + LOGD(" TS: src analog"); + + psrv_info->tsinfo = tsinfo; + + /*if atsc, generate the analog channel's channel number*/ + if (mAtvIsAtsc) { + + int tsid = -1; + int found = 0; + + LOGD("collecting info for %d", tsinfo->fe.getFrequency()); + + /*try get channel number from vct*/ + for (tsid_list_t::iterator p=tsid_list.begin(); p != tsid_list.end(); p++) { + if ((*p)->freq == tsinfo->fe.getFrequency()) + tsid = (*p)->tsid; + } + if (tsid != -1) { + dvbpsi_atsc_vct_t *vct; + dvbpsi_atsc_vct_channel_t *vcinfo; + + AM_SI_LIST_BEGIN(ts->digital.vcts, vct){ + AM_SI_LIST_BEGIN(vct->p_first_channel, vcinfo){ + if (vcinfo->i_channel_tsid == tsid) { + LOGD("found channel info in vct."); + extractSrvInfoFromVc(result, vcinfo, psrv_info); + found = 1; + } + } AM_SI_LIST_END() + } AM_SI_LIST_END() + } + + LOGD("tsid:%d, found:%d", tsid, found); + /*generate by channel id*/ + if (tsid == -1 || found == 0) { + int mode = mScanParas.getAtvModifier(CFrontEnd::FEParas::FEP_MODE, -1); + if (mode == -1) + mode = mFEParas.getFEMode().getMode(); + const char *list_name = getDtvScanListName(mode); + Vector<sp<CTvChannel>> vcp; + CTvRegion::getChannelListByName(const_cast<char*>(list_name), vcp); + for (int i = 0; i < (int)vcp.size(); i++) { + int diff = abs(vcp[i]->getFrequency() - tsinfo->fe.getFrequency()); + if (diff >= 0 && diff <= 2000000) { // 2M tolerance + psrv_info->major_chan_num = vcp[i]->getLogicalChannelNum(); + psrv_info->minor_chan_num = 0; + psrv_info->chan_num = (psrv_info->major_chan_num<<16) | (psrv_info->minor_chan_num&0xffff); + psrv_info->hidden = 0; + psrv_info->hide_guide = 0; + psrv_info->source_id = -1; + char name[] = "ATV Program"; + memcpy(psrv_info->name, "xxx", 3); + memcpy(psrv_info->name+3, name, sizeof(name)); + psrv_info->name[sizeof(name)+3] = 0; + psrv_info->srv_type = AM_SCAN_SRV_ATV; + + LOGD("get channel info by channel id [%d.%d][%s]", + psrv_info->major_chan_num, psrv_info->minor_chan_num, + psrv_info->name); + found = 1; + break; + } + } + if (found == 0) { // do not match channel table, major channel number start from table max number + 1 + if (slist.size() <= 0 || slist.back()->major_chan_num <= vcp.size() + 1) + psrv_info->major_chan_num = vcp.size() + 2; + else + psrv_info->major_chan_num = slist.back()->major_chan_num + 1; + + psrv_info->minor_chan_num = 0; + psrv_info->chan_num = (psrv_info->major_chan_num<<16) | (psrv_info->minor_chan_num&0xffff); + psrv_info->hidden = 0; + psrv_info->hide_guide = 0; + psrv_info->source_id = -1; + char name[] = "ATV Program"; + memcpy(psrv_info->name, "xxx", 3); + memcpy(psrv_info->name+3, name, sizeof(name)); + psrv_info->name[sizeof(name)+3] = 0; + psrv_info->srv_type = AM_SCAN_SRV_ATV; + LOGD("ntsc channel[%d] doesn't match table[%s], set channel id to [%d.%d][%s]", + tsinfo->fe.getFrequency(), list_name, + psrv_info->major_chan_num, psrv_info->minor_chan_num, + psrv_info->name); + } + } + } + + { + int cc_fixed = getParamOption("cc.fixed"); + bool is_cc_fixed = (cc_fixed == -1)? false : (cc_fixed != 0); + + if (is_cc_fixed) { + memset(&psrv_info->cap_info, 0, sizeof(psrv_info->cap_info)); + addFixedATSCCaption(&psrv_info->cap_info, 0, -1, -1, 0); + } + } + slist.push_back(psrv_info); +} + +void CTvScanner::processAtscTs(AM_SCAN_Result_t *result, AM_SCAN_TS_t *ts, SCAN_TsInfo_t *tsinfo, service_list_t &slist) +{ + LOGD("processAtscTs"); + #define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff) + if(ts->digital.vcts + && (ts->digital.vcts->i_extension != ts->digital.pats->i_ts_id) + && (ts->digital.pats->i_ts_id == 0)) + ts->digital.use_vct_tsid = 1; + + dvbpsi_atsc_vct_t *vct; + dvbpsi_atsc_vct_channel_t *vcinfo; + dvbpsi_pmt_t *pmt; + dvbpsi_pmt_es_t *es; + int mode = result->start_para->dtv_para.mode; + int src = result->start_para->dtv_para.source; + bool stream_found_in_vct = false; + bool program_found_in_vct = false; + SCAN_ServiceInfo_t *psrv_info; + int cc_fixed = getParamOption("cc.fixed"); + bool is_cc_fixed = (cc_fixed == -1)? false : (cc_fixed != 0); + bool mNeedCheck_tsid = true; + /*if do store the programs in VCT but NOT in PMT,we need set store_cvt_mode true*/ + bool store_vct_notin_pmt = false;/*!!!!for CVTE, need set false*/ + if (!ts->digital.pats && !ts->digital.vcts) + { + LOGD("No PAT or VCT found in ts"); + return; + } + + AM_SI_LIST_BEGIN(ts->digital.pmts, pmt) { + if (!(psrv_info = getServiceInfo())) + return; + psrv_info->srv_id = pmt->i_program_number; + psrv_info->src = src; + psrv_info->pmt_pid = getPmtPid(ts->digital.pats, pmt->i_program_number); + psrv_info->pcr_pid = pmt->i_pcr_pid; + /* looking for CA descr */ + if (! psrv_info->scrambled_flag) { + if (mode & TV_SCAN_DTVMODE_SCRAMB_TSHEAD) { + psrv_info->scrambled_flag = pmt->i_scramble_flag; + } else { + extractCaScrambledFlag(pmt->p_first_descriptor, &psrv_info->scrambled_flag); + } + } + AM_SI_LIST_BEGIN(pmt->p_first_es, es) { + AM_SI_ExtractAVFromES(es, &psrv_info->vid, &psrv_info->vfmt, &psrv_info->aud_info); + if (!is_cc_fixed) + AM_SI_ExtractATSCCaptionFromES(es, &psrv_info->cap_info); + if (! psrv_info->scrambled_flag && !(mode & TV_SCAN_DTVMODE_SCRAMB_TSHEAD)) + extractCaScrambledFlag(es->p_first_descriptor, &psrv_info->scrambled_flag); + }AM_SI_LIST_END() + /* Skip program for FTA mode */ + if (psrv_info->scrambled_flag && (mode & TV_SCAN_DTVMODE_FTA)) { + LOGD( "Skip program '%s' vid:[%d]for FTA mode", psrv_info->name, psrv_info->vid); + continue; + } + program_found_in_vct = false; + mNeedCheck_tsid = true; + VCT_REPEAT: + AM_SI_LIST_BEGIN(ts->digital.vcts, vct) { + AM_SI_LIST_BEGIN(vct->p_first_channel, vcinfo) { + /*Skip inactive program*/ + if (vcinfo->i_program_number == 0 || vcinfo->i_program_number == 0xffff) + continue; + + if ((ts->digital.use_vct_tsid || (vct->i_extension == ts->digital.pats->i_ts_id) || mNeedCheck_tsid == false) + && vcinfo->i_channel_tsid == vct->i_extension) { + if (vcinfo->i_program_number == pmt->i_program_number) { + if (mNeedCheck_tsid == true) { + if (vct->b_cable_vct) + psrv_info->vct_type = 1; + + int vpid = 0; + int vfmt = 0; + AM_SI_ExtractAVFromVC(vcinfo, &vpid, &vfmt, &psrv_info->aud_info); + if (!VALID_PID(psrv_info->vid)) { + psrv_info->vid = vpid; + psrv_info->vfmt = vfmt; + } + } + extractSrvInfoFromVc(result, vcinfo, psrv_info); + program_found_in_vct = true; + goto VCT_END; + } + } else { + LOGD("Program(%d ts:%d) in VCT(ts:%d) found, current (ts:%d)", + vcinfo->i_program_number, vcinfo->i_channel_tsid, + vct->i_extension, ts->digital.pats->i_ts_id); + continue; + } + } AM_SI_LIST_END() + } AM_SI_LIST_END() + /*if not find in vct on check tsid mode,we need repeat check on not check tsid*/ + if (program_found_in_vct == false && mNeedCheck_tsid == true) { + mNeedCheck_tsid = false; + goto VCT_REPEAT; + } +VCT_END: + /*Store this service*/ + updateServiceInfo(result, psrv_info); + if (is_cc_fixed) { + memset(&psrv_info->cap_info, 0, sizeof(psrv_info->cap_info)); + addFixedATSCCaption(&psrv_info->cap_info, -1, -1, -1, 1); + } + + if (!program_found_in_vct) { + const char *list_name = getDtvScanListName(mFEParas.getFEMode().getMode()); + Vector<sp<CTvChannel>> vcp; + CTvRegion::getChannelListByName((char *)list_name, vcp); + for (int i = 0; i < (int)vcp.size(); i++) { + if ((tsinfo->fe.getFrequency()/1000) == (vcp[i]->getFrequency()/1000)) { + psrv_info->major_chan_num = vcp[i]->getLogicalChannelNum(); + psrv_info->minor_chan_num = psrv_info->srv_id; + } + } + } + + slist.push_back(psrv_info); + + } AM_SI_LIST_END() + + /* All programs in PMTs added, now trying the programs in VCT but NOT in PMT */ + if (store_vct_notin_pmt == true) { + AM_SI_LIST_BEGIN(ts->digital.vcts, vct) { + AM_SI_LIST_BEGIN(vct->p_first_channel, vcinfo) { + bool found_in_pmt = false; + + if (!(psrv_info = getServiceInfo())) + return; + psrv_info->srv_id = vcinfo->i_program_number; + psrv_info->src = src; + + /*Skip inactive program*/ + if (vcinfo->i_program_number == 0 || vcinfo->i_program_number == 0xffff) + continue; + + /* Is already added in PMT? */ + AM_SI_LIST_BEGIN(ts->digital.pmts, pmt) { + if (vcinfo->i_program_number == pmt->i_program_number) { + found_in_pmt = true; + break; + } + } AM_SI_LIST_END() + + if (found_in_pmt) + continue; + + if (vcinfo->i_channel_tsid == vct->i_extension) { + AM_SI_ExtractAVFromVC(vcinfo, &psrv_info->vid, &psrv_info->vfmt, &psrv_info->aud_info); + extractSrvInfoFromVc(result, vcinfo, psrv_info); + updateServiceInfo(result, psrv_info); + + if (is_cc_fixed) { + memset(&psrv_info->cap_info, 0, sizeof(psrv_info->cap_info)); + addFixedATSCCaption(&psrv_info->cap_info, -1, -1, -1, 1); + } + + slist.push_back(psrv_info); + + } else { + LOGD("Program(%d ts:%d) in VCT(ts:%d) found", + vcinfo->i_program_number, vcinfo->i_channel_tsid, + vct->i_extension); + continue; + } + } AM_SI_LIST_END() + } AM_SI_LIST_END() + } +} + +void CTvScanner::storeScanHelper(AM_SCAN_Result_t *result) +{ + if (mInstance) + mInstance->storeScan(result, NULL); + else + LOGE("no Scanner running, ignore"); +} + +void CTvScanner::storeScan(AM_SCAN_Result_t *result, AM_SCAN_TS_t *curr_ts) +{ + AM_SCAN_TS_t *ts; + service_list_t service_list; + ts_list_t ts_list; + + LOGD("Storing tses ..."); + + UNUSED(curr_ts); + + service_list_t slist; + AM_SI_LIST_BEGIN(result->tses, ts) { + if (ts->type == AM_SCAN_TS_DIGITAL) { + SCAN_TsInfo_t *tsinfo = (SCAN_TsInfo_t*)calloc(sizeof(SCAN_TsInfo_t), 1); + if (!tsinfo) { + LOGE("No Memory for Scanner."); + return; + } + processTsInfo(result, ts, tsinfo); + ts_list.push_back(tsinfo); + + if (result->start_para->dtv_para.standard == TV_SCAN_DTV_STD_ATSC) + processAtscTs(result, ts, tsinfo, slist); + else + processDvbTs(result, ts, slist); + for (service_list_t::iterator p=slist.begin(); p != slist.end(); p++) { + (*p)->tsinfo = tsinfo; + } + service_list.merge(slist); + slist.clear(); + } + } + AM_SI_LIST_END() + + AM_SI_LIST_BEGIN(result->tses, ts) { + if (ts->type == AM_SCAN_TS_ANALOG) { + int mode = result->start_para->store_mode; + //not store pal type program + if (((ts->analog.std & V4L2_COLOR_STD_PAL) == V4L2_COLOR_STD_PAL) && + (mode & AM_SCAN_ATV_STOREMODE_NOPAL) == AM_SCAN_ATV_STOREMODE_NOPAL) + { + LOGE("skip pal type program"); + continue; + } + //not store secam type program + if (((ts->analog.std & V4L2_COLOR_STD_SECAM) == V4L2_COLOR_STD_SECAM) && + (mode & AM_SCAN_DTV_STOREMODE_NOSECAM) == AM_SCAN_DTV_STOREMODE_NOSECAM) + { + LOGE("skip secam type program"); + continue; + } + SCAN_TsInfo_t *tsinfo = (SCAN_TsInfo_t*)calloc(sizeof(SCAN_TsInfo_t), 1); + if (!tsinfo) { + LOGE("No memory for Scanner"); + return; + } + processTsInfo(result, ts, tsinfo); + ts_list.push_back(tsinfo); + + processAnalogTs(result, ts, tsinfo, service_list); + } + } + AM_SI_LIST_END() + for (tsid_list_t::iterator p=tsid_list.begin(); p != tsid_list.end(); p++) + free(*p); + tsid_list.clear(); + + if (result->start_para->dtv_para.sort_method == AM_SCAN_SORT_BY_LCN) { + lcn_list_t lcn_list; + AM_SI_LIST_BEGIN(result->tses, ts) { + lcn_list_t llist; + getLcnInfo(result, ts, llist); + lcn_list.merge(llist); + llist.clear(); + } + AM_SI_LIST_END() + + /*notify lcn info*/ + LOGD("notify lcn info."); + for (lcn_list_t::iterator p=lcn_list.begin(); p != lcn_list.end(); p++) + notifyLcn(*p); + + /*free lcn list*/ + for (lcn_list_t::iterator p=lcn_list.begin(); p != lcn_list.end(); p++) + free(*p); + lcn_list.clear(); + } + + /*notify services info*/ + LOGD("notify service info."); + for (service_list_t::iterator p=service_list.begin(); p != service_list.end(); p++) + notifyService(*p); + + /*free services in list*/ + for (service_list_t::iterator p=service_list.begin(); p != service_list.end(); p++) + free(*p); + service_list.clear(); + + /*free ts in list*/ + for (ts_list_t::iterator p=ts_list.begin(); p != ts_list.end(); p++) + free(*p); + ts_list.clear(); +} + +int CTvScanner::createAtvParas(AM_SCAN_ATVCreatePara_t &atv_para, CFrontEnd::FEParas &fp, ScanParas &scp) { + atv_para.mode = scp.getAtvMode(); + if (atv_para.mode == TV_SCAN_ATVMODE_NONE) + return 0; + + int analog_auto = getParamOption("analog.auto"); + bool is_analog_auto = (analog_auto == -1)? false : (analog_auto != 0); + + int freq1, freq2; + freq1 = scp.getAtvFrequency1(); + freq2 = scp.getAtvFrequency2(); + if ((atv_para.mode != TV_SCAN_ATVMODE_FREQ && (freq1 <= 0 || freq2 <= 0) && is_analog_auto) + || (atv_para.mode == TV_SCAN_ATVMODE_MANUAL && freq1 == freq2) + || (atv_para.mode == TV_SCAN_ATVMODE_AUTO && freq1 > freq2) + || (atv_para.mode == TV_SCAN_ATVMODE_FREQ && freq1 > freq2)) { + LOGW(" freq error start:%d end=%d amode:%d", freq1, freq2, atv_para.mode); + return -1; + } + + if (TV_FE_ATSC == fp.getFEMode().getBase()) { + mAtvIsAtsc = 1; + atv_para.afc_range = 2000000; + LOGD("create ATV scan param: ATSC"); + } else { + atv_para.afc_range = 2000000; + } + + atv_para.am_scan_atv_cvbs_lock = &checkAtvCvbsLockHelper; + atv_para.default_std = CFrontEnd::getInstance()->enumToStdAndColor(fp.getVideoStd(), fp.getAudioStd()); + atv_para.channel_id = -1; + //atv_para.afc_range = 2000000; + + if (mAtvIsAtsc && !is_analog_auto) {// atsc scan with list-mode, not auto mode + int mode = scp.getAtvModifier(CFrontEnd::FEParas::FEP_MODE, -1); + if (mode == -1) + mode = fp.getFEMode().getMode(); + const char *list_name = getDtvScanListName(mode); + LOGD("Using Region List [%s] for ATV", list_name); + + int f1 = scp.getAtvModifier(CFrontEnd::FEParas::FEP_FREQ, -1); + if (f1 != -1) + freq1 = freq2 = f1; + + Vector<sp<CTvChannel>> vcp; + + //for FREQ_MODE + //freq1 == freq2 == 0 : full list auto search + //freq1 == freq2 != 0 : single freq manual search + //freq1 != freq2 : list(range) freq manual search + if (freq1 == freq2 && freq1 == 0) + CTvRegion::getChannelListByName((char *)list_name, vcp); + else + CTvRegion::getChannelListByNameAndFreqRange((char *)list_name, freq1, freq2, vcp); + + int size = vcp.size(); + LOGD("channel list size = %d", size); + + if (size == 0) { + CTvDatabase::GetTvDb()->importXmlToDB(CTV_DATABASE_DEFAULT_XML); + CTvRegion::getChannelListByName((char *)list_name, vcp); + size = vcp.size(); + } + + if (!(atv_para.fe_paras = static_cast<AM_FENDCTRL_DVBFrontendParameters_t *>(calloc(size, sizeof(AM_FENDCTRL_DVBFrontendParameters_t))))) + return -1; + + int i; + for (i = 0; i < size; i++) { + atv_para.fe_paras[i].m_type = TV_FE_ANALOG; + atv_para.fe_paras[i].analog.para.frequency = vcp[i]->getFrequency(); + } + atv_para.fe_cnt = size; + + return 0; + } + + atv_para.fe_paras = static_cast<AM_FENDCTRL_DVBFrontendParameters_t *>(calloc(3, sizeof(AM_FENDCTRL_DVBFrontendParameters_t))); + if (atv_para.fe_paras != NULL) { + memset(atv_para.fe_paras, 0, 3 * sizeof(AM_FENDCTRL_DVBFrontendParameters_t)); + atv_para.fe_paras[0].m_type = TV_FE_ANALOG; + atv_para.fe_paras[0].analog.para.frequency = scp.getAtvFrequency1(); + atv_para.fe_paras[1].m_type = TV_FE_ANALOG; + atv_para.fe_paras[1].analog.para.frequency = scp.getAtvFrequency2(); + atv_para.fe_paras[2].m_type = TV_FE_ANALOG; + atv_para.fe_paras[2].analog.para.frequency = (atv_para.mode == TV_SCAN_ATVMODE_AUTO)? 0 : scp.getAtvFrequency1(); + } + atv_para.fe_cnt = 3; + if (atv_para.mode == TV_SCAN_ATVMODE_AUTO) { + atv_para.afc_unlocked_step = 3000000; + atv_para.cvbs_unlocked_step = 1500000; + atv_para.cvbs_locked_step = 6000000; + } else { + atv_para.direction = (atv_para.fe_paras[1].analog.para.frequency >= atv_para.fe_paras[0].analog.para.frequency)? 1 : 0; + atv_para.cvbs_unlocked_step = 1000000; + atv_para.cvbs_locked_step = 3000000; + } + return 0; +} + +int CTvScanner::freeAtvParas(AM_SCAN_ATVCreatePara_t &atv_para) { + if (atv_para.fe_paras != NULL) + free(atv_para.fe_paras); + return 0; +} + +int CTvScanner::createDtvParas(AM_SCAN_DTVCreatePara_t &dtv_para, CFrontEnd::FEParas &fp, ScanParas &scp) { + + dtv_para.mode = scp.getDtvMode(); + if (dtv_para.mode == TV_SCAN_DTVMODE_NONE) + return 0; + + dtv_para.source = fp.getFEMode().getBase(); + dtv_para.dmx_dev_id = 0;//default 0 + dtv_para.standard = TV_SCAN_DTV_STD_DVB; + if (dtv_para.source == TV_FE_ATSC) + dtv_para.standard = TV_SCAN_DTV_STD_ATSC; + else if (dtv_para.source == TV_FE_ISDBT) + dtv_para.standard = TV_SCAN_DTV_STD_ISDB; + + int forceDtvStd = getScanDtvStandard(scp); + if (forceDtvStd != -1) { + dtv_para.standard = (AM_SCAN_DTVStandard_t)forceDtvStd; + LOGD("force dtv std: %d", forceDtvStd); + } + + const char *list_name = getDtvScanListName(fp.getFEMode().getMode()); + LOGD("Using Region List [%s] for DTV", list_name); + + Vector<sp<CTvChannel>> vcp; + + if (scp.getDtvMode() == TV_SCAN_DTVMODE_ALLBAND) { + CTvRegion::getChannelListByName((char *)list_name, vcp); + } else { + CTvRegion::getChannelListByNameAndFreqRange((char *)list_name, scp.getDtvFrequency1(), scp.getDtvFrequency2(), vcp); + } + int size = vcp.size(); + LOGD("channel list size = %d", size); + + if (size == 0) { + if (scp.getMode() != TV_SCAN_DTVMODE_ALLBAND) { + LOGD("frequncy: %d not found in channel list [%s], break", scp.getDtvFrequency1(), list_name); + return -1; + } + CTvDatabase::GetTvDb()->importXmlToDB(CTV_DATABASE_DEFAULT_XML); + CTvRegion::getChannelListByName((char *)list_name, vcp); + size = vcp.size(); + } + + int air_on_cable = getParamOption("air_on_cable.enable"); + bool is_air_on_cable = (air_on_cable == -1)? false : (air_on_cable != 0); + if (dtv_para.source == TV_FE_ATSC && is_air_on_cable && size) { + int cnt = 0; + int i; + for (i = 0; i < size; i++) { + fe_modulation_t mod = (fe_modulation_t)(vcp[i]->getModulation()); + if (mod >= QAM_16 && mod <= QAM_AUTO) { + vcp.push_back(new CTvChannel( + vcp[i]->getID(), vcp[i]->getMode(), vcp[i]->getFrequency(), + vcp[i]->getBandwidth(), VSB_8, + vcp[i]->getSymbolRate(), 0, 0)); + cnt++; + } + } + size = vcp.size(); + LOGD("Feature[air on cable] on, list size more: %d, total:%d", cnt, size); + } + + if (!(dtv_para.fe_paras = static_cast<AM_FENDCTRL_DVBFrontendParameters_t *>(calloc(size, sizeof(AM_FENDCTRL_DVBFrontendParameters_t))))) + return -1; + + int i; + for (i = 0; i < size; i++) { + dtv_para.fe_paras[i].m_type = dtv_para.source; + switch (dtv_para.fe_paras[i].m_type) { + case TV_FE_DTMB: + dtv_para.fe_paras[i].dtmb.para.frequency = vcp[i]->getFrequency(); + dtv_para.fe_paras[i].dtmb.para.inversion = INVERSION_OFF; + dtv_para.fe_paras[i].dtmb.para.u.ofdm.bandwidth = (fe_bandwidth_t)(vcp[i]->getBandwidth()); + if (fp.getBandwidth() != -1) + dtv_para.fe_paras[i].dtmb.para.u.ofdm.bandwidth = (fe_bandwidth_t)fp.getBandwidth(); + break; + case TV_FE_QAM: + dtv_para.fe_paras[i].cable.para.frequency = vcp[i]->getFrequency(); + dtv_para.fe_paras[i].cable.para.inversion = INVERSION_OFF; + dtv_para.fe_paras[i].cable.para.u.qam.symbol_rate = vcp[i]->getSymbolRate(); + dtv_para.fe_paras[i].cable.para.u.qam.modulation = (fe_modulation_t)vcp[i]->getModulation(); + if (fp.getSymbolrate() != -1) + dtv_para.fe_paras[i].cable.para.u.qam.symbol_rate = fp.getSymbolrate(); + if (fp.getModulation() != -1) + dtv_para.fe_paras[i].cable.para.u.qam.modulation = (fe_modulation_t)fp.getModulation(); + break; + case TV_FE_OFDM: + dtv_para.fe_paras[i].terrestrial.para.frequency = vcp[i]->getFrequency(); + dtv_para.fe_paras[i].terrestrial.para.inversion = INVERSION_OFF; + dtv_para.fe_paras[i].terrestrial.para.u.ofdm.bandwidth = (fe_bandwidth_t)(vcp[i]->getBandwidth()); + dtv_para.fe_paras[i].terrestrial.para.u.ofdm.ofdm_mode = (fe_ofdm_mode_t)fp.getFEMode().getGen(); + if (fp.getBandwidth() != -1) + dtv_para.fe_paras[i].terrestrial.para.u.ofdm.bandwidth = (fe_bandwidth_t)fp.getBandwidth(); + break; + case TV_FE_ATSC: + dtv_para.fe_paras[i].atsc.para.frequency = vcp[i]->getFrequency(); + dtv_para.fe_paras[i].atsc.para.inversion = INVERSION_OFF; + dtv_para.fe_paras[i].atsc.para.u.vsb.modulation = (fe_modulation_t)(vcp[i]->getModulation()); + if (fp.getModulation() != -1) + dtv_para.fe_paras[i].atsc.para.u.vsb.modulation = (fe_modulation_t)(fe_modulation_t)fp.getModulation(); + break; + case TV_FE_ISDBT: + dtv_para.fe_paras[i].isdbt.para.frequency = vcp[i]->getFrequency(); + dtv_para.fe_paras[i].isdbt.para.inversion = INVERSION_OFF; + dtv_para.fe_paras[i].isdbt.para.u.ofdm.bandwidth = (fe_bandwidth_t)(vcp[i]->getBandwidth()); + if (fp.getBandwidth() != -1) + dtv_para.fe_paras[i].isdbt.para.u.ofdm.bandwidth = (fe_bandwidth_t)fp.getBandwidth(); + break; + } + } + + dtv_para.fe_cnt = size; + dtv_para.resort_all = false; + + const char *sort_mode = config_get_str ( CFG_SECTION_TV, CFG_DTV_SCAN_SORT_MODE, "null"); + if (!strcmp(sort_mode, "lcn") && (dtv_para.standard != TV_SCAN_DTV_STD_ATSC)) + dtv_para.sort_method = AM_SCAN_SORT_BY_LCN; + else + dtv_para.sort_method = AM_SCAN_SORT_BY_FREQ_SRV_ID; + + return 0; +} + +int CTvScanner::freeDtvParas(AM_SCAN_DTVCreatePara_t &dtv_para) { + if (dtv_para.fe_paras != NULL) + free(dtv_para.fe_paras); + return 0; +} + +void CTvScanner::CC_VBINetworkCb(void* handle, vbi_network *n) +{ + void *userData = AM_CC_GetUserData(handle); + if (userData != (void*)this) + return; + mVbiTsId = n->ts_id; +} + +void CTvScanner::CC_VBINetworkCbHelper(void* handle, vbi_network *n) +{ + if (mInstance) + mInstance->CC_VBINetworkCb(handle, n); + else + LOGE("no scanner running, ignore CC_VBINetworkCb"); +} + +#endif + +CTvScanner::SCAN_ServiceInfo_t* CTvScanner::getServiceInfo() +{ + SCAN_ServiceInfo_t *srv_info = (SCAN_ServiceInfo_t*)calloc(sizeof(SCAN_ServiceInfo_t), 1); + if (!srv_info) { + LOGE("No Memory for Scanner."); + return NULL; + } + + memset(srv_info, 0, sizeof(SCAN_ServiceInfo_t)); + srv_info->vid = 0x1fff; + srv_info->vfmt = -1; + srv_info->free_ca = 1; + srv_info->srv_id = 0xffff; + srv_info->pmt_pid = 0x1fff; + srv_info->plp_id = -1; + srv_info->sdt_version = 0xff; + return srv_info; +} + +const char *CTvScanner::getDtvScanListName(int mode) +{ + char *list_name = NULL; +#ifdef SUPPORT_ADTV + CFrontEnd::FEMode feMode(mode); + int base = feMode.getBase(); + int list = feMode.getList(); + + switch (base) { + case TV_FE_DTMB: + list_name = (char *)"CHINA,Default DTMB ALL"; + break; + case TV_FE_QAM: + list_name = (char *)"China,DVB-C allband"; + break; + case TV_FE_OFDM: + list_name = (char *)"UK,Default DVB-T"; + break; + case TV_FE_ATSC: + switch (list) { + case 1: + list_name = (char *)"U.S.,ATSC Cable Standard"; + break; + case 2: + list_name = (char *)"U.S.,ATSC Cable IRC"; + break; + case 3: + list_name = (char *)"U.S.,ATSC Cable HRC"; + break; + case 4: + list_name = (char *)"U.S.,ATSC Cable Auto"; + break; + case 5: + list_name = (char *)"U.S.,ATSC Air"; + break; + case 6: + list_name = (char *)"U.S.,NTSC Cable Standard"; + break; + case 7: + list_name = (char *)"U.S.,NTSC Cable IRC"; + break; + case 8: + list_name = (char *)"U.S.,NTSC Cable HRC"; + break; + case 9: + list_name = (char *)"U.S.,NTSC Cable Auto"; + break; + case 10: + list_name = (char *)"U.S.,NTSC Air"; + break; + default: + list_name = (char *)"U.S.,ATSC Air"; + break; + }break; + case TV_FE_ISDBT: + list_name = (char *)"BRAZIL,Default ISDBT"; + break; + default: + list_name = (char *)"CHINA,Default DTMB ALL"; + LOGD("unknown scan mode %d, using default[%s]", mode, list_name); + break; + } +#endif + return list_name; +} + +bool CTvScanner::checkAtvCvbsLock(unsigned long *colorStd) +{ + tvafe_cvbs_video_t cvbs_lock_status; + int ret, i = 0; + + *colorStd = 0; + while (i < 20) { + ret = CTvin::getInstance()->AFE_GetCVBSLockStatus(&cvbs_lock_status); + + if (cvbs_lock_status == TVAFE_CVBS_VIDEO_HV_LOCKED) + /*||cvbs_lock_status == TVAFE_CVBS_VIDEO_V_LOCKED + ||cvbs_lock_status == TVAFE_CVBS_VIDEO_H_LOCKED)*/ { + //usleep(2000 * 1000); + tvin_info_t info; + CTvin::getInstance()->VDIN_GetSignalInfo(&info); + *colorStd = CTvin::CvbsFtmToV4l2ColorStd(info.fmt); + LOGD("checkAtvCvbsLock locked and cvbs fmt = %d std = 0x%x", info.fmt, (unsigned int) *colorStd); + return true; + } + usleep(50 * 1000); + i++; + } + return false; +} + +bool CTvScanner::checkAtvCvbsLockHelper(void *data) +{ + if (data == NULL) return false; +#ifdef SUPPORT_ADTV + AM_SCAN_ATV_LOCK_PARA_t *pAtvPara = (AM_SCAN_ATV_LOCK_PARA_t *)data; + CTvScanner *pScan = (CTvScanner *)(pAtvPara->pData); + if (mInstance != pScan) + return false; + unsigned long std; + bool isLock = pScan->checkAtvCvbsLock(&std); + pAtvPara->pOutColorSTD = std; + return isLock; +#else + return false; +#endif +} + +int CTvScanner::getScanDtvStandard(ScanParas &scp) { +#ifdef SUPPORT_ADTV + int forceDtvStd = scp.getDtvStandard(); + const char *dtvStd = config_get_str ( CFG_SECTION_TV, "dtv.scan.std.force", "null"); + if (!strcmp(dtvStd, "atsc")) + forceDtvStd = TV_SCAN_DTV_STD_ATSC; + else if (!strcmp(dtvStd, "dvb")) + forceDtvStd = TV_SCAN_DTV_STD_DVB; + else if (!strcmp(dtvStd, "isdb")) + forceDtvStd = TV_SCAN_DTV_STD_ISDB; + + if (forceDtvStd != -1) { + LOGD("force dtv std: %d", forceDtvStd); + return forceDtvStd; + } +#endif + return -1; +} + +void CTvScanner::reconnectDmxToFend(int dmx_no, int fend_no) +{ +#ifdef SUPPORT_ADTV + AM_DMX_Source_t src; + + if (AM_FEND_GetTSSource(fend_no, &src) == DVB_SUCCESS) { + LOGD("Set demux%d source to %d", dmx_no, src); + AM_DMX_SetSource(dmx_no, src); + } else { + LOGD("Cannot get frontend ts source!!"); + } +#endif +} + +bool CTvScanner::needVbiAssist() { + return (getScanDtvStandard(mScanParas) == TV_SCAN_DTV_STD_ATSC + && mScanParas.getAtvMode() != TV_SCAN_ATVMODE_NONE); +} + +int CTvScanner::startVBI() +{ +#ifdef SUPPORT_ADTV + AM_CC_CreatePara_t cc_para; + AM_CC_StartPara_t spara; + int ret; + + if (mVbi) + return 0; + + mVbiTsId = -1; + + memset(&cc_para, 0, sizeof(cc_para)); + cc_para.input = AM_CC_INPUT_VBI; + cc_para.network_cb = CC_VBINetworkCbHelper; + cc_para.user_data = this; + ret = AM_CC_Create(&cc_para, &mVbi); + if (ret != DVB_SUCCESS) + goto error; + + memset(&spara, 0, sizeof(spara)); + spara.caption1 = AM_CC_CAPTION_XDS; + spara.caption2 = AM_CC_CAPTION_NONE; + ret = AM_CC_Start(mVbi, &spara); + if (ret != DVB_SUCCESS) + goto error; + +#endif + LOGD("start cc successfully!"); + return 0; +error: + stopVBI(); + LOGD("start cc failed!"); + return -1; + +} + +void CTvScanner::stopVBI() +{ +#ifdef SUPPORT_ADTV + if (mVbi != NULL) { + AM_CC_Destroy(mVbi); + mVbi = NULL; + } + mVbiTsId = -1; +#endif +} + +void CTvScanner::resetVBI() +{ + stopVBI(); + startVBI(); +} + +bool CTvScanner::checkVbiDataReady(int freq) { + for (int i = 0; i < 5; i++) { + if (mVbiTsId != -1) + break; + usleep(50 * 1000); + } + + if (mVbiTsId == -1) { + LOGD("VbiDataNotReady"); + return false; + } + + LOGD("VbiDataReady"); + SCAN_TsIdInfo_t *tsid_info = (SCAN_TsIdInfo_t*)calloc(sizeof(SCAN_TsIdInfo_t), 1); + if (!tsid_info) { + LOGE("No Memory for Scanner."); + return false; + } + + tsid_info->freq = freq; + tsid_info->tsid = mVbiTsId; + tsid_list.push_back(tsid_info); + return true; +} + +int CTvScanner::FETypeHelperCBHelper(int id, void *para, void *user) { + if (mInstance) + mInstance->FETypeHelperCB(id, para, user); + else + LOGE("no scanner running, ignore FETypeHelperCB"); + return -1; +} + +int CTvScanner::FETypeHelperCB(int id, void *para, void *user) { +#ifdef SUPPORT_ADTV + if ((id != AM_SCAN_HELPER_ID_FE_TYPE_CHANGE) + || (user != (void*)this)) + return -1; + + fe_type_t type = static_cast<fe_type_t>(reinterpret_cast<intptr_t>(para)); + LOGD("FE set mode %d", type); + + if (type == mFEType) + return 0; + + mFEType = type; + + CFrontEnd *fe = CFrontEnd::getInstance(); + CTvin *tvin = CTvin::getInstance(); + if (type == TV_FE_ANALOG) { + fe->setMode(type); + tvin->Tvin_StopDecoder(); + tvin->VDIN_ClosePort(); + tvin->VDIN_OpenPort(tvin->Tvin_GetSourcePortBySourceInput(SOURCE_TV)); + if (needVbiAssist()) + resetVBI(); + } else { + if (needVbiAssist()) + stopVBI(); + tvin->Tvin_StopDecoder(); + tvin->VDIN_ClosePort(); + //tvin->VDIN_OpenPort(tvin->Tvin_GetSourcePortBySourceInput(SOURCE_DTV)); + //tvin->VDIN_CloseModule(); + //tvin->AFE_CloseModule(); + fe->setMode(type); + //CTvScanner *pScanner = (CTvScanner *)user; + reconnectDmxToFend(0, 0); + } +#endif + return 0; +} + + + void CTvScanner::evtCallback(long dev_no, int event_type, void *param, void *data __unused) +{ +#ifdef SUPPORT_ADTV + CTvScanner *pT = NULL; + long long tmpFreq = 0; + + LOGD("evt evt:%d", event_type); + AM_SCAN_GetUserData((void*)dev_no, (void **)&pT); + if (pT == NULL) { + return; + } + int AdtvMixed = (pT->mScanParas.getAtvMode() != TV_SCAN_ATVMODE_NONE + && pT->mScanParas.getDtvMode() != TV_SCAN_DTVMODE_NONE)? 1 : 0; + int factor = (AdtvMixed && pT->mScanParas.getAtvMode() != TV_SCAN_ATVMODE_FREQ)? 50 : 100; + + pT->mCurEv.clear(); + memset(pT->mCurEv.mProgramName, '\0', sizeof(pT->mCurEv.mProgramName)); + memset(pT->mCurEv.mParas, '\0', sizeof(pT->mCurEv.mParas)); + memset(pT->mCurEv.mVct, '\0', sizeof(pT->mCurEv.mVct)); + if (event_type == AM_SCAN_EVT_PROGRESS) { + AM_SCAN_Progress_t *evt = (AM_SCAN_Progress_t *)param; + LOGD("progress evt:%d [%d%%]", evt->evt, pT->mCurEv.mPercent); + switch (evt->evt) { + case AM_SCAN_PROGRESS_SCAN_BEGIN: { + AM_SCAN_CreatePara_t *cp = (AM_SCAN_CreatePara_t*)evt->data; + pT->mCurEv.mPercent = 0; + pT->mCurEv.mScanMode = (cp->mode<<24)|((cp->atv_para.mode&0xFF)<<16)|(cp->dtv_para.mode&0xFFFF); + pT->mCurEv.mSortMode = (cp->dtv_para.standard<<16)|(cp->dtv_para.sort_method&0xFFFF); + if (TV_FE_ATSC == pT->mFEParas.getFEMode().getBase()) + pT->mCurEv.mSortMode = pT->mCurEv.mSortMode | (TV_SCAN_DTV_STD_ATSC<<16); + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_BEGIN; + pT->sendEvent(pT->mCurEv); + } + break; + case AM_SCAN_PROGRESS_NIT_BEGIN: + break; + case AM_SCAN_PROGRESS_NIT_END: + break; + case AM_SCAN_PROGRESS_TS_BEGIN: { + AM_SCAN_TSProgress_t *tp = (AM_SCAN_TSProgress_t *)evt->data; + if (tp == NULL) + break; + pT->mCurEv.mChannelIndex = tp->index; + if (pT->mFEParas.getFEMode().getBase() == tp->fend_para.m_type) + pT->mCurEv.mMode = pT->mFEParas.getFEMode().getMode(); + else + pT->mCurEv.mMode = tp->fend_para.m_type; + pT->mCurEv.mFrequency = ((struct dvb_frontend_parameters *)(&tp->fend_para))->frequency; + pT->mCurEv.mSymbolRate = tp->fend_para.cable.para.u.qam.symbol_rate; + pT->mCurEv.mModulation = tp->fend_para.cable.para.u.qam.modulation; + pT->mCurEv.mBandwidth = tp->fend_para.terrestrial.para.u.ofdm.bandwidth; + + pT->mCurEv.mFEParas.fromFENDCTRLParameters(CFrontEnd::FEMode(pT->mCurEv.mMode), &tp->fend_para); + + if (tp->fend_para.m_type == TV_FE_ANALOG) { + if (AdtvMixed || pT->mScanParas.getAtvMode() == TV_SCAN_ATVMODE_FREQ) {//mix + pT->mCurEv.mPercent = (tp->index * factor) / tp->total; + } else { + pT->mCurEv.mPercent = 0; + } + } else { + pT->mCurEv.mPercent = (tp->index * factor) / tp->total; + } + + if (pT->mCurEv.mTotalChannelCount == 0) + pT->mCurEv.mTotalChannelCount = tp->total; + if (pT->mCurEv.mPercent >= factor) + pT->mCurEv.mPercent = factor -1; + + pT->mCurEv.mLockedStatus = 0; + pT->mCurEv.mStrength = 0; + pT->mCurEv.mSnr = 0; + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_PROGRESS; + + pT->sendEvent(pT->mCurEv); + } + break; + case AM_SCAN_PROGRESS_TS_END: { + /*pT->mCurEv.mLockedStatus = 0; + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_PROGRESS; + pT->sendEvent(pT->mCurEv);*/ + } + break; + + case AM_SCAN_PROGRESS_PAT_DONE: /*{ + if (pT->mCurEv.mTotalChannelCount == 1) { + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_PROGRESS; + pT->sendEvent(pT->mCurEv); + } + }*/ + break; + case AM_SCAN_PROGRESS_SDT_DONE: /*{ + dvbpsi_sdt_t *sdts = (dvbpsi_sdt_t *)evt->data; + dvbpsi_sdt_t *sdt; + + if (pT->mCurEv.mTotalChannelCount == 1) { + pT->mCurEv.mPercent += 25; + if (pT->mCurEv.mPercent >= 100) + pT->mCurEv.mPercent = 99; + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_PROGRESS; + + pT->sendEvent(pT->mCurEv); + } + }*/ + break; + case AM_SCAN_PROGRESS_CAT_DONE: /*{ + dvbpsi_cat_t *cat = (dvbpsi_cat_t *)evt->data; + if (pT->mCurEv.mTotalChannelCount == 1) { + pT->mCurEv.mPercent += 25; + if (pT->mCurEv.mPercent >= 100) + pT->mCurEv.mPercent = 99; + + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_PROGRESS; + + pT->sendEvent(pT->mCurEv); + } + }*/ + break; + case AM_SCAN_PROGRESS_PMT_DONE: /*{ + dvbpsi_pmt_t *pmt = (dvbpsi_pmt_t *)evt->data; + if (pT->mCurEv.mTotalChannelCount == 1) { + pT->mCurEv.mPercent += 25; + if (pT->mCurEv.mPercent >= 100) + pT->mCurEv.mPercent = 99; + + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_PROGRESS; + pT->sendEvent(pT->mCurEv); + } + }*/ + break; + case AM_SCAN_PROGRESS_MGT_DONE: { + mgt_section_info_t *mgt = (mgt_section_info_t *)evt->data; + + if (pT->mCurEv.mTotalChannelCount == 1) { + pT->mCurEv.mPercent += 10; + if (pT->mCurEv.mPercent >= 100) + pT->mCurEv.mPercent = 99; + + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_PROGRESS; + pT->sendEvent(pT->mCurEv); + } + } + break; + case AM_SCAN_PROGRESS_VCT_DONE: { + /*ATSC TVCT*/ + if (pT->mCurEv.mTotalChannelCount == 1) { + pT->mCurEv.mPercent += 30; + if (pT->mCurEv.mPercent >= 100) + pT->mCurEv.mPercent = 99; + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_PROGRESS; + pT->sendEvent(pT->mCurEv); + } + } + break; + case AM_SCAN_PROGRESS_NEW_PROGRAM: { + /* Notify the new searched programs */ + AM_SCAN_ProgramProgress_t *pp = (AM_SCAN_ProgramProgress_t *)evt->data; + if (pp != NULL) { + pT->mCurEv.mprogramType = pp->service_type; + snprintf(pT->mCurEv.mProgramName, sizeof(pT->mCurEv.mProgramName), "%s", pp->name); + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_PROGRESS; + pT->sendEvent(pT->mCurEv); + } + } + break; + case AM_SCAN_PROGRESS_NEW_PROGRAM_MORE: { + AM_SCAN_NewProgram_Data_t *npd = (AM_SCAN_NewProgram_Data_t *)evt->data; + if (npd != NULL) { + switch (npd->newts->type) { + case AM_SCAN_TS_ANALOG: + if (npd->result->start_para->atv_para.mode & TV_SCAN_ATVMODE_AUTO == TV_SCAN_ATVMODE_AUTO + || npd->result->start_para->atv_para.mode & TV_SCAN_ATVMODE_FREQ == TV_SCAN_ATVMODE_FREQ) + pT->storeScan(npd->result, npd->newts); + break; + case AM_SCAN_TS_DIGITAL: + if ((npd->result->start_para->dtv_para.mode & TV_SCAN_DTVMODE_AUTO == TV_SCAN_DTVMODE_AUTO) + || (npd->result->start_para->dtv_para.mode & TV_SCAN_DTVMODE_ALLBAND == TV_SCAN_DTVMODE_ALLBAND)) + pT->storeScan(npd->result, npd->newts); + break; + default: + break; + } + } + } + break; + case AM_SCAN_PROGRESS_BLIND_SCAN: { + AM_SCAN_DTVBlindScanProgress_t *bs_prog = (AM_SCAN_DTVBlindScanProgress_t *)evt->data; + + if (bs_prog) { + pT->mCurEv.mPercent = bs_prog->progress; + + /*snprintf(pT->mCurEv.mMSG, sizeof(pT->mCurEv.mMSG), "%s/%s %dMHz", + bs_prog->polar == AM_FEND_POLARISATION_H ? "H" : "V", + bs_prog->lo == AM_FEND_LOCALOSCILLATORFREQ_L ? "L-LOF" : "H-LOF", + bs_prog->freq / 1000); + */ + pT->mCurEv.mType = ScannerEvent::EVENT_BLINDSCAN_PROGRESS; + + pT->sendEvent(pT->mCurEv); + + if (bs_prog->new_tp_cnt > 0) { + int i = 0; + for (i = 0; i < bs_prog->new_tp_cnt; i++) { + LOGD("New tp: %dkS/s %d====", bs_prog->new_tps[i].frequency, + bs_prog->new_tps[i].u.qpsk.symbol_rate); + + pT->mCurEv.mFrequency = bs_prog->new_tps[i].frequency; + pT->mCurEv.mSymbolRate = bs_prog->new_tps[i].u.qpsk.symbol_rate; + pT->mCurEv.mSat_polarisation = bs_prog->polar; + pT->mCurEv.mType = ScannerEvent::EVENT_BLINDSCAN_NEWCHANNEL; + pT->sendEvent(pT->mCurEv); + } + } + if (bs_prog->progress >= 100) { + pT->mCurEv.mType = ScannerEvent::EVENT_BLINDSCAN_END; + pT->sendEvent(pT->mCurEv); + pT->mCurEv.mPercent = 0; + } + } + } + break; + case AM_SCAN_PROGRESS_STORE_BEGIN: { + pT->mCurEv.mType = ScannerEvent::EVENT_STORE_BEGIN; + pT->mCurEv.mLockedStatus = 0; + pT->sendEvent(pT->mCurEv); + } + break; + case AM_SCAN_PROGRESS_STORE_END: { + pT->mCurEv.mLockedStatus = 0; + pT->mCurEv.mType = ScannerEvent::EVENT_STORE_END; + pT->sendEvent(pT->mCurEv); + } + break; + case AM_SCAN_PROGRESS_SCAN_END: { + pT->mCurEv.mPercent = 100; + pT->mCurEv.mLockedStatus = 0; + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_END; + pT->sendEvent(pT->mCurEv); + } + break; + case AM_SCAN_PROGRESS_SCAN_EXIT: { + pT->mCurEv.mLockedStatus = 0; + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_EXIT; + pT->sendEvent(pT->mCurEv); + } + break; + case AM_SCAN_PROGRESS_ATV_TUNING: { + CFrontEnd::FEMode femode(TV_FE_ANALOG); + pT->mCurEv.mFEParas.setFEMode(femode); + pT->mCurEv.mFEParas.setFrequency((long)evt->data); + pT->mCurEv.mFrequency = (long)evt->data; + pT->mCurEv.mLockedStatus = 0; + tmpFreq = (pT->mCurEv.mFrequency - pT->mCurScanStartFreq) / 1000000; + pT->mCurEv.mPercent = tmpFreq * factor / ((pT->mCurScanEndFreq - pT->mCurScanStartFreq) / 1000000) + + ((factor == 50)? 50 : 0); + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_PROGRESS; + + pT->sendEvent(pT->mCurEv); + } + break; + + default: + break; + } + } else if (event_type == AM_SCAN_EVT_SIGNAL) { + AM_SCAN_DTVSignalInfo_t *evt = (AM_SCAN_DTVSignalInfo_t *)param; + //pT->mCurEv.mprogramType = 0xff; + pT->mCurEv.mFrequency = (int)evt->frequency; + pT->mCurEv.mFEParas.setFrequency(evt->frequency); + pT->mCurEv.mLockedStatus = (evt->locked ? 1 : 0); + + if (pT->mCurEv.mFEParas.getFEMode().getBase() == TV_FE_ANALOG && evt->locked) {//trick here for atv new prog + pT->mCurEv.mLockedStatus |= 0x10; + if (pT->needVbiAssist()) + pT->checkVbiDataReady(evt->frequency); + } + + pT->mCurEv.mType = ScannerEvent::EVENT_SCAN_PROGRESS; + if (pT->mCurEv.mFEParas.getFEMode().getBase() != TV_FE_ANALOG && evt->locked) { + pT->mCurEv.mStrength = evt->strength; + pT->mCurEv.mSnr = evt->snr; + } else { + pT->mCurEv.mStrength = 0; + pT->mCurEv.mSnr = 0; + } + + //if (pT->mCurEv.mMode == TV_FE_ANALOG) + pT->sendEvent(pT->mCurEv); + pT->mCurEv.mLockedStatus &= ~0x10; + } +#endif +} + + +const char* CTvScanner::ScanParas::SCP_MODE = "m"; +const char* CTvScanner::ScanParas::SCP_ATVMODE = "am"; +const char* CTvScanner::ScanParas::SCP_DTVMODE = "dm"; +const char* CTvScanner::ScanParas::SCP_ATVFREQ1 = "af1"; +const char* CTvScanner::ScanParas::SCP_ATVFREQ2 = "af2"; +const char* CTvScanner::ScanParas::SCP_DTVFREQ1 = "df1"; +const char* CTvScanner::ScanParas::SCP_DTVFREQ2 = "df2"; +const char* CTvScanner::ScanParas::SCP_PROC = "prc"; +const char* CTvScanner::ScanParas::SCP_DTVSTD = "dstd"; + +CTvScanner::ScanParas& CTvScanner::ScanParas::operator = (const ScanParas &spp) +{ + this->mparas = spp.mparas; + return *this; +} + +int CTvScanner::getAtscChannelPara(int attennaType, Vector<sp<CTvChannel> > &vcp) +{ + switch (attennaType) { //region name should be remove to config file and read here + case 1: + CTvRegion::getChannelListByName((char *)"U.S.,ATSC Air", vcp); + break; + case 2: + CTvRegion::getChannelListByName((char *)"U.S.,ATSC Cable Standard", vcp); + break; + case 3: + CTvRegion::getChannelListByName((char *)"U.S.,ATSC Cable IRC", vcp); + break; + case 4: + CTvRegion::getChannelListByName((char *)"U.S.,ATSC Cable HRC", vcp); + break; + default: + return -1; + } + + return 0; +} + +int CTvScanner::ATVManualScan(int min_freq, int max_freq, int std, int store_Type, int channel_num) +{ +#ifdef SUPPORT_ADTV + UNUSED(store_Type); + UNUSED(channel_num); + + char paras[128]; + CFrontEnd::convertParas(paras, TV_FE_ANALOG, min_freq, max_freq, std, 0); + + CFrontEnd::FEParas fe(paras); + + ScanParas sp; + sp.setMode(TV_SCAN_MODE_ATV_DTV); + sp.setDtvMode(TV_SCAN_DTVMODE_NONE); + sp.setAtvMode(TV_SCAN_ATVMODE_MANUAL); + sp.setAtvFrequency1(min_freq); + sp.setAtvFrequency2(max_freq); + return Scan(fe, sp); +#else + return -1; +#endif +} + +int CTvScanner::autoAtvScan(int min_freq, int max_freq, int std, int search_type, int proc_mode) +{ +#ifdef SUPPORT_ADTV + UNUSED(search_type); + + char paras[128]; + CFrontEnd::convertParas(paras, TV_FE_ANALOG, min_freq, max_freq, std, 0); + + CFrontEnd::FEParas fe(paras); + + ScanParas sp; + sp.setMode(TV_SCAN_MODE_ATV_DTV); + sp.setDtvMode(TV_SCAN_DTVMODE_NONE); + sp.setAtvMode(TV_SCAN_ATVMODE_AUTO); + sp.setAtvFrequency1(min_freq); + sp.setAtvFrequency2(max_freq); + sp.setProc(proc_mode); + return Scan(fe, sp); +#else + return -1; +#endif +} + +int CTvScanner::autoAtvScan(int min_freq, int max_freq, int std, int search_type) +{ + return autoAtvScan(min_freq, max_freq, std, search_type, 0); +} + +int CTvScanner::dtvScan(int mode, int scan_mode, int beginFreq, int endFreq, int para1, int para2) +{ + char feparas[128]; + CFrontEnd::convertParas(feparas, mode, beginFreq, endFreq, para1, para2); + return dtvScan(feparas, scan_mode, beginFreq, endFreq); +} + +int CTvScanner::dtvScan(char *feparas, int scan_mode, int beginFreq, int endFreq) +{ + LOGE("dtvScan fe:[%s]", feparas); + CFrontEnd::FEParas fe(feparas); + ScanParas sp; + sp.setMode(TV_SCAN_MODE_DTV_ATV); + sp.setAtvMode(TV_SCAN_ATVMODE_NONE); + sp.setDtvMode(scan_mode); + sp.setDtvFrequency1(beginFreq); + sp.setDtvFrequency2(endFreq); + return Scan(fe, sp); +} + +int CTvScanner::dtvAutoScan(int mode) +{ + return dtvScan(mode, TV_SCAN_DTVMODE_ALLBAND, 0, 0, -1, -1); +} + +int CTvScanner::dtvManualScan(int mode, int beginFreq, int endFreq, int para1, int para2) +{ + return dtvScan(mode, TV_SCAN_DTVMODE_MANUAL, beginFreq, endFreq, para1, para2); +} + +int CTvScanner::manualDtmbScan(int beginFreq, int endFreq, int modulation) +{ +#ifdef SUPPORT_ADTV + return dtvManualScan(TV_FE_DTMB, beginFreq, endFreq, modulation, -1); +#else + return -1; +#endif +} + +//only test for dtv allbland auto +int CTvScanner::autoDtmbScan() +{ +#ifdef SUPPORT_ADTV + return dtvAutoScan(TV_FE_DTMB); +#else + return -1; +#endif +} + + diff --git a/tv/tvserver/libtv/tv/CTvScanner.h b/tv/tvserver/libtv/tv/CTvScanner.h new file mode 100644 index 0000000..c092acb --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvScanner.h @@ -0,0 +1,490 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifdef SUPPORT_ADTV +#include <am_scan.h> +#include <am_check_scramb.h> +#include <am_epg.h> +#include <am_mem.h> +#include <am_db.h> +#include "am_cc.h" +#endif +#include "CTvChannel.h" +#include "CTvLog.h" +#include "CTvEv.h" +#include "tvin/CTvin.h" +#include "tv/CFrontEnd.h" + +#include <list> + + +//must sync with dvb am_scan.h +enum +{ + TV_SCAN_ATVMODE_AUTO = 0x01, /**< auto scan mode*/ + TV_SCAN_ATVMODE_MANUAL = 0x02, /**< manual scan mode*/ + TV_SCAN_ATVMODE_FREQ = 0x03, /**< all band scan mode*/ + TV_SCAN_ATVMODE_NONE = 0x07, /**< none*/ +}; + +enum +{ + TV_SCAN_DTVMODE_AUTO = 0x01, /**< auto scan mode*/ + TV_SCAN_DTVMODE_MANUAL = 0x02, /**< manual scan mode*/ + TV_SCAN_DTVMODE_ALLBAND = 0x03, /**< all band scan mode*/ + TV_SCAN_DTVMODE_SAT_BLIND = 0x04, /**< Satellite blind scan mode*/ + TV_SCAN_DTVMODE_NONE = 0x07, /**< none*/ + /* OR option(s)*/ + TV_SCAN_DTVMODE_SEARCHBAT = 0x08, /**< Whether to search BAT table*/ + TV_SCAN_DTVMODE_SAT_UNICABLE = 0x10, /**< Satellite Unicable mode*/ + TV_SCAN_DTVMODE_FTA = 0x20, /**< Only scan free programs*/ + TV_SCAN_DTVMODE_NOTV = 0x40, /**< Donot store tv programs*/ + TV_SCAN_DTVMODE_NORADIO = 0x80, /**< Donot store radio programs*/ + TV_SCAN_DTVMODE_ISDBT_ONESEG = 0x100, /**< Scan ISDBT oneseg in layer A*/ + TV_SCAN_DTVMODE_ISDBT_FULLSEG = 0x200, /**< Scan ISDBT fullseg*/ + TV_SCAN_DTVMODE_SCRAMB_TSHEAD = 0x400, /**< is check scramb by ts head*/ + TV_SCAN_DTVMODE_NOVCT = 0x800, /**< Donot store in vct but not in pmt programs*/ + TV_SCAN_DTVMODE_NOVCTHIDE = 0x1000, /**< Donot store in vct hide flag is set 1*/ +}; + +enum +{ + TV_SCAN_DTV_STD_DVB = 0x00, /**< DVB standard*/ + TV_SCAN_DTV_STD_ATSC = 0x01, /**< ATSC standard*/ + TV_SCAN_DTV_STD_ISDB = 0x02, /**< ISDB standard*/ + TV_SCAN_DTV_STD_MAX, +}; + +enum { + TV_FE_QPSK, + TV_FE_QAM, + TV_FE_OFDM, + TV_FE_ATSC, + TV_FE_ANALOG, + TV_FE_DTMB, + TV_FE_ISDBT +}; + +enum +{ + TV_SCAN_MODE_ATV_DTV, /**< First search all ATV, then search all DTV*/ + TV_SCAN_MODE_DTV_ATV, /**< First search all DTV, then search all ATV*/ + TV_SCAN_MODE_ADTV, /**< A/DTV Use the same frequency table earch the A/DTV one by one In a frequency*/ +}; +//end + +#if !defined(_CTVSCANNER_H) +#define _CTVSCANNER_H +class CTvScanner { +public: + /** ATSC Attenna type */ + static const int AM_ATSC_ATTENNA_TYPE_AIR = 1; + static const int AM_ATSC_ATTENNA_TYPE_CABLE_STD = 2; + static const int AM_ATSC_ATTENNA_TYPE_CABLE_IRC = 3; + static const int AM_ATSC_ATTENNA_TYPE_CABLE_HRC = 4; + CTvScanner(); + ~CTvScanner(); + + /*deprecated{{*/ + int ATVManualScan(int min_freq, int max_freq, int std, int store_Type = 0, int channel_num = 0); + int autoAtvScan(int min_freq, int max_freq, int std, int search_type); + int autoAtvScan(int min_freq, int max_freq, int std, int search_type, int proc_mode); + int autoDtmbScan(); + int manualDtmbScan(int beginFreq, int endFreq, int modulation = -1); + int manualDtmbScan(int freq); + int unsubscribeEvent(); + int dtvAutoScan(int mode); + int dtvManualScan(int mode, int beginFreq, int endFreq, int para1, int para2); + int dtvScan(int mode, int scan_mode, int beginFreq, int endFreq, int para1, int para2); + int dtvScan(char *feparas, int scan_mode, int beginFreq, int endFreq); + /*}}deprecated*/ + + int Scan(char *feparas, char *scanparas); + int stopScan(); + int pauseScan(); + int resumeScan(); + int getScanStatus(int *status); + + static const char *getDtvScanListName(int mode); + static CTvScanner *getInstance(); + + struct ScannerLcnInfo { + + public: + #define MAX_LCN 4 + int net_id; + int ts_id; + int service_id; + int visible[MAX_LCN]; + int lcn[MAX_LCN]; + int valid[MAX_LCN]; + }; + + typedef std::list<ScannerLcnInfo*> lcn_list_t; + + + class ScannerEvent: public CTvEv { + public: + static const int EVENT_SCAN_PROGRESS = 0; + static const int EVENT_STORE_BEGIN = 1; + static const int EVENT_STORE_END = 2; + static const int EVENT_SCAN_END = 3; + static const int EVENT_BLINDSCAN_PROGRESS = 4; + static const int EVENT_BLINDSCAN_NEWCHANNEL = 5; + static const int EVENT_BLINDSCAN_END = 6; + static const int EVENT_ATV_PROG_DATA = 7; + static const int EVENT_DTV_PROG_DATA = 8; + static const int EVENT_SCAN_EXIT = 9; + static const int EVENT_SCAN_BEGIN = 10; + static const int EVENT_LCN_INFO_DATA = 11; + + ScannerEvent(): CTvEv(CTvEv::TV_EVENT_SCANNER) + { + reset(); + } + void reset() + { + clear(); + mFEParas.clear(); + } + void clear() + { + mType = -1; + mProgramName[0] = '\0'; + mParas[0] = '\0'; + mAcnt = 0; + mScnt = 0; + mVctType = 0; + mVct[0] = '\0'; + + memset(&mLcnInfo, 0, sizeof(ScannerLcnInfo)); + + mMajorChannelNumber = -1; + mMinorChannelNumber = -1; + } + ~ScannerEvent() + { + } + + //common + int mType; + int mPercent; + int mTotalChannelCount; + int mLockedStatus; + int mChannelIndex; + + int mMode; + long mFrequency; + int mSymbolRate; + int mModulation; + int mBandwidth; + int mReserved; + + int mSat_polarisation; + int mStrength; + int mSnr; + + char mProgramName[1024]; + int mprogramType; + char mParas[128]; + + //for atv + int mVideoStd; + int mAudioStd; + int mIsAutoStd; + + //for DTV + int mTsId; + int mONetId; + int mServiceId; + int mVid; + int mVfmt; + int mAcnt; + int mAid[32]; + int mAfmt[32]; + char mAlang[32][10]; + int mAtype[32]; + int mAExt[32]; + int mPcr; + + int mScnt; + int mStype[32]; + int mSid[32]; + int mSstype[32]; + int mSid1[32]; + int mSid2[32]; + char mSlang[32][10]; + + int mFree_ca; + int mScrambled; + + int mScanMode; + + int mSdtVer; + + int mSortMode; + + ScannerLcnInfo mLcnInfo; + + CFrontEnd::FEParas mFEParas; + + int mMajorChannelNumber; + int mMinorChannelNumber; + int mSourceId; + char mAccessControlled; + char mHidden; + char mHideGuide; + char mVctType; + char mVct[1024]; + }; + + class IObserver { + public: + IObserver() {}; + virtual ~IObserver() {}; + virtual void onEvent(const ScannerEvent &ev) = 0; + }; + // 1 VS n + //int addObserver(IObserver* ob); + //int removeObserver(IObserver* ob); + + // 1 VS 1 + int setObserver(IObserver *ob) + { + mpObserver = ob; + return 0; + } + + class ScanParas : public Paras { + + public: + ScanParas() : Paras() { } + ScanParas(const ScanParas &sp) : Paras(sp.mparas) { } + ScanParas(const char *paras) : Paras(paras) { } + ScanParas& operator = (const ScanParas &spp); + + int getMode() const { return getInt(SCP_MODE, 0); } + ScanParas& setMode(int m) { setInt(SCP_MODE, m); return *this; } + int getAtvMode() const { return getInt(SCP_ATVMODE, 0); } + ScanParas& setAtvMode(int a) { setInt(SCP_ATVMODE, a); return *this; } + int getDtvMode() const { return getInt(SCP_DTVMODE, 0); } + ScanParas& setDtvMode(int d) { setInt(SCP_DTVMODE, d); return *this; } + ScanParas& setAtvFrequency1(int f) { setInt(SCP_ATVFREQ1, f); return *this; } + int getAtvFrequency1() const { return getInt(SCP_ATVFREQ1, 0); } + ScanParas& setAtvFrequency2(int f) { setInt(SCP_ATVFREQ2, f); return *this; } + int getAtvFrequency2() const { return getInt(SCP_ATVFREQ2, 0); } + ScanParas& setDtvFrequency1(int f) { setInt(SCP_DTVFREQ1, f); return *this; } + int getDtvFrequency1() const { return getInt(SCP_DTVFREQ1, 0); } + ScanParas& setDtvFrequency2(int f) { setInt(SCP_DTVFREQ2, f); return *this; } + int getDtvFrequency2() const { return getInt(SCP_DTVFREQ2, 0); } + ScanParas& setProc(int p) { setInt(SCP_PROC, p); return *this; } + int getProc() const { return getInt(SCP_PROC, 0); } + ScanParas& setDtvStandard(int s) { setInt(SCP_DTVSTD, s); return *this; } + int getDtvStandard() const { return getInt(SCP_DTVSTD, -1); } + + ScanParas& setAtvModifier(const char* name, int m) { char n[32] = {0}; snprintf(n, 32, "%s_amod", name); setInt(n, m); return *this; } + int getAtvModifier(const char* name, int def) { char n[32] = {0}; snprintf(n, 32, "%s_amod", name); return getInt(n, def); } + ScanParas& setDtvModifier(const char* name, int m) { char n[32] = {0}; snprintf(n, 32, "%s_dmod", name); setInt(n, m); return *this; } + int getDtvModifier(const char* name, int def) { char n[32] = {0}; snprintf(n, 32, "%s_dmod", name); return getInt(n, def); } + + public: + static const char* SCP_MODE; + static const char* SCP_ATVMODE; + static const char* SCP_DTVMODE; + static const char* SCP_ATVFREQ1; + static const char* SCP_ATVFREQ2; + static const char* SCP_DTVFREQ1; + static const char* SCP_DTVFREQ2; + static const char* SCP_PROC; + static const char* SCP_DTVSTD; + }; + + int Scan(CFrontEnd::FEParas &fp, ScanParas &sp); + +private: + bool checkAtvCvbsLock(unsigned long *colorStd); + static bool checkAtvCvbsLockHelper(void *); + + static void evtCallback(long dev_no, int event_type, void *param, void *data); + + void reconnectDmxToFend(int dmx_no, int fend_no); + int getAtscChannelPara(int attennaType, Vector<sp<CTvChannel> > &vcp); + void sendEvent(ScannerEvent &evt); + // + void* mScanHandle; + volatile bool mbScanStart; + + //scan para info + /** General TV Scan Mode */ + static const int TV_MODE_ATV = 0; // Only search ATV + static const int TV_MODE_DTV = 1; // Only search DTV + static const int TV_MODE_ADTV = 2; // A/DTV will share a same frequency list, like ATSC + /** DTV scan mode */ + static const int DTV_MODE_AUTO = 1; + static const int DTV_MODE_MANUAL = 2; + static const int DTV_MODE_ALLBAND = 3; + static const int DTV_MODE_BLIND = 4; + + /** DTV scan options, DONOT channge */ + static const int DTV_OPTION_UNICABLE = 0x10; //Satellite unicable mode + static const int DTV_OPTION_FTA = 0x20; //Only store free programs + static const int DTV_OPTION_NO_TV = 0x40; //Only store tv programs + static const int DTV_OPTION_NO_RADIO = 0x80; //Only store radio programs + + /** ATV scan mode */ + static const int ATV_MODE_AUTO = 1; + static const int ATV_MODE_MANUAL = 2; + + // + /*subtitle*/ + static const int TYPE_DVB_SUBTITLE = 1; + static const int TYPE_DTV_TELETEXT = 2; + static const int TYPE_ATV_TELETEXT = 3; + static const int TYPE_DTV_CC = 4; + static const int TYPE_ATV_CC = 5; + + typedef struct { + int nid; + int tsid; + CFrontEnd::FEParas fe; + int dtvstd; + char vct[1024]; + } SCAN_TsInfo_t; + + typedef std::list<SCAN_TsInfo_t*> ts_list_t; + +#define AM_SCAN_MAX_SRV_NAME_LANG 4 +#define AM_DB_MAX_SRV_NAME_LEN 64 + + typedef struct { + uint8_t srv_type, eit_sche, eit_pf, rs, free_ca; + uint8_t access_controlled, hidden, hide_guide; + uint8_t plp_id, vct_type; + int vid, vfmt, srv_id, pmt_pid, pcr_pid, src; + int chan_num, scrambled_flag; + int major_chan_num, minor_chan_num, source_id; + char name[(AM_DB_MAX_SRV_NAME_LEN + 4)*AM_SCAN_MAX_SRV_NAME_LANG + 1]; + #ifdef SUPPORT_ADTV + AM_SI_AudioInfo_t aud_info; + AM_SI_SubtitleInfo_t sub_info; + AM_SI_TeletextInfo_t ttx_info; + AM_SI_CaptionInfo_t cap_info; + #endif + int sdt_version; + SCAN_TsInfo_t *tsinfo; + } SCAN_ServiceInfo_t; + + typedef std::list<SCAN_ServiceInfo_t*> service_list_t; + +#ifdef SUPPORT_ADTV + dvbpsi_pat_t *getValidPats(AM_SCAN_TS_t *ts); + int getPmtPid(dvbpsi_pat_t *pats, int pn); + void extractCaScrambledFlag(dvbpsi_descriptor_t *p_first_descriptor, int *flag); + void extractSrvInfoFromSdt(AM_SCAN_Result_t *result, dvbpsi_sdt_t *sdts, SCAN_ServiceInfo_t *service); + void extractSrvInfoFromVc(AM_SCAN_Result_t *result, dvbpsi_atsc_vct_channel_t *vcinfo, SCAN_ServiceInfo_t *service); + void updateServiceInfo(AM_SCAN_Result_t *result, SCAN_ServiceInfo_t *service); + void getLcnInfo(AM_SCAN_Result_t *result, AM_SCAN_TS_t *ts, lcn_list_t &llist); + void addFixedATSCCaption(AM_SI_CaptionInfo_t *cap_info, int service, int cc, int text, int is_digital_cc); + void processDvbTs(AM_SCAN_Result_t *result, AM_SCAN_TS_t *ts, service_list_t &slist); + void processAnalogTs(AM_SCAN_Result_t *result, AM_SCAN_TS_t *ts, SCAN_TsInfo_t *tsinfo, service_list_t &slist); + void processAtscTs(AM_SCAN_Result_t *result, AM_SCAN_TS_t *ts, SCAN_TsInfo_t *tsinfo, service_list_t &slist); + void processTsInfo(AM_SCAN_Result_t *result, AM_SCAN_TS_t *ts, SCAN_TsInfo_t *info); + void storeNewDvb(AM_SCAN_Result_t *result, AM_SCAN_TS_t *newts); + void storeNewAnalog(AM_SCAN_Result_t *result, AM_SCAN_TS_t *newts); + void storeNewAtsc(AM_SCAN_Result_t *result, AM_SCAN_TS_t *newts); + void storeScan(AM_SCAN_Result_t *result, AM_SCAN_TS_t *curr_ts); + int createAtvParas(AM_SCAN_ATVCreatePara_t &atv_para, CFrontEnd::FEParas &fp, ScanParas &sp); + int freeAtvParas(AM_SCAN_ATVCreatePara_t &atv_para); + int createDtvParas(AM_SCAN_DTVCreatePara_t &dtv_para, CFrontEnd::FEParas &fp, ScanParas &sp); + int freeDtvParas(AM_SCAN_DTVCreatePara_t &dtv_para); + void CC_VBINetworkCb(void* handle, vbi_network *n); + static void storeScanHelper(AM_SCAN_Result_t *result); + static void CC_VBINetworkCbHelper(void* handle, vbi_network *n); +#endif + SCAN_ServiceInfo_t* getServiceInfo(); + void notifyService(SCAN_ServiceInfo_t *service); + void notifyLcn(ScannerLcnInfo *lcn); + int insertLcnList(lcn_list_t &llist, ScannerLcnInfo *lcn, int idx); + int getParamOption(char *para); + int getScanDtvStandard(ScanParas &scp); + bool needVbiAssist(); + bool checkVbiDataReady(int freq); + int startVBI(); + void stopVBI(); + void resetVBI(); + int FETypeHelperCB(int id, void *para, void *user); + static int FETypeHelperCBHelper(int id, void *para, void *user); + + +private: + static CTvScanner *mInstance; + + IObserver *mpObserver; + // + CTvin *mpTvin; + int mMode; + int mFendID; + /** DTV parameters */ + int mTvMode; + int mTvOptions; + int mSat_id; + int mSource; + + //showboz + //TVSatelliteParams tv_satparams; + int mTsSourceID; + CTvChannel mStartChannel; + Vector<CTvChannel> mvChooseListChannels; + /** ATV parameters */ + int mAtvMode; + int mStartFreq; + int mDirection; + int mChannelID; + + //extern for scanner + //int channelID; //can be used for manual scan + /** Atv set */ + int mMinFreq; + int mMaxFreq; + long long mCurScanStartFreq; + long long mCurScanEndFreq; + int tunerStd; + /** Tv set */ + int demuxID;//default 0 + String8 defaultTextLang; + String8 orderedTextLangs; + //showboz + //Vector<CTvChannel> ChannelList;//VS mvChooseListChannels + + /** Dtv-Sx set Unicable settings*/ + int user_band; + int ub_freq;//!< kHz + + CFrontEnd::FEParas mFEParas; + ScanParas mScanParas; + + int mFEType; + + static ScannerEvent mCurEv; + + static service_list_t service_list_dummy; + + void* mVbi; + int mVbiTsId; + int mAtvIsAtsc; + + typedef struct { + int freq; + int tsid; + }SCAN_TsIdInfo_t; + typedef std::list<SCAN_TsIdInfo_t*> tsid_list_t; + tsid_list_t tsid_list; + +}; +#endif //CTVSCANNER_H diff --git a/tv/tvserver/libtv/tv/CTvScreenCapture.cpp b/tv/tvserver/libtv/tv/CTvScreenCapture.cpp new file mode 100644 index 0000000..d2664cd --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvScreenCapture.cpp @@ -0,0 +1,809 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvScreenCapture" + +#define UNUSED(x) (void)x + +#include <stdlib.h> +#include <fcntl.h> +#include <strings.h> +#include <sys/ioctl.h> +#include <asm/types.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <malloc.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <time.h> +#include <sys/mman.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <linux/videodev2.h> +#include <dirent.h> + +#include <binder/MemoryHeapBase.h> +#include <binder/MemoryBase.h> + +//#include <media/stagefright/MediaSource.h> +//#include <media/stagefright/MediaBuffer.h> +//#include <OMX_IVCommon.h> +//#include <media/stagefright/MetaData.h> +//#include <media/stagefright/ScreenCatch.h> +using namespace android; + + +#include "CTvScreenCapture.h" + +#define CLEAR(x) memset (&(x), 0, sizeof (x)) + +int CTvScreenCapture::xioctl(int fd, int request, void *arg) +{ + /* + int r = 0; + do { + r = ioctl(fd, request, arg); + } while (-1 == r && EINTR == errno); + + return r;*/ + + //TODO + UNUSED(fd); + UNUSED(request); + UNUSED(arg); + return 0; +} + +int CTvScreenCapture::OpenCamera(struct camera *pCameraDev) +{ + /* + int iOutRet = 0, iRet; + struct stat st; + + do { + if (-1 == stat(pCameraDev->device_name, &st)) { + LOGD( "Cannot identify '%s'\n", pCameraDev->device_name); + iOutRet = FAILED; + break; + } + + if (!S_ISCHR(st.st_mode)) { + LOGD("%s is no device\n", pCameraDev->device_name); + iOutRet = FAILED; + break; + } + + pCameraDev->fd = open(pCameraDev->device_name, O_RDWR | O_NONBLOCK, 0); // O_NONBLOCK + if (SUCCEED > pCameraDev->fd) { + LOGD("Cannot open '%s'\n", pCameraDev->device_name); + iOutRet = FAILED; + break; + } + } while (FALSE); + + return iOutRet;*/ + + //TODO + UNUSED(pCameraDev); + return 0; +} + + +int CTvScreenCapture::InitVCap(sp<IMemory> Mem) +{ + /* + int iOutRet = FAILED; + + do { + m_pMem = Mem; + m_pData = (char *)m_pMem->pointer(); + LOGD("VVVVVVVVVVVVVVVVVVVVVVVVVVVVV %p\n", m_pData); + //default + } while (FALSE); + + return iOutRet;*/ + + //TODO + Mem = 0; + return 0; +} + +int CTvScreenCapture::InitMmap(struct camera *cam) +{ + /* + int iOutRet = SUCCEED, iRet; + struct v4l2_requestbuffers req; + + do { + CLEAR(req); + + req.count = 4; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_MMAP; + + iRet = xioctl(cam->fd, VIDIOC_REQBUFS, &req); + if (FAILED == iRet) { + if (EINVAL == errno) { + LOGD("VIDIOC_REQBUFS %s does not support memory mapping\n", cam->device_name); + } + iOutRet = iRet; + break; + } + + if (req.count < 2) { + LOGD("Insufficient buffer memory on %s\n", cam->device_name); + iOutRet = FAILED; + break; + } + + cam->buffers = (struct buffer *)calloc(req.count, sizeof(*(cam->buffers))); + if (!cam->buffers) { + LOGD("Out of memory\n"); + iOutRet = FAILED; + break; + } + + for (m_capNumBuffers = 0; m_capNumBuffers < req.count; ++m_capNumBuffers) { + struct v4l2_buffer buf; + + CLEAR(buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = m_capNumBuffers; + + if (FAILED == xioctl(cam->fd, VIDIOC_QUERYBUF, &buf)) { + LOGD("VIDIOC_QUERYBUF ERROR\n"); + iOutRet = FAILED; + goto IS_ERROR; + } + + cam->buffers[m_capNumBuffers].length = buf.length; + cam->buffers[m_capNumBuffers].start = mmap(NULL \, + buf.length, PROT_READ | PROT_WRITE, + MAP_SHARED, cam->fd, buf.m.offset); + + if (MAP_FAILED == cam->buffers[m_capNumBuffers].start) { + iOutRet = FAILED; + break; + } + + + } + + LOGD("END m_capNumBuffers : %d\n", m_capNumBuffers); + } while (FALSE); +IS_ERROR: + return iOutRet;*/ + + //TODO + UNUSED(cam); + return 0; +} + +int CTvScreenCapture::InitCamera(struct camera *cam) +{ + /* + int iOutRet = SUCCEED, iRet; + struct v4l2_capability *cap = &(cam->v4l2_cap); + struct v4l2_cropcap *cropcap = &(cam->v4l2_cropcap); + struct v4l2_crop *crop = &(cam->crop); + struct v4l2_format *fmt = &(cam->v4l2_fmt); + unsigned int min; + + do { + iRet = xioctl(cam->fd, VIDIOC_QUERYCAP, cap); + if (FAILED == iRet) { + if (EINVAL == errno) { + LOGD("%s is no V4L2 device\n", cam->device_name); + } + iOutRet = iRet; + break; + } + + if (!(cap->capabilities & V4L2_CAP_VIDEO_CAPTURE)) { + LOGD("%s is no video capture device\n", cam->device_name); + iOutRet = FAILED; + break; + } + + if (!(cap->capabilities & V4L2_CAP_STREAMING)) { + LOGD("%s does not support streaming i/o\n", cam->device_name); + iOutRet = FAILED; + break; + } + + LOGD("VIDOOC_QUERYCAP camera driver is [%s] card is [%s] businfo is [%s] version is [%d]\n", cap->driver, + cap->card, cap->bus_info, cap->version); + + // Select video input, video standard and tune here. + + CLEAR(*cropcap); + cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + crop->c.width = cam->width; + crop->c.height = cam->height; + crop->c.left = 0; + crop->c.top = 0; + crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + CLEAR(*fmt); + fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt->fmt.pix.width = cam->width; + fmt->fmt.pix.height = cam->height; + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_NV21; + fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + iRet = xioctl(cam->fd, VIDIOC_S_FMT, fmt); + if (FAILED == iRet) { + iOutRet = iRet; + LOGD("VIDIOC_S_FMT is ERROR\n"); + break; + } + + // Note VIDIOC_S_FMT may change width and height. + // Buggy driver paranoia. + min = fmt->fmt.pix.width * 2; + LOGD("bytesperline : %d w:h [%d %d]\n", fmt->fmt.pix.bytesperline, fmt->fmt.pix.width, fmt->fmt.pix.height); + if (fmt->fmt.pix.bytesperline < min) { + fmt->fmt.pix.bytesperline = min; + } + + min = fmt->fmt.pix.bytesperline * fmt->fmt.pix.height; + if (fmt->fmt.pix.sizeimage < min) { + fmt->fmt.pix.sizeimage = min; + } + + iRet = InitMmap(cam); + if (FAILED == iRet) { + LOGD("INIT MMAP FAILED\n"); + iOutRet = iRet; + break; + } + } while (FALSE); + return iOutRet; + */ + + //TODO + UNUSED(cam); + return 0; +} + + +int CTvScreenCapture::SetVideoParameter(int width, int height, int frame) +{ + /* + int iOutRet = SUCCEED, iRet; + + do { + m_capV4l2Cam.device_name = "/dev/video11"; + m_capV4l2Cam.buffers = NULL; + m_capV4l2Cam.width = 1280; + m_capV4l2Cam.height = 720; + m_capV4l2Cam.display_depth = 24; //5; //RGB24 + m_capV4l2Cam.frame_number = 1; //fps + iOutRet = OpenCamera(&m_capV4l2Cam) ; + if (SUCCEED != iOutRet) { + LOGD("ERROR:::Open Camera device failed\n"); + break; + } + m_capV4l2Cam.width = width; + m_capV4l2Cam.height = height; + m_capV4l2Cam.frame_number = frame; + + iRet = InitCamera(&m_capV4l2Cam); + if (SUCCEED != iRet) { + iOutRet = iRet; + break; + } + + } while (FALSE); + + return iOutRet ;*/ + + //TODO + UNUSED(width); + UNUSED(height); + UNUSED(frame); + return 0; +} + +int CTvScreenCapture::StartCapturing(struct camera *cam) +{ + /* + unsigned int i; + int iOutRet = SUCCEED, iRet; + enum v4l2_buf_type type; + + do { + for (i = 0; i < m_capNumBuffers; ++i) { + struct v4l2_buffer buf; + + //CLEAR(buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; + + iRet = xioctl(cam->fd, VIDIOC_QBUF, &buf); + if (FAILED == iRet) { + iOutRet = iRet; + goto IS_ERROR; + } + } + + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + iRet = xioctl(cam->fd, VIDIOC_STREAMON, &type); + if (FAILED == iRet) { + iOutRet = iRet; + break; + } + } while (FALSE); + +IS_ERROR: + return iOutRet;*/ + + //TODO + UNUSED(cam); + return 0; +} + +int CTvScreenCapture::VideoStart() +{ + /* + int iOutRet = SUCCEED, iRet; + do { + iRet = StartCapturing(&m_capV4l2Cam); + if (FAILED == iRet) { + iOutRet = iRet; + break; + } + } while (FALSE); + + return iOutRet;*/ + + return 0; +} + +void CTvScreenCapture::yuv_to_rgb32(unsigned char y, unsigned char u, unsigned char v, unsigned char *rgb) +{ + /* + register int r, g, b; + int rgb24; + + r = (1192 * (y - 16) + 1634 * (v - 128) ) >> 10; + g = (1192 * (y - 16) - 833 * (v - 128) - 400 * (u - 128) ) >> 10; + b = (1192 * (y - 16) + 2066 * (u - 128) ) >> 10; + + r = r > 255 ? 255 : r < 0 ? 0 : r; + g = g > 255 ? 255 : g < 0 ? 0 : g; + b = b > 255 ? 255 : b < 0 ? 0 : b; + + rgb24 = (int)((r << 16) | (g << 8) | b); + + //ARGB + *rgb = (unsigned char)r; + rgb ++; + *rgb = (unsigned char)g; + rgb++; + *rgb = (unsigned char)b; + rgb++; + *rgb = 0xff;*/ + + //TODO + UNUSED(y); + UNUSED(u); + UNUSED(v); + UNUSED(rgb); +} + +void CTvScreenCapture::nv21_to_rgb32(unsigned char *buf, unsigned char *rgb, int width, int height, int *len) +{ + /* + int x, y, z = 0; + int h, w; + int blocks; + unsigned char Y1, Y2, U, V; + + *len = 0; + blocks = (width * height) * 2; + for (h = 0, z = 0; h < height; h += 2) { + for (y = 0; y < width * 2; y += 2) { + Y1 = buf[ h * width + y + 0]; + V = buf[ blocks / 2 + h * width / 2 + y % width + 0 ]; + Y2 = buf[ h * width + y + 1]; + U = buf[ blocks / 2 + h * width / 2 + y % width + 1 ]; + + yuv_to_rgb32(Y1, U, V, &rgb[z]); + yuv_to_rgb32(Y2, U, V, &rgb[z + 4]); + z += 8; + } + } + *len = z; + */ + + //TODO + UNUSED(buf); + UNUSED(rgb); + UNUSED(width); + UNUSED(height); + UNUSED(len); +} + +int CTvScreenCapture::GetVideoData(int *length) +{ + /* + int iOutRet = SUCCEED, iRet; + + *length = 0; + while (true) { + fd_set fds; + struct timeval tv; + FD_ZERO(&fds); + FD_SET(m_capV4l2Cam.fd, &fds); + // Timeout. + tv.tv_sec = 0; + tv.tv_usec = 30000; + iRet = select(m_capV4l2Cam.fd + 1, &fds, NULL, NULL, &tv); + if (FAILED == iRet) { + LOGD("select FAILED\n"); + if (EINTR == errno) { + LOGD("select FAILED Continue\n"); + continue; + } + } + + if (0 == iRet) { + LOGD("select timeout\n"); + continue ; + } + + struct v4l2_buffer buf; + CLEAR(buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + iRet = xioctl(m_capV4l2Cam.fd, VIDIOC_DQBUF, &buf); + if (FAILED == iRet) { + if (errno == EAGAIN) { + LOGD("GetVideoData EAGAIN \n"); + } + continue; + } + + LOGD("DDDDDDDDDDAAAAAAAAAAAAAAAAAAAATTTTTTTTTTTTTTAAAAAAAAAAAAAAAAAAAAAAAAAAAAA %d %d [width:%d] [height:%d]\n", buf.length, iRet, + m_capV4l2Cam.width, m_capV4l2Cam.height); + int tmpLen = 0; + nv21_to_rgb32((unsigned char *)m_capV4l2Cam.buffers[buf.index].start, (unsigned char *)m_pData, m_capV4l2Cam.width, m_capV4l2Cam.height, &tmpLen); + //memcpy(m_pData,m_capV4l2Cam.buffers[buf.index].start, buf.length +1); + *length = buf.length; + break; + } + + if (*length > 0) { + mCapEvt.mFrameWide = m_capV4l2Cam.width; + mCapEvt.mFrameHeight = m_capV4l2Cam.height; + mCapEvt.mFrameNum = 1; + mCapEvt.mFrameSize = *length; + } else { + mCapEvt.mFrameWide = 0; + mCapEvt.mFrameHeight = 0; + mCapEvt.mFrameNum = 0; + mCapEvt.mFrameSize = 0; + } + + if (NULL != mpObserver) { + mpObserver->onTvEvent(mCapEvt); + } + + return iOutRet;*/ + + //TODO + UNUSED(length); + return 0; +} + +int CTvScreenCapture::StopCapturing(struct camera *cam) +{ + /* + int iOutRet = SUCCEED, iRet; + enum v4l2_buf_type type; + + do { + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + iRet = xioctl(cam->fd, VIDIOC_STREAMOFF, &type); + if (FAILED == iRet) { + iOutRet = iRet; + break; + } + } while (FALSE); + return iOutRet;*/ + + //TODO + UNUSED(cam); + return 0; +} + +int CTvScreenCapture::VideoStop() +{ + /* + StopCapturing(&m_capV4l2Cam); + UninitCamera(&m_capV4l2Cam); + return SUCCEED;*/ + return 0; +} + +int CTvScreenCapture::UninitCamera(struct camera *cam) +{ + /* + unsigned int i; + + for (i = 0; i < m_capNumBuffers; ++i) { + if (cam->buffers[i].start == NULL) { + break; + } + + if (FAILED == munmap(cam->buffers[i].start, cam->buffers[i].length)) { + LOGD("ERROR::munmap cam buffer failed\n"); + break; + } + } + + if (NULL != cam->buffers) + free(cam->buffers); + cam->buffers = NULL; + return SUCCEED;*/ + + //TODO + UNUSED(cam); + return 0; +} + +int CTvScreenCapture::CloseCamera(struct camera *cam) +{ + /* + int iOutRet = SUCCEED, iRet; + + do { + if (cam->fd > 0) { + iRet = close(cam->fd); + if (FAILED == iRet) { + iOutRet = iRet; + break; + } + + cam->fd = -1; + } + } while (FALSE); + + return iOutRet;*/ + + //TODO + UNUSED(cam); + return 0; +} + +int CTvScreenCapture::DeinitVideoCap() +{ + /* + CloseCamera(&m_capV4l2Cam); + return SUCCEED ; + */ + return 0; +} + +int CTvScreenCapture::AmvideocapCapFrame(char *buf, int size, int *w, int *h, int *ret_size) +{ + /* + int iOutRet = SUCCEED, iRet; + int iDevFd = -1; + int format = FORMAT_S32_ABGR; + + do { + iDevFd = open(VIDEOCAPDEV, O_RDWR); + if (iDevFd < 0) { + LOGD("ERROR,open amvideocap0 failed\n"); + iOutRet = FAILED; + break; + } + + if ((w != NULL) && (*w > 0)) { + iRet = ioctl(iDevFd, AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH, *w); + if (iRet < 0) { + iOutRet = iRet; + break; + } + } + + if ((h != NULL) && (*h > 0)) { + iRet = ioctl(iDevFd, AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT, *h); + if (iRet < 0) { + iOutRet = iRet; + break; + } + } + + iRet = ioctl(iDevFd, AMVIDEOCAP_IOW_SET_WANTFRAME_FORMAT, format); + if (iRet < 0) { + iOutRet = iRet; + break; + } + + *ret_size = read(iDevFd, buf, size); + if (0 == *ret_size) { + LOGD("ERROR:: Cann't Read video data\n"); + iOutRet = FAILED; + *ret_size = 0; + break; + } + + LOGD("========== Got Data Size : %d ==============\n", *ret_size); +#if 0 + if (w != NULL) { + iRet = ioctl(iDevFd, AMVIDEOCAP_IOR_GET_FRAME_WIDTH, w); + } + + if (h != NULL) { + iRet = ioctl(iDevFd, AMVIDEOCAP_IOR_GET_FRAME_HEIGHT, h); + } +#endif + } while (FALSE); + + close(iDevFd); + return iOutRet;*/ + + //TODO + UNUSED(buf); + UNUSED(size); + UNUSED(w); + UNUSED(h); + UNUSED(ret_size); + return 0; +} + +int CTvScreenCapture::CapOsdAndVideoLayer(int width, int height) +{ + /* + int iOutRet = SUCCEED, iRet; + status_t iStatus; + ScreenCatch *mScreenCatch = NULL; + MetaData *pMeta = NULL; + MediaBuffer *buffer = NULL; + int dataLen = 0; + + do { + mScreenCatch = new ScreenCatch(width, height, 32); + if (NULL == mScreenCatch) { + LOGD("ERROR!!! mScreenCatch is NULL\n"); + iOutRet = FAILED; + break; + } + + pMeta = new MetaData(); + if (NULL == pMeta) { + LOGD("ERROR!!! pMeta is NULL\n"); + iOutRet = FAILED; + break; + } + pMeta->setInt32(kKeyColorFormat, OMX_COLOR_Format32bitARGB8888); + + mScreenCatch->start(pMeta); + + while (true) { + iStatus = mScreenCatch->read(&buffer); + if (iStatus != OK ) { + usleep(1000); + continue; + } + + if (NULL == buffer) { + iOutRet = FAILED; + break; + } + + LOGD("DDDDDDDDDDAAAAAAAAAAAAAAAAAAAATTTTTTTTTTTTTTAAAAAAAAAAAAAAAAAAAAAAAAAAAAA %d %d\n", buffer->size(), iStatus); + //nv21_to_rgb32((unsigned char*)buffer->data(),(unsigned char *)m_pData,width,height,&dataLen); + memcpy((unsigned char *)m_pData, (unsigned char *)buffer->data(), buffer->size()); + break; + } + } while (FALSE); + + if (dataLen > 0) { + mCapEvt.mFrameWide = width; + mCapEvt.mFrameHeight = height; + mCapEvt.mFrameNum = 1; + mCapEvt.mFrameSize = dataLen; + } else { + mCapEvt.mFrameWide = 0; + mCapEvt.mFrameHeight = 0; + mCapEvt.mFrameNum = 0; + mCapEvt.mFrameSize = 0; + } + + if (NULL != mpObserver) { + mpObserver->onTvEvent(mCapEvt); + } + + mScreenCatch->stop(); + + mScreenCatch->free(buffer); + buffer = NULL; + return iOutRet;*/ + + //TODO + UNUSED(width); + UNUSED(height); + return 0; +} + +int CTvScreenCapture::CapMediaPlayerVideoLayerOnly(int width, int height) +{ + /* + int iOutRet = SUCCEED, iRet; + int ibufSize, iDataSize = 0; + int w, h; + + do { + ibufSize = width * height * 4; + w = width; + h = height; + + iRet = AmvideocapCapFrame(m_pData, ibufSize, &w, &h, &iDataSize); + if (SUCCEED != iRet) { + LOGD("AmvideocapCapFrame Cannt CapFram\n"); + iOutRet = iRet; + break; + } + + LOGD("GOT DDDDDDDDDAAAAAAAATTTTTTTTTTTAAAAAA Size : %d w:%d h: %d\n", iDataSize, w, h); + + if (iDataSize > 0) { + mCapEvt.mFrameWide = w; + mCapEvt.mFrameHeight = h; + mCapEvt.mFrameNum = 1; + mCapEvt.mFrameSize = iDataSize; + } else { + mCapEvt.mFrameWide = 0; + mCapEvt.mFrameHeight = 0; + mCapEvt.mFrameNum = 0; + mCapEvt.mFrameSize = 0; + } + + if (NULL != mpObserver) { + mpObserver->onTvEvent(mCapEvt); + } + } while (FALSE); + + return iOutRet;*/ + + //TODO + UNUSED(width); + UNUSED(height); + return 0; +} + +CTvScreenCapture::CTvScreenCapture() +{ + /* + m_capNumBuffers = 0; + memset(&m_capV4l2Cam, 0x00, sizeof(camera)); + mpObserver = NULL;*/ +} + +CTvScreenCapture::~CTvScreenCapture() +{ + /* + memset(&m_capV4l2Cam, 0x00, sizeof(camera)); + m_pData = NULL;*/ +} + diff --git a/tv/tvserver/libtv/tv/CTvScreenCapture.h b/tv/tvserver/libtv/tv/CTvScreenCapture.h new file mode 100644 index 0000000..bbe4980 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvScreenCapture.h @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef CTVSCREENCAPTURE_H__ +#define CTVSCREENCAPTURE_H__ + +#define VIDEOCAPDEV "/dev/amvideocap0" + +#define AMVIDEOCAP_IOC_MAGIC 'V' +#include <linux/videodev2.h> +#include <binder/MemoryHeapBase.h> +#include <binder/MemoryBase.h> +#include "CTvLog.h" +#include "CTvEv.h" + +#define CAP_FLAG_AT_CURRENT 0 +#define CAP_FLAG_AT_TIME_WINDOW 1 +#define CAP_FLAG_AT_END 2 + + +#define FALSE 0 +#define SUCCEED 0 +#define FAILED -1 + +using namespace android; + +struct buffer { + void *start; + size_t length; +}; + +struct camera { + char *device_name; + int fd; + int width; + int height; + int display_depth; + int image_size; + int frame_number; //fps + int bitrate ; // bitrate + struct v4l2_capability v4l2_cap; + struct v4l2_cropcap v4l2_cropcap; + struct v4l2_format v4l2_fmt; + struct v4l2_crop crop; + struct buffer *buffers; +}; + +/* +format see linux/ge2d/ge2d.h +like: +GE2D_FORMAT_S24_RGB +*/ +#define ENDIAN_SHIFT 24 +#define TV_LITTLE_ENDIAN (1 << ENDIAN_SHIFT) +#define FMT_S24_RGB (TV_LITTLE_ENDIAN|0x00200) /* 10_00_0_00_0_00 */ +#define FMT_S16_RGB (TV_LITTLE_ENDIAN|0x00100) /* 01_00_0_00_0_00 */ +#define FMT_S32_RGBA (TV_LITTLE_ENDIAN|0x00300) /* 11_00_0_00_0_00 */ + +#define COLOR_MAP_SHIFT 20 +#define COLOR_MAP_MASK (0xf << COLOR_MAP_SHIFT) +/* 16 bit */ +#define COLOR_MAP_RGB565 (5 << COLOR_MAP_SHIFT) +/* 24 bit */ +#define COLOR_MAP_RGB888 (0 << COLOR_MAP_SHIFT) +#define COLOR_MAP_BGR888 (5 << COLOR_MAP_SHIFT) +/* 32 bit */ +#define COLOR_MAP_RGBA8888 (0 << COLOR_MAP_SHIFT) +#define COLOR_MAP_ARGB8888 (1 << COLOR_MAP_SHIFT) +#define COLOR_MAP_ABGR8888 (2 << COLOR_MAP_SHIFT) +#define COLOR_MAP_BGRA8888 (3 << COLOR_MAP_SHIFT) + +/*16 bit*/ +#define FORMAT_S16_RGB_565 (FMT_S16_RGB | COLOR_MAP_RGB565) +/*24 bit*/ +#define FORMAT_S24_BGR (FMT_S24_RGB | COLOR_MAP_BGR888) +#define FORMAT_S24_RGB (FMT_S24_RGB | COLOR_MAP_RGB888) +/*32 bit*/ +#define FORMAT_S32_ARGB (FMT_S32_RGBA | COLOR_MAP_ARGB8888) +#define FORMAT_S32_ABGR (FMT_S32_RGBA | COLOR_MAP_ABGR8888) +#define FORMAT_S32_BGRA (FMT_S32_RGBA | COLOR_MAP_BGRA8888) +#define FORMAT_S32_RGBA (FMT_S32_RGBA | COLOR_MAP_RGBA8888) + +#define AMVIDEOCAP_IOW_SET_WANTFRAME_FORMAT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x01, int) +#define AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH _IOW(AMVIDEOCAP_IOC_MAGIC, 0x02, int) +#define AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x03, int) +#define AMVIDEOCAP_IOW_SET_WANTFRAME_TIMESTAMP_MS _IOW(AMVIDEOCAP_IOC_MAGIC, 0x04, u64) +#define AMVIDEOCAP_IOW_SET_WANTFRAME_WAIT_MAX_MS _IOW(AMVIDEOCAP_IOC_MAGIC, 0x05, u64) +#define AMVIDEOCAP_IOW_SET_WANTFRAME_AT_FLAGS _IOW(AMVIDEOCAP_IOC_MAGIC, 0x06, int) + + +#define AMVIDEOCAP_IOR_GET_FRAME_FORMAT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x10, int) +#define AMVIDEOCAP_IOR_GET_FRAME_WIDTH _IOR(AMVIDEOCAP_IOC_MAGIC, 0x11, int) +#define AMVIDEOCAP_IOR_GET_FRAME_HEIGHT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x12, int) +#define AMVIDEOCAP_IOR_GET_FRAME_TIMESTAMP_MS _IOR(AMVIDEOCAP_IOC_MAGIC, 0x13, int) + + +#define AMVIDEOCAP_IOR_GET_SRCFRAME_FORMAT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x20, int) +#define AMVIDEOCAP_IOR_GET_SRCFRAME_WIDTH _IOR(AMVIDEOCAP_IOC_MAGIC, 0x21, int) +#define AMVIDEOCAP_IOR_GET_SRCFRAME_HEIGHT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x22, int) + + +#define AMVIDEOCAP_IOR_GET_STATE _IOR(AMVIDEOCAP_IOC_MAGIC, 0x31, int) +#define AMVIDEOCAP_IOW_SET_START_CAPTURE _IOW(AMVIDEOCAP_IOC_MAGIC, 0x32, int) +#define AMVIDEOCAP_IOW_SET_CANCEL_CAPTURE _IOW(AMVIDEOCAP_IOC_MAGIC, 0x33, int) + +#define AMVIDEOCAP_IOR_SET_SRC_X _IOR(AMVIDEOCAP_IOC_MAGIC, 0x40, int) +#define AMVIDEOCAP_IOR_SET_SRC_Y _IOR(AMVIDEOCAP_IOC_MAGIC, 0x41, int) +#define AMVIDEOCAP_IOR_SET_SRC_WIDTH _IOR(AMVIDEOCAP_IOC_MAGIC, 0x42, int) +#define AMVIDEOCAP_IOR_SET_SRC_HEIGHT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x43, int) + +enum amvideocap_state { + AMVIDEOCAP_STATE_INIT = 0, + AMVIDEOCAP_STATE_ON_CAPTURE = 200, + AMVIDEOCAP_STATE_FINISHED_CAPTURE = 300, + AMVIDEOCAP_STATE_ERROR = 0xffff, +}; + +class CTvScreenCapture { +public: + CTvScreenCapture(); + ~CTvScreenCapture(); + + int InitVCap(sp<IMemory> Mem); + int SetVideoParameter(int width, int height, int frame); + int VideoStart(); + int GetVideoData( int *length); + int VideoStop(); + int DeinitVideoCap(); + int CapMediaPlayerVideoLayerOnly(int width, int height); + int CapOsdAndVideoLayer(int width, int height); + class CapEvent : public CTvEv { + public: + CapEvent(): CTvEv(CTvEv::TV_EVENT_HDMI_IN_CAP) {}; + ~CapEvent() {}; + + int mFrameNum; + int mFrameWide; + int mFrameHeight; + int mFrameSize; + }; + + class TvIObserver { + public: + TvIObserver() {}; + virtual ~TvIObserver() {}; + virtual void onTvEvent ( const CTvEv &ev ) = 0; + }; + + int setObserver(TvIObserver *ob) + { + mpObserver = ob; + return 0; + } + +private: + + int xioctl(int fd, int request, void *arg); + int OpenCamera(struct camera *pCameraDev); + int InitMmap(struct camera *cam) ; + //int SetFrameRate( struct camera *cam); + int InitCamera(struct camera *cam) ; + int StartCapturing(struct camera *cam); + int StopCapturing(struct camera *cam); + int UninitCamera(struct camera *cam); + int CloseCamera(struct camera *cam); + void yuv_to_rgb32(unsigned char y, unsigned char u, unsigned char v, unsigned char *rgb); + void nv21_to_rgb32(unsigned char *buf, unsigned char *rgb, int width, int height, int *len); + int AmvideocapCapFrame(char *buf, int size, int *w, int *h, int *ret_size); +private: + sp<IMemory> m_pMem; + camera m_capV4l2Cam; + unsigned int m_capNumBuffers; + + char *m_pData; + TvIObserver *mpObserver; + CapEvent mCapEvt; +}; +#endif + diff --git a/tv/tvserver/libtv/tv/CTvSubtitle.cpp b/tv/tvserver/libtv/tv/CTvSubtitle.cpp new file mode 100644 index 0000000..6eef0fa --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvSubtitle.cpp @@ -0,0 +1,644 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvSubtitle" +#define UNUSED(x) (void)x + +#include "CTvSubtitle.h" +#ifdef SUPPORT_ADTV +#include "am_misc.h" +#include "am_dmx.h" +#endif + +CTvSubtitle::CTvSubtitle() +{ + mpObser = NULL; +} + +CTvSubtitle::~CTvSubtitle() +{ +} + +void CTvSubtitle::setObserver(IObserver *pObser) +{ + isSubOpen = false; + mpObser = pObser; +} + +void CTvSubtitle::setBuffer(char *share_mem) +{ + pthread_mutex_lock(&lock); + buffer = (unsigned char *)share_mem; + pthread_mutex_unlock(&lock); +} + +void CTvSubtitle::stopDecoder() +{ +} + +void CTvSubtitle::startSub() +{ +} + +void CTvSubtitle::stop() +{ +} + +void CTvSubtitle::clear() +{ +} + +void CTvSubtitle::nextPage() +{ +} + +void CTvSubtitle::previousPage() +{ +} + +void CTvSubtitle::gotoPage(int page __unused) +{ +} + +void CTvSubtitle::goHome() +{ +} + +void CTvSubtitle::colorLink(int color __unused) +{ +} + +void CTvSubtitle::setSearchPattern(char *pattern __unused, bool casefold __unused) +{ +} + +void CTvSubtitle::searchNext() +{ +} + +void CTvSubtitle::searchPrevious() +{ +} + +int CTvSubtitle::sub_init(int bmp_width, int bmp_height) +{ + pthread_mutex_init(&lock, NULL); + bmp_w = bmp_width; + bmp_h = bmp_height; + sub_w = 720; + sub_h = 576; + bmp_pitch = bmp_w * 4; + return 0; +} + +int CTvSubtitle::sub_destroy() +{ + return 0; +} + +int CTvSubtitle::sub_lock() +{ + pthread_mutex_lock(&lock); + return 0; +} + +int CTvSubtitle::sub_unlock() +{ + pthread_mutex_unlock(&lock); + return 0; +} + +int CTvSubtitle::sub_clear() +{ + return 0; +} + +static void clear_bitmap(CTvSubtitle *pSub) +{ + unsigned char *ptr = pSub->buffer; + int y = pSub->bmp_h; + + while (y--) { + memset(ptr, 0, pSub->bmp_pitch); + ptr += pSub->bmp_pitch; + } +} + +#ifdef SUPPORT_ADTV +static void show_sub_cb(void * handle, AM_SUB2_Picture_t *pic) +{ + LOGD("dvb callback-----------"); + + CTvSubtitle *pSub = ((CTvSubtitle *) AM_SUB2_GetUserData(handle)); + pthread_mutex_lock(&pSub->lock); + clear_bitmap(pSub); + + if (pic) { + AM_SUB2_Region_t *rgn = pic->p_region; + pSub->sub_w = pic->original_width; + pSub->sub_h = pic->original_height; + while (rgn) { + int sx, sy, dx, dy, rw, rh; + + // ensure we have a valid buffer + if (! rgn->p_buf) { + rgn = rgn->p_next; + continue; + } + + sx = 0; + sy = 0; + dx = pic->original_x + rgn->left; + dy = pic->original_y + rgn->top; + rw = rgn->width; + rh = rgn->height; + + if (dx < 0) { + sx = -dx; + dx = 0; + rw += dx; + } + + if (dx + rw > pSub->bmp_w) { + rw = pSub->bmp_w - dx; + } + + if (dy < 0) { + sy = -dy; + dy = 0; + rh += dy; + } + + if (dy + rh > pSub->bmp_h) { + rh = pSub->bmp_h - dy; + } + + if ((rw > 0) && (rh > 0)) { + unsigned char *sbegin = (unsigned char *)rgn->p_buf + sy * rgn->width + sx; + unsigned char *dbegin = pSub->buffer + dy * pSub->bmp_pitch + dx * 4; + unsigned char *src, *dst; + int size; + + while (rh) { + src = sbegin; + dst = dbegin; + size = rw; + while (size--) { + int c = src[0]; + + if (c < (int)rgn->entry) { + if (rgn->clut[c].a) { + *dst++ = rgn->clut[c].r; + *dst++ = rgn->clut[c].g; + *dst++ = rgn->clut[c].b; + } else { + dst += 3; + } + *dst++ = rgn->clut[c].a; + } else { + dst += 4; + } + src ++; + } + sbegin += rgn->width; + dbegin += pSub->bmp_pitch; + rh--; + } + } + + rgn = rgn->p_next; + } + pSub->mpObser->updateSubtitle(pic->original_width, pic->original_height); + } + pthread_mutex_unlock(&pSub->lock); + +} +#endif + +static uint64_t get_pts_cb(void *handle __unused, uint64_t pts __unused) +{ +#ifdef SUPPORT_ADTV + char buf[32]; + AM_ErrorCode_t ret; + uint32_t v; + uint64_t r; + + ret = AM_FileRead("/sys/class/tsync/pts_pcrscr", buf, sizeof(buf)); + if (!ret) { + v = strtoul(buf, 0, 16); + if (pts & (1LL << 32)) { + r = ((uint64_t)v) | (1LL << 32); + } else { + r = (uint64_t)v; + } + } else { + r = 0LL; + } + + return r; +#else + return -1; +#endif +} + +static void pes_data_cb(int dev_no __unused, int fhandle __unused, + const uint8_t *data, int len, void *user_data) +{ +#ifdef SUPPORT_ADTV + CTvSubtitle *pSub = ((CTvSubtitle *) user_data); + AM_PES_Decode(pSub->pes_handle, (uint8_t *)data, len); +#endif +} + +static int close_dmx(CTvSubtitle *pSub) +{ +#ifdef SUPPORT_ADTV + AM_DMX_FreeFilter(pSub->dmx_id, pSub->filter_handle); + AM_DMX_Close(pSub->dmx_id); + pSub->dmx_id = -1; + pSub->filter_handle = -1; +#endif + return 0; +} + +static int open_dmx(CTvSubtitle *pSub, int dmx_id, int pid) +{ +#ifdef SUPPORT_ADTV + close_dmx(pSub); + AM_DMX_OpenPara_t op; + struct dmx_pes_filter_params pesp; + AM_ErrorCode_t ret; + + pSub->dmx_id = -1; + pSub->filter_handle = -1; + memset(&op, 0, sizeof(op)); + + ret = AM_DMX_Open(dmx_id, &op); + if (ret != DVB_SUCCESS) { + LOGD("error AM_DMX_Open != DVB_SUCCESS"); + goto error; + } + pSub->dmx_id = dmx_id; + + ret = AM_DMX_AllocateFilter(dmx_id, &pSub->filter_handle); + if (ret != DVB_SUCCESS) { + LOGD("error AM_DMX_AllocateFilter != DVB_SUCCESS"); + goto error; + } + + ret = AM_DMX_SetBufferSize(dmx_id, pSub->filter_handle, 0x80000); + if (ret != DVB_SUCCESS) { + LOGD("error AM_DMX_SetBufferSize != DVB_SUCCESS"); + goto error; + } + + memset(&pesp, 0, sizeof(pesp)); + pesp.pid = pid; + pesp.output = DMX_OUT_TAP; + pesp.pes_type = DMX_PES_TELETEXT0; + + ret = AM_DMX_SetPesFilter(dmx_id, pSub->filter_handle, &pesp); + if (ret != DVB_SUCCESS) { + LOGD("error AM_DMX_SetPesFilter != DVB_SUCCESS, err = %s", strerror(errno)); + goto error; + } + + ret = AM_DMX_SetCallback(dmx_id, pSub->filter_handle, pes_data_cb, pSub); + if (ret != DVB_SUCCESS) { + LOGD("error AM_DMX_SetCallback != DVB_SUCCESS"); + goto error; + } + + ret = AM_DMX_StartFilter(dmx_id, pSub->filter_handle); + if (ret != DVB_SUCCESS) { + LOGD("error AM_DMX_StartFilter != DVB_SUCCESS,dmx_id=%d,filter_handle=%d, ret = %d", dmx_id, pSub->filter_handle, ret); + goto error; + } + + return 0; +error: + if (pSub->filter_handle != -1) { + AM_DMX_FreeFilter(dmx_id, pSub->filter_handle); + } + if (pSub->dmx_id != -1) { + AM_DMX_Close(dmx_id); + } +#endif + return -1; +} + +static void pes_sub_cb(void* handle, uint8_t *buf, int size) +{ +#ifdef SUPPORT_ADTV + CTvSubtitle *pSub = ((CTvSubtitle *) AM_SUB2_GetUserData(handle)); + AM_SUB2_Decode(pSub->sub_handle, buf, size); +#endif +} + +int CTvSubtitle::sub_switch_status() +{ + return isSubOpen ? 1 : 0; +} + +int CTvSubtitle::sub_start_dvb_sub(int dmx_id, int pid, int page_id, int anc_page_id) +{ + LOGD("start dvb subtitle=----------------"); +#ifdef SUPPORT_ADTV + AM_PES_Para_t pesp; + AM_SUB2_Para_t subp; + int ret; + + memset(&pesp, 0, sizeof(pesp)); + pesp.packet = pes_sub_cb; + pesp.user_data = this; + ret = AM_PES_Create(&pes_handle, &pesp); + if (ret != DVB_SUCCESS) { + LOGD("error AM_PES_Create != DVB_SUCCESS"); + goto error; + } + + memset(&subp, 0, sizeof(subp)); + subp.show = show_sub_cb; + subp.get_pts = get_pts_cb; + subp.composition_id = page_id; + subp.ancillary_id = anc_page_id; + subp.user_data = this; + ret = AM_SUB2_Create(&sub_handle, &subp); + if (ret != DVB_SUCCESS) { + LOGD("error AM_SUB2_Create != DVB_SUCCESS"); + goto error; + } + + ret = AM_SUB2_Start(sub_handle); + if (ret != DVB_SUCCESS) { + LOGD("error AM_SUB2_Start != DVB_SUCCESS"); + goto error; + } + + ret = open_dmx(this, dmx_id, pid); + if (ret < 0) { + LOGD("error open_dmx != DVB_SUCCESS"); + goto error; + } + isSubOpen = true; + return 0; +error: + if (sub_handle) { + AM_SUB2_Destroy(sub_handle); + sub_handle = NULL; + } + if (pes_handle) { + AM_PES_Destroy(pes_handle); + pes_handle = NULL; + } +#endif + return -1; +} + +int CTvSubtitle::sub_start_dtv_tt(int dmx_id __unused, int region_id __unused, int pid __unused, + int page __unused, int sub_page __unused, bool is_sub __unused) +{ + return 0; +} + +int CTvSubtitle::sub_stop_dvb_sub() +{ +#ifdef SUPPORT_ADTV + pthread_mutex_lock(&lock); + close_dmx(this); + AM_SUB2_Destroy(sub_handle); + AM_PES_Destroy(pes_handle); + + clear_bitmap(this); + mpObser->updateSubtitle(0, 0); + + sub_handle = NULL; + pes_handle = NULL; + isSubOpen = false; + pthread_mutex_unlock(&lock); +#endif + return 0; +} + +int CTvSubtitle::sub_stop_dtv_tt() +{ + return 0; +} + +int CTvSubtitle::sub_tt_goto(int page __unused) +{ + return 0; +} + +int CTvSubtitle::sub_tt_color_link(int color __unused) +{ + return 0; +} + +int CTvSubtitle::sub_tt_home_link() +{ + return 0; +} + +int CTvSubtitle::sub_tt_next(int dir __unused) +{ + return 0; +} + +int CTvSubtitle::sub_tt_set_search_pattern(char *pattern __unused, bool casefold __unused) +{ + return 0; +} + +int CTvSubtitle::sub_tt_search(int dir __unused) +{ + return 0; +} + +/* + * 1, Set the country first and parameters should be either USA or KOREA +#define CMD_SET_COUNTRY_USA 0x5001 +#define CMD_SET_COUNTRY_KOREA 0x5002 + +2, Set the source type which including + a)VBI data(for analog program only) + b)USER data(for AIR or Cable service) +CMD_CC_SET_VBIDATA = 0x7001, +CMD_CC_SET_USERDATA = 0x7002, +2.1 If the frontend type is Analog we must set the channel Index + with command 'CMD_CC_SET_CHAN_NUM' and the parameter is like 57M + we set 0x20000, this should according to USA standard frequency + table. + +3, Next is to set the CC service type + +#define CMD_CC_1 0x3001 +#define CMD_CC_2 0x3002 +#define CMD_CC_3 0x3003 +#define CMD_CC_4 0x3004 + +//this doesn't support currently +#define CMD_TT_1 0x3005 +#define CMD_TT_2 0x3006 +#define CMD_TT_3 0x3007 +#define CMD_TT_4 0x3008 + +#define CMD_SERVICE_1 0x4001 +#define CMD_SERVICE_2 0x4002 +#define CMD_SERVICE_3 0x4003 +#define CMD_SERVICE_4 0x4004 +#define CMD_SERVICE_5 0x4005 +#define CMD_SERVICE_6 0x4006 + +4, Then set CMD_CC_START to start the CC service, and you needn't to stop + +CC service while switching services + +5, CMD_CC_STOP should be called in some cases like switch source, change + +program, no signal, blocked...*/ + +//channel_num == 0 ,if frontend is dtv +//else != 0 +int CTvSubtitle::sub_start_atsc_cc(enum cc_param_country country, enum cc_param_source_type src_type, int channel_num, enum cc_param_caption_type caption_type) +{ +/* + LOGD("----sub_start_atsc_cc-1--- country=%d,src=%d,ctype=%d", country, src_type, caption_type); + switch (country) { + case CC_PARAM_COUNTRY_USA: + AM_CC_Cmd(CMD_SET_COUNTRY_USA); + break; + case CC_PARAM_COUNTRY_KOREA: + AM_CC_Cmd(CMD_SET_COUNTRY_KOREA); + break; + default: + AM_CC_Cmd(CMD_SET_COUNTRY_USA); + break; + } + + switch (src_type) { + case CC_PARAM_SOURCE_VBIDATA: + AM_CC_Cmd(CMD_CC_SET_VBIDATA); + break; + case CC_PARAM_SOURCE_USERDATA: + AM_CC_Cmd(CMD_CC_SET_USERDATA); + break; + default: + AM_CC_Cmd(CMD_CC_SET_USERDATA); + break; + } + + //just for test + if (channel_num == 0) { + } else { + //AM_CC_Cmd(CMD_CC_SET_CHAN_NUM); + } + + AM_CLOSECAPTION_cmd_t cc_t_cmd; + switch (caption_type) { + case CC_PARAM_ANALOG_CAPTION_TYPE_CC1: + cc_t_cmd = CMD_CC_1; + break; + case CC_PARAM_ANALOG_CAPTION_TYPE_CC2: + cc_t_cmd = CMD_CC_2; + break; + case CC_PARAM_ANALOG_CAPTION_TYPE_CC3: + cc_t_cmd = CMD_CC_3; + break; + case CC_PARAM_ANALOG_CAPTION_TYPE_CC4: + cc_t_cmd = CMD_CC_4; + break; + case CC_PARAM_DIGITAL_CAPTION_TYPE_SERVICE1: + cc_t_cmd = CMD_SERVICE_1; + break; + case CC_PARAM_DIGITAL_CAPTION_TYPE_SERVICE2: + cc_t_cmd = CMD_SERVICE_2; + break; + case CC_PARAM_DIGITAL_CAPTION_TYPE_SERVICE3: + cc_t_cmd = CMD_SERVICE_3; + break; + case CC_PARAM_DIGITAL_CAPTION_TYPE_SERVICE4: + cc_t_cmd = CMD_SERVICE_4; + break; + default: + cc_t_cmd = CMD_SERVICE_1; + break; + } + AM_CC_Cmd(cc_t_cmd); + + AM_CC_Set_CallBack(close_caption_callback, this); + AM_VCHIP_Set_CallBack(atv_vchip_callback, this); + //start + AM_CC_Cmd(CMD_CC_START); + LOGD("----sub_start_atsc_cc-2--- country=%d,src=%d,ctype=%d", country, src_type, caption_type); +*/ + return 0; +} + +int CTvSubtitle::sub_stop_atsc_cc() +{ +/* + LOGD("----sub_stop_atsc_cc----"); + AM_CC_Cmd(CMD_CC_STOP); +*/ + return 0; +} + +int CTvSubtitle::ResetVchipChgStat() +{ +/* + avchip_chg = 0; + AM_CC_Cmd(CMD_VCHIP_RST_CHGSTAT); +*/ + return 0; +} + +int CTvSubtitle::IsVchipChange() +{ + return avchip_chg; +} + +//cnt :data buf len +//databuf len is max 512 +//cmdbuf len is max 128 +void CTvSubtitle::close_caption_callback(char *str, int cnt, int data_buf[], int cmd_buf[], void *user_data) +{ + /* + CTvSubtitle *pSub = (CTvSubtitle *)user_data; + + if (pSub == NULL) + { + LOGD("sub cc callback is null user data for this"); + return; + } + + if (pSub->mpObser == NULL) return; + + pSub->mCurCCEv.mDataBufSize = cnt; + pSub->mCurCCEv.mpDataBuffer = data_buf; + pSub->mCurCCEv.mCmdBufSize = 128;//max + pSub->mCurCCEv.mpCmdBuffer = cmd_buf; + + pSub->mpObser->onEvent(pSub->mCurCCEv); + */ + //TODO + UNUSED(str); + UNUSED(cnt); + UNUSED(data_buf); + UNUSED(cmd_buf); + UNUSED(user_data); +} + +void CTvSubtitle::atv_vchip_callback(int Is_chg, void *user_data) +{ + CTvSubtitle *pSub = (CTvSubtitle *)user_data; + pSub->avchip_chg = Is_chg; +} + diff --git a/tv/tvserver/libtv/tv/CTvSubtitle.h b/tv/tvserver/libtv/tv/CTvSubtitle.h new file mode 100644 index 0000000..2fb97c9 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvSubtitle.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CTVSUBTITLE_H) +#define _CTVSUBTITLE_H +#include <stdlib.h> +#include <CTvLog.h> +//using namespace android; + +#ifdef SUPPORT_ADTV +#include "am_cc.h" +#include "am_sub2.h" +#include "am_pes.h" +#endif +#include "CTvEv.h" + +enum cc_param_country { + CC_PARAM_COUNTRY_USA = 0, + CC_PARAM_COUNTRY_KOREA, +}; + +enum cc_param_source_type { + CC_PARAM_SOURCE_VBIDATA = 0, + CC_PARAM_SOURCE_USERDATA, +}; + +enum cc_param_caption_type { + CC_PARAM_ANALOG_CAPTION_TYPE_CC1 = 0, + CC_PARAM_ANALOG_CAPTION_TYPE_CC2, + CC_PARAM_ANALOG_CAPTION_TYPE_CC3, + CC_PARAM_ANALOG_CAPTION_TYPE_CC4, + CC_PARAM_ANALOG_CAPTION_TYPE_TEXT1, + CC_PARAM_ANALOG_CAPTION_TYPE_TEXT2, + CC_PARAM_ANALOG_CAPTION_TYPE_TEXT3, + CC_PARAM_ANALOG_CAPTION_TYPE_TEXT4, + // + CC_PARAM_DIGITAL_CAPTION_TYPE_SERVICE1, + CC_PARAM_DIGITAL_CAPTION_TYPE_SERVICE2, + CC_PARAM_DIGITAL_CAPTION_TYPE_SERVICE3, + CC_PARAM_DIGITAL_CAPTION_TYPE_SERVICE4, + CC_PARAM_DIGITAL_CAPTION_TYPE_SERVICE5, + CC_PARAM_DIGITAL_CAPTION_TYPE_SERVICE6, +}; + +class CTvSubtitle { +public: + class IObserver { + public: + IObserver() {}; + virtual ~IObserver() {}; + //virtual void onEvent(const CloseCaptionEvent &ev); + virtual void updateSubtitle(int, int) {}; + }; + void* sub_handle; + void* pes_handle; + + int dmx_id; + int filter_handle; + int bmp_w; + int bmp_h; + int bmp_pitch; + unsigned char *buffer; + int sub_w; + int sub_h; + pthread_mutex_t lock; + + IObserver *mpObser; + CTvSubtitle(); + ~CTvSubtitle(); + + class CloseCaptionEvent: public CTvEv { + public: + //static const int CC_CMD_LEN = 128; + //static const int CC_DATA_LEN = 512; + CloseCaptionEvent(): CTvEv(CTvEv::TV_EVENT_CC) + { + } + ~CloseCaptionEvent() + { + } + public: + int mCmdBufSize; + int *mpCmdBuffer; + int mDataBufSize; + int *mpDataBuffer; + }; + + void setObserver(IObserver *pObser); + void setBuffer(char *share_mem); + void stopDecoder(); + void startSub(); + void stop(); + void clear(); + void nextPage(); + void previousPage(); + void gotoPage(int page); + void goHome(); + void colorLink(int color); + void setSearchPattern(char *pattern, bool casefold); + void searchNext(); + void searchPrevious(); + + int sub_init(int, int); + // + int sub_destroy(); + // + int sub_lock(); + // + int sub_unlock(); + // + int sub_clear(); + // + int sub_switch_status(); + int sub_start_dvb_sub(int dmx_id, int pid, int page_id, int anc_page_id); + // + int sub_start_dtv_tt(int dmx_id, int region_id, int pid, int page, int sub_page, bool is_sub); + // + int sub_stop_dvb_sub(); + // + int sub_stop_dtv_tt(); + // + int sub_tt_goto(int page); + // + int sub_tt_color_link(int color); + // + int sub_tt_home_link(); + // + int sub_tt_next(int dir); + // + int sub_tt_set_search_pattern(char *pattern, bool casefold); + // + int sub_tt_search(int dir); + // + int sub_start_atsc_cc(enum cc_param_country country, enum cc_param_source_type src_type, int channel_num, enum cc_param_caption_type caption_type); + // + int sub_stop_atsc_cc(); + static void close_caption_callback(char *str, int cnt, int data_buf[], int cmd_buf[], void *user_data); + static void atv_vchip_callback(int Is_chg, void *user_data); + int IsVchipChange(); + int ResetVchipChgStat(); +private: + + struct DVBSubParams { + int mDmx_id; + int mPid; + int mComposition_page_id; + int mAncillary_page_id; + + DVBSubParams() + { + } + DVBSubParams(int dmx_id, int pid, int page_id, int anc_page_id) + { + mDmx_id = dmx_id; + mPid = pid; + mComposition_page_id = page_id; + mAncillary_page_id = anc_page_id; + } + }; + + struct DTVTTParams { + int mDmx_id; + int mPid; + int mPage_no; + int mSub_page_no; + int mRegion_id; + + DTVTTParams() + { + } + DTVTTParams(int dmx_id, int pid, int page_no, int sub_page_no, int region_id) + { + mDmx_id = dmx_id; + mPid = pid; + mPage_no = page_no; + mSub_page_no = sub_page_no; + mRegion_id = region_id; + } + }; + + int mSubType; + CloseCaptionEvent mCurCCEv; + int avchip_chg; + bool isSubOpen; +}; +#endif //_CTVSUBTITLE_H diff --git a/tv/tvserver/libtv/tv/CTvTime.cpp b/tv/tvserver/libtv/tv/CTvTime.cpp new file mode 100644 index 0000000..ec14418 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvTime.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvTime" + +#include "CTvTime.h" +#include <CTvLog.h> + +long CTvTime::getSysUTCTime() +{ + //struct tm tm; + //time_t t; + //int64_t r = mktime_tz(&(tm), NULL); + //time_t t = time(NULL); + //LOGD("---------utc t = %ld time t=%ld", r, t); + return 0; +} + +void CTvTime::setTime(long t) +{ + //long utcMS; + //time(&utcMS); + //nsecs_t ns = systemTime(CLOCK_REALTIME); + //nsecs_t tm = ns2s(ns); + //unsigned long ticks = times(NULL); + //long tm = ticks/mHZ; + struct sysinfo s_info; + int error; + error = sysinfo(&s_info); + + mDiff = t - s_info.uptime; + LOGD("--- mDiff=%ld", mDiff); +} + +long CTvTime::getTime() +{ + //long utcMS; + //time(&utcMS); + //nsecs_t ns = systemTime(CLOCK_REALTIME); + //nsecs_t sec = ns2s(ns); + + //unsigned long ticks = times(NULL); + //long sec = ticks/mHZ; + struct sysinfo s_info; + int error; + error = sysinfo(&s_info); + + + LOGD("--- mDiff=%ld, sec=%ld", mDiff, s_info.uptime); + return s_info.uptime + mDiff; +} diff --git a/tv/tvserver/libtv/tv/CTvTime.h b/tv/tvserver/libtv/tv/CTvTime.h new file mode 100644 index 0000000..cac7b25 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvTime.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file +*/ + +#ifndef _C_TV_TIME_H_ +#define _C_TV_TIME_H_ + +#include <utils/Timers.h> +#include <time.h> +#include <sys/times.h> +#include <sys/sysinfo.h> + +class CTvTime { +public: + CTvTime() { + mDiff = 0; + mHZ = sysconf( _SC_CLK_TCK ); + } + + long getSysUTCTime(); + void setTime(long t); + long getTime(); + long getDiffTime() { + return mDiff; + } + + void setDiffTime(long diff) { + mDiff = diff; + } + +private: + long mDiff; + unsigned long mHZ; +}; +#endif/*_C_TV_TIME_H_*/ + diff --git a/tv/tvserver/libtv/tv/CTvVchipCheck.cpp b/tv/tvserver/libtv/tv/CTvVchipCheck.cpp new file mode 100644 index 0000000..8889f7f --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvVchipCheck.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvVchipCheck" + +#include "CTvVchipCheck.h" +CTvVchipCheck:: CTvVchipCheck() +{ +} + +CTvVchipCheck:: ~CTvVchipCheck() +{ +} + +bool CTvVchipCheck::CheckProgramBlock(int id) +{ + bool lock = false; + CTvProgram prog; + CTvEvent ev; + int ret = 0; + + ret = CTvProgram::selectByID(id, prog); + if (ret != 0) return false; + + int type = prog.getProgType(); + + if (type == CTvProgram::TYPE_ATV) { + ret = ev.getATVProgEvent(prog.getSrc(), prog.getID(), ev); + } else { + //long epgtime = mDmTime.getTime(); + //ret = ev.getProgPresentEvent(prog.getSrc(),prog.getSourceId(), epgtime, ev); + } + if (ret == 0) { + if (prog.isATSCMode()) { + // ATSC V-Chip + Vector<CTvDimension::VChipRating *> definedRatings = ev.getVChipRatings(); + for (int i = 0; i < (int)definedRatings.size(); i++) { + CTvDimension dm; + if (dm.isBlocked(dm, definedRatings[i])) { + lock = true; + { + /*CurvchipDimension = dm.getName(); + CurvchipAbbrev = dm.getAbbrev(definedRatings[i]->getValue()); + CurvchipText= dm.getText(definedRatings[i]->getValue()); + LOGD("%s, %d Dimension:%s, Abbrev: %s, idx:%d","TV",__LINE__,CurvchipDimension.string(), + CurvchipAbbrev.string(),definedRatings[i]->getValue());*/ + } + break; + } + } + } + } else { + LOGD("Present event of playing program not received yet, will unblock this program."); + } + + return lock; +} + +void *CTvVchipCheck::VchipCheckingThread (void *arg __unused) +{ + /*CTv *pt = static_cast<CTv *> ( arg ); + + if ( !pt->IsVchipEnable() ) { + return NULL; + } + + while ( pt->mvchip_running ) { + bool lock = 0; + String8 curdm; + String8 curabbrev; + tvin_info_t siginfo = pt->Tv_GetCurrentSignalInfo(); + + //if ( TVIN_SIG_STATUS_STABLE == siginfo.status ) { + lock = pt->mTvVchip.CheckProgramBlock ( pt->getDTVProgramID() ); + curdm = pt->mTvVchip.getCurdimension(); + curabbrev = pt->mTvVchip.getCurAbbr(); + + if ( ( lock != pt->mlastlockstatus ) || ( pt->mlastdm != curdm ) || ( pt->mlastabbrev != curabbrev ) ) { + pt->mlastlockstatus = lock; + pt->mlastdm = curdm; + pt->mlastabbrev = curabbrev; + BlockEvent evt; + + if ( lock ) { + evt.programBlockType = 0; + evt.block_status = 1; + evt.vchipDimension = curdm; + evt.vchipAbbrev = curdm; + LOGD ( "%s, %d block the program by type %s, %s", "TV", __LINE__, curdm.string(), curabbrev.string() ); + } else { + LOGD ( "unblock the program" ); + evt.programBlockType = 0; + evt.block_status = 0; + } + + pt->sendTvEvent ( evt ); + pt->Programblock ( lock ); + } + + usleep ( 1000 * 1000 ); + //} else { + //usleep ( 500 * 1000 ); + //} + }*/ + + return NULL; +} + +int CTvVchipCheck::stopVChipCheck() +{ + AutoMutex _l( mLock ); + LOGD ( "stopVChipCheck() and exit thread" ); + requestExit(); + return 0; +} + +int CTvVchipCheck::pauseVChipCheck() +{ + AutoMutex _l( mLock ); + LOGD ( "pauseVChipCheck() set request pause flag, when flag true, thread loop go pause on condition" ); + m_request_pause_detect = true; + return 0; +} + +int CTvVchipCheck::requestAndWaitPauseVChipCheck() +{ + AutoMutex _l( mLock ); + LOGD ( "requestAndWaitPauseVChipCheck(),first set pause flag to true, and wait when loop run to pause code segment" ); + m_request_pause_detect = true; + + if ( mDetectState == STATE_RUNNING ) { + mRequestPauseCondition.wait ( mLock ); + } + + return 0; +} + +int CTvVchipCheck::resumeVChipCheck() +{ + AutoMutex _l( mLock ); + LOGD ( "resumeVChipCheck() first set flag false, and signal to paused condition, let run loop" ); + m_request_pause_detect = false; + mDetectPauseCondition.signal(); + return 0; +} + +bool CTvVchipCheck::threadLoop() +{ + while ( !exitPending() ) { //requietexit() or requietexitWait() not call + while ( m_request_pause_detect ) { + mRequestPauseCondition.broadcast(); + mLock.lock(); + mDetectState = STATE_PAUSE; + mDetectPauseCondition.wait ( mLock ); //first unlock,when return,lock again,so need,call unlock + mDetectState = STATE_RUNNING; + mLock.unlock(); + } + //loop codes + + if ( !m_request_pause_detect ) { //not request pause, sleep 1s which loop + usleep ( 1000 * 1000 ); + } + } + //exit + mDetectState = STATE_STOPED; + //return true, run again, return false,not run. + return false; +} diff --git a/tv/tvserver/libtv/tv/CTvVchipCheck.h b/tv/tvserver/libtv/tv/CTvVchipCheck.h new file mode 100644 index 0000000..512aea7 --- a/dev/null +++ b/tv/tvserver/libtv/tv/CTvVchipCheck.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CTVVCHIPCHECK_H) +#define _CTVVCHIPCHECK_H +#include <utils/Vector.h> +#include "CTvDatabase.h" +#include <utils/String8.h> +#include <stdlib.h> +#include "CTvDimension.h" +#include "CTvProgram.h" +#include "CTvTime.h" +#include "CTvEvent.h" +#include "CTvLog.h" +#include <utils/Thread.h> +// TV ATSC rating dimension +class CTvVchipCheck: public Thread { +public: + CTvVchipCheck(); + ~CTvVchipCheck(); + bool CheckProgramBlock(int id); + static void *VchipCheckingThread ( void *arg ); + int startVChipCheck(); + int stopVChipCheck(); + int pauseVChipCheck(); + int resumeVChipCheck(); + int requestAndWaitPauseVChipCheck(); +private: + bool threadLoop(); + mutable Mutex mLock; + Condition mDetectPauseCondition; + Condition mRequestPauseCondition; + volatile bool m_request_pause_detect; + enum DetectState { + STATE_STOPED = 0, + STATE_RUNNING, + STATE_PAUSE + }; + int mDetectState; +}; +#endif //_CTVDIMENSION_H diff --git a/tv/tvserver/libtv/tv/ScreenCatch.cpp b/tv/tvserver/libtv/tv/ScreenCatch.cpp new file mode 100644 index 0000000..dc69d20 --- a/dev/null +++ b/tv/tvserver/libtv/tv/ScreenCatch.cpp @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_NDEBUG 1 +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "ScreenCatch" + +#include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/MediaDefs.h> +#include <media/stagefright/MetaData.h> +#include <OMX_IVCommon.h> +#include <MetadataBufferType.h> + +#include <ui/GraphicBuffer.h> +#include <gui/ISurfaceComposer.h> +#include <gui/IGraphicBufferAlloc.h> +#include <OMX_Component.h> + +#include <CTvLog.h> +#include <utils/String8.h> + +#include <private/gui/ComposerService.h> + +#include <media/stagefright/ScreenCatch.h> +#include <media/stagefright/ScreenSource.h> + +#include <binder/IPCThreadState.h> +#include <binder/MemoryBase.h> +#include <binder/MemoryHeapBase.h> + +#include <stdio.h> +#include <assert.h> +#include <limits.h> +#include <unistd.h> +#include <fcntl.h> +#include <sched.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <binder/IServiceManager.h> + +#define BOUNDRY 32 + +#define ALIGN(x) (x + (BOUNDRY) - 1)& ~((BOUNDRY) - 1) + +namespace android { + + struct ScreenCatch::ScreenCatchClient : public BnScreenMediaSourceClient { + ScreenCatchClient(void *user) + { + mUser = user; + LOGE("[%s %d] user:%x", __FUNCTION__, __LINE__, user); + } + + virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) + { + LOGI("notify %d, %d, %d", msg, ext1, ext2); + } + + virtual int dataCallback(const sp<IMemory> &data) + { + return 0; + } + + protected: + void *mUser; + virtual ~ScreenCatchClient() {} + + private: + DISALLOW_EVIL_CONSTRUCTORS(ScreenCatchClient); + }; + + ScreenCatch::ScreenCatch(uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bitSize) : + mWidth(ALIGN(bufferWidth)), + mHeight(bufferHeight), + mScreenMediaSourceService(NULL), + mColorFormat(OMX_COLOR_Format32bitARGB8888), + mBitSize(bitSize) + { + LOGE("ScreenCatch: %dx%d", bufferWidth, bufferHeight); + + if (bufferWidth <= 0 || bufferHeight <= 0 || bufferWidth > 1920 || bufferHeight > 1080) { + LOGE("Invalid dimensions %dx%d", bufferWidth, bufferHeight); + } + + if (bitSize != 24 || bitSize != 32) + bitSize = 32; + + mCorpX = -1; + mCorpY = -1; + mCorpWidth = -1; + mCorpHeight = -1; + + } + + ScreenCatch::~ScreenCatch() + { + LOGE("~ScreenCatch"); + } + + void ScreenCatch::setVideoRotation(int degree) + { + int angle; + + LOGI("[%s %d] setVideoRotation degree:%x", __FUNCTION__, __LINE__, degree); + + } + + void ScreenCatch::setVideoCrop(int x, int y, int width, int height) + { + mCorpX = x; + mCorpY = y; + mCorpWidth = width; + mCorpHeight = height; + } + + static inline void yuv_to_rgb32(unsigned char y, unsigned char u, unsigned char v, unsigned char *rgb) + { + register int r, g, b; + + r = (1192 * (y - 16) + 1634 * (v - 128) ) >> 10; + g = (1192 * (y - 16) - 833 * (v - 128) - 400 * (u - 128) ) >> 10; + b = (1192 * (y - 16) + 2066 * (u - 128) ) >> 10; + + r = r > 255 ? 255 : r < 0 ? 0 : r; + g = g > 255 ? 255 : g < 0 ? 0 : g; + b = b > 255 ? 255 : b < 0 ? 0 : b; + + /*ARGB*/ + *rgb = (unsigned char)r; + rgb++; + *rgb = (unsigned char)g; + rgb++; + *rgb = (unsigned char)b; + rgb++; + *rgb = 0xff; + + } + + void nv21_to_rgb32(unsigned char *buf, unsigned char *rgb, int width, int height) + { + int x, y, z = 0; + int h, w; + int blocks; + unsigned char Y1, Y2, U, V; + + blocks = (width * height) * 2; + + for (h = 0, z = 0; h < height; h += 2) { + for (y = 0; y < width * 2; y += 2) { + + Y1 = buf[ h * width + y + 0]; + V = buf[ blocks / 2 + h * width / 2 + y % width + 0 ]; + Y2 = buf[ h * width + y + 1]; + U = buf[ blocks / 2 + h * width / 2 + y % width + 1 ]; + + yuv_to_rgb32(Y1, U, V, &rgb[z]); + yuv_to_rgb32(Y2, U, V, &rgb[z + 4]); + z += 8; + } + } + } + + static inline void yuv_to_rgb24(unsigned char y, unsigned char u, unsigned char v, unsigned char *rgb) + { + register int r, g, b; + + r = (1192 * (y - 16) + 1634 * (v - 128) ) >> 10; + g = (1192 * (y - 16) - 833 * (v - 128) - 400 * (u - 128) ) >> 10; + b = (1192 * (y - 16) + 2066 * (u - 128) ) >> 10; + + r = r > 255 ? 255 : r < 0 ? 0 : r; + g = g > 255 ? 255 : g < 0 ? 0 : g; + b = b > 255 ? 255 : b < 0 ? 0 : b; + + /*ARGB*/ + *rgb = (unsigned char)r; + rgb++; + *rgb = (unsigned char)g; + rgb++; + *rgb = (unsigned char)b; + } + + void nv21_to_rgb24(unsigned char *buf, unsigned char *rgb, int width, int height) + { + int x, y, z = 0; + int h, w; + int blocks; + unsigned char Y1, Y2, U, V; + + blocks = (width * height) * 2; + + for (h = 0, z = 0; h < height; h += 2) { + for (y = 0; y < width * 2; y += 2) { + + Y1 = buf[ h * width + y + 0]; + V = buf[ blocks / 2 + h * width / 2 + y % width + 0 ]; + Y2 = buf[ h * width + y + 1]; + U = buf[ blocks / 2 + h * width / 2 + y % width + 1 ]; + + yuv_to_rgb24(Y1, U, V, &rgb[z]); + yuv_to_rgb24(Y2, U, V, &rgb[z + 3]); + z += 6; + } + } + } + + int ScreenCatch::threadFunc() + { + int64_t pts; + int status; + + sp<MemoryHeapBase> newMemoryHeap = new MemoryHeapBase(mWidth * mHeight * 3 / 2); + sp<MemoryBase> buffer = new MemoryBase(newMemoryHeap, 0, mWidth * mHeight * 3 / 2); + + LOGV("[%s %d] empty:%d", __FUNCTION__, __LINE__, mRawBufferQueue.empty()); + + while (mStart == true) { + + status = mScreenMediaSourceService->readBuffer(mClientId, buffer, &pts); + + if (status != OK && mStart == true) { + usleep(10000); + continue; + } + + if (mStart != true) + break; + + MediaBuffer *accessUnit; + + if (OMX_COLOR_Format24bitRGB888 == mColorFormat) { //rgb 24bit + accessUnit = new MediaBuffer(mWidth * mHeight * 3); + nv21_to_rgb24((unsigned char *)buffer->pointer(), (unsigned char *)accessUnit->data(), mWidth, mHeight); + accessUnit->set_range(0, mWidth * mHeight * 3); + } else if (OMX_COLOR_Format32bitARGB8888 == mColorFormat) { //rgba 32bit + accessUnit = new MediaBuffer(mWidth * mHeight * 4); + nv21_to_rgb32((unsigned char *)buffer->pointer(), (unsigned char *)accessUnit->data(), mWidth, mHeight); + accessUnit->set_range(0, mWidth * mHeight * 4); + } else if (OMX_COLOR_FormatYUV420SemiPlanar == mColorFormat) { //nv21 + accessUnit = new MediaBuffer(mWidth * mHeight * 3 / 2); + memcpy((unsigned char *)accessUnit->data(), (unsigned char *)buffer->pointer(), mWidth * mHeight * 3 / 2); + accessUnit->set_range(0, mWidth * mHeight * 3 / 2); + } + mRawBufferQueue.push_back(accessUnit); + } + + LOGE("[%s %d] thread out", __FUNCTION__, __LINE__); + + mThreadOutCondition.signal(); + + return 0; + } + + void *ScreenCatch::ThreadWrapper(void *me) + { + + ScreenCatch *Convertor = static_cast<ScreenCatch *>(me); + Convertor->threadFunc(); + return NULL; + } + + status_t ScreenCatch::start(MetaData *params) + { + LOGE("[%s %d] mWidth:%d mHeight:%d", __FUNCTION__, __LINE__, mWidth, mHeight); + AutoMutex _l(mLock); + + status_t status; + int64_t pts; + int client_id; + + sp<IServiceManager> sm = defaultServiceManager(); + sp<IBinder> binder = sm->getService(String16("media.screenmediasource")); + mScreenMediaSourceService = interface_cast<IScreenMediaSource>(binder); + + sp<ScreenCatchClient> mIScreenSourceClient = new ScreenCatchClient(this); + + LOGE("[%s %d] mWidth:%d mHeight:%d", __FUNCTION__, __LINE__, mWidth, mHeight); + + mScreenMediaSourceService->registerClient(mIScreenSourceClient, mWidth, mHeight, 1, SCREENMEDIASOURC_RAWDATA_TYPE, &client_id, NULL); + + LOGE("[%s %d] client_id:%d", __FUNCTION__, __LINE__, client_id); + + mClientId = client_id; + + if (status != OK) { + LOGE("setResolutionRatio fail"); + return !OK; + } + + LOGV("[%s %d] mCorpX:%d mCorpY:%d mCorpWidth:%d mCorpHeight:%d", __FUNCTION__, __LINE__, mCorpX, mCorpY, mCorpWidth, mCorpHeight); + + if (mCorpX != -1) + mScreenMediaSourceService->setVideoCrop(client_id, mCorpX, mCorpY, mCorpWidth, mCorpHeight); + + + status = mScreenMediaSourceService->start(client_id); + + if (status != OK) { + mScreenMediaSourceService->unregisterClient(mClientId); + LOGE("ScreenMediaSourceService start fail"); + return !OK; + } + + if (!(params->findInt32(kKeyColorFormat, &mColorFormat) + && (mColorFormat != OMX_COLOR_FormatYUV420SemiPlanar + || mColorFormat != OMX_COLOR_Format24bitRGB888 + || mColorFormat != OMX_COLOR_Format32bitARGB8888))) + mColorFormat = OMX_COLOR_Format32bitARGB8888; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + pthread_create(&mThread, &attr, ThreadWrapper, this); + pthread_attr_destroy(&attr); + + mStart = true; + + LOGV("[%s %d]", __FUNCTION__, __LINE__); + return OK; + } + + status_t ScreenCatch::stop() + { + LOGV("[%s %d]", __FUNCTION__, __LINE__); + AutoMutex _l(mLock); + mStart = false; + + mThreadOutCondition.waitRelative(mLock, 1000000000000); + LOGV("[%s %d]", __FUNCTION__, __LINE__); + + while (!mRawBufferQueue.empty()) { + + LOGV("[%s %d] free buffer", __FUNCTION__, __LINE__); + + MediaBuffer *rawBuffer = *mRawBufferQueue.begin(); + mRawBufferQueue.erase(mRawBufferQueue.begin()); + rawBuffer->release(); + } + + mScreenMediaSourceService->stop(mClientId); + mScreenMediaSourceService->unregisterClient(mClientId); + + return OK; + } + + status_t ScreenCatch::read(MediaBuffer **buffer) + { + AutoMutex _l(mLock); + + if (!mRawBufferQueue.empty()) { + MediaBuffer *rawBuffer = *mRawBufferQueue.begin(); + mRawBufferQueue.erase(mRawBufferQueue.begin()); + *buffer = rawBuffer; + return OK; + } + + return !OK; + } + + status_t ScreenCatch::free(MediaBuffer *buffer) + { + AutoMutex _l(mLock); + buffer->release(); + return OK; + } + +} // end of namespace android diff --git a/tv/tvserver/libtv/tvdb/CTvChannel.cpp b/tv/tvserver/libtv/tvdb/CTvChannel.cpp new file mode 100644 index 0000000..4d9f1aa --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvChannel.cpp @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvChannel" + +#ifdef UNUSED +#elif defined(__GNUC__) +# define UNUSED(x) UNUSED_ ## x __attribute__((unused)) +#elif defined(__LCLINT__) +# define UNUSED(x) /*@unused@*/ x +#else +# define UNUSED(x) x +#endif + +#include "CTvChannel.h" + +void CTvChannel::createFromCursor(CTvDatabase::Cursor &c) +{ + int col; + int src, freq, mod, symb, bw, satid, satpolar; + + col = c.getColumnIndex("db_id"); + this->id = c.getInt(col); + + col = c.getColumnIndex("ts_id"); + this->dvbTSID = c.getInt(col); + + col = c.getColumnIndex("src"); + src = c.getInt(col); + + col = c.getColumnIndex("freq"); + freq = c.getInt(col); + + if (src == MODE_QAM) { + col = c.getColumnIndex("mod"); + mod = c.getInt(col); + + col = c.getColumnIndex("symb"); + symb = c.getInt(col); + + frequency = freq; + modulation = mod; + symbolRate = symb; + mode = MODE_QAM; + + } else if (src == MODE_OFDM) { + col = c.getColumnIndex("bw"); + bw = c.getInt(col); + + frequency = freq; + bandwidth = bw; + mode = MODE_OFDM; + + } else if (src == MODE_ATSC) { + col = c.getColumnIndex("mod"); + mod = c.getInt(col); + + frequency = freq; + modulation = mod; + mode = MODE_ATSC; + } else if (src == MODE_ANALOG) { + col = c.getColumnIndex("std"); + int std = c.getInt(col); + col = c.getColumnIndex("aud_mode"); + int aud_mode = c.getInt(col); + col = c.getColumnIndex("flags"); + int afc_flag = c.getInt(col); + + frequency = freq; + audio = aud_mode; + standard = std; + afc_data = afc_flag; + mode = MODE_ANALOG; + } else if (src == MODE_QPSK) { + col = c.getColumnIndex("symb"); + symb = c.getInt(col); + + col = c.getColumnIndex("db_sat_para_id"); + satid = c.getInt(col); + + col = c.getColumnIndex("polar"); + satpolar = c.getInt(col); + + frequency = freq; + symbolRate = symb; + sat_id = satid; + sat_polarisation = satpolar; + mode = MODE_QPSK; + + /*new tv_satparams*/ + //showboz + //TVSatellite sat = TVSatellite.tvSatelliteSelect(sat_id); + //tv_satparams = sat.getParams(); + } else if (src == MODE_DTMB) { + col = c.getColumnIndex("bw"); + bw = c.getInt(col); + + frequency = freq; + bandwidth = bw; + mode = MODE_DTMB; + } else if (src == MODE_ISDBT) { + col = c.getColumnIndex("bw"); + bw = c.getInt(col); + + frequency = freq; + bandwidth = bw; + mode = MODE_ISDBT; + } + + this->fendID = 0; +} + +CTvChannel::CTvChannel() +{ +} + +CTvChannel::CTvChannel(int dbID, int mode, int freq, int bw, int mod, int symb, int ofdm __unused, int channelNum) +{ + //other member not init,just a paras + if (mode == MODE_QAM) { + id = dbID; + frequency = freq; + modulation = mod; + symbolRate = symb; + this->mode = MODE_QAM; + logicalChannelNum = channelNum; + } else if (mode == MODE_OFDM) { + id = dbID; + frequency = freq; + bandwidth = bw; + this->mode = MODE_OFDM; + logicalChannelNum = channelNum; + } else if (mode == MODE_ATSC) { + id = dbID; + frequency = freq; + modulation = mod; + logicalChannelNum = channelNum; + this->mode = MODE_ATSC; + } else if (mode == MODE_ANALOG) { + id = dbID; + frequency = freq; + audio = 0; + standard = 0; + afc_data = 0; + logicalChannelNum = channelNum; + this->mode = MODE_ANALOG; + } else if (mode == MODE_DTMB) { + id = dbID; + frequency = freq; + bandwidth = bw; + mode = MODE_DTMB; + logicalChannelNum = channelNum; + } else if (mode == MODE_ISDBT) { + id = dbID; + frequency = freq; + bandwidth = bw; + mode = MODE_ISDBT; + logicalChannelNum = channelNum; + } +} + +CTvChannel::~CTvChannel() +{ +} + +CTvChannel::CTvChannel(const CTvChannel& channel) +{ + id = channel.id; + dvbTSID = channel.dvbTSID; + dvbOrigNetID = channel.dvbOrigNetID; + fendID = channel.fendID; + tsSourceID = channel.tsSourceID; + + mode = channel.mode; + frequency = channel.frequency; + symbolRate = channel.symbolRate; + modulation = channel.modulation; + bandwidth = channel.bandwidth; + audio = channel.audio; + standard = channel.standard; + afc_data = channel.afc_data; + sat_id = channel.sat_id; + logicalChannelNum = channel.logicalChannelNum; + sat_polarisation = channel.sat_polarisation; +} +//TODO +CTvChannel& CTvChannel::operator= (const CTvChannel& UNUSED(channel)) +{ + return *this; +} + +Vector<CTvChannel> CTvChannel::tvChannelList(int sat_id __unused) +{ + Vector<CTvChannel> v_channel; + return v_channel; +} + +int CTvChannel::selectByID(int cid, CTvChannel &channel) +{ + String8 cmd = String8("select * from ts_table where ts_table.db_id = ") + String8::format("%d", cid); + CTvDatabase::Cursor c; + CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + channel.createFromCursor(c); + } else { + c.close(); + return -1; + } + c.close(); + + return 0; +} + +int CTvChannel::SelectByFreq(int freq, CTvChannel &channel) +{ + String8 cmd ; + CTvDatabase::Cursor c; + int iOutRet = 0; + + do { + cmd = String8("select * from ts_table where ts_table.freq = ") + String8::format("%d", freq); + CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + channel.createFromCursor(c); + } else { + iOutRet = -1; + break; + } + + cmd = String8("delete from ts_table where ts_table.freq = ") + String8::format("%d", freq); + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + } while (false); + + c.close(); + return iOutRet; +} + +int CTvChannel::DeleteBetweenFreq(int beginFreq, int endFreq) +{ + String8 cmd ; + CTvDatabase::Cursor c; + int iOutRet = 0; + CTvChannel channel; + + do { + cmd = String8("select * from ts_table where ts_table.freq >= ") + String8::format("%d", beginFreq) + + String8("and ts_table.freq <= ") + String8::format("%d", endFreq); + CTvDatabase::GetTvDb()->select(cmd, c); + if (c.moveToFirst()) { + do { + channel.createFromCursor(c); + cmd = String8("delete from ts_table where ts_table.freq = ") + String8::format("%d", channel.frequency); + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + } while (c.moveToNext()); + } else { + iOutRet = -1; + break; + } + + } while (false); + + c.close(); + return iOutRet; +} + +int CTvChannel::CleanAllChannelBySrc(int src) +{ + String8 cmd = String8("delete from ts_table where src = ") + String8::format("%d", src); + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + return 0; +} + +int CTvChannel::getChannelListBySrc(int src, Vector< sp<CTvChannel> > &v_channel) +{ + CTvDatabase::Cursor c; + CTvChannel *channel; + do { + String8 cmd = String8("select * from ts_table where src = ") + String8::format("%d", src); + CTvDatabase::GetTvDb()->select(cmd, c); + if (c.moveToFirst()) { + do { + channel = new CTvChannel(); + channel->createFromCursor(c); + v_channel.add(channel); + } while (c.moveToNext()); + } else { + break; + } + } while (false); + + return 0; +} + +int CTvChannel::updateByID(int progID, int std, int freq, int fineFreq) +{ + + String8 cmd = String8("update ts_table set std = ") + String8::format("%d", std) + + String8(", freq = ") + String8::format("%d", freq) + + String8(", flags = ") + String8::format("%d", fineFreq) + + String8(" where ts_table.db_id = ") + String8::format("%d", progID); + LOGD("%s, cmd = %s\n", "TV", cmd.string()); + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + + return 0; +} + +void CTvChannel::tvChannelDel() +{ +} + +void CTvChannel::tvChannelDelBySatID(int id __unused) +{ +} + +int CTvChannel::getDVBTSID() +{ + return dvbTSID; +} + +void CTvChannel::getDVBOrigNetID() +{ +} + +void CTvChannel::getFrontendID() +{ +} + +void CTvChannel::getTSSourceID() +{ +} + +void CTvChannel::isDVBCMode() +{ +} + +void CTvChannel::setFrequency() +{ +} + +void CTvChannel::setSymbolRate() +{ +} + +void CTvChannel::setPolarisation() +{ +} + +void CTvChannel::setATVAudio() +{ +} + +void CTvChannel::setATVVideoFormat() +{ +} + +void CTvChannel::setATVAudioFormat() +{ +} + +void CTvChannel::setATVFreq() +{ +} + +void CTvChannel::setATVAfcData() +{ +} + diff --git a/tv/tvserver/libtv/tvdb/CTvChannel.h b/tv/tvserver/libtv/tvdb/CTvChannel.h new file mode 100644 index 0000000..f5f2785 --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvChannel.h @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CTVCHANNEL_H) +#define _CTVCHANNEL_H +#include <utils/Vector.h> +#include "CTvDatabase.h" +#include <utils/String8.h> +#include <utils/RefBase.h> +#include <stdlib.h> + +#include "CTvLog.h" +using namespace android; + +//must sync with dvb frontend.h +enum { + TV_FE_HAS_SIGNAL = 0x01, /* found something above the noise level */ + TV_FE_HAS_CARRIER = 0x02, /* found a DVB signal */ + TV_FE_HAS_VITERBI = 0x04, /* FEC is stable */ + TV_FE_HAS_SYNC = 0x08, /* found sync bytes */ + TV_FE_HAS_LOCK = 0x10, /* everything's working... */ + TV_FE_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */ + TV_FE_REINIT = 0x40 /* frontend was reinitialized, */ +}; /* application is recommended to reset */ +//end + +class CTvChannel: public LightRefBase<CTvChannel> { + +public : + static const int MODE_QPSK = 0; + + static const int MODE_QAM = 1; + + static const int MODE_OFDM = 2; + + static const int MODE_ATSC = 3; + + static const int MODE_ANALOG = 4; + + static const int MODE_DTMB = 5; + + static const int MODE_ISDBT = 6; + + + + static const int BANDWIDTH_8_MHZ = 0; + + static const int BANDWIDTH_7_MHZ = 1; + + static const int BANDWIDTH_6_MHZ = 2; + + static const int BANDWIDTH_AUTO = 3; + + static const int BANDWIDTH_5_MHZ = 4; + + static const int BANDWIDTH_10_MHZ = 5; + + + static const int MODULATION_QPSK = 0; + + static const int MODULATION_QAM_16 = 1; + + static const int MODULATION_QAM_32 = 2; + + static const int MODULATION_QAM_64 = 3; + + static const int MODULATION_QAM_128 = 4; + + static const int MODULATION_QAM_256 = 5; + + static const int MODULATION_QAM_AUTO = 6; + + static const int MODULATION_VSB_8 = 7; + + static const int MODULATION_VSB_16 = 8; + + static const int MODULATION_PSK_8 = 9; + + static const int MODULATION_APSK_16 = 10; + + static const int MODULATION_APSK_32 = 11; + + static const int MODULATION_DQPSK = 12; + + + static const int AUDIO_MONO = 0x0000; + + static const int AUDIO_STEREO = 0x0001; + + static const int AUDIO_LANG2 = 0x0002; + + static const int AUDIO_SAP = 0x0002; + + static const int AUDIO_LANG1 = 0x0003; + + static const int AUDIO_LANG1_LANG2 = 0x0004; + + /**PAL B*/ + static const int STD_PAL_B = 0x00000001; + /**PAL B1*/ + static const int STD_PAL_B1 = 0x00000002; + /**PAL G*/ + static const int STD_PAL_G = 0x00000004; + /**PAL H*/ + static const int STD_PAL_H = 0x00000008; + /**PAL I*/ + static const int STD_PAL_I = 0x00000010; + /**PAL D*/ + static const int STD_PAL_D = 0x00000020; + /**PAL D1*/ + static const int STD_PAL_D1 = 0x00000040; + /**PAL K*/ + static const int STD_PAL_K = 0x00000080; + /**PAL M*/ + static const int STD_PAL_M = 0x00000100; + /**PAL N*/ + static const int STD_PAL_N = 0x00000200; + /**PAL Nc*/ + static const int STD_PAL_Nc = 0x00000400; + /**PAL 60*/ + static const int STD_PAL_60 = 0x00000800; + /**NTSC M*/ + static const int STD_NTSC_M = 0x00001000; + /**NTSC M JP*/ + static const int STD_NTSC_M_JP = 0x00002000; + /**NTSC 443*/ + static const int STD_NTSC_443 = 0x00004000; + /**NTSC M KR*/ + static const int STD_NTSC_M_KR = 0x00008000; + /**SECAM B*/ + static const int STD_SECAM_B = 0x00010000; + /**SECAM D*/ + static const int STD_SECAM_D = 0x00020000; + /**SECAM G*/ + static const int STD_SECAM_G = 0x00040000; + /**SECAM H*/ + static const int STD_SECAM_H = 0x00080000; + /**SECAM K*/ + static const int STD_SECAM_K = 0x00100000; + /**SECAM K1*/ + static const int STD_SECAM_K1 = 0x00200000; + /**SECAM L*/ + static const int STD_SECAM_L = 0x00400000; + /**SECAM LC*/ + static const int STD_SECAM_LC = 0x00800000; + /**ATSC VSB8*/ + static const int STD_ATSC_8_VSB = 0x01000000; + /**ATSC VSB16*/ + static const int STD_ATSC_16_VSB = 0x02000000; + /**NTSC*/ + static const int STD_NTSC = STD_NTSC_M | STD_NTSC_M_JP | STD_NTSC_M_KR; + /**SECAM DK*/ + static const int STD_SECAM_DK = STD_SECAM_D | STD_SECAM_K | STD_SECAM_K1; + /**SECAM*/ + static const int STD_SECAM = STD_SECAM_B | STD_SECAM_G | STD_SECAM_H | STD_SECAM_DK | STD_SECAM_L | STD_SECAM_LC; + /**PAL BG*/ + static const int STD_PAL_BG = STD_PAL_B | STD_PAL_B1 | STD_PAL_G; + /**PAL DK*/ + static const int STD_PAL_DK = STD_PAL_D | STD_PAL_D1 | STD_PAL_K; + /**PAL*/ + static const int STD_PAL = STD_PAL_BG | STD_PAL_DK | STD_PAL_H | STD_PAL_I; + + //static const int TUNER_STD_MN = STD_PAL_M|STD_PAL_N|STD_PAL_Nc| STD_NTSC + static const int STD_B = STD_PAL_B | STD_PAL_B1 | STD_SECAM_B; + static const int STD_GH = STD_PAL_G | STD_PAL_H | STD_SECAM_G | STD_SECAM_H; + static const int STD_DK = STD_PAL_DK | STD_SECAM_DK; + static const int STD_M = STD_PAL_M | STD_NTSC_M; + static const int STD_BG = STD_PAL_BG | STD_SECAM_B | STD_SECAM_G ; + + static const int COLOR_AUTO = 0x02000000; + static const int COLOR_PAL = 0x04000000; + static const int COLOR_NTSC = 0x08000000; + static const int COLOR_SECAM = 0x10000000; + + static const int SAT_POLARISATION_H = 0; + static const int SAT_POLARISATION_V = 1; + +public: + CTvChannel(); + CTvChannel(int dbID, int mode, int freq, int bw, int mod, int sym, int ofdm, int channelNum); + ~CTvChannel(); + CTvChannel(const CTvChannel&); + CTvChannel& operator= (const CTvChannel& cTvChannel); + static Vector<CTvChannel> tvChannelList(int sat_id); + static int selectByID(int id, CTvChannel &c); + static int updateByID(int progID, int std, int freq, int fineFreq); + static int SelectByFreq(int freq, CTvChannel &channel); + static int DeleteBetweenFreq(int beginFreq, int endFreq); + static int CleanAllChannelBySrc(int src); + static int getChannelListBySrc(int src, Vector< sp<CTvChannel> > &v_channel); + void tvChannelDel(); + static void tvChannelDelBySatID(int id); + int getID() + { + return id; + }; + int getDVBTSID(); + void getDVBOrigNetID(); + void getFrontendID(); + void getTSSourceID(); + void isDVBCMode(); + void setFrequency(); + int getFrequency() + { + return frequency; + } + int getSymbolRate() + { + return symbolRate; + } + int getModulation() + { + return modulation; + } + int getBandwidth() + { + return bandwidth; + } + int getMode() + { + return mode; + } + + int getStd() + { + return standard; + }; + int getAfcData() + { + return afc_data; + }; + int getLogicalChannelNum() + { + return logicalChannelNum; + }; + void setSymbolRate(); + void setPolarisation(); + void setATVAudio(); + void setATVVideoFormat(); + void setATVAudioFormat(); + void setATVFreq(); + void setATVAfcData(); + void setModulation(int modulation) + { + this->modulation = modulation; + } + // +private: + friend class LightRefBase<CTvChannel>; + void createFromCursor(CTvDatabase::Cursor &c); + + // + int id; + int dvbTSID; + int dvbOrigNetID; + int fendID; + int tsSourceID; + + int mode; + int frequency; + int symbolRate; + int modulation; + int bandwidth; + int audio; + int standard; + int afc_data; + int sat_id; + int logicalChannelNum; + //showboz + //public TVSatelliteParams tv_satparams; + int sat_polarisation; + +}; + +#endif //_CTVCHANNEL_H + diff --git a/tv/tvserver/libtv/tvdb/CTvDatabase.cpp b/tv/tvserver/libtv/tvdb/CTvDatabase.cpp new file mode 100644 index 0000000..28d1d26 --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvDatabase.cpp @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvDatabase" +//#define LOG_NDEBUG 0 + +#include <assert.h> +#include <tinyxml.h> +#include "CTvDatabase.h" +#include <tvutils.h> +#include <tvconfig.h> + +const char *CTvDatabase::DEFAULT_DB_PATH = "/param/tv_default.xml"; + +const char *CTvDatabase::DB_VERSION_FIELD = "DATABASE_VERSION"; +using namespace android; + +CTvDatabase *CTvDatabase::mpDb = NULL; + +const char CTvDatabase::feTypes[][32] = {"dvbs", "dvbc", "dvbt", "atsc", "analog", "dtmb", "isdbt"}; +const char CTvDatabase::srvTypes[][32] = {"other", "dtv", "radio", "atv", "other"}; +const char CTvDatabase::vidFmts[][32] = {"mpeg12", "mpeg4", "h264", "mjpeg", "real", "jpeg", "vc1", "avs"}; +const char CTvDatabase::audFmts[][32] = {"mpeg", "pcm_s16le", "aac", "ac3", "alaw", "mulaw", "dts", "pcm_s16be", + "flac", "cook", "pcm_u8", "adpcm", "amr", "raac", "wma", "wma_pro", + "pcm_bluray", "alac", "vorbis", "aac_latm", "ape", "eac3", "pcm_wifidisplay" + }; +const char CTvDatabase::mods[][32] = {"qpsk", "qam16", "qam32", "qam64", "qam128", "qam256", "qamauto", "vsb8", "vsb16", "psk8", "apsk16", "apsk32", "dqpsk"}; +const char CTvDatabase::bandwidths[][32] = {"8", "7", "6", "auto", "5", "10", "1_712"}; +const char CTvDatabase::lnbPowers[][32] = {"13v", "18V", "off", "13/18v"}; +const char CTvDatabase::sig22K[][32] = {"on", "off", "auto"}; +const char CTvDatabase::tonebursts[][32] = {"none", "bursta", "burstb"}; +const char CTvDatabase::diseqc10s[][32] = {"lnb1", "lnb2", "lnb3", "lnb4", "none"}; +const char CTvDatabase::diseqc11s[][32] = {"lnb1", "lnb2", "lnb3", "lnb4", "lnb5", "lnb6", "lnb7", "lnb8", + "lnb9", "lnb10", "lnb11", "lnb12", "lnb13", "lnb14", "lnb15", "lnb16", "none" + }; +const char CTvDatabase::motors[][32] = {"none", "none", "none", "diseqc1.2", "diseqc1.3"}; +const char CTvDatabase::ofdmModes[][32] = {"dvbt", "dvbt2"}; +const char CTvDatabase::atvVideoStds[][32] = {"auto", "pal", "ntsc", "secam"}; +const char CTvDatabase::atvAudioStds[][32] = {"dk", "i", "bg", "m", "l", "auto"}; + +CTvDatabase::CTvDatabase() +{ +} + +int CTvDatabase::isFreqListExist() +{ +#ifdef SUPPORT_ADTV + String8 cmd = String8("select * from region_table"); + CTvDatabase::Cursor c; + select(cmd, c); + return c.moveToFirst(); +#else + return -1; +#endif +} + +int CTvDatabase::UnInitTvDb() +{ +#ifdef SUPPORT_ADTV + AM_DB_UnSetup(); + closeDb(); +#endif + return 0; +} + +int CTvDatabase::InitTvDb(const char *path) +{ +#ifdef SUPPORT_ADTV + if (path != NULL) { + if (isFileExist(path) && config_get_int("TV", "tv_db_created", 0) == 1) { //exist or created + LOGD("tv db file(%s) exist and created, open it", path); + if (openDb(path) < 0 ) { + LOGD("db(%s) open fail", path); + return -1; + } + //setup and path set + AM_DB_Setup((char *)path, getHandle()); + if (isFreqListExist() == false) { + importXmlToDB(CTV_DATABASE_DEFAULT_XML); + LOGD("scan region table is NULL, so import freq XML again\n"); + } + } else { + if (isFileExist(path)) { // if just exist, create flag not set, delete it + LOGD("tv db file (%s) exist, but delete it", path); + if (unlink(path) != 0) { + LOGD("delete tv db file(%s) err=%s", path, strerror(errno)); + } + } + LOGD("tv db file(%s) not exist, create it", path); + //setup and path set + sqlite3 *h = NULL; + AM_DB_Setup((char *)path, h); + //create db + AM_DB_GetHandle(&h); + //create table + AM_DB_CreateTables(h); + setHandle(h); + //clear db + ClearDbTable(); + //insert 256 ATV Program + //load init date + importXmlToDB(CTV_DATABASE_DEFAULT_XML); + config_set_int("TV", "tv_db_created", 1); + } + } +#endif + return 0; +} + +CTvDatabase::~CTvDatabase() +{ +#ifdef SUPPORT_ADTV + AM_DB_UnSetup(); +#endif +} + +int CTvDatabase::getChannelParaList(char *path, Vector<sp<ChannelPara> > &vcp) +{ +#ifdef SUPPORT_ADTV + TiXmlDocument myDocument(path); + bool ret = myDocument.LoadFile(); + TiXmlElement *RootElement = myDocument.RootElement(); + //dvbc + TiXmlElement *channel_list_element = RootElement->FirstChildElement("channel_list"); + for (TiXmlElement *channel_entry = channel_list_element->FirstChildElement("channel_entry") ; channel_entry != NULL; channel_entry = channel_entry->NextSiblingElement("channel_entry")) { + sp<ChannelPara> pCp = new ChannelPara(); + channel_entry->Attribute("frequency", &(pCp->freq)); + channel_entry->Attribute("modulation", &(pCp->modulation)); + channel_entry->Attribute("symbol_rate", &(pCp->symbol_rate)); + vcp.push_back(pCp); + } + return vcp.size(); +#else + return -1; +#endif +} + +int CTvDatabase::ClearDbTable() +{ + LOGD("Clearing database ..."); +#ifdef SUPPORT_ADTV + exeSql("delete from net_table"); + exeSql("delete from ts_table"); + exeSql("delete from srv_table"); + exeSql("delete from evt_table"); + exeSql("delete from booking_table"); + exeSql("delete from grp_table"); + exeSql("delete from grp_map_table"); + exeSql("delete from dimension_table"); + exeSql("delete from sat_para_table"); + exeSql("delete from region_table"); +#endif + return 0; +} + +int CTvDatabase::clearDbAllProgramInfoTable() +{ + LOGD("Clearing clearDbAllProgramInfoTable ..."); +#ifdef SUPPORT_ADTV + exeSql("delete from net_table"); + exeSql("delete from ts_table"); + exeSql("delete from srv_table"); + exeSql("delete from evt_table"); + exeSql("delete from booking_table"); + exeSql("delete from grp_table"); + exeSql("delete from grp_map_table"); + exeSql("delete from dimension_table"); + exeSql("delete from sat_para_table"); +#endif + return 0; +} + +//showboz now just channellist +int CTvDatabase::importXmlToDB(const char *xmlPath) +{ +#ifdef SUPPORT_ADTV + //delete region table before importing xml + exeSql("delete from region_table"); + + TiXmlDocument myDocument(xmlPath); + bool ret = myDocument.LoadFile(); + + TiXmlElement *RootElement = myDocument.RootElement(); + beginTransaction();//----------------------------------------------- + //list-->entry + for (TiXmlElement *channel_list_element = RootElement->FirstChildElement("channel_list"); channel_list_element != NULL; channel_list_element = channel_list_element->NextSiblingElement("channel_list")) { + //LOGD("showboz-----channel_list =%d", channel_list_element); + const char *channel_name = channel_list_element->Attribute("name"); + const char *channel_fe_type = channel_list_element->Attribute("fe_type"); + //LOGD("showboz-----channel_list name = %s type=%s", channel_name, channel_fe_type); + + for (TiXmlElement *channel_entry = channel_list_element->FirstChildElement("channel_entry") ; channel_entry != NULL; channel_entry = channel_entry->NextSiblingElement("channel_entry")) { + int freq, symb, channelNum; + String8 cmd = String8("insert into region_table(name,fe_type,frequency,symbol_rate,modulation,bandwidth,ofdm_mode,logical_channel_num)"); + cmd += String8("values('") + channel_name + String8("',") + String8::format("%d", StringToIndex(feTypes, channel_fe_type)) + String8(","); + channel_entry->Attribute("frequency", &freq); + cmd += String8::format("%d", freq) + String8(","); + channel_entry->Attribute("symbol_rate", &symb); + cmd += String8::format("%d", symb) + String8(","); + //LOGD("showboz---------m=%s,b=%s,o=%s", channel_entry->Attribute("modulation"), channel_entry->Attribute("bandwidth"), channel_entry->Attribute("ofdm_mode")); + cmd += String8::format("%d", StringToIndex(mods, channel_entry->Attribute("modulation"))) + String8(","); + cmd += String8::format("%d", StringToIndex(bandwidths, channel_entry->Attribute("bandwidth"))) + String8(","); + cmd += String8::format("%d", StringToIndex(ofdmModes, channel_entry->Attribute("ofdm_mode"))) + String8(","); + channel_entry->Attribute("id", &channelNum); + cmd += String8::format("%d", channelNum) + String8(")"); + exeSql(cmd.string()); + } + } + + commitTransaction();//------------------------------------------------------ +#endif + return 0; +} + +bool CTvDatabase::isAtv256ProgInsertForSkyworth() +{ +#ifdef SUPPORT_ADTV + String8 select_ts_atvcount = String8("select * from ts_table where src = 4"); + Cursor c; + select(select_ts_atvcount, c); + return c.getCount() < 256 ? false : true; +#else + return -1; +#endif +} + +int CTvDatabase::insert256AtvProgForSkyworth() +{ +#ifdef SUPPORT_ADTV + beginTransaction(); + for (int i = 0; i < 256; i++) { + String8 insert_ts = String8("insert into ts_table(db_id, src, db_net_id, ts_id, freq, symb, mod, bw, snr, ber, strength, db_sat_para_id, polar, std, aud_mode, flags, dvbt_flag) values ("); + insert_ts += String8::format("'%d'", i); + insert_ts += String8(", '4', '-1', '-1', '44250000', '0', '0', '0', '0', '0', '0', '-1', '-1', '-1', '1', '0', '0')"); + exeSql(insert_ts.string()); + String8 insert_srv = String8("insert into srv_table(db_id, src, db_net_id, db_ts_id, name, service_id, service_type, eit_schedule_flag, eit_pf_flag, running_status, free_ca_mode, volume, aud_track, pmt_pid, vid_pid, vid_fmt, scrambled_flag, current_aud, aud_pids, aud_fmts, aud_langs, aud_types, current_sub, sub_pids, sub_types, sub_composition_page_ids, sub_ancillary_page_ids, sub_langs, current_ttx, ttx_pids, ttx_types, ttx_magazine_nos, ttx_page_nos, ttx_langs, chan_num, skip, lock, favor, lcn, sd_lcn, hd_lcn, default_chan_num, chan_order, lcn_order, service_id_order, hd_sd_order, db_sat_para_id, dvbt2_plp_id, major_chan_num, minor_chan_num, access_controlled, hidden, hide_guide, source_id, sdt_ver) values ("); + insert_srv += String8::format("'%d'", i); + insert_srv += String8(" , '4', '-1', "); + insert_srv += String8::format("'%d'", i); + insert_srv += String8(", 'xxxATV Program', '-1', '3', '-1', '-1', '-1', '-1', '50', '1', '-1', '-1', '-1', '0', '-1', '-1', '-1', 'Audio1', '0', '-1', ' ', ' ', ' ', ' ', ' ', '-1', ' ', ' ', ' ', ' ', ' ', '-1', '1', '0', '0', '-1', '-1', '-1', '-1', "); + insert_srv += String8::format("'%d'", i); + insert_srv += String8(" , '0', '0', '0', '-1', '255', '0', '0', '0', '0', '0', '0', '255') "); + exeSql(insert_srv.string()); + } + commitTransaction(); +#endif + return 0; +} + +void CTvDatabase::deleteTvDb() +{ +#ifdef SUPPORT_ADTV + if (mpDb != NULL) { + delete mpDb; + mpDb = NULL; + } +#endif +} + +CTvDatabase *CTvDatabase::GetTvDb() +{ +#ifdef SUPPORT_ADTV + if (mpDb == NULL) { + mpDb = new CTvDatabase(); + } + return mpDb; +#else + return nullptr; +#endif +} diff --git a/tv/tvserver/libtv/tvdb/CTvDatabase.h b/tv/tvserver/libtv/tvdb/CTvDatabase.h new file mode 100644 index 0000000..47991ba --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvDatabase.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifdef SUPPORT_ADTV +#include <am_db.h> +#endif + +#if !defined(_CTVDATABASE_H) +#define _CTVDATABASE_H +#include <unistd.h> +#include <stdlib.h> +#include <utils/String8.h> +#include <utils/Log.h> +#include <utils/Vector.h> +#include <utils/RefBase.h> +#include <CSqlite.h> + +#include "CTvLog.h" + + +#define CTV_DATABASE_DEFAULT_XML "/vendor/etc/tv_default.xml" + +using namespace android; + +class CTvDatabase: public CSqlite { +public: + static const char *DEFAULT_DB_PATH; + static const int DB_VERSION = 8; + static const char *DB_VERSION_FIELD; + + static const char feTypes[][32]; + static const char srvTypes[][32]; + static const char vidFmts[][32]; + static const char audFmts[][32]; + static const char mods[][32]; + static const char bandwidths[][32]; + static const char lnbPowers[][32]; + static const char sig22K[][32]; + static const char tonebursts[][32]; + static const char diseqc10s[][32]; + static const char diseqc11s[][32]; + static const char motors[][32]; + static const char ofdmModes[][32]; + static const char atvVideoStds[][32]; + static const char atvAudioStds[][32]; + template<typename T> + int StringToIndex(const T &t, const char *item) + { + if (item == NULL) return -1; + int size = sizeof(t) / sizeof(t[0]); + for (int i = 0; i < size; i++) { + if (strcmp(t[i], item) == 0) return i; + } + return -1; + } +public: + CTvDatabase(); + //CTvDatabase(char* path, sqlite3 * h); + static CTvDatabase *GetTvDb(); + static void deleteTvDb(); + ~CTvDatabase(); + int UnInitTvDb(); + int InitTvDb(const char *path); + //showboz test + class ChannelPara : public LightRefBase<ChannelPara> { + public: + int mode; + int freq; + int symbol_rate; + int modulation; + int bandwidth; + int polar; + }; + + static int getChannelParaList(char *path, Vector<sp<ChannelPara> > &vcp); + + int importDbToXml(); + int importXmlToDB(const char *xmlPath); + bool isAtv256ProgInsertForSkyworth(); + int insert256AtvProgForSkyworth(); + int ClearDbTable(); + int clearDbAllProgramInfoTable(); +private: + static CTvDatabase *mpDb; + int isFreqListExist(void); +}; + +#endif //_CTVDATABASE_H diff --git a/tv/tvserver/libtv/tvdb/CTvDimension.cpp b/tv/tvserver/libtv/tvdb/CTvDimension.cpp new file mode 100644 index 0000000..5bdfb46 --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvDimension.cpp @@ -0,0 +1,560 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvDimension" + +#include "CTvDimension.h" +#include "CTvProgram.h" +#include "CTvTime.h" +#include "CTvEvent.h" +#include <tvconfig.h> + +#include <vector> + +/** + *TV ATSC rating dimension + */ + +void CTvDimension::createFromCursor(CTvDatabase::Cursor &c) +{ + int col; + + col = c.getColumnIndex("db_id"); + this->id = c.getInt(col); + + col = c.getColumnIndex("index_j"); + this->indexj = c.getInt(col); + + col = c.getColumnIndex("rating_region"); + this->ratingRegion = c.getInt(col); + + col = c.getColumnIndex("graduated_scale"); + this->graduatedScale = c.getInt(col); + + col = c.getColumnIndex("name"); + this->name = c.getString(col); + + col = c.getColumnIndex("rating_region_name"); + this->ratingRegionName = c.getString(col); + + col = c.getColumnIndex("values_defined"); + this->valuesDefined = c.getInt(col); + this->lockValues = new int[valuesDefined]; + this->abbrevValues = new String8[valuesDefined]; + this->textValues = new String8[valuesDefined]; + char temp[256]; + for (int i = 0; i < valuesDefined; i++) { + sprintf(temp, "abbrev%d", i); + col = c.getColumnIndex(temp); + this->abbrevValues[i] = c.getString(col); + sprintf(temp, "text%d", i); + col = c.getColumnIndex(temp); + this->textValues[i] = c.getString(col); + sprintf(temp, "locked%d", i); + col = c.getColumnIndex(temp); + this->lockValues[i] = c.getInt(col); + } + + if (ratingRegion == REGION_US && !strcmp(name, "All")) { + isPGAll = true; + } else { + isPGAll = false; + } +} + +CTvDimension::CTvDimension(CTvDatabase::Cursor &c) +{ + createFromCursor(c); +} +CTvDimension::CTvDimension() +{ + +} +CTvDimension::~CTvDimension() +{ + if (lockValues != NULL) { + delete []lockValues; + } + if (textValues != NULL) { + delete []textValues; + } + if (abbrevValues != NULL) { + delete []abbrevValues; + } +} + +/* 'All' is a very special case, it links to dimension0 & dimension5 */ +int CTvDimension::getUSPGAllLockStatus(String8 abbrev) +{ +//TODO + int len = 0; + CTvDimension dm5; + int j = 0; + selectByIndex(dm5, CTvDimension::REGION_US, 5); + len = dm5.getDefinedValue(); + + std::vector<String8> dm5Abbrev(len - 1); + dm5.getAbbrev(dm5Abbrev); + for (j = 0; j < len - 1; j++) { + if (dm5Abbrev[j] == abbrev) { + return dm5.getLockStatus(j + 1); + } + } + CTvDimension dm0; + selectByIndex(dm0, CTvDimension::REGION_US, 0); + len = dm0.getDefinedValue(); + std::vector<String8> dm0Abbrev(len - 1); + dm0.getAbbrev(dm0Abbrev); + for (j = 0; j < len - 1; j++) { + if (dm0Abbrev[j] == abbrev) { + return dm0.getLockStatus(j + 1); + } + } + return -1; +} + +void CTvDimension::setUSPGAllLockStatus(String8 abbrev, int lock) +{ + + int len = 0; + int j = 0; + + CTvDimension dm5; + + selectByIndex(dm5, REGION_US, 5); + len = dm5.getDefinedValue(); + std::vector<String8> dm5Abbrev(len - 1); + dm5.getAbbrev(dm5Abbrev); + + for (j = 0; j < len - 1; j++) { + if (abbrev == dm5Abbrev[j]) { + dm5.setLockStatus(j + 1, lock); + return; + } + } + + CTvDimension dm0; + selectByIndex(dm0, REGION_US, 0); + len = dm0.getDefinedValue(); + std::vector<String8> dm0Abbrev(len - 1); + dm0.getAbbrev(dm0Abbrev); + + for (j = 0; j < len - 1; j++) { + if (abbrev == dm0Abbrev[j]) { + dm0.setLockStatus(j + 1, lock); + return; + } + } + + return; +} + + +void CTvDimension::selectByID(CTvDimension &dm, int id) +{ + String8 cmd = String8("select * from dimension_table where evt_table.db_id = ") + String8::format("%d", id); + CTvDatabase::Cursor c; + int ret = CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + dm.createFromCursor(c); + LOGD("%s, %d success", "TV", __LINE__); + } else { + LOGD("%s, %d fail", "TV", __LINE__); + c.close(); + return; + } + c.close(); + +} + +void CTvDimension::selectByRatingRegion(CTvDimension &dm, int ratingRegionID) +{ + String8 cmd = String8("select * from dimension_table where rating_region = ") + String8::format("%d", ratingRegionID); + CTvDatabase::Cursor c; + int ret = CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + dm.createFromCursor(c); + LOGD("%s, %d success", "TV", __LINE__); + } else { + LOGD("%s, %d fail", "TV", __LINE__); + c.close(); + return; + } + c.close(); +} + +int CTvDimension::selectByIndex(CTvDimension &dm, int ratingRegionID, int index) +{ + String8 cmd = String8("select * from dimension_table where rating_region = ") + String8::format("%d", ratingRegionID); + cmd += String8(" and index_j=") + String8::format("%d", index); + CTvDatabase::Cursor c; + int ret = CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + dm.createFromCursor(c); + LOGD("%s, %d success", "TV", __LINE__); + } else { + LOGD("%s, %d fail", "TV", __LINE__); + c.close(); + return -1; + } + c.close(); + + return 0; +} + +void CTvDimension::selectByName(CTvDimension &dm, int ratingRegionID, String8 dimensionName) +{ + String8 cmd = String8("select * from dimension_table where rating_region = ") + String8::format("%d", ratingRegionID); + cmd += String8(" and name='") + dimensionName + String8("'"); + CTvDatabase::Cursor c; + CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + LOGD("%s, %d success", "TV", __LINE__); + dm.createFromCursor(c); + } else { + LOGD("%s, %d fail", "TV", __LINE__); + c.close(); + return; + } + c.close(); + + return; +} + + +bool CTvDimension::isBlocked(CTvDimension &dm, VChipRating *definedRating) +{ + int ret = 0; + ret = selectByIndex(dm, definedRating->getRegion(), definedRating->getDimension()); + if (ret != -1) { + LOGD("%s, %d, index=%d", "TV", __LINE__, definedRating->getValue()); + return (dm.getLockStatus(definedRating->getValue()) == 1); + } + + return false; +} + +int CTvDimension::getID() +{ + return id; +} + +int CTvDimension::getRatingRegion() +{ + return ratingRegion; +} + +int CTvDimension::getDefinedValue() +{ + return valuesDefined; +} + +String8 CTvDimension::getRatingRegionName() +{ + return ratingRegionName; +} + +String8 CTvDimension::getName() +{ + return name; +} + +int CTvDimension::getGraduatedScale() +{ + return graduatedScale; +} + +#if 0 +int *CTvDimension::getLockStatus() +{ + int len = getDefinedValue(); + if (len > 1) { + if (isPGAll) { + return getUSPGAllLockStatus(abbrevValues); + } else { + int *lock = new int[len - 1]; + //System.arraycopy(lockValues, 1, l, 0, l.length); + for (int i = 0; i < len - 1; i++) + lock[i] = lockValues[1 + i]; + return lock; + } + } else { + return NULL; + } +} +#endif + +int CTvDimension::getLockStatus(int valueIndex) +{ + int len = getDefinedValue(); + if (valueIndex >= len) { + return -1; + } else { + return lockValues[valueIndex]; + } +} + +void CTvDimension::getLockStatus(String8 abbrevs[], int lock[], int *array_len) +{ + int i = 0; + int len = getDefinedValue(); + + if (abbrevs != NULL && lock != NULL) { + for (int i = 0; i < *array_len; i++) { + *(lock + i) = -1; + for (int j = 0; j < len; j++) { + if (abbrevs[i] == abbrevValues[j]) { + *(lock + i) = lockValues[j]; + break; + } + } + } + } + *array_len = len; +} + +int CTvDimension::getAbbrev(std::vector<String8> abb) +{ + /* the first rating_value must be not visible to user */ + int len = getDefinedValue(); + if (len > 1) { + for (int i = 0; i < len - 1; i++) + abb[i] = abbrevValues[i + 1]; + return 0; + } else { + return -1; + } +} + +String8 CTvDimension::getAbbrev(int valueIndex) +{ + int len = getDefinedValue(); + if (valueIndex >= len) + return String8(""); + else + return abbrevValues[valueIndex]; +} + +int CTvDimension::getText(String8 tx[]) +{ + int len = getDefinedValue(); + if (len > 1) { + for (int i = 0; i < len - 1; i++) + tx[i] = textValues[i + 1]; + return 0; + } else { + return -1; + } +} + +String8 CTvDimension::getText(int valueIndex) +{ + int len = getDefinedValue(); + if (valueIndex >= len) + return String8(""); + else + return textValues[valueIndex]; +} + +void CTvDimension::setLockStatus(int valueIndex, int status) +{ + int len = getDefinedValue(); + if (valueIndex >= len) + return; + + if (lockValues[valueIndex] != -1 && lockValues[valueIndex] != status) { + lockValues[valueIndex] = status; + String8 cmd = String8("update dimension_table set locked") + String8::format("%d", valueIndex); + cmd += String8("=") + String8::format("%d", status) + String8(" where db_id = ") + String8::format("%d", id); + + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + } +} + +void CTvDimension::setLockStatus(int status[]) +{ + int len = getDefinedValue(); + if (status == NULL) { + LOGD("Cannot set lock status, invalid param"); + return; + } + for (int i = 0; i < len; i++) { + setLockStatus(i + 1, status[i]); + } +} + +void CTvDimension::setLockStatus(String8 abbrevs[], int locks[], int abb_size) +{ + int len = getDefinedValue(); + if (abbrevs == NULL || locks == NULL) + return; + + for (int i = 0; i < abb_size; i++) { + for (int j = 0; j < len; j++) { + if (abbrevs[i] == abbrevValues[j]) { + setLockStatus(j, locks[i]); + break; + } + } + } +} + +CTvDimension::VChipRating::VChipRating(int region, int dimension, int value) +{ + this->region = region; + this->dimension = dimension; + this->value = value; +} +CTvDimension::VChipRating::VChipRating() +{ +} + +CTvDimension::VChipRating::~VChipRating() +{ +} +int CTvDimension::VChipRating::getRegion() +{ + return region; +} + +int CTvDimension::VChipRating::getDimension() +{ + return dimension; +} + +int CTvDimension::VChipRating::getValue()const +{ + return value; +} + +String8 CTvDimension::getCurdimension() +{ + return CurvchipDimension; +} +String8 CTvDimension::getCurAbbr() +{ + return CurvchipAbbrev; + +} +String8 CTvDimension::getCurText() +{ + return CurvchipText; +} + +void CTvDimension::insertNewDimension(const int region, String8 regionName, String8 name, + int indexj, int *lock, const char **abbrev, const char **text, int size) +{ + String8 cmd = String8("insert into dimension_table(rating_region,rating_region_name,name,graduated_scale,"); + cmd += String8("values_defined,index_j,version,abbrev0,text0,locked0,abbrev1,text1,locked1,abbrev2,text2,locked2,"); + cmd += String8("abbrev3,text3,locked3,abbrev4,text4,locked4,abbrev5,text5,locked5,abbrev6,text6,locked6,"); + cmd += String8("abbrev7,text7,locked7,abbrev8,text8,locked8,abbrev9,text9,locked9,abbrev10,text10,locked10,"); + cmd += String8("abbrev11,text11,locked11,abbrev12,text12,locked12,abbrev13,text13,locked13,abbrev14,text14,locked14,"); + cmd += String8("abbrev15,text15,locked15) values(") + String8::format("%d", region) + String8(",'") + regionName.string(); + cmd += String8("','") + name.string() + String8("',0,") + String8::format("%d", size) + String8(",") + String8::format("%d", indexj) + String8(",0"); + for (int i = 0; i < 16; i++) { + if (i < size) { + cmd += String8(",'") + String8::format("%s", abbrev[i]) + String8("'"); + cmd += String8(",'") + String8::format("%s", text[i]) + String8("'"); + cmd += String8(",'") + String8::format("%d", lock[i]) + String8("'"); + } else { + cmd += String8(",''"); + cmd += String8(",''"); + cmd += String8(",-1"); + } + } + cmd += String8(")"); + CTvDatabase::GetTvDb()->exeSql(cmd.string()); +} +/** + * ??????Standard ATSC V-Chip Dimensions + */ +void CTvDimension::builtinAtscDimensions() +{ + CTvDatabase::GetTvDb()->exeSql("delete from dimension_table"); + + /* Add U.S. Rating region 0x1 */ + const char *abbrev0[] = {"", "None", "TV-G", "TV-PG", "TV-14", "TV-MA"}; + const char *text0[] = {"", "None", "TV-G", "TV-PG", "TV-14", "TV-MA"}; + int lock0[] = { -1, -1, 0, 0, 0, 0}; + const char *abbrev1[] = {"", "D", "TV-G", "TV-PG", "TV-14", "TV-MA"}; + const char *text1[] = {"", "D", "TV-G", "TV-PG", "TV-14", "TV-MA"}; + int lock1[] = { -1, -1, -1, 0, 0, -1}; + const char *abbrev2[] = {"", "L", "TV-G", "TV-PG", "TV-14", "TV-MA"}; + const char *text2[] = {"", "L", "TV-G", "TV-PG", "TV-14", "TV-MA"}; + int lock2[] = { -1, -1, -1, 0, 0, 0}; + const char *abbrev3[] = {"", "S", "TV-G", "TV-PG", "TV-14", "TV-MA"}; + const char *text3[] = {"", "S", "TV-G", "TV-PG", "TV-14", "TV-MA"}; + int lock3[] = { -1, -1, -1, 0, 0, 0}; + const char *abbrev4[] = {"", "V", "TV-G", "TV-PG", "TV-14", "TV-MA"}; + const char *text4[] = {"", "V", "TV-G", "TV-PG", "TV-14", "TV-MA"}; + int lock4[] = { -1, -1, -1, 0, 0, 0}; + const char *abbrev5[] = {"", "TV-Y", "TV-Y7"}; + const char *text5[] = {"", "TV-Y", "TV-Y7"}; + int lock5[] = { -1, 0, 0}; + const char *abbrev6[] = {"", "FV", "TV-Y7"}; + const char *text6[] = {"", "FV", "TV-Y7"}; + int lock6[] = { -1, -1, 0}; + const char *abbrev7[] = {"", "N/A", "G", "PG", "PG-13", "R", "NC-17", "X", "NR"}; + const char *text7[] = {"", "MPAA Rating Not Applicable", "Suitable for AllAges", + "Parental GuidanceSuggested", "Parents Strongly Cautioned", + "Restricted, under 17 must be accompanied by adult", + "No One 17 and Under Admitted", "No One 17 and Under Admitted", + "no Rated by MPAA" + }; + int lock7[] = { -1, -1, 0, 0, 0, 0, 0, 0, 0}; + /*Extra for 'All' */ + const char *abbrevall[] = {"TV-Y", "TV-Y7", "TV-G", "TV-PG", "TV-14", "TV-MA"}; + const char *textall[] = {"TV-Y", "TV-Y7", "TV-G", "TV-PG", "TV-14", "TV-MA"}; + int lockall[] = {0, 0, 0, 0, 0, 0}; + + insertNewDimension(CTvDimension::REGION_US, String8("US (50 states + possessions)"), + String8("Entire Audience"), 0, lock0, abbrev0, text0, sizeof(lock0) / sizeof(int)); + insertNewDimension(CTvDimension::REGION_US, String8("US (50 states + possessions)"), + String8("Dialogue"), 1, lock1, abbrev1, text1, sizeof(lock1) / sizeof(int)); + insertNewDimension(CTvDimension::REGION_US, String8("US (50 states + possessions)"), + String8("Language"), 2, lock2, abbrev2, text2, sizeof(lock2) / sizeof(int)); + insertNewDimension(CTvDimension::REGION_US, String8("US (50 states + possessions)"), + String8("Sex"), 3, lock3, abbrev3, text3, sizeof(lock3) / sizeof(int)); + insertNewDimension(CTvDimension::REGION_US, String8("US (50 states + possessions)"), + String8("Violence"), 4, lock4, abbrev4, text4, sizeof(lock4) / sizeof(int)); + insertNewDimension(CTvDimension::REGION_US, String8("US (50 states + possessions)"), + String8("Children"), 5, lock5, abbrev5, text5, sizeof(lock5) / sizeof(int)); + insertNewDimension(CTvDimension::REGION_US, String8("US (50 states + possessions)"), + String8("Fantasy violence"), 6, lock6, abbrev6, text6, sizeof(lock6) / sizeof(int)); + insertNewDimension(CTvDimension::REGION_US, String8("US (50 states + possessions)"), + String8("MPAA"), 7, lock7, abbrev7, text7, sizeof(lock7) / sizeof(int)); + insertNewDimension(CTvDimension::REGION_US, String8("US (50 states + possessions)"), + String8("All"), -1, lockall, abbrevall, textall, sizeof(lockall) / sizeof(int)); + /* Add Canadian Rating region 0x2 */ + const char *cabbrev0[] = {"E", "C", "C8+", "G", "PG", "14+", "18+"}; + const char *ctext0[] = {"Exempt", "Children", "8+", "General", "PG", "14+", "18+"}; + int clock0[] = {0, 0, 0, 0, 0, 0, 0}; + const char *cabbrev1[] = {"E", "G", "8 ans+", "13 ans+", "16 ans+", "18 ans+"}; + const char *ctext1[] = {"Exempt??es", "Pour tous", "8+", "13+", "16+", "18+"}; + int clock1[] = {0, 0, 0, 0, 0, 0}; + + insertNewDimension(CTvDimension::REGION_CANADA, String8("Canada"), + String8("Canadian English Language Rating"), 0, clock0, cabbrev0, ctext0, sizeof(clock0) / sizeof(int)); + insertNewDimension(CTvDimension::REGION_CANADA, String8("Canada"), + String8("Codes francais du Canada"), 1, clock1, cabbrev1, ctext1, sizeof(clock1) / sizeof(int)); +} + +int CTvDimension::isDimensionTblExist() +{ + String8 cmd = String8("select * from dimension_table"); + CTvDatabase::Cursor c; + CTvDatabase::GetTvDb()->select(cmd, c); + return c.moveToFirst(); +} diff --git a/tv/tvserver/libtv/tvdb/CTvDimension.h b/tv/tvserver/libtv/tvdb/CTvDimension.h new file mode 100644 index 0000000..ead3b4c --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvDimension.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CTVDIMENSION_H) +#define _CTVDIMENSION_H +#include <utils/Vector.h> +#include "CTvDatabase.h" +#include <utils/String8.h> +#include <stdlib.h> + +#include "CTvLog.h" + +#include <vector> + +// TV ATSC rating dimension +class CTvDimension { +public: + class VChipRating { + private: + int region; + int dimension; + int value; + + public: + VChipRating(int region, int dimension, int value); + VChipRating(); + ~VChipRating(); + int getRegion(); + int getDimension(); + int getValue()const; + }; + /* 'All' is a very special case, it links to dimension0 & dimension5 */ + void createFromCursor(CTvDatabase::Cursor &c); + static int getUSPGAllLockStatus(String8 abbrev); + static void setUSPGAllLockStatus(String8 abbrev, int lock); + static void selectByID(CTvDimension &dm, int id); + static int selectByIndex(CTvDimension &dm, int ratingRegionID, int index); + static void selectByName(CTvDimension &dm, int ratingRegionID, String8 dimensionName); + static void selectByRatingRegion(CTvDimension &dm, int ratingRegionID); + bool isBlocked(CTvDimension &dm, VChipRating *definedRating); + int getID(); + int getRatingRegion(); + String8 getRatingRegionName(); + String8 getName(); + int getGraduatedScale(); + int getDefinedValue(); + //int* getLockStatus(); + int getLockStatus(int valueIndex); + void getLockStatus(String8 abbrevs[], int lock[], int *array_len); + int getAbbrev(std::vector<String8> abb); + String8 getAbbrev(int valueIndex); + int getText(String8 tx[]); + String8 getText(int valueIndex); + void setLockStatus(int valueIndex, int status); + void setLockStatus(int status[]); + void setLockStatus(String8 abbrevs[], int locks[], int abb_size); + /**Rating regions*/ +public: + static const int REGION_US = 0x1; + static const int REGION_CANADA = 0x2; + static const int REGION_TAIWAN = 0x3; + static const int REGION_SOUTHKOREA = 0x4; + + CTvDimension(CTvDatabase::Cursor &c); + CTvDimension(); + ~CTvDimension(); + + static void insertNewDimension(const int region, String8 regionName, String8 name, + int indexj, int *lock, const char **abbrev, const char **text, int size); + static void builtinAtscDimensions(); + static int isDimensionTblExist(); + String8 getCurdimension(); + String8 getCurAbbr(); + String8 getCurText(); +private: + int id; + int indexj; + int ratingRegion; + int graduatedScale; + int valuesDefined; + int *lockValues; + String8 name; + String8 ratingRegionName; + String8 *abbrevValues; + String8 *textValues; + bool isPGAll; + String8 CurvchipDimension; + String8 CurvchipAbbrev; + String8 CurvchipText; +}; +#endif //_CTVDIMENSION_H diff --git a/tv/tvserver/libtv/tvdb/CTvEvent.cpp b/tv/tvserver/libtv/tvdb/CTvEvent.cpp new file mode 100644 index 0000000..f839789 --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvEvent.cpp @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvEvent" + +#include "CTvEvent.h" +#include "CTvDatabase.h" +#include "CTvProgram.h" +#include <stdlib.h> + +void CTvEvent::InitFromCursor(CTvDatabase::Cursor &c) +{ + int col; + + col = c.getColumnIndex("db_id"); + this->id = c.getInt(col); + + col = c.getColumnIndex("event_id"); + this->dvbEventID = c.getInt(col); + + col = c.getColumnIndex("name"); + this->name = c.getString(col); + + col = c.getColumnIndex("start"); + this->start = (long)c.getInt(col); + + col = c.getColumnIndex("end"); + this->end = (long)c.getInt(col) ; + + col = c.getColumnIndex("nibble_level"); + this->dvbContent = c.getInt(col); + + col = c.getColumnIndex("parental_rating"); + this->dvbViewAge = c.getInt(col); + + col = c.getColumnIndex("sub_flag"); + this->sub_flag = c.getInt(col); + + col = c.getColumnIndex("db_srv_id"); + this->programID = c.getInt(col); + + col = c.getColumnIndex("rrt_ratings"); + String8 rrtRatings = c.getString(col); + char *tmp; + Vector<String8> ratings; + int l = 0; + char *pSave; + tmp = strtok_r(rrtRatings.lockBuffer(rrtRatings.size()), ",", &pSave); + LOGD("TV, %d, %s", __LINE__, tmp); + while (tmp != NULL) { + ratings.push_back(String8(tmp)); + tmp = strtok_r(NULL, ",", &pSave); + } + rrtRatings.unlockBuffer(); + rating_len = ratings.size(); + if (!ratings.isEmpty()) { + for (int i = 0; i < (int)ratings.size(); i++) { + Vector<String8> rating; + tmp = strtok_r(ratings.editItemAt(i).lockBuffer(ratings.editItemAt(i).length()), " ", &pSave); + while (tmp != NULL) { + rating.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + ratings.editItemAt(i).unlockBuffer(); + if (rating.size() >= 3) { + int re = atoi(rating[0]); + int dm = atoi(rating[1]); + int vl = atoi(rating[2]); + vchipRatings.add( new CTvDimension::VChipRating(re, dm, vl)); + } else + vchipRatings.add(NULL); + } + } + + col = c.getColumnIndex("descr"); + this->description = c.getString(col); + + col = c.getColumnIndex("ext_descr"); + this->extDescription = c.getString(col); +} + +//id; CTvChannel.MODE_ATSC sourceid , other id +int CTvEvent::getProgPresentEvent(int progSrc, int progID, long nowTime, CTvEvent &ev) +{ + String8 cmd; + CTvDatabase::Cursor c; + + cmd = String8("select * from evt_table where evt_table."); + + if (progSrc == CTvChannel::MODE_ATSC) { + cmd += String8("source_id = ") + String8::format("%d", progID); + } else { + cmd += String8("db_srv_id = ") + String8::format("%d", progID); + } + + cmd += String8(" and evt_table.start <= ") + String8::format("%ld", nowTime) + String8(" and evt_table.end > ") + String8::format("%ld", nowTime); + + int ret = CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + ev.InitFromCursor(c); + } else { + c.close(); + return -1; + } + + c.close(); + + return 0; +} + +int CTvEvent::getProgScheduleEvents(int progSrc, int progID, long start, long duration, Vector<sp<CTvEvent> > &vEv) +{ + String8 cmd; + long begin = start; + long end = start + duration; + + cmd = String8("select * from evt_table where evt_table."); + if (progSrc == CTvChannel::MODE_ATSC) { + cmd += String8("source_id = ") + String8::format("%d", progID); + } else { + cmd += String8("db_srv_id = ") + String8::format("%d", progID); + } + cmd += String8(" and "); + cmd += String8(" ((start < ") + String8::format("%ld", begin) + String8(" and end > ") + String8::format("%ld", begin) + String8(") ||"); + cmd += String8(" (start >= ") + String8::format("%ld", begin) + String8(" and start < ") + String8::format("%ld", end) + String8("))"); + cmd += String8(" order by evt_table.start"); + + CTvDatabase::Cursor c; + int ret = CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + do { + vEv.add(new CTvEvent(c)); + } while (c.moveToNext()); + + } else { + c.close(); + return -1; + } + + c.close(); + return 0; +} +int CTvEvent::getATVProgEvent(int progSrc, int progID, CTvEvent &ev) +{ + String8 cmd; + CTvDatabase::Cursor c; + + cmd = String8("select * from evt_table where evt_table."); + + if (progSrc == CTvChannel::MODE_ATSC) { + LOGD("%s, %d MODE_ATSC", "TV", __LINE__); + cmd += String8("source_id = ") + String8::format("%d", progID); + } else { + LOGD("%s, %d MODE_ANALOG", "TV", __LINE__); + cmd += String8("db_srv_id = ") + String8::format("%d", progID); + } + + //cmd += String8(" and evt_table.start <= ") + String8::format("%ld", nowTime) + String8(" and evt_table.end > ") + String8::format("%ld", nowTime); + + int ret = CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + ev.InitFromCursor(c); + } else { + c.close(); + return -1; + } + + c.close(); + + return 0; +} + +int CTvEvent::CleanAllEvent() +{ + CTvDatabase::GetTvDb()->exeSql("delete from evt_table"); + return 0; +} + +int CTvEvent::selectByID(int id, CTvEvent &evt) +{ + CTvDatabase::Cursor c; + String8 sql; + + sql = String8("select * from evt_table where evt_table.db_id = ") + String8::format("%d", id); + CTvDatabase::GetTvDb()->select(sql.string(), c); + if (c.moveToFirst()) { + evt.InitFromCursor(c); + } else { + c.close(); + return -1; + } + + c.close(); + return 0; +} + +int CTvEvent::bookEvent(int evtId, bool bBookFlag) +{ + String8 cmd; + + cmd = String8("update evt_table set sub_flag=") + String8::format("%d", bBookFlag) + + String8(" where event_id=") + String8::format("%d", evtId); + + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + + return 0; +} + +CTvEvent::CTvEvent(CTvDatabase::Cursor &c) +{ + InitFromCursor(c); +} + +CTvEvent::CTvEvent() +{ +} + +CTvEvent::~CTvEvent() +{ + int size = vchipRatings.size(); + for (int i = 0; i < size; i++) + delete vchipRatings[i]; +} +Vector<CTvDimension::VChipRating *> CTvEvent::getVChipRatings() +{ + return vchipRatings; +} + diff --git a/tv/tvserver/libtv/tvdb/CTvEvent.h b/tv/tvserver/libtv/tvdb/CTvEvent.h new file mode 100644 index 0000000..6234632 --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvEvent.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CTVEVENT_H) +#define _CTVEVENT_H + +#include <utils/Vector.h> +#include "CTvProgram.h" +#include "CTvDatabase.h" +#include "CTvDimension.h" + +class CTvEvent : public LightRefBase<CTvEvent> { +public: + CTvEvent(CTvDatabase::Cursor &c); + CTvEvent(); + ~CTvEvent(); + + int getProgPresentEvent(int progSrc, int progID, long nowTime, CTvEvent &ev); + int getProgScheduleEvents(int progSrc, int progID, long start, long duration, Vector<sp<CTvEvent> > &vEv); + int getATVProgEvent(int progSrc, int progID, CTvEvent &ev); + int bookEvent(int evtId, bool bBookFlag); + static int selectByID(int id, CTvEvent &p); + static int CleanAllEvent(); + String8 &getName() + { + return name; + }; + String8 &getDescription() + { + return description; + }; + String8 &getExtDescription() + { + return extDescription; + }; + long getStartTime() + { + return start; + }; + long getEndTime() + { + return end; + }; + int getSubFlag() + { + return sub_flag; + }; + int getProgramId() + { + return programID; + }; + int getEventId() + { + return dvbEventID; + }; + Vector<CTvDimension::VChipRating *> getVChipRatings(); + +private: + void InitFromCursor(CTvDatabase::Cursor &c); + + int id; + int dvbEventID; + String8 name; + String8 description; + String8 extDescription; + int programID; + long start; + long end; + int dvbContent; + int dvbViewAge; + int sub_flag; + int rating_len; + Vector<CTvDimension::VChipRating *> vchipRatings; +}; + +#endif //_CTVEVENT_H diff --git a/tv/tvserver/libtv/tvdb/CTvGroup.cpp b/tv/tvserver/libtv/tvdb/CTvGroup.cpp new file mode 100644 index 0000000..fe7651a --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvGroup.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvGroup" + +#include "CTvGroup.h" + +Vector<CTvGroup> CTvGroup::selectByGroup() +{ + Vector<CTvGroup> vGroup; + return vGroup; +} + +void CTvGroup::addGroup() +{ + +} + +CTvGroup::CTvGroup() +{ + +} +CTvGroup::~CTvGroup() +{ + +} + +void CTvGroup::deleteGroup() +{ + +} + +void CTvGroup::editGroup() +{ + +} + diff --git a/tv/tvserver/libtv/tvdb/CTvGroup.h b/tv/tvserver/libtv/tvdb/CTvGroup.h new file mode 100644 index 0000000..a20d91b --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvGroup.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CTVGROUP_H) +#define _CTVGROUP_H + +#include <utils/Vector.h> +using namespace android; +class CTvGroup { +public: + CTvGroup(); + ~CTvGroup(); + static Vector<CTvGroup> selectByGroup(); + static void addGroup(); + static void deleteGroup(); + static void editGroup(); +}; + +#endif //_CTVGROUP_H diff --git a/tv/tvserver/libtv/tvdb/CTvProgram.cpp b/tv/tvserver/libtv/tvdb/CTvProgram.cpp new file mode 100644 index 0000000..4a94fa4 --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvProgram.cpp @@ -0,0 +1,900 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvProgram" + +#ifdef UNUSED +#elif defined(__GNUC__) +# define UNUSED(x) UNUSED_ ## x __attribute__((unused)) +#elif defined(__LCLINT__) +# define UNUSED(x) /*@unused@*/ x +#else +# define UNUSED(x) x +#endif + +#include "CTvProgram.h" +#include "CTvDatabase.h" +#include "CTvChannel.h" +#include "CTvEvent.h" + +CTvProgram::CTvProgram(CTvDatabase::Cursor &c) +{ + CreateFromCursor(c); +} + +CTvProgram::~CTvProgram() +{ + //free mem + // video + if (mpVideo != NULL) delete mpVideo; + // audios + int size = mvAudios.size(); + for (int i = 0; i < size; i++) + delete mvAudios[i]; + // subtitles + size = mvSubtitles.size(); + for (int i = 0; i < size; i++) + delete mvSubtitles[i]; + // teletexts + size = mvTeletexts.size(); + for (int i = 0; i < size; i++) + delete mvTeletexts[i]; +} + +CTvProgram::CTvProgram(int channelID __unused, int type __unused) +{ + mpVideo = NULL; +} + +CTvProgram::CTvProgram() +{ + mpVideo = NULL; +} + +CTvProgram::CTvProgram(const CTvProgram& UNUSED(cTvProgram)) +{ +} +//TODO +CTvProgram& CTvProgram::operator= (const CTvProgram& UNUSED(cTvProgram)) +{ + return *this; +} + +int CTvProgram::CreateFromCursor(CTvDatabase::Cursor &c) +{ + int i = 0; + int col; + int num, type; + int major, minor; + char tmp_buf[256]; + //LOGD("CTvProgram::CreateFromCursor"); + col = c.getColumnIndex("db_id"); + this->id = c.getInt(col); + + col = c.getColumnIndex("source_id"); + this->sourceID = c.getInt(col); + + col = c.getColumnIndex("src"); + this->src = c.getInt(col); + + col = c.getColumnIndex("service_id"); + this->dvbServiceID = c.getInt(col); + + col = c.getColumnIndex("db_ts_id"); + this->channelID = c.getInt(col); + + col = c.getColumnIndex("name"); + this->name = c.getString(col); + + col = c.getColumnIndex("chan_num"); + num = c.getInt(col); + + col = c.getColumnIndex("chan_order"); + this->chanOrderNum = c.getInt(col); + + col = c.getColumnIndex("major_chan_num"); + major = c.getInt(col); + + col = c.getColumnIndex("minor_chan_num"); + minor = c.getInt(col); + + col = c.getColumnIndex("aud_track"); + this->audioTrack = c.getInt(col); + + if (src == CTvChannel::MODE_ATSC || (src == CTvChannel::MODE_ANALOG && major > 0)) { + this->major = major; + this->minor = minor; + this->atscMode = true; + this->minorCheck = MINOR_CHECK_NONE; + } else { + this->major = num; + this->minor = 0; + this->atscMode = false; + this->minorCheck = MINOR_CHECK_NONE; + } + + col = c.getColumnIndex("service_type"); + this->type = c.getInt(col); + + col = c.getColumnIndex("pmt_pid"); + pmtPID = c.getInt(col); + + //LOGD("CTvProgram::CreateFromCursor type = %d", this->type); + col = c.getColumnIndex("skip"); + this->skip = c.getInt(col); + + col = c.getColumnIndex("lock"); + this->lock = (c.getInt(col) != 0); + + col = c.getColumnIndex("scrambled_flag"); + this->scrambled = (c.getInt(col) != 0); + + col = c.getColumnIndex("favor"); + this->favorite = (c.getInt(col) != 0); + + col = c.getColumnIndex("volume"); + this->volume = c.getInt(col); + + //Video + int pid, fmt; + col = c.getColumnIndex("vid_pid"); + pid = c.getInt(col); + + col = c.getColumnIndex("vid_fmt"); + fmt = c.getInt(col); + + //LOGD("----------vpid = %d", pid); + this->mpVideo = new Video(pid, fmt); + //LOGD("----------vpid = %d", this->mpVideo->getPID()); + + col = c.getColumnIndex("pcr_pid"); + this->pcrID = c.getInt(col); + + //Audio + String8 strPids; + String8 strFmts; + String8 strLangs; + int count = 0; + col = c.getColumnIndex("aud_pids"); + strPids = c.getString(col); + + col = c.getColumnIndex("aud_fmts"); + strFmts = c.getString(col); + + col = c.getColumnIndex("aud_langs"); + strLangs = c.getString(col); + col = c.getColumnIndex("current_aud"); + this->currAudTrackIndex = c.getInt(col); + + char *tmp; + Vector<String8> vpid ; + Vector<String8> vfmt ; + Vector<String8> vlang; + + char *pSave; + tmp = strtok_r(strPids.lockBuffer(strPids.length()), " ", &pSave); + while (tmp != NULL) { + vpid.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + strPids.unlockBuffer(); + + tmp = strtok_r(strFmts.lockBuffer(strFmts.length()), " ", &pSave); + while (tmp != NULL) { + vfmt.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + strFmts.unlockBuffer(); + + tmp = strtok_r(strLangs.lockBuffer(strLangs.length()), " ", &pSave); + + while (tmp != NULL) { + vlang.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + strLangs.unlockBuffer(); + + //check empty aud_langs + for (i = vlang.size(); i < (int)vpid.size(); i++) { + sprintf(tmp_buf, "Audio%d", i + 1); + vlang.push_back(String8(tmp_buf)); + LOGE("%s, aud_langs is empty, add dummy data (%s).\n", "TV", tmp_buf); + } + + //String8 l(vlang[i]); + for (i = 0; i < (int)vpid.size(); i++) { + int i_pid = atoi(vpid[i]); + int i_fmt = atoi(vfmt[i]); + mvAudios.push_back(new Audio(i_pid, vlang[i], i_fmt)); + } + + /* parse subtitles */ + vpid.clear(); + vlang.clear(); + Vector<String8> vcid; + Vector<String8> vaid; + String8 strCids; + String8 strAids; + + col = c.getColumnIndex("sub_pids"); + strPids = c.getString(col); + + col = c.getColumnIndex("sub_composition_page_ids"); + strCids = c.getString(col); + + col = c.getColumnIndex("sub_ancillary_page_ids"); + strAids = c.getString(col); + + col = c.getColumnIndex("sub_langs"); + strLangs = c.getString(col); + + tmp = strtok_r(strPids.lockBuffer(strPids.length()), " ", &pSave); + while (tmp != NULL) { + vpid.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + strPids.unlockBuffer(); + + tmp = strtok_r(strCids.lockBuffer(strCids.length()), " ", &pSave); + while (tmp != NULL) { + vcid.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + strCids.unlockBuffer(); + + tmp = strtok_r(strAids.lockBuffer(strAids.length()), " ", &pSave); + while (tmp != NULL) { + vaid.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + strAids.unlockBuffer(); + + tmp = strtok_r(strLangs.lockBuffer(strLangs.length()), " ", &pSave); + while (tmp != NULL) { + vlang.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + strLangs.unlockBuffer(); + + //Subtitle + for (int i = 0; i < (int)vpid.size(); i++) { + this->mvSubtitles.push_back(new Subtitle( + atoi(vpid[i]), + String8(vlang[i]), Subtitle::TYPE_DVB_SUBTITLE, + atoi(vcid[i]), + atoi(vaid[i]))); + } + + /* + parse teletexts + int ttx_count = 0, ttx_sub_count = 0; + String8 str_ttx_pids, str_ttx_types, str_mag_nos, str_page_nos, str_ttx_langs; + Vector<String8> v_ttx_pids, v_ttx_types, v_mag_nos, v_page_nos, v_ttx_langs; + col = c.getColumnIndex("ttx_pids"); + str_ttx_pids = c.getString(col); + + col = c.getColumnIndex("ttx_types"); + str_ttx_types = c.getString(col); + + col = c.getColumnIndex("ttx_magazine_nos"); + str_mag_nos = c.getString(col); + + col = c.getColumnIndex("ttx_page_nos"); + str_page_nos = c.getString(col); + + col = c.getColumnIndex("ttx_langs"); + str_ttx_langs = c.getString(col); + + tmp = strtok_r(str_ttx_pids.lockBuffer(str_ttx_pids.length()), " ", &pSave); + while (tmp != NULL) { + v_ttx_pids.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + str_ttx_pids.unlockBuffer(); + + tmp = strtok_r(str_ttx_types.lockBuffer(str_ttx_types.length()), " ", &pSave); + while (tmp != NULL) { + v_ttx_types.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + str_ttx_types.unlockBuffer(); + + tmp = strtok_r(str_mag_nos.lockBuffer(str_mag_nos.length()), " ", &pSave); + while (tmp != NULL) { + v_mag_nos.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + str_mag_nos.unlockBuffer(); + + tmp = strtok_r(str_page_nos.lockBuffer(str_page_nos.length()), " ", &pSave); + while (tmp != NULL) { + v_page_nos.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + str_page_nos.unlockBuffer(); + + tmp = strtok_r(str_ttx_langs.lockBuffer(str_ttx_langs.length()), " ", &pSave); + while (tmp != NULL) { + v_ttx_langs.push_back(String8(tmp)); + tmp = strtok_r(NULL, " ", &pSave); + } + str_ttx_langs.unlockBuffer(); + + for (int i = 0; i < v_ttx_pids.size(); i++) { + int ttype = atoi(v_ttx_types[i]); + if (ttype == 0x2 || ttype == 0x5) { + this->mvSubtitles.push_back(new Subtitle( + atoi(v_ttx_pids[i].string()), + String8(v_ttx_langs[i]), Subtitle::TYPE_DTV_TELETEXT, + atoi(v_mag_nos[i]), + atoi(v_page_nos[i]))); + } else { + this->mvTeletexts.push_back(new Teletext( + atoi(v_ttx_pids[i]), + String8(v_ttx_langs[i]), + atoi(v_mag_nos[i]), + atoi(v_page_nos[i]))); + } + } + */ + return 0; +} + +int CTvProgram::selectProgramInChannelByNumber(int channelID, int num, CTvDatabase::Cursor &c) +{ + String8 cmd = String8("select * from srv_table where db_ts_id = ") + String8::format("%d", channelID) + String8(" and "); + cmd += String8("chan_num = ") + String8::format("%d", num); + return CTvDatabase::GetTvDb()->select(cmd, c); +} + +int CTvProgram::selectProgramInChannelByNumber(int channelID, int major, int minor, CTvDatabase::Cursor &c) +{ + String8 cmd = String8("select * from srv_table where db_ts_id = ") + String8::format("%d", channelID) + String8(" and "); + cmd += String8("major_chan_num = ") + String8::format("%d", major) + String8(" and minor_chan_num = ") + String8::format("%d", minor); + + return CTvDatabase::GetTvDb()->select(cmd, c); +} + +CTvProgram::CTvProgram(int channelID, int type, int num, int skipFlag) +{ + CTvChannel channel; + int ret = CTvChannel::selectByID(channelID, channel); + if (ret != 0) { + //Log.d(TAG, "Cannot add new program, invalid channel id "+channelID); + this->id = -1; + } else { + CTvDatabase::Cursor c ; + selectProgramInChannelByNumber(channelID, num, c); + + if (c.moveToFirst()) { + /*Construct*/ + CreateFromCursor(c); + } else { + String8 tpids = String8(""), ttypes = String8(""), tmagnums = String8(""), tpgnums = String8(""), tlangs = String8(""); + String8 spids = String8(""), stypes = String8(""), scpgids = String8(""), sapgids = String8(""), slangs = String8(""); + + /*add a new atv program to database*/ + String8 cmd = String8("insert into srv_table(db_net_id,db_ts_id,service_id,src,name,service_type,"); + cmd += String8("eit_schedule_flag,eit_pf_flag,running_status,free_ca_mode,volume,aud_track,vid_pid,"); + cmd += String8("vid_fmt,aud_pids,aud_fmts,aud_langs,skip,lock,chan_num,major_chan_num,"); + cmd += String8("minor_chan_num,access_controlled,hidden,hide_guide,source_id,favor,current_aud,"); + cmd += String8("current_sub,sub_pids,sub_types,sub_composition_page_ids,sub_ancillary_page_ids,sub_langs,"); + cmd += String8("current_ttx,ttx_pids,ttx_types,ttx_magazine_nos,ttx_page_nos,ttx_langs,"); + cmd += String8("db_sat_para_id,scrambled_flag,lcn,hd_lcn,sd_lcn,default_chan_num,chan_order) "); + cmd += String8("values(-1,") + String8::format("%d", channelID) + String8(",65535,") + String8::format("%d", channel.getMode()) + String8(",'',") + String8::format("%d", type) + String8(","); + cmd += String8("0,0,0,0,0,0,8191,"); + int chanNum = num; + int majorNum = 0; + cmd += String8("-1,'','','',") + String8::format("%d", skipFlag) + String8(",0,") + String8::format("%d", chanNum) + String8(",") + String8::format("%d", majorNum) + String8(","); + cmd += String8("") + /*num.getMinor()*/String8("0") + String8(",0,0,0,-1,0,-1,"); + cmd += String8("-1,'") + spids + String8("','") + stypes + String8("','") + scpgids + String8("','") + sapgids + String8("','") + slangs + String8("',"); + cmd += String8("-1,'") + tpids + String8("','") + ttypes + String8("','") + tmagnums + String8("','") + tpgnums + String8("','") + tlangs + String8("',"); + cmd += String8("-1,0,-1,-1,-1,-1,0)"); + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + + CTvDatabase::Cursor cr; + selectProgramInChannelByNumber(channelID, num, cr); + if (cr.moveToFirst()) { + /*Construct*/ + CreateFromCursor(cr); + } else { + /*A critical error*/ + //Log.d(TAG, "Cannot add new program, sqlite error"); + this->id = -1; + } + cr.close(); + } + c.close(); + } + +} + +CTvProgram::CTvProgram(int channelID, int type, int major, int minor, int skipFlag) +{ + CTvChannel channel; + int ret = CTvChannel::selectByID(channelID, channel); + if (ret != 0) { + //Log.d(TAG, "Cannot add new program, invalid channel id "+channelID); + this->id = -1; + } else { + CTvDatabase::Cursor c ; + selectProgramInChannelByNumber(channelID, major, minor, c); + + if (c.moveToFirst()) { + /*Construct*/ + CreateFromCursor(c); + } else { + String8 tpids = String8(""), ttypes = String8(""), tmagnums = String8(""), tpgnums = String8(""), tlangs = String8(""); + String8 spids = String8(""), stypes = String8(""), scpgids = String8(""), sapgids = String8(""), slangs = String8(""); + + /*add a new atv program to database*/ + String8 cmd = String8("insert into srv_table(db_net_id,db_ts_id,service_id,src,name,service_type,"); + cmd += String8("eit_schedule_flag,eit_pf_flag,running_status,free_ca_mode,volume,aud_track,vid_pid,"); + cmd += String8("vid_fmt,aud_pids,aud_fmts,aud_langs,skip,lock,chan_num,major_chan_num,"); + cmd += String8("minor_chan_num,access_controlled,hidden,hide_guide,source_id,favor,current_aud,"); + cmd += String8("current_sub,sub_pids,sub_types,sub_composition_page_ids,sub_ancillary_page_ids,sub_langs,"); + cmd += String8("current_ttx,ttx_pids,ttx_types,ttx_magazine_nos,ttx_page_nos,ttx_langs,"); + cmd += String8("db_sat_para_id,scrambled_flag,lcn,hd_lcn,sd_lcn,default_chan_num,chan_order) "); + cmd += String8("values(-1,") + String8::format("%d", channelID) + String8(",65535,") + String8::format("%d", channel.getMode()) + String8(",'',") + String8::format("%d", type) + String8(","); + cmd += String8("0,0,0,0,0,0,8191,"); + int chanNum = major << 16 | minor; + int majorNum = major; + cmd += String8("-1,'','','',") + String8::format("%d", skipFlag) + String8(",0,") + String8::format("%d", chanNum) + String8(",") + String8::format("%d", majorNum) + String8(","); + cmd += String8("") + String8::format("%d", minor) + String8(",0,0,0,-1,0,-1,"); + cmd += String8("-1,'") + spids + String8("','") + stypes + String8("','") + scpgids + String8("','") + sapgids + String8("','") + slangs + String8("',"); + cmd += String8("-1,'") + tpids + String8("','") + ttypes + String8("','") + tmagnums + String8("','") + tpgnums + String8("','") + tlangs + String8("',"); + cmd += String8("-1,0,-1,-1,-1,-1,0)"); + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + + CTvDatabase::Cursor cr; + selectProgramInChannelByNumber(channelID, major, minor, cr); + if (cr.moveToFirst()) { + /*Construct*/ + CreateFromCursor(cr); + } else { + /*A critical error*/ + //Log.d(TAG, "Cannot add new program, sqlite error"); + this->id = -1; + } + cr.close(); + } + c.close(); + } + +} + +int CTvProgram::selectByID(int id, CTvProgram &prog) +{ + CTvDatabase::Cursor c; + String8 sql; + sql = String8("select * from srv_table where srv_table.db_id = ") + String8::format("%d", id); + CTvDatabase::GetTvDb()->select(sql.string(), c) ; + if (c.moveToFirst()) { + prog.CreateFromCursor(c); + } else { + c.close(); + return -1; + } + c.close(); + return 0; +} + +int CTvProgram::updateVolComp(int progID, int volValue) +{ + String8 cmd = String8("update srv_table set volume = ") + String8::format("%d", volValue) + + String8(" where srv_table.db_id = ") + String8::format("%d", progID); + LOGD("%s, cmd = %s\n", "TV", cmd.string()); + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + + return 0; +} + +int CTvProgram::getChannel(CTvChannel &c) +{ + return CTvChannel::selectByID(channelID, c); +} + +int CTvProgram::upDateChannel(CTvChannel &c __unused, int std, int Freq, int fineFreq) +{ + return CTvChannel::updateByID(channelID, std, Freq, fineFreq); +} + +int CTvProgram::deleteChannelsProgram(CTvChannel &c) +{ + String8 cmd; + cmd = String8("delete from srv_table where srv_table.db_ts_id = ") + String8::format("%d", c.getID()); + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + return 0; +} + +int CTvProgram::selectByNumber(int type, int num, CTvProgram &prog) +{ + String8 cmd; + + cmd = String8("select * from srv_table where "); + if (type != TYPE_UNKNOWN) { + if (type == TYPE_DTV) { + cmd += String8("(service_type = ") + String8::format("%d", TYPE_DTV) + String8(" or service_type = ") + String8::format("%d", TYPE_RADIO) + String8(") and "); + } else { + cmd += String8("service_type = ") + String8::format("%d", type) + String8(" and "); + } + } + + cmd += String8("chan_num = ") + String8::format("%d", num); + + CTvDatabase::Cursor c; + CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + prog.CreateFromCursor(c); + } else { + c.close(); + return -1; + } + c.close(); + + return 0; +} + +int CTvProgram::selectByNumber(int type, int major, int minor, CTvProgram &prog, int minor_check) +{ + String8 cmd; + + cmd = String8("select * from srv_table where "); + if (type != TYPE_UNKNOWN) { + if (type == TYPE_DTV) { + cmd += String8("(service_type = ") + String8::format("%d", TYPE_TV) + String8(" or service_type = ") + String8::format("%d", TYPE_RADIO) + String8(") and "); + } else { + cmd += String8("service_type = ") + String8::format("%d", type) + String8(" and "); + } + } + + if (minor < 0) { + /*recursive call*/ + /*select dtv program first*/ + //showbo + int ret = selectByNumber(TYPE_DTV, major, 1, prog, MINOR_CHECK_NEAREST_UP); + if (ret != 0) { + /*then try atv program*/ + selectByNumber(TYPE_ATV, major, 0 , prog, MINOR_CHECK_NONE); + } + return 0; + } else if (minor >= 1) { + if (minor_check == MINOR_CHECK_UP) { + cmd += String8("major_chan_num = ") + String8::format("%d", major) + String8(" and minor_chan_num >= ") + String8::format("%d", minor) + String8(" "); + cmd += String8("order by minor_chan_num DESC limit 1"); + } else if (minor_check == MINOR_CHECK_DOWN) { + cmd += String8("major_chan_num = ") + String8::format("%d", major) + String8(" and minor_chan_num <= ") + String8::format("%d", minor) + String8(" "); + cmd += String8("order by minor_chan_num limit 1"); + } else if (minor_check == MINOR_CHECK_NEAREST_UP) { + cmd += String8("major_chan_num = ") + String8::format("%d", major) + String8(" and minor_chan_num >= ") + String8::format("%d", minor) + String8(" "); + cmd += String8("order by minor_chan_num limit 1"); + } else if (minor_check == MINOR_CHECK_NEAREST_DOWN) { + cmd += String8("major_chan_num = ") + String8::format("%d", major) + String8(" and minor_chan_num <= ") + String8::format("%d", minor) + String8(" "); + cmd += String8("order by minor_chan_num DESC limit 1"); + } else { + cmd += String8("major_chan_num = ") + String8::format("%d", major) + String8(" and minor_chan_num = ") + String8::format("%d", minor); + } + } else { + cmd += String8("major_chan_num = ") + String8::format("%d", major) + String8(" and minor_chan_num = ") + String8::format("%d", minor); + } + + + CTvDatabase::Cursor c; + CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + prog.CreateFromCursor(c); + } else { + c.close(); + return -1; + } + c.close(); + + return 0; +} + +int CTvProgram::selectByChannel(int channelID, int type, Vector<sp<CTvProgram> > &out) +{ + //Vector<CTvProgram*> vp; + String8 cmd = String8("select * from srv_table "); + + if (type == TYPE_DTV) { + cmd += String8("where (service_type = ") + String8::format("%d", TYPE_TV) + String8(" or service_type = ") + String8::format("%d", TYPE_RADIO) + String8(") "); + } else if (type != TYPE_UNKNOWN) { + cmd += String8("where service_type = ") + String8::format("%d", type) + String8(" "); + } + + cmd += String8(" and db_ts_id = ") + String8::format("%d", channelID) + String8(" order by chan_order"); + + CTvDatabase::Cursor c; + int ret = CTvDatabase::GetTvDb()->select(cmd, c); + + LOGD("selectByChannel select ret = %d", ret); + + if (c.moveToFirst()) { + do { + out.add(new CTvProgram(c)); + } while (c.moveToNext()); + } + c.close(); + + return 0; +} + +void CTvProgram::deleteProgram(int progId) +{ + String8 cmd; + + cmd = String8("delete from srv_table where srv_table.db_id = ") + String8::format("%d", progId); + CTvDatabase::GetTvDb()->exeSql(cmd.string()); +} + +int CTvProgram::CleanAllProgramBySrvType(int srvType) +{ + String8 cmd = String8("delete from srv_table where service_type = ") + String8::format("%d", srvType); + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + return 0; +} + +int CTvProgram::selectByType(int type, int skip, Vector<sp<CTvProgram> > &out) +{ + String8 cmd = String8("select * from srv_table "); + LOGD("%s, type= %d\n", "TV", (int)type); + + if (type == TYPE_UNKNOWN) { + cmd += String8("where (service_type = ") + String8::format("%d", TYPE_ATV) + + String8(" or service_type = ") + String8::format("%d", TYPE_DTV) + + String8(" or service_type = ") + String8::format("%d", TYPE_RADIO) + + String8(") "); + } else { + cmd += String8("where service_type = ") + String8::format("%d", type) + String8(" "); + } + + if (skip == PROGRAM_SKIP_NO || skip == PROGRAM_SKIP_YES) + cmd += String8(" and skip = ") + String8::format("%d", skip) + String8(" "); + + if (type == TYPE_DTV || type == TYPE_RADIO) { + cmd += String8(" order by db_ts_id"); + } else { + cmd += String8(" order by chan_order"); + } + + CTvDatabase::Cursor c; + int ret = CTvDatabase::GetTvDb()->select(cmd, c); + + LOGD("selectByType select ret = %d", ret); + + if (c.moveToFirst()) { + do { + out.add(new CTvProgram(c)); + } while (c.moveToNext()); + } + c.close(); + + return 0; +} + +int CTvProgram::selectByChanID(int type, int skip, Vector < sp < CTvProgram > > &out) +{ + String8 cmd = String8("select * from srv_table "); + + if (type == TYPE_UNKNOWN) { + cmd += String8("where (service_type = ") + String8::format("%d", TYPE_ATV) + + String8(" or service_type = ") + String8::format("%d", TYPE_DTV) + + String8(") "); + } else { + cmd += String8("where service_type = ") + String8::format("%d", type) + String8(" "); + } + + if (skip == PROGRAM_SKIP_NO || skip == PROGRAM_SKIP_YES) + cmd += String8(" and skip = ") + String8::format("%d", PROGRAM_SKIP_NO) + + String8(" or skip = ") + String8::format("%d", PROGRAM_SKIP_YES) + String8(" "); + + cmd += String8(" order by db_id"); + + CTvDatabase::Cursor c; + int ret = CTvDatabase::GetTvDb()->select(cmd, c); + + if (c.moveToFirst()) { + do { + out.add(new CTvProgram(c)); + } while (c.moveToNext()); + } + c.close(); + + return 0; +} + +int CTvProgram::selectAll(bool no_skip, Vector<sp<CTvProgram> > &out) +{ + return selectByType(TYPE_UNKNOWN, no_skip, out); +} + +Vector<CTvProgram> CTvProgram::selectByChannel(int channelID __unused) +{ + Vector<CTvProgram> vProg; + return vProg; +} + +Vector<CTvProgram> CTvProgram::selectByName(int name __unused) +{ + Vector<CTvProgram> vProg; + return vProg; +} + +void CTvProgram::tvProgramDelByChannelID(int UNUSED(channelID)) +{ + //TODO +} + +String8 CTvProgram::getName() +{ + return name; +} + +int CTvProgram::getProgSkipFlag() +{ + return skip; +} + +int CTvProgram::getCurrentAudio(String8 defaultLang) +{ + CTvDatabase::Cursor c; + String8 cmd; + cmd = String8("select current_aud from srv_table where db_id = ") + String8::format("%d", this->id); + int ret = CTvDatabase::GetTvDb()->select(cmd, c); + LOGD("getCurrentAudio a size = %d", mvAudios.size()); + int id = 0; + if (c.moveToFirst()) { + id = c.getInt(0); + LOGD("getCurrentAudio a id = %d", id); + if (id < 0 && mvAudios.size() > 0) { + LOGD("getCurrentAudio defaultLang.isEmpty() =%s= %d", defaultLang.string(), defaultLang.isEmpty()); + if (!defaultLang.isEmpty()) { + for (int i = 0; i < (int)mvAudios.size(); i++) { + LOGD("getCurrentAudio a mvAudios[i] = %x", (long)mvAudios[i]); + if (mvAudios[i]->getLang() == defaultLang) { + id = i; + break; + } + } + } + + if (id < 0) { + /* still not found, using the first */ + id = 0; + } + } + } + LOGD("getCurrentAudio a idsss = %d", id); + c.close(); + + return id; +} + +int CTvProgram::getAudioChannel() +{ + return audioTrack; +} + +int CTvProgram::updateAudioChannel(int progId, int ch) +{ + String8 cmd; + + cmd = String8("update srv_table set aud_track =") + "\'" + String8::format("%d", ch) + "\'" + + String8(" where srv_table.db_id = ") + String8::format("%d", progId); + + return CTvDatabase::GetTvDb()->exeSql(cmd.string()); +} + +int CTvProgram::getSubtitleIndex(int progId) +{ + CTvDatabase::Cursor c; + String8 cmd = String8("select current_sub from srv_table where db_id = ") + String8::format("%d", progId); + int ret = CTvDatabase::GetTvDb()->select(cmd, c); + if (c.moveToFirst()) { + return c.getInt(0); + } else { + return -1; + } +} + +int CTvProgram::setSubtitleIndex(int progId, int index) +{ + String8 cmd = String8("update srv_table set current_sub = ") + String8::format("%d", index) + String8(" where db_id = ") + String8::format("%d", progId); + return CTvDatabase::GetTvDb()->exeSql(cmd.string()); +} + +int CTvProgram::getCurrAudioTrackIndex() +{ + int audTrackIdx = -1; + + if (-1 == currAudTrackIndex) { // no set field "current_aud" + audTrackIdx = getCurrentAudio(String8("eng")); + setCurrAudioTrackIndex(this->id, audTrackIdx); + } else { + audTrackIdx = currAudTrackIndex; + } + + return audTrackIdx; +} + +void CTvProgram::setCurrAudioTrackIndex(int programId, int audioIndex) +{ + String8 cmd; + + cmd = String8("update srv_table set current_aud = ") + + String8::format("%d", audioIndex) + String8(" where srv_table.db_id = ") + String8::format("%d", programId); + + CTvDatabase::GetTvDb()->exeSql(cmd.string()); +} + +void CTvProgram::setFavoriteFlag(int progId, bool bFavor) +{ + String8 cmd; + + cmd = String8("update srv_table set favor = ") + + String8::format("%d", bFavor ? 1 : 0) + String8(" where srv_table.db_id = ") + String8::format("%d", progId); + + CTvDatabase::GetTvDb()->exeSql(cmd.string()); +} + +void CTvProgram::setSkipFlag(int progId, bool bSkipFlag) +{ + String8 cmd; + + cmd = String8("update srv_table set skip = ") + String8::format("%d", bSkipFlag ? 1 : 0) + + String8(" where srv_table.db_id = ") + String8::format("%d", progId); + + CTvDatabase::GetTvDb()->exeSql(cmd.string()); +} + +void CTvProgram::updateProgramName(int progId, String8 strName) +{ + String8 newName = String8("xxx") + strName; + String8 cmd; + + cmd = String8("update srv_table set name =") + "\'" + String8::format("%s", newName.string()) + "\'" + + String8(" where srv_table.db_id = ") + String8::format("%d", progId); + + CTvDatabase::GetTvDb()->exeSql(cmd.string()); +} + +void CTvProgram::swapChanOrder(int ProgId1, int chanOrderNum1, int ProgId2, int chanOrderNum2) +{ + String8 cmd; + + cmd = String8("update srv_table set chan_order = ") + String8::format("%d", chanOrderNum2) + + String8(" where db_id = ") + String8::format("%d", ProgId1); + CTvDatabase::GetTvDb()->exeSql(cmd.string()); + + String8 cmd2; + cmd2 = String8("update srv_table set chan_order = ") + String8::format("%d", chanOrderNum1) + + String8(" where db_id = ") + String8::format("%d", ProgId2); + CTvDatabase::GetTvDb()->exeSql(cmd2.string()); +} + +void CTvProgram::setLockFlag(int progId, bool bLockFlag) +{ + String8 cmd; + + cmd = String8("update srv_table set lock = ") + String8::format("%d", bLockFlag ? 1 : 0) + + String8(" where srv_table.db_id = ") + String8::format("%d", progId); + + CTvDatabase::GetTvDb()->exeSql(cmd.string()); +} + +bool CTvProgram::getLockFlag() +{ + return lock; +} + diff --git a/tv/tvserver/libtv/tvdb/CTvProgram.h b/tv/tvserver/libtv/tvdb/CTvProgram.h new file mode 100644 index 0000000..87ecb44 --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvProgram.h @@ -0,0 +1,446 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + + +#if !defined(_CTVPROGRAM_H) +#define _CTVPROGRAM_H + +#include "CTvDatabase.h" +#include "CTvChannel.h" +#include <utils/String8.h> +#include <utils/RefBase.h> +#include <stdlib.h> +#include "CTvLog.h" +using namespace android; + +class CTvEvent; +class CTvProgram : public LightRefBase<CTvProgram> { +public: + + static const int TYPE_UNKNOWN = 0; + + static const int TYPE_TV = 4; + + static const int TYPE_RADIO = 2; + + static const int TYPE_ATV = 3; + + static const int TYPE_DATA = 5; + + static const int TYPE_DTV = 1 ; + /** PVR/Timeshifting playback program*/ + static const int TYPE_PLAYBACK = 6; + + static const int PROGRAM_SKIP_NO = 0; + static const int PROGRAM_SKIP_YES = 1; + static const int PROGRAM_SKIP_UNKOWN = 2; + +public: + class Element { + private : + int mpid; + + public : + Element(int pid) + { + this->mpid = pid; + } + + int getPID() + { + return mpid; + } + }; + + + +public: + class MultiLangElement : public Element { + private : + String8 mlang; + + public : + MultiLangElement(int pid, String8 lang): Element(pid) + { + this->mlang = lang; + } + + String8 getLang() + { + return mlang; + } + }; + +public : + class Video : public Element { + public: + /**MPEG1/2*/ + static const int FORMAT_MPEG12 = 0; + /**MPEG4*/ + static const int FORMAT_MPEG4 = 1; + /**H.264*/ + static const int FORMAT_H264 = 2; + /**MJPEG*/ + static const int FORMAT_MJPEG = 3; + /**Real video*/ + static const int FORMAT_REAL = 4; + /**JPEG*/ + static const int FORMAT_JPEG = 5; + /**Microsoft VC1*/ + static const int FORMAT_VC1 = 6; + /**AVS*/ + static const int FORMAT_AVS = 7; + /**YUV*/ + static const int FORMAT_YUV = 8; + /**H.264 MVC*/ + static const int FORMAT_H264MVC = 9; + /**QJPEG*/ + static const int FORMAT_QJPEG = 10; + + Video(int pid, int fmt): Element(pid) + { + this->mformat = fmt; + } + + int getFormat() + { + return mformat; + } + private : + int mformat; + }; + +public : + class Audio : public MultiLangElement { + public : + /**MPEG*/ + static const int FORMAT_MPEG = 0; + static const int FORMAT_PCM_S16LE = 1; + /**AAC*/ + static const int FORMAT_AAC = 2; + /**AC3*/ + static const int FORMAT_AC3 = 3; + /**ALAW*/ + static const int FORMAT_ALAW = 4; + /**MULAW*/ + static const int FORMAT_MULAW = 5; + /**DTS*/ + static const int FORMAT_DTS = 6; + + static const int FORMAT_PCM_S16BE = 7; + /**FLAC*/ + static const int FORMAT_FLAC = 8; + /**COOK*/ + static const int FORMAT_COOK = 9; + /**PCM*/ + static const int FORMAT_PCM_U8 = 10; + /**ADPCM*/ + static const int FORMAT_ADPCM = 11; + /**AMR*/ + static const int FORMAT_AMR = 12; + /**RAAC*/ + static const int FORMAT_RAAC = 13; + /**WMA*/ + static const int FORMAT_WMA = 14; + /**WMA Pro*/ + static const int FORMAT_WMAPRO = 15; + + static const int FORMAT_PCM_BLURAY = 16; + /**ALAC*/ + static const int FORMAT_ALAC = 17; + /**Vorbis*/ + static const int FORMAT_VORBIS = 18; + + static const int FORMAT_AAC_LATM = 19; + /**APE*/ + static const int FORMAT_APE = 20; + + + Audio(int pid, String8 lang, int fmt): MultiLangElement(pid, lang) + { + this->mformat = fmt; + } + + int getFormat() + { + return mformat; + } + private : + int mformat; + }; + +public : + class Subtitle : public MultiLangElement { + public : + /**DVB subtitle*/ + static const int TYPE_DVB_SUBTITLE = 1; + + static const int TYPE_DTV_TELETEXT = 2; + + static const int TYPE_ATV_TELETEXT = 3; + + static const int TYPE_DTV_CC = 4; + + static const int TYPE_ATV_CC = 5; + + + + Subtitle(int pid, String8 lang, int type, int num1, int num2): MultiLangElement(pid, lang) + { + + this->type = type; + if (type == TYPE_DVB_SUBTITLE) { + compositionPage = num1; + ancillaryPage = num2; + } else if (type == TYPE_DTV_TELETEXT) { + magazineNo = num1; + pageNo = num2; + } + } + + + int getType() + { + return type; + } + + + int getCompositionPageID() + { + return compositionPage; + } + + + int getAncillaryPageID() + { + return ancillaryPage; + } + + + int getMagazineNumber() + { + return magazineNo; + } + + int getPageNumber() + { + return pageNo; + } + + private : + int compositionPage; + int ancillaryPage; + int magazineNo; + int pageNo; + int type; + }; + + +public : + class Teletext : public MultiLangElement { + public: + Teletext(int pid, String8 lang, int mag, int page): MultiLangElement(pid, lang) + { + magazineNo = mag; + pageNo = page; + } + + int getMagazineNumber() + { + return magazineNo; + } + + int getPageNumber() + { + return pageNo; + } + + private : + int magazineNo; + int pageNo; + }; + + +public: + + static const int MINOR_CHECK_NONE = 0; + + static const int MINOR_CHECK_UP = 1; + + static const int MINOR_CHECK_DOWN = 2; + + static const int MINOR_CHECK_NEAREST_UP = 3; + + static const int MINOR_CHECK_NEAREST_DOWN = 4; + + int getNumber() + { + return major; + } + + int getMajor() + { + return major; + } + + int getMinor() + { + return minor; + } + + bool isATSCMode() + { + return atscMode; + } + + int getMinorCheck() + { + return minorCheck; + } + +private: + int major; + int minor; + int minorCheck; + bool atscMode; + + +public: + CTvProgram(CTvDatabase::Cursor &c); + CTvProgram(int channelID, int type, int num, int skipFlag); + CTvProgram(int channelID, int type, int major, int minor, int skipFlag); + ~CTvProgram(); + CTvProgram(int channelID, int type); + + CTvProgram(); + CTvProgram(const CTvProgram&); + CTvProgram& operator= (const CTvProgram& cTvProgram); + + + int getCurrentAudio(String8 defaultLang); + Video *getVideo() + { + return mpVideo; + } + Audio *getAudio(int id) + { + if (mvAudios.size() <= 0) return NULL; + return mvAudios[id]; + } + + int getAudioTrackSize() + { + return mvAudios.size(); + } + static int selectByID(int id, CTvProgram &p); + static CTvProgram selectByNumber(int num, int type); + int selectByNumber(int type, int major, int minor, CTvProgram &prog, int minor_check = MINOR_CHECK_NONE); + static int selectByNumber(int type, int num, CTvProgram &prog); + static int selectByChannel(int channelID, int type, Vector<sp<CTvProgram> > &out); + static int selectAll(bool no_skip, Vector<sp<CTvProgram> > &out); + static int selectByType(int type, int skip, Vector<sp<CTvProgram> > &out); + static int selectByChanID(int type, int skip, Vector<sp<CTvProgram> > &out); + static Vector<CTvProgram> selectByChannel(int channelID); + static Vector<CTvProgram> selectByName(int name); + void tvProgramDelByChannelID(int channelID); + int getID() + { + return id; + }; + int getSrc() + { + return src; + }; + int getProgType() + { + return type; + }; + int getChanOrderNum() + { + return chanOrderNum; + }; + int getChanVolume() + { + return volume; + }; + int getSourceId() + { + return sourceID; + }; + int getServiceId() + { + return dvbServiceID; + }; + int getPcrId() + { + return pcrID; + }; + + int getProgSkipFlag(); + int getSubtitleIndex(int progId); + int setSubtitleIndex(int progId, int index); + void setCurrAudioTrackIndex(int programId, int audioIndex); + int getCurrAudioTrackIndex(); + + String8 getName(); + void getCurrentSubtitle(); + void getCurrentTeletext(); + int getChannel(CTvChannel &c); + int upDateChannel(CTvChannel &c, int std, int freq, int fineFreq); + int updateVolComp(int progID, int volValue); + void updateProgramName(int progId, String8 strName); + void setSkipFlag(int progId, bool bSkipFlag); + void setFavoriteFlag(int progId, bool bFavor); + int getFavoriteFlag() + { + return favorite; + }; + void deleteProgram(int progId); + static int CleanAllProgramBySrvType(int srvType); + void setLockFlag(int progId, bool bLockFlag); + bool getLockFlag(); + void swapChanOrder(int ProgId1, int chanOrderNum1, int ProgId2, int chanOrderNum2); + int getAudioChannel(); + static int updateAudioChannel(int progId, int ch); + static int deleteChannelsProgram(CTvChannel &c); + Vector<Subtitle *> getSubtitles() + { + return mvSubtitles; + } +private: + friend class LightRefBase<CTvProgram>; + int CreateFromCursor(CTvDatabase::Cursor &c); + int selectProgramInChannelByNumber(int channelID, int num, CTvDatabase::Cursor &c); + int selectProgramInChannelByNumber(int channelID, int major, int minor, CTvDatabase::Cursor &c); + CTvChannel channel; + int id; + int dvbServiceID; + int type; + String8 name; + int channelID; + int skip; + int favorite; + int volume; + int sourceID; + int pmtPID; + int src; + int audioTrack; + int chanOrderNum; + int currAudTrackIndex; + bool lock; + bool scrambled; + Video *mpVideo; + int pcrID; + Vector<Audio *> mvAudios; + Vector<Subtitle *> mvSubtitles; + Vector<Teletext *> mvTeletexts; + +}; + +#endif //_CTVPROGRAM_H diff --git a/tv/tvserver/libtv/tvdb/CTvRegion.cpp b/tv/tvserver/libtv/tvdb/CTvRegion.cpp new file mode 100644 index 0000000..23cb1b4 --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvRegion.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvRegion" + +#include "CTvRegion.h" +#include "CTvDatabase.h" + +CTvRegion::CTvRegion(CTvDatabase db __unused) +{ +} + +CTvRegion::CTvRegion() +{ +} + +CTvRegion::~CTvRegion() +{ +} + +CTvRegion CTvRegion::selectByID() +{ + CTvRegion r; + return r; +} + +int CTvRegion::getChannelListByName(char *name, Vector<sp<CTvChannel> > &vcp) +{ + if (name == NULL) + return -1; + + String8 cmd; + cmd = String8("select * from region_table where name = ") + String8("\'") + name + String8("\'"); + + CTvDatabase::Cursor c; + CTvDatabase::GetTvDb()->select(cmd, c); + int col, size = 0; + int id; + int mode; + int frequency = 0; + int bandwidth; + int modulation; + int symbolRate; + int ofdmMode; + int channelNum = 0; + + if (c.moveToFirst()) { + do { + col = c.getColumnIndex("db_id"); + id = c.getInt(col); + col = c.getColumnIndex("fe_type"); + mode = c.getInt(col); + col = c.getColumnIndex("frequency"); + frequency = c.getInt(col); + col = c.getColumnIndex("modulation"); + modulation = c.getInt(col); + col = c.getColumnIndex("bandwidth"); + bandwidth = c.getInt(col); + col = c.getColumnIndex("symbol_rate"); + symbolRate = c.getInt(col); + col = c.getColumnIndex("ofdm_mode"); + ofdmMode = c.getInt(col); + col = c.getColumnIndex("logical_channel_num"); + channelNum = c.getInt(col); + vcp.add(new CTvChannel(id, mode, frequency, bandwidth, modulation, symbolRate, ofdmMode, channelNum)); + size++; + } while (c.moveToNext()); + } + c.close(); + + return size; +} + +int CTvRegion::getChannelListByNameAndFreqRange(char *name, int beginFreq, int endFreq, Vector<sp<CTvChannel> > &vcp) +{ + if (name == NULL) + return -1; + int ret = 0; + String8 cmd; + cmd = String8("select * from region_table where name = ") + String8("\'") + name + String8("\'") + + String8(" and frequency >= ") + String8::format("%d", beginFreq) + String8(" and frequency <= ") + + String8::format("%d", endFreq); + + CTvDatabase::Cursor c; + CTvDatabase::GetTvDb()->select(cmd, c); + int col, size = 0; + int id; + int mode; + int frequency = 0; + int bandwidth; + int modulation; + int symbolRate; + int ofdmMode; + int channelNum = 0; + + do { + if (c.moveToFirst()) { + do { + col = c.getColumnIndex("db_id"); + id = c.getInt(col); + col = c.getColumnIndex("fe_type"); + mode = c.getInt(col); + col = c.getColumnIndex("frequency"); + frequency = c.getInt(col); + col = c.getColumnIndex("modulation"); + modulation = c.getInt(col); + col = c.getColumnIndex("bandwidth"); + bandwidth = c.getInt(col); + col = c.getColumnIndex("symbol_rate"); + symbolRate = c.getInt(col); + col = c.getColumnIndex("ofdm_mode"); + ofdmMode = c.getInt(col); + col = c.getColumnIndex("logical_channel_num"); + channelNum = c.getInt(col); + vcp.add(new CTvChannel(id, mode, frequency, bandwidth, modulation, symbolRate, ofdmMode, channelNum)); + size++; + } while (c.moveToNext()); + } else { + ret = -1; + break; + } + } while (false); + + c.close(); + return ret; +} + +void CTvRegion::selectByCountry() +{ +} + +Vector<String8> CTvRegion::getAllCountry() +{ + Vector<String8> vStr; + return vStr; +} + +//CTvChannel CTvRegion::getChannels() +//{ +// CTvChannel p; +// return p; +//} + +int CTvRegion::getLogicNumByNameAndfreq(char *name, int freq) +{ + int ret = 0; + int col = 0; + + if (name == NULL) + return -1; + + String8 cmd; + cmd = String8("select * from region_table where name = ") + String8("\'") + name + String8("\'"); + cmd += String8(" and frequency = ") + String8::format("%d", freq); + + + CTvDatabase::Cursor c; + CTvDatabase::GetTvDb()->select(cmd, c); + if (c.moveToFirst()) { + col = c.getColumnIndex("logical_channel_num"); + ret = c.getInt(col); + } + c.close(); + + return ret; +} + diff --git a/tv/tvserver/libtv/tvdb/CTvRegion.h b/tv/tvserver/libtv/tvdb/CTvRegion.h new file mode 100644 index 0000000..ff94b38 --- a/dev/null +++ b/tv/tvserver/libtv/tvdb/CTvRegion.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CTVREGION_H) +#define _CTVREGION_H + +#include "CTvDatabase.h" +#include "CTvChannel.h" +#include <utils/String8.h> +#include <utils/Vector.h> + +using namespace android; +class CTvRegion { +public: + int id; + String8 name; + String8 country; + CTvRegion(CTvDatabase db); + CTvRegion(); + ~CTvRegion(); + static CTvRegion selectByID(); + static int getChannelListByName(char *name, Vector<sp<CTvChannel> > &vcp); + static int getChannelListByNameAndFreqRange(char *name, int beginFreq, int endFreq, Vector<sp<CTvChannel> > &vcp); + static int getLogicNumByNameAndfreq(char *name, int freq); + void selectByCountry(); + Vector<String8> getAllCountry(); + //CTvChannel getChannels(); +}; + +#endif //_CTVREGION_H diff --git a/tv/tvserver/libtv/tvin/CDevicesPollStatusDetect.cpp b/tv/tvserver/libtv/tvin/CDevicesPollStatusDetect.cpp new file mode 100644 index 0000000..1a1fffe --- a/dev/null +++ b/tv/tvserver/libtv/tvin/CDevicesPollStatusDetect.cpp @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CDevicesDetect" + +#include "CTvin.h" +#include <CTvLog.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/prctl.h> +#include <fcntl.h> +#include <errno.h> + +#include <cutils/log.h> + +#include <tvutils.h> +#include <tvconfig.h> + +#include "CDevicesPollStatusDetect.h" + +CDevicesPollStatusDetect::CDevicesPollStatusDetect() +{ + mVdinDetectFd = -1; + mpObserver = NULL; + if (mEpoll.create() < 0) { + return; + } + //avin + if (mAvinDetectFile.openFile(AVIN_DETECT_PATH) > 0) { + m_event.data.fd = mAvinDetectFile.getFd(); + m_event.events = EPOLLIN | EPOLLET; + mEpoll.add(mAvinDetectFile.getFd(), &m_event); + } + //HDMI + if (mHdmiDetectFile.openFile(HDMI_DETECT_PATH) > 0) { + m_event.data.fd = mHdmiDetectFile.getFd(); + m_event.events = EPOLLIN | EPOLLET; + mEpoll.add(mHdmiDetectFile.getFd(), &m_event); + } +} + +CDevicesPollStatusDetect::~CDevicesPollStatusDetect() +{ +} + +int CDevicesPollStatusDetect::startDetect() +{ + //signal status + int fd = CTvin::getInstance()->getVdinDeviceFd(); + if (fd > 0) { + m_event.data.fd = fd; + m_event.events = EPOLLIN | EPOLLET; + mEpoll.add(fd, &m_event); + + mVdinDetectFd = fd; + + LOGD("startDetect get vdin device fd :%d", fd); + } + this->run("CDevicesPollStatusDetect"); + return 0; +} + +char* CDevicesPollStatusDetect::inputToName(tv_source_input_t srcInput) { + char* inputName[] = { + /*"INVALID",*/ + "TV", + "AV1", + "AV2", + "YPBPR1", + "YPBPR2", + "HDMI1", + "HDMI2", + "HDMI3", + "HDMI4", + "VGA,", + "MPEG", + "DTV", + "SVIDEO", + "IPTV", + "DUMMY", + "SPDIF", + "ADTV", + "MAX" + }; + + if (SOURCE_INVALID == srcInput) + return "INVALID"; + else + return inputName[srcInput]; +} + +int CDevicesPollStatusDetect::SourceInputMaptoChipHdmiPort(tv_source_input_t source_input) +{ + tvin_port_t source_port = TVIN_PORT_NULL; + source_port = CTvin::getInstance()->Tvin_GetSourcePortBySourceInput(source_input); + switch (source_port) { + case TVIN_PORT_HDMI0: + return HDMI_DETECT_STATUS_BIT_A; + break; + case TVIN_PORT_HDMI1: + return HDMI_DETECT_STATUS_BIT_B; + break; + case TVIN_PORT_HDMI2: + return HDMI_DETECT_STATUS_BIT_C; + break; + case TVIN_PORT_HDMI3: + return HDMI_DETECT_STATUS_BIT_D; + break; + default: + return HDMI_DETECT_STATUS_BIT_A; + break; + } +} + +tv_source_input_t CDevicesPollStatusDetect::ChipHdmiPortMaptoSourceInput(int port) +{ + switch (port) { + case HDMI_DETECT_STATUS_BIT_A: + return CTvin::getInstance()->Tvin_PortToSourceInput(TVIN_PORT_HDMI0); + break; + case HDMI_DETECT_STATUS_BIT_B: + return CTvin::getInstance()->Tvin_PortToSourceInput(TVIN_PORT_HDMI1); + break; + case HDMI_DETECT_STATUS_BIT_C: + return CTvin::getInstance()->Tvin_PortToSourceInput(TVIN_PORT_HDMI2); + break; + case HDMI_DETECT_STATUS_BIT_D: + return CTvin::getInstance()->Tvin_PortToSourceInput(TVIN_PORT_HDMI3); + break; + default: + return CTvin::getInstance()->Tvin_PortToSourceInput(TVIN_PORT_HDMI0); + break; + } +} + +int CDevicesPollStatusDetect::GetSourceConnectStatus(tv_source_input_t source_input) +{ + int PlugStatus = -1; + int hdmi_status = 0; + int source = -1; + int HdmiDetectStatusBit = SourceInputMaptoChipHdmiPort((tv_source_input_t)source_input); + switch (source_input) { + case SOURCE_AV2: + case SOURCE_AV1: { + struct report_data_s status[2]; + mAvinDetectFile.readFile((void *)(&status), sizeof(struct report_data_s) * 2); + for (int i = 0; i < 2; i++) { + if (status[i].channel == AVIN_CHANNEL1) { + source = SOURCE_AV1; + } else if (status[i].channel == AVIN_CHANNEL2) { + source = SOURCE_AV2; + } + + if (source == source_input) { + if (status[i].status == AVIN_STATUS_IN) { + PlugStatus = CC_SOURCE_PLUG_IN; + } else { + PlugStatus = CC_SOURCE_PLUG_OUT; + } + break; + } + m_avin_status[i] = status[i]; + }//end for + + break; + } + case SOURCE_HDMI1: + case SOURCE_HDMI2: + case SOURCE_HDMI3: + case SOURCE_HDMI4:{ + mHdmiDetectFile.readFile((void *)(&hdmi_status), sizeof(int)); + if ((hdmi_status & HdmiDetectStatusBit) == HdmiDetectStatusBit) { + PlugStatus = CC_SOURCE_PLUG_IN; + } else { + PlugStatus = CC_SOURCE_PLUG_OUT; + } + m_hdmi_status = hdmi_status; + break; + } + default: + LOGD("GetSourceConnectStatus not support source :%s", inputToName(source_input)); + break; + } + + LOGD("GetSourceConnectStatus source :%s, status:%s", inputToName(source_input), (CC_SOURCE_PLUG_IN == PlugStatus)?"plug in":"plug out"); + return PlugStatus; +} + +bool CDevicesPollStatusDetect::threadLoop() +{ + if ( mpObserver == NULL ) { + return false; + } + + LOGD("detect thread start"); + + prctl(PR_SET_NAME, (unsigned long)"CDevicesPollStatusDetect thread loop"); + //init status + mHdmiDetectFile.readFile((void *)(&m_hdmi_status), sizeof(int)); + mAvinDetectFile.readFile((void *)(&m_avin_status), sizeof(struct report_data_s) * 2); + LOGD("CDevicesPollStatusDetect Loop, get init hdmi = 0x%x avin[0].status = %d, avin[1].status = %d", m_hdmi_status, m_avin_status[0].status, m_avin_status[1].status); + + while (!exitPending()) { //requietexit() or requietexitWait() not call + int num = mEpoll.wait(); + for (int i = 0; i < num; ++i) { + int fd = (mEpoll)[i].data.fd; + /** + * EPOLLIN event + */ + if ((mEpoll)[i].events & EPOLLIN) { + if (fd == mAvinDetectFile.getFd()) {//avin + struct report_data_s status[2]; + mAvinDetectFile.readFile((void *)(&status), sizeof(struct report_data_s) * 2); + for (int i = 0; i < 2; i++) { + int source = -1, plug = -1; + if (/*status[i].channel == m_avin_status[i].channel &&*/ status[i].status != m_avin_status[i].status) { + //LOGD("status[i].status != m_avin_status[i].status"); + if (status[i].status == AVIN_STATUS_IN) { + plug = CC_SOURCE_PLUG_IN; + } else { + plug = CC_SOURCE_PLUG_OUT; + } + + if (status[i].channel == AVIN_CHANNEL1) { + source = SOURCE_AV1; + } else if (status[i].channel == AVIN_CHANNEL2) { + source = SOURCE_AV2; + } + + LOGD("%s detected\n", inputToName((tv_source_input_t)source)); + if (mpObserver != NULL) { + mpObserver->onSourceConnect(source, plug); + } + }//not equal + m_avin_status[i] = status[i]; + } + } else if (fd == mHdmiDetectFile.getFd()) { //hdmi + int hdmi_status = 0; + mHdmiDetectFile.readFile((void *)(&hdmi_status), sizeof(int)); + LOGD("HDMI detected\n"); + int source = -1, plug = -1; + if ((hdmi_status & HDMI_DETECT_STATUS_BIT_A) != (m_hdmi_status & HDMI_DETECT_STATUS_BIT_A) ) { + if ((hdmi_status & HDMI_DETECT_STATUS_BIT_A) == HDMI_DETECT_STATUS_BIT_A) { + source = ChipHdmiPortMaptoSourceInput(HDMI_DETECT_STATUS_BIT_A); + plug = CC_SOURCE_PLUG_IN; + } else { + source = ChipHdmiPortMaptoSourceInput(HDMI_DETECT_STATUS_BIT_A); + plug = CC_SOURCE_PLUG_OUT; + } + mpObserver->onSourceConnect(source, plug); + } + + if ((hdmi_status & HDMI_DETECT_STATUS_BIT_B) != (m_hdmi_status & HDMI_DETECT_STATUS_BIT_B) ) { + if ((hdmi_status & HDMI_DETECT_STATUS_BIT_B) == HDMI_DETECT_STATUS_BIT_B) { + source = ChipHdmiPortMaptoSourceInput(HDMI_DETECT_STATUS_BIT_B); + plug = CC_SOURCE_PLUG_IN; + } else { + source = ChipHdmiPortMaptoSourceInput(HDMI_DETECT_STATUS_BIT_B); + plug = CC_SOURCE_PLUG_OUT; + } + mpObserver->onSourceConnect(source, plug); + } + + if ((hdmi_status & HDMI_DETECT_STATUS_BIT_C) != (m_hdmi_status & HDMI_DETECT_STATUS_BIT_C) ) { + if ((hdmi_status & HDMI_DETECT_STATUS_BIT_C) == HDMI_DETECT_STATUS_BIT_C) { + source = ChipHdmiPortMaptoSourceInput(HDMI_DETECT_STATUS_BIT_C); + plug = CC_SOURCE_PLUG_IN; + } else { + source = ChipHdmiPortMaptoSourceInput(HDMI_DETECT_STATUS_BIT_C); + plug = CC_SOURCE_PLUG_OUT; + } + mpObserver->onSourceConnect(source, plug); + } + + if ((hdmi_status & HDMI_DETECT_STATUS_BIT_D) != (m_hdmi_status & HDMI_DETECT_STATUS_BIT_D) ) { + if ((hdmi_status & HDMI_DETECT_STATUS_BIT_D) == HDMI_DETECT_STATUS_BIT_D) { + source = ChipHdmiPortMaptoSourceInput(HDMI_DETECT_STATUS_BIT_D); + plug = CC_SOURCE_PLUG_IN; + } else { + source = ChipHdmiPortMaptoSourceInput(HDMI_DETECT_STATUS_BIT_D); + plug = CC_SOURCE_PLUG_OUT; + } + mpObserver->onSourceConnect(source, plug); + } + + int pc_mode_status = (hdmi_status >> 4); + mpObserver->onSetPQPCMode(source, pc_mode_status); + + m_hdmi_status = hdmi_status; + }else if ( fd == mVdinDetectFd ) { + LOGD("VDIN detected\n"); + if (mpObserver != NULL) { + mpObserver->onVdinSignalChange(); + } + } + + if ((mEpoll)[i].events & EPOLLOUT) { + + } + } + } + }//exit + + LOGD("CDevicesPollStatusDetect, exiting...\n"); + //return true, run again, return false,not run. + return false; +} diff --git a/tv/tvserver/libtv/tvin/CDevicesPollStatusDetect.h b/tv/tvserver/libtv/tvin/CDevicesPollStatusDetect.h new file mode 100644 index 0000000..a0cd307 --- a/dev/null +++ b/tv/tvserver/libtv/tvin/CDevicesPollStatusDetect.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef C_SOURCE_CONNECT_DETECT_H +#define C_SOURCE_CONNECT_DETECT_H + +#include <utils/Thread.h> +#include <CFile.h> +#include <zepoll.h> + +enum avin_status_e { + AVIN_STATUS_IN = 0, + AVIN_STATUS_OUT = 1, + AVIN_STATUS_UNKNOW = 2, +}; +enum avin_channel_e { + AVIN_CHANNEL1 = 0, + AVIN_CHANNEL2 = 1, +}; + +struct report_data_s { + enum avin_channel_e channel; + enum avin_status_e status; +}; + +/* +3 R 0 stat_5v_portD: +Status of 5v power for port D. +2 R 0 stat_5v_portC: +Status of 5v power for port C. +1 R 0 stat_5v_portB: +Status of 5v power for port B. +0 R 0 stat_5v_portA: +Status of 5v power for port A. + */ +static const int HDMI_DETECT_STATUS_BIT_A = 0x01; +static const int HDMI_DETECT_STATUS_BIT_B = 0x02; +static const int HDMI_DETECT_STATUS_BIT_C = 0x04; +static const int HDMI_DETECT_STATUS_BIT_D = 0x08; + +static const char *AVIN_DETECT_PATH = "/dev/avin_detect"; +static const char *HDMI_DETECT_PATH = "/dev/hdmirx0"; +static const char *VPP_POLL_PATCH = "/dev/amvideo_poll"; + +using namespace android; +class CDevicesPollStatusDetect: public Thread { +public: + CDevicesPollStatusDetect(); + ~CDevicesPollStatusDetect(); + int startDetect(); + int GetSourceConnectStatus(tv_source_input_t source_input); + int SourceInputMaptoChipHdmiPort(tv_source_input_t source_input); + tv_source_input_t ChipHdmiPortMaptoSourceInput(int port); + + class ISourceConnectObserver { + public: + ISourceConnectObserver() {}; + virtual ~ISourceConnectObserver() {}; + virtual void onSourceConnect(int source __unused, int connect_status __unused) {}; + virtual void onVdinSignalChange() {}; + virtual void onSetPQPCMode(int source, int status) {}; + }; + + void setObserver ( ISourceConnectObserver *pOb ) { + mpObserver = pOb; + }; +private: + bool threadLoop(); + char* inputToName(tv_source_input_t srcInput); + + int mVdinDetectFd; + ISourceConnectObserver *mpObserver; + Epoll mEpoll; + mutable Mutex mLock; + epoll_event m_event; + CFile mAvinDetectFile; + CFile mHdmiDetectFile; + CFile mVppPollFile; + struct report_data_s m_avin_status[2]; + int m_hdmi_status; +}; +#endif diff --git a/tv/tvserver/libtv/tvin/CHDMIRxManager.cpp b/tv/tvserver/libtv/tvin/CHDMIRxManager.cpp new file mode 100644 index 0000000..c8919d7 --- a/dev/null +++ b/tv/tvserver/libtv/tvin/CHDMIRxManager.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CHDMIRxManager" + +#include "CHDMIRxManager.h" +#include <fcntl.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <CTvLog.h> +#include <tvutils.h> + + +CHDMIRxManager::CHDMIRxManager() +{ + +} + +CHDMIRxManager::~CHDMIRxManager() +{ +} + +int CHDMIRxManager::HdmiRxEdidUpdate() +{ + int m_hdmi_fd = -1; + m_hdmi_fd = open(CS_HDMIRX_DEV_PATH, O_RDWR); + if (m_hdmi_fd < 0) { + LOGE("%s, Open file %s error: (%s)!\n", __FUNCTION__, CS_HDMIRX_DEV_PATH, strerror ( errno )); + return -1; + } + ioctl(m_hdmi_fd, HDMI_IOC_EDID_UPDATE, 1); + close(m_hdmi_fd); + m_hdmi_fd = -1; + return 0; +} + +int CHDMIRxManager::HdmiRxHdcpVerSwitch(tv_hdmi_hdcp_version_t version) +{ + int m_hdmi_fd = -1; + m_hdmi_fd = open(CS_HDMIRX_DEV_PATH, O_RDWR); + if (m_hdmi_fd < 0) { + LOGE("%s, Open file %s error: (%s)!\n", __FUNCTION__, CS_HDMIRX_DEV_PATH, strerror ( errno )); + return -1; + } + if (HDMI_HDCP_VER_14 == version) { + ioctl(m_hdmi_fd, HDMI_IOC_HDCP22_FORCE14, NULL); + } else if (HDMI_HDCP_VER_22 == version) { + ioctl(m_hdmi_fd, HDMI_IOC_HDCP22_AUTO, NULL); + } else { + close(m_hdmi_fd); + m_hdmi_fd = -1; + return -1; + } + close(m_hdmi_fd); + m_hdmi_fd = -1; + return 0; +} + +int CHDMIRxManager::HdmiRxHdcpOnOff(tv_hdmi_hdcpkey_enable_t flag) +{ + int m_hdmi_fd = -1; + + m_hdmi_fd = open(CS_HDMIRX_DEV_PATH, O_RDWR); + if (m_hdmi_fd < 0) { + LOGE("%s, Open file %s error: (%s)!\n", __FUNCTION__, CS_HDMIRX_DEV_PATH, strerror ( errno )); + return -1; + } + + if (hdcpkey_enable == flag) { + ioctl(m_hdmi_fd, HDMI_IOC_HDCP_ON, NULL); + }else if (hdcpkey_enable == flag) { + ioctl(m_hdmi_fd, HDMI_IOC_HDCP_OFF, NULL); + }else { + return -1; + } + + close(m_hdmi_fd); + m_hdmi_fd = -1; + + return 0; +} + +int CHDMIRxManager::GetHdmiHdcpKeyKsvInfo(struct _hdcp_ksv *msg) +{ + int m_hdmi_fd = -1; + + m_hdmi_fd = open(CS_HDMIRX_DEV_PATH, O_RDWR); + if (m_hdmi_fd < 0) { + LOGE("%s, Open file %s error: (%s)!\n", __FUNCTION__, CS_HDMIRX_DEV_PATH, strerror ( errno )); + return -1; + } + + ioctl(m_hdmi_fd, HDMI_IOC_HDCP_GET_KSV, msg); + + close(m_hdmi_fd); + m_hdmi_fd = -1; + + return 0; +} + +int CHDMIRxManager::SetHdmiColorRangeMode(tv_hdmi_color_range_t range_mode) +{ + char val[5] = {0}; + sprintf(val, "%d", range_mode); + tvWriteSysfs(HDMI_FORCE_COLOR_RANGE, val); + return 0; +} + +tv_hdmi_color_range_t CHDMIRxManager::GetHdmiColorRangeMode() +{ + char value[5] = {0}; + tvReadSysfs(HDMI_FORCE_COLOR_RANGE, value); + + return (tv_hdmi_color_range_t)atoi(value); +} + +int CHDMIRxManager::SetHdmiPortCecPhysicAddr() +{ + char val[10] = {0}; + tv_source_input_t tmpHdmiPortCecPhysicAddr[4] = {SOURCE_MAX}; + tvin_port_t tvInport[4] = {TVIN_PORT_HDMI0,TVIN_PORT_HDMI1,TVIN_PORT_HDMI2,TVIN_PORT_HDMI3}; + int HdmiPortCecPhysicAddr = 0x0; + for (int i = 0; i < 4; i++) { + tmpHdmiPortCecPhysicAddr[i] = CTvin::getInstance()->Tvin_PortToSourceInput(tvInport[i]); + } + HdmiPortCecPhysicAddr |= ((tmpHdmiPortCecPhysicAddr[0] == SOURCE_MAX? 0xf:(tmpHdmiPortCecPhysicAddr[0]-4)) + |((tmpHdmiPortCecPhysicAddr[1] == SOURCE_MAX? 0xf:(tmpHdmiPortCecPhysicAddr[1]-4)) << 4) + |((tmpHdmiPortCecPhysicAddr[2] == SOURCE_MAX? 0xf:(tmpHdmiPortCecPhysicAddr[2]-4)) << 8) + |((tmpHdmiPortCecPhysicAddr[3] == SOURCE_MAX? 0xf:(tmpHdmiPortCecPhysicAddr[3]-4)) << 12)); + sprintf(val, "%x", HdmiPortCecPhysicAddr); + tvWriteSysfs(HDMI_CEC_PORT_SEQUENCE, val); + memset(val,0,10); + sprintf(val, "%d", HdmiPortCecPhysicAddr); + tvWriteSysfs(HDMI_CEC_PORT_MAP,val); + return 0; +} + diff --git a/tv/tvserver/libtv/tvin/CHDMIRxManager.h b/tv/tvserver/libtv/tvin/CHDMIRxManager.h new file mode 100644 index 0000000..a94d81c --- a/dev/null +++ b/tv/tvserver/libtv/tvin/CHDMIRxManager.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _C_HDMI_RX_MANAGER_H_ +#define _C_HDMI_RX_MANAGER_H_ + + +#include "CTvin.h" + +#define HDMI_IOC_MAGIC 'H' +#define HDMI_IOC_HDCP_ON _IO(HDMI_IOC_MAGIC, 0x01) +#define HDMI_IOC_HDCP_OFF _IO(HDMI_IOC_MAGIC, 0x02) +#define HDMI_IOC_EDID_UPDATE _IO(HDMI_IOC_MAGIC, 0x03) +#define HDMI_IOC_PC_MODE_ON _IO(HDMI_IOC_MAGIC, 0x04) +#define HDMI_IOC_PC_MODE_OFF _IO(HDMI_IOC_MAGIC, 0x05) +#define HDMI_IOC_HDCP22_AUTO _IO(HDMI_IOC_MAGIC, 0x06) +#define HDMI_IOC_HDCP22_FORCE14 _IO(HDMI_IOC_MAGIC, 0x07) + +#define HDMI_IOC_HDCP_GET_KSV _IOR(HDMI_IOC_MAGIC, 0x09, struct _hdcp_ksv) + + +#define CS_HDMIRX_DEV_PATH "/dev/hdmirx0" +#define HDMI_FORCE_COLOR_RANGE "/sys/module/tvin_hdmirx/parameters/force_color_range" +#define HDMIRX0_DEBUG_PATH "/sys/class/hdmirx/hdmirx0/debug" +#define HDMI_CEC_PORT_SEQUENCE "/sys/class/cec/port_seq" +#define HDMI_CEC_PORT_MAP "/sys/module/tvin_hdmirx/parameters/port_map" + + +typedef struct _hdcp_ksv { + int bksv0; + int bksv1; +} _hdcp_ksv; + +class CHDMIRxManager { + public: + CHDMIRxManager(); + ~CHDMIRxManager(); + int HdmiRxEdidUpdate(); + int HdmiRxHdcpVerSwitch(tv_hdmi_hdcp_version_t version); + int HdmiRxHdcpOnOff(tv_hdmi_hdcpkey_enable_t flag); + int GetHdmiHdcpKeyKsvInfo(struct _hdcp_ksv *msg); + int SetHdmiColorRangeMode(tv_hdmi_color_range_t range_mode); + tv_hdmi_color_range_t GetHdmiColorRangeMode(); + int SetHdmiPortCecPhysicAddr(); +}; + +#endif/*_C_HDMI_RX_MANAGER_H_*/ diff --git a/tv/tvserver/libtv/tvin/CTvin.cpp b/tv/tvserver/libtv/tvin/CTvin.cpp new file mode 100644 index 0000000..cb9088b --- a/dev/null +++ b/tv/tvserver/libtv/tvin/CTvin.cpp @@ -0,0 +1,2201 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvin" + +#include "CTvin.h" +#include <CTvLog.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> +#include <dlfcn.h> +#include <linux/fb.h> +#include <stdlib.h> +#include <cutils/properties.h> +#include <cutils/log.h> +#include <sys/mman.h> +#include "CAv.h" +#include "../tvsetting/CTvSetting.h" +#include <tvutils.h> +#include <tvconfig.h> +#include "fbcutils/CFbcCommunication.h" + +#define AFE_DEV_PATH "/dev/tvafe0" +#define AMLVIDEO2_DEV_PATH "/dev/video11" +#define VDIN0_ATTR_PATH "/sys/class/vdin/vdin0/attr" +#define VDIN1_ATTR_PATH "/sys/class/vdin/vdin1/attr" + + + +#define CC_SEL_VDIN_DEV (0) + +/* ADC calibration pattern & format define */ +/* default 100% 8 color-bar */ +//#define VGA_SOURCE_RGB444 +#define VGA_H_ACTIVE (1024) +#define VGA_V_ACTIVE (768) +#define COMP_H_ACTIVE (1280) +#define COMP_V_ACTIVE (720) +#define CVBS_H_ACTIVE (720) +#define CVBS_V_ACTIVE (480) + +int CTvin::mSourceInputToPortMap[SOURCE_MAX]; +CTvin *CTvin::mInstance; + +CTvin *CTvin::getInstance() +{ + if (NULL == mInstance) mInstance = new CTvin(); + return mInstance; +} + +CTvin::CTvin() : mAfeDevFd(-1), mVdin0DevFd(-1) +{ + m_snow_status = false; + + m_tvin_param.index = 0; + mDecoderStarted = false; + gVideoPath[0] = '\0'; + + for (int i = 0; i < SOURCE_MAX; i++) { + mSourceInputToPortMap[i] = TVIN_PORT_NULL; + } + + mSourceInputToPortMap[SOURCE_TV] = TVIN_PORT_CVBS3; + mSourceInputToPortMap[SOURCE_AV1] = TVIN_PORT_CVBS1; + mSourceInputToPortMap[SOURCE_AV2] = TVIN_PORT_CVBS2; + mSourceInputToPortMap[SOURCE_YPBPR1] = TVIN_PORT_COMP0; + mSourceInputToPortMap[SOURCE_YPBPR2] = TVIN_PORT_COMP1; + mSourceInputToPortMap[SOURCE_HDMI1] = TVIN_PORT_HDMI0; + mSourceInputToPortMap[SOURCE_HDMI2] = TVIN_PORT_HDMI2; + mSourceInputToPortMap[SOURCE_HDMI3] = TVIN_PORT_HDMI1; + mSourceInputToPortMap[SOURCE_HDMI4] = TVIN_PORT_HDMI3; + mSourceInputToPortMap[SOURCE_VGA] = TVIN_PORT_VGA0; + mSourceInputToPortMap[SOURCE_MPEG] = TVIN_PORT_MPEG0; + mSourceInputToPortMap[SOURCE_DTV] = TVIN_PORT_DTV; + mSourceInputToPortMap[SOURCE_IPTV] = TVIN_PORT_BT656; + mSourceInputToPortMap[SOURCE_SPDIF] = TVIN_PORT_CVBS3; + //init_vdin(); +} + +CTvin::~CTvin() +{ +} + +int CTvin::OpenTvin() +{ + const char *config_value; + config_value = config_get_str ( CFG_SECTION_TV, "tvin.manual.set.tvpath", "null" ); + strcpy ( config_tv_path, config_value ); + memset ( config_default_path, 0x0, 64 ); + config_value = config_get_str ( CFG_SECTION_TV, "tvin.manual.set.defaultpath", "null" ); + strcpy ( config_default_path, config_value ); + return 0; +} + +int CTvin::setMpeg2Vdin(int enable) +{ + /* let output data loop to vdin */ + char str[32] = {0}; + sprintf (str, "%d", enable); + return tvWriteSysfs("/sys/module/di/parameters/mpeg2vdin_en", str); +} + +int CTvin::VDIN_AddPath ( const char *videopath ) +{ + if (strlen(videopath) > 1024) { + LOGE("video path too long\n"); + return -1; + } + + char str[1024 + 1] = {0}; + sprintf (str, "%s", videopath); + return tvWriteSysfs(SYS_VFM_MAP_PATH, str); +} + +int CTvin::VDIN_RmDefPath ( void ) +{ + return tvWriteSysfs(SYS_VFM_MAP_PATH, "rm default"); +} + +int CTvin::VDIN_RmTvPath ( void ) +{ + return tvWriteSysfs(SYS_VFM_MAP_PATH, "rm tvpath"); +} + +int CTvin::VDIN_AddVideoPath ( int selPath ) +{ + int ret = -1; + std::string vdinPath; + std::string suffixVideoPath("ppmgr deinterlace amvideo"); + bool amlvideo2Exist = isFileExist(AMLVIDEO2_DEV_PATH); + switch ( selPath ) { + case TV_PATH_VDIN_AMLVIDEO2_PPMGR_DEINTERLACE_AMVIDEO: + if (amlvideo2Exist) + vdinPath = "add tvpath vdin0 amlvideo2.0 "; + else + vdinPath = "add tvpath vdin0 "; + break; + + case TV_PATH_DECODER_AMLVIDEO2_PPMGR_DEINTERLACE_AMVIDEO: + if (amlvideo2Exist) + vdinPath = "add default decoder amlvideo2.0 "; + else + vdinPath = "add default decoder "; + break; + default: + break; + } + + vdinPath += suffixVideoPath; + ret = VDIN_AddPath (vdinPath.c_str()); + return ret; +} + +int CTvin::getVdinDeviceFd() { + if (mVdin0DevFd < 0) { + mVdin0DevFd = VDIN_OpenModule(); + } + return mVdin0DevFd; +} + +int CTvin::VDIN_OpenModule() +{ + char file_name[64]; + sprintf ( file_name, "/dev/vdin%d", CC_SEL_VDIN_DEV ); + int fd = open ( file_name, O_RDWR ); + if ( fd < 0 ) { + LOGW ( "Open %s error(%s)!\n", file_name, strerror ( errno ) ); + return -1; + } + + memset ( &gTvinVDINParam, 0, sizeof ( gTvinVDINParam ) ); + memset ( &gTvinVDINSignalInfo, 0, sizeof ( gTvinVDINSignalInfo ) ); + + LOGD ( "Open vdin%d module fd = [%d]", CC_SEL_VDIN_DEV, fd ); + + //mVdin0DevFd = fd; + return fd; +} + +int CTvin::VDIN_CloseModule() +{ + if ( mVdin0DevFd != -1 ) { + close ( mVdin0DevFd ); + mVdin0DevFd = -1; + } + + return 0; +} + +int CTvin::VDIN_DeviceIOCtl ( int request, ... ) +{ + int tmp_ret = -1; + va_list ap; + void *arg; + + if (mVdin0DevFd < 0) { + mVdin0DevFd = VDIN_OpenModule(); + } + + if ( mVdin0DevFd >= 0 ) { + va_start ( ap, request ); + arg = va_arg ( ap, void * ); + va_end ( ap ); + + tmp_ret = ioctl ( mVdin0DevFd, request, arg ); + return tmp_ret; + } + + return -1; +} + +int CTvin::VDIN_OpenPort ( tvin_port_t port ) +{ + struct tvin_parm_s vdinParam; + vdinParam.port = port; + vdinParam.index = 0; + int rt = VDIN_DeviceIOCtl ( TVIN_IOC_OPEN, &vdinParam ); + if ( rt < 0 ) { + LOGW ( "Vdin open port, error(%s)!", strerror ( errno ) ); + } + + return rt; +} + +int CTvin::VDIN_ClosePort() +{ + int rt = VDIN_DeviceIOCtl ( TVIN_IOC_CLOSE ); + if ( rt < 0 ) { + LOGW ( "Vdin close port, error(%s)!", strerror ( errno ) ); + } + + return rt; +} + +int CTvin::VDIN_StartDec ( const struct tvin_parm_s *vdinParam ) +{ + if ( vdinParam == NULL ) { + return -1; + } + + LOGD ( "VDIN_StartDec: index = [%d] port = [0x%x] format = [0x%x]\n", + vdinParam->index, ( unsigned int ) vdinParam->port, ( unsigned int ) ( vdinParam->info.fmt )); + int rt = VDIN_DeviceIOCtl ( TVIN_IOC_START_DEC, vdinParam ); + if ( rt < 0 ) { + LOGW ( "Vdin start decode, error(%s)!\n", strerror ( errno ) ); + } + + return rt; +} + +int CTvin::VDIN_StopDec() +{ + int rt = VDIN_DeviceIOCtl ( TVIN_IOC_STOP_DEC ); + if ( rt < 0 ) { + LOGW ( "Vdin stop decode, error(%s)", strerror ( errno ) ); + } + + return rt; +} + +int CTvin::VDIN_GetSignalInfo ( struct tvin_info_s *SignalInfo ) +{ + int rt = VDIN_DeviceIOCtl ( TVIN_IOC_G_SIG_INFO, SignalInfo ); + if ( rt < 0 ) { + LOGW ( "Vdin get signal info, error(%s), ret = %d.\n", strerror ( errno ), rt ); + } + return rt; +} + +int CTvin::VDIN_SetVdinParam ( const struct tvin_parm_s *vdinParam ) +{ + int rt = VDIN_DeviceIOCtl ( TVIN_IOC_S_PARM, vdinParam ); + if ( rt < 0 ) { + LOGW ( "Vdin set signal param, error(%s)\n", strerror ( errno ) ); + } + + return rt; +} + +int CTvin::VDIN_GetVdinParam ( const struct tvin_parm_s *vdinParam ) +{ + int rt = VDIN_DeviceIOCtl ( TVIN_IOC_G_PARM, vdinParam ); + if ( rt < 0 ) { + LOGW ( "Vdin get signal param, error(%s)\n", strerror ( errno ) ); + } + + return rt; +} + +void CTvin::VDIN_GetDisplayVFreq (int need_freq, int *iSswitch, char * display_mode) +{ + int lastFreq = 50; + char buf[32] = {0}; + char *p = NULL; + + if ( 0 > tvReadSysfs(SYS_DISPLAY_MODE_PATH, buf) ) { + LOGW("Read /sys/class/display/mode failed!\n"); + return; + } + + LOGD( "%s, display mode: %s\n", __FUNCTION__, buf); + if ((p = strstr(buf, "50hz")) != NULL) { + lastFreq = 50; + } else if ((p = strstr(buf, "60hz")) != NULL) { + lastFreq = 60; + } else { + LOGW("%s, can not find 50hz or 60hz in %s\n", __FUNCTION__, buf); + } + + if ((need_freq != lastFreq) && (NULL != p)) { + if (50 == need_freq) + strncpy( p, "50hz", 4); + else if (60 == need_freq) + strncpy( p, "60hz", 4); + + strcpy(display_mode, buf); + *iSswitch = 1; + } +} + +int CTvin::VDIN_SetDisplayVFreq ( int freq, bool isFbc) +{ + int iSswitch = 0; + char display_mode[32] = {0}; + + VDIN_GetDisplayVFreq(freq, &iSswitch, display_mode); + if (0 == iSswitch) { + LOGW ( "%s, same freq = %d.", __FUNCTION__, freq); + return 0; + } else { + LOGD ( "%s, set display mode to %s", __FUNCTION__, display_mode); + } + + if ( isFbc ) { + GetSingletonFBC()->cfbc_Set_VMute (COMM_DEV_SERIAL, 2); + usleep ( 300000 ); + } + + tvWriteDisplayMode(display_mode); + return 0; +} + +int CTvin::VDIN_Get_avg_luma(void) +{ + unsigned int lum_sum, pixel_sum, luma_avg; + struct tvin_parm_s vdinParam; + + if ( 0 == VDIN_GetVdinParam( &vdinParam )) { + lum_sum = vdinParam.luma_sum; + pixel_sum = vdinParam.pixel_sum * 2; + if (pixel_sum != 0 && mDecoderStarted) { + luma_avg = lum_sum / pixel_sum; + } else { + luma_avg = 116; + } + } else { + return -1; + } + LOGD ( "VDIN_get_avg_lut lum_sum =%d,pixel_sum=%d,lut_avg=%d\n", lum_sum, pixel_sum, luma_avg); + return luma_avg; +} + +int CTvin::VDIN_SetMVCViewMode ( int mode ) +{ + char str[32] = {0}; + sprintf (str, "%d", mode); + tvWriteSysfs("/sys/module/amvdec_h264mvc/parameters/view_mode", str); + return 0; +} + +int CTvin::VDIN_GetMVCViewMode ( void ) +{ + char buf[32] = {0}; + + tvReadSysfs("/sys/module/amvdec_h264mvc/parameters/view_mode", buf); + int mode = atoi(buf); + return mode; +} + +int CTvin::VDIN_SetDIBuffMgrMode ( int mgr_mode ) +{ + char str[32] = {0}; + sprintf (str, "%d", mgr_mode); + tvWriteSysfs("sys/module/di/parameters/buf_mgr_mode", str); + return 0; +} + +int CTvin::VDIN_SetDICFG ( int cfg ) +{ + tvWriteSysfs("sys/class/deinterlace/di0/config", (0 == cfg)?"disable":"enable"); + return 0; +} + +int CTvin::VDIN_SetDI3DDetc ( int enable ) +{ + char str[32] = {0}; + sprintf (str, "%d", enable); + tvWriteSysfs("/sys/module/di/parameters/det3d_en", str); + return 0; +} + +int CTvin::VDIN_Get3DDetc ( void ) +{ + char buf[32] = {0}; + + tvReadSysfs("/sys/module/di/parameters/det3d_en", buf); + if ( strcmp ( "enable", buf ) == 0 ) { + return 1; + } + return 0; +} + + +int CTvin::VDIN_GetVscalerStatus ( void ) +{ + char buf[32] = {0}; + + tvReadSysfs("/sys/class/video/vscaler", buf); + int ret = atoi(buf); + + ret = ( ( ret & 0x40000 ) == 0 ) ? 1 : 0; + if ( ret == 1 ) { + sleep ( 1 ); + } + + return ret; +} + +int CTvin::VDIN_TurnOnBlackBarDetect ( int isEnable ) +{ + char str[32] = {0}; + sprintf (str, "%d", isEnable); + tvWriteSysfs("/sys/module/tvin_vdin/parameters/black_bar_enable", str); + return 0; +} + +int CTvin::VDIN_SetVideoFreeze ( int enable ) +{ + tvWriteSysfs(VDIN0_ATTR_PATH, (enable == 1)?"freeze":"unfreeze"); + return 0; +} + +int CTvin::VDIN_SetDIBypasshd ( int enable ) +{ + char str[32] = {0}; + sprintf (str, "%d", enable); + tvWriteSysfs("/sys/module/di/parameters/bypass_hd", str); + return 0; +} + +int CTvin::VDIN_SetDIBypassAll ( int enable ) +{ + char str[32] = {0}; + sprintf (str, "%d", enable); + tvWriteSysfs("/sys/module/di/parameters/bypass_all", str); + return 0; +} + +int CTvin::VDIN_SetDIBypass_Get_Buf_Threshold ( int enable ) +{ + char str[32] = {0}; + sprintf (str, "%d", enable); + tvWriteSysfs("/sys/module/di/parameters/bypass_get_buf_threshold", str); + return 0; +} + +int CTvin::VDIN_SetDIBypassProg ( int enable ) +{ + char str[32] = {0}; + sprintf (str, "%d", enable); + tvWriteSysfs("/sys/module/di/parameters/bypass_prog", str); + return 0; +} + +int CTvin::VDIN_SetDIBypassDynamic ( int flag ) +{ + char str[32] = {0}; + sprintf (str, "%d", flag); + tvWriteSysfs("/sys/module/di/parameters/bypass_dynamic", str); + return 0; +} + +int CTvin::VDIN_EnableRDMA ( int enable ) +{ + char str[32] = {0}; + sprintf (str, "%d", enable); + tvWriteSysfs("/sys/module/rdma/parameters/enable", str); + return 0; +} + +// AFE +int CTvin::AFE_OpenModule ( void ) +{ + int fd = open ( AFE_DEV_PATH, O_RDWR ); + if ( fd < 0 ) { + LOGW ( "Open tvafe module, error(%s).\n", strerror ( errno ) ); + return -1; + } + + LOGD ( "Open %s module fd = [%d]", AFE_DEV_PATH, fd ); + return fd; +} + +void CTvin::AFE_CloseModule ( void ) +{ + if ( mAfeDevFd >= 0 ) { + close ( mAfeDevFd ); + mAfeDevFd = -1; + } +} + +int CTvin::AFE_DeviceIOCtl ( int request, ... ) +{ + int tmp_ret = -1; + va_list ap; + void *arg; + + if (mAfeDevFd < 0) { + mAfeDevFd = AFE_OpenModule(); + } + + if ( mAfeDevFd >= 0 ) { + va_start ( ap, request ); + arg = va_arg ( ap, void * ); + va_end ( ap ); + + tmp_ret = ioctl ( mAfeDevFd, request, arg ); + + return tmp_ret; + } + + return -1; +} + +int CTvin::AFE_SetVGAEdid ( const unsigned char *ediddata ) +{ + int rt = -1; + struct tvafe_vga_edid_s vgaEdid; + +#ifdef NO_IC_TEST + + for ( int i = 0; i < 256; i++ ) { + test_edid[i] = ediddata[i]; + } + +#endif + + for ( int i = 0; i < 256; i++ ) { + vgaEdid.value[i] = ediddata[i]; + } + + rt = AFE_DeviceIOCtl ( TVIN_IOC_S_AFE_VGA_EDID, &vgaEdid ); + + if ( rt < 0 ) { + LOGW ( "AFE_SetVGAEdid, error(%s).!\n", strerror ( errno ) ); + } + + return rt; +} + +int CTvin::AFE_GetVGAEdid ( unsigned char *ediddata ) +{ + int rt = -1; + struct tvafe_vga_edid_s vgaEdid; + +#ifdef NO_IC_TEST + + for ( int i = 0; i < 256; i++ ) { + ediddata[i] = test_edid[i]; + } + + LOGD ( "AFE_GetVGAEdid:\n" ); + LOGD ( "===================================================\n" ); + + for ( int i = 0; i < 256; i++ ) { + LOGD ( "vag edid[%d] = [0x%x].\n", i, ediddata[i] ); + } + + LOGD ( "===================================================\n" ); +#endif + + rt = AFE_DeviceIOCtl ( TVIN_IOC_G_AFE_VGA_EDID, &vgaEdid ); + + for ( int i = 0; i < 256; i++ ) { + ediddata[i] = vgaEdid.value[i]; + } + + if ( rt < 0 ) { + LOGW ( "AFE_GetVGAEdid, error(%s)!\n", strerror ( errno ) ); + } + + return rt; +} + +int CTvin::AFE_SetADCTimingAdjust ( const struct tvafe_vga_parm_s *timingadj ) +{ + int rt = -1; + + if ( timingadj == NULL ) { + return rt; + } + + rt = AFE_DeviceIOCtl ( TVIN_IOC_S_AFE_VGA_PARM, timingadj ); + + if ( rt < 0 ) { + LOGW ( "AFE_SetADCTimingAdjust, error(%s)!\n", strerror ( errno ) ); + } + + return rt; +} + +int CTvin::AFE_GetADCCurrentTimingAdjust ( struct tvafe_vga_parm_s *timingadj ) +{ + int rt = -1; + + if ( timingadj == NULL ) { + return rt; + } + + rt = AFE_DeviceIOCtl ( TVIN_IOC_G_AFE_VGA_PARM, timingadj ); + + if ( rt < 0 ) { + LOGW ( "AFE_GetADCCurrentTimingAdjust, error(%s)!\n", strerror ( errno ) ); + return -1; + } + + return 0; +} + +int CTvin::AFE_VGAAutoAdjust ( struct tvafe_vga_parm_s *timingadj ) +{ + enum tvafe_cmd_status_e CMDStatus = TVAFE_CMD_STATUS_PROCESSING; + struct tvin_parm_s tvin_para; + int rt = -1, i = 0; + + if ( timingadj == NULL ) { + return -1; + } + + for ( i = 0, CMDStatus == TVAFE_CMD_STATUS_PROCESSING; i < 50; i++ ) { + rt = AFE_DeviceIOCtl ( TVIN_IOC_G_AFE_CMD_STATUS, &CMDStatus ); + + if ( rt < 0 ) { + LOGD ( "get afe CMD status, error(%s), return(%d).\n", strerror ( errno ), rt ); + } + + if ( ( CMDStatus == TVAFE_CMD_STATUS_IDLE ) || ( CMDStatus == TVAFE_CMD_STATUS_SUCCESSFUL ) ) { + break; + } + + usleep ( 10 * 1000 ); + } + + if ( ( CMDStatus == TVAFE_CMD_STATUS_PROCESSING ) || ( CMDStatus == TVAFE_CMD_STATUS_FAILED ) ) { + return -1; + } + + for ( i = 0; i < 100; i++ ) { + rt = VDIN_DeviceIOCtl ( TVIN_IOC_G_PARM, &tvin_para ); + + if ( tvin_para.info.status == TVIN_SIG_STATUS_STABLE ) { + break; + } + + usleep ( 10 * 1000 ); + } + + rt = AFE_DeviceIOCtl ( TVIN_IOC_S_AFE_VGA_AUTO ); + + if ( rt < 0 ) { + timingadj->clk_step = 0; + timingadj->phase = 0; + timingadj->hpos_step = 0; + timingadj->vpos_step = 0; + AFE_DeviceIOCtl ( TVIN_IOC_S_AFE_VGA_PARM, timingadj ); + return rt; + } else { + ;//AFE_DeviceIOCtl(TVIN_IOC_G_AFE_VGA_PARM, timingadj); + } + + for ( i = 0; i < 10; i++ ) { + sleep ( 1 ); + + rt = AFE_DeviceIOCtl ( TVIN_IOC_G_AFE_CMD_STATUS, &CMDStatus ); + + if ( rt < 0 ) { + return rt; + } else { + if ( CMDStatus == TVAFE_CMD_STATUS_SUCCESSFUL ) { + usleep ( 100 * 1000 ); + AFE_GetADCCurrentTimingAdjust ( timingadj ); + LOGD ( "AFE_VGAAutoAdjust, successfull!\n" ); + return 0; + } + } + } + + return -1; +} + +int CTvin::AFE_SetVGAAutoAjust ( void ) +{ + int rt = -1; + tvafe_vga_parm_t timingadj; + tvafe_cmd_status_t Status; + rt = AFE_DeviceIOCtl ( TVIN_IOC_G_AFE_CMD_STATUS, &Status ); + + if ( ( Status == TVAFE_CMD_STATUS_IDLE ) || ( Status == TVAFE_CMD_STATUS_SUCCESSFUL ) ) { + ; + } else { + LOGW ( "AFE_SetVGAAutoAjust, TVIN_IOC_G_AFE_CMD_STATUS failed!\n" ); + return -1; + } + + rt = AFE_DeviceIOCtl ( TVIN_IOC_S_AFE_VGA_AUTO ); + + if ( rt < 0 ) { + timingadj.clk_step = 0; + timingadj.phase = 0; + timingadj.hpos_step = 0; + timingadj.vpos_step = 0; + AFE_DeviceIOCtl ( TVIN_IOC_S_AFE_VGA_PARM, &timingadj ); + return rt; + } + + return 0; +} + +int CTvin::AFE_GetVGAAutoAdjustCMDStatus ( tvafe_cmd_status_t *Status ) +{ + int rt = -1; + + if ( Status == NULL ) { + return rt; + } + + rt = AFE_DeviceIOCtl ( TVIN_IOC_G_AFE_CMD_STATUS, Status ); + + if ( rt < 0 ) { + LOGW ( "AFE_GetVGAAutoAdjustStatus, get status, error(%s) return(%d)\n", strerror ( errno ), rt ); + return rt; + } + + return 0; +} + +int CTvin::AFE_GetAdcCal ( struct tvafe_adc_cal_s *adccalvalue ) +{ + int rt = -1; + + rt = AFE_DeviceIOCtl ( TVIN_IOC_G_AFE_ADC_CAL, adccalvalue ); + + if ( rt < 0 ) { + LOGW ( "AFE_GetADCGainOffset, error(%s)!\n", strerror ( errno ) ); + } + + return rt; +} + +int CTvin::AFE_SetAdcCal ( struct tvafe_adc_cal_s *adccalvalue ) +{ + int rt = AFE_DeviceIOCtl ( TVIN_IOC_S_AFE_ADC_CAL, adccalvalue ); + + if ( rt < 0 ) { + LOGW ( "AFE_SetAdcCal, error(%s)!", strerror ( errno ) ); + } + + return rt; +} + +int CTvin::AFE_GetAdcCompCal ( struct tvafe_adc_comp_cal_s *adccalvalue ) +{ + int rt = -1; + + rt = AFE_DeviceIOCtl ( TVIN_IOC_G_AFE_ADC_COMP_CAL, adccalvalue ); + + if ( rt < 0 ) { + LOGW ( "AFE_GetYPbPrADCGainOffset, error(%s)!\n", strerror ( errno ) ); + } + + return rt; +} + +int CTvin::AFE_SetAdcCompCal ( struct tvafe_adc_comp_cal_s *adccalvalue ) +{ + int rt = AFE_DeviceIOCtl ( TVIN_IOC_S_AFE_ADC_COMP_CAL, adccalvalue ); + + if ( rt < 0 ) { + LOGW ( "AFE_SetYPbPrADCGainOffset, error(%s)!", strerror ( errno ) ); + } + + return rt; +} +int CTvin::AFE_GetYPbPrWSSinfo ( struct tvafe_comp_wss_s *wssinfo ) +{ + int rt = AFE_DeviceIOCtl ( TVIN_IOC_G_AFE_COMP_WSS, wssinfo ); + + if ( rt < 0 ) { + LOGW ( "AFE_GetYPbPrWSSinfo, error(%s)!", strerror ( errno ) ); + } + + return rt; +} + +#define RGB444 3 +#define YCBCR422 2 +#define YCBCR444 3 +#define Y422_POS 0 +#define CB422_POS 1 +#define CR422_POS 3 +#define Y444_POS 0 +#define CB444_POS 1 +#define CR444_POS 2 +#define R444_POS 0 +#define G444_POS 1 +#define B444_POS 2 + +//=========== VGA ===================== +#define VGA_BUF_WID (VGA_H_ACTIVE) + +#ifdef PATTERN_7_COLOR_BAR +#define VGA_BAR_WID (VGA_H_ACTIVE/7) +#define VGA_H_CUT_WID (10) +#else +#define VGA_BAR_WID (VGA_H_ACTIVE/8) +#define VGA_H_CUT_WID (10) +#endif + +#define VGA_V_CUT_WID (40) +#define VGA_V_CAL_WID (200+VGA_V_CUT_WID) + +#define VGA_WHITE_HS (VGA_BAR_WID*0+VGA_H_CUT_WID) +#define VGA_WHITE_HE (VGA_BAR_WID*1-VGA_H_CUT_WID-1) +#define VGA_WHITE_VS (VGA_V_CUT_WID) +#define VGA_WHITE_VE (VGA_V_CAL_WID-1) +#define VGA_WHITE_SIZE ((VGA_WHITE_HE-VGA_WHITE_HS+1)*(VGA_WHITE_VE-VGA_WHITE_VS+1)) +#ifdef PATTERN_7_COLOR_BAR +#define VGA_BLACK_HS (VGA_BAR_WID*6+VGA_H_CUT_WID) +#define VGA_BLACK_HE (VGA_BAR_WID*7-VGA_H_CUT_WID-1) +#define VGA_BLACK_VS (768-140) +#define VGA_BLACK_VE (768-40-1) +#define VGA_BLACK_SIZE ((VGA_BLACK_HE-VGA_BLACK_HS+1)*(VGA_BLACK_VE-VGA_BLACK_VS+1)) +#else +#define VGA_BLACK_HS (VGA_BAR_WID*7+VGA_H_CUT_WID) +#define VGA_BLACK_HE (VGA_BAR_WID*8-VGA_H_CUT_WID-1) +#define VGA_BLACK_VS (VGA_V_CUT_WID) +#define VGA_BLACK_VE (VGA_V_CAL_WID-1) +#define VGA_BLACK_SIZE ((VGA_BLACK_HE-VGA_BLACK_HS+1)*(VGA_BLACK_VE-VGA_BLACK_VS+1)) +#endif + +//=========== YPBPR ===================== +#define COMP_BUF_WID (COMP_H_ACTIVE) + +#define COMP_BAR_WID (COMP_H_ACTIVE/8) +#define COMP_H_CUT_WID (20) +#define COMP_V_CUT_WID (100) +#define COMP_V_CAL_WID (200+COMP_V_CUT_WID) + +#define COMP_WHITE_HS (COMP_BAR_WID*0+COMP_H_CUT_WID) +#define COMP_WHITE_HE (COMP_BAR_WID*1-COMP_H_CUT_WID-1) +#define COMP_WHITE_VS (COMP_V_CUT_WID) +#define COMP_WHITE_VE (COMP_V_CAL_WID-1) +#define COMP_WHITE_SIZE ((COMP_WHITE_HE-COMP_WHITE_HS+1)*(COMP_WHITE_VE-COMP_WHITE_VS+1)) +#define CB_WHITE_SIZE ((COMP_WHITE_HE-COMP_WHITE_HS+1)*(COMP_WHITE_VE-COMP_WHITE_VS+1)/2) +#define CR_WHITE_SIZE ((COMP_WHITE_HE-COMP_WHITE_HS+1)*(COMP_WHITE_VE-COMP_WHITE_VS+1)/2) + +#define COMP_YELLOW_HS (COMP_BAR_WID*1+COMP_H_CUT_WID) +#define COMP_YELLOW_HE (COMP_BAR_WID*2-COMP_H_CUT_WID-1) +#define COMP_YELLOW_VS (COMP_V_CUT_WID) +#define COMP_YELLOW_VE (COMP_V_CAL_WID-1) +#define COMP_YELLOW_SIZE ((COMP_YELLOW_HE-COMP_YELLOW_HS+1)*(COMP_YELLOW_VE-COMP_YELLOW_VS+1)/2) + +#define COMP_CYAN_HS (COMP_BAR_WID*2+COMP_H_CUT_WID) +#define COMP_CYAN_HE (COMP_BAR_WID*3-COMP_H_CUT_WID-1) +#define COMP_CYAN_VS (COMP_V_CUT_WID) +#define COMP_CYAN_VE (COMP_V_CAL_WID-1) +#define COMP_CYAN_SIZE ((COMP_CYAN_HE-COMP_CYAN_HS+1)*(COMP_CYAN_VE-COMP_CYAN_VS+1)/2) + +#define COMP_RED_HS (COMP_BAR_WID*5+COMP_H_CUT_WID) +#define COMP_RED_HE (COMP_BAR_WID*6-COMP_H_CUT_WID-1) +#define COMP_RED_VS (COMP_V_CUT_WID) +#define COMP_RED_VE (COMP_V_CAL_WID-1) +#define COMP_RED_SIZE ((COMP_RED_HE-COMP_RED_HS+1)*(COMP_RED_VE-COMP_RED_VS+1)/2) + +#define COMP_BLUE_HS (COMP_BAR_WID*6+COMP_H_CUT_WID) +#define COMP_BLUE_HE (COMP_BAR_WID*7-COMP_H_CUT_WID-1) +#define COMP_BLUE_VS (COMP_V_CUT_WID) +#define COMP_BLUE_VE (COMP_V_CAL_WID-1) +#define COMP_BLUE_SIZE ((COMP_BLUE_HE-COMP_BLUE_HS+1)*(COMP_BLUE_VE-COMP_BLUE_VS+1)/2) + +#define COMP_BLACK_HS (COMP_BAR_WID*7+COMP_H_CUT_WID) +#define COMP_BLACK_HE (COMP_BAR_WID*8-COMP_H_CUT_WID-1) +#define COMP_BLACK_VS (COMP_V_CUT_WID) +#define COMP_BLACK_VE (COMP_V_CAL_WID-1) +#define COMP_BLACK_SIZE ((COMP_BLACK_HE-COMP_BLACK_HS+1)*(COMP_BLACK_VE-COMP_BLACK_VS+1)) +#define CB_BLACK_SIZE ((COMP_BLACK_HE-COMP_BLACK_HS+1)*(COMP_BLACK_VE-COMP_BLACK_VS+1)/2) +#define CR_BLACK_SIZE ((COMP_BLACK_HE-COMP_BLACK_HS+1)*(COMP_BLACK_VE-COMP_BLACK_VS+1)/2) + +//=========== CVBS ===================== +#define CVBS_BUF_WID (CVBS_H_ACTIVE) +#define CVBS_BAR_WID (CVBS_H_ACTIVE/8) +#define CVBS_H_CUT_WID (20) + +#define CVBS_V_CUT_WID (40) +#define CVBS_V_CAL_WID (140+CVBS_V_CUT_WID) + +#define CVBS_WHITE_HS (CVBS_BAR_WID*0+CVBS_H_CUT_WID) +#define CVBS_WHITE_HE (CVBS_BAR_WID*1-CVBS_H_CUT_WID-1) +#define CVBS_WHITE_VS (CVBS_V_CUT_WID) +#define CVBS_WHITE_VE (CVBS_V_CAL_WID-1) +#define CVBS_WHITE_SIZE ((CVBS_WHITE_HE-CVBS_WHITE_HS+1)*(CVBS_WHITE_VE-CVBS_WHITE_VS+1)) + +#define CVBS_BLACK_HS (CVBS_BAR_WID*7+CVBS_H_CUT_WID) +#define CVBS_BLACK_HE (CVBS_BAR_WID*8-CVBS_H_CUT_WID-1) +#define CVBS_BLACK_VS (CVBS_V_CUT_WID) +#define CVBS_BLACK_VE (CVBS_V_CAL_WID-1) +#define CVBS_BLACK_SIZE ((CVBS_BLACK_HE-CVBS_BLACK_HS+1)*(CVBS_BLACK_VE-CVBS_BLACK_VS+1)) + +#define COMP_CAP_SIZE (COMP_H_ACTIVE*COMP_V_ACTIVE*YCBCR422) +#ifdef VGA_SOURCE_RGB444 +#define VGA_CAP_SIZE (VGA_H_ACTIVE*VGA_V_ACTIVE*RGB444) +#else +#define VGA_CAP_SIZE (VGA_H_ACTIVE*VGA_V_ACTIVE*YCBCR444) +#endif +#define CVBS_CAP_SIZE (CVBS_H_ACTIVE*CVBS_V_ACTIVE) + +#define PRE_0 -16 +#define PRE_1 -128 +#define PRE_2 -128 +#define COEF_00 1.164 +#define COEF_01 0 +#define COEF_02 1.793 +#define COEF_10 1.164 +#define COEF_11 -0.213 +#define COEF_12 -0.534 +#define COEF_20 1.164 +#define COEF_21 2.115 +#define COEF_22 0 +#define POST_0 0 +#define POST_1 0 +#define POST_2 0 + +unsigned int CTvin::data_limit ( float data ) +{ + if ( data < 0 ) { + return ( 0 ); + } else if ( data > 255 ) { + return ( 255 ); + } else { + return ( ( unsigned int ) data ); + } +} + +void CTvin::matrix_convert_yuv709_to_rgb ( unsigned int y, unsigned int u, unsigned int v, unsigned int *r, unsigned int *g, unsigned int *b ) +{ + *r = data_limit ( ( ( float ) y + PRE_0 ) * COEF_00 + ( ( float ) u + PRE_1 ) * COEF_01 + ( ( float ) v + PRE_2 ) * COEF_02 + POST_0 + 0.5 ); + *g = data_limit ( ( ( float ) y + PRE_0 ) * COEF_10 + ( ( float ) u + PRE_1 ) * COEF_11 + ( ( float ) v + PRE_2 ) * COEF_12 + POST_1 + 0.5 ); + *b = data_limit ( ( ( float ) y + PRE_0 ) * COEF_20 + ( ( float ) u + PRE_1 ) * COEF_21 + ( ( float ) v + PRE_2 ) * COEF_22 + POST_2 + 0.5 ); +} + +void CTvin::re_order ( unsigned int *a, unsigned int *b ) +{ + unsigned int c = 0; + + if ( *a > *b ) { + c = *a; + *a = *b; + *b = c; + } +} + +char *CTvin::get_cap_addr ( enum adc_cal_type_e calType ) +{ + int n; + char *dp; + + for ( n = 0; n < 0x00ff; n++ ) { + if ( VDIN_DeviceIOCtl ( TVIN_IOC_G_SIG_INFO, &gTvinAFESignalInfo ) < 0 ) { + LOGW ( "get_cap_addr, get signal info, error(%s),fd(%d).\n", strerror ( errno ), mVdin0DevFd ); + return NULL; + } else { + if ( gTvinAFESignalInfo.status == TVIN_SIG_STATUS_STABLE ) { + gTvinAFEParam.info.fmt = gTvinAFESignalInfo.fmt; + break; + } + } + } + + if ( gTvinAFESignalInfo.status != TVIN_SIG_STATUS_STABLE ) { + LOGD ( "get_cap_addr, signal isn't stable, out of calibration!\n" ); + return NULL; + } else { + if ( VDIN_DeviceIOCtl ( TVIN_IOC_STOP_DEC ) < 0 ) { + LOGW ( "get_cap_addr, stop vdin, error (%s).\n", strerror ( errno ) ); + return NULL; + } + + usleep ( 1000 ); + + if ( calType == CAL_YPBPR ) { + dp = ( char * ) mmap ( NULL, COMP_CAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, mVdin0DevFd, 0 ); + } else { + dp = ( char * ) mmap ( NULL, VGA_CAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, mVdin0DevFd, 0 ); + } + + if ( dp == NULL ) { + LOGE ( "get_cap_addr, mmap failed!\n" ); + } + + return dp; + } + + return NULL; +} + +inline unsigned char CTvin::get_mem_data ( char *dp, unsigned int addr ) +{ + return ( * ( dp + ( addr ^ 7 ) ) ); +} + +int CTvin::get_frame_average ( enum adc_cal_type_e calType, struct adc_cal_s *mem_data ) +{ + unsigned int y = 0, cb = 0, cr = 0; + unsigned int r = 0, g = 0, b = 0; + unsigned long n; + unsigned int i = 0, j = 0; + char *dp = get_cap_addr ( calType ); + + if ( calType == CAL_YPBPR ) { + for ( j = COMP_WHITE_VS; j <= COMP_WHITE_VE; j++ ) { + for ( i = COMP_WHITE_HS; i <= COMP_WHITE_HE; i++ ) { + mem_data->g_y_max += get_mem_data ( dp, ( ( COMP_BUF_WID * j + i ) * YCBCR422 ) ); + } + } + + mem_data->g_y_max /= COMP_WHITE_SIZE; + + for ( j = COMP_WHITE_VS; j <= COMP_WHITE_VE; j++ ) { + for ( i = COMP_WHITE_HS; i <= COMP_WHITE_HE; ) { + mem_data->cb_white += get_mem_data ( dp, ( ( COMP_BUF_WID * j + i ) * YCBCR422 + CB422_POS ) ); + mem_data->cr_white += get_mem_data ( dp, ( ( COMP_BUF_WID * j + i ) * YCBCR422 + CR422_POS ) ); + i = i + 2; + } + } + + mem_data->cb_white /= CB_WHITE_SIZE; + mem_data->cr_white /= CR_WHITE_SIZE; + + for ( j = COMP_RED_VS; j <= COMP_RED_VE; j++ ) { + for ( i = COMP_RED_HS; i <= COMP_RED_HE; ) { + mem_data->rcr_max += get_mem_data ( dp, ( ( COMP_BUF_WID * j + i ) * YCBCR422 + CR422_POS ) ); + i = i + 2; + } + } + + mem_data->rcr_max /= COMP_RED_SIZE; + + for ( j = COMP_BLUE_VS; j <= COMP_BLUE_VE; j++ ) { + for ( i = COMP_BLUE_HS; i <= COMP_BLUE_HE; ) { + mem_data->bcb_max += get_mem_data ( dp, ( ( COMP_BUF_WID * j + i ) * YCBCR422 + CB422_POS ) ); + i = i + 2; + } + } + + mem_data->bcb_max /= COMP_BLUE_SIZE; + + for ( j = COMP_BLACK_VS; j <= COMP_BLACK_VE; j++ ) { + for ( i = COMP_BLACK_HS; i <= COMP_BLACK_HE; i++ ) { + mem_data->g_y_min += get_mem_data ( dp, ( ( COMP_BUF_WID * j + i ) * YCBCR422 ) ); + } + } + + mem_data->g_y_min /= COMP_BLACK_SIZE; + + for ( j = COMP_BLACK_VS; j <= COMP_BLACK_VE; j++ ) { + for ( i = COMP_BLACK_HS; i <= COMP_BLACK_HE; ) { + mem_data->cb_black += get_mem_data ( dp, ( ( COMP_BUF_WID * j + i ) * YCBCR422 + CB422_POS ) ); + mem_data->cr_black += get_mem_data ( dp, ( ( COMP_BUF_WID * j + i ) * YCBCR422 + CR422_POS ) ); + i = i + 2; + } + } + + mem_data->cb_black /= CB_BLACK_SIZE; + mem_data->cr_black /= CR_BLACK_SIZE; + + /* + for (j=COMP_BLACK_VS; j<=COMP_BLACK_VE; j++) { + for (i=COMP_BLACK_HS; i<=COMP_BLACK_HE;) { + //mem_data->cb_black += get_mem_data(dp, ((COMP_BUF_WID*j+i)*YCBCR422+CB422_POS)); + mem_data->cr_black += get_mem_data(dp, ((COMP_BUF_WID*j+i)*YCBCR422+CR422_POS)); + i = i+2; + } + } + mem_data->cr_black /= CR_BLACK_SIZE; + */ + for ( j = COMP_CYAN_VS; j <= COMP_CYAN_VE; j++ ) { + for ( i = COMP_CYAN_HS; i <= COMP_CYAN_HE; ) { + mem_data->rcr_min += get_mem_data ( dp, ( ( COMP_BUF_WID * j + i ) * YCBCR422 + CR422_POS ) ); + i = i + 2; + } + } + + mem_data->rcr_min /= COMP_CYAN_SIZE; + + for ( j = COMP_YELLOW_VS; j <= COMP_YELLOW_VE; j++ ) { + for ( i = COMP_YELLOW_HS; i <= COMP_YELLOW_HE; ) { + mem_data->bcb_min += get_mem_data ( dp, ( COMP_BUF_WID * j + i ) * YCBCR422 + CB422_POS ); + i = i + 2; + } + } + + mem_data->bcb_min /= COMP_YELLOW_SIZE; + + } else if ( calType == CAL_VGA ) { + for ( j = VGA_WHITE_VS; j <= VGA_WHITE_VE; j++ ) { + for ( i = VGA_WHITE_HS; i <= VGA_WHITE_HE; i++ ) { +#ifdef VGA_SOURCE_RGB444 + r = get_mem_data ( dp, ( ( VGA_BUF_WID * j + i ) * RGB444 + R444_POS ) ); + g = get_mem_data ( dp, ( ( VGA_BUF_WID * j + i ) * RGB444 + G444_POS ) ); + b = get_mem_data ( dp, ( ( VGA_BUF_WID * j + i ) * RGB444 + B444_POS ) ); +#else + y = get_mem_data ( dp, ( ( VGA_BUF_WID * j + i ) * YCBCR444 + Y444_POS ) ); + cb = get_mem_data ( dp, ( ( VGA_BUF_WID * j + i ) * YCBCR444 + CB444_POS ) ); + cr = get_mem_data ( dp, ( ( VGA_BUF_WID * j + i ) * YCBCR444 + CR444_POS ) ); + matrix_convert_yuv709_to_rgb ( y, cb, cr, &r, &g, &b ); +#endif + mem_data->rcr_max = mem_data->rcr_max + r; + mem_data->g_y_max = mem_data->g_y_max + g; + mem_data->bcb_max = mem_data->bcb_max + b; + } + } + + mem_data->rcr_max = mem_data->rcr_max / VGA_WHITE_SIZE; + mem_data->g_y_max = mem_data->g_y_max / VGA_WHITE_SIZE; + mem_data->bcb_max = mem_data->bcb_max / VGA_WHITE_SIZE; + + for ( j = VGA_BLACK_VS; j <= VGA_BLACK_VE; j++ ) { + for ( i = VGA_BLACK_HS; i <= VGA_BLACK_HE; i++ ) { +#ifdef VGA_SOURCE_RGB444 + r = get_mem_data ( dp, ( ( VGA_BUF_WID * j + i ) * RGB444 + R444_POS ) ); + g = get_mem_data ( dp, ( ( VGA_BUF_WID * j + i ) * RGB444 + G444_POS ) ); + b = get_mem_data ( dp, ( ( VGA_BUF_WID * j + i ) * RGB444 + B444_POS ) ); +#else + y = get_mem_data ( dp, ( ( VGA_BUF_WID * j + i ) * YCBCR444 + Y444_POS ) ); + cb = get_mem_data ( dp, ( ( VGA_BUF_WID * j + i ) * YCBCR444 + CB444_POS ) ); + cr = get_mem_data ( dp, ( ( VGA_BUF_WID * j + i ) * YCBCR444 + CR444_POS ) ); + matrix_convert_yuv709_to_rgb ( y, cb, cr, &r, &g, &b ); +#endif + mem_data->rcr_min = mem_data->rcr_min + r; + mem_data->g_y_min = mem_data->g_y_min + g; + mem_data->bcb_min = mem_data->bcb_min + b; + } + } + + mem_data->rcr_min = mem_data->rcr_min / VGA_BLACK_SIZE; + mem_data->g_y_min = mem_data->g_y_min / VGA_BLACK_SIZE; + mem_data->bcb_min = mem_data->bcb_min / VGA_BLACK_SIZE; + + } else { //CVBS + for ( j = CVBS_WHITE_VS; j <= CVBS_WHITE_VE; j++ ) { + for ( i = CVBS_WHITE_HS; i <= CVBS_WHITE_HE; i++ ) { + mem_data->g_y_max += mem_data->g_y_max + get_mem_data ( dp, ( ( CVBS_BUF_WID * j + i ) * YCBCR422 ) ); + } + } + + mem_data->g_y_max /= COMP_WHITE_SIZE; + + for ( j = CVBS_BLACK_VS; j <= CVBS_BLACK_VE; j++ ) { + for ( i = CVBS_BLACK_HS; i <= CVBS_BLACK_HE; i++ ) { + mem_data->g_y_min += mem_data->g_y_min + get_mem_data ( dp, ( ( CVBS_BUF_WID * j + i ) * YCBCR422 ) ); + } + } + + mem_data->g_y_min /= CVBS_BLACK_SIZE; + } + + if ( calType == CAL_YPBPR ) { + munmap ( dp, COMP_CAP_SIZE ); + } else if ( calType == CAL_VGA ) { + munmap ( dp, VGA_CAP_SIZE ); + } else { + munmap ( dp, CVBS_CAP_SIZE ); + } + + if ( VDIN_DeviceIOCtl ( TVIN_IOC_START_DEC, &gTvinAFEParam ) < 0 ) { + LOGW ( "get_frame_average, get vdin signal info, error(%s),fd(%d).\n", strerror ( errno ), mVdin0DevFd ); + return 0; + } + + return 0; +} + +#define ADC_CAL_FRAME_QTY_ORDER 2 //NOTE: MUST >=2!! +struct adc_cal_s CTvin::get_n_frame_average ( enum adc_cal_type_e calType ) +{ + struct adc_cal_s mem_data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + unsigned int rcrmax[1 << ADC_CAL_FRAME_QTY_ORDER]; + unsigned int rcrmin[1 << ADC_CAL_FRAME_QTY_ORDER]; + unsigned int g_ymax[1 << ADC_CAL_FRAME_QTY_ORDER]; + unsigned int g_ymin[1 << ADC_CAL_FRAME_QTY_ORDER]; + unsigned int bcbmax[1 << ADC_CAL_FRAME_QTY_ORDER]; + unsigned int bcbmin[1 << ADC_CAL_FRAME_QTY_ORDER]; + unsigned int cbwhite[1 << ADC_CAL_FRAME_QTY_ORDER]; + unsigned int crwhite[1 << ADC_CAL_FRAME_QTY_ORDER]; + unsigned int cbblack[1 << ADC_CAL_FRAME_QTY_ORDER]; + unsigned int crblack[1 << ADC_CAL_FRAME_QTY_ORDER]; + unsigned int i = 0, j = 0; + + for ( i = 0; i < ( 1 << ADC_CAL_FRAME_QTY_ORDER ); i++ ) { + get_frame_average ( calType, &mem_data ); + rcrmax[i] = mem_data.rcr_max; + rcrmin[i] = mem_data.rcr_min; + g_ymax[i] = mem_data.g_y_max; + g_ymin[i] = mem_data.g_y_min; + bcbmax[i] = mem_data.bcb_max; + bcbmin[i] = mem_data.bcb_min; + cbwhite[i] = mem_data.cb_white; + crwhite[i] = mem_data.cr_white; + cbblack[i] = mem_data.cb_black; + crblack[i] = mem_data.cr_black; + } + + for ( i = 0; i < ( 1 << ADC_CAL_FRAME_QTY_ORDER ) - 1; i++ ) { + for ( j = 1; j < ( 1 << ADC_CAL_FRAME_QTY_ORDER ); j++ ) { + re_order ( & ( rcrmax[i] ), & ( rcrmax[j] ) ); + re_order ( & ( rcrmin[i] ), & ( rcrmin[j] ) ); + re_order ( & ( g_ymax[i] ), & ( g_ymax[j] ) ); + re_order ( & ( g_ymin[i] ), & ( g_ymin[j] ) ); + re_order ( & ( bcbmax[i] ), & ( bcbmax[j] ) ); + re_order ( & ( bcbmin[i] ), & ( bcbmin[j] ) ); + re_order ( & ( cbwhite[i] ), & ( cbwhite[j] ) ); + re_order ( & ( crwhite[i] ), & ( crwhite[j] ) ); + re_order ( & ( cbblack[i] ), & ( cbblack[j] ) ); + re_order ( & ( crblack[i] ), & ( crblack[j] ) ); + } + } + + memset ( &mem_data, 0, sizeof ( mem_data ) ); + + for ( i = 0; i < ( 1 << ( ADC_CAL_FRAME_QTY_ORDER - 1 ) ); i++ ) { //(1<<(ADC_CAL_FRAME_QTY_ORDER-1)) + mem_data.rcr_max += rcrmax[i + ( 1 << ( ADC_CAL_FRAME_QTY_ORDER - 2 ) )]; + mem_data.rcr_min += rcrmin[i + ( 1 << ( ADC_CAL_FRAME_QTY_ORDER - 2 ) )]; + mem_data.g_y_max += g_ymax[i + ( 1 << ( ADC_CAL_FRAME_QTY_ORDER - 2 ) )]; + mem_data.g_y_min += g_ymin[i + ( 1 << ( ADC_CAL_FRAME_QTY_ORDER - 2 ) )]; + mem_data.bcb_max += bcbmax[i + ( 1 << ( ADC_CAL_FRAME_QTY_ORDER - 2 ) )]; + mem_data.bcb_min += bcbmin[i + ( 1 << ( ADC_CAL_FRAME_QTY_ORDER - 2 ) )]; + mem_data.cb_white += cbwhite[i + ( 1 << ( ADC_CAL_FRAME_QTY_ORDER - 2 ) )]; + mem_data.cr_white += crwhite[i + ( 1 << ( ADC_CAL_FRAME_QTY_ORDER - 2 ) )]; + mem_data.cb_black += cbblack[i + ( 1 << ( ADC_CAL_FRAME_QTY_ORDER - 2 ) )]; + mem_data.cr_black += crblack[i + ( 1 << ( ADC_CAL_FRAME_QTY_ORDER - 2 ) )]; + } + + + mem_data.rcr_max >>= ( ADC_CAL_FRAME_QTY_ORDER - 1 ); + mem_data.rcr_min >>= ( ADC_CAL_FRAME_QTY_ORDER - 1 ); + mem_data.g_y_max >>= ( ADC_CAL_FRAME_QTY_ORDER - 1 ); + mem_data.g_y_min >>= ( ADC_CAL_FRAME_QTY_ORDER - 1 ); + mem_data.bcb_max >>= ( ADC_CAL_FRAME_QTY_ORDER - 1 ); + mem_data.bcb_min >>= ( ADC_CAL_FRAME_QTY_ORDER - 1 ); + mem_data.cb_white >>= ( ADC_CAL_FRAME_QTY_ORDER - 1 ); + mem_data.cr_white >>= ( ADC_CAL_FRAME_QTY_ORDER - 1 ); + mem_data.cb_black >>= ( ADC_CAL_FRAME_QTY_ORDER - 1 ); + mem_data.cr_black >>= ( ADC_CAL_FRAME_QTY_ORDER - 1 ); + + return mem_data; +} + +int CTvin::AFE_GetMemData ( int typeSel, struct adc_cal_s *mem_data ) +{ + int rt = -1; + + if ( mVdin0DevFd < 0 || mem_data == NULL ) { + LOGW ( "AFE_GetMemData, didn't open vdin fd, return!\n" ); + return -1; + } + + memset ( &gTvinAFEParam, 0, sizeof ( gTvinAFEParam ) ); + memset ( &gTvinAFESignalInfo, 0, sizeof ( gTvinAFESignalInfo ) ); + + if ( VDIN_DeviceIOCtl ( TVIN_IOC_G_PARM, &gTvinAFEParam ) < 0 ) { + LOGW ( "AFE_GetMemData, get vdin param, error(%s), fd(%d)!\n", strerror ( errno ), mVdin0DevFd ); + return -1; + } + + gTvinAFEParam.flag = gTvinAFEParam.flag | TVIN_PARM_FLAG_CAP; + + if ( VDIN_DeviceIOCtl ( TVIN_IOC_S_PARM, &gTvinAFEParam ) < 0 ) { + LOGW ( "AFE_GetMemData, set vdin param error(%s)!\n", strerror ( errno ) ); + return -1; + } + + if ( typeSel == 0 ) { + get_frame_average ( CAL_YPBPR, mem_data ); + } else if ( typeSel == 1 ) { + get_frame_average ( CAL_VGA, mem_data ); + } else { + *mem_data = get_n_frame_average ( CAL_CVBS ); + } + + gTvinAFEParam.flag &= 0x11111110; + + if ( VDIN_DeviceIOCtl ( TVIN_IOC_S_PARM, &gTvinAFEParam ) < 0 ) { + LOGW ( "AFE_GetMemData, set vdin param error(%s)\n", strerror ( errno ) ); + return -1; + } + + LOGD ( "AFE_GetMemData, MAX ======> :\n Y(White)->%d \n Cb(Blue)->%d \n Cr(Red)->%d\n", mem_data->g_y_max, mem_data->bcb_max, mem_data->rcr_max ); + LOGD ( "AFE_GetMemData, MIN ======>:\n Y(Black)->%d \n Cb(Yellow)->%d \n Cr(Cyan)->%d\n Cb(White) ->%d\n Cb(Black)->%d\n Cr(Black)->%d\n", mem_data->g_y_min, mem_data->bcb_min, mem_data->rcr_min, + mem_data->cb_white, mem_data->cb_black, mem_data->cr_black ); + return 0; +} + +int CTvin::AFE_GetCVBSLockStatus ( enum tvafe_cvbs_video_e *cvbs_lock_status ) +{ + int rt = AFE_DeviceIOCtl ( TVIN_IOC_G_AFE_CVBS_LOCK, cvbs_lock_status ); + if ( rt < 0 ) { + LOGD ( "AFE_GetCVBSLockStatus, error: return(%d), error(%s)!\n", rt, strerror ( errno ) ); + } else { + LOGD ( "AFE_GetCVBSLockStatus, value=%d.\n", *cvbs_lock_status ); + } + + return *cvbs_lock_status; +} + +int CTvin::AFE_SetCVBSStd ( tvin_sig_fmt_t fmt ) +{ + LOGD ( "AFE_SetCVBSStd, sig_fmt = %d\n", fmt ); + int rt = AFE_DeviceIOCtl ( TVIN_IOC_S_AFE_CVBS_STD, &fmt ); + if ( rt < 0 ) { + LOGD ( "AFE_SetCVBSStd, error: return(%d), error(%s)!\n", rt, strerror ( errno ) ); + } + + return rt; +} + +int CTvin::TvinApi_SetStartDropFrameCn ( int count ) +{ + char set_str[4] = {0}; + sprintf ( set_str, "%d", count ); + return tvWriteSysfs ( "/sys/module/di/parameters/start_frame_drop_count", set_str ); +} + +int CTvin::TvinApi_SetVdinHVScale ( int vdinx, int hscale, int vscale ) +{ + int ret = -1; + char set_str[32]= {0}; + + sprintf ( set_str, "%s %d %d", "hvscaler", hscale, vscale ); + if ( vdinx == 0 ) { + ret = tvWriteSysfs ( VDIN0_ATTR_PATH, set_str ); + } else { + ret = tvWriteSysfs ( VDIN1_ATTR_PATH, set_str ); + } + + return ret; +} + +tvin_trans_fmt CTvin::TvinApi_Get3DDectMode() +{ + char buf[32] = {0}; + + tvReadSysfs("/sys/module/di/parameters/det3d_mode", buf); + int mode3d = atoi(buf); + return (tvin_trans_fmt)mode3d; +} + +int CTvin::TvinApi_SetCompPhaseEnable ( int enable ) +{ + int ret = -1; + if ( enable == 1 ) { + ret = tvWriteSysfs ( "/sys/module/tvin_afe/parameters/enable_dphase", "Y" ); + LOGD ( "%s, enable TvinApi_SetCompPhase.", CFG_SECTION_TV ); + } + + return ret; +} + +int CTvin::VDIN_GetPortConnect ( int port ) +{ + int status = 0; + + if ( VDIN_DeviceIOCtl ( TVIN_IOC_CALLMASTER_SET, &port ) < 0 ) { + LOGW ( "TVIN_IOC_CALLMASTER_SET error(%s) port %d\n", strerror ( errno ), port ); + return 0; + } + + if ( VDIN_DeviceIOCtl ( TVIN_IOC_CALLMASTER_GET, &status ) < 0 ) { + LOGW ( "TVIN_IOC_CALLMASTER_GET error(%s)\n", strerror ( errno ) ); + return 0; + } + + //LOGD("%s, port:%x,status:%d", CFG_SECTION_TV,port,status); + return status; +} + +int CTvin::VDIN_OpenHDMIPinMuxOn ( bool flag ) +{ + char buf[32] = {0}; + if ( flag ) { + sprintf ( buf, "%s", "pinmux_on" ); + } else { + sprintf ( buf, "%s", "pinmux_off" ); + } + + tvWriteSysfs("/sys/class/hdmirx/hdmirx0/debug", buf); + return 1; +} + +int CTvin::TvinApi_GetHDMIAudioStatus ( void ) +{ + char buf[32] = {0}; + + tvReadSysfs("/sys/module/tvin_hdmirx/parameters/auds_rcv_sts", buf); + int val = atoi(buf); + return val; +} + +tv_source_input_type_t CTvin::Tvin_SourceInputToSourceInputType ( tv_source_input_t source_input ) +{ + tv_source_input_type_t ret = SOURCE_TYPE_MPEG; + switch (source_input) { + case SOURCE_TV: + ret = SOURCE_TYPE_TV; + break; + case SOURCE_AV1: + case SOURCE_AV2: + ret = SOURCE_TYPE_AV; + break; + case SOURCE_YPBPR1: + case SOURCE_YPBPR2: + ret = SOURCE_TYPE_COMPONENT; + break; + case SOURCE_VGA: + ret = SOURCE_TYPE_VGA; + break; + case SOURCE_HDMI1: + case SOURCE_HDMI2: + case SOURCE_HDMI3: + case SOURCE_HDMI4: + ret = SOURCE_TYPE_HDMI; + break; + case SOURCE_DTV: + ret = SOURCE_TYPE_DTV; + break; + case SOURCE_IPTV: + ret = SOURCE_TYPE_IPTV; + break; + case SOURCE_SPDIF: + ret = SOURCE_TYPE_SPDIF; + break; + default: + ret = SOURCE_TYPE_MPEG; + break; + } + + return ret; +} + +tv_source_input_type_t CTvin::Tvin_SourcePortToSourceInputType ( tvin_port_t source_port ) +{ + tv_source_input_t source_input = Tvin_PortToSourceInput(source_port); + return Tvin_SourceInputToSourceInputType(source_input); +} + +tvin_port_t CTvin::Tvin_GetSourcePortBySourceType ( tv_source_input_type_t source_type ) +{ + tvin_port_t source_port; + tv_source_input_t source_input; + + switch (source_type) { + case SOURCE_TYPE_TV: + source_input = SOURCE_TV; + break; + case SOURCE_TYPE_AV: + source_input = SOURCE_AV1; + break; + case SOURCE_TYPE_COMPONENT: + source_input = SOURCE_YPBPR1; + break; + case SOURCE_TYPE_VGA: + source_input = SOURCE_VGA; + break; + case SOURCE_TYPE_HDMI: + source_input = SOURCE_HDMI1; + break; + case SOURCE_TYPE_IPTV: + source_input = SOURCE_IPTV; + break; + case SOURCE_TYPE_DTV: + source_input = SOURCE_DTV; + break; + case SOURCE_TYPE_SPDIF: + source_input = SOURCE_SPDIF; + break; + default: + source_input = SOURCE_MPEG; + break; + } + + return Tvin_GetSourcePortBySourceInput(source_input); +} + +tvin_port_t CTvin::Tvin_GetSourcePortBySourceInput ( tv_source_input_t source_input ) +{ + tvin_port_t source_port = TVIN_PORT_NULL; + + if ( source_input < SOURCE_TV || source_input >= SOURCE_MAX ) { + source_port = TVIN_PORT_NULL; + } else { + source_port = ( tvin_port_t ) mSourceInputToPortMap[ ( int ) source_input]; + } + + return source_port; +} + +tv_source_input_t CTvin::Tvin_PortToSourceInput ( tvin_port_t port ) +{ + for ( int i = SOURCE_TV; i < SOURCE_MAX; i++ ) { + if ( mSourceInputToPortMap[i] == (int)port ) { + return (tv_source_input_t)i; + } + } + + return SOURCE_MAX; +} + +unsigned int CTvin::Tvin_TransPortStringToValue(const char *port_str) +{ + if (strcasecmp(port_str, "TVIN_PORT_CVBS0") == 0) { + return TVIN_PORT_CVBS0; + } else if (strcasecmp(port_str, "TVIN_PORT_CVBS1") == 0) { + return TVIN_PORT_CVBS1; + } else if (strcasecmp(port_str, "TVIN_PORT_CVBS2") == 0) { + return TVIN_PORT_CVBS2; + } else if (strcasecmp(port_str, "TVIN_PORT_CVBS3") == 0) { + return TVIN_PORT_CVBS3; + } else if (strcasecmp(port_str, "TVIN_PORT_COMP0") == 0) { + return TVIN_PORT_COMP0; + } else if (strcasecmp(port_str, "TVIN_PORT_COMP1") == 0) { + return TVIN_PORT_COMP1; + } else if (strcasecmp(port_str, "TVIN_PORT_VGA0") == 0) { + return TVIN_PORT_VGA0; + } else if (strcasecmp(port_str, "TVIN_PORT_HDMI0") == 0) { + return TVIN_PORT_HDMI0; + } else if (strcasecmp(port_str, "TVIN_PORT_HDMI1") == 0) { + return TVIN_PORT_HDMI1; + } else if (strcasecmp(port_str, "TVIN_PORT_HDMI2") == 0) { + return TVIN_PORT_HDMI2; + } else if (strcasecmp(port_str, "TVIN_PORT_HDMI3") == 0) { + return TVIN_PORT_HDMI3; + } + + return TVIN_PORT_NULL; +} + +void CTvin::Tvin_LoadSourceInputToPortMap() +{ + const char *config_value = NULL; + + config_value = config_get_str(CFG_SECTION_SRC_INPUT, "ro.tv.tvinchannel.atv", "TVIN_PORT_CVBS3"); + mSourceInputToPortMap[SOURCE_TV] = Tvin_TransPortStringToValue(config_value); + + config_value = config_get_str(CFG_SECTION_SRC_INPUT, "ro.tv.tvinchannel.av1", "TVIN_PORT_CVBS1"); + mSourceInputToPortMap[SOURCE_AV1] = Tvin_TransPortStringToValue(config_value); + + config_value = config_get_str(CFG_SECTION_SRC_INPUT, "ro.tv.tvinchannel.av2", "TVIN_PORT_CVBS2"); + mSourceInputToPortMap[SOURCE_AV2] = Tvin_TransPortStringToValue(config_value); + + config_value = config_get_str(CFG_SECTION_SRC_INPUT, "ro.tv.tvinchannel.ypbpr1", "TVIN_PORT_COMP0"); + mSourceInputToPortMap[SOURCE_YPBPR1] = Tvin_TransPortStringToValue(config_value); + + config_value = config_get_str(CFG_SECTION_SRC_INPUT, "ro.tv.tvinchannel.ypbpr2", "TVIN_PORT_COMP1"); + mSourceInputToPortMap[SOURCE_YPBPR2] = Tvin_TransPortStringToValue(config_value); + + config_value = config_get_str(CFG_SECTION_SRC_INPUT, "ro.tv.tvinchannel.hdmi1", ""); + mSourceInputToPortMap[SOURCE_HDMI1] = Tvin_TransPortStringToValue(config_value); + + config_value = config_get_str(CFG_SECTION_SRC_INPUT, "ro.tv.tvinchannel.hdmi2", ""); + mSourceInputToPortMap[SOURCE_HDMI2] = Tvin_TransPortStringToValue(config_value); + + config_value = config_get_str(CFG_SECTION_SRC_INPUT, "ro.tv.tvinchannel.hdmi3", ""); + mSourceInputToPortMap[SOURCE_HDMI3] = Tvin_TransPortStringToValue(config_value); + + config_value = config_get_str(CFG_SECTION_SRC_INPUT, "ro.tv.tvinchannel.hdmi4", ""); + mSourceInputToPortMap[SOURCE_HDMI4] = Tvin_TransPortStringToValue(config_value); + + config_value = config_get_str(CFG_SECTION_SRC_INPUT, "ro.tv.tvinchannel.vga", "TVIN_PORT_VGA0"); + mSourceInputToPortMap[SOURCE_VGA] = Tvin_TransPortStringToValue(config_value); + + mSourceInputToPortMap[SOURCE_MPEG] = TVIN_PORT_MPEG0; + mSourceInputToPortMap[SOURCE_DTV] = TVIN_PORT_DTV; + mSourceInputToPortMap[SOURCE_IPTV] = TVIN_PORT_BT656; +} + +int CTvin::Tvin_GetSourcePortByCECPhysicalAddress(int physical_addr) +{ + if (physical_addr == 0x1000) { + return TVIN_PORT_HDMI0; + } else if (physical_addr == 0x2000) { + return TVIN_PORT_HDMI1; + } else if (physical_addr == 0x3000) { + return TVIN_PORT_HDMI2; + } + + return TVIN_PORT_MAX; +} + +tv_audio_channel_t CTvin::Tvin_GetInputSourceAudioChannelIndex ( tv_source_input_t source_input ) +{ + int aud_chan = TV_AUDIO_LINE_IN_0; + const char *config_value = NULL; + + if ( source_input == SOURCE_TV ) { + config_value = config_get_str(CFG_SECTION_TV, "tvin.aud.chan.atv", "2"); + } else if ( source_input == SOURCE_AV1 ) { + config_value = config_get_str(CFG_SECTION_TV, "tvin.aud.chan.av1", "1"); + } else if ( source_input == SOURCE_AV2 ) { + config_value = config_get_str(CFG_SECTION_TV, "tvin.aud.chan.av2", "3"); + } else if ( source_input == SOURCE_YPBPR1 ) { + config_value = config_get_str(CFG_SECTION_TV, "tvin.aud.chan.comp1", "0"); + } else if ( source_input == SOURCE_YPBPR2 ) { + config_value = config_get_str(CFG_SECTION_TV, "tvin.aud.chan.comp2", "0"); + } else if ( source_input == SOURCE_HDMI1 ) { + config_value = config_get_str(CFG_SECTION_TV, "tvin.aud.chan.hdmi1", "0"); + } else if ( source_input == SOURCE_HDMI2 ) { + config_value = config_get_str(CFG_SECTION_TV, "tvin.aud.chan.hdmi2", "0"); + } else if ( source_input == SOURCE_HDMI3 ) { + config_value = config_get_str(CFG_SECTION_TV, "tvin.aud.chan.hdmi3", "0"); + } else if ( source_input == SOURCE_HDMI4 ) { + config_value = config_get_str(CFG_SECTION_TV, "tvin.aud.chan.hdmi4", "0"); + } else if ( source_input == SOURCE_VGA ) { + config_value = config_get_str(CFG_SECTION_TV, "tvin.aud.chan.vga", "0"); + } else if ( source_input == SOURCE_MPEG ) { + config_value = config_get_str(CFG_SECTION_TV, "tvin.aud.chan.mpeg", "0"); + } + + if (config_value != NULL) { + aud_chan = strtol (config_value, NULL, 10); + } + + return ( tv_audio_channel_t ) aud_chan; +} + +tv_audio_in_source_type_t CTvin::Tvin_GetAudioInSourceType ( tv_source_input_t source_input ) +{ + const char *config_value = NULL; + tv_audio_in_source_type_t ret = TV_AUDIO_IN_SOURCE_TYPE_LINEIN; + switch (source_input) { + case SOURCE_TV: + config_value = config_get_str(CFG_SECTION_TV, "tvin.aud.insource.atv", "TV_AUDIO_IN_SOURCE_TYPE_LINEIN"); + if (strcasecmp(config_value, "TV_AUDIO_IN_SOURCE_TYPE_ATV") == 0) { + ret = TV_AUDIO_IN_SOURCE_TYPE_ATV; + } + break; + case SOURCE_HDMI1: + case SOURCE_HDMI2: + case SOURCE_HDMI3: + case SOURCE_HDMI4: + ret = TV_AUDIO_IN_SOURCE_TYPE_HDMI; + break; + case SOURCE_SPDIF: + ret = TV_AUDIO_IN_SOURCE_TYPE_SPDIF; + break; + default: + ret = TV_AUDIO_IN_SOURCE_TYPE_LINEIN; + break; + } + + return ret; +} + +int CTvin::isVgaFmtInHdmi ( tvin_sig_fmt_t fmt ) +{ + if ( fmt == TVIN_SIG_FMT_HDMI_640X480P_60HZ + || fmt == TVIN_SIG_FMT_HDMI_800X600_00HZ + || fmt == TVIN_SIG_FMT_HDMI_1024X768_00HZ + || fmt == TVIN_SIG_FMT_HDMI_720X400_00HZ + || fmt == TVIN_SIG_FMT_HDMI_1280X768_00HZ + || fmt == TVIN_SIG_FMT_HDMI_1280X800_00HZ + || fmt == TVIN_SIG_FMT_HDMI_1280X960_00HZ + || fmt == TVIN_SIG_FMT_HDMI_1280X1024_00HZ + || fmt == TVIN_SIG_FMT_HDMI_1360X768_00HZ + || fmt == TVIN_SIG_FMT_HDMI_1366X768_00HZ + || fmt == TVIN_SIG_FMT_HDMI_1600X1200_00HZ + || fmt == TVIN_SIG_FMT_HDMI_1920X1200_00HZ ) { + LOGD ( "%s, HDMI source : VGA format.", CFG_SECTION_TV ); + return 1; + } + + return -1; +} + +int CTvin::isSDFmtInHdmi ( tvin_sig_fmt_t fmt ) +{ + if ( fmt == TVIN_SIG_FMT_HDMI_640X480P_60HZ + || fmt == TVIN_SIG_FMT_HDMI_720X480P_60HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X480I_60HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X240P_60HZ + || fmt == TVIN_SIG_FMT_HDMI_2880X480I_60HZ + || fmt == TVIN_SIG_FMT_HDMI_2880X240P_60HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X480P_60HZ + || fmt == TVIN_SIG_FMT_HDMI_720X576P_50HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X576I_50HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X288P_50HZ + || fmt == TVIN_SIG_FMT_HDMI_2880X576I_50HZ + || fmt == TVIN_SIG_FMT_HDMI_2880X288P_50HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X576P_50HZ + || fmt == TVIN_SIG_FMT_HDMI_2880X480P_60HZ + || fmt == TVIN_SIG_FMT_HDMI_2880X576P_60HZ + || fmt == TVIN_SIG_FMT_HDMI_720X576P_100HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X576I_100HZ + || fmt == TVIN_SIG_FMT_HDMI_720X480P_120HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X480I_120HZ + || fmt == TVIN_SIG_FMT_HDMI_720X576P_200HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X576I_200HZ + || fmt == TVIN_SIG_FMT_HDMI_720X480P_240HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X480I_240HZ + || fmt == TVIN_SIG_FMT_HDMI_800X600_00HZ + || fmt == TVIN_SIG_FMT_HDMI_720X400_00HZ ) { + LOGD ( "%s, SD format.", CFG_SECTION_TV ); + return true; + } else { + LOGD ( "%s, HD format.", CFG_SECTION_TV ); + return false; + } +} + +bool CTvin::Tvin_is50HzFrameRateFmt ( tvin_sig_fmt_t fmt ) +{ + /** component **/ + if ( fmt == TVIN_SIG_FMT_COMP_576P_50HZ_D000 + || fmt == TVIN_SIG_FMT_COMP_576I_50HZ_D000 + || fmt == TVIN_SIG_FMT_COMP_720P_50HZ_D000 + || fmt == TVIN_SIG_FMT_COMP_1080P_50HZ_D000 + || fmt == TVIN_SIG_FMT_COMP_1080I_50HZ_D000_A + || fmt == TVIN_SIG_FMT_COMP_1080I_50HZ_D000_B + || fmt == TVIN_SIG_FMT_COMP_1080I_50HZ_D000_C + || fmt == TVIN_SIG_FMT_COMP_1080P_24HZ_D000 + || fmt == TVIN_SIG_FMT_COMP_1080P_25HZ_D000 + /** hdmi **/ + || fmt == TVIN_SIG_FMT_HDMI_720X576P_50HZ + || fmt == TVIN_SIG_FMT_HDMI_1280X720P_50HZ + || fmt == TVIN_SIG_FMT_HDMI_1920X1080I_50HZ_A + || fmt == TVIN_SIG_FMT_HDMI_1440X576I_50HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X288P_50HZ + || fmt == TVIN_SIG_FMT_HDMI_2880X576I_50HZ + || fmt == TVIN_SIG_FMT_HDMI_2880X288P_50HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X576P_50HZ + || fmt == TVIN_SIG_FMT_HDMI_1920X1080P_50HZ + || fmt == TVIN_SIG_FMT_HDMI_1920X1080I_50HZ_B + || fmt == TVIN_SIG_FMT_HDMI_1280X720P_50HZ_FRAME_PACKING + || fmt == TVIN_SIG_FMT_HDMI_1920X1080I_50HZ_FRAME_PACKING + || fmt == TVIN_SIG_FMT_HDMI_720X576P_50HZ_FRAME_PACKING + /** cvbs **/ + || fmt == TVIN_SIG_FMT_CVBS_PAL_I + || fmt == TVIN_SIG_FMT_CVBS_PAL_M + || fmt == TVIN_SIG_FMT_CVBS_PAL_CN + || fmt == TVIN_SIG_FMT_CVBS_SECAM ) { + LOGD ( "%s, Frame rate == 50Hz.", CFG_SECTION_TV ); + return true; + } else { + LOGD ( "%s, Frame rate != 50Hz.", CFG_SECTION_TV ); + return false; + } +} + +bool CTvin::Tvin_IsDeinterlaceFmt ( tvin_sig_fmt_t fmt ) +{ + if ( fmt == TVIN_SIG_FMT_COMP_480I_59HZ_D940 + || fmt == TVIN_SIG_FMT_COMP_576I_50HZ_D000 + || fmt == TVIN_SIG_FMT_COMP_1080I_47HZ_D952 + || fmt == TVIN_SIG_FMT_COMP_1080I_48HZ_D000 + || fmt == TVIN_SIG_FMT_COMP_1080I_50HZ_D000_A + || fmt == TVIN_SIG_FMT_COMP_1080I_50HZ_D000_B + || fmt == TVIN_SIG_FMT_COMP_1080I_50HZ_D000_C + || fmt == TVIN_SIG_FMT_COMP_1080I_60HZ_D000 + || fmt == TVIN_SIG_FMT_HDMI_1440X480I_120HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X480I_240HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X480I_60HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X576I_100HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X576I_200HZ + || fmt == TVIN_SIG_FMT_HDMI_1440X576I_50HZ + || fmt == TVIN_SIG_FMT_HDMI_1920X1080I_100HZ + || fmt == TVIN_SIG_FMT_HDMI_1920X1080I_120HZ + || fmt == TVIN_SIG_FMT_HDMI_1920X1080I_50HZ_A + || fmt == TVIN_SIG_FMT_HDMI_1920X1080I_50HZ_B + || fmt == TVIN_SIG_FMT_HDMI_1920X1080I_50HZ_FRAME_PACKING + || fmt == TVIN_SIG_FMT_HDMI_1920X1080I_60HZ + || fmt == TVIN_SIG_FMT_HDMI_1920X1080I_60HZ_FRAME_PACKING + || fmt == TVIN_SIG_FMT_HDMI_2880X480I_60HZ + || fmt == TVIN_SIG_FMT_HDMI_2880X576I_50HZ + || fmt == TVIN_SIG_FMT_CVBS_NTSC_M + || fmt == TVIN_SIG_FMT_CVBS_NTSC_443 + || fmt == TVIN_SIG_FMT_CVBS_PAL_60 + || fmt == TVIN_SIG_FMT_CVBS_PAL_CN + || fmt == TVIN_SIG_FMT_CVBS_PAL_I + || fmt == TVIN_SIG_FMT_CVBS_PAL_M + || fmt == TVIN_SIG_FMT_CVBS_SECAM ) { + LOGD ( "%s, Interlace format.", CFG_SECTION_TV ); + return true; + } else { + LOGD ( "%s, Progressive format.", CFG_SECTION_TV ); + return false; + } +} + +int CTvin::Tvin_StartDecoder ( tvin_info_t &info ) +{ + if (mDecoderStarted) + return -2; + + m_tvin_param.info = info; + + if ( VDIN_StartDec ( &m_tvin_param ) >= 0 ) { + LOGD ( "StartDecoder succeed." ); + mDecoderStarted = true; + return 0; + } + + LOGW ( "StartDecoder failed." ); + return -1; +} + +int CTvin::SwitchSnow(bool enable) +{ + int ret = -1; + //static bool last_status = false; + + if ( m_snow_status == enable ) { + return 0; + } else { + m_snow_status = enable; + } + if ( enable ) { + ret = AFE_DeviceIOCtl( TVIN_IOC_S_AFE_SONWON ); + ret = VDIN_DeviceIOCtl( TVIN_IOC_SNOWON ); + } else { + ret = AFE_DeviceIOCtl( TVIN_IOC_S_AFE_SONWOFF ); + ret = VDIN_DeviceIOCtl( TVIN_IOC_SNOWOFF ); + } + + return ret; +} + +bool CTvin::getSnowStatus() +{ + return m_snow_status; +} + +int CTvin::SwitchPort (tvin_port_t source_port ) +{ + int ret = 0; + LOGD ("%s, source_port = %x", __FUNCTION__, source_port); + ret = Tvin_StopDecoder(); + if (ret < 0) { + LOGW ( "%s,stop decoder failed.", __FUNCTION__); + return -1; + } + + VDIN_ClosePort(); + Tvin_WaitPathInactive ( TV_PATH_TYPE_TVIN ); + // Open Port + if ( VDIN_OpenPort ( source_port ) < 0 ) { + LOGD ( "%s, OpenPort failed, source_port =%x ", __FUNCTION__, source_port ); + } + m_tvin_param.port = source_port; + + return 0; +} + +int CTvin::Tvin_StopDecoder() +{ + if (!mDecoderStarted) + return 1; + + if ( VDIN_StopDec() >= 0 ) { + LOGD ( "StopDecoder ok!" ); + mDecoderStarted = false; + return 0; + } + return -1; +} + +int CTvin::init_vdin ( void ) +{ + VDIN_OpenModule(); + return 0; +} + +int CTvin::uninit_vdin ( void ) +{ + VDIN_ClosePort(); + VDIN_CloseModule(); + return 0; +} + +int CTvin::Tvin_WaitPathInactive ( tv_path_type_t pathtype ) +{ + int ret = -1; + int i = 0, dly = 100; + + for ( i = 0; i<50; i++ ) { + ret = Tvin_CheckPathActive ( pathtype ); + if ( ret == TV_PATH_STATUS_INACTIVE ) { + LOGD ( "%s, check path is inactive, %d ms gone.\n", CFG_SECTION_TV, ( dly * i ) ); + break; + } else if ( ret == TV_PATH_STATUS_ACTIVE ) { + usleep ( dly * 1000 ); + } + } + + if ( i == 500 ) { + LOGE ( "%s, check path active faild, %d ms gone.\n", "TV", ( dly * i ) ); + } + return 0; +} + +int CTvin::Tvin_RemovePath ( tv_path_type_t pathtype ) +{ + int ret = -1; + int i = 0, dly = 10; + + Tvin_WaitPathInactive(pathtype); + if ( pathtype == TV_PATH_TYPE_DEFAULT ) { + for ( i = 0; i < 50; i++ ) { + ret = VDIN_RmDefPath(); + + if ( ret > 0 ) { + LOGD ( "%s, remove default path ok, %d ms gone.\n", CFG_SECTION_TV, ( dly * i ) ); + break; + } else { + LOGW ( "%s, remove default path faild, %d ms gone.\n", CFG_SECTION_TV, ( dly * i ) ); + usleep ( dly * 1000 ); + } + } + } else if ( pathtype == TV_PATH_TYPE_TVIN ) { + for ( i = 0; i < 50; i++ ) { + ret = VDIN_RmTvPath(); + + if ( ret > 0 ) { + LOGD ( "%s, remove tvin path ok, %d ms gone.\n", CFG_SECTION_TV, ( dly * i ) ); + break; + } else { + LOGW ( "%s, remove tvin path faild, %d ms gone.\n", CFG_SECTION_TV, ( dly * i ) ); + usleep ( dly * 1000 ); + } + } + + } + + return ret; +} + +int CTvin::Tvin_CheckPathActive ( tv_path_type_t path_type) +{ + FILE *f = NULL; + char path[100] = {0}; + char decoder_str[20] = "default {"; + char tvin_str[20] = "tvpath {"; + + char *str_find = NULL; + char active_str[4] = "(1)"; + int mount_freq; + int match; + int is_active = TV_PATH_STATUS_INACTIVE; + + f = fopen ( SYS_VFM_MAP_PATH, "r" ); + if ( !f ) { + LOGE ( "%s, can not open %s!\n", CFG_SECTION_TV, SYS_VFM_MAP_PATH ); + return TV_PATH_STATUS_NO_DEV; + } + + while ( fgets ( path, sizeof(path)-1, f ) ) { + if ( path_type == TV_PATH_TYPE_DEFAULT ) { + str_find = strstr ( path, decoder_str ); + } else if ( path_type == TV_PATH_TYPE_TVIN) { + str_find = strstr ( path, tvin_str ); + } else { + break; + } + + if ( str_find ) { + if ( strstr ( str_find, active_str) ) { + is_active = TV_PATH_STATUS_ACTIVE; + } else { + is_active = TV_PATH_STATUS_INACTIVE; + } + break; + } + } + + fclose ( f ); + f = NULL; + + return is_active; +} + +int CTvin::Tv_init_afe ( void ) +{ + //AFE_OpenModule(); + return 0; +} + +int CTvin::Tv_uninit_afe ( void ) +{ + AFE_CloseModule(); + return 0; +} + +int CTvin::get_hdmi_sampling_rate() +{ + char buf[32] = {0}; + + tvReadSysfs("/sys/module/tvin_hdmirx/parameters/audio_sample_rate", buf); + int val = atoi(buf); + return val; +} + +//************************************************************************** +CTvin::CHDMIAudioCheck::CHDMIAudioCheck () +{ + mCheckState = STATE_STOPED; + mpObserver = NULL; + initCheckState(); +} + +CTvin::CHDMIAudioCheck::~CHDMIAudioCheck() +{ +} + +int CTvin::CHDMIAudioCheck::initCheckState() +{ + mResumeLaterTime = 0; + mHDMIAudioCheckEnable = true; + return 0; +} + +int CTvin::CHDMIAudioCheck::startCheck(bool bPause) +{ + LOGD ("startCheck--Check state:%d", mCheckState); + + if ( mCheckState == STATE_RUNNING || mCheckState == STATE_PAUSE ) { + return mCheckState; + } + + m_request_pause_check = bPause; + initCheckState(); + this->run("startCheck"); + return mCheckState; +} + +int CTvin::CHDMIAudioCheck::stopCheck() +{ + AutoMutex _l( mLock ); + LOGD ( "stopCheck()" ); + requestExit(); + return 0; +} + +int CTvin::CHDMIAudioCheck::pauseCheck() +{ + AutoMutex _l( mLock ); + LOGD ( "pauseCheck()" ); + m_request_pause_check = true; + return 0; +} + +int CTvin::CHDMIAudioCheck::resumeCheck(int later)//ms +{ + AutoMutex _l( mLock ); + LOGD ( "resumeCheck()" ); + mResumeLaterTime = later; + m_request_pause_check = false; + mCheckPauseCondition.signal(); + return 0; +} + +int CTvin::CHDMIAudioCheck::requestAndWaitPauseCheck() +{ + AutoMutex _l( mLock ); + LOGD ( "requestAndWaitPauseCheck()" ); + + m_request_pause_check = true; + + if ( mCheckState == STATE_RUNNING ) { + mRequestPauseCondition.wait ( mLock ); + } + + return 0; +} + +void CTvin::CHDMIAudioCheck::setHDMIAudioCheckEnable(bool enable) +{ + if (enable) + LOGD("setHDMIAudioCheck enable"); + else + LOGD("setHDMIAudioCheck disable"); + + mHDMIAudioCheckEnable = enable; +} + +bool CTvin::CHDMIAudioCheck::threadLoop() +{ + //enter onStart() + if ( mpObserver == NULL ) { + return false; + } + + int sleeptime = 200;//ms + mCheckState = STATE_RUNNING; + + while ( !exitPending() ) { //requietexit() or requietexitWait() not call + while ( m_request_pause_check ) { + mLock.lock(); + mRequestPauseCondition.broadcast(); + mCheckState = STATE_PAUSE; + mCheckPauseCondition.wait ( mLock ); //first unlock,when return,lock again,so need,call unlock + mCheckState = STATE_RUNNING; + mLock.unlock(); + // + while (!m_request_pause_check && mResumeLaterTime > 0) { + usleep(10 * 1000); + mResumeLaterTime -= 10; + } + } + mResumeLaterTime = 0; + mpObserver->onHDMIAudioCheckLoop(); + if (mHDMIAudioCheckEnable) { + sleeptime = 20; + } + + if ( !m_request_pause_check ) { + usleep ( sleeptime * 1000 ); + } + } + + mCheckState = STATE_STOPED; + mRequestPauseCondition.broadcast(); + /*exit + true: run again; + false,not run. + */ + return false; +} + + +unsigned long CTvin::CvbsFtmToV4l2ColorStd(tvin_sig_fmt_t fmt) +{ + unsigned long v4l2_std = 0; +#ifdef SUPPORT_ADTV + if (fmt == TVIN_SIG_FMT_CVBS_NTSC_M || fmt == TVIN_SIG_FMT_CVBS_NTSC_443) { + v4l2_std = V4L2_COLOR_STD_NTSC; + } else if (fmt >= TVIN_SIG_FMT_CVBS_PAL_I && fmt <= TVIN_SIG_FMT_CVBS_PAL_CN) { + v4l2_std = V4L2_COLOR_STD_PAL; + } else if (fmt == TVIN_SIG_FMT_CVBS_SECAM) { + v4l2_std = V4L2_COLOR_STD_SECAM; + } else { + v4l2_std = V4L2_COLOR_STD_PAL; + } +#endif + return v4l2_std; +} + +int CTvin::CvbsFtmToColorStdEnum(tvin_sig_fmt_t fmt) +{ + unsigned long v4l2_std = 0; +#ifdef SUPPORT_ADTV + if (fmt == TVIN_SIG_FMT_CVBS_NTSC_M || fmt == TVIN_SIG_FMT_CVBS_NTSC_443) { + v4l2_std = CC_ATV_VIDEO_STD_NTSC; + } else if (fmt >= TVIN_SIG_FMT_CVBS_PAL_I && fmt <= TVIN_SIG_FMT_CVBS_PAL_CN) { + v4l2_std = CC_ATV_VIDEO_STD_PAL; + } else if (fmt == TVIN_SIG_FMT_CVBS_SECAM) { + v4l2_std = CC_ATV_VIDEO_STD_SECAM; + } else { + v4l2_std = CC_ATV_VIDEO_STD_PAL; + } +#endif + return v4l2_std; +} + +int CTvin::GetITContent() +{ + char buf[32] = {0}; + + tvReadSysfs("/sys/module/tvin_hdmirx/parameters/it_content", buf); + int value = atoi(buf); + return value; +} + diff --git a/tv/tvserver/libtv/tvin/CTvin.h b/tv/tvserver/libtv/tvin/CTvin.h new file mode 100644 index 0000000..148073d --- a/dev/null +++ b/tv/tvserver/libtv/tvin/CTvin.h @@ -0,0 +1,803 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _CTVIN_H +#define _CTVIN_H + +#include <pthread.h> +#include <cm.h> +#include <ve.h> +#include <utils/Thread.h> +#include <utils/Mutex.h> +#include "PQType.h" +#ifdef SUPPORT_ADTV +#include "../tv/CFrontEnd.h" +#endif + +using namespace android; + +#define SYS_VFM_MAP_PATH "/sys/class/vfm/map" +#define SYS_DISPLAY_MODE_PATH "/sys/class/display/mode" +#define DEPTH_LEVEL_2DTO3D 33 +static const int DepthTable_2DTO3D[DEPTH_LEVEL_2DTO3D] = { + -64, // -16 + -60, // -15 + -56, // -14 + -52, // -13 + -49, // -12 + -46, // -11 + -43, // -10 + -40, // -09 + -37, // -08 + -34, // -07 + -31, // -06 + -28, // -05 + -25, // -04 + -22, // -03 + -19, // -02 + -16, // -01 + -13, // 0 + 3, // 1 + 6, // 2 + 9, // 3 + 12, // 4 + 15, // 5 + 18, // 6 + 21, // 7 + 24, // 8 + 28, // 9 + 32, // 10 + 36, // 11 + 40, // 12 + 44, // 13 + 48, // 14 + 52, // 15 + 56, // 16 +}; + +enum { + MEMP_VDIN_WITHOUT_3D = 0, + MEMP_VDIN_WITH_3D, + MEMP_DCDR_WITHOUT_3D, + MEMP_DCDR_WITH_3D, + MEMP_ATV_WITHOUT_3D, + MEMP_ATV_WITH_3D, +}; + +// *************************************************************************** +// *** TVIN general definition/enum/struct *********************************** +// *************************************************************************** +/* tvin input port select */ + +const char *tvin_port_str(enum tvin_port_e port); + +//tvin signal status +typedef enum tvin_sig_status_e { + TVIN_SIG_STATUS_NULL = 0, // processing status from init to the finding of the 1st confirmed status + TVIN_SIG_STATUS_NOSIG, // no signal - physically no signal + TVIN_SIG_STATUS_UNSTABLE, // unstable - physically bad signal + TVIN_SIG_STATUS_NOTSUP, // not supported - physically good signal & not supported + TVIN_SIG_STATUS_STABLE, // stable - physically good signal & supported +} tvin_sig_status_t; + +const char *tvin_sig_status_str(enum tvin_sig_status_e status); + +// tvin parameters +#define TVIN_PARM_FLAG_CAP 0x00000001 //tvin_parm_t.flag[ 0]: 1/enable or 0/disable frame capture function +#define TVIN_PARM_FLAG_CAL 0x00000002 //tvin_parm_t.flag[ 1]: 1/enable or 0/disable adc calibration +/*used for processing 3d in ppmgr set this flag to drop one field and send real height in vframe*/ +#define TVIN_PARM_FLAG_2D_TO_3D 0x00000004 //tvin_parm_t.flag[ 2]: 1/enable or 0/disable 2D->3D mode + +const char *tvin_trans_fmt_str(enum tvin_trans_fmt trans_fmt); + +typedef enum tvin_color_fmt_e { + TVIN_RGB444 = 0, + TVIN_YUV422, // 1 + TVIN_YUV444, // 2 + TVIN_YUYV422,// 3 + TVIN_YVYU422,// 4 + TVIN_UYVY422,// 5 + TVIN_VYUY422,// 6 + TVIN_NV12, // 7 + TVIN_NV21, // 8 + TVIN_BGGR, // 9 raw data + TVIN_RGGB, // 10 raw data + TVIN_GBRG, // 11 raw data + TVIN_GRBG, // 12 raw data + TVIN_COLOR_FMT_MAX, +} tvin_color_fmt_t; + +const char *tvin_color_fmt_str(enum tvin_color_fmt_e color_fmt); +typedef enum tvin_scan_mode_e { + TVIN_SCAN_MODE_NULL = 0, + TVIN_SCAN_MODE_PROGRESSIVE, + TVIN_SCAN_MODE_INTERLACED, +} tvin_scan_mode_t; + +typedef struct tvin_info_s { + enum tvin_trans_fmt trans_fmt; + enum tvin_sig_fmt_e fmt; + volatile enum tvin_sig_status_e status; + enum tvin_color_fmt_e cfmt; + unsigned int fps; + unsigned int reserved; +} tvin_info_t; + +typedef struct tvin_buf_info_s { + unsigned int vf_size; + unsigned int buf_count; + unsigned int buf_width; + unsigned int buf_height; + unsigned int buf_size; + unsigned int wr_list_size; +} tvin_buf_info_t; + +typedef struct tvin_video_buf_s { + unsigned int index; + unsigned int reserved; +} tvin_video_buf_t; + +typedef struct tvin_parm_s { + int index; // index of frontend for vdin + enum tvin_port_e port; // must set port in IOCTL + struct tvin_info_s info; + unsigned int hist_pow; + unsigned int luma_sum; + unsigned int pixel_sum; + unsigned short histgram[64]; + unsigned int flag; + unsigned short dest_width;//for vdin horizontal scale down + unsigned short dest_height;//for vdin vertical scale down + bool h_reverse;//for vdin horizontal reverse + bool v_reverse;//for vdin vertical reverse + unsigned int reserved; +} tvin_parm_t; + + + +// *************************************************************************** +// *** AFE module definition/enum/struct ************************************* +// *************************************************************************** + +typedef enum tvafe_cmd_status_e { + TVAFE_CMD_STATUS_IDLE = 0, // idle, be ready for TVIN_IOC_S_AFE_VGA_AUTO command + TVAFE_CMD_STATUS_PROCESSING, // TVIN_IOC_S_AFE_VGA_AUTO command is in process + TVAFE_CMD_STATUS_SUCCESSFUL, // TVIN_IOC_S_AFE_VGA_AUTO command is done with success + TVAFE_CMD_STATUS_FAILED, // TVIN_IOC_S_AFE_VGA_AUTO command is done with failure + TVAFE_CMD_STATUS_TERMINATED, // TVIN_IOC_S_AFE_VGA_AUTO command is terminated by others related +} tvafe_cmd_status_t; + +typedef struct tvafe_vga_edid_s { + unsigned char value[256]; //256 byte EDID +} tvafe_vga_edid_t; + +typedef struct tvafe_comp_wss_s { + unsigned int wss1[5]; + unsigned int wss2[5]; +} tvafe_comp_wss_t; + + +#define TVAFE_ADC_CAL_VALID 0x00000001 +typedef struct tvafe_adc_cal_s { + // ADC A + unsigned short a_analog_clamp; // 0x00~0x7f + unsigned short a_analog_gain; // 0x00~0xff, means 0dB~6dB + unsigned short a_digital_offset1; // offset for fine-tuning + // s11.0: signed value, 11 integer bits, 0 fraction bits + unsigned short a_digital_gain; // 0~3.999 + // u2.10: unsigned value, 2 integer bits, 10 fraction bits + unsigned short a_digital_offset2; // offset for format + // s11.0: signed value, 11 integer bits, 0 fraction bits + // ADC B + unsigned short b_analog_clamp; // ditto to ADC A + unsigned short b_analog_gain; + unsigned short b_digital_offset1; + unsigned short b_digital_gain; + unsigned short b_digital_offset2; + // ADC C + unsigned short c_analog_clamp; // ditto to ADC A + unsigned short c_analog_gain; + unsigned short c_digital_offset1; + unsigned short c_digital_gain; + unsigned short c_digital_offset2; + // ADC D + unsigned short d_analog_clamp; // ditto to ADC A + unsigned short d_analog_gain; + unsigned short d_digital_offset1; + unsigned short d_digital_gain; + unsigned short d_digital_offset2; + unsigned int reserved; // bit[ 0]: TVAFE_ADC_CAL_VALID +} tvafe_adc_cal_t; + +typedef struct tvafe_adc_cal_clamp_s { + short a_analog_clamp_diff; + short b_analog_clamp_diff; + short c_analog_clamp_diff; +} tvafe_adc_cal_clamp_t; + +typedef struct tvafe_adc_comp_cal_s { + struct tvafe_adc_cal_s comp_cal_val[3]; +} tvafe_adc_comp_cal_t; + +typedef enum tvafe_cvbs_video_e { + TVAFE_CVBS_VIDEO_HV_UNLOCKED = 0, + TVAFE_CVBS_VIDEO_H_LOCKED, + TVAFE_CVBS_VIDEO_V_LOCKED, + TVAFE_CVBS_VIDEO_HV_LOCKED, +} tvafe_cvbs_video_t; + +// for pin selection +typedef enum tvafe_adc_pin_e { + TVAFE_ADC_PIN_NULL = 0, +#if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV) + TVAFE_CVBS_IN0 = 1, + TVAFE_CVBS_IN1 = 2, + TVAFE_CVBS_IN2 = 3, + TVAFE_CVBS_IN3 = 4,//as atvdemod to tvafe +#else + TVAFE_ADC_PIN_A_PGA_0 = 1, + TVAFE_ADC_PIN_A_PGA_1 = 2, + TVAFE_ADC_PIN_A_PGA_2 = 3, + TVAFE_ADC_PIN_A_PGA_3 = 4, + TVAFE_ADC_PIN_A_PGA_4 = 5, + TVAFE_ADC_PIN_A_PGA_5 = 6, + TVAFE_ADC_PIN_A_PGA_6 = 7, + TVAFE_ADC_PIN_A_PGA_7 = 8, + TVAFE_ADC_PIN_A_0 = 9, + TVAFE_ADC_PIN_A_1 = 10, + TVAFE_ADC_PIN_A_2 = 11, + TVAFE_ADC_PIN_A_3 = 12, + TVAFE_ADC_PIN_A_4 = 13, + TVAFE_ADC_PIN_A_5 = 14, + TVAFE_ADC_PIN_A_6 = 15, + TVAFE_ADC_PIN_A_7 = 16, + TVAFE_ADC_PIN_B_0 = 17, + TVAFE_ADC_PIN_B_1 = 18, + TVAFE_ADC_PIN_B_2 = 19, + TVAFE_ADC_PIN_B_3 = 20, + TVAFE_ADC_PIN_B_4 = 21, + TVAFE_ADC_PIN_B_5 = 22, + TVAFE_ADC_PIN_B_6 = 23, + TVAFE_ADC_PIN_B_7 = 24, + TVAFE_ADC_PIN_C_0 = 25, + TVAFE_ADC_PIN_C_1 = 26, + TVAFE_ADC_PIN_C_2 = 27, + TVAFE_ADC_PIN_C_3 = 28, + TVAFE_ADC_PIN_C_4 = 29, + TVAFE_ADC_PIN_C_5 = 30, + TVAFE_ADC_PIN_C_6 = 31, + TVAFE_ADC_PIN_C_7 = 32, + TVAFE_ADC_PIN_D_0 = 33, + TVAFE_ADC_PIN_D_1 = 34, + TVAFE_ADC_PIN_D_2 = 35, + TVAFE_ADC_PIN_D_3 = 36, + TVAFE_ADC_PIN_D_4 = 37, + TVAFE_ADC_PIN_D_5 = 38, + TVAFE_ADC_PIN_D_6 = 39, + TVAFE_ADC_PIN_D_7 = 40, + TVAFE_ADC_PIN_SOG_0 = 41, + TVAFE_ADC_PIN_SOG_1 = 42, + TVAFE_ADC_PIN_SOG_2 = 43, + TVAFE_ADC_PIN_SOG_3 = 44, + TVAFE_ADC_PIN_SOG_4 = 45, + TVAFE_ADC_PIN_SOG_5 = 46, + TVAFE_ADC_PIN_SOG_6 = 47, + TVAFE_ADC_PIN_SOG_7 = 48, +#endif + TVAFE_ADC_PIN_MAX, +} tvafe_adc_pin_t; + +typedef enum tvafe_src_sig_e { +#if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV) + CVBS_IN0 = 0, + CVBS_IN1, + CVBS_IN2, + CVBS_IN3, +#else + CVBS0_Y = 0, + CVBS0_SOG, + CVBS1_Y, + CVBS1_SOG, + CVBS2_Y, + CVBS2_SOG, + CVBS3_Y, + CVBS3_SOG, + CVBS4_Y, + CVBS4_SOG, + CVBS5_Y, + CVBS5_SOG, + CVBS6_Y, + CVBS6_SOG, + CVBS7_Y, + CVBS7_SOG, + S_VIDEO0_Y, + S_VIDEO0_C, + S_VIDEO0_SOG, + S_VIDEO1_Y, + S_VIDEO1_C, + S_VIDEO1_SOG, + S_VIDEO2_Y, + S_VIDEO2_C, + S_VIDEO2_SOG, + S_VIDEO3_Y, + S_VIDEO3_C, + S_VIDEO3_SOG, + S_VIDEO4_Y, + S_VIDEO4_C, + S_VIDEO4_SOG, + S_VIDEO5_Y, + S_VIDEO5_C, + S_VIDEO5_SOG, + S_VIDEO6_Y, + S_VIDEO6_C, + S_VIDEO6_SOG, + S_VIDEO7_Y, + S_VIDEO7_C, + S_VIDEO7_SOG, + VGA0_G, + VGA0_B, + VGA0_R, + VGA0_SOG, + VGA1_G, + VGA1_B, + VGA1_R, + VGA1_SOG, + VGA2_G, + VGA2_B, + VGA2_R, + VGA2_SOG, + VGA3_G, + VGA3_B, + VGA3_R, + VGA3_SOG, + VGA4_G, + VGA4_B, + VGA4_R, + VGA4_SOG, + VGA5_G, + VGA5_B, + VGA5_R, + VGA5_SOG, + VGA6_G, + VGA6_B, + VGA6_R, + VGA6_SOG, + VGA7_G, + VGA7_B, + VGA7_R, + VGA7_SOG, + COMP0_Y, + COMP0_PB, + COMP0_PR, + COMP0_SOG, + COMP1_Y, + COMP1_PB, + COMP1_PR, + COMP1_SOG, + COMP2_Y, + COMP2_PB, + COMP2_PR, + COMP2_SOG, + COMP3_Y, + COMP3_PB, + COMP3_PR, + COMP3_SOG, + COMP4_Y, + COMP4_PB, + COMP4_PR, + COMP4_SOG, + COMP5_Y, + COMP5_PB, + COMP5_PR, + COMP5_SOG, + COMP6_Y, + COMP6_PB, + COMP6_PR, + COMP6_SOG, + COMP7_Y, + COMP7_PB, + COMP7_PR, + COMP7_SOG, + SCART0_G, + SCART0_B, + SCART0_R, + SCART0_CVBS, + SCART1_G, + SCART1_B, + SCART1_R, + SCART1_CVBS, + SCART2_G, + SCART2_B, + SCART2_R, + SCART2_CVBS, + SCART3_G, + SCART3_B, + SCART3_R, + SCART3_CVBS, + SCART4_G, + SCART4_B, + SCART4_R, + SCART4_CVBS, + SCART5_G, + SCART5_B, + SCART5_R, + SCART5_CVBS, + SCART6_G, + SCART6_B, + SCART6_R, + SCART6_CVBS, + SCART7_G, + SCART7_B, + SCART7_R, + SCART7_CVBS, +#endif + TVAFE_SRC_SIG_MAX_NUM, +} tvafe_src_sig_t; + +typedef struct tvafe_pin_mux_s { + enum tvafe_adc_pin_e pin[TVAFE_SRC_SIG_MAX_NUM]; +} tvafe_pin_mux_t; + + +// *************************************************************************** +// *** IOCTL command definition ********************************************** +// *************************************************************************** + +#define TVIN_IOC_MAGIC 'T' + +//GENERAL +#define TVIN_IOC_OPEN _IOW(TVIN_IOC_MAGIC, 0x01, struct tvin_parm_s) +#define TVIN_IOC_START_DEC _IOW(TVIN_IOC_MAGIC, 0x02, struct tvin_parm_s) +#define TVIN_IOC_STOP_DEC _IO( TVIN_IOC_MAGIC, 0x03) +#define TVIN_IOC_CLOSE _IO( TVIN_IOC_MAGIC, 0x04) +#define TVIN_IOC_G_PARM _IOR(TVIN_IOC_MAGIC, 0x05, struct tvin_parm_s) +#define TVIN_IOC_S_PARM _IOW(TVIN_IOC_MAGIC, 0x06, struct tvin_parm_s) +#define TVIN_IOC_G_SIG_INFO _IOR(TVIN_IOC_MAGIC, 0x07, struct tvin_info_s) +#define TVIN_IOC_G_BUF_INFO _IOR(TVIN_IOC_MAGIC, 0x08, struct tvin_buf_info_s) +#define TVIN_IOC_START_GET_BUF _IO( TVIN_IOC_MAGIC, 0x09) +#define TVIN_IOC_GET_BUF _IOR(TVIN_IOC_MAGIC, 0x10, struct tvin_video_buf_s) +#define TVIN_IOC_PAUSE_DEC _IO(TVIN_IOC_MAGIC, 0x41) +#define TVIN_IOC_RESUME_DEC _IO(TVIN_IOC_MAGIC, 0x42) +#define TVIN_IOC_VF_REG _IO(TVIN_IOC_MAGIC, 0x43) +#define TVIN_IOC_VF_UNREG _IO(TVIN_IOC_MAGIC, 0x44) +#define TVIN_IOC_FREEZE_VF _IO(TVIN_IOC_MAGIC, 0x45) +#define TVIN_IOC_UNFREEZE_VF _IO(TVIN_IOC_MAGIC, 0x46) +#define TVIN_IOC_SNOWON _IO(TVIN_IOC_MAGIC, 0x47) +#define TVIN_IOC_SNOWOFF _IO(TVIN_IOC_MAGIC, 0x48) + + +//TVAFE +#define TVIN_IOC_S_AFE_ADC_CAL _IOW(TVIN_IOC_MAGIC, 0x11, struct tvafe_adc_cal_s) +#define TVIN_IOC_G_AFE_ADC_CAL _IOR(TVIN_IOC_MAGIC, 0x12, struct tvafe_adc_cal_s) +#define TVIN_IOC_G_AFE_COMP_WSS _IOR(TVIN_IOC_MAGIC, 0x13, struct tvafe_comp_wss_s) +#define TVIN_IOC_S_AFE_VGA_EDID _IOW(TVIN_IOC_MAGIC, 0x14, struct tvafe_vga_edid_s) +#define TVIN_IOC_G_AFE_VGA_EDID _IOR(TVIN_IOC_MAGIC, 0x15, struct tvafe_vga_edid_s) +#define TVIN_IOC_S_AFE_VGA_PARM _IOW(TVIN_IOC_MAGIC, 0x16, struct tvafe_vga_parm_s) +#define TVIN_IOC_G_AFE_VGA_PARM _IOR(TVIN_IOC_MAGIC, 0x17, struct tvafe_vga_parm_s) +#define TVIN_IOC_S_AFE_VGA_AUTO _IO( TVIN_IOC_MAGIC, 0x18) +#define TVIN_IOC_G_AFE_CMD_STATUS _IOR(TVIN_IOC_MAGIC, 0x19, enum tvafe_cmd_status_e) +#define TVIN_IOC_G_AFE_CVBS_LOCK _IOR(TVIN_IOC_MAGIC, 0x1a, enum tvafe_cvbs_video_e) +#define TVIN_IOC_S_AFE_CVBS_STD _IOW(TVIN_IOC_MAGIC, 0x1b, enum tvin_sig_fmt_e) +#define TVIN_IOC_CALLMASTER_SET _IOW(TVIN_IOC_MAGIC, 0x1c, enum tvin_port_e) +#define TVIN_IOC_CALLMASTER_GET _IO( TVIN_IOC_MAGIC, 0x1d) +#define TVIN_IOC_S_AFE_ADC_COMP_CAL _IOW(TVIN_IOC_MAGIC, 0x1e, struct tvafe_adc_comp_cal_s) +#define TVIN_IOC_G_AFE_ADC_COMP_CAL _IOR(TVIN_IOC_MAGIC, 0x1f, struct tvafe_adc_comp_cal_s) +//#define TVIN_IOC_LOAD_REG _IOW(TVIN_IOC_MAGIC, 0x20, struct am_regs_s) +#define TVIN_IOC_S_AFE_ADC_DIFF _IOW(TVIN_IOC_MAGIC, 0x21, struct tvafe_adc_cal_clamp_s) +#define TVIN_IOC_S_AFE_SONWON _IO(TVIN_IOC_MAGIC, 0x22) +#define TVIN_IOC_S_AFE_SONWOFF _IO(TVIN_IOC_MAGIC, 0x23) + + +// *************************************************************************** +// *** add more ********************************************** +// *************************************************************************** + +enum { + TV_PATH_VDIN_AMLVIDEO2_PPMGR_DEINTERLACE_AMVIDEO, + TV_PATH_DECODER_AMLVIDEO2_PPMGR_DEINTERLACE_AMVIDEO, +}; + +#define CAMERA_IOC_MAGIC 'C' +#define CAMERA_IOC_START _IOW(CAMERA_IOC_MAGIC, 0x01, struct camera_info_s) +#define CAMERA_IOC_STOP _IO(CAMERA_IOC_MAGIC, 0x02) +#define CAMERA_IOC_SET_PARA _IOW(CAMERA_IOC_MAGIC, 0x03, struct camera_info_s) +#define CAMERA_IOC_GET_PARA _IOR(CAMERA_IOC_MAGIC, 0x04, struct camera_info_s) + + +#define CC_HIST_GRAM_BUF_SIZE (64) +/*******************************extend define*******************************/ + +typedef enum adc_cal_type_e { + CAL_YPBPR = 0, + CAL_VGA, + CAL_CVBS, +} adc_cal_type_t; + +typedef enum signal_range_e { + RANGE100 = 0, + RANGE75, +} signal_range_t; + +typedef enum tv_hdmi_port_id_e { + HDMI_PORT_1 = 1, + HDMI_PORT_2, + HDMI_PORT_3, + HDMI_PORT_4, +} tv_hdmi_port_id_t; + +typedef enum tv_hdmi_hdcp_version_e { + HDMI_HDCP_VER_14 = 0, + HDMI_HDCP_VER_22 , +} tv_hdmi_hdcp_version_t; + +typedef enum tv_hdmi_edid_version_e { + HDMI_EDID_VER_14 = 0, + HDMI_EDID_VER_20 , +} tv_hdmi_edid_version_t; + +typedef enum tv_hdmi_hdcpkey_enable_e { + hdcpkey_enable = 0, + hdcpkey_disable , +} tv_hdmi_hdcpkey_enable_t; + +typedef enum tv_hdmi_color_range_e { + AUTO_RANGE = 0, + FULL_RANGE, + LIMIT_RANGE, +} tv_hdmi_color_range_t; + + + +typedef struct adc_cal_s { + unsigned int rcr_max; + unsigned int rcr_min; + unsigned int g_y_max; + unsigned int g_y_min; + unsigned int bcb_max; + unsigned int bcb_min; + unsigned int cr_white; + unsigned int cb_white; + unsigned int cr_black; + unsigned int cb_black; +} adc_cal_t; + +typedef struct tvin_window_pos_s { + int x1; + int y1; + int x2; + int y2; +} tvin_window_pos_t; + + +typedef enum tv_path_type_e { + TV_PATH_TYPE_DEFAULT, + TV_PATH_TYPE_TVIN, + TV_PATH_TYPE_MAX, +} tv_path_type_t; + +typedef enum tv_path_status_e { + TV_PATH_STATUS_NO_DEV = -2, + TV_PATH_STATUS_ERROR = -1, + TV_PATH_STATUS_INACTIVE = 0, + TV_PATH_STATUS_ACTIVE = 1, + TV_PATH_STATUS_MAX, +} tv_path_status_t; + +typedef enum tv_audio_channel_e { + TV_AUDIO_LINE_IN_0, + TV_AUDIO_LINE_IN_1, + TV_AUDIO_LINE_IN_2, + TV_AUDIO_LINE_IN_3, + TV_AUDIO_LINE_IN_4, + TV_AUDIO_LINE_IN_5, + TV_AUDIO_LINE_IN_6, + TV_AUDIO_LINE_IN_7, + TV_AUDIO_LINE_IN_MAX, +} tv_audio_channel_t; + +typedef enum tv_audio_in_source_type_e { + TV_AUDIO_IN_SOURCE_TYPE_LINEIN, + TV_AUDIO_IN_SOURCE_TYPE_ATV, + TV_AUDIO_IN_SOURCE_TYPE_HDMI, + TV_AUDIO_IN_SOURCE_TYPE_SPDIF, + TV_AUDIO_IN_SOURCE_TYPE_MAX, +} tv_audio_in_source_type_t; + +#define CC_RESOLUTION_1366X768_W (1366) +#define CC_RESOLUTION_1366X768_H (768) +#define CC_RESOLUTION_1920X1080_W (1920) +#define CC_RESOLUTION_1920X1080_H (1080) +#define CC_RESOLUTION_3840X2160_W (3840) +#define CC_RESOLUTION_3840X2160_H (2160) + +typedef enum tv_source_connect_detect_status_e { + CC_SOURCE_PLUG_OUT = 0, + CC_SOURCE_PLUG_IN = 1, +} tv_source_connect_detect_status_t; + + + +#define CC_REQUEST_LIST_SIZE (32) +#define CC_SOURCE_DEV_REFRESH_CNT (E_LA_MAX) + +class CTvin { +public: + CTvin(); + ~CTvin(); + int OpenTvin(); + int init_vdin(); + int uninit_vdin ( void ); + int Tv_init_afe ( void ); + int Tv_uninit_afe ( void ); + int Tvin_RemovePath ( tv_path_type_t pathtype ); + int Tvin_CheckPathActive ( tv_path_type_t path_type ); + int setMpeg2Vdin(int enable); + //pre apis + int AFE_DeviceIOCtl ( int request, ... ); + void TvinApi_CloseAFEModule ( void ); + int TvinApi_SetVdinHVScale ( int vdinx, int hscale, int vscale ); + int TvinApi_SetStartDropFrameCn ( int count ); + int TvinApi_SetCompPhaseEnable ( int enable ); + tvin_trans_fmt TvinApi_Get3DDectMode(); + int TvinApi_GetHDMIAudioStatus ( void ); + int Tvin_StartDecoder ( tvin_info_t &info ); + int Tvin_StopDecoder(); + int get_hdmi_sampling_rate(); + int SwitchPort (tvin_port_t source_port ); + int SwitchSnow(bool enable); + bool getSnowStatus(void); + int Tvin_WaitPathInactive ( tv_path_type_t pathtype ); + int VDIN_AddPath ( const char *videopath ); + int VDIN_RmDefPath ( void ); + int VDIN_RmTvPath ( void ); + int VDIN_AddVideoPath ( int selPath ); + + int VDIN_OpenModule(); + int VDIN_CloseModule(); + int VDIN_DeviceIOCtl ( int request, ... ); + int VDIN_GetDeviceFileHandle(); + int VDIN_OpenPort ( tvin_port_t port ); + int VDIN_ClosePort(); + int VDIN_StartDec ( const struct tvin_parm_s *vdinParam ); + int VDIN_StopDec(); + int VDIN_GetSignalInfo ( struct tvin_info_s *SignalInfo ); + int VDIN_SetVdinParam ( const struct tvin_parm_s *vdinParam ); + int VDIN_GetVdinParam ( const struct tvin_parm_s *vdinParam ); + void VDIN_GetDisplayVFreq (int need_freq, int *iSswitch, char * display_mode); + int VDIN_SetDisplayVFreq ( int freq, bool isFbc); + + int VDIN_Get_avg_luma(void); + int VDIN_SetMVCViewMode ( int mode ); + int VDIN_GetMVCViewMode ( void ); + int VDIN_SetDIBuffMgrMode ( int mgr_mode ); + int VDIN_SetDICFG ( int cfg ); + int VDIN_SetDI3DDetc ( int enable ); + int VDIN_Get3DDetc ( void ); + int VDIN_GetVscalerStatus ( void ); + int VDIN_TurnOnBlackBarDetect ( int isEnable ); + int VDIN_SetVideoFreeze ( int enable ); + int VDIN_SetDIBypasshd ( int enable ); + int VDIN_SetDIBypassAll ( int enable ); + int VDIN_SetDIBypass_Get_Buf_Threshold ( int enable ); + int VDIN_SetDIBypassProg ( int enable ); + int VDIN_SetDIBypassDynamic ( int flag ); + int VDIN_EnableRDMA ( int enable ); + + int getVdinDeviceFd(); + int AFE_OpenModule ( void ); + void AFE_CloseModule ( void ); int AFE_SetCVBSStd ( tvin_sig_fmt_t cvbs_fmt ); + int AFE_SetVGAEdid ( const unsigned char *ediddata ); + int AFE_GetVGAEdid ( unsigned char *ediddata ); + int AFE_SetADCTimingAdjust ( const struct tvafe_vga_parm_s *timingadj ); + int AFE_GetADCCurrentTimingAdjust ( struct tvafe_vga_parm_s *timingadj ); + int AFE_VGAAutoAdjust ( struct tvafe_vga_parm_s *timingadj ); + int AFE_SetVGAAutoAjust ( void ); + int AFE_GetVGAAutoAdjustCMDStatus ( tvafe_cmd_status_t *Status ); + int AFE_GetAdcCal ( struct tvafe_adc_cal_s *adccalvalue ); + int AFE_SetAdcCal ( struct tvafe_adc_cal_s *adccalvalue ); + int AFE_GetAdcCompCal ( struct tvafe_adc_comp_cal_s *adccalvalue ); + int AFE_SetAdcCompCal ( struct tvafe_adc_comp_cal_s *adccalvalue ); + int AFE_GetYPbPrWSSinfo ( struct tvafe_comp_wss_s *wssinfo ); + unsigned int data_limit ( float data ); + void matrix_convert_yuv709_to_rgb ( unsigned int y, unsigned int u, unsigned int v, unsigned int *r, unsigned int *g, unsigned int *b ); + void re_order ( unsigned int *a, unsigned int *b ); + char *get_cap_addr ( enum adc_cal_type_e calType ); + inline unsigned char get_mem_data ( char *dp, unsigned int addr ); + int get_frame_average ( enum adc_cal_type_e calType, struct adc_cal_s *mem_data ); + struct adc_cal_s get_n_frame_average ( enum adc_cal_type_e calType ) ; + int AFE_GetMemData ( int typeSel, struct adc_cal_s *mem_data ); + int AFE_GetCVBSLockStatus ( enum tvafe_cvbs_video_e *cvbs_lock_status ); + static int CvbsFtmToColorStdEnum(tvin_sig_fmt_t fmt); + int VDIN_GetPortConnect ( int port ); + int VDIN_OpenHDMIPinMuxOn ( bool flag ); + int GetITContent(); + /*******************************************extend funs*********************/ + static tv_source_input_type_t Tvin_SourcePortToSourceInputType ( tvin_port_t source_port ); + static tv_source_input_type_t Tvin_SourceInputToSourceInputType ( tv_source_input_t source_input ); + static tvin_port_t Tvin_GetSourcePortBySourceType ( tv_source_input_type_t source_type ); + static tvin_port_t Tvin_GetSourcePortBySourceInput ( tv_source_input_t source_input ); + static unsigned int Tvin_TransPortStringToValue(const char *port_str); + static void Tvin_LoadSourceInputToPortMap(); + static int Tvin_GetSourcePortByCECPhysicalAddress(int physical_addr); + static tv_audio_channel_t Tvin_GetInputSourceAudioChannelIndex ( tv_source_input_t source_input ); + static tv_audio_in_source_type_t Tvin_GetAudioInSourceType ( tv_source_input_t source_input ); + static tv_source_input_t Tvin_PortToSourceInput ( tvin_port_t port ); + static int isVgaFmtInHdmi ( tvin_sig_fmt_t fmt ); + static int isSDFmtInHdmi ( tvin_sig_fmt_t fmt ); + static bool Tvin_is50HzFrameRateFmt ( tvin_sig_fmt_t fmt ); + static bool Tvin_IsDeinterlaceFmt ( tvin_sig_fmt_t fmt ); + static unsigned long CvbsFtmToV4l2ColorStd(tvin_sig_fmt_t fmt); + + static CTvin *getInstance(); + +public: + class CHDMIAudioCheck: public Thread { + public: + CHDMIAudioCheck (); + ~CHDMIAudioCheck(); + int startCheck(bool bPause = true); + int stopCheck(); + int pauseCheck(); + int resumeCheck(int later = 0); + int initCheckState(); + void setHDMIAudioCheckEnable(bool enable = true); + int requestAndWaitPauseCheck(); + //first pause detect? ok + + class IHDMIAudioCheckObserver { + public: + IHDMIAudioCheckObserver() + {}; + virtual ~IHDMIAudioCheckObserver() + {}; + virtual void onHDMIAudioCheckEnter() {}; + virtual void onHDMIAudioCheckLoop() {}; + }; + void setObserver ( IHDMIAudioCheckObserver *pOb ) + { + mpObserver = pOb; + }; + + private: + bool threadLoop(); + + //member + mutable Mutex mLock; + Condition mCheckPauseCondition; + Condition mRequestPauseCondition; + volatile bool m_request_pause_check; + enum CheckState { + STATE_STOPED = 0, + STATE_RUNNING, + STATE_PAUSE + }; + int mCheckState; + int mResumeLaterTime; + bool mHDMIAudioCheckEnable; + IHDMIAudioCheckObserver *mpObserver; + }; + +private: + static CTvin *mInstance; + int mAfeDevFd; + int mVdin0DevFd; + bool m_snow_status; + tvin_parm_t m_tvin_param; + tvin_parm_t gTvinVDINParam; + tvin_info_t gTvinVDINSignalInfo; + tvin_parm_t gTvinAFEParam; + tvin_info_t gTvinAFESignalInfo; + static int mSourceInputToPortMap[SOURCE_MAX]; + char gVideoPath[256]; + bool mDecoderStarted; + + char config_tv_path[64]; + char config_default_path[64]; +}; +#endif diff --git a/tv/tvserver/libtv/tvsetting/CBlobDeviceRam.cpp b/tv/tvserver/libtv/tvsetting/CBlobDeviceRam.cpp new file mode 100644 index 0000000..38779c4 --- a/dev/null +++ b/tv/tvserver/libtv/tvsetting/CBlobDeviceRam.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvSettingDeviceRam" + +#include <stdio.h> +#include <string.h> + +#include <android/log.h> + +#include "CTvSettingDeviceRam.h" +#include "CTvLog.h" + +CTvSettingDeviceRam::CTvSettingDeviceRam() +{ + RAM_DEV_TOTAL_SIZE = 4 * 1024; + RAM_DEV_RW_START_OFFSET = 0; + RAM_DEV_RW_END_OFFSET = RAM_DEV_TOTAL_SIZE - 1; + RAM_DEV_W_PAGE_SIZE = 32; + RAM_DEV_R_PAGE_SIZE = 32; + RAM_DEV_SLAVE_ADDR = (0xA0 >> 1); + RAM_DEV_RW_TEST_OFFSET = -1; + device_use_buffer = 0; + device_buf = NULL; + gFilePathBuf[0] = '\0'; +} + +CTvSettingDeviceRam::~CTvSettingDeviceRam() +{ +} + +int CTvSettingDeviceRam::GetDeviceTotalSize() +{ + return 0; +} +int CTvSettingDeviceRam::InitCheck() +{ + int tmp_dev_total_size = 0; + + if (device_buf == NULL) { + tmp_dev_total_size = GetDeviceTotalSize(); + if (tmp_dev_total_size <= 0) { + LOGE("%s, Device file size must be more than 0.\n", "TV"); + return -1; + } + + device_buf = new unsigned char[tmp_dev_total_size]; + if (device_buf == NULL) { + return -1; + } + + memset((void *) device_buf, CC_INIT_BYTE_VAL, tmp_dev_total_size); + } + + return 0; +} + +int CTvSettingDeviceRam::OpenDevice() +{ + return 0; +} + +int CTvSettingDeviceRam::CloseDevice(int *device_fd) +{ + + + return 0; +} + +int CTvSettingDeviceRam::CheckDeviceWrAvaliable(int offset, int len) +{ + /*int tmp_dev_start_offset = 0; + int tmp_dev_end_offset = 0; + + GetDeviceRWStartOffset(&tmp_dev_start_offset); + if (tmp_dev_start_offset < 0) { + LOGE("%s, Device file r/w start offset must be greater than or euqal to 0.\n", "TV"); + return -1; + } + + GetDeviceRWEndOffset(&tmp_dev_end_offset); + if (tmp_dev_end_offset < 0) { + LOGE("%s, Device file r/w end offset must be more than 0.\n", "TV"); + return -1; + } + + if (len <= 0) { + LOGE("%s, The w/r length should be more than 0.\n", "TV"); + return -1; + } + + if ((len + tmp_dev_start_offset + offset) > tmp_dev_end_offset + 1) { + LOGE("%s, w/r would be overflow!!! len = %d, start offset = %d, offset = %d, end offset = %d.\n", "TV", len, tmp_dev_start_offset, offset, tmp_dev_end_offset); + return -1; + } + + if (ValidOperateCheck() < 0) { + return -1; + }*/ + + return 0; +} + +int CTvSettingDeviceRam::WriteSpecialBytes(int offset, int len, unsigned char data_buf[]) +{ + int tmp_dev_w_page_size = 0; + + //GetDeviceWritePageSize(&tmp_dev_w_page_size); + //if (len > tmp_dev_w_page_size) { + // LOGE("%s, The write length should be less than page size(%d).\n", "TV", tmp_dev_w_page_size); + // return -1; + // } + + if (CheckDeviceWrAvaliable(offset, len) < 0) { + return -1; + } + + memcpy((void *) (device_buf + offset), (void *) data_buf, len); + + return 0; +} + +int CTvSettingDeviceRam::ReadSpecialBytes(int offset, int len, unsigned char data_buf[]) +{ + if (CheckDeviceWrAvaliable(offset, len) < 0) { + return -1; + } + + memcpy((void *) data_buf, (void *) (device_buf + offset), len); + + return 0; +} diff --git a/tv/tvserver/libtv/tvsetting/CBlobDeviceRam.h b/tv/tvserver/libtv/tvsetting/CBlobDeviceRam.h new file mode 100644 index 0000000..cec7dcc --- a/dev/null +++ b/tv/tvserver/libtv/tvsetting/CBlobDeviceRam.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef TV_SETTING_RAM_H +#define TV_SETTING_RAM_H + +#include "CTvSettingBaseDevice.h" + +class CTvSettingDeviceRam: public CTvSettingBaseDevice { + +public: + CTvSettingDeviceRam(); + virtual ~CTvSettingDeviceRam(); + + virtual int InitCheck(); + virtual int OpenDevice(); + virtual int CloseDevice(int *device_fd); + virtual int GetDeviceTotalSize(); + + virtual int CheckDeviceWrAvaliable(int offset, int len); + virtual int WriteSpecialBytes(int offset, int len, unsigned char data_buf[]); + virtual int ReadSpecialBytes(int offset, int len, unsigned char data_buf[]); + +private: + int ValidOperateCheck(); + +private: + int RAM_DEV_TOTAL_SIZE; + int RAM_DEV_RW_START_OFFSET; + int RAM_DEV_RW_END_OFFSET; + int RAM_DEV_W_PAGE_SIZE; + int RAM_DEV_R_PAGE_SIZE; + int RAM_DEV_SLAVE_ADDR; + int RAM_DEV_RW_TEST_OFFSET; + int device_use_buffer; + unsigned char *device_buf; + char gFilePathBuf[CC_MAX_FILE_PATH]; +}; + +#endif // ANDROID_SSM_RAM_H diff --git a/tv/tvserver/libtv/tvsetting/CTvSetting.cpp b/tv/tvserver/libtv/tvsetting/CTvSetting.cpp new file mode 100644 index 0000000..daf8886 --- a/dev/null +++ b/tv/tvserver/libtv/tvsetting/CTvSetting.cpp @@ -0,0 +1,1943 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CTvSetting" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <cutils/properties.h> + +#include <netinet/ether.h> +#include <netinet/if_ether.h> + +#include <netutils/ifc.h> + +#include "CTvSetting.h" + +#include <tvconfig.h> +#include <tvutils.h> +#include <CTvLog.h> +#include "../vpp/CVpp.h" + +#define CC_DEF_CHARACTER_CHAR_VAL (0x8A) + +pthread_mutex_t ssm_r_w_op_mutex = PTHREAD_MUTEX_INITIALIZER; + +/************************ Start APIs For UI ************************/ +int TVSSMWriteNTypes(int id, int data_len, int data_buf, int offset) +{ + return tvSSMWriteNTypes(id, data_len, data_buf, offset); +} + +int TVSSMReadNTypes(int id, int data_len, int *data_buf, int offset) +{ + return tvSSMReadNTypes(id, data_len, data_buf, offset); +} + +/************************ Start APIs For UI ************************/ +int MiscSSMRestoreDefault() +{ + SSMSaveFactoryBurnMode(0); + SSMSavePowerOnOffChannel(1); + SSMSaveSystemLanguage(0); + SSMSaveAgingMode(0); + SSMSavePanelType(0); + SSMSavePowerOnMusicSwitch(0); + SSMSavePowerOnMusicVolume(20); + SSMSaveSystemSleepTimer(0xFFFFFFFF); + SSMSaveInputSourceParentalControl(0, 0); + SSMSaveParentalControlSwitch(0); + SSMSaveBlackoutEnable(0); + return 0; +} + +int MiscSSMFacRestoreDefault() +{ + SSMSaveSystemLanguage(0); + SSMSavePowerOnMusicSwitch(1); + SSMSavePowerOnMusicVolume(20); + SSMSaveSystemSleepTimer(0xFFFFFFFF); + SSMSaveInputSourceParentalControl(0, 0); + SSMSaveParentalControlSwitch(0); + SSMSaveSearchNavigateFlag(1); + SSMSaveInputNumLimit(2); + SSMSaveLocalDimingOnOffFlg(0); + + return 0; +} + +int ReservedSSMRestoreDefault() +{ + return SSMSaveBurnWriteCharaterChar(CC_DEF_CHARACTER_CHAR_VAL); +} + +int SSMSaveBurnWriteCharaterChar(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RSV_W_CHARACTER_CHAR_START, 1, rw_val); +} + +int SSMReadBurnWriteCharaterChar() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RSV_W_CHARACTER_CHAR_START, 1, &tmp_val) < 0) { + return -1; + } + + return tmp_val; +} + +int SSMSaveFactoryBurnMode(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_FBMF_START, 1, rw_val); +} + +int SSMReadFactoryBurnMode() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_FBMF_START, 1, &tmp_val) < 0) { + return 0; + } + + if (tmp_val != 0) { + return 1; + } + + return 0; +} + +int SSMSavePowerOnOffChannel(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_POWER_CHANNEL_START, 1, rw_val); +} + +int SSMReadPowerOnOffChannel() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_POWER_CHANNEL_START, 1, &tmp_val) < 0) { + return 0; + } + return tmp_val; +} + +int SSMSaveLastSelectSourceInput(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_LAST_SOURCE_INPUT_START, 1, rw_val); +} + +int SSMReadLastSelectSourceInput() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_LAST_SOURCE_INPUT_START, 1, &tmp_val) < 0) { + return 0; + } + return tmp_val; +} + +int SSMSaveSystemLanguage(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_SYS_LANGUAGE_START, 1, rw_val); +} + +int SSMReadSystemLanguage() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_SYS_LANGUAGE_START, 1, &tmp_val) < 0) { + return 0; + } + return tmp_val; +} + +int SSMSaveAgingMode(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_AGING_MODE_START, 4, rw_val); +} + +int SSMReadAgingMode() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_AGING_MODE_START, 4, &tmp_val) < 0) { + return 0; + } + return tmp_val; +} + +int SSMSavePanelType(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_PANEL_TYPE_START, 1, rw_val); +} + +int SSMReadPanelType() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_PANEL_TYPE_START, 1, &tmp_val) < 0) { + return 0; + } + return tmp_val; +} + +int SSMSavePowerOnMusicSwitch(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_POWER_ON_MUSIC_SWITCH_START, 1, rw_val); +} + +int SSMReadPowerOnMusicSwitch() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_POWER_ON_MUSIC_SWITCH_START, 1, &tmp_val) < 0) { + return 0; + } + return tmp_val; +} + +int SSMSavePowerOnMusicVolume(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_POWER_ON_MUSIC_VOL_START, 1, rw_val); +} + +int SSMReadPowerOnMusicVolume() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_POWER_ON_MUSIC_VOL_START, 1, &tmp_val) < 0) { + return 0; + } + return tmp_val; +} + +int SSMSaveSystemSleepTimer(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_SYS_SLEEP_TIMER_START, 1, rw_val); +} + +int SSMReadSystemSleepTimer() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_SYS_SLEEP_TIMER_START, 4, &tmp_val) < 0) { + return 0; + } + + if (tmp_val < 0) { + tmp_val = 0; + } + + return tmp_val; +} + +int SSMSaveInputSourceParentalControl(int source_index, unsigned char ctl_flag) +{ + int tmp_val = 0; + + if (source_index < 0 || source_index > 31) { + return -1; + } + + if (ctl_flag != 0 && ctl_flag != 1) { + return -1; + } + + if (TVSSMReadNTypes(SSM_RW_INPUT_SRC_PARENTAL_CTL_START, 4, &tmp_val) < 0) { + return -1; + } + + tmp_val = (tmp_val & (~(1 << source_index))) | (ctl_flag << source_index); + + return TVSSMWriteNTypes(SSM_RW_INPUT_SRC_PARENTAL_CTL_START, 4, tmp_val); +} + +int SSMReadInputSourceParentalControl(int source_index) +{ + int tmp_val = 0; + + if (SSMReadParentalControlSwitch() == 0) { + return 0; + } + + if (TVSSMReadNTypes(SSM_RW_INPUT_SRC_PARENTAL_CTL_START, 4, &tmp_val) < 0) { + return 0; + } + + if (tmp_val & (1 << source_index)) { + return 1; + } + + return 0; +} + +int SSMSaveParentalControlSwitch(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_PARENTAL_CTL_SWITCH_START, 1, rw_val); +} + +int SSMReadParentalControlSwitch() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_PARENTAL_CTL_SWITCH_START, 1, &tmp_val) < 0) { + return 0; + } + + if (tmp_val != 0) { + tmp_val = 1; + } + + return tmp_val; +} + +int SSMGetCustomerDataStart() +{ + return tvGetActualAddr(CUSTOMER_DATA_POS_HDMI1_EDID_START); +} + +int SSMGetCustomerDataLen() +{ + int LastAddr = tvGetActualAddr(CUSTOMER_DATA_POS_HDMI_HDCP_SWITCHER_START); + int LastSize = tvGetActualSize(CUSTOMER_DATA_POS_HDMI_HDCP_SWITCHER_START); + int len = LastAddr - SSMGetCustomerDataStart() + LastSize; + + return len; +} + +int SSMGetATVDataStart() +{ + return 0; +} + +int SSMGetATVDataLen() +{ + return 0; +} + +int SSMGetVPPDataStart() +{ + return tvGetActualAddr(VPP_DATA_POS_COLOR_DEMO_MODE_START); +} + +int SSMGetVPPDataLen() +{ + int LastAddr = tvGetActualAddr(SSM_RSV3); + int LastSize = tvGetActualSize(SSM_RSV3); + int len = LastAddr - SSMGetVPPDataStart() + LastSize; + + return len; +} + +int SSMSaveSearchNavigateFlag(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_SEARCH_NAVIGATE_FLAG_START, 1, rw_val); +} + +int SSMReadSearchNavigateFlag() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_SEARCH_NAVIGATE_FLAG_START, 1, &tmp_val) < 0) { + return 0; + } + + return tmp_val; +} + +int SSMSaveInputNumLimit(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_INPUT_NUMBER_LIMIT_START, 1, rw_val); +} + +int SSMReadInputNumLimit() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_INPUT_NUMBER_LIMIT_START, 1, &tmp_val) < 0) { + return 0; + } + + return tmp_val; +} + +int SSMSaveLocalDimingOnOffFlg(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_LOCAL_DIMING_START, 1, rw_val); +} + +int SSMReadLocalDimingOnOffFlg() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_LOCAL_DIMING_START, 1, &tmp_val) < 0) { + return 0; + } + + return tmp_val; +} + +int SSMSaveVDac2DValue(unsigned short rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_VDAC_2D_START, 1, rw_val); +} + +int SSMReadVDac2DValue() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_VDAC_2D_START, 1, &tmp_val) < 0) { + return 0; + } + + return tmp_val; +} + +int SSMSaveVDac3DValue(unsigned short rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_VDAC_3D_START, 1, rw_val); +} + +int SSMReadVDac3DValue() +{ + unsigned short tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_VDAC_3D_START, 1, (int *)&tmp_val) < 0) { + return 0; + } + + return tmp_val; +} + +int SSMSaveChromaStatus(int mode) +{ + int fd = -1, ret = -1; + char value[20] = ""; + + sprintf(value, "%d", mode); + + fd = open("/sys/class/tvafe/tvafe0/cvd_reg8a", O_RDWR); + + if (fd < 0) { + LOGE("open /sys/class/tvafe/tvafe0/cvd_reg8a ERROR(%s)!!\n", + strerror(errno)); + return -1; + } + + ret = write(fd, value, strlen(value)); + + close(fd); + + return ret; +} + +int SSMSaveNonStandardValue(unsigned short rw_val) +{ + LOGD("%s, save NonStandard_value = %d", CFG_SECTION_TV, rw_val); + + return TVSSMWriteNTypes(SSM_RW_NON_STANDARD_START, 2, rw_val); +} + +int SSMReadNonStandardValue(void) +{ + int i = 0, value = 0; + + if (TVSSMReadNTypes(SSM_RW_NON_STANDARD_START, 2, &value) < 0) { + LOGE("%s, read NonStandard_value error.", CFG_SECTION_TV); + return 0; + } + + LOGD("%s, read NonStandard_value = %d.", CFG_SECTION_TV, value); + + return value; +} + +int SSMSaveAdbSwitchValue(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_ADB_SWITCH_START, 1, rw_val); +} + +int SSMReadAdbSwitchValue(void) +{ + int switch_val = 0; + + if (TVSSMReadNTypes(SSM_RW_ADB_SWITCH_START, 1, &switch_val) < 0) { + LOGD("%s, read switch value error", CFG_SECTION_TV); + return -1; + } + + LOGD("%s, read switch value = %d", CFG_SECTION_TV, switch_val); + + return switch_val; +} + +int SSMSaveNoiseGateThresholdValue(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_NOISE_GATE_THRESHOLD_START, 1, rw_val); +} + +int SSMReadNoiseGateThresholdValue(void) +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_NOISE_GATE_THRESHOLD_START, 1, &tmp_val) < 0) { + LOGD("%s, read NoiseGateThreshold error", CFG_SECTION_TV); + return -1; + } + + LOGD("%s, read NoiseGateThreshold = %d", CFG_SECTION_TV, tmp_val); + + return tmp_val; +} + +int SSMSaveGraphyBacklight(int rw_val) +{ + if (rw_val < 0 || rw_val > 100) { + return -1; + } + + return TVSSMWriteNTypes(SSM_RW_UI_GRHPHY_BACKLIGHT_START, 1, rw_val); +} + +int SSMReadGraphyBacklight(void) +{ + int value = 0; + + if (TVSSMReadNTypes(SSM_RW_UI_GRHPHY_BACKLIGHT_START, 1, &value) < 0) { + LOGD("%s, read graphybacklight error.\n", CFG_SECTION_TV); + return -1; + } + + if (value > 100) { + LOGD("%s, range of graphybacklight (%d) is not between 0-100.\n", + CFG_SECTION_TV, value); + return -1; + } + + return value; +} + +int SSMSaveFastSuspendFlag(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_FASTSUSPEND_FLAG_START, 1, rw_val); +} + +int SSMReadFastSuspendFlag(void) +{ + int value = 0; + + if (TVSSMReadNTypes(SSM_RW_FASTSUSPEND_FLAG_START, 1, &value) < 0) { + LOGD("%s, read FastSuspendFlag error.\n", CFG_SECTION_TV); + return -1; + } + + return value; +} + +int SSMSaveCABufferSizeValue(unsigned short rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_CA_BUFFER_SIZE_START, 2, rw_val); +} + +int SSMReadCABufferSizeValue(void) +{ + int data = 0; + + if (TVSSMReadNTypes(SSM_RW_CA_BUFFER_SIZE_START, 2, &data) < 0) { + LOGE("%s, read ca_buffer_size error", CFG_SECTION_TV); + return 0; + } + + return data; +} + +int SSMSaveStandbyMode(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_STANDBY_MODE_FLAG_START, 1, rw_val); +} + +int SSMReadStandbyMode() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_STANDBY_MODE_FLAG_START, 1, &tmp_val) < 0) { + return 0; + } + + return tmp_val; +} + +int SSMSaveHDMIEQMode(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_HDMIEQ_MODE_START, 1, rw_val); +} + +int SSMReadHDMIEQMode() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_HDMIEQ_MODE_START, 1, &tmp_val) < 0) { + return 0; + } + + return tmp_val; +} + +int SSMSaveLogoOnOffFlag(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_LOGO_ON_OFF_FLAG_START, 1, rw_val); +} + +int SSMReadLogoOnOffFlag() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_LOGO_ON_OFF_FLAG_START, 1, &tmp_val) < 0) { + return 0; + } + + return tmp_val; +} + +int SSMSaveHDMIInternalMode(unsigned int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_HDMIINTERNAL_MODE_START, 4, rw_val); +} + +int SSMReadHDMIInternalMode() +{ + int value; + if (TVSSMReadNTypes(SSM_RW_HDMIINTERNAL_MODE_START, 4, &value) < 0) { + return 0; + } + + return value; +} + +int SSMSaveParentalControlPassWord(unsigned char *password, int size) +{ + return TVSSMWriteNTypes(SSM_RW_PARENTAL_CTL_PASSWORD_START, size, (int)*password); +} + +int SSMReadParentalControlPassWord(unsigned short *password) +{ + + if (TVSSMReadNTypes(SSM_RW_PARENTAL_CTL_PASSWORD_START, 16, (int *)password) < 0) { + return -1; + } + + return 0; +} + +int SSMSaveDisable3D(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_DISABLE_3D_START, 1, rw_val); +} + +int SSMReadDisable3D() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_DISABLE_3D_START, 1, &tmp_val) < 0) { + return 0; + } + return tmp_val; +} + +int SSMSaveGlobalOgoEnable(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_GLOBAL_OGO_ENABLE_START, 1, rw_val); +} + +int SSMReadGlobalOgoEnable() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(SSM_RW_GLOBAL_OGO_ENABLE_START, 1, &tmp_val) < 0) { + return 0; + } + return tmp_val; +} + +//Mark r/w values +static const int SSM_MARK_01_VALUE = 0xDD; +static const int SSM_MARK_02_VALUE = 0x88; +static const int SSM_MARK_03_VALUE = 0xCC; + +int SSMDeviceMarkCheck() +{ + int i = 0, failed_count = 0; + int mark_offset[3] = { 0, 0, 0 }; + unsigned char mark_values[3] = { 0, 0, 0 }; + int tmp_ch = 0; + + //read temp one byte + TVSSMReadNTypes(0, 1, &tmp_ch); + + mark_offset[0] = SSM_MARK_01_START; + mark_offset[1] = SSM_MARK_02_START; + mark_offset[2] = SSM_MARK_03_START; + + mark_values[0] = SSM_MARK_01_VALUE; + mark_values[1] = SSM_MARK_02_VALUE; + mark_values[2] = SSM_MARK_03_VALUE; + + if (SSMReadBurnWriteCharaterChar() != CC_DEF_CHARACTER_CHAR_VAL) { + SSMSaveBurnWriteCharaterChar(CC_DEF_CHARACTER_CHAR_VAL); + } + + failed_count = 0; + for (i = 0; i < 3; i++) { + tmp_ch = 0; + if (TVSSMReadNTypes(mark_offset[i], 1, &tmp_ch) < 0) { + LOGE("%s, SSMDeviceMarkCheck Read Mark failed!!!\n", CFG_SECTION_TV); + break; + } + + if ((unsigned char)tmp_ch != mark_values[i]) { + failed_count += 1; + LOGE( + "%s, SSMDeviceMarkCheck Mark[%d]'s offset = %d, Mark[%d]'s Value = %d, read value = %d.\n", + CFG_SECTION_TV, i, mark_offset[i], i, mark_values[i], tmp_ch); + } + } + + if (failed_count >= 3) { + return -1; + } + + return 0; +} + +int SSMRestoreDeviceMarkValues() +{ + int i; + int mark_offset[3] = { + (int) SSM_MARK_01_START, // + (int) SSM_MARK_02_START, // + (int) SSM_MARK_03_START, // + }; + + int mark_values[3] = {SSM_MARK_01_VALUE, SSM_MARK_02_VALUE, SSM_MARK_03_VALUE}; + + for (i = 0; i < 3; i++) { + if (TVSSMWriteNTypes(mark_offset[i], 1, mark_values[i]) < 0) { + LOGD("SSMRestoreDeviceMarkValues Write Mark failed.\n"); + break; + } + } + + if (i < 3) { + return -1; + } + + return 0; +} + +static int SSMGetPreCopyingEnableCfg() +{ + const char *prop_value; + + prop_value = config_get_str(CFG_SECTION_TV, "ssm.precopying.en", "null"); + if (strcmp(prop_value, "null") == 0 || strcmp(prop_value, "0") == 0 + || strcmp(prop_value, "disable") == 0) { + return 0; + } + + return 1; +} + +static int SSMGetPreCopyingDevicePathCfg(char dev_path[]) +{ + const char *prop_value; + + if (dev_path == NULL) { + return -1; + } + + prop_value = config_get_str(CFG_SECTION_TV, "ssm.precopying.devpath", "null"); + if (strcmp(prop_value, "null") == 0) { + return 1; + } + + strcpy(dev_path, prop_value); + + return 0; +} + +static unsigned char gTempDataBuf[4096] = { 0 }; +int SSMHandlePreCopying() +{ + int device_fd = -1; + int i = 0, tmp_size = 0; + int tmp_ch = 0; + char tmpPreCopyingDevicePath[256] = { '\0' }; + + if (SSMGetPreCopyingEnableCfg() == 0) { + LOGD("%s, Pre copying is disable now.\n", CFG_SECTION_TV); + return 0; + } + + //read temp one byte + TVSSMReadNTypes(0, 1, &tmp_ch); + + SSMGetPreCopyingDevicePathCfg(tmpPreCopyingDevicePath); + + device_fd = open(tmpPreCopyingDevicePath, O_RDONLY); + if (device_fd < 0) { + LOGE("%s, Open device file \"%s\" error: %s.\n", CFG_SECTION_TV, + tmpPreCopyingDevicePath, strerror(errno)); + return -1; + } + + tmp_size = lseek(device_fd, 0, SEEK_END); + if (tmp_size == 4096) { + lseek(device_fd, 0, SEEK_SET); + read(device_fd, gTempDataBuf, tmp_size); + for (i=0;i<tmp_size;i++) { + TVSSMWriteNTypes(0, 1, gTempDataBuf[i]); + } + } + + close(device_fd); + + remove(tmpPreCopyingDevicePath); + + return 0; +} + +int SSMSaveDTVType(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_DTV_TYPE_START, 1, rw_val); +} + +int SSMReadDTVType(int *rw_val) +{ + int tmp_ret = 0; + + tmp_ret = TVSSMReadNTypes(SSM_RW_DTV_TYPE_START, 1, rw_val); + + return tmp_ret; +} + +#ifndef NELEM +# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) +#endif + +/************************ End APIs For UI ************************/ + +// other api +int GetSSMCfgBufferData(const char *key_str, int *buf_item_count, int radix, + unsigned char data_buf[]) +{ + int cfg_item_count = 0; + char *token = NULL; + const char *strDelimit = ","; + const char *config_value; + char data_str[CC_CFG_VALUE_STR_MAX_LEN] = { 0 }; + + config_value = config_get_str(CFG_SECTION_TV, key_str, "null"); + if (strcasecmp(config_value, "null") == 0) { + LOGE("%s, can't get config \"%s\"!!!\n", CFG_SECTION_TV, key_str); + return -1; + } + + cfg_item_count = 0; + + memset((void *)data_str, 0, sizeof(data_str)); + strncpy(data_str, config_value, sizeof(data_str) - 1); + + char *pSave; + token = strtok_r(data_str, strDelimit, &pSave); + while (token != NULL) { + if (cfg_item_count < *buf_item_count) { + data_buf[cfg_item_count] = strtol(token, NULL, radix); + + token = strtok_r(NULL, strDelimit, &pSave); + cfg_item_count += 1; + } else { + LOGE("%s, we get data count more than desire count (%d)!!!\n", + CFG_SECTION_TV, *buf_item_count); + return -1; + } + } + + *buf_item_count = cfg_item_count; + + return 0; +} + +int SSMSaveSourceInput(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(TVIN_DATA_POS_SOURCE_INPUT_START, 1, tmp_val); +} + +int SSMReadSourceInput() +{ + int tmp_val = 0; + + if (TVSSMReadNTypes(TVIN_DATA_POS_SOURCE_INPUT_START, 1, &tmp_val) < 0) { + return 0; + } + return tmp_val; +} + +int SSMSaveCVBSStd(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(TVIN_DATA_CVBS_STD_START, 1, tmp_val); +} + +int SSMReadCVBSStd(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(TVIN_DATA_CVBS_STD_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSave3DMode(unsigned char rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(TVIN_DATA_POS_3D_MODE_START, 1, tmp_val); +} + +int SSMRead3DMode(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(TVIN_DATA_POS_3D_MODE_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSave3DLRSwitch(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(TVIN_DATA_POS_3D_LRSWITCH_START, 1, tmp_val); +} + +int SSMRead3DLRSwitch(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(TVIN_DATA_POS_3D_LRSWITCH_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSave3DDepth(unsigned char rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(TVIN_DATA_POS_3D_DEPTH_START, 1, tmp_val); +} + +int SSMRead3DDepth(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(TVIN_DATA_POS_3D_DEPTH_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSave3DTO2D(unsigned char rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(TVIN_DATA_POS_3D_TO2D_START, 1, tmp_val); +} + +int SSMRead3DTO2D(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(TVIN_DATA_POS_3D_TO2D_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveDisplayMode(int offset, int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_DISPLAY_MODE_START, 1, rw_val, offset); +} + +int SSMSaveSceneMode(int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_SCENE_MODE_START, 1, rw_val); +} + +int SSMReadSceneMode(int *rw_val) +{ + int tmp_ret = 0; + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_SCENE_MODE_START, 1, rw_val); + + return tmp_ret; +} + +int SSMSaveBackLightVal(int offset, int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_BACKLIGHT_START, 1, rw_val, offset); +} + +int SSMReadBackLightVal(int offset, int *rw_val) +{ + int tmp_ret = 0; + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_BACKLIGHT_START, 1, rw_val, offset); + //TODO + if (tmp_ret < 0 || tmp_ret > 100) { + int i = 0; + for (i = 0; i < SOURCE_MAX; i++) { + SSMSaveBackLightVal(i, DEFAULT_BACKLIGHT_BRIGHTNESS); + } + tmp_ret = DEFAULT_BACKLIGHT_BRIGHTNESS; + } + + return tmp_ret; +} + +int SSMSaveFBCN360BackLightVal(int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_FBC_BACKLIGHT_START , 1, rw_val); +} + +int SSMReadFBCN360BackLightVal(int *rw_val) +{ + int tmp_ret = 0; + + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_FBC_BACKLIGHT_START, 1, rw_val); + + return tmp_ret; +} + +int SSMSaveFBCN360ColorTempVal(int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_FBC_COLORTEMP_START , 1, rw_val); +} + +int SSMReadFBCN360ColorTempVal(int *rw_val) +{ + int tmp_ret = 0; + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_FBC_COLORTEMP_START, 1, rw_val); + + return tmp_ret; +} + + +int SSMSaveFBCELECmodeVal(int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_FBC_ELECMODE_START , 1, rw_val); +} + +int SSMReadFBCELECmodeVal(int *rw_val) +{ + int tmp_ret = 0; + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_FBC_ELECMODE_START, 1, rw_val); + + return tmp_ret; +} + +int SSMSaveDBCStart(unsigned char rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(VPP_DATA_POS_DBC_START, 1, tmp_val); +} + +int SSMReadDBCStart(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_POS_DBC_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveDnlpStart(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_POS_DNLP_START, 1, tmp_val); +} + +int SSMReadDnlpStart(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_POS_DNLP_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSavePanoramaStart(int offset, unsigned char rw_val) +{ + int tmp_val = tmp_val; + return TVSSMWriteNTypes(VPP_DATA_POS_PANORAMA_START, 1, tmp_val, offset); +} + +int SSMReadPanoramaStart(int offset, unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_POS_PANORAMA_START, 1, &tmp_val, offset); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveTestPattern(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_POS_TEST_PATTERN_START, 1, tmp_val); +} + +int SSMReadTestPattern(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + ret = TVSSMReadNTypes(VPP_DATA_POS_TEST_PATTERN_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAPL(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_APL_START, 1, tmp_val); +} + +int SSMReadAPL(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_APL_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAPL2(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_APL2_START, 1, tmp_val); +} + +int SSMReadAPL2(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_APL2_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveBD(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_BD_START, 1, tmp_val); +} + +int SSMReadBD(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_BD_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveBP(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_BP_START, 1, tmp_val); +} + +int SSMReadBP(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_BP_START, 1, &tmp_val);\ + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveDDRSSC(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_POS_DDR_SSC_START, 1, tmp_val); +} + +int SSMReadDDRSSC(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_POS_DDR_SSC_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveLVDSSSC(unsigned char *rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_LVDS_SSC_START, 1, *rw_val); +} + +int SSMReadLVDSSSC(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_POS_LVDS_SSC_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveDreamPanel(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_POS_DREAM_PANEL_START, 1, tmp_val); +} + +int SSMReadDreamPanel(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_POS_DREAM_PANEL_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveUserNatureLightSwitch(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_USER_NATURE_SWITCH_START, 1, tmp_val); +} + +int SSMReadUserNatureLightSwitch(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_USER_NATURE_SWITCH_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveDBCBacklightEnable(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_DBC_BACKLIGHT_START, 1, tmp_val); +} + +int SSMReadDBCBacklightEnable(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_DBC_BACKLIGHT_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveDBCBacklightStd(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_DBC_STANDARD_START, 1, tmp_val); +} + +int SSMReadDBCBacklightStd(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_DBC_STANDARD_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveDBCEnable(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_DBC_ENABLE_START, 1, tmp_val); +} + +int SSMReadDBCEnable(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_DBC_ENABLE_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveBackLightReverse(unsigned char rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(VPP_DATA_POS_BACKLIGHT_REVERSE_START, 1, tmp_val); +} + +int SSMReadBackLightReverse(unsigned char *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(VPP_DATA_POS_BACKLIGHT_REVERSE_START, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioMasterVolume(int8_t rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(SSM_AUD_MASTR_VOLUME_VAL, 1, tmp_val); +} + +int SSMReadAudioMasterVolume(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + ret = TVSSMReadNTypes(SSM_AUD_MASTR_VOLUME_VAL, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioBalanceVal(int8_t rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(SSM_AUD_BALANCE_VAL, 1, tmp_val); +} + +int SSMReadAudioBalanceVal(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_BALANCE_VAL, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioSupperBassVolume(int8_t rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(SSM_AUD_SUPPERBASS_VOLUME_VAL, 1, tmp_val); +} + +int SSMReadAudioSupperBassVolume(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_SUPPERBASS_VOLUME_VAL, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioSupperBassSwitch(int8_t rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(SSM_AUD_SUPPERBASS_SWITCH, 1, tmp_val); +} + +int SSMReadAudioSupperBassSwitch(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_SUPPERBASS_SWITCH, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioSRSSurroundSwitch(int8_t rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(SSM_AUD_SRS_SURROUND_SWITCH, 1, tmp_val); +} + +int SSMReadAudioSRSSurroundSwitch(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_SRS_SURROUND_SWITCH, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioSRSDialogClaritySwitch(int8_t rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(SSM_AUD_SRS_DIALOG_CLARITY_SWITCH, 1, tmp_val); +} + +int SSMSaveAudioDbxTvValue(int son_value, int vol_value, int sur_value) +{ + TVSSMWriteNTypes(SSM_AUD_DBX_TV_SON, 1, son_value); + TVSSMWriteNTypes(SSM_AUD_DBX_TV_VAL, 1, vol_value); + TVSSMWriteNTypes(SSM_AUD_DBX_TV_SUR, 1, sur_value); + return 0; +} + +int SSMReadAudioDbxTvValue(int *son_value, int *vol_value, int *sur_value) +{ + int rw_val; + TVSSMReadNTypes(SSM_AUD_DBX_TV_SON, 1, &rw_val); + *son_value = rw_val; + TVSSMReadNTypes(SSM_AUD_DBX_TV_VAL, 1, &rw_val); + *vol_value = rw_val; + TVSSMReadNTypes(SSM_AUD_DBX_TV_SUR, 1, &rw_val); + *sur_value = rw_val; + return 0; +} + +int SSMReadAudioSRSDialogClaritySwitch(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_SRS_DIALOG_CLARITY_SWITCH, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioSRSTruBassSwitch(int8_t rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(SSM_AUD_SRS_TRUEBASS_SWITCH, 1, tmp_val); +} + +int SSMReadAudioSRSTruBassSwitch(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_SRS_TRUEBASS_SWITCH, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioBassVolume(int8_t rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(SSM_AUD_BASS_VOLUME_VAL, 1, tmp_val); +} + +int SSMReadAudioBassVolume(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_BASS_VOLUME_VAL, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioTrebleVolume(int8_t rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(SSM_AUD_TREBLE_VOLUME_VAL, 1, tmp_val); +} + +int SSMReadAudioTrebleVolume(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_TREBLE_VOLUME_VAL, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioSoundModeVal(int8_t rw_val) +{ + int tmp_val = rw_val; + return TVSSMWriteNTypes(SSM_AUD_SOUND_MODE_VAL, 1, tmp_val); +} + +int SSMReadAudioSoundModeVal(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_SOUND_MODE_VAL, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioWallEffectSwitch(int8_t rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(SSM_AUD_WALL_EFFCT_SWITCH, 1, tmp_val); +} + +int SSMReadAudioWallEffectSwitch(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_WALL_EFFCT_SWITCH, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioSPDIFSwitchVal(int8_t rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(SSM_AUD_SPDIF_SWITCH, 1, tmp_val); +} + +int SSMReadAudioSPDIFSwitchVal(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_SPDIF_SWITCH, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioSPDIFModeVal(int8_t rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(SSM_AUD_SPDIF_MODE_VAL, 1, tmp_val); +} + +int SSMReadAudioSPDIFModeVal(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_SPDIF_MODE_VAL, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioEQModeVal(int8_t rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(SSM_AUD_EQ_MODE_VAL, 1, tmp_val); +} + +int SSMReadAudioEQModeVal(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_EQ_MODE_VAL, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioEQGain(int offset, int size, int8_t tmp_buf[]) +{ + int i = 0; + for (i=0;i<size;i++) { + TVSSMWriteNTypes(SSM_AUD_EQ_GAIN, 1, tmp_buf[i], offset); + } + + return 0; +} + +int SSMReadAudioEQGain(int offset __unused, int size, int8_t tmp_buf[]) +{ + int data_buf[size]; + int i = 0; + int ret = 0; + memset(data_buf, 0x0, sizeof(data_buf)); + + for (i=0;i<size;i++) { + ret = TVSSMReadNTypes(SSM_AUD_EQ_GAIN, 1, data_buf+i); + tmp_buf[i] = data_buf[i]; + } + + return ret; +} + +int SSMSaveAudioAVOutMuteVal(int8_t rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(SSM_AUD_AVOUT_MUTE, 1, tmp_val); +} + +int SSMReadAudioAVOutMuteVal(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_AVOUT_MUTE, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveAudioSPIDFMuteVal(int8_t rw_val) +{ + int tmp_val = rw_val; + + return TVSSMWriteNTypes(SSM_AUD_SPIDF_MUTE, 1, tmp_val); +} + +int SSMReadAudioSPIDFMuteVal(int8_t *rw_val) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_AUD_SPIDF_MUTE, 1, &tmp_val); + *rw_val = tmp_val; + + return ret; +} + +int SSMSaveBlackoutEnable(int8_t enable) +{ + int tmp_val = enable; + + return TVSSMWriteNTypes(SSM_RW_BLACKOUT_ENABLE_START, 1, tmp_val); +} + +int SSMReadBlackoutEnable(int8_t *enable) +{ + int tmp_val = 0; + int ret = 0; + + ret = TVSSMReadNTypes(SSM_RW_BLACKOUT_ENABLE_START, 1, &tmp_val); + *enable = tmp_val; + + return ret; +} + +int SSMSaveFBCN310BackLightVal(int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_FBC_N310_BACKLIGHT_START , 1, rw_val); +} + +int SSMReadFBCN310BackLightVal(int *rw_val) +{ + int tmp_ret = 0; + + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_FBC_N310_BACKLIGHT_START, 1, rw_val); + + return tmp_ret; +} + +int SSMSaveFBCN310ColorTempVal(int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_FBC_N310_COLORTEMP_START , 1, rw_val); +} + +int SSMReadFBCN310ColorTempVal(int *rw_val) +{ + int tmp_ret = 0; + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_FBC_N310_COLORTEMP_START, 1, rw_val); + + + return tmp_ret; +} + +int SSMSaveFBCN310LightsensorVal(int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_FBC_N310_LIGHTSENSOR_START , 1, rw_val); +} + +int SSMReadFBCN310LightsensorVal(int *rw_val) +{ + int tmp_ret = 0; + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_FBC_N310_LIGHTSENSOR_START, 1, rw_val); + + return tmp_ret; +} + +int SSMSaveFBCN310Dream_PanelVal(int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_FBC_N310_DREAMPANEL_START , 1, rw_val); +} + +int SSMReadFBCN310Dream_PanelVal(int *rw_val) +{ + int tmp_ret = 0; + + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_FBC_N310_DREAMPANEL_START, 1, rw_val); + return tmp_ret; +} + +int SSMSaveFBCN310MULT_PQVal(int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_FBC_N310_MULTI_PQ_START , 1, rw_val); +} + +int SSMReadFBCN310MULT_PQVal(int *rw_val) +{ + int tmp_ret = 0; + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_FBC_N310_MULTI_PQ_START, 1, rw_val); + + return tmp_ret; +} + +int SSMSaveFBCN310MEMCVal(int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_FBC_N310_MEMC_START , 1, rw_val); +} + +int SSMReadFBCN310MEMCVal(int *rw_val) +{ + int tmp_ret = 0; + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_FBC_N310_MEMC_START, 1, rw_val); + + return tmp_ret; +} + +int SSMSaveN311_VbyOne_Spread_Spectrum_Val(int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_N311_VBYONE_SPREAD_SPECTRUM_START , 1, rw_val); +} + +int SSMReadN311_VbyOne_Spread_Spectrum_Val(int *rw_val) +{ + int tmp_ret = 0; + + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_N311_VBYONE_SPREAD_SPECTRUM_START, 1, rw_val); + return tmp_ret; +} +int SSMSaveN311_Bluetooth_Vol(int rw_val) +{ + return TVSSMWriteNTypes(VPP_DATA_POS_N311_BLUETOOTH_VAL_START , 1, rw_val); +} + +int SSMReadN311_Bluetooth_Vol(void) +{ + int tmp_ret = 0; + int tmp_val = 0; + + tmp_ret = TVSSMReadNTypes(VPP_DATA_POS_N311_BLUETOOTH_VAL_START, 1, &tmp_val); + + if (tmp_ret < 0) { + return 0; + } + + return tmp_val; +} +int SSMSave_DRC_ONOFF_Val(int rw_val) +{ + return TVSSMWriteNTypes(SSM_AUD_DRC_ONOFF , 1, rw_val); + +} +int SSMRead_DRC_ONOFF_Val(void) +{ + int tmp_val = 0; + int tmp_ret = 0; + + tmp_ret = TVSSMReadNTypes(SSM_AUD_DRC_ONOFF, 1, &tmp_val); + + if (tmp_ret < 0) { + return 0; + } + + return tmp_val; + +} + +int SSMSave_PANEL_ID_Val(int rw_val) +{ + return TVSSMWriteNTypes(SSM_RW_PANEL_ID_START , 1, rw_val); +} +int SSMRead_PANEL_ID_Val(void) +{ + int tmp_val = 0; + int tmp_ret = 0; + tmp_ret = TVSSMReadNTypes(SSM_RW_PANEL_ID_START, 1, &tmp_val); + if (tmp_ret < 0) { + return 0; + } + return tmp_val; +} + +int SSMSaveHDMIEdidMode(tv_hdmi_port_id_t port, tv_hdmi_edid_version_t rw_val) +{ + int ret = -1; + int tmp_val = rw_val; + switch (port) { + case HDMI_PORT_1 : + ret = TVSSMWriteNTypes(CUSTOMER_DATA_POS_HDMI1_EDID_START, 1, tmp_val); + break; + case HDMI_PORT_2 : + ret = TVSSMWriteNTypes(CUSTOMER_DATA_POS_HDMI2_EDID_START, 1, tmp_val); + break; + case HDMI_PORT_3 : + ret = TVSSMWriteNTypes(CUSTOMER_DATA_POS_HDMI3_EDID_START, 1, tmp_val); + break; + case HDMI_PORT_4 : + ret = TVSSMWriteNTypes(CUSTOMER_DATA_POS_HDMI4_EDID_START, 1, tmp_val); + default: + break; + } + return ret; +} + +tv_hdmi_edid_version_t SSMReadHDMIEdidVersion(tv_hdmi_port_id_t port) +{ + int tmp_val = 0; + int tmp_ret = 0; + switch (port) { + case HDMI_PORT_1: + tmp_ret = TVSSMReadNTypes(CUSTOMER_DATA_POS_HDMI1_EDID_START, 1, &tmp_val); + if (tmp_ret < 0) { + tmp_val = 0; + } + if (1 < tmp_val ) { + tmp_val = 0; + } + break; + case HDMI_PORT_2 : + tmp_ret = TVSSMReadNTypes(CUSTOMER_DATA_POS_HDMI2_EDID_START, 1, &tmp_val); + if (tmp_ret < 0) { + tmp_val = 0; + } + if (1 < tmp_val ) { + tmp_val = 0; + } + break; + case HDMI_PORT_3 : + tmp_ret = TVSSMReadNTypes(CUSTOMER_DATA_POS_HDMI3_EDID_START, 1, &tmp_val); + if (tmp_ret < 0) { + tmp_val = 0; + } + if (1 < tmp_val ) { + tmp_val = 0; + } + break; + case HDMI_PORT_4: + tmp_ret = TVSSMReadNTypes(CUSTOMER_DATA_POS_HDMI4_EDID_START, 1, &tmp_val); + if (tmp_ret < 0) { + tmp_val = 0; + } + if (1 < tmp_val ) { + tmp_val = 0; + } + break; + default: + tmp_val = 0; + break; + } + return (tv_hdmi_edid_version_t)tmp_val; +} + + +int SSMSaveHDMIHdcpSwitcher(int rw_val) +{ + return TVSSMWriteNTypes(CUSTOMER_DATA_POS_HDMI_HDCP_SWITCHER_START, 1, rw_val); +} + +int SSMReadHDMIHdcpSwitcher(void) +{ + int tmp_val = 0; + int tmp_ret = 0; + tmp_ret = TVSSMReadNTypes(CUSTOMER_DATA_POS_HDMI_HDCP_SWITCHER_START, 1, &tmp_val); + if (tmp_ret < 0) { + tmp_val = 0; + } + if (1 < tmp_val ) { + tmp_val = 0; + } + return tmp_val; +} + +int SSMHDMIEdidRestoreDefault(void) +{ + if (config_get_str(CFG_SECTION_TV, CS_HDMI_EDID_USE_CFG, NULL) != NULL) + config_set_str(CFG_SECTION_TV, CS_HDMI_EDID_USE_CFG, ""); + if (config_get_str(CFG_SECTION_TV, CS_HDMI_PORT1_EDID_FILE_PATH_CFG, NULL) != NULL) + config_set_str(CFG_SECTION_TV, CS_HDMI_PORT1_EDID_FILE_PATH_CFG, ""); + if (config_get_str(CFG_SECTION_TV, CS_HDMI_PORT2_EDID_FILE_PATH_CFG, NULL) != NULL) + config_set_str(CFG_SECTION_TV, CS_HDMI_PORT2_EDID_FILE_PATH_CFG, ""); + if (config_get_str(CFG_SECTION_TV, CS_HDMI_PORT3_EDID_FILE_PATH_CFG, NULL) != NULL) + config_set_str(CFG_SECTION_TV, CS_HDMI_PORT3_EDID_FILE_PATH_CFG, ""); + if (config_get_str(CFG_SECTION_TV, CS_HDMI_PORT4_EDID_FILE_PATH_CFG, NULL) != NULL) + config_set_str(CFG_SECTION_TV, CS_HDMI_PORT4_EDID_FILE_PATH_CFG, ""); + + int tmp_val = HDMI_EDID_VER_14; + return TVSSMWriteNTypes(CUSTOMER_DATA_POS_HDMI1_EDID_START, SSMGetCustomerDataLen(), tmp_val); +} + +int SSMSaveAmAudioVal(int rw_val, int source) +{ + return TVSSMWriteNTypes(SSM_AM_AUDIO_VOLUME, 1, rw_val, source); +} + +int SSMReadAmAudioVal(int *rw_val, int source) +{ + return TVSSMReadNTypes(SSM_AM_AUDIO_VOLUME, 1, rw_val, source); +} diff --git a/tv/tvserver/libtv/tvsetting/CTvSetting.h b/tv/tvserver/libtv/tvsetting/CTvSetting.h new file mode 100644 index 0000000..021e685 --- a/dev/null +++ b/tv/tvserver/libtv/tvsetting/CTvSetting.h @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __TV_SETTING_H__ +#define __TV_SETTING_H__ + +#include <pthread.h> +#include <stdint.h> +#include "../tvin/CTvin.h" +#include "TvKeyData.h" +#include <CTvLog.h> +#include "PQSettingCfg.h" + +using namespace android; + +#ifdef __cplusplus +extern "C" { +#endif + +int MiscSSMRestoreDefault(); +int MiscSSMFacRestoreDefault(); +int ReservedSSMRestoreDefault(); +int TVSSMWriteNTypes(int id, int data_len, int data_buf, int offset = 0); +int TVSSMReadNTypes(int id, int data_len, int *data_buf, int offset = 0); + +int SSMSaveEEP_One_N310_N311(int offset, int rw_val) ; +int SSMReadEEP_One_N310_N311(int offset); +int SSMSaveEEP_N_N310_N311(int offset, int data_len, int *data_buf); +int SSMReadEEP_N_N310_N311(int offset, int data_len, int *data_buf); +int SSMSaveFlash_N_N310_N311(int offset, int data_len, int *data_buf); +int SSMReadFlash_N_N310_N311(int offset, int data_len, int *data_buf); + +int SSMSaveBurnWriteCharaterChar(int rw_val); +int SSMReadBurnWriteCharaterChar(); +int SSMSaveFactoryBurnMode(int rw_val); +int SSMReadFactoryBurnMode(); +int SSMSavePowerOnOffChannel(int rw_val); +int SSMReadPowerOnOffChannel(); +int SSMSaveLastSelectSourceInput(int rw_val); +int SSMReadLastSelectSourceInput(); +int SSMSaveSystemLanguage(int rw_val); +int SSMReadSystemLanguage(); +int SSMSaveAgingMode(int rw_val); +int SSMReadAgingMode(); +int SSMSavePanelType(int rw_val); +int SSMReadPanelType(); +int SSMSavePowerOnMusicSwitch(int rw_val); +int SSMReadPowerOnMusicSwitch(); +int SSMSavePowerOnMusicVolume(int rw_val); +int SSMReadPowerOnMusicVolume(); +int SSMSaveSystemSleepTimer(int rw_val); +int SSMReadSystemSleepTimer(); +int SSMSaveInputSourceParentalControl(int source_index, unsigned char ctl_flag); +int SSMReadInputSourceParentalControl(int source_index); +int SSMSaveParentalControlSwitch(int rw_val); +int SSMReadParentalControlSwitch(); +int SSMGetCustomerDataStart(); +int SSMGetCustomerDataLen(); +int SSMGetATVDataStart(); +int SSMGetATVDataLen(); +int SSMGetVPPDataStart(); +int SSMGetVPPDataLen(); +int SSMSaveSearchNavigateFlag(int rw_val); +int SSMReadSearchNavigateFlag(); +int SSMSaveInputNumLimit(int rw_val); +int SSMReadInputNumLimit(); +int SSMSaveLocalDimingOnOffFlg(int rw_val); +int SSMReadLocalDimingOnOffFlg(); +int SSMSaveVDac2DValue(unsigned short rw_val); +int SSMReadVDac2DValue(); +int SSMSaveVDac3DValue(unsigned short rw_val); +int SSMReadVDac3DValue(); +int SSMSaveChromaStatus(int mode); +int SSMSaveNonStandardValue(unsigned short rw_val); +int SSMReadNonStandardValue(void); +int SSMSaveAdbSwitchValue(int rw_val); +int SSMReadAdbSwitchValue(void); +int SSMSaveNoiseGateThresholdValue(int rw_val); +int SSMReadNoiseGateThresholdValue(void); +int SSMSaveGraphyBacklight(int rw_val); +int SSMReadGraphyBacklight(void); +int SSMSaveFastSuspendFlag(int rw_val); +int SSMReadFastSuspendFlag(void); +int SSMSaveCABufferSizeValue(unsigned short rw_val); +int SSMReadCABufferSizeValue(void); +int SSMSaveStandbyMode(int rw_val); +int SSMReadStandbyMode(); +int SSMSaveHDMIEQMode(int rw_val); +int SSMReadHDMIEQMode(); +int SSMSaveLogoOnOffFlag(int rw_val); +int SSMReadLogoOnOffFlag(); +int SSMSaveHDMIInternalMode(unsigned int rw_val); +int SSMReadHDMIInternalMode(); +int SSMSaveParentalControlPassWord(unsigned char *password, int size); +int SSMReadParentalControlPassWord(unsigned short *password); +int SSMSaveDisable3D(int rw_val); +int SSMReadDisable3D(); +int SSMSaveGlobalOgoEnable(int rw_val); +int SSMReadGlobalOgoEnable(); +int SSMDeviceMarkCheck(); +int SSMRestoreDeviceMarkValues(); +int SSMHandlePreCopying(); +int SSMSaveDTVType(int rw_val); +int SSMReadDTVType(int *rw_val); +int GetSSMCfgBufferData(const char *key_str, int *buf_item_count, int radix, unsigned char data_buf[]); +int SSMSaveSourceInput(unsigned char rw_val); +int SSMReadSourceInput(); +int SSMSaveCVBSStd(unsigned char rw_val); +int SSMReadCVBSStd(unsigned char *rw_val); +int SSMSave3DMode(unsigned char rw_val); +int SSMRead3DMode(unsigned char *rw_val); +int SSMSave3DLRSwitch(unsigned char rw_val); +int SSMRead3DLRSwitch(unsigned char *rw_val); +int SSMSave3DDepth(unsigned char rw_val); +int SSMRead3DDepth(unsigned char *rw_val); +int SSMSave3DTO2D(unsigned char rw_val); +int SSMRead3DTO2D(unsigned char *rw_val); +int SSMSaveSceneMode(int rw_val); +int SSMReadSceneMode(int *rw_val); +int SSMSaveDisplayMode(int offset, int rw_val); +int SSMReadDisplayMode(int offset, int *rw_val); +int SSMSaveBackLightVal(int offset, int rw_val); +int SSMReadBackLightVal(int offset, int *rw_val); +int SSMReadFBCN360BackLightVal(int *rw_val); +int SSMSaveFBCN360BackLightVal(int rw_val); +int SSMSaveFBCELECmodeVal(int rw_val); +int SSMReadFBCELECmodeVal(int *rw_val); +int SSMSaveFBCN360ColorTempVal(int rw_val); +int SSMReadFBCN360ColorTempVal(int *rw_val); +int SSMSaveDBCStart(unsigned char rw_val); +int SSMReadDBCStart(unsigned char *rw_val); +int SSMSaveDnlpStart(unsigned char rw_val); +int SSMReadDnlpStart(unsigned char *rw_val); +int SSMSavePanoramaStart(int offset, unsigned char rw_val); +int SSMReadPanoramaStart(int offset, unsigned char *rw_val); +int SSMSaveTestPattern(unsigned char rw_val); +int SSMReadTestPattern(unsigned char *rw_val); +int SSMSaveAPL(unsigned char rw_val); +int SSMReadAPL(unsigned char *rw_val); +int SSMSaveAPL2(unsigned char rw_val); +int SSMReadAPL2(unsigned char *rw_val); +int SSMSaveBD(unsigned char rw_val); +int SSMReadBD(unsigned char *rw_val); +int SSMSaveBP(unsigned char rw_val); +int SSMReadBP(unsigned char *rw_val); +int SSMSaveDDRSSC(unsigned char rw_val); +int SSMReadDDRSSC(unsigned char *rw_val); +int SSMSaveLVDSSSC(unsigned char *rw_val); +int SSMReadLVDSSSC(unsigned char *rw_val); +int SSMSaveDreamPanel(unsigned char rw_val); +int SSMReadDreamPanel(unsigned char *rw_val); +int SSMSaveUserNatureLightSwitch(unsigned char rw_val); +int SSMReadUserNatureLightSwitch(unsigned char *rw_val); +int SSMSaveDBCBacklightEnable(unsigned char rw_val); +int SSMReadDBCBacklightEnable(unsigned char *rw_val); +int SSMSaveDBCBacklightStd(unsigned char rw_val); +int SSMReadDBCBacklightStd(unsigned char *rw_val); +int SSMSaveDBCEnable(unsigned char rw_val); +int SSMReadDBCEnable(unsigned char *rw_val); +int SSMSaveBackLightReverse(unsigned char rw_val); +int SSMReadBackLightReverse(unsigned char *rw_val); +//audio +int SSMSaveAudioMasterVolume(int8_t rw_val); +int SSMReadAudioMasterVolume(int8_t *rw_val); +int SSMSaveAudioBalanceVal(int8_t rw_val); +int SSMReadAudioBalanceVal(int8_t *rw_val); +int SSMSaveAudioSupperBassVolume(int8_t rw_val); +int SSMReadAudioSupperBassVolume(int8_t *rw_val); +int SSMSaveAudioSupperBassSwitch(int8_t rw_val); +int SSMReadAudioSupperBassSwitch(int8_t *rw_val); +int SSMSaveAudioSRSSurroundSwitch(int8_t rw_val); +int SSMReadAudioSRSSurroundSwitch(int8_t *rw_val); +int SSMSaveAudioSRSDialogClaritySwitch(int8_t rw_val); +int SSMReadAudioSRSDialogClaritySwitch(int8_t *rw_val); +int SSMSaveAudioSRSTruBassSwitch(int8_t rw_val); +int SSMReadAudioSRSTruBassSwitch(int8_t *rw_val); +int SSMSaveAudioBassVolume(int8_t rw_val); +int SSMReadAudioBassVolume(int8_t *rw_val); +int SSMSaveAudioTrebleVolume(int8_t rw_val); +int SSMReadAudioTrebleVolume(int8_t *rw_val); +int SSMSaveAudioSoundModeVal(int8_t rw_val); +int SSMReadAudioSoundModeVal(int8_t *rw_val); +int SSMSaveAudioWallEffectSwitch(int8_t rw_val); +int SSMReadAudioWallEffectSwitch(int8_t *rw_val); +int SSMSaveAudioSPDIFSwitchVal(int8_t rw_val); +int SSMReadAudioSPDIFSwitchVal(int8_t *rw_val); +int SSMSaveAudioSPDIFModeVal(int8_t rw_val); +int SSMReadAudioSPDIFModeVal(int8_t *rw_val); +int SSMSaveAudioEQModeVal(int8_t rw_val); +int SSMReadAudioEQModeVal(int8_t *rw_val); +int SSMSaveAudioEQGain(int offset, int size, int8_t tmp_buf[]); +int SSMReadAudioEQGain(int offset, int size, int8_t tmp_buf[]); +int SSMSaveAudioDbxTvValue(int son_value, int vol_value, int sur_value); +int SSMReadAudioDbxTvValue(int *son_value, int *vol_value, int *sur_value); +int SSMSaveAudioAVOutMuteVal(int8_t rw_val); +int SSMReadAudioAVOutMuteVal(int8_t *rw_val); +int SSMSaveAudioSPIDFMuteVal(int8_t rw_val); +int SSMReadAudioSPIDFMuteVal(int8_t *rw_val); +//hdmi +int SSMSaveBlackoutEnable(int8_t enable); +int SSMReadBlackoutEnable(int8_t *enable); +int SSMSaveFBCN310BackLightVal(int rw_val); +int SSMReadFBCN310BackLightVal(int *rw_val); +int SSMSaveFBCN310ColorTempVal(int rw_val); +int SSMReadFBCN310ColorTempVal(int *rw_val); +int SSMSaveFBCN310LightsensorVal(int rw_val); +int SSMReadFBCN310LightsensorVal(int *rw_val); +int SSMSaveFBCN310Dream_PanelVal(int rw_val); +int SSMReadFBCN310Dream_PanelVal(int *rw_val); +int SSMSaveFBCN310MULT_PQVal(int rw_val); +int SSMReadFBCN310MULT_PQVal(int *rw_val); +int SSMSaveFBCN310MEMCVal(int rw_val); +int SSMReadFBCN310MEMCVal(int *rw_val) ; +int SSMSaveN311_VbyOne_Spread_Spectrum_Val(int rw_val); +int SSMReadN311_VbyOne_Spread_Spectrum_Val(int *rw_val); +int SSMSaveN311_Bluetooth_Vol(int rw_val); +int SSMReadN311_Bluetooth_Vol(void) ; +int SSMSave_DRC_ONOFF_Val(int rw_val); +int SSMRead_DRC_ONOFF_Val(void); +int SSMSave_PANEL_ID_Val(int rw_val); +int SSMRead_PANEL_ID_Val(void); +int SSMSaveHDMIEdidMode(tv_hdmi_port_id_t port, tv_hdmi_edid_version_t rw_val); +tv_hdmi_edid_version_t SSMReadHDMIEdidVersion(tv_hdmi_port_id_t port); +int SSMSaveHDMIHdcpSwitcher(int rw_val); +int SSMReadHDMIHdcpSwitcher(void); +int SSMHDMIEdidRestoreDefault(void); + +int SSMSaveAmAudioVal(int rw_val, int source); +int SSMReadAmAudioVal(int *rw_val, int source); + +#ifdef __cplusplus +} +#endif + +#endif //__TV_SSM_API_H__ diff --git a/tv/tvserver/libtv/tvsetting/PQSettingCfg.h b/tv/tvserver/libtv/tvsetting/PQSettingCfg.h new file mode 100644 index 0000000..7f466ac --- a/dev/null +++ b/tv/tvserver/libtv/tvsetting/PQSettingCfg.h @@ -0,0 +1,143 @@ +#ifndef __PQ_SETTING_CFG__H__ +#define __PQ_SETTING_CFG__H__ + +enum{ + CHKSUM_PROJECT_ID_OFFSET = 0, + CHKSUM_MAC_ADDRESS_OFFSET = 1, + CHKSUM_HDCP_KEY_OFFSET = 2, + CHKSUM_BARCODE_OFFSET = 3, + SSM_RSV_W_CHARACTER_CHAR_START = 10, + SSM_CR_START = 11, + SSM_MARK_01_START = 12, + SSM_MARK_02_START = 13, + SSM_MARK_03_START = 14, + SSM_RSV0 = 20, + SSM_RW_FBMF_START = 21, + SSM_RW_DEF_HDCP_START = 22, + SSM_RW_POWER_CHANNEL_START = 23, + SSM_RW_LAST_SOURCE_INPUT_START = 24, + SSM_RW_SYS_LANGUAGE_START = 25, + SSM_RW_AGING_MODE_START = 26, + SSM_RW_PANEL_TYPE_START = 27, + SSM_RW_POWER_ON_MUSIC_SWITCH_START = 28, + SSM_RW_POWER_ON_MUSIC_VOL_START = 29, + SSM_RW_SYS_SLEEP_TIMER_START = 30, + SSM_RW_INPUT_SRC_PARENTAL_CTL_START = 31, + SSM_RW_PARENTAL_CTL_SWITCH_START = 32, + SSM_RW_PARENTAL_CTL_PASSWORD_START = 33, + SSM_RW_SEARCH_NAVIGATE_FLAG_START = 34, + SSM_RW_INPUT_NUMBER_LIMIT_START = 35, + SSM_RW_SERIAL_ONOFF_FLAG_START = 36, + SSM_RW_STANDBY_MODE_FLAG_START = 37, + SSM_RW_HDMIEQ_MODE_START = 38, + SSM_RW_LOGO_ON_OFF_FLAG_START = 39, + SSM_RW_HDMIINTERNAL_MODE_START = 40, + SSM_RW_DISABLE_3D_START = 41, + SSM_RW_GLOBAL_OGO_ENABLE_START = 42, + SSM_RW_LOCAL_DIMING_START = 43, + SSM_RW_VDAC_2D_START = 44, + SSM_RW_VDAC_3D_START = 45, + SSM_RW_NON_STANDARD_START = 46, + SSM_RW_ADB_SWITCH_START = 47, + SSM_RW_SERIAL_CMD_SWITCH_START = 48, + SSM_RW_CA_BUFFER_SIZE_START = 49, + SSM_RW_NOISE_GATE_THRESHOLD_START = 50, + SSM_RW_DTV_TYPE_START = 51, + SSM_RW_UI_GRHPHY_BACKLIGHT_START = 52, + SSM_RW_FASTSUSPEND_FLAG_START = 53, + SSM_RW_BLACKOUT_ENABLE_START = 54, + SSM_RW_PANEL_ID_START = 55, + SSM_RSV_1 = 80, + SSM_AUD_MASTR_VOLUME_VAL = 81, + SSM_AUD_BALANCE_VAL = 82, + SSM_AUD_SUPPERBASS_VOLUME_VAL = 83, + SSM_AUD_SUPPERBASS_SWITCH = 84, + SSM_AUD_SRS_SURROUND_SWITCH = 85, + SSM_AUD_SRS_DIALOG_CLARITY_SWITCH = 86, + SSM_AUD_SRS_TRUEBASS_SWITCH = 87, + SSM_AUD_BASS_VOLUME_VAL = 88, + SSM_AUD_TREBLE_VOLUME_VAL = 89, + SSM_AUD_SOUND_MODE_VAL = 90, + SSM_AUD_WALL_EFFCT_SWITCH = 91, + SSM_AUD_SPDIF_SWITCH = 92, + SSM_AUD_SPDIF_MODE_VAL = 93, + SSM_AUD_EQ_MODE_VAL = 94, + SSM_AUD_EQ_GAIN = 95, + SSM_AUD_NOLINE_POINTS = 96, + SSM_AUD_DBX_TV_SON = 97, + SSM_AUD_DBX_TV_VAL = 98, + SSM_AUD_DBX_TV_SUR = 99, + SSM_AUD_AVOUT_MUTE = 100, + SSM_AUD_SPIDF_MUTE = 101, + SSM_AUD_DRC_ONOFF = 102, + SSM_RSV_2 = 150, + VPP_DATA_POS_COLOR_DEMO_MODE_START = 151, + VPP_DATA_POS_COLOR_BASE_MODE_START = 152, + VPP_DATA_POS_TEST_PATTERN_START = 153, + VPP_DATA_POS_DDR_SSC_START = 154, + VPP_DATA_POS_LVDS_SSC_START = 155, + VPP_DATA_POS_DREAM_PANEL_START = 156, + VPP_DATA_POS_BACKLIGHT_REVERSE_START = 157, + VPP_DATA_POS_BRIGHTNESS_START = 158, + VPP_DATA_POS_CONTRAST_START = 159, + VPP_DATA_POS_SATURATION_START = 160, + VPP_DATA_POS_HUE_START = 161, + VPP_DATA_POS_SHARPNESS_START = 162, + VPP_DATA_POS_COLOR_TEMPERATURE_START = 163, + VPP_DATA_POS_NOISE_REDUCTION_START = 164, + VPP_DATA_POS_SCENE_MODE_START = 165, + VPP_DATA_POS_PICTURE_MODE_START = 166, + VPP_DATA_POS_DISPLAY_MODE_START = 167, + VPP_DATA_POS_BACKLIGHT_START = 168, + VPP_DATA_POS_RGB_GAIN_R_START = 169, + VPP_DATA_POS_RGB_GAIN_G_START = 170, + VPP_DATA_POS_RGB_GAIN_B_START = 171, + VPP_DATA_POS_RGB_POST_OFFSET_R_START = 172, + VPP_DATA_POS_RGB_POST_OFFSET_G_START = 173, + VPP_DATA_POS_RGB_POST_OFFSET_B_START = 174, + VPP_DATA_POS_DBC_START = 175, + VPP_DATA_PROJECT_ID_START = 176, + VPP_DATA_POS_DNLP_START = 177, + VPP_DATA_POS_PANORAMA_START = 178, + VPP_DATA_APL_START = 179, + VPP_DATA_APL2_START = 180, + VPP_DATA_BD_START = 181, + VPP_DATA_BP_START = 182, + VPP_DATA_RGB_START = 183, + VPP_DATA_COLOR_SPACE_START = 184, + VPP_DATA_USER_NATURE_SWITCH_START = 185, + VPP_DATA_GAMMA_VALUE_START = 186, + VPP_DATA_DBC_BACKLIGHT_START = 187, + VPP_DATA_DBC_STANDARD_START = 188, + VPP_DATA_DBC_ENABLE_START = 189, + VPP_DATA_POS_FBC_BACKLIGHT_START = 190, + VPP_DATA_POS_FBC_ELECMODE_START = 191, + VPP_DATA_POS_FBC_COLORTEMP_START = 192, + VPP_DATA_POS_FBC_N310_BACKLIGHT_START = 193, + VPP_DATA_POS_FBC_N310_COLORTEMP_START = 194, + VPP_DATA_POS_FBC_N310_LIGHTSENSOR_START = 195, + VPP_DATA_POS_FBC_N310_MEMC_START = 196, + VPP_DATA_POS_FBC_N310_DREAMPANEL_START = 197, + VPP_DATA_POS_FBC_N310_MULTI_PQ_START = 198, + VPP_DATA_POS_N311_VBYONE_SPREAD_SPECTRUM_START = 199, + VPP_DATA_POS_N311_BLUETOOTH_VAL_START = 200, + VPP_DATA_EYE_PROTECTION_MODE_START = 201, + SSM_RSV3 = 250, + TVIN_DATA_POS_SOURCE_INPUT_START = 251, + TVIN_DATA_CVBS_STD_START = 252, + TVIN_DATA_POS_3D_MODE_START = 253, + TVIN_DATA_POS_3D_LRSWITCH_START = 254, + TVIN_DATA_POS_3D_DEPTH_START = 255, + TVIN_DATA_POS_3D_TO2D_START = 256, + TVIN_DATA_POS_3D_TO2DNEW_START = 257, + SSM_RSV4 = 280, + CUSTOMER_DATA_POS_HDMI1_EDID_START = 281, + CUSTOMER_DATA_POS_HDMI2_EDID_START = 282, + CUSTOMER_DATA_POS_HDMI3_EDID_START = 283, + CUSTOMER_DATA_POS_HDMI4_EDID_START = 284, + CUSTOMER_DATA_POS_HDMI_HDCP_SWITCHER_START = 285, + + SSM_AM_AUDIO_VOLUME = 286, + +}; +#endif diff --git a/tv/tvserver/libtv/tvsetting/TvKeyData.cpp b/tv/tvserver/libtv/tvsetting/TvKeyData.cpp new file mode 100644 index 0000000..3f2e309 --- a/dev/null +++ b/tv/tvserver/libtv/tvsetting/TvKeyData.cpp @@ -0,0 +1,1320 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "TvKeyData" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <cutils/properties.h> + +#include <netinet/ether.h> +#include <netinet/if_ether.h> + +#include <netutils/ifc.h> +//#include <netutils/dhcp.h> + +#include <tvconfig.h> +#include "../tvin/CTvin.h" + +#include "TvKeyData.h" + + +static unsigned char mHDCPKeyDefHeaderBuf[CC_HDCP_KEY_HEAD_SIZE] = { + //40 bytes + 0x53, 0x4B, 0x59, 0x01, 0x00, 0x10, 0x0D, 0x15, 0x3A, 0x8E, // 000~009 + 0x99, 0xEE, 0x2A, 0x55, 0x58, 0xEE, 0xED, 0x4B, 0xBE, 0x00, // 010~019 + 0x74, 0xA9, 0x00, 0x10, 0x0A, 0x21, 0xE3, 0x30, 0x66, 0x34, // 020~029 + 0xCE, 0x9C, 0xC7, 0x8B, 0x51, 0x27, 0xF9, 0x0B, 0xAD, 0x09, // 030~039 +}; + +static unsigned char mDefHDCPKeyContentBuf[CC_HDCP_KEY_CONTENT_SIZE] = { + //328 bytes + 0x5F, 0x4D, 0xC2, 0xCA, 0xA2, 0x13, 0x06, 0x18, 0x8D, 0x34, // 000~009 + 0x82, 0x46, 0x2D, 0xC9, 0x4B, 0xB0, 0x1C, 0xDE, 0x3D, 0x49, // 010~019 + 0x39, 0x58, 0xEF, 0x2B, 0x68, 0x39, 0x71, 0xC9, 0x4D, 0x25, // 020~029 + 0xE9, 0x75, 0x4D, 0xAC, 0x62, 0xF5, 0xF5, 0x87, 0xA0, 0xB2, // 030~039 + 0x4A, 0x60, 0xD3, 0xF1, 0x09, 0x3A, 0xB2, 0x3E, 0x19, 0x4F, // 040~049 + 0x3B, 0x1B, 0x2F, 0x85, 0x14, 0x28, 0x44, 0xFC, 0x69, 0x6F, // 050~059 + 0x50, 0x42, 0x81, 0xBF, 0x7C, 0x2B, 0x3A, 0x17, 0x2C, 0x15, // 060~069 + 0xE4, 0x93, 0x77, 0x74, 0xE8, 0x1F, 0x1C, 0x38, 0x54, 0x49, // 070~079 + 0x10, 0x64, 0x5B, 0x7D, 0x90, 0x3D, 0xA0, 0xE1, 0x8B, 0x67, // 080~089 + 0x5C, 0x19, 0xE6, 0xCA, 0x9D, 0xE9, 0x68, 0x5A, 0xB5, 0x62, // 090~099 + 0xDF, 0xA1, 0x28, 0xBC, 0x68, 0x82, 0x9A, 0x22, 0xC4, 0xDC, // 100~109 + 0x48, 0x85, 0x0F, 0xF1, 0x3E, 0x05, 0xDD, 0x1B, 0x2D, 0xF5, // 120~119 + 0x49, 0x3A, 0x15, 0x29, 0xE7, 0xB6, 0x0B, 0x2A, 0x40, 0xE3, // 120~129 + 0xB0, 0x89, 0xD5, 0x75, 0x84, 0x2E, 0x76, 0xE7, 0xBC, 0x63, // 130~139 + 0x67, 0xE3, 0x57, 0x67, 0x86, 0x81, 0xF4, 0xD7, 0xEA, 0x4D, // 140~149 + 0x89, 0x8E, 0x37, 0x95, 0x59, 0x1C, 0x8A, 0xCD, 0x79, 0xF8, // 150~159 + 0x4F, 0x82, 0xF2, 0x6C, 0x7E, 0x7F, 0x79, 0x8A, 0x6B, 0x90, // 160~169 + 0xC0, 0xAF, 0x4C, 0x8D, 0x43, 0x47, 0x1F, 0x9A, 0xF1, 0xBB, // 170~179 + 0x88, 0x64, 0x49, 0x14, 0x50, 0xD1, 0xC3, 0xDF, 0xA6, 0x87, // 180~189 + 0xA0, 0x15, 0x98, 0x51, 0x81, 0xF5, 0x97, 0x55, 0x10, 0x4A, // 190~199 + 0x99, 0x30, 0x54, 0xA4, 0xFC, 0xDA, 0x0E, 0xAC, 0x6A, 0xFA, // 200~209 + 0x90, 0xEE, 0x12, 0x70, 0x69, 0x74, 0x63, 0x46, 0x63, 0xFB, // 210~219 + 0xE6, 0x1F, 0x72, 0xEC, 0x43, 0x5D, 0x50, 0xFF, 0x03, 0x4F, // 220~229 + 0x05, 0x33, 0x88, 0x36, 0x93, 0xE4, 0x72, 0xD5, 0xCC, 0x34, // 230~239 + 0x52, 0x96, 0x15, 0xCE, 0xD0, 0x32, 0x52, 0x41, 0x4F, 0xBC, // 240~249 + 0x2D, 0xDF, 0xC5, 0xD6, 0x7F, 0xD5, 0x74, 0xCE, 0x51, 0xDC, // 250~259 + 0x10, 0x5E, 0xF7, 0xAA, 0x4A, 0x2D, 0x20, 0x9A, 0x17, 0xDD, // 260~269 + 0x30, 0x89, 0x71, 0x82, 0x36, 0x50, 0x09, 0x1F, 0x7C, 0xF3, // 270~279 + 0x12, 0xE9, 0x43, 0x10, 0x5F, 0x51, 0xBF, 0xB8, 0x45, 0xA8, // 280~289 + 0x5A, 0x8D, 0x3F, 0x77, 0xE5, 0x96, 0x73, 0x68, 0xAB, 0x73, // 290~299 + 0xE5, 0x4C, 0xFB, 0xE5, 0x98, 0xB9, 0xAE, 0x74, 0xEB, 0x51, // 300~309 + 0xDB, 0x91, 0x07, 0x7B, 0x66, 0x02, 0x9B, 0x79, 0x03, 0xC5, // 310~319 + 0x34, 0x1C, 0x58, 0x13, 0x31, 0xD2, 0x4A, 0xEC, // 320~327 +}; + + +static int TransStringToHex(int data_cnt, char data_buf[], + unsigned char hex_buf[]) +{ + int i = 0, j = 0, tmp_val = 0; + char tmp_buf[3] = { 0, 0, 0 }; + + while (i < data_cnt) { + tmp_val = 0; + tmp_buf[0] = data_buf[i]; + tmp_buf[1] = data_buf[i + 1]; + tmp_val = strtoul(tmp_buf, NULL, 16); + hex_buf[j] = tmp_val; + //LOGD("%s, hex_buf[%d] = 0x%x\n", __FUNCTION__, j, hex_buf[j]); + i += 2; + j += 1; + } + + return j; +} + +static int TransToHexString(int hex_cnt, char data_buf[], + unsigned char hex_buf[]) +{ + int i = 0, j = 0; + char tmp_buf[17] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + data_buf[0] = 0; + for (i = 0; i < hex_cnt; i++) { + sprintf(tmp_buf, "%02X", (unsigned char) hex_buf[i]); + strcat(data_buf, tmp_buf); + } + + return 2 * hex_cnt; +} + +static int write_partiton_raw(const char *partition, const void *data, const int size) +{ + int fd = 0; + int len = 0; + + fd = open(partition, O_WRONLY); + if (fd < 0) { + LOGE("%s, open %s failed!\n", __FUNCTION__, partition); + return -1; + } + + if (write(fd, data, size) != size) { + LOGE("%s, write %s size:%d failed!\n", __FUNCTION__, partition, size); + close(fd); + return -1; + } + + //debugP("write partition:%s, data:%s\n", partition, (char *)data); + + close(fd); + return 0; +} + +static int read_partiton_raw(const char *partition, char *data, const int size) +{ + int fd = 0; + int len = 0; + + fd = open(partition, O_RDONLY); + if (fd < 0) { + LOGE("%s, open %s failed!\n", __FUNCTION__, partition); + return -1; + } + + if (read(fd, data, size) != size) { + LOGE("%s, read %s size:%d failed!\n", __FUNCTION__, partition, size); + close(fd); + return -1; + } + + //LOGD("%s, read partition:%s, data:%s\n", __FUNCTION__, partition, (char *)data); + + close(fd); + return 0; +} + +int ReadKeyData(const char *key_name, unsigned char data_buf[]) +{ + int rc = 0; + + if (write_partiton_raw(CS_KEY_DATA_ATTACH_DEV_PATH, "1", strlen("1"))) { + LOGE("%s, attach failed!\n", __FUNCTION__); + return -__LINE__; + } + + if (write_partiton_raw(CS_KEY_DATA_NAME_DEV_PATH, key_name, strlen(key_name))) { + LOGE("%s, name failed!\n", __FUNCTION__); + return -__LINE__; + } + + rc = read_partiton_raw(CS_KEY_DATA_READ_DEV_PATH, (char*)data_buf, CC_HDCP_KEY_CONTENT_SIZE); + if ( rc ) { + LOGE("%s, Fail in read (%s) in len %d\n", __FUNCTION__, key_name, CC_HDCP_KEY_CONTENT_SIZE); + return -__LINE__; + } + + return CC_HDCP_KEY_CONTENT_SIZE; +} + +int WriteKeyData(const char *key_name, int wr_size, char data_buf[]) +{ + FILE *dev_fp = NULL; + int wr_cnt = 0; + + dev_fp = fopen(CS_KEY_DATA_NAME_DEV_PATH, "w"); + if (dev_fp == NULL) { + LOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__, + CS_KEY_DATA_NAME_DEV_PATH, strerror(errno)); + return -1; + } + + fprintf(dev_fp, "%s", key_name); + + fclose(dev_fp); + dev_fp = NULL; + + dev_fp = fopen(CS_KEY_DATA_WRITE_DEV_PATH, "w"); + if (dev_fp == NULL) { + LOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__, + CS_KEY_DATA_WRITE_DEV_PATH, strerror(errno)); + return -1; + } + + wr_cnt = fwrite(data_buf, 1, wr_size, dev_fp); + + fclose(dev_fp); + dev_fp = NULL; + + return wr_cnt; +} + +int KeyData_GetMacAddressDataLen() +{ + return CC_MAC_LEN; +} + +int KeyData_ReadMacAddress(unsigned char data_buf[]) +{ + int i = 0, rd_size = 0; + int data_i_buf[CC_MAC_LEN] = { 0, 0, 0, 0, 0, 0 }; + unsigned char rd_buf[128] = { 0 }; + unsigned char tmp_buf[128] = { 0 }; + + memset((void *)rd_buf, 0 , 128); + rd_size = ReadKeyData(CS_MAC_KEY_NAME, rd_buf); + LOGD("%s, rd_size = %d\n", __FUNCTION__, rd_size); + +#if ANDROID_PLATFORM_SDK_VERSION == 19 + memcpy((void *)tmp_buf, (void *)rd_buf, 128); + rd_size = TransStringToHex(rd_size, (char *)rd_buf, tmp_buf); +#endif + +#if ANDROID_PLATFORM_SDK_VERSION >= 21 + memcpy((void *)tmp_buf, (void *)rd_buf, 128); +#endif + + if (rd_size == 17) { + sscanf((char *) tmp_buf, "%02x:%02x:%02x:%02x:%02x:%02x", + &data_i_buf[0], &data_i_buf[1], &data_i_buf[2], &data_i_buf[3], + &data_i_buf[4], &data_i_buf[5]); + for (i = 0; i < CC_MAC_LEN; i++) { + data_buf[i] = data_i_buf[i] & 0xFF; + } + + return KeyData_GetMacAddressDataLen(); + } + + return 0; +} + +int KeyData_SaveMacAddress(unsigned char data_buf[]) +{ + int tmp_ret = 0, wr_size = 0; + unsigned char hex_buf[128] = { 0 }; + char tmp_buf[128] = { 0 }; + + sprintf((char *) hex_buf, "%02x:%02x:%02x:%02x:%02x:%02x", data_buf[0], + data_buf[1], data_buf[2], data_buf[3], data_buf[4], data_buf[5]); + +#if ANDROID_PLATFORM_SDK_VERSION == 19 + memset((void *)tmp_buf, 0, 128); + TransToHexString(strlen((char *) hex_buf), tmp_buf, hex_buf); +#endif + +#if ANDROID_PLATFORM_SDK_VERSION >= 21 + memset((void *)tmp_buf, 0, 128); + memcpy(tmp_buf, (const char *)hex_buf, strlen((char *) hex_buf)); +#endif + + wr_size = strlen(tmp_buf); + tmp_ret = WriteKeyData(CS_MAC_KEY_NAME, wr_size, tmp_buf); + if (tmp_ret != wr_size) { + return -1; + } + + CreateMacAddressStartWorkThread(); + + return 0; +} + +static int gSSMBarCodeLen = -1; +int KeyData_GetBarCodeDataLen() +{ + const char *config_value; + + if (gSSMBarCodeLen <= 0) { + config_value = config_get_str(CFG_SECTION_TV, CS_BARCODE_LEN_CFG, "null"); + if (strcmp(config_value, "null") == 0) { + gSSMBarCodeLen = 32; + } else { + gSSMBarCodeLen = strtol(config_value, NULL, 10); + } + } + + return gSSMBarCodeLen; +} + +int KeyData_ReadBarCode(unsigned char data_buf[]) +{ + int rd_size = 0, tmp_len = 0; + unsigned char rd_buf[CC_MAX_KEY_DATA_SIZE] = { 0 }; + + tmp_len = KeyData_GetBarCodeDataLen(); + rd_size = ReadKeyData(CS_BARCODE_KEY_NAME, rd_buf); + LOGD("%s, rd_size = %d\n", __FUNCTION__, rd_size); + +#if ANDROID_PLATFORM_SDK_VERSION == 19 + unsigned char tmp_buf[CC_MAX_KEY_DATA_SIZE] = { 0 }; + + memcpy((void *)tmp_buf, (void *)rd_buf, CC_MAX_KEY_DATA_SIZE); + rd_size = TransStringToHex(rd_size, (char *)rd_buf, tmp_buf); + + if (rd_size == tmp_len) { + memcpy(data_buf, tmp_buf, rd_size); + return rd_size; + } +#endif + +#if ANDROID_PLATFORM_SDK_VERSION >= 21 + if (rd_size == tmp_len) { + memcpy(data_buf, rd_buf, rd_size); + return rd_size; + } +#endif + + return 0; +} + +int KeyData_SaveBarCode(unsigned char data_buf[]) +{ + int tmp_len = 0, wr_size = 0; + char tmp_buf[CC_MAX_KEY_DATA_SIZE] = { 0 }; + + tmp_len = KeyData_GetBarCodeDataLen(); + +#if ANDROID_PLATFORM_SDK_VERSION == 19 + memset((void *)tmp_buf, 0, CC_MAX_KEY_DATA_SIZE); + TransToHexString(tmp_len, tmp_buf, data_buf); +#endif + +#if ANDROID_PLATFORM_SDK_VERSION >= 21 + memset((void *)tmp_buf, 0, CC_MAX_KEY_DATA_SIZE); + memcpy(tmp_buf, (const char *)data_buf, strlen((char *) data_buf)); +#endif + + wr_size = strlen(tmp_buf); + tmp_len = WriteKeyData(CS_BARCODE_KEY_NAME, wr_size, tmp_buf); + if (tmp_len != wr_size) { + return -1; + } + + return 0; +} + +int SSMReadHDCPKey(unsigned char hdcp_key_buf[]) +{ + int tmp_ret = 0, rd_size = 0; + unsigned char rd_buf[CC_MAX_KEY_DATA_SIZE] = { 0 }; + //unsigned char tmp_buf[CC_MAX_KEY_DATA_SIZE] = { 0 }; + + tmp_ret = GetHDCPKeyFromFile(0, CC_HDCP_KEY_TOTAL_SIZE, hdcp_key_buf); + if (tmp_ret < 0) { + rd_size = ReadKeyData(CS_RX_HDCP14_KEY_NAME, rd_buf); + LOGD("%s, rd_size = %d\n", __FUNCTION__, rd_size); + + //memcpy((void *)tmp_buf, (void *)rd_buf, CC_MAX_KEY_DATA_SIZE); + //rd_size = TransStringToHex(rd_size, (char *)rd_buf, tmp_buf); + + //LOGD("%s, after TransStringToHex rd_size = %d\n", __FUNCTION__, rd_size); + LOGD("%s, rd_buf = %x, %x, %x\n", __FUNCTION__, rd_buf[0], rd_buf[1], rd_buf[3]); + if (rd_size == CC_HDCP_KEY_CONTENT_SIZE) { + memcpy(hdcp_key_buf, mHDCPKeyDefHeaderBuf, CC_HDCP_KEY_HEAD_SIZE); + memcpy(hdcp_key_buf + CC_HDCP_KEY_HEAD_SIZE, rd_buf, CC_HDCP_KEY_CONTENT_SIZE); + return CC_HDCP_KEY_TOTAL_SIZE; + } + return 0; + } + return CC_HDCP_KEY_TOTAL_SIZE; +} + + + +int SSMSaveHDCPKey(unsigned char hdcp_key_buf[]) +{ + int tmp_ret = 0, wr_size = 0; + char tmp_buf[CC_MAX_KEY_DATA_SIZE] = { 0 }; + + tmp_ret = SaveHDCPKeyToFile(0, CC_HDCP_KEY_TOTAL_SIZE, hdcp_key_buf); + if (tmp_ret < 0) { + memset((void *)tmp_buf, 0, CC_MAX_KEY_DATA_SIZE); + TransToHexString(CC_HDCP_KEY_TOTAL_SIZE, tmp_buf, hdcp_key_buf); + + wr_size = strlen(tmp_buf); + tmp_ret = WriteKeyData(CS_RX_HDCP_KEY_NAME, wr_size, tmp_buf); + if (tmp_ret != wr_size) { + tmp_ret = -1; + } else { + tmp_ret = 0; + } + } + + return tmp_ret; +} + +int SSMSetHDCPKey() +{ + + int i = 0; + unsigned char hdcp_key_buf[CC_HDCP_KEY_TOTAL_SIZE]; + + if (GetSSMHandleHDCPKeyEnableCFG() == 1) { + if (GetSSMHandleHDCPKeyDemoEnableCFG() == 1) { + return SSMSetDefaultHDCPKey(hdcp_key_buf); + } else { + if (SSMReadHDCPKey(hdcp_key_buf) == CC_HDCP_KEY_TOTAL_SIZE) { + LOGD("%s, using ssm's hdcp key.\n", __FUNCTION__); + return RealHandleHDCPKey(hdcp_key_buf); + } + } + } + + return -1; +} + +int SSMRefreshHDCPKey() +{ + int ret = -1; + ret = SSMSetHDCPKey(); + system ( "/vendor/bin/dec" ); + return ret; +} + +int SSMGetHDCPKeyDataLen() +{ + return CC_HDCP_KEY_TOTAL_SIZE; +} + +//hdmi edid +int SSMSetHDMIEdid(int port) +{ + int i = 0; + unsigned char customer_hdmi_edid_buf[CC_CUSTOMER_HDMI_EDID_TOTAL_SIZE]; + unsigned char hdmi_edid_buf[SSM_HDMI_EDID_SIZE]; + + if (port < 1 || port > SSM_HDMI_PORT_MAX) { + LOGD("%s, hdmi port error.%d\n", __FUNCTION__, port); + return -1; + } + + if (GetSSMHandleHDMIEdidByCustomerEnableCFG() == 1) { + if (SSMReadHDMIEdid(port, hdmi_edid_buf) == 0) { + LOGD("%s, using ssm's hdmi edid.\n", __FUNCTION__); + LOGD("%s, begin to write hdmi edid:0x%x, 0x%x, 0x%x, 0x%x.\n", + __FUNCTION__, hdmi_edid_buf[8], hdmi_edid_buf[9], + hdmi_edid_buf[10], hdmi_edid_buf[255]); + if ( AppendEdidPrefixCode(customer_hdmi_edid_buf, hdmi_edid_buf) == 0 ) + return RealHandleHDMIEdid(customer_hdmi_edid_buf); + } + } + + return -1; +} + +int SSMReadHDMIEdid(int port, unsigned char hdmi_edid_buf[]) +{ + int tmp_ret = 0; + LOGD("%s, read hdmi edid from bin file.\n", __FUNCTION__); + tmp_ret = GetHDMIEdidFromFile(0, SSM_HDMI_EDID_SIZE, port, hdmi_edid_buf); + if (tmp_ret < 0) { + LOGD("%s, read hdmi edid error.\n", __FUNCTION__); + } else { + LOGD("%s, 0x%x, 0x%x, 0x%x, 0x%x.\n", __FUNCTION__, hdmi_edid_buf[8], + hdmi_edid_buf[9], hdmi_edid_buf[10], hdmi_edid_buf[255]); + } + return tmp_ret; +} + +int KeyData_SaveProjectID(int rw_val) +{ + int tmp_ret = 0, wr_size = 0; + char tmp_buf[64] = { 0 }; + + sprintf(tmp_buf, "%08X", rw_val); + + wr_size = strlen(tmp_buf); + tmp_ret = WriteKeyData(CS_PROJECT_ID_KEY_NAME, wr_size, tmp_buf); + if (tmp_ret != wr_size) { + return -1; + } + + return 0; +} + +int KeyData_ReadProjectID() +{ + int rd_size = 0, tmp_val = 0; + unsigned char tmp_buf[64] = { 0 }; + + rd_size = ReadKeyData(CS_PROJECT_ID_KEY_NAME, tmp_buf); + LOGD("%s, rd_size = %d\n", __FUNCTION__, rd_size); + if (rd_size == 4) { + tmp_val = 0; + tmp_val |= tmp_buf[0] << 24; + tmp_val |= tmp_buf[1] << 16; + tmp_val |= tmp_buf[2] << 8; + tmp_val |= tmp_buf[3] << 0; + } + + return tmp_val; +} + +int SSMSaveAudioNoLinePoints(int offset, int size, unsigned char tmp_buf[]) +{ + return SaveAudioNoLinePointsDataToFile(offset, size, tmp_buf); +} + +int SSMReadAudioNoLinePoints(int offset, int size, unsigned char tmp_buf[]) +{ + return GetAudioNoLinePointsDataFromFile(offset, size, tmp_buf); +} + +/**************************** start mac address static functions ****************************/ +#define CC_ERR_THREAD_ID (0) + +static pthread_t mMacAddressStartWorkThreadID = CC_ERR_THREAD_ID; + +static volatile unsigned int mMacAddressLow = -1; +static volatile unsigned int mMacAddressHigh = -1; +static volatile int mMacAddressStartWorkThreadExecFlag = -1; +static volatile int mMacAddressStartWorkThreadTurnOnFlag = -1; + +static pthread_mutex_t mac_address_low_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t mac_address_high_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t mac_address_exec_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t mac_address_turnon_mutex = PTHREAD_MUTEX_INITIALIZER; + +static int GetSSMMacAddressStartWorkEnableCFG() +{ + const char *config_value; + + config_value = config_get_str(CFG_SECTION_TV, CS_MAC_ADDRESS_STARTWRK_EN_CFG, "null"); + if (strcmp(config_value, "null") == 0) { + LOGD( + "%s, get config is \"%s\", return 0 to not enable mac address start work.\n", + __FUNCTION__, config_value); + return 0; + } + + return strtoul(config_value, NULL, 10); +} + +static unsigned int SetMacAddressLow(unsigned int low_val) +{ + unsigned int tmp_val; + + pthread_mutex_lock(&mac_address_low_mutex); + + tmp_val = mMacAddressLow; + + mMacAddressLow = low_val; + + pthread_mutex_unlock(&mac_address_low_mutex); + + return tmp_val; +} + +static unsigned int GetMacAddressLow() +{ + unsigned int tmp_val = 0; + + pthread_mutex_lock(&mac_address_low_mutex); + + tmp_val = mMacAddressLow; + + pthread_mutex_unlock(&mac_address_low_mutex); + + return tmp_val; +} + +static unsigned int SetMacAddressHigh(unsigned int high_val) +{ + unsigned int tmp_val; + + pthread_mutex_lock(&mac_address_high_mutex); + + tmp_val = mMacAddressHigh; + + mMacAddressHigh = high_val; + + pthread_mutex_unlock(&mac_address_high_mutex); + + return tmp_val; +} + +static unsigned int GetMacAddressHigh() +{ + int tmp_val = 0; + + pthread_mutex_lock(&mac_address_high_mutex); + + tmp_val = mMacAddressHigh; + + pthread_mutex_unlock(&mac_address_high_mutex); + + return tmp_val; +} + +static int SetMacAddressStartWorkThreadExecFlag(int tmp_flag) +{ + int tmp_val; + + pthread_mutex_lock(&mac_address_exec_mutex); + + tmp_val = mMacAddressStartWorkThreadExecFlag; + + mMacAddressStartWorkThreadExecFlag = tmp_flag; + + pthread_mutex_unlock(&mac_address_exec_mutex); + + return tmp_val; +} + +static int GetMacAddressStartWorkThreadExecFlag() +{ + int tmp_val = 0; + + pthread_mutex_lock(&mac_address_exec_mutex); + + tmp_val = mMacAddressStartWorkThreadExecFlag; + + pthread_mutex_unlock(&mac_address_exec_mutex); + + return tmp_val; +} + +static int SetMacAddressStartWorkThreadTurnOnFlag(int tmp_flag) +{ + int tmp_val; + + pthread_mutex_lock(&mac_address_turnon_mutex); + + tmp_val = mMacAddressStartWorkThreadTurnOnFlag; + + mMacAddressStartWorkThreadTurnOnFlag = tmp_flag; + + pthread_mutex_unlock(&mac_address_turnon_mutex); + + return tmp_val; +} + +static int GetMacAddressStartWorkThreadTurnOnFlag() +{ + int tmp_val = 0; + + pthread_mutex_lock(&mac_address_turnon_mutex); + + tmp_val = mMacAddressStartWorkThreadTurnOnFlag; + + pthread_mutex_unlock(&mac_address_turnon_mutex); + + return tmp_val; +} + +static void *SSMMacAddressStartWorkMainApp(void *data __unused) +{ + unsigned int curMacAddrLow = 0, curMacAddrHigh = 0; + int p_status; + char ssm_addr_str[128]; + const char *iname = "eth0"; + pid_t pid; + + LOGD("%s, entering...\n", __FUNCTION__); + + if (GetSSMMacAddressStartWorkEnableCFG() == 0) { + LOGE("%s, ssm mac address start work is not enable.\n", CFG_SECTION_TV); + return NULL; + } + + curMacAddrLow = GetMacAddressLow(); + curMacAddrHigh = GetMacAddressHigh(); + + while (GetMacAddressStartWorkThreadTurnOnFlag() == 1) { + pid = fork(); + if (pid == 0) { + if (execl("/vendor/bin/stop", "stop_eth_dhcpcd", "eth_dhcpcd", NULL) + < 0) { + _exit(-1); + } + _exit(0); + } + waitpid(pid, &p_status, 0); + + ifc_init(); + + ifc_down(iname); + + sprintf(ssm_addr_str, "%02x:%02x:%02x:%02x:%02x:%02x", + ((curMacAddrLow >> 0) & 0xFF), ((curMacAddrLow >> 8) & 0xFF), + ((curMacAddrLow >> 16) & 0xFF), ((curMacAddrLow >> 24) & 0xFF), + ((curMacAddrHigh >> 0) & 0xFF), ((curMacAddrHigh >> 8) & 0xFF)); + struct ether_addr *addr = ether_aton(ssm_addr_str); + if (addr) { + ifc_set_hwaddr(iname, addr->ether_addr_octet); + } + + ifc_up(iname); + + ifc_close(); + + if (curMacAddrLow == GetMacAddressLow() + && curMacAddrHigh == GetMacAddressHigh()) { + break; + } + + curMacAddrLow = GetMacAddressLow(); + curMacAddrHigh = GetMacAddressHigh(); + } + + return NULL; +} + +static void *SSMMacAddressStartWorkThreadMain(void *data __unused) +{ + void *tmp_ret = NULL; + SetMacAddressStartWorkThreadExecFlag(1); + tmp_ret = SSMMacAddressStartWorkMainApp(NULL); + SetMacAddressStartWorkThreadExecFlag(0); + return tmp_ret; +} + +static int KillMacAddressStartWorkThread() +{ + int i = 0, tmp_timeout_count = 600; + + SetMacAddressStartWorkThreadTurnOnFlag(0); + while (1) { + if (GetMacAddressStartWorkThreadExecFlag() == 0) { + break; + } + + if (i >= tmp_timeout_count) { + break; + } + + i++; + + usleep(100 * 1000); + } + + if (i == tmp_timeout_count) { + LOGE( + "%s, we have try %d times, but the mac address start work thread's exec flag is still(%d)!!!\n", + CFG_SECTION_TV, tmp_timeout_count, + GetMacAddressStartWorkThreadExecFlag()); + return -1; + } + + pthread_join(mMacAddressStartWorkThreadID, NULL); + mMacAddressStartWorkThreadID = CC_ERR_THREAD_ID; + + LOGD("%s, kill the mac address start work thread sucess.\n", __FUNCTION__); + + return 0; +} + +int CreateMacAddressStartWorkThread() +{ + unsigned int macAddrLow = 0, macAddrHigh = 0; + pthread_attr_t attr; + struct sched_param param; + unsigned char ssm_addr_buf[16] = { 0, 0, 0, 0, 0, 0 }; + + if (KeyData_ReadMacAddress(ssm_addr_buf) < 0) { + return -1; + } + + macAddrLow = 0; + macAddrLow |= ((ssm_addr_buf[0] & 0xFF) << 0); + macAddrLow |= ((ssm_addr_buf[1] & 0xFF) << 8); + macAddrLow |= ((ssm_addr_buf[2] & 0xFF) << 16); + macAddrLow |= ((ssm_addr_buf[3] & 0xFF) << 24); + + macAddrHigh = 0; + macAddrHigh |= ((ssm_addr_buf[4] & 0xFF) << 0); + macAddrHigh |= ((ssm_addr_buf[5] & 0xFF) << 8); + + if (mMacAddressStartWorkThreadID != CC_ERR_THREAD_ID) { + if (GetMacAddressStartWorkThreadExecFlag() == 1) { + SetMacAddressLow(macAddrLow); + SetMacAddressHigh(macAddrHigh); + return 0; + } else { + KillMacAddressStartWorkThread(); + } + } + + SetMacAddressLow(macAddrLow); + SetMacAddressHigh(macAddrHigh); + SetMacAddressStartWorkThreadTurnOnFlag(1); + + pthread_attr_init(&attr); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + param.sched_priority = 20; + pthread_attr_setschedparam(&attr, ¶m); + + if (pthread_create(&mMacAddressStartWorkThreadID, &attr, + SSMMacAddressStartWorkThreadMain, NULL) < 0) { + pthread_attr_destroy(&attr); + mMacAddressStartWorkThreadID = CC_ERR_THREAD_ID; + return -1; + } + + pthread_attr_destroy(&attr); + + LOGD("%s, create channel select thread sucess.\n", __FUNCTION__); + + return 0; +} +/**************************** end mac address static functions ****************************/ + +/**************************** start hdcp key static functions ****************************/ +int GetSSMHandleHDCPKeyEnableCFG() +{ + const char *config_value; + + config_value = config_get_str(CFG_SECTION_TV, CS_HDCP_KEY_EN_CFG, "null"); +#if 0 + LOGD("%s, get \"%s\" is \"%s\".\n", __FUNCTION__, CS_HDCP_KEY_EN_CFG, + config_value); +#endif + if (strcmp(config_value, "null") == 0) { + LOGD( + "%s, get config \"%s\" is \"%s\", return 0 to not enable handle hdcp key.\n", + __FUNCTION__, CS_HDCP_KEY_EN_CFG, config_value); + return 0; + } + + return strtoul(config_value, NULL, 10); +} + +int GetSSMHandleHDCPKeyDemoEnableCFG() +{ + const char *config_value; + + config_value = config_get_str(CFG_SECTION_TV, CS_HDCP_KEY_DEMO_EN_CFG, "null"); +#if 0 + LOGD("%s, get \"%s\" is \"%s\".\n", __FUNCTION__, CS_HDCP_KEY_DEMO_EN_CFG, + config_value); +#endif + if (strcmp(config_value, "null") == 0) { + LOGD( + "%s, get config \"%s\" is \"%s\", return 0 to not enable handle hdcp key demo.\n", + __FUNCTION__, CS_HDCP_KEY_DEMO_EN_CFG, config_value); + return 0; + } + + return strtoul(config_value, NULL, 10); +} + + +int SSMSetDefaultHDCPKey(unsigned char hdcp_key_buf[]) +{ + int i = 0; + + for (i = 0; i < CC_HDCP_KEY_HEAD_SIZE; i++) { + hdcp_key_buf[i] = mHDCPKeyDefHeaderBuf[i]; + } + + for (i = 0; i < CC_HDCP_KEY_CONTENT_SIZE; i++) { + hdcp_key_buf[i + CC_HDCP_KEY_HEAD_SIZE] = mDefHDCPKeyContentBuf[i]; + } + + LOGD("%s, using default hdcp key.\n", __FUNCTION__); + + return RealHandleHDCPKey(hdcp_key_buf); +} + +int RealHandleHDCPKey(unsigned char hdcp_key_buf[]) +{ + int i = 0, dev_fd = -1; + + if (hdcp_key_buf == NULL) { + return -1; + } + + dev_fd = open("/sys/class/hdmirx/hdmirx0/edid", O_RDWR); + if (dev_fd < 0) { + LOGE("%s, open edid file ERROR(%s)!!\n", CFG_SECTION_TV, strerror(errno)); + return -1; + } + + if (write(dev_fd, hdcp_key_buf, CC_HDCP_KEY_TOTAL_SIZE) < 0) { + close(dev_fd); + dev_fd = -1; + LOGE("%s, write edid file ERROR(%s)!!\n", CFG_SECTION_TV, strerror(errno)); + + return -1; + } + + close(dev_fd); + dev_fd = -1; + return 0; +} + +/**************************** end hdcp key static functions ****************************/ + +/**************************** start hdmi edid static functions ****************************/ +int GetSSMHandleHDMIEdidByCustomerEnableCFG() +{ + const char *config_value; + + config_value = config_get_str(CFG_SECTION_TV, CFG_SSM_HDMI_EDID_EN, "null"); + if (strcmp(config_value, "null") == 0) { + LOGD( + "%s, get config \"%s\" is \"%s\", return 0 to not enable handle hdmi edid by customer.\n", + __FUNCTION__, CFG_SSM_HDMI_EDID_EN, config_value); + return 0; + } + + return strtoul(config_value, NULL, 10); +} + +int RealHandleHDMIEdid(unsigned char customer_hdmi_edid_buf[]) +{ + int i = 0, dev_fd = -1; + + if (customer_hdmi_edid_buf == NULL) { + return -1; + } + + dev_fd = open("/sys/class/hdmirx/hdmirx0/edid", O_RDWR); + if (dev_fd < 0) { + LOGE("%s, open edid file ERROR(%s)!!\n", CFG_SECTION_TV, strerror(errno)); + return -1; + } + + if (write(dev_fd, customer_hdmi_edid_buf, CC_CUSTOMER_HDMI_EDID_TOTAL_SIZE) + < 0) { + close(dev_fd); + dev_fd = -1; + LOGE("%s, write edid file ERROR(%s)!!\n", CFG_SECTION_TV, strerror(errno)); + + return -1; + } + + close(dev_fd); + dev_fd = -1; + return 0; +} + +int AppendEdidPrefixCode(unsigned char customer_hdmi_edid_buf[], + unsigned char hdmi_edid_buf[]) +{ + if (customer_hdmi_edid_buf == NULL || hdmi_edid_buf == NULL) { + LOGE("%s, Append hdmi edid's prefixCode ERROR(%s)!!\n", CFG_SECTION_TV, + strerror(errno)); + return -1; + } + memset(customer_hdmi_edid_buf, 0, + sizeof(char) * CC_CUSTOMER_HDMI_EDID_TOTAL_SIZE); + customer_hdmi_edid_buf[0] = 'E'; + customer_hdmi_edid_buf[1] = 'D'; + customer_hdmi_edid_buf[2] = 'I'; + customer_hdmi_edid_buf[3] = 'D'; + memcpy(customer_hdmi_edid_buf + 4, hdmi_edid_buf, + CC_CUSTOMER_HDMI_EDID_TOTAL_SIZE - 4); + + return 0; +} + +/**************************** end hdmi edid static functions ****************************/ + +/**************************** start critical data op functions ****************************/ +#define CC_OP_TYPE_READ (0) +#define CC_OP_TYPE_SAVE (1) +#define CC_DATA_TYPE_CHAR (0) +#define CC_DATA_TYPE_INT (1) + +typedef int (*op_fun_ptr)(char *, int, int, unsigned char *); + +typedef struct tagRWDataInfo { + int op_type; + int data_type; + int max_size; + int rw_off; + int rw_size; + void *data_buf; + char *path_cfg_name; + char *off_cfg_name; + op_fun_ptr op_cb; +} RWDataInfo; + +static int GetFilePathCFG(char *key_str, char path_buf[]) +{ + int tmp_ret = 0; + const char *cfg_value; + + path_buf[0] = '\0'; + cfg_value = config_get_str(CFG_SECTION_TV, key_str, ""); + strcpy(path_buf, cfg_value); +#if 0 + LOGD("%s, get \"%s\" is \"%s\".\n", CFG_SECTION_TV, key_str, path_buf); +#endif + return tmp_ret; +} + +static int GetFileOffsetCFG(char *key_str) +{ + const char *cfg_value; + + cfg_value = config_get_str(CFG_SECTION_TV, key_str, "null"); +#if 0 + LOGD("%s, get \"%s\" is \"%s\".\n", CFG_SECTION_TV, key_str, cfg_value); +#endif + if (strcmp(cfg_value, "null") == 0) { + LOGD("%s, get config \"%s\" is \"%s\", return 0 for default.\n", CFG_SECTION_TV, + key_str, cfg_value); + return 0; + } + + return strtol(cfg_value, NULL, 10); +} + +static int handleDataFilePath(char *file_name, int offset __unused, int nsize __unused, char file_path[] __unused) +{ + if (file_name == NULL) { + LOGE("%s, file_name is NULL!!!\n", CFG_SECTION_TV); + return -1; + } + + return 0; +} + +static int ReadDataFromFile(char *file_name, int offset, int nsize, + unsigned char data_buf[]) +{ + int device_fd = -1; + int tmp_ret = 0; + char *tmp_ptr = NULL; + char file_path[512] = { '\0' }; + + if (data_buf == NULL) { + LOGE("%s, data_buf is NULL!!!\n", CFG_SECTION_TV); + return -1; + } + + tmp_ret = handleDataFilePath(file_name, offset, nsize, file_path); + if (tmp_ret < 0) { + tmp_ptr = NULL; + } else if (tmp_ret == 0) { + tmp_ptr = file_name; + } else if (tmp_ret == 1) { + tmp_ptr = file_path; + } + + if (tmp_ptr == NULL) { + return -1; + } + + device_fd = open(tmp_ptr, O_RDONLY); + if (device_fd < 0) { + LOGE("%s: open file \"%s\" error(%s).\n", CFG_SECTION_TV, file_name, + strerror(errno)); + return -1; + } + + lseek(device_fd, offset, SEEK_SET); + read(device_fd, data_buf, nsize); + + close(device_fd); + device_fd = -1; + + return 0; +} + +static int SaveDataToFile(char *file_name, int offset, int nsize, + unsigned char data_buf[]) +{ + int device_fd = -1; + int i = 0, tmp_ret = 0; + char *tmp_ptr = NULL; + char file_path[512] = { '\0' }; + + if (data_buf == NULL) { + LOGE("%s, data_buf is NULL!!!\n", CFG_SECTION_TV); + return -1; + } + + tmp_ret = handleDataFilePath(file_name, offset, nsize, file_path); + if (tmp_ret < 0) { + tmp_ptr = NULL; + } else if (tmp_ret == 0) { + tmp_ptr = file_name; + } else if (tmp_ret == 1) { + tmp_ptr = file_path; + } + + if (tmp_ptr == NULL) { + return -1; + } + + device_fd = open(tmp_ptr, O_RDWR | O_SYNC); + if (device_fd < 0) { + LOGE("%s: open file \"%s\" error(%s).\n", CFG_SECTION_TV, file_name, + strerror(errno)); + return -1; + } + + lseek(device_fd, offset, SEEK_SET); + write(device_fd, data_buf, nsize); + fsync(device_fd); + + close(device_fd); + device_fd = -1; + + return 0; +} + +static int RealRWData(RWDataInfo *data_info) +{ + int i = 0, file_off = 0; + char file_name[256] = { '\0' }; + + memset(file_name, '\0', 256); + GetFilePathCFG(data_info->path_cfg_name, file_name); +#if 0 + LOGD("%s, file_name is %s.\n", __FUNCTION__, file_name); +#endif + if (strlen(file_name) == 0) { + LOGE("%s, length of file_name is 0!!!\n", CFG_SECTION_TV); + return -2; + } + + if (data_info->rw_off < 0) { + LOGE("%s, data_info->rw_off (%d) is less than 0!!!\n", CFG_SECTION_TV, + data_info->rw_off); + return -1; + } + + if (data_info->rw_off + data_info->rw_size > data_info->max_size) { + LOGE( + "%s, data_info->rw_off + data_info->rw_size (%d) is more than data_info->max_size(%d) !!!\n", + CFG_SECTION_TV, data_info->rw_off + data_info->rw_size, + data_info->max_size); + return -1; + } + + file_off = GetFileOffsetCFG(data_info->off_cfg_name); + if (file_off < 0) { + LOGE("%s, file_off (%d) is less than 0!!!\n", CFG_SECTION_TV, file_off); + return -1; + } + + file_off += data_info->rw_off; + + if (data_info->op_cb(file_name, file_off, data_info->rw_size, + (unsigned char *) data_info->data_buf) < 0) { + return -1; + } + + return 0; +} + +static int HandleRWData(RWDataInfo *data_info) +{ + int i = 0, tmp_ret = 0; + int *tmp_iptr = NULL; + unsigned char *tmp_cptr = NULL; + RWDataInfo tmpInfo; + + if (data_info == NULL) { + return -1; + } + + tmpInfo = *data_info; + + if (data_info->data_type == CC_DATA_TYPE_INT) { + tmp_cptr = new unsigned char[data_info->rw_size]; + if (tmp_cptr != NULL) { + tmpInfo.data_buf = tmp_cptr; + + if (tmpInfo.op_type == CC_OP_TYPE_SAVE) { + tmp_iptr = (int *) data_info->data_buf; + for (i = 0; i < data_info->rw_size; i++) { + tmp_cptr[i] = tmp_iptr[i]; + } + + tmp_ret |= RealRWData(&tmpInfo); + } else { + tmp_ret |= RealRWData(&tmpInfo); + + tmp_iptr = (int *) data_info->data_buf; + for (i = 0; i < data_info->rw_size; i++) { + tmp_iptr[i] = tmp_cptr[i]; + } + } + + delete tmp_cptr; + tmp_cptr = NULL; + + return tmp_ret; + } + } + + return RealRWData(&tmpInfo); +} + +int GetAudioNoLinePointsDataFromFile(int rd_off, int rd_size, + unsigned char data_buf[]) +{ + RWDataInfo tmpInfo; + + tmpInfo.op_type = CC_OP_TYPE_READ; + tmpInfo.data_type = CC_DATA_TYPE_CHAR; + tmpInfo.max_size = 256; + tmpInfo.rw_off = rd_off; + tmpInfo.rw_size = rd_size; + tmpInfo.data_buf = data_buf; + tmpInfo.path_cfg_name = (char *) CS_AUDIO_NOLINEPOINTS_FILE_PATH_CFG; + tmpInfo.off_cfg_name = (char *) CS_AUDIO_NOLINEPOINTS_FILE_OFFSET_CFG; + tmpInfo.op_cb = ReadDataFromFile; + + return HandleRWData(&tmpInfo); +} + +int SaveAudioNoLinePointsDataToFile(int wr_off, int wr_size, + unsigned char data_buf[]) +{ + RWDataInfo tmpInfo; + + tmpInfo.op_type = CC_OP_TYPE_SAVE; + tmpInfo.data_type = CC_DATA_TYPE_CHAR; + tmpInfo.max_size = 256; + tmpInfo.rw_off = wr_off; + tmpInfo.rw_size = wr_size; + tmpInfo.data_buf = data_buf; + tmpInfo.path_cfg_name = (char *) CS_AUDIO_NOLINEPOINTS_FILE_PATH_CFG; + tmpInfo.off_cfg_name = (char *) CS_AUDIO_NOLINEPOINTS_FILE_OFFSET_CFG; + tmpInfo.op_cb = SaveDataToFile; + + return HandleRWData(&tmpInfo); +} + +int GetHDCPKeyFromFile(int rd_off, int rd_size, + unsigned char data_buf[]) +{ + RWDataInfo tmpInfo; + + tmpInfo.op_type = CC_OP_TYPE_READ; + tmpInfo.data_type = CC_DATA_TYPE_CHAR; + tmpInfo.max_size = CC_HDCP_KEY_TOTAL_SIZE; + tmpInfo.rw_off = rd_off; + tmpInfo.rw_size = rd_size; + tmpInfo.data_buf = data_buf; + tmpInfo.path_cfg_name = (char *) CS_HDCP_KEY_FILE_PATH_CFG; + tmpInfo.off_cfg_name = (char *) CS_HDCP_KEY_FILE_OFFSET_CFG; + tmpInfo.op_cb = ReadDataFromFile; + + return HandleRWData(&tmpInfo); +} + +int SaveHDCPKeyToFile(int wr_off, int wr_size, + unsigned char data_buf[]) +{ + RWDataInfo tmpInfo; + + tmpInfo.op_type = CC_OP_TYPE_SAVE; + tmpInfo.data_type = CC_DATA_TYPE_CHAR; + tmpInfo.max_size = CC_HDCP_KEY_TOTAL_SIZE; + tmpInfo.rw_off = wr_off; + tmpInfo.rw_size = wr_size; + tmpInfo.data_buf = data_buf; + tmpInfo.path_cfg_name = (char *) CS_HDCP_KEY_FILE_PATH_CFG; + tmpInfo.off_cfg_name = (char *) CS_HDCP_KEY_FILE_OFFSET_CFG; + tmpInfo.op_cb = SaveDataToFile; + + return HandleRWData(&tmpInfo); +} + +int GetHDMIEdidFromFile(int rd_off, int rd_size, int port, + unsigned char data_buf[]) +{ + RWDataInfo tmpInfo; + + tmpInfo.op_type = CC_OP_TYPE_READ; + tmpInfo.data_type = CC_DATA_TYPE_CHAR; + tmpInfo.max_size = SSM_HDMI_EDID_SIZE; + tmpInfo.rw_off = rd_off; + tmpInfo.rw_size = rd_size; + tmpInfo.data_buf = data_buf; + switch (port) { + case 1: + tmpInfo.path_cfg_name = (char *) CS_HDMI_PORT1_EDID_FILE_PATH_CFG; + break; + case 2: + tmpInfo.path_cfg_name = (char *) CS_HDMI_PORT2_EDID_FILE_PATH_CFG; + break; + case 3: + tmpInfo.path_cfg_name = (char *) CS_HDMI_PORT3_EDID_FILE_PATH_CFG; + break; + case 4: + tmpInfo.path_cfg_name = (char *) CS_HDMI_PORT4_EDID_FILE_PATH_CFG; + break; + default: + LOGE("%s, port is error, =%d\n", CFG_SECTION_TV, port); + tmpInfo.path_cfg_name = (char *) CS_HDMI_EDID_FILE_PATH_CFG; + break; + } + tmpInfo.off_cfg_name = (char *) CS_HDMI_EDID_FILE_OFFSET_CFG; + tmpInfo.op_cb = ReadDataFromFile; + + return HandleRWData(&tmpInfo); +} + +/**************************** end critical data op functions ****************************/ diff --git a/tv/tvserver/libtv/tvsetting/TvKeyData.h b/tv/tvserver/libtv/tvsetting/TvKeyData.h new file mode 100644 index 0000000..5844c39 --- a/dev/null +++ b/tv/tvserver/libtv/tvsetting/TvKeyData.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __TV_KEY_DATA_H__ +#define __TV_KEY_DATA_H__ + +#include <pthread.h> +#include <stdint.h> + +#include <CTvLog.h> + +#define SSM_CR_RGBOGO_LEN (256) +#define SSM_CR_RGBOGO_CHKSUM_LEN (2) +#define SSM_HDMI_PORT_MAX (4) +#define SSM_HDMI_EDID_SIZE (256) + +#if ANDROID_PLATFORM_SDK_VERSION == 19 +#define CS_KEY_DATA_NAME_DEV_PATH "/sys/class/aml_keys/aml_keys/key_name" +#define CS_KEY_DATA_READ_DEV_PATH "/sys/class/aml_keys/aml_keys/key_read" +#define CS_KEY_DATA_WRITE_DEV_PATH "/sys/class/aml_keys/aml_keys/key_write" + +#define CS_MAC_KEY_NAME "mac" +#define CS_BARCODE_KEY_NAME "usid" +#define CS_RX_HDCP_KEY_NAME "rxhdcp20" +#define CS_PROJECT_ID_KEY_NAME "projid" +#endif + +#if ANDROID_PLATFORM_SDK_VERSION >= 21 +#define CS_KEY_DATA_ATTACH_DEV_PATH "/sys/class/unifykeys/attach" +#define CS_KEY_DATA_NAME_DEV_PATH "/sys/class/unifykeys/name" +#define CS_KEY_DATA_READ_DEV_PATH "/sys/class/unifykeys/read" +#define CS_KEY_DATA_WRITE_DEV_PATH "/sys/class/unifykeys/write" + +#define CS_MAC_KEY_NAME "mac" +#define CS_BARCODE_KEY_NAME "usid" +#define CS_RX_HDCP_KEY_NAME "hdcp2_rx" +#define CS_RX_HDCP14_KEY_NAME "hdcp14_rx" +#define CS_PROJECT_ID_KEY_NAME "projid" +#endif + +#define CC_MAX_KEY_DATA_SIZE (2048) +#define CC_MAX_FILE_PATH (256) + +#define CC_MAC_LEN (6) +#define CC_HDCP_KEY_TOTAL_SIZE (368) +#define CC_HDCP_KEY_HEAD_SIZE (40) +#define CC_HDCP_KEY_CONTENT_SIZE (CC_HDCP_KEY_TOTAL_SIZE - CC_HDCP_KEY_HEAD_SIZE) + +#define CC_CUSTOMER_HDMI_EDID_TOTAL_SIZE (SSM_HDMI_EDID_SIZE + 4) + +#define CS_MAC_ADDRESS_STARTWRK_EN_CFG "ssm.macaddr.startwork.en" +#define CS_BARCODE_LEN_CFG "ssm.barcode.len" + +#define CS_HDCP_KEY_EN_CFG "ssm.handle.hdcpkey.en" +#define CS_HDCP_KEY_DEMO_EN_CFG "ssm.handle.hdcpkey.demo.en" +#define CS_HDCP_KEY_FILE_PATH_CFG "ssm.handle.hdcpkey.file.path" +#define CS_HDCP_KEY_FILE_OFFSET_CFG "ssm.handle.hdcpkey.file.offset" + + +//#define CS_HDMI_EDID_EN_CFG "ssm.handle.hdmi.edid.en" +#define CS_HDMI_EDID_USE_CFG "ssm.handle.hdmi.edid.use" +#define CS_HDMI_EDID_FILE_PATH_CFG "ssm.handle.hdmi.edid.file.path" +#define CS_HDMI_PORT1_EDID_FILE_PATH_CFG "ssm.handle.hdmi.port1.edid.file.path" +#define CS_HDMI_PORT2_EDID_FILE_PATH_CFG "ssm.handle.hdmi.port2.edid.file.path" +#define CS_HDMI_PORT3_EDID_FILE_PATH_CFG "ssm.handle.hdmi.port3.edid.file.path" +#define CS_HDMI_PORT4_EDID_FILE_PATH_CFG "ssm.handle.hdmi.port4.edid.file.path" + +#define CS_HDMI_EDID_FILE_OFFSET_CFG "ssm.handle.hdmi.edid.file.offset" + +#define CS_AUDIO_NOLINEPOINTS_FILE_PATH_CFG "ssm.audio.nolinepoints.file.path" +#define CS_AUDIO_NOLINEPOINTS_FILE_OFFSET_CFG "ssm.audio.nolinepoints.file.offset" +int ReadKeyData(const char *key_name, unsigned char data_buf[]); +int WriteKeyData(const char *key_name, int wr_size, char data_buf[]); + +int KeyData_SaveProjectID(int rw_val); +int KeyData_ReadProjectID(); + +int KeyData_GetMacAddressDataLen(); +int KeyData_ReadMacAddress(unsigned char data_buf[]); +int KeyData_SaveMacAddress(unsigned char data_buf[]); + +int KeyData_GetBarCodeDataLen(); +int KeyData_ReadBarCode(unsigned char data_buf[]); +int KeyData_SaveBarCode(unsigned char data_buf[]); + +int SSMReadHDCPKey(unsigned char hdcp_key_buf[]); +int SSMSaveHDCPKey(unsigned char hdcp_key_buf[]); +int SSMSetHDCPKey(); +int SSMGetHDCPKeyDataLen(); +int SSMRefreshHDCPKey(); + + +int SSMReadHDMIEdid(int port, unsigned char hdmi_edid_buf[]); +int SSMSetHDMIEdid(int port); + +int SSMReadAudioNoLinePoints(int offset, int size, unsigned char tmp_buf[]); +int SSMSaveAudioNoLinePoints(int offset, int size, unsigned char tmp_buf[]); +int CreateMacAddressStartWorkThread(); + +int GetSSMHandleHDCPKeyEnableCFG(); +int GetSSMHandleHDCPKeyDemoEnableCFG(); +int SSMSetDefaultHDCPKey(unsigned char hdcp_key_buf[]); +int RealHandleHDCPKey(unsigned char hdcp_key_buf[]); +int GetHDCPKeyFromFile(int rd_off, int rd_size, unsigned char data_buf[]); +int SaveHDCPKeyToFile(int wr_off, int wr_size, unsigned char data_buf[]); + +int GetHDMIEdidFromFile(int rd_off, int rd_size, int port, unsigned char data_buf[]); +int RealHandleHDMIEdid(unsigned char hdmi_edid_buf[]); +int GetSSMHandleHDMIEdidByCustomerEnableCFG(); +int AppendEdidPrefixCode(unsigned char customer_hdmi_edid_buf[], unsigned char hdmi_edid_buf[]); + +int GetAudioNoLinePointsDataFromFile(int offset, int size, unsigned char data_buf[]); +int SaveAudioNoLinePointsDataToFile(int offset, int size, unsigned char data_buf[]); + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif //__TV_KEY_DATA_H__ diff --git a/tv/tvserver/libtv/tvsetting/audio_cfg.cpp b/tv/tvserver/libtv/tvsetting/audio_cfg.cpp new file mode 100644 index 0000000..4347330 --- a/dev/null +++ b/tv/tvserver/libtv/tvsetting/audio_cfg.cpp @@ -0,0 +1,747 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "audio_cfg" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <android/log.h> +#include <cutils/properties.h> + +#include "../tvsetting/CTvSetting.h" +#include <tvconfig.h> +#include "audio_cfg.h" +#include "../audio/audio_alsa.h" +#include "CTvLog.h" + +static const char AudioAmpMainVolLutBaseNameTable[CC_GET_TYPE_CNT][128] = {"audio.amp.mainvol.tv.lutbuf",//0 + "audio.amp.mainvol.av.lutbuf",//1 + "audio.amp.mainvol.comp.lutbuf",//2 + "audio.amp.mainvol.hdmi.lutbuf",//3 + "audio.amp.mainvol.vga.lutbuf",//4 + "audio.amp.mainvol.mpeg.lutbuf",//5 + "audio.amp.mainvol.hdmi4k2k.lutbuf",//6 + "audio.amp.mainvol.usb4k2k.lutbuf"//7 + }; + +static const int Default_EQGain_Table[24] = { + // + 50, 50, 50, 50, 50, 50, // SM_STD + 70, 60, 50, 60, 70, 50, // SM_MUSIC + 25, 50, 70, 66, 25, 50, // SM_NEWS + 75, 65, 50, 65, 75, 50, // SM_THEATER +}; + +static const int Default_AVoutGain_Table[9] = { + //PGA_IN ADC_Capture DAC_Playback + 11, 92, 255, // CC_AUDIO_IN_SOURCE_LINEIN + 11, 92, 255, //CC_AUDIO_IN_SOURCE_HDMI + 11, 92, 255, //CC_AUDIO_IN_SOURCE_ATV +}; + +int GetAudioAmpMasterNolinePointData(int get_type, const char *value_buf, int data_buf[]) +{ + const char *config_value; + if (value_buf != NULL) { + config_value = config_get_str(CFG_SECTION_TV, value_buf, "null"); + } else { + switch (get_type) { + case CC_GET_LUT_TV: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.master.noline.point.data.tv", "null"); + } + break; + case CC_GET_LUT_AV: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.master.noline.point.data.av", "null"); + } + break; + case CC_GET_LUT_COMP: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.master.noline.point.data.comp", "null"); + } + break; + case CC_GET_LUT_HDMI: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.master.noline.point.data.hdmi", "null"); + } + break; + case CC_GET_LUT_VGA: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.master.noline.point.data.vga", "null"); + } + break; + case CC_GET_LUT_MPEG: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.master.noline.point.data.mpeg", "null"); + } + break; + case CC_GET_LUT_HDMI_4K2K: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.master.noline.point.data.hdmi4k2k", "null"); + } + break; + case CC_GET_LUT_USB_4K2K: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.master.noline.point.data.usb4k2k", "null"); + } + break; + default: { + config_value = "null"; + } + break; + } + } + if (strcasecmp(config_value, "null") == 0) { + //LOGE("%s, can't get config \"%s\"!!!\n", CFG_SECTION_TV, key_str); + return -1; + } + + char *pSave; + char data_str[CC_CFG_VALUE_STR_MAX_LEN] = { 0 }; + + memset((void *)data_str, 0, sizeof(data_str)); + strncpy(data_str, config_value, sizeof(data_str) - 1); + char *token = strtok_r(data_str, ",", &pSave); + int bufferDataIndex = 0; + while (token != NULL) { + data_buf[bufferDataIndex] = strtol(token, NULL, 10); + bufferDataIndex ++; + token = strtok_r(NULL, ",", &pSave); + } + + return 0; +} + +int GetDefault_EQGain_Table(int *EqTable) +{ + memcpy(EqTable, Default_EQGain_Table, sizeof(Default_EQGain_Table)); + + return 0; +} + +int GetAudioEQPresetBufferPtr(int *EqTable) +{ + int bufs_count = 0, buf_item_count = 0; + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.eq.presetbuf", "null"); + if (strcasecmp(config_value, "null") == 0) { + return -1; + } + + char *pSave; + char data_str[CC_CFG_VALUE_STR_MAX_LEN] = { 0 }; + + memset((void *)data_str, 0, sizeof(data_str)); + strncpy(data_str, config_value, sizeof(data_str) - 1); + char *token = strtok_r(data_str, ",", &pSave); + int allIndex = 0, bufferDataIndex = 0; + while (token != NULL) { + if (allIndex == 0) { + bufs_count = strtol(token, NULL, 10); + } else if (allIndex == 1) { + buf_item_count = strtol(token, NULL, 10); + } else if (allIndex >= 2) { + EqTable[bufferDataIndex] = strtol(token, NULL, 10); + bufferDataIndex ++; + } + + token = strtok_r(NULL, ",", &pSave); + allIndex ++; + } + + return 0; +} + +/** + * @param:get_type + * @return:data_buf + */ +const char *GetAudioAmpMainvolTableBaseName(int get_type) +{ + return AudioAmpMainVolLutBaseNameTable[get_type]; +} + +int GetAudioAmpMainvolBuf(const char *TableKeyName, int data_buf[]) +{ + int bufs_count = 0, buf_item_count = 0; + const char *config_value; + + config_value = config_get_str(CFG_SECTION_TV, TableKeyName, "null"); + if (strcasecmp(config_value, "null") == 0) { + return -1; + } + char *pSave; + char data_str[CC_CFG_VALUE_STR_MAX_LEN] = { 0 }; + memset((void *)data_str, 0, sizeof(data_str)); + strncpy(data_str, config_value, sizeof(data_str) - 1); + char *token = strtok_r(data_str, ",", &pSave); + int allIndex = 0, bufferDataIndex = 0; + while (token != NULL) { + if (allIndex == 0) { + bufs_count = strtol(token, NULL, 10); + } else if (allIndex == 1) { + buf_item_count = strtol(token, NULL, 10); + } else if (allIndex >= 2) { + data_buf[bufferDataIndex] = strtol(token, NULL, 10); + bufferDataIndex ++; + } + token = strtok_r(NULL, ",", &pSave); + allIndex ++; + } + + return 0; +} + +/** + * @param:get_type + * @return:data_buf + */ +int GetAudioAmpSupbassvolBuf(int get_type, int data_buf[]) +{ + int bufs_count = 0, buf_item_count = 0; + const char *config_value; + + switch (get_type) { + case CC_GET_LUT_TV: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.supbassvol.tv.lutbuf", "null"); + } + + break; + case CC_GET_LUT_AV: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.supbassvol.av.lutbuf", "null"); + } + break; + case CC_GET_LUT_COMP: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.supbassvol.comp.lutbuf", "null"); + } + break; + case CC_GET_LUT_HDMI: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.supbassvol.hdmi.lutbuf", "null"); + } + break; + case CC_GET_LUT_VGA: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.supbassvol.vga.lutbuf", "null"); + } + + break; + case CC_GET_LUT_MPEG: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.supbassvol.mpeg.lutbuf", "null"); + } + + break; + case CC_GET_LUT_HDMI_4K2K: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.supbassvol.hdmi4k2k.lb.name", "null"); + } + + break; + case CC_GET_LUT_USB_4K2K: { + config_value = config_get_str(CFG_SECTION_TV, "audio.amp.supbassvol.usb4k2k.lb.name", "null"); + } + + break; + default: { + config_value = "null"; + } + break; + } + + if (strcasecmp(config_value, "null") == 0) { + return -1; + } + char *pSave; + char data_str[CC_CFG_VALUE_STR_MAX_LEN] = { 0 }; + memset((void *)data_str, 0, sizeof(data_str)); + strncpy(data_str, config_value, sizeof(data_str) - 1); + char *token = strtok_r(data_str, ",", &pSave); + int allIndex = 0, bufferDataIndex = 0; + while (token != NULL) { + if (allIndex == 0) { + bufs_count = strtol(token, NULL, 10); + } else if (allIndex == 1) { + buf_item_count = strtol(token, NULL, 10); + } else if (allIndex >= 2) { + data_buf[bufferDataIndex] = strtol(token, NULL, 10); + bufferDataIndex ++; + } + token = strtok_r(NULL, ",", &pSave); + allIndex ++; + } + + return 0; +} + +int GetAudioAmplifierMasterNoLineSwitchFlag() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.amp.master.noline.switch", "null"); + + if (strcmp(config_value, "null") == 0) { + return 0; + } + + return strtol(config_value, NULL, 10); +} + +int GetAudioAmplifierSupperBassNoLineSwitchFlag() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.amp.supperbass.noline.switch", "null"); + + if (strcmp(config_value, "null") == 0) { + return 0; + } + + return strtol(config_value, NULL, 10); +} + +int GetAudioAmplifierMasterNoLinePointsCount() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.amp.master.noline.point.cnt", "null"); + + if (strcmp(config_value, "null") == 0) { + return 11; + } + + return strtol(config_value, NULL, 10); +} + +int GetAudioAmplifierSupperBassNoLinePointsCount() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.amp.supperbass.noline.point.cnt", "null"); + + if (strcmp(config_value, "null") == 0) { + return 5; + } + + return strtol(config_value, NULL, 10); +} + +int GetAudioAmplifierBalanceExchangeCFG() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.amp.balance.exchg", "null"); + + // if (data_buf[0] >= 0 && data_buf[0] <= 100) { + // LOGD("%s, we have get the index buffer.\n", CFG_SECTION_TV); + // return 0; + // } + + if (strcmp(config_value, "null") == 0) { + return 0; //return 0 to disable balance exchange + } + + return strtol(config_value, NULL, 10); +} + +int GetAudioMainVolLutBufCFGIndexModifyEnable() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.amp.master.cfgindex.mod.en", "null"); + + if (strcmp(config_value, "null") == 0) { + return 0; + } + + return strtoul(config_value, NULL, 10); +} + +int GetAudioMainVolLutBufNameModifyUbootenvCFG() +{ + char config_value[PROPERTY_VALUE_MAX]; + + memset(config_value, '\0', 32); + getBootEnv(UBOOTENV_AMPINDEX, config_value, "null"); + + if (strcasecmp(config_value, "null") == 0) { + return 0; + } + + return strtoul(config_value, NULL, 10); +} + + +int GetAudioMainVolLutBufNameModifyEnableCFG() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.amp.mainvol.lutbufname.mod.en", "null"); + + if (strcmp(config_value, "null") == 0) { + return 0; + } + + return strtoul(config_value, NULL, 10); +} + + +int GetAudioSupperBassVolLutBufCFGIndexModifyEnable() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.amp.supperbass.cfgindex.mod.en", "null"); + + if (strcmp(config_value, "null") == 0) { + return 0; + } + + return strtoul(config_value, NULL, 10); +} + +int GetAudioSupperBassVolLutBufNameModifyEnableCFG() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.amp.supbassvol.lutbufname.mod.en", "null"); + + if (strcmp(config_value, "null") == 0) { + return 0; + } + + return strtoul(config_value, NULL, 10); +} + + +int GetAudioDVISupportEnable() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.dvi.support.enable", "null"); + + if (strcmp(config_value, "null") == 0) { + return 0; + } + + return strtoul(config_value, NULL, 10); +} + + +int GetTvAudioCardName(char tv_card_name_buf[]) +{ + const char *value = config_get_str(CFG_SECTION_TV, "audio.tv.card.name", "null"); + + strcpy(tv_card_name_buf, value); + if (strcmp(value, "null") == 0) { + strcpy(tv_card_name_buf, "AMLSYNO9629"); + } + + return 0; +} + +int GetTvAudioCardNeedSet() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.tv.card.needset", "null"); + if (strcmp(config_value, "null") == 0) { + return 0; + } + + if (strtoul(config_value, NULL, 10) == 0) { + return 0; + } + + return 1; +} + +int GetAudioEffectAmplifierGainCfg(const char *cfg_name, int def_gain_val, int max_gain_val) +{ + int tmp_val; + const char *config_value = config_get_str(CFG_SECTION_TV, cfg_name, "null"); + if (strcmp(config_value, "null") == 0) { + tmp_val = def_gain_val; + } else { + tmp_val = strtoul(config_value, NULL, 10); + if (tmp_val < 0 || tmp_val > max_gain_val) { + tmp_val = def_gain_val; + } + } + LOGD("%s = %d\n", cfg_name, tmp_val); + return tmp_val; +} + + +int GetAudioSRSSourroundEnableCFG() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.srs.sourround.enable", "null"); + + if (strcmp(config_value, "null") == 0) { + return 0; + } + + return strtoul(config_value, NULL, 10); +} + +int GetAudioSRSGainCfg(const char *cfg_name, int def_gain_val) +{ + int tmp_val = 0; + const char *config_value = config_get_str(CFG_SECTION_TV, cfg_name, "null"); + + if (strcmp(config_value, "null") == 0) { + tmp_val = def_gain_val; + } else { + if (tmp_val < 0 || tmp_val > 100) { + tmp_val = def_gain_val; + LOGE("Error setting: %s = %d (0~100)\n", cfg_name, tmp_val); + } + tmp_val = strtoul(config_value, NULL, 10); + } + //LOGD(" %s = %d\n", cfg_name, tmp_val); + return tmp_val; +} + +int GetAudioSRSSupperBassTrubassSpeakerSizeCfg() +{ + char cfg_name[128] = { 0 }; + + strcpy(cfg_name, CFG_AUDIO_SRS_TRUBASS_SPEAKERSIZE); + + const char *config_value = config_get_str(CFG_SECTION_TV, cfg_name, "null"); + + if (strcmp(config_value, "null") == 0) { + return -1; + } + + int tmp_val = strtoul(config_value, NULL, 10); + if (tmp_val < 0 || tmp_val > 7) { + tmp_val = -1; + } + + return tmp_val; +} + +int GetAudioDumpDataEnableFlagCfg() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.dump.data.en", "null"); + + if (strcmp(config_value, "null") == 0) { + return 0; + } + + return strtol(config_value, NULL, 10); +} + +int GetAudioSupperBassSwitchDisableCFG() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.supperbass.switch.disable", "null"); + + if (strcmp(config_value, "null") == 0) { + return 0; + } + + return strtoul(config_value, NULL, 10); +} + +int GetAudioWallEffectTypeCfg() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.walleffect.type", "null"); + + if (strcmp(config_value, "null") == 0) { + return 0; + } + + return strtol(config_value, NULL, 10); +} + +int Get2d4gHeadsetEnable() +{ + const char *config_value = config_get_str ( CFG_SECTION_TV, "tvin.2d4G.headset.en", "null" ); + if (strcmp(config_value, "enable") == 1) { + return 1; + } + + + return 0; +} + +int GetUseAndroidVolEnable() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.android.vol.en", "null"); + if (!strcmp(config_value, "enable")) { + return 1; + } + return 0; +} + +const char *GetAudExtDacLibPath() +{ + return config_get_str(CFG_SECTION_TV, "audio.external.dac.libpath", "/vendor/lib/libdac.so"); +} + +int GetKaraokAvEnable() +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.switch.karaok.av.enable", "null"); + if (strtoul(config_value, NULL, 10) == 1) + return 1; + + return 0; +} + +int GetDefaultAvOutGainBuf(int *nAvoutTable) +{ + memcpy(nAvoutTable, Default_AVoutGain_Table, sizeof(Default_AVoutGain_Table)); + + return 0; +} + +int GetAvOutGainBuf_Cfg(int *nAvoutTable) +{ + int bufs_count = 0, buf_item_count = 0; + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.avoutgain.presetbuf", "null"); + if (strcasecmp(config_value, "null") == 0) { + // LOGE("%s, can't get config \"%s\"!!!\n", CFG_SECTION_TV, key_str); + return -1; + } + + char *pSave; + char data_str[CC_CFG_VALUE_STR_MAX_LEN] = { 0 }; + + memset((void *)data_str, 0, sizeof(data_str)); + strncpy(data_str, config_value, sizeof(data_str) - 1); + char *token = strtok_r(data_str, ",", &pSave); + int allIndex = 0, bufferDataIndex = 0; + while (token != NULL) { + if (allIndex == 0) { + bufs_count = strtol(token, NULL, 10); + } else if (allIndex == 1) { + buf_item_count = strtol(token, NULL, 10); + } else if (allIndex >= 2) { + nAvoutTable[bufferDataIndex] = strtol(token, NULL, 10); + bufferDataIndex ++; + } + + token = strtok_r(NULL, ",", &pSave); + allIndex ++; + } + + return 0; +} + +int GetADCDigitalCaptureVol_Cfg(void) +{ + int capture_vol = 0; + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.adc.digital.capture.vol", "null"); + + if (strcmp(config_value, "null") == 0) { + return -1; + } + + return strtoul(config_value, NULL, 10); +} + +int GetAudioInternalDacPGAInGain_Cfg(void) +{ + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.internal.dac.pga_in.gain", "null"); + + if (strcmp(config_value, "null") == 0) { + return 16; + } + + return strtol(config_value, NULL, 10); +} + +int GetAudioInternalDACDigitalPlayBackVolume_Cfg(int audio_src_in_type) +{ + const char *config_value = NULL; + + if (audio_src_in_type == CC_AUDIO_IN_SOURCE_HDMI) { // CC_AUDIO_IN_SOURCE_HDMI + config_value = config_get_str(CFG_SECTION_TV, "audio.internal.dac.playback.volume_hdmi", "null"); + } else if (audio_src_in_type == CC_AUDIO_IN_SOURCE_LINEIN) { // CC_AUDIO_IN_SOURCE_LINEIN + config_value = config_get_str(CFG_SECTION_TV, "audio.internal.dac.playback.volume_linein", "null"); + } else if (audio_src_in_type == CC_AUDIO_IN_SOURCE_ATV) { // CC_AUDIO_IN_SOURCE_ATV + config_value = config_get_str(CFG_SECTION_TV, "audio.internal.dac.playback.volume_atv", "null"); + } else if (audio_src_in_type == CC_AUDIO_IN_SOURCE_SPDIFIN) { // CC_AUDIO_IN_SOURCE_SPDIFIN + config_value = config_get_str(CFG_SECTION_TV, "audio.internal.dac.playback.volume_hdmi", "null"); + } + + if (strcmp(config_value, "null") == 0) { + return 255; + } + + return strtol(config_value, NULL, 10); +} + +int GetAudioOutputSwapStatus(tv_source_input_t source_input) +{ + int sw_status = 0; + const char *config_value = config_get_str(CFG_SECTION_TV, "audio.output.swap.enable", "null"); + if ( strcmp ( config_value, "enable" ) == 0 ) { + switch (source_input) { + case SOURCE_AV1: + config_value = config_get_str(CFG_SECTION_TV, "audio.output.swap.av1", "null"); + break; + case SOURCE_AV2: + config_value = config_get_str(CFG_SECTION_TV, "audio.output.swap.av2", "null"); + break; + case SOURCE_HDMI1: + config_value = config_get_str(CFG_SECTION_TV, "audio.output.swap.hdmi1", "null"); + break; + case SOURCE_HDMI2: + config_value = config_get_str(CFG_SECTION_TV, "audio.output.swap.hdmi2", "null"); + break; + case SOURCE_HDMI3: + config_value = config_get_str(CFG_SECTION_TV, "audio.output.swap.hdmi3", "null"); + break; + case SOURCE_HDMI4: + config_value = config_get_str(CFG_SECTION_TV, "audio.output.swap.hdmi4", "null"); + break; + case SOURCE_TV: + config_value = config_get_str(CFG_SECTION_TV, "audio.output.swap.tv", "null"); + break; + case SOURCE_DTV: + config_value = config_get_str(CFG_SECTION_TV, "audio.output.swap.dtv", "null"); + break; + case SOURCE_MPEG: + config_value = config_get_str(CFG_SECTION_TV, "audio.output.swap.mpeg", "null"); + break; + default: + break; + } + + } + + sw_status = atoi ( config_value ); + return sw_status; +} + +int GetAudioArchitectureTypeCFG() +{ + static int architecture_type = -1; + const char *config_value = NULL; + + config_value = config_get_str ( CFG_SECTION_TV, "audio.architecture.type", "null" ); + if (strcasecmp(config_value, "null") == 0) { + architecture_type = CC_DAC_G9TV_EXTERNAL_DAC_OFF_BOARD_FBC; + } else if ((strcasecmp(config_value, "t866_external_dac_offboard_fbc") == 0) || (strcasecmp(config_value, "g9tv_external_dac_offboard_fbc") == 0)) { + architecture_type = CC_DAC_G9TV_EXTERNAL_DAC_OFF_BOARD_FBC; + } else if ((strcasecmp(config_value, "t866_external_dac_offboard_customer_lib") == 0) || (strcasecmp(config_value, "g9tv_external_dac_customer_lib") == 0)) { + architecture_type = CC_DAC_G9TV_EXTERNAL_DAC_CUSTOMER_LIB; + } else if ((strcasecmp(config_value, "t866_external_dac_offboard_digital") == 0) || (strcasecmp(config_value, "g9tv_external_dac_digital") == 0)) { + architecture_type = CC_DAC_G9TV_EXTERNAL_DAC_DIGITAL; + } else if ((strcasecmp(config_value, "t866_external_dac_onboard") == 0) || (strcasecmp(config_value, "g9tv_external_dac_onboard") == 0)) { + architecture_type = CC_DAC_G9TV_EXTERNAL_DAC_ON_BOARD; + } else if ((strcasecmp(config_value, "t866_iternal_dac") == 0) || (strcasecmp(config_value, "g9tv_iternal_dac") == 0)) { + architecture_type = CC_DAC_G9TV_INTERNAL_DAC; + } + + return architecture_type; +} + +static int gAudioResampleType = -1; +int GetAudioResampleTypeCFG() +{ + char *token = NULL; + const char *strDelimit = ","; + const char *config_value = NULL; + char cfg_buf[1024]; + + if (gAudioResampleType == -1) { + gAudioResampleType = 0; + + char *pSave; + config_value = config_get_str ( CFG_SECTION_TV, "audio.resample.type", "null" ); + strncpy(cfg_buf, config_value, sizeof(cfg_buf)); + if (strcmp(cfg_buf, "") != 0) { + token = strtok_r(cfg_buf, strDelimit, &pSave); + while (token != NULL) { + if (strcasecmp(token, "hw") == 0) { + gAudioResampleType |= CC_AUD_RESAMPLE_TYPE_HW; + } else if (strcasecmp(token, "sw") == 0) { + gAudioResampleType |= CC_AUD_RESAMPLE_TYPE_SW; + } + + token = strtok_r(NULL, strDelimit, &pSave); + } + } else { + gAudioResampleType = CC_AUD_RESAMPLE_TYPE_SW; //if can't find config string, allow sw resample + } + } + + return gAudioResampleType; +} + diff --git a/tv/tvserver/libtv/tvsetting/audio_cfg.h b/tv/tvserver/libtv/tvsetting/audio_cfg.h new file mode 100644 index 0000000..7630004 --- a/dev/null +++ b/tv/tvserver/libtv/tvsetting/audio_cfg.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __TV_AUDIO_CFG_H__ +#define __TV_AUDIO_CFG_H__ + +#include <tvconfig.h> +#include <tvutils.h> + +#include "../tvin/CTvin.h" + +#define CC_GET_LUT_TV (0) +#define CC_GET_LUT_AV (1) +#define CC_GET_LUT_COMP (2) +#define CC_GET_LUT_HDMI (3) +#define CC_GET_LUT_VGA (4) +#define CC_GET_LUT_MPEG (5) +#define CC_GET_LUT_HDMI_4K2K (6) +#define CC_GET_LUT_USB_4K2K (7) +#define CC_GET_TYPE_CNT (8) + +#define CC_DAC_G9TV_EXTERNAL_DAC_ON_BOARD (1) +#define CC_DAC_G9TV_EXTERNAL_DAC_OFF_BOARD_FBC (2) +#define CC_DAC_G9TV_EXTERNAL_DAC_CUSTOMER_LIB (3) +#define CC_DAC_G9TV_EXTERNAL_DAC_DIGITAL (4) +#define CC_DAC_G9TV_INTERNAL_DAC (5) + +#define CC_AUD_RESAMPLE_TYPE_HW (1) +#define CC_AUD_RESAMPLE_TYPE_SW (2) + +int GetAudioAmpMasterNolinePointData(int get_type, const char *value_buf, int data_buf[]); +int GetAudioEQPresetBufferPtr(int * ); +int GetAudioAmpMainvolBuf(const char *TableKeyName, int data_buf[]); +int GetAudioAmpSupbassvolBuf(int get_type, int data_buf[]); +int GetAudioAmplifierMasterNoLineSwitchFlag(); +int GetAudioAmplifierMasterNoLinePointsCount(); +int GetAudioSupperBassSwitchDisableCFG(); +int GetAudioAmplifierSupperBassNoLineSwitchFlag(); +int GetAudioAmplifierSupperBassNoLinePointsCount(); +int GetAudioAmplifierBalanceExchangeCFG(); +int GetAudioMainVolLutBufNameModifyUbootenvCFG(); +int GetAudioMainVolLutBufNameModifyEnableCFG(); +int GetAudioSupperBassVolLutBufNameModifyEnableCFG(); + +int GetAudioDVISupportEnable(); +int GetTvAudioCardName(char tv_card_name_buf[]); +int GetTvAudioCardNeedSet(); +int GetAudioDumpDataEnableFlagCfg(); +int GetAudioWallEffectTypeCfg(); + +//srs user setting +int GetAudioSRSSourroundEnableCFG(); +int GetAudioSRSGainCfg(const char *cfg_name, int def_gain_val); +int GetAudioEffectAmplifierGainCfg(const char *cfg_name, int def_gain_val, int max_gain_val); +int GetAudioSRSSupperBassTrubassSpeakerSizeCfg(); +//tinymix control +int Get2d4gHeadsetEnable() ; +int GetUseAndroidVolEnable(); +int GetAudioOutputSwapStatus(tv_source_input_t source_input); +//hardware design +int GetAudioArchitectureTypeCFG(); +const char *GetAudExtDacLibPath(); +int GetAudioResampleTypeCFG(); +int GetKaraokAvEnable(); +//audio path gain setting by user +int GetADCDigitalCaptureVol_Cfg(void); +int GetAudioInternalDacPGAInGain_Cfg(void); +int GetAudioInternalDACDigitalPlayBackVolume_Cfg(int audio_src_in_type); +const char *GetAudioAmpMainvolTableBaseName(int get_type); +int GetDefault_EQGain_Table(int *EqTable); +int GetDefaultAvOutGainBuf(int *nAvoutTable); +int GetAvOutGainBuf_Cfg(int *nAvoutTable); + +#endif //__TV_AUDIO_CFG_H__ diff --git a/tv/tvserver/libtv/version/version.cpp b/tv/tvserver/libtv/version/version.cpp new file mode 100644 index 0000000..7ee8e54 --- a/dev/null +++ b/tv/tvserver/libtv/version/version.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "version" + +#include <stdio.h> +#include <string.h> +#include <android/log.h> + +#include "version.h" + +static char gitversionstr[256] = "N/A"; + +static int tvservice_version_info_init(void) +{ + static int info_is_inited = 0; + int dirty_num = 0; + + if (info_is_inited > 0) { + return 0; + } + info_is_inited++; + +#ifdef HAVE_VERSION_INFO + +#ifdef LIBTVSERVICE_GIT_UNCOMMIT_FILE_NUM +#if LIBTVSERVICE_GIT_UNCOMMIT_FILE_NUM>0 + dirty_num = LIBTVSERVICE_GIT_UNCOMMIT_FILE_NUM; +#endif +#endif + +#ifdef LIBTVSERVICE_GIT_VERSION + if (dirty_num > 0) { + snprintf(gitversionstr, 250, "%s-with-%d-dirty-files", LIBTVSERVICE_GIT_VERSION, dirty_num); + } else { + snprintf(gitversionstr, 250, "%s", LIBTVSERVICE_GIT_VERSION); + } +#endif + +#endif + + return 0; +} + +const char *tvservice_get_git_version_info(void) +{ + tvservice_version_info_init(); + return gitversionstr; +} + +const char *tvservice_get_last_chaned_time_info(void) +{ +#ifdef HAVE_VERSION_INFO +#ifdef LIBTVSERVICE_LAST_CHANGED + return LIBTVSERVICE_LAST_CHANGED; +#endif +#endif + return " Unknow "; +} + +const char *tvservice_get_git_branch_info(void) +{ +#ifdef HAVE_VERSION_INFO +#ifdef LIBTVSERVICE_GIT_BRANCH + return LIBTVSERVICE_GIT_BRANCH; +#endif +#endif + return " Unknow "; +} + +const char *tvservice_get_build_time_info(void) +{ +#ifdef HAVE_VERSION_INFO +#ifdef LIBTVSERVICE_BUILD_TIME + return LIBTVSERVICE_BUILD_TIME; +#endif +#endif + return " Unknow "; +} + +const char *tvservice_get_build_name_info(void) +{ +#ifdef HAVE_VERSION_INFO +#ifdef LIBTVSERVICE_BUILD_NAME + return LIBTVSERVICE_BUILD_NAME; +#endif +#endif + return " Unknow "; +} + +const char *tvservice_get_board_version_info(void) +{ +#ifdef HAVE_VERSION_INFO +#ifdef TVAPI_BOARD_VERSION + return TVAPI_BOARD_VERSION; +#endif +#endif + return " Unknow "; +} diff --git a/tv/tvserver/libtv/version/version.h b/tv/tvserver/libtv/version/version.h new file mode 100644 index 0000000..e96345c --- a/dev/null +++ b/tv/tvserver/libtv/version/version.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __LIBTVSERVICE_VERSION_H__ +#define __LIBTVSERVICE_VERSION_H__ + +extern const char *tvservice_get_git_version_info(void); +extern const char *tvservice_get_last_chaned_time_info(void); +extern const char *tvservice_get_git_branch_info(void); +extern const char *tvservice_get_build_time_info(void); +extern const char *tvservice_get_build_name_info(void); +extern const char *tvservice_get_board_version_info(void); + +#endif //__LIBTVSERVICE_VERSION_H__ diff --git a/tv/tvserver/libtv/vpp/CVpp.cpp b/tv/tvserver/libtv/vpp/CVpp.cpp new file mode 100644 index 0000000..6e38abf --- a/dev/null +++ b/tv/tvserver/libtv/vpp/CVpp.cpp @@ -0,0 +1,1294 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CVpp" + +#include "CVpp.h" +#include <CTvLog.h> +#include "../tvsetting/CTvSetting.h" +#include <cutils/properties.h> +#include <math.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <string.h> +#include <pthread.h> +#include <errno.h> +#include <dlfcn.h> +#include "CTvLog.h" +#include <tvconfig.h> +#include "CAv.h" +#include "../tvin/CHDMIRxManager.h" + + +#define PI 3.14159265358979 + +CVpp *CVpp::mInstance; +CVpp *CVpp::getInstance() +{ + if (NULL == mInstance) mInstance = new CVpp(); + return mInstance; +} + +CVpp::CVpp() +{ + fbcIns = GetSingletonFBC(); +} + +CVpp::~CVpp() +{ + +} + +int CVpp::Vpp_Init(bool hdmiOutFbc) +{ + int ret = -1; + int backlight = DEFAULT_BACKLIGHT_BRIGHTNESS; + int offset_r = 0, offset_g = 0, offset_b = 0, gain_r = 1024, gain_g = 1024, gain_b = 1024; + + mHdmiOutFbc = hdmiOutFbc; + + Vpp_GetVppConfig(); + + backlight = GetBacklight(SOURCE_TV); + + if (mbVppCfg_backlight_init) { + backlight = (backlight + 100) * 255 / 200; + + if (backlight < 127 || backlight > 255) { + backlight = 255; + } + } + SetBacklight(backlight, SOURCE_TV, 0); + + if (SSMReadNonStandardValue() & 1) { + Set_Fixed_NonStandard(0); //close + } else { + Set_Fixed_NonStandard(2); //open + } + + if (!LoadVppLdimRegs()) { + LOGD ("Load local dimming regs success.\n"); + } + else { + LOGD ("Load local dimming regs failure!!!\n"); + } + return ret; +} + +int CVpp::Vpp_ResetLastVppSettingsSourceType(void) +{ + return tvResetLastVppSettingsSourceType(); +} + +int CVpp::LoadVppLdimRegs() +{ + return tvLoadCpqLdimRegs(); +} + +int CVpp::LoadVppSettings(tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, + is_3d_type_t is3d, tvin_trans_fmt_t trans_fmt) +{ + source_input_param_t source_input_param; + source_input_param.source_input = tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType(tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + source_input_param.sig_fmt = sig_fmt; + source_input_param.is3d = is3d; + source_input_param.trans_fmt = trans_fmt; + return tvLoadPQSettings(source_input_param); +} + +int CVpp::Vpp_GetVppConfig(void) +{ + const char *config_value; + + config_value = config_get_str(CFG_SECTION_TV, "vpp.pqmode.depend.bklight", "null"); + if (strcmp(config_value, "enable") == 0) { + mbVppCfg_pqmode_depend_bklight = true; + } else { + mbVppCfg_pqmode_depend_bklight = false; + } + + config_value = config_get_str(CFG_SECTION_TV, "vpp.backlight.reverse", "null"); + if (strcmp(config_value, "enable") == 0) { + mbVppCfg_backlight_reverse = true; + } else { + mbVppCfg_backlight_reverse = false; + } + + config_value = config_get_str(CFG_SECTION_TV, "vpp.backlight.init", "null"); + if (strcmp(config_value, "enable") == 0) { + mbVppCfg_backlight_init = true; + } else { + mbVppCfg_backlight_init = false; + } + + config_value = config_get_str(CFG_SECTION_TV, "vpp.color.temp.bysource", "enable"); + if (strcmp(config_value, "enable") == 0) { + tvSetPQConfig(COLORTEMP_BY_SOURCE, 1); + } else { + tvSetPQConfig(COLORTEMP_BY_SOURCE, 0); + } + + config_value = config_get_str(CFG_SECTION_TV, "vpp.pqwithout.hue", "null"); + if (strcmp(config_value, "enable") == 0) { + tvSetPQConfig(PQ_WITHOUT_HUE, 1); + } else { + tvSetPQConfig(PQ_WITHOUT_HUE, 0); + } + + config_value = config_get_str(CFG_SECTION_TV, "vpp.hue.reverse", "null"); + if (strcmp(config_value, "enable") == 0) { + tvSetPQConfig(HUE_REVERSE, 1); + } else { + tvSetPQConfig(HUE_REVERSE, 0); + } + + config_value = config_get_str(CFG_SECTION_TV, "vpp.gamma.onoff", "null"); + if (strcmp(config_value, "disable") == 0) { + tvSetPQConfig(GAMMA_ONOFF, 1); + } else { + tvSetPQConfig(GAMMA_ONOFF, 0); + } + + config_value = config_get_str(CFG_SECTION_TV, "vpp.new.cm", "disable"); + if (strcmp(config_value, "enable") == 0) { + tvSetPQConfig(NEW_CM, 1); + } else { + tvSetPQConfig(NEW_CM, 0); + } + + config_value = config_get_str(CFG_SECTION_TV, "vpp.new.nr", "disable"); + if (strcmp(config_value, "enable") == 0) { + tvSetPQConfig(NEW_NR, 1); + } else { + tvSetPQConfig(NEW_NR, 0); + } + + config_value = config_get_str(CFG_SECTION_TV, "vpp.contrast.withOSD", "disable"); + if (strcmp(config_value, "enable") == 0) { + tvSetPQConfig(CONTRAST_WITHOSD, 1); + } else { + tvSetPQConfig(CONTRAST_WITHOSD, 0); + } + + config_value = config_get_str(CFG_SECTION_TV, "vpp.hue.withOSD", "disable"); + if (strcmp(config_value, "enable") == 0) { + tvSetPQConfig(HUE_WITHOSD, 1); + } else { + tvSetPQConfig(HUE_WITHOSD, 0); + } + + config_value = config_get_str(CFG_SECTION_TV, "vpp.brightness.withOSD", "disable"); + if (strcmp(config_value, "enable") == 0) { + tvSetPQConfig(BRIGHTNESS_WITHOSD, 1); + } else { + tvSetPQConfig(BRIGHTNESS_WITHOSD, 0); + } + + config_value = config_get_str(CFG_SECTION_TV, "vpp.xvycc.switch_control", "null"); + if (strcmp(config_value, "enable") == 0) { + tvSetPQConfig(XVYCC_SWITCH_CONTROL, 1); + } else { + tvSetPQConfig(XVYCC_SWITCH_CONTROL, 0); + } + + return 0; +} + +int CVpp::SetPQMode(vpp_picture_mode_t pq_mode, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, + tvin_trans_fmt_t trans_fmt, is_3d_type_t is3d, int is_save, int is_autoswitch) +{ + return tvSetPQMode(pq_mode, is_save, is_autoswitch); + +} + +vpp_picture_mode_t CVpp::GetPQMode(tv_source_input_t tv_source_input) +{ + return tvGetPQMode(); +} + +int CVpp::SavePQMode(vpp_picture_mode_t pq_mode, tv_source_input_t tv_source_input) +{ + + return tvSavePQMode(pq_mode); +} + +int CVpp::Vpp_GetPQModeValue(tv_source_input_t tv_source_input, vpp_picture_mode_t pq_mode, + vpp_pq_para_t *pq_para) +{ + source_input_param_t source_input_param; + source_input_param.source_input = tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType(tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + + return tvGetPQParams(source_input_param, pq_mode, pq_para); +} + +int CVpp::Vpp_GetAutoSwitchPCModeFlag(void) +{ + return tvGetAutoSwitchPCModeFlag(); +} + +void CVpp::enableMonitorMode(bool enable) +{ + if (enable) { + tvWriteSysfs(DI_NR2_ENABLE, "0"); + tvWriteSysfs(AMVECM_PC_MODE, "0"); + if (mHdmiOutFbc && fbcIns) { + fbcIns->cfbc_EnterPCMode(0); + } + } else { + tvWriteSysfs(DI_NR2_ENABLE, "1"); + tvWriteSysfs(AMVECM_PC_MODE, "1"); + if (mHdmiOutFbc && fbcIns) { + fbcIns->cfbc_EnterPCMode(1); + } + } +} + + + int CVpp::SetBrightness(int value, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, + tvin_trans_fmt_t trans_fmt, is_3d_type_t is3d, int is_save) + { + return tvSetBrightness(value, is_save); + } + + int CVpp::GetBrightness( tv_source_input_t tv_source_input) + { + return tvGetBrightness(); + } + + int CVpp::SaveBrightness(int value, tv_source_input_t tv_source_input) + { + return tvSaveBrightness(value); + } + + int CVpp::SetSaturation(int value, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, + tvin_trans_fmt_t trans_fmt, is_3d_type_t is3d, int is_save) + { + return tvSetSaturation(value, is_save); + } + + int CVpp::GetSaturation(tv_source_input_t tv_source_input) + { + return tvGetSaturation(); + } + + int CVpp::SaveSaturation(int value, tv_source_input_t tv_source_input) + { + return tvSaveSaturation(value); + } + + int CVpp::SetColorTemperature(vpp_color_temperature_mode_t temp_mode, tv_source_input_t tv_source_input, int is_save) + { + return tvSetColorTemperature(temp_mode, is_save); + } + + vpp_color_temperature_mode_t CVpp::GetColorTemperature(tv_source_input_t tv_source_input) + { + return (vpp_color_temperature_mode_t)tvGetColorTemperature(); + } + + int CVpp::SaveColorTemperature(vpp_color_temperature_mode_t temp_mode, tv_source_input_t tv_source_input) + { + return tvSaveColorTemperature(temp_mode); + } + + int CVpp::SetNoiseReductionMode(vpp_noise_reduction_mode_t nr_mode, + tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, is_3d_type_t is3d, + tvin_trans_fmt_t trans_fmt, int is_save) + { + return tvSetNoiseReductionMode(nr_mode, is_save); + } + + vpp_noise_reduction_mode_t CVpp::GetNoiseReductionMode(tv_source_input_t tv_source_input) + { + return (vpp_noise_reduction_mode_t)tvGetNoiseReductionMode(); + } + + int CVpp::SaveNoiseReductionMode(vpp_noise_reduction_mode_t nr_mode, tv_source_input_t tv_source_input) + { + return tvSaveNoiseReductionMode(nr_mode); + } + + int CVpp::SetSharpness(int value, tv_source_input_t tv_source_input, int is_enable, + is_3d_type_t is3d, tvin_sig_fmt_t sig_fmt, tvin_trans_fmt_t trans_fmt, int is_save) + { + return tvSetSharpness(value, is_enable, is_save); + } + + int CVpp::GetSharpness(tv_source_input_t tv_source_input) + { + return tvGetSharpness(); + } + + int CVpp::SaveSharpness(int value, tv_source_input_t tv_source_input) + { + return tvSaveSharpness(value); + } + + int CVpp::SetHue(int value, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, + tvin_trans_fmt_t trans_fmt, is_3d_type_t is3d, int is_save) + { + return tvSetHue(value, is_save); + } + + int CVpp::GetHue(tv_source_input_t tv_source_input) + { + return tvGetHue(); + } + + int CVpp::SaveHue(int value, tv_source_input_t tv_source_input) + { + return tvSaveHue(value); + } + + int CVpp::SetContrast(int value, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, + tvin_trans_fmt_t trans_fmt, is_3d_type_t is3d, int is_save) + { + return tvSetContrast(value, is_save); + } + + int CVpp::GetContrast(tv_source_input_t tv_source_input) + { + return tvGetContrast(); + } + + int CVpp::SaveContrast(int value, tv_source_input_t tv_source_input) + { + return tvSaveContrast(value); + } + + int CVpp::SetEyeProtectionMode(tv_source_input_t tv_source_input, int enable) + { + source_input_param_t source_input_param; + source_input_param.source_input = tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType(tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + + return tvSetEyeProtectionMode(source_input_param, enable); + } + + int CVpp::GetEyeProtectionMode() + { + return tvGetEyeProtectionMode(); + } + +int CVpp::VPP_SetNonLinearFactor(int value) +{ + LOGD("VPP_SetNonLinearFactor /sys/class/video/nonlinear_factor : %d", value); + FILE *fp = fopen("/sys/class/video/nonlinear_factor", "w"); + if (fp == NULL) { + LOGE("Open /sys/class/video/nonlinear_factor error(%s)!\n", strerror(errno)); + return -1; + } + + fprintf(fp, "%d", value); + fclose(fp); + fp = NULL; + return 0; +} + +int CVpp::SetGammaValue(vpp_gamma_curve_t gamma_curve, int is_save) +{ + return tvSetGamma((int)gamma_curve, is_save); +} + +int CVpp::GetGammaValue() +{ + return tvGetGamma(); +} + + +vpp_display_mode_t CVpp::GetDisplayMode(tv_source_input_t tv_source_input) +{ + source_input_param_t source_input_param;; + source_input_param.source_input = tv_source_input; + return (vpp_display_mode_t)tvGetDisplayMode(source_input_param); +} + +int CVpp::SetBacklight(int value, tv_source_input_t tv_source_input, int is_save) +{ + int ret = -1; + if (mHdmiOutFbc) { + if (fbcIns != NULL) { + ret = fbcIns->cfbc_Set_Backlight(COMM_DEV_SERIAL, value*255/100); + } + } else { + ret = SetBacklightWithoutSave(value, tv_source_input); + } + + if (ret >= 0 && is_save == 1) { + ret = SaveBacklight(value, tv_source_input); + } + + return ret; +} + +int CVpp::GetBacklight(tv_source_input_t tv_source_input) +{ + int data = 0; + vpp_pq_para_t pq_para; + + if (mbVppCfg_pqmode_depend_bklight) { + vpp_picture_mode_t pq_mode = GetPQMode(tv_source_input); + if (pq_mode == VPP_PICTURE_MODE_USER) { + SSMReadBackLightVal(tv_source_input, &data); + } else { + Vpp_GetPQModeValue(tv_source_input, pq_mode, &pq_para); + data = pq_para.backlight; + } + } else { + tv_source_input = SOURCE_TV; + SSMReadBackLightVal(tv_source_input, &data); + } + + if (data < 0 || data > 100) { + data = DEFAULT_BACKLIGHT_BRIGHTNESS; + } + return data; +} + +int CVpp::SaveBacklight(int value, tv_source_input_t tv_source_input) +{ + int backlight_value, backlight_reverse = 0; + int ret = -1; + int tmp_pic_mode = 0; + + if (!mbVppCfg_pqmode_depend_bklight) { + tv_source_input = SOURCE_TV; + } + + if (value < 0 || value > 100) { + value = 100; + } + ret = SSMSaveBackLightVal(tv_source_input, value); + + return ret; +} + +int CVpp::SetBacklightWithoutSave(int value, tv_source_input_t tv_source_input __unused) +{ + int backlight_value; + + if (value < 0 || value > 100) { + value = 100; + } + + if (mbVppCfg_backlight_reverse) { + backlight_value = (100 - value) * 255 / 100; + } else { + backlight_value = value * 255 / 100; + } + return VPP_SetBackLightLevel(backlight_value); +} + +int CVpp::VPP_SetBackLightLevel(int value) +{ + LOGD("VPP_SetBackLightLevel %s : %d", BACKLIGHT_BRIGHTNESS, value); + return tvWriteSysfs(BACKLIGHT_BRIGHTNESS, value); +} + + +int CVpp::VPP_SetBackLight_Switch(int value) +{ + LOGD("VPP_SetBackLight_Switch VPP_PANEL_BACKLIGHT_DEV_PATH : %d ", value); + FILE *fp = fopen(VPP_PANEL_BACKLIGHT_DEV_PATH, "w"); + if (fp == NULL) { + LOGE("Open VPP_PANEL_BACKLIGHT_DEV_PATH error(%s)!\n", strerror(errno)); + return -1; + } + + fprintf(fp, "%d", value); + fclose(fp); + fp = NULL; + return 0; +} + +int CVpp::VPP_GetBackLight_Switch(void) +{ + int value; + + FILE *fp = fopen(VPP_PANEL_BACKLIGHT_DEV_PATH, "w"); + if (fp == NULL) { + LOGE("Open VPP_PANEL_BACKLIGHT_DEV_PATH error(%s)!\n", strerror(errno)); + return -1; + } + + fscanf(fp, "%d", &value); + LOGD("VPP_GetBackLight_Switch VPP_PANEL_BACKLIGHT_DEV_PATH : %d", value); + fclose(fp); + fp = NULL; + if (value < 0) { + return 0; + } else { + return value; + } +} + +int CVpp::FactorySetPQMode_Brightness(int source_type, int pq_mode, int brightness) +{ + source_input_param_t source_input_param; + source_input_param.source_type = (tv_source_input_type_t)source_type; + + return tvFactorySetPQParam(source_input_param, pq_mode, BRIGHTNESS, brightness); +} + +int CVpp::FactoryGetPQMode_Brightness(int tv_source_input, int pq_mode) +{ + source_input_param_t source_input_param; + source_input_param.source_input = (tv_source_input_t)tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + + return tvFactoryGetPQParam(source_input_param, pq_mode, BRIGHTNESS); +} + +int CVpp::FactorySetPQMode_Contrast(int tv_source_input, int pq_mode, int contrast) +{ + source_input_param_t source_input_param; + source_input_param.source_input = (tv_source_input_t)tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + + return tvFactorySetPQParam(source_input_param, pq_mode, CONTRAST, contrast); +} + +int CVpp::FactoryGetPQMode_Contrast(int tv_source_input, int pq_mode) +{ + source_input_param_t source_input_param; + source_input_param.source_input = (tv_source_input_t)tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + + return tvFactoryGetPQParam(source_input_param, pq_mode, CONTRAST); +} + +int CVpp::FactorySetPQMode_Saturation(int tv_source_input, int pq_mode, int saturation) +{ + source_input_param_t source_input_param; + source_input_param.source_input = (tv_source_input_t)tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + + return tvFactorySetPQParam(source_input_param, pq_mode, SATURATION, saturation); +} + +int CVpp::FactoryGetPQMode_Saturation(int tv_source_input, int pq_mode) +{ + source_input_param_t source_input_param; + source_input_param.source_input = (tv_source_input_t)tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + + return tvFactoryGetPQParam(source_input_param, pq_mode, SATURATION); +} + +int CVpp::FactorySetPQMode_Hue(int tv_source_input, int pq_mode, int hue) +{ + source_input_param_t source_input_param; + source_input_param.source_input = (tv_source_input_t)tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + + return tvFactorySetPQParam(source_input_param, pq_mode, HUE, hue); +} + +int CVpp::FactoryGetPQMode_Hue(int tv_source_input, int pq_mode) +{ + source_input_param_t source_input_param; + source_input_param.source_input = (tv_source_input_t)tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + + return tvFactoryGetPQParam(source_input_param, pq_mode, HUE); +} + +int CVpp::FactorySetPQMode_Sharpness(int tv_source_input, int pq_mode, int sharpness) +{ + source_input_param_t source_input_param; + source_input_param.source_input = (tv_source_input_t)tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + + return tvFactorySetPQParam(source_input_param, pq_mode, SHARPNESS, sharpness); +} + +int CVpp::FactoryGetPQMode_Sharpness(int tv_source_input, int pq_mode) +{ + source_input_param_t source_input_param; + source_input_param.source_input = (tv_source_input_t)tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + + return tvFactoryGetPQParam(source_input_param, pq_mode, SHARPNESS); +} + +int CVpp::GetColorTemperatureParams(vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t *params) +{ + params->en = tvGetColorTemperatureParams(Tempmode, EN); + params->r_post_offset = tvGetColorTemperatureParams(Tempmode, POST_OFFSET_R); + params->g_post_offset = tvGetColorTemperatureParams(Tempmode, POST_OFFSET_G); + params->b_post_offset = tvGetColorTemperatureParams(Tempmode, POST_OFFSET_B); + params->r_gain = tvGetColorTemperatureParams(Tempmode, GAIN_R); + params->g_gain = tvGetColorTemperatureParams(Tempmode, GAIN_G); + params->b_gain = tvGetColorTemperatureParams(Tempmode, GAIN_B); + params->r_pre_offset = tvGetColorTemperatureParams(Tempmode, PRE_OFFSET_R); + params->g_pre_offset = tvGetColorTemperatureParams(Tempmode, PRE_OFFSET_G); + params->b_pre_offset = tvGetColorTemperatureParams(Tempmode, PRE_OFFSET_B); + + return 0; +} + +int CVpp::SetColorTemperatureParams(vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t params) +{ + return tvSetColorTemperatureParams(Tempmode, params); +} + + +int CVpp::FactorySetColorTemp_Rgain(int source_type, int colortemp_mode, int rgain) +{ + return tvFactorySetColorTemperatureParam(colortemp_mode, GAIN_R, rgain); +} + +int CVpp::FactorySaveColorTemp_Rgain(int source_type __unused, int colortemp_mode, int rgain) +{ + return tvFactorySaveColorTemperatureParam(colortemp_mode, GAIN_R, rgain); +} + +int CVpp::FactoryGetColorTemp_Rgain(int source_type __unused, int colortemp_mode) +{ + return tvFactoryGetColorTemperatureParam(colortemp_mode, GAIN_R); +} + +int CVpp::FactorySetColorTemp_Ggain(int source_type, int colortemp_mode, int ggain) +{ + return tvFactorySetColorTemperatureParam(colortemp_mode, GAIN_G, ggain); +} + +int CVpp::FactorySaveColorTemp_Ggain(int source_type __unused, int colortemp_mode, int ggain) +{ + return tvFactorySaveColorTemperatureParam(colortemp_mode, GAIN_G, ggain); +} + +int CVpp::FactoryGetColorTemp_Ggain(int source_type __unused, int colortemp_mode) +{ + return tvFactoryGetColorTemperatureParam(colortemp_mode, GAIN_G); +} + +int CVpp::FactorySetColorTemp_Bgain(int source_type, int colortemp_mode, int bgain) +{ + return tvFactorySetColorTemperatureParam(colortemp_mode, GAIN_B, bgain); +} + +int CVpp::FactorySaveColorTemp_Bgain(int source_type __unused, int colortemp_mode, int bgain) +{ + return tvFactorySaveColorTemperatureParam(colortemp_mode, GAIN_B, bgain); +} + +int CVpp::FactoryGetColorTemp_Bgain(int source_type __unused, int colortemp_mode) +{ + return tvFactoryGetColorTemperatureParam(colortemp_mode, GAIN_B); +} + +int CVpp::FactorySetColorTemp_Roffset(int source_type, int colortemp_mode, int roffset) +{ + return tvFactorySetColorTemperatureParam(colortemp_mode, POST_OFFSET_R, roffset); +} + +int CVpp::FactorySaveColorTemp_Roffset(int source_type __unused, int colortemp_mode, int roffset) +{ + return tvFactorySaveColorTemperatureParam(colortemp_mode, POST_OFFSET_R, roffset); +} + +int CVpp::FactoryGetColorTemp_Roffset(int source_type __unused, int colortemp_mode) +{ + return tvFactoryGetColorTemperatureParam(colortemp_mode, POST_OFFSET_R); +} + +int CVpp::FactorySetColorTemp_Goffset(int source_type, int colortemp_mode, int goffset) +{ + return tvFactorySetColorTemperatureParam(colortemp_mode, POST_OFFSET_G, goffset); +} + +int CVpp::FactorySaveColorTemp_Goffset(int source_type __unused, int colortemp_mode, int goffset) +{ + return tvFactorySaveColorTemperatureParam(colortemp_mode, POST_OFFSET_G, goffset); +} + +int CVpp::FactoryGetColorTemp_Goffset(int source_type __unused, int colortemp_mode) +{ + return tvFactoryGetColorTemperatureParam(colortemp_mode, POST_OFFSET_G); +} + +int CVpp::FactorySetColorTemp_Boffset(int source_type, int colortemp_mode, int boffset) +{ + return tvFactorySetColorTemperatureParam(colortemp_mode, POST_OFFSET_B, boffset); +} + +int CVpp::FactorySaveColorTemp_Boffset(int source_type __unused, int colortemp_mode, int boffset) +{ + return tvFactorySaveColorTemperatureParam(colortemp_mode, POST_OFFSET_B, boffset); +} + +int CVpp::FactoryGetColorTemp_Boffset(int source_type __unused, int colortemp_mode) +{ + return tvFactoryGetColorTemperatureParam(colortemp_mode, POST_OFFSET_B); +} + +int CVpp::FactoryGetTestPattern(void) +{ + unsigned char data = VPP_TEST_PATTERN_NONE; + SSMReadTestPattern(&data); + return data; +} + +int CVpp::FactoryResetPQMode(void) +{ + return tvFactoryResetPQMode(); +} + +int CVpp::FactoryResetNonlinear(void) +{ + return tvFactoryResetNonlinear(); +} + +int CVpp::FactoryResetColorTemp(void) +{ + return tvFactoryResetColorTemp(); +} + +int CVpp::FactorySetParamsDefault(void) +{ + return tvFactorySetParamsDefault(); +} + +int CVpp::FactorySetDDRSSC(int step) +{ + int ret = -1; + + switch (step) { + case 1: + break; + + case 2: + break; + + case 3: + break; + + case 4: + break; + + case 5: + break; + + case 0: + default: + break; + } + + if (ret < 0) { + return -1; + } + + return SSMSaveDDRSSC(step); +} + +int CVpp::FactoryGetDDRSSC(void) +{ + unsigned char data = 0; + SSMReadDDRSSC(&data); + return data; +} + +int CVpp::SetLVDSSSC(int step) +{ + int ret = -1; + if (step > 4) + step = 4; + ret = TvMisc_SetLVDSSSC(step); + return ret; +} + +int CVpp::FactorySetLVDSSSC(int step) +{ + int ret = -1; + unsigned char data[2] = {0, 0}; + char cmd_tmp_1[128]; + int value = 0, panel_idx = 0, tmp = 0; + const char *PanelIdx; + if (step > 3) + step = 3; + + PanelIdx = config_get_str ( CFG_SECTION_TV, "get.panel.index", "0" ); + panel_idx = strtoul(PanelIdx, NULL, 10); + LOGD ("%s, panel_idx = %x", __FUNCTION__, panel_idx); + SSMReadLVDSSSC(data); + + //every 2 bits represent one panel, use 2 byte store 8 panels + value = (data[1] << 8) | data[0]; + step = step & 0x03; + panel_idx = panel_idx * 2; + tmp = 3 << panel_idx; + value = (value & (~tmp)) | (step << panel_idx); + data[0] = value & 0xFF; + data[1] = (value >> 8) & 0xFF; + LOGD ("%s, tmp = %x, save value = %x", __FUNCTION__, tmp, value); + + SetLVDSSSC(step); + return SSMSaveLVDSSSC(data); +} + +int CVpp::FactoryGetLVDSSSC(void) +{ + unsigned char data[2] = {0, 0}; + int value = 0, panel_idx = 0; + const char *PanelIdx = config_get_str ( CFG_SECTION_TV, "get.panel.index", "0" ); + + panel_idx = strtoul(PanelIdx, NULL, 10); + SSMReadLVDSSSC(data); + value = (data[1] << 8) | data[0]; + value = (value >> (2 * panel_idx)) & 0x03; + LOGD ("%s, panel_idx = %x, value= %d", __FUNCTION__, panel_idx, value); + return value; +} + +noline_params_t CVpp::FactoryGetNolineParams(int type, int source_type) +{ + int ret = -1; + noline_params_t noline_params; + source_input_param_t source_input_param; + + source_input_param.source_type = (tv_source_input_type_t)source_type; + noline_params.osd0 = tvFactoryGetNolineParams(source_input_param, type, OSD_0); + noline_params.osd25 = tvFactoryGetNolineParams(source_input_param, type, OSD_25); + noline_params.osd50 = tvFactoryGetNolineParams(source_input_param, type, OSD_50); + noline_params.osd75 = tvFactoryGetNolineParams(source_input_param, type, OSD_75); + noline_params.osd100 = tvFactoryGetNolineParams(source_input_param, type, OSD_100); + + return noline_params; +} + +int CVpp::FactorySetNolineParams(int type, int tv_source_input, noline_params_t noline_params) +{ + int ret = 0; + source_input_param_t source_input_param; + source_input_param.source_input = (tv_source_input_t)tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType((tv_source_input_t)tv_source_input); + + ret |= tvFactorySetNolineParams(source_input_param, type, noline_params); + return ret; +} + +int CVpp::FactorySetOverscan(int source_type, int fmt, int trans_fmt, tvin_cutwin_t cutwin_t) +{ + int ret = 0; + source_input_param_t source_input_param; + source_input_param.source_type = (tv_source_input_type_t)source_type; + source_input_param.sig_fmt = (tvin_sig_fmt_t)fmt; + source_input_param.trans_fmt = (tvin_trans_fmt_t)trans_fmt; + + ret |= tvFactorySetOverscanParam(source_input_param, cutwin_t); + + return ret; +} + +tvin_cutwin_t CVpp::FactoryGetOverscan(int source_type, int fmt, is_3d_type_t is3d, int trans_fmt) +{ + source_input_param_t source_input_param; + tvin_cutwin_t cutwin_t; + source_input_param.source_type = (tv_source_input_type_t)source_type; + source_input_param.sig_fmt = (tvin_sig_fmt_t)fmt; + source_input_param.trans_fmt = (tvin_trans_fmt_t)trans_fmt; + source_input_param.is3d = is3d; + + cutwin_t.he = tvFactoryGetOverscanParam(source_input_param, CUTWIN_HE); + cutwin_t.hs = tvFactoryGetOverscanParam(source_input_param, CUTWIN_HS); + cutwin_t.ve = tvFactoryGetOverscanParam(source_input_param, CUTWIN_VE); + cutwin_t.vs = tvFactoryGetOverscanParam(source_input_param, CUTWIN_VS); + + return cutwin_t; +} + +int CVpp::FactorySetGamma(tcon_gamma_table_t gamma_r, tcon_gamma_table_t gamma_g, tcon_gamma_table_t gamma_b) +{ + int gamma_r_value = gamma_r.data[0]; + int gamma_g_value = gamma_g.data[0]; + int gamma_b_value = gamma_b.data[0]; + LOGD("%s", __FUNCTION__); + return tvFactorySetGamma(gamma_r_value, gamma_g_value, gamma_b_value); +} + +int CVpp::VPPSSMFacRestoreDefault() +{ + tvFactorySSMRestore(); + VPP_SSMRestorToDefault(0, true); + + return 0; +} + +void CVpp::video_set_saturation_hue(signed char saturation, signed char hue, signed long *mab) +{ + signed short ma = (signed short) (cos((float) hue * PI / 128.0) * ((float) saturation / 128.0 + + 1.0) * 256.0); + signed short mb = (signed short) (sin((float) hue * PI / 128.0) * ((float) saturation / 128.0 + + 1.0) * 256.0); + + if (ma > 511) { + ma = 511; + } + + if (ma < -512) { + ma = -512; + } + + if (mb > 511) { + mb = 511; + } + + if (mb < -512) { + mb = -512; + } + + *mab = ((ma & 0x3ff) << 16) | (mb & 0x3ff); +} + +void CVpp::video_get_saturation_hue(signed char *sat, signed char *hue, signed long *mab) +{ + signed long temp = *mab; + signed int ma = (signed int) ((temp << 6) >> 22); + signed int mb = (signed int) ((temp << 22) >> 22); + signed int sat16 = (signed int) ((sqrt( + ((float) ma * (float) ma + (float) mb * (float) mb) / 65536.0) - 1.0) * 128.0); + signed int hue16 = (signed int) (atan((float) mb / (float) ma) * 128.0 / PI); + + if (sat16 > 127) { + sat16 = 127; + } + + if (sat16 < -128) { + sat16 = -128; + } + + if (hue16 > 127) { + hue16 = 127; + } + + if (hue16 < -128) { + hue16 = -128; + } + + *sat = (signed char) sat16; + *hue = (signed char) hue16; +} + +int CVpp::VPP_SetGrayPattern(int value) +{ + if (value < 0) { + value = 0; + } else if (value > 255) { + value = 255; + } + value = value << 16 | 0x8080; + + LOGD("VPP_SetGrayPattern /sys/class/video/test_screen : %x", value); + FILE *fp = fopen("/sys/class/video/test_screen", "w"); + if (fp == NULL) { + LOGE("Open /sys/classs/video/test_screen error(%s)!\n", strerror(errno)); + return -1; + } + + fprintf(fp, "0x%x", value); + fclose(fp); + fp = NULL; + + return 0; +} + +int CVpp::VPP_GetGrayPattern() +{ + int value; + + LOGD("VPP_GetGrayPattern /sys/class/video/test_screen"); + FILE *fp = fopen("/sys/class/video/test_screen", "r+"); + if (fp == NULL) { + LOGE("Open /sys/class/video/test_screen error(%s)!\n", strerror(errno)); + return -1; + } + + fscanf(fp, "%d", &value); + fclose(fp); + fp = NULL; + if (value < 0) { + return 0; + } else { + value = value >> 16; + if (value > 255) { + value = 255; + } + return value; + } +} + +tvin_cutwin_t CVpp::GetOverscan(tv_source_input_t tv_source_input, tvin_sig_fmt_t fmt, + is_3d_type_t is3d, tvin_trans_fmt_t trans_fmt) +{ + int ret = 0; + tvin_cutwin_t cutwin_t; + source_input_param_t source_input_param; + memset(&cutwin_t, 0, sizeof(cutwin_t)); + source_input_param.source_input = tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType(tv_source_input); + source_input_param.source_port = CTvin::Tvin_GetSourcePortBySourceType(source_input_param.source_type); + source_input_param.sig_fmt = fmt; + source_input_param.is3d = is3d; + source_input_param.trans_fmt = trans_fmt; + cutwin_t.he = tvGetOverscanParam(source_input_param, CUTWIN_HE); + cutwin_t.hs = tvGetOverscanParam(source_input_param, CUTWIN_HS); + cutwin_t.ve = tvGetOverscanParam(source_input_param, CUTWIN_VE); + cutwin_t.vs = tvGetOverscanParam(source_input_param, CUTWIN_VS); + + return cutwin_t; +} + +int CVpp::VPP_SetVideoCrop(int Voffset0, int Hoffset0, int Voffset1, int Hoffset1) +{ + char set_str[32]; + + LOGD("VPP_SetVideoCrop /sys/class/video/crop : %d %d %d %d##", Voffset0, Hoffset0, Voffset1, Hoffset1); + int fd = open("/sys/class/video/crop", O_RDWR); + if (fd < 0) { + LOGE("Open /sys/class/video/crop error(%s)!\n", strerror(errno)); + return -1; + } + + memset(set_str, 0, 32); + sprintf(set_str, "%d %d %d %d", Voffset0, Hoffset0, Voffset1, Hoffset1); + write(fd, set_str, strlen(set_str)); + close(fd); + + return 0; +} + +int CVpp::VPP_SetScalerPathSel(const unsigned int value) +{ + FILE *fp = NULL; + + fp = fopen(SYS_VIDEO_SCALER_PATH_SEL, "w"); + LOGD("VPP_SetScalerPathSel %s : %d", SYS_VIDEO_SCALER_PATH_SEL, value); + if (fp == NULL) { + LOGE("Open %s error(%s)!\n",SYS_VIDEO_SCALER_PATH_SEL, strerror(errno)); + return -1; + } + fprintf(fp, "%d", value); + fclose(fp); + fp = NULL; + return 0; +} + +int CVpp::VPP_FBCSetColorTemperature(vpp_color_temperature_mode_t temp_mode) +{ + int ret = -1; + if (fbcIns != NULL) { + ret = fbcIns->fbcSetEyeProtection(COMM_DEV_SERIAL, GetEyeProtectionMode()); + ret |= fbcIns->cfbc_Set_ColorTemp_Mode(COMM_DEV_SERIAL, temp_mode); + } + return ret; +} + +int CVpp::VPP_FBCColorTempBatchSet(vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t params) +{ + unsigned char mode = 0, r_gain, g_gain, b_gain, r_offset, g_offset, b_offset; + switch (Tempmode) { + case VPP_COLOR_TEMPERATURE_MODE_STANDARD: + mode = 1; //COLOR_TEMP_STD + break; + case VPP_COLOR_TEMPERATURE_MODE_WARM: + mode = 2; //COLOR_TEMP_WARM + break; + case VPP_COLOR_TEMPERATURE_MODE_COLD: + mode = 0; //COLOR_TEMP_COLD + break; + case VPP_COLOR_TEMPERATURE_MODE_USER: + mode = 3; //COLOR_TEMP_USER + break; + default: + break; + } + r_gain = (params.r_gain * 255) / 2047; // u1.10, range 0~2047, default is 1024 (1.0x) + g_gain = (params.g_gain * 255) / 2047; + b_gain = (params.b_gain * 255) / 2047; + r_offset = (params.r_post_offset + 1024) * 255 / 2047; // s11.0, range -1024~+1023, default is 0 + g_offset = (params.g_post_offset + 1024) * 255 / 2047; + b_offset = (params.b_post_offset + 1024) * 255 / 2047; + LOGD ( "~colorTempBatchSet##%d,%d,%d,%d,%d,%d,##", r_gain, g_gain, b_gain, r_offset, g_offset, b_offset ); + + if (fbcIns != NULL) { + fbcIns->cfbc_Set_WB_Batch(COMM_DEV_SERIAL, mode, r_gain, g_gain, b_gain, r_offset, g_offset, b_offset); + return 0; + } + + return -1; +} + +int CVpp::VPP_FBCColorTempBatchGet(vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t *params) +{ + unsigned char mode = 0, r_gain, g_gain, b_gain, r_offset, g_offset, b_offset; + switch (Tempmode) { + case VPP_COLOR_TEMPERATURE_MODE_STANDARD: + mode = 1; //COLOR_TEMP_STD + break; + case VPP_COLOR_TEMPERATURE_MODE_WARM: + mode = 2; //COLOR_TEMP_WARM + break; + case VPP_COLOR_TEMPERATURE_MODE_COLD: + mode = 0; //COLOR_TEMP_COLD + break; + case VPP_COLOR_TEMPERATURE_MODE_USER: + mode = 3; //COLOR_TEMP_USER + break; + default: + break; + } + + if (fbcIns != NULL) { + fbcIns->cfbc_Get_WB_Batch(COMM_DEV_SERIAL, mode, &r_gain, &g_gain, &b_gain, &r_offset, &g_offset, &b_offset); + LOGD ( "~colorTempBatchGet##%d,%d,%d,%d,%d,%d,##", r_gain, g_gain, b_gain, r_offset, g_offset, b_offset ); + + params->r_gain = (r_gain * 2047) / 255; + params->g_gain = (g_gain * 2047) / 255; + params->b_gain = (b_gain * 2047) / 255; + params->r_post_offset = (r_offset * 2047) / 255 - 1024; + params->g_post_offset = (g_offset * 2047) / 255 - 1024; + params->b_post_offset = (b_offset * 2047) / 255 - 1024; + return 0; + } + + return -1; +} + +int CVpp::VPP_SSMRestorToDefault(int id, bool resetAll) +{ + int i = 0, tmp_val = 0; + int tmp_panorama_nor = 0, tmp_panorama_full = 0; + + if (resetAll || VPP_DATA_USER_NATURE_SWITCH_START == id) + SSMSaveUserNatureLightSwitch(1); + + if (resetAll || SSM_RW_UI_GRHPHY_BACKLIGHT_START == id) + SSMSaveGraphyBacklight(100); + + if (resetAll || VPP_DATA_POS_DBC_START == id) + SSMSaveDBCStart(0); + + if (resetAll || VPP_DATA_POS_DNLP_START == id) + SSMSaveDnlpStart(0); //0: ON,1: OFF,default is on + + if (resetAll || VPP_DATA_APL_START == id) + SSMSaveAPL(30); + + if (resetAll || VPP_DATA_APL2_START == id) + SSMSaveAPL2(30); + + if (resetAll || VPP_DATA_BD_START == id) + SSMSaveBD(30); + + if (resetAll || VPP_DATA_BP_START == id) + SSMSaveBP(30); + + if (resetAll || VPP_DATA_POS_FBC_ELECMODE_START == id) + SSMSaveFBCELECmodeVal(11); + + if (resetAll || VPP_DATA_POS_FBC_BACKLIGHT_START == id) + SSMSaveFBCN360BackLightVal(10); + + if (resetAll || VPP_DATA_POS_FBC_COLORTEMP_START == id) + SSMSaveFBCN360ColorTempVal(1); // standard colortemp + + if (resetAll || VPP_DATA_POS_FBC_N310_COLORTEMP_START == id) + SSMSaveFBCN310ColorTempVal(0); + + if (resetAll || VPP_DATA_POS_FBC_N310_LIGHTSENSOR_START == id) + SSMSaveFBCN310LightsensorVal(0); + + if (resetAll || VPP_DATA_POS_FBC_N310_DREAMPANEL_START == id) + SSMSaveFBCN310Dream_PanelVal(1); + + if (resetAll || VPP_DATA_POS_FBC_N310_MULTI_PQ_START == id) + SSMSaveFBCN310MULT_PQVal(1); + + if (resetAll || VPP_DATA_POS_FBC_N310_MEMC_START == id) + SSMSaveFBCN310MEMCVal(2); + + if (resetAll || VPP_DATA_POS_FBC_N310_BACKLIGHT_START == id) + SSMSaveFBCN310BackLightVal(254); + + tmp_panorama_nor = VPP_PANORAMA_MODE_NORMAL; + tmp_panorama_full = VPP_PANORAMA_MODE_FULL; + for (i = 0; i < SOURCE_MAX; i++) { + if (resetAll || VPP_DATA_POS_PANORAMA_START == id) { + if (i == SOURCE_TYPE_HDMI) { + SSMSavePanoramaStart(i, tmp_panorama_full); + } else { + SSMSavePanoramaStart(i, tmp_panorama_nor); + } + } + + tmp_val = DEFAULT_BACKLIGHT_BRIGHTNESS; + if (resetAll || VPP_DATA_POS_BACKLIGHT_START == id) + SSMSaveBackLightVal(i, tmp_val); + } + + return 0; +} + +int CVpp::TV_SSMRecovery() +{ + int ret = 0 ; + ret = tvSSMRecovery(); + ret |= VPP_SSMRestorToDefault(0, true); + + return ret; +} + +int CVpp::VPP_SetPLLValues (tv_source_input_t tv_source_input, tvin_port_t source_port, tvin_sig_fmt_t sig_fmt) +{ + source_input_param_t source_input_param; + source_input_param.source_input = tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType(tv_source_input); + source_input_param.source_port = source_port; + source_input_param.sig_fmt = sig_fmt; + + return tvSetPLLValues(source_input_param); +} + +int CVpp::VPP_SetCVD2Values (tv_source_input_t tv_source_input, tvin_port_t source_port, tvin_sig_fmt_t sig_fmt) + +{ + source_input_param_t source_input_param; + source_input_param.source_input = tv_source_input; + source_input_param.source_type = CTvin::Tvin_SourceInputToSourceInputType(tv_source_input); + source_input_param.source_port = source_port; + source_input_param.sig_fmt = sig_fmt; + + return tvSetCVD2Values(source_input_param); +} + +int CVpp::VPP_GetSSMStatus (void) +{ + return tvGetSSMStatus(); +} + diff --git a/tv/tvserver/libtv/vpp/CVpp.h b/tv/tvserver/libtv/vpp/CVpp.h new file mode 100644 index 0000000..e71e461 --- a/dev/null +++ b/tv/tvserver/libtv/vpp/CVpp.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _C_VPP_H +#define _C_VPP_H +#include "../tvin/CTvin.h" +#include "fbcutils/CFbcCommunication.h" +#include <tvutils.h> + +#define GLOBAL_OGO_FORMAT_FLAG 0x6688 +#define RGB_FORMAT 0 +#define YCbCr_422_FORMAT 1 +#define YCbCr_444_FORMAT 2 +#define PQ_USER_DATA_FROM_E2P 0 +#define PQ_USER_DATA_FROM_DB 1 + +#define VPP_PANEL_BACKLIGHT_DEV_PATH "/sys/class/aml_bl/power" +#define BACKLIGHT_BRIGHTNESS "/sys/class/backlight/aml-bl/brightness" +#define DI_NR2_ENABLE "/sys/module/di/parameters/nr2_en" +#define AMVECM_PC_MODE "/sys/class/amvecm/pc_mode" + +// default backlight value 10% +#define DEFAULT_BACKLIGHT_BRIGHTNESS 10 + +#define MODE_VPP_3D_DISABLE 0x00000000 +#define MODE_VPP_3D_ENABLE 0x00000001 +#define MODE_VPP_3D_AUTO 0x00000002 +#define MODE_VPP_3D_LR 0x00000004 +#define MODE_VPP_3D_TB 0x00000008 +#define MODE_VPP_3D_LA 0x00000010 +#define MODE_VPP_3D_FA 0x00000020 +#define MODE_VPP_3D_LR_SWITCH 0x00000100 +#define MODE_VPP_3D_TO_2D_L 0x00000200 +#define MODE_VPP_3D_TO_2D_R 0x00000400 + +typedef enum vpp_panorama_mode_e { + VPP_PANORAMA_MODE_FULL, + VPP_PANORAMA_MODE_NORMAL, + VPP_PANORAMA_MODE_MAX, +} vpp_panorama_mode_t; + +typedef enum vpp_dream_panel_e { + VPP_DREAM_PANEL_OFF, + VPP_DREAM_PANEL_LIGHT, + VPP_DREAM_PANEL_SCENE, + VPP_DREAM_PANEL_FULL, + VPP_DREAM_PANEL_DEMO, + VPP_DREAM_PANEL_MAX, +} vpp_dream_panel_t; + + +class CVpp { +public: + CVpp(); + ~CVpp(); + int Vpp_Init(bool hdmiOutFbc); + int Vpp_ResetLastVppSettingsSourceType(void); + int LoadVppLdimRegs(); + int LoadVppSettings ( tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, is_3d_type_t is3d, tvin_trans_fmt_t trans_fmt ); + int Vpp_GetVppConfig(); + int SetPQMode ( vpp_picture_mode_t pq_mode, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, tvin_trans_fmt_t trans_fmt, is_3d_type_t is3d, int is_save, int is_autoswitch); + vpp_picture_mode_t GetPQMode ( tv_source_input_t tv_source_input ); + int SavePQMode ( vpp_picture_mode_t pq_mode, tv_source_input_t tv_source_input ); + int Vpp_GetPQModeValue ( tv_source_input_t, vpp_picture_mode_t, vpp_pq_para_t * ); + int Vpp_GetAutoSwitchPCModeFlag(void); + void enableMonitorMode(bool enable); + int SetBrightness ( int value, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, tvin_trans_fmt_t trans_fmt, is_3d_type_t is3d, int is_save ); + int GetBrightness ( tv_source_input_t tv_source_input ); + int SaveBrightness (int value, tv_source_input_t tv_source_input); + int SetSaturation ( int value, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, tvin_trans_fmt_t trans_fmt, is_3d_type_t is3d, int is_save ); + int GetSaturation ( tv_source_input_t tv_source_input ); + int SaveSaturation ( int value, tv_source_input_t tv_source_input ); + int SetColorTemperature ( vpp_color_temperature_mode_t temp_mode, tv_source_input_t tv_source_input, int is_save ); + vpp_color_temperature_mode_t GetColorTemperature ( tv_source_input_t tv_source_input ); + int SaveColorTemperature ( vpp_color_temperature_mode_t temp_mode, tv_source_input_t tv_source_input ); + + int SaveNoiseReductionMode ( vpp_noise_reduction_mode_t nr_mode, tv_source_input_t tv_source_input ); + int SetNoiseReductionMode ( vpp_noise_reduction_mode_t nr_mode, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, is_3d_type_t is3d, tvin_trans_fmt_t trans_fmt, int is_save ); + vpp_noise_reduction_mode_t GetNoiseReductionMode ( tv_source_input_t tv_source_input ); + int SetSharpness ( int value, tv_source_input_t tv_source_input, int is_enable, is_3d_type_t is3d, tvin_sig_fmt_t sig_fmt, tvin_trans_fmt_t trans_fmt, int is_save ); + int GetSharpness ( tv_source_input_t tv_source_input ); + int SaveSharpness ( int value, tv_source_input_t tv_source_input ); + int SetHue ( int value, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, tvin_trans_fmt_t trans_fmt, is_3d_type_t is3d, int is_save ); + int GetHue ( tv_source_input_t tv_source_input ); + int SaveHue (int value, tv_source_input_t tv_source_input ); + int SetContrast ( int value, tv_source_input_t tv_source_input, tvin_sig_fmt_t sig_fmt, tvin_trans_fmt_t trans_fmt, is_3d_type_t is3d, int is_save ); + int GetContrast ( tv_source_input_t tv_source_input ); + int SaveContrast ( int value, tv_source_input_t tv_source_input ); + int SetEyeProtectionMode(tv_source_input_t tv_source_input, int enable); + int GetEyeProtectionMode(); + int SetGammaValue(vpp_gamma_curve_t gamma_curve, int is_save); + int GetGammaValue(); + vpp_display_mode_t GetDisplayMode ( tv_source_input_t tv_source_input ); + int SetBacklight ( int value, tv_source_input_t tv_source_input, int is_save ); + int GetBacklight ( tv_source_input_t tv_source_input ); + int SetBacklightWithoutSave ( int value, tv_source_input_t tv_source_input ); + int SaveBacklight ( int value, tv_source_input_t tv_source_input ); + int FactorySetPQMode_Brightness ( int source_type, int pq_mode, int brightness ); + int FactoryGetPQMode_Brightness ( int tv_source_input, int pq_mode ); + int FactorySetPQMode_Contrast ( int tv_source_input, int pq_mode, int contrast ); + int FactoryGetPQMode_Contrast ( int tv_source_input, int pq_mode ); + int FactorySetPQMode_Saturation ( int tv_source_input, int pq_mode, int saturation ); + int FactoryGetPQMode_Saturation ( int source_type, int pq_mode ); + int FactorySetPQMode_Hue ( int tv_source_input, int pq_mode, int hue ); + int FactoryGetPQMode_Hue ( int tv_source_input, int pq_mode ); + int FactorySetPQMode_Sharpness ( int tv_source_input, int pq_mode, int sharpness ); + int FactoryGetPQMode_Sharpness ( int tv_source_input, int pq_mode ); + int FactorySetColorTemp_Rgain ( int source_type, int colortemp_mode, int rgain ); + int FactorySaveColorTemp_Rgain ( int source_type, int colortemp_mode, int rgain ); + int FactoryGetColorTemp_Rgain ( int source_type, int colortemp_mode ); + int FactorySetColorTemp_Ggain ( int source_type, int colortemp_mode, int ggain ); + int FactorySaveColorTemp_Ggain ( int source_type, int colortemp_mode, int ggain ); + int FactoryGetColorTemp_Ggain ( int source_type, int colortemp_mode ); + int FactorySetColorTemp_Bgain ( int source_type, int colortemp_mode, int bgain ); + int FactorySaveColorTemp_Bgain ( int source_type, int colortemp_mode, int bgain ); + int FactoryGetColorTemp_Bgain ( int source_type, int colortemp_mode ); + int FactorySetColorTemp_Roffset ( int source_type, int colortemp_mode, int roffset ); + int FactorySaveColorTemp_Roffset ( int source_type, int colortemp_mode, int roffset ); + int FactoryGetColorTemp_Roffset ( int source_type, int colortemp_mode ); + int FactorySetColorTemp_Goffset ( int source_type, int colortemp_mode, int goffset ); + int FactorySaveColorTemp_Goffset ( int source_type, int colortemp_mode, int goffset ); + int FactoryGetColorTemp_Goffset ( int source_type, int colortemp_mode ); + int FactorySetColorTemp_Boffset ( int source_type, int colortemp_mode, int boffset ); + int FactorySaveColorTemp_Boffset ( int source_type, int colortemp_mode, int boffset ); + int FactoryGetColorTemp_Boffset ( int source_type, int colortemp_mode ); + //int Tv_FactorySaveRGBDatatoAllSrc ( int source_type, int colortemp_mode ); + int FactoryGetTestPattern ( void ); + int FactoryResetPQMode ( void ); + int FactoryResetColorTemp ( void ); + int FactorySetParamsDefault ( void ); + int FactorySetDDRSSC ( int step ); + int FactoryGetDDRSSC(); + int FactorySetLVDSSSC ( int step ); + int FactoryGetLVDSSSC(); + int SetLVDSSSC(int step); + int FactorySetNolineParams ( int type, int tv_source_input, noline_params_t noline_params ); + noline_params_t FactoryGetNolineParams ( int type, int source_type ); + int FactorySetOverscan ( int source_type, int fmt, int trans_fmt, tvin_cutwin_t cutwin_t ); + tvin_cutwin_t FactoryGetOverscan ( int source_type, int fmt, is_3d_type_t is3d, int trans_fmt ); + int FactorySetGamma(tcon_gamma_table_t gamma_r, tcon_gamma_table_t gamma_g, tcon_gamma_table_t gamma_b); + + int VPPSSMFacRestoreDefault(); + + int GetColorTemperatureParams ( vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t *params ); + int SetColorTemperatureParams ( vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t params ); + int SaveColorTemperatureParams ( vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t params ); + + int FactoryResetNonlinear(); + tvin_cutwin_t GetOverscan ( tv_source_input_t tv_source_input, tvin_sig_fmt_t fmt, is_3d_type_t is3d, tvin_trans_fmt_t trans_fmt ); + int VPP_SetPLLValues (tv_source_input_t tv_source_input, tvin_port_t source_port, tvin_sig_fmt_t sig_fmt); + int VPP_SetCVD2Values (tv_source_input_t tv_source_input, tvin_port_t source_port, tvin_sig_fmt_t sig_fmt); + //api + int VPP_SetVideoCrop ( int Voffset0, int Hoffset0, int Voffset1, int Hoffset1 ); + int VPP_SetNonLinearFactor ( int value ); + int VPP_SetGrayPattern(int value); + int VPP_GetGrayPattern(); + int VPP_SetBackLight_Switch ( int value ); + int VPP_GetBackLight_Switch ( void ); + int VPP_SetScalerPathSel (const unsigned int value); + int VPP_SSMRestorToDefault(int id, bool resetAll); + int TV_SSMRecovery(); + int VPP_GetSSMStatus (void); + static CVpp *getInstance(); +private: + // + int VPP_SetCMRegisterMap ( struct cm_regmap_s *pRegMap ); + void video_set_saturation_hue ( signed char saturation, signed char hue, signed long *mab ); + void video_get_saturation_hue ( signed char *sat, signed char *hue, signed long *mab ); + int VPP_SetBackLightLevel ( int value ); + int VPP_FBCColorTempBatchGet(vpp_color_temperature_mode_t, tcon_rgb_ogo_t *); + int VPP_FBCColorTempBatchSet(vpp_color_temperature_mode_t, tcon_rgb_ogo_t); + int VPP_FBCSetColorTemperature(vpp_color_temperature_mode_t); + + static CVpp *mInstance; + bool mHdmiOutFbc; + CFbcCommunication *fbcIns; + //cfg + bool mbVppCfg_backlight_reverse; + bool mbVppCfg_backlight_init; + bool mbVppCfg_pqmode_depend_bklight; +}; +#endif diff --git a/tv/tvserver/libtv/vpp/pqdata.cpp b/tv/tvserver/libtv/vpp/pqdata.cpp new file mode 100644 index 0000000..a4513eb --- a/dev/null +++ b/tv/tvserver/libtv/vpp/pqdata.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#include "pqdata.h" + +//vpp +unsigned long DemoColorYOffRegMap[CM_REG_NUM] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80ff807f, 0x00800800, 0x00001000, 0x1077f010, + 0xf077ff10, 0x7777ff10, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80700124, 0x00000000, +}; +//vpp +unsigned long DemoColorCOffRegMap[CM_REG_NUM] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80ff807f, 0x00802800, + 0x00001000, 0x1077f010, 0xf077ff10, 0x7777ff10, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80700124, 0x00000000, +}; + +unsigned long DemoColorGOffRegMap[CM_REG_NUM] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x80ff807f, 0x00801800, 0x00001000, + 0x1077f010, 0xf077ff10, 0x7777ff10, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80700124, 0x00000000, +}; + +unsigned long DemoColorMOffRegMap[CM_REG_NUM] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80ff807f, 0x00804800, 0x00001000, 0x1077f010, 0xf077ff10, + 0x7777ff10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80700124, 0x00000000, +}; + +unsigned long DemoColorROffRegMap[CM_REG_NUM] = { + 0x80ff807f, 0x00805800, 0x00001000, 0x1077f010, 0xf077ff10, + 0x7777ff10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80700124, 0x00000000, +}; + +unsigned long DemoColorBOffRegMap[CM_REG_NUM] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80ff807f, + 0x00803800, 0x00001000, 0x1077f010, 0xf077ff10, 0x7777ff10, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80700124, 0x00000000 +}; + +unsigned long DemoColorRGBOffRegMap[CM_REG_NUM] = { + 0x80ff807f, 0x00805800, 0x00001000, 0x1077f010, 0xf077ff10, + 0x7777ff10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x80ff807f, 0x00801800, 0x00001000, + 0x1077f010, 0xf077ff10, 0x7777ff10, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80ff807f, + 0x00803800, 0x00001000, 0x1077f010, 0xf077ff10, 0x7777ff10, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80700124, 0x00000000, +}; + +unsigned long DemoColorYMCOffRegMap[CM_REG_NUM] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80ff807f, 0x00800800, 0x00001000, 0x1077f010, + 0xf077ff10, 0x7777ff10, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80ff807f, 0x00802800, + 0x00001000, 0x1077f010, 0xf077ff10, 0x7777ff10, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80ff807f, 0x00804800, 0x00001000, 0x1077f010, 0xf077ff10, + 0x7777ff10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80700124, 0x00000000, +}; + +unsigned long DemoColorALLOffRegMap[CM_REG_NUM] = { + 0x81ff8080, 0x00805800, 0x00001000, 0x0077ff00, 0xff77ff00, + 0x7777ff00, 0x80ff8080, 0x00800800, 0x00001000, 0x0077ff00, + 0xff77ff00, 0x7777ff00, 0x80ff8080, 0x00a01800, 0x00000ccd, + 0x0077ff00, 0xff77ff00, 0x7777ff00, 0x80ff8080, 0x00ff2800, + 0x00000800, 0x0077ff00, 0xff77ff00, 0x7777ff00, 0x80ff8080, + 0x00ff3c00, 0x00000800, 0x0077ff00, 0xff77ff00, 0x7777ff00, + 0x80ff8080, 0x00ff4c00, 0x00000800, 0x0077ff00, 0x00000000, + 0x7777ff00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xff77ff00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80700124, 0x00000000, +}; + +unsigned long DemoColorSplit4_3RegMap[CM_REG_NUM] = { + 0x8A58821E, 0x00525911, 0x000018FA, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8A3F8A14, 0x002803BB, 0x00003333, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8A6C8A24, 0x00130911, 0x00006BCA, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8AA48A50, 0x00440BBB, 0x00001E1E, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8ACC8221, 0x00AA1488, 0x00000C0C, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8AF48A24, 0x00632A22, 0x000014B0, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8AFF8A4C, 0x008536EE, 0x00000F66, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8AC68244, 0x00854800, 0x00000F66, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8492D024, 0x81000000 +}; + +unsigned long DemoColorSplitRegMap[CM_REG_NUM] = { + 0x8A58821E, 0x00525911, 0x000018FA, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8A3F8A14, 0x002803BB, 0x00003333, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8A6C8A24, 0x00130911, 0x00006BCA, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8AA48A50, 0x00440BBB, 0x00001E1E, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8ACC8221, 0x00AA1488, 0x00000C0C, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8AF48A24, 0x00632A22, 0x000014B0, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8AFF8A4C, 0x008536EE, 0x00000F66, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8AC68244, 0x00854800, 0x00000F66, 0x1033E010, 0xE033F50A, 0x3333E010, + 0x8493C024, 0x81000000 +}; diff --git a/tv/tvserver/libtv/vpp/pqdata.h b/tv/tvserver/libtv/vpp/pqdata.h new file mode 100644 index 0000000..782b141 --- a/dev/null +++ b/tv/tvserver/libtv/vpp/pqdata.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _PQDATA_H_ +#define _PQDATA_H_ + + +#define CM_REG_NUM 50 +#define PQ_TOTAL_STEP 101 +#define GAMMA_TABLE_NUM 256 + +extern unsigned long DemoColorYOffRegMap[CM_REG_NUM]; + +extern unsigned long DemoColorCOffRegMap[CM_REG_NUM]; + +extern unsigned long DemoColorGOffRegMap[CM_REG_NUM]; + +extern unsigned long DemoColorMOffRegMap[CM_REG_NUM]; + +extern unsigned long DemoColorROffRegMap[CM_REG_NUM]; + +extern unsigned long DemoColorBOffRegMap[CM_REG_NUM]; + +extern unsigned long DemoColorRGBOffRegMap[CM_REG_NUM]; + +extern unsigned long DemoColorYMCOffRegMap[CM_REG_NUM]; + +extern unsigned long DemoColorALLOffRegMap[CM_REG_NUM]; + +extern unsigned long DemoColorSplit4_3RegMap[CM_REG_NUM]; + +extern unsigned long DemoColorSplitRegMap[CM_REG_NUM]; +#endif diff --git a/tv/tvserver/tvfbclinker/Android.mk b/tv/tvserver/tvfbclinker/Android.mk new file mode 100644 index 0000000..fcab208 --- a/dev/null +++ b/tv/tvserver/tvfbclinker/Android.mk @@ -0,0 +1,44 @@ +# Copyright (c) 2014 Amlogic, Inc. All rights reserved. +# +# This source code is subject to the terms and conditions defined in the +# file 'LICENSE' which is part of this source code package. +# +# Description: makefile + +ifeq ($(USE_ANOTHER_FBC_LINKER),) + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LIB_TV_UTILS := $(LOCAL_PATH)/../tvutils + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + CFbcLinker.cpp \ + CFbcProtocol.cpp \ + CFbcUpgrade.cpp \ + CSerialPort.cpp \ + CHdmiCecCmd.cpp \ + CVirtualInput.cpp + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/include \ + $(LIB_TV_UTILS)/include + +LOCAL_STATIC_LIBRARIES := \ + libtv_utils + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + liblog \ + libutils + +LOCAL_MODULE:= libtv_linker + +ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK) +LOCAL_PROPRIETARY_MODULE := true +endif + +include $(BUILD_SHARED_LIBRARY) +endif diff --git a/tv/tvserver/tvfbclinker/CFbcLinker.cpp b/tv/tvserver/tvfbclinker/CFbcLinker.cpp new file mode 100644 index 0000000..fb2162c --- a/dev/null +++ b/tv/tvserver/tvfbclinker/CFbcLinker.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_NDEBUG 0 + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CFbcLinker" + +#include <CTvLog.h> +#include "CFbcLinker.h" + + +static CFbcLinker *mInstance; + +CFbcLinker *getFbcLinkerInstance() +{ + if (mInstance == NULL) { + mInstance = new CFbcLinker(); + } + return mInstance; +} + +CFbcLinker::CFbcLinker() +{ + pUpgradeIns = getFbcUpgradeInstance(); + pProtocolIns = GetFbcProtocolInstance(); +} + +CFbcLinker::~CFbcLinker() +{ + if (pUpgradeIns != NULL) { + pUpgradeIns->stop(); + delete pUpgradeIns; + pUpgradeIns = NULL; + } + if (pProtocolIns != NULL) { + delete pProtocolIns; + pProtocolIns = NULL; + } +} + +int CFbcLinker::sendCommandToFBC(unsigned char *data, int count, int flag) +{ + LOGV("%s, dev_type=%d, cmd_id=%d, flag=%d", __FUNCTION__, *data, *(data+1), flag); + + if (count < 2) + return -1; + + int ret = -1; + if (pProtocolIns != NULL) { + COMM_DEV_TYPE_E toDev = (COMM_DEV_TYPE_E)*data; + if (flag == 1) {//get something from fbc + ret = pProtocolIns->fbcGetBatchValue(toDev, (unsigned char*)(data+1), count-1); + } else {//set something to fbc + ret = pProtocolIns->fbcSetBatchValue(toDev, (unsigned char*)(data+1), count-1); + } + } + return ret; +} + +int CFbcLinker::setUpgradeFbcObserver(IUpgradeFBCObserver *pOb) +{ + pUpgradeIns->setObserver(pOb); + return 0; +} + +int CFbcLinker::startFBCUpgrade(char *file_name, int mode, int blk_size) +{ + pUpgradeIns->SetUpgradeFileName(file_name); + pUpgradeIns->SetUpgradeMode(mode); + pUpgradeIns->SetUpgradeBlockSize(blk_size); + pUpgradeIns->start(); + return 0; +} + +int sendCommandToFBC(unsigned char *data, int count, int flag) +{ + CFbcLinker *pLinker = getFbcLinkerInstance(); + if (pLinker == NULL) + return -1; + + if (CMD_FBC_RELEASE == (fbc_command_t)*(data+1) && pLinker != NULL) { + delete pLinker; + pLinker = NULL; + return -1; + } + + return pLinker->sendCommandToFBC(data, count, flag); +} + +int startFBCUpgrade(char *file_name, int blk_size, int mode) +{ + CFbcLinker *pLinker = getFbcLinkerInstance(); + if (pLinker == NULL) + return -1; + return pLinker->startFBCUpgrade(file_name, mode, blk_size); +} + +int setUpgradeFbcObserver(IUpgradeFBCObserver *pOb) +{ + CFbcLinker *pLinker = getFbcLinkerInstance(); + if (pLinker == NULL) + return -1; + return pLinker->setUpgradeFbcObserver(pOb); +} + diff --git a/tv/tvserver/tvfbclinker/CFbcProtocol.cpp b/tv/tvserver/tvfbclinker/CFbcProtocol.cpp new file mode 100644 index 0000000..be3dff8 --- a/dev/null +++ b/tv/tvserver/tvfbclinker/CFbcProtocol.cpp @@ -0,0 +1,606 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_NDEBUG 0 + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CFbcProtocol" + +#include "CFbcProtocol.h" +#include <time.h> +#include <CTvLog.h> + + +static CFbcProtocol *mInstace = NULL; +CFbcProtocol *GetFbcProtocolInstance(unsigned int baud_rate) +{ + if (mInstace == NULL) { + mInstace = new CFbcProtocol(); + if (NULL == mInstace || (-1 == mInstace->start(baud_rate))) { + + if (mInstace) + delete mInstace; + + mInstace = NULL; + + LOGD ("Create FbcProtocolInstance Failure!"); + } + } + + return mInstace; +} + +void ResetFbcProtocolInstance() +{ + if (mInstace) + delete mInstace; + + mInstace = NULL; +} + +CFbcProtocol::CFbcProtocol() +{ + initCrc32Table(); + + m_event.data.fd = -1; + m_event.events = EPOLLIN | EPOLLET; + + mpRevDataBuf = new unsigned char[512]; + + mUpgradeFlag = 0; + mbDownHaveSend = 0;//false + //mFbcMsgQueue.startMsgQueue(); + mbFbcKeyEnterDown = 0;//false + mFbcEnterKeyDownTime = -1; +} + +CFbcProtocol::~CFbcProtocol() +{ + m_event.data.fd = mSerialPort.getFd(); + m_event.events = EPOLLIN | EPOLLET; + mEpoll.del(mSerialPort.getFd(), &m_event); + closeAll(); + delete[] mpRevDataBuf; +} + +int CFbcProtocol::start(unsigned int baud_rate) +{ + //int serial_port = config_get_int("TV", "fbc.communication.serial", SERIAL_C); + if (mSerialPort.OpenDevice(SERIAL_C) < 0) { + } else { + LOGD("%s %d be called......\n", __FUNCTION__, __LINE__); + mSerialPort.setup_serial(baud_rate); + } + + if (mEpoll.create() < 0) { + return -1; + } + + m_event.data.fd = mSerialPort.getFd(); + m_event.events = EPOLLIN | EPOLLET; + mEpoll.add(mSerialPort.getFd(), &m_event); + + //timeout for long + mEpoll.setTimeout(3000); + + this->run("CFbcProtocol"); + return 0; +} + +void CFbcProtocol::testUart() +{ + unsigned char write_buf[64], read_buf[64]; + int idx = 0; + memset(write_buf, 0, sizeof(write_buf)); + memset(read_buf, 0, sizeof(read_buf)); + + write_buf[0] = 0x5a; + write_buf[1] = 0x5a; + write_buf[2] = 0xb; + write_buf[3] = 0x0; + write_buf[4] = 0x0; + write_buf[5] = 0x40; + write_buf[6] = 0x0; + + write_buf[7] = 0x2; + write_buf[8] = 0x3c; + write_buf[9] = 0x75; + write_buf[10] = 0x30; + //LOGD("to write ..........\n"); + mSerialPort.writeFile(write_buf, 11); + sleep(1); + //LOGD("to read........\n"); + mSerialPort.readFile(read_buf, 12); + for (idx = 0; idx < 12; idx++) + LOGD("the data is:0x%x\n", read_buf[idx]); + LOGD("end....\n"); +} + +void CFbcProtocol::showTime(struct timeval *_time) +{ + struct timeval curTime; + + if (_time == NULL) { + gettimeofday(&curTime, NULL); + } else { + curTime.tv_sec = _time->tv_sec; + curTime.tv_usec = _time->tv_usec; + } + if (curTime.tv_usec > 100000) { + LOGD("[%ld.%ld]", curTime.tv_sec, curTime.tv_usec); + } else if (curTime.tv_usec > 10000) { + LOGD("[%ld.0%ld]", curTime.tv_sec, curTime.tv_usec); + } else if (curTime.tv_usec > 1000) { + LOGD("[%ld.00%ld]", curTime.tv_sec, curTime.tv_usec); + } else if (curTime.tv_usec > 100) { + LOGD("[%ld.000%ld]", curTime.tv_sec, curTime.tv_usec); + } else if (curTime.tv_usec > 10) { + LOGD("[%ld.0000%ld]", curTime.tv_sec, curTime.tv_usec); + } else if (curTime.tv_usec > 1) { + LOGD("[%ld.00000%ld]", curTime.tv_sec, curTime.tv_usec); + } +} + +long CFbcProtocol::getTime(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +void CFbcProtocol::initCrc32Table() +{ + int i, j; + unsigned int Crc; + for (i = 0; i < 256; i++) { + Crc = i; + for (j = 0; j < 8; j++) { + if (Crc & 1) + Crc = (Crc >> 1) ^ 0xEDB88320; + else + Crc >>= 1; + } + mCrc32Table[i] = Crc; + } +} + +void CFbcProtocol::sendAckCmd(bool isOk) +{ + int crc32value = 0; + unsigned char ackcmd[12]; + ackcmd[0] = 0x5A; + ackcmd[1] = 0x5A; + ackcmd[2] = 12;//little endian + ackcmd[3] = 0x00; + ackcmd[4] = 0x80;//ack flag + ackcmd[5] = 0xff;//cmd id + if (isOk) { + ackcmd[6] = 0xfe; + ackcmd[7] = 0x7f; + } else { + ackcmd[6] = 0x80; + ackcmd[7] = 0x01; + } + //*((unsigned int*) (ackcmd + 8)) = GetCrc32(ackcmd, 8); + crc32value = Calcrc32(0, ackcmd, 8); + ackcmd[8] = (crc32value >> 0) & 0xFF; + ackcmd[9] = (crc32value >> 8) & 0xFF; + ackcmd[10] = (crc32value >> 16) & 0xFF; + ackcmd[11] = (crc32value >> 24) & 0xFF; + LOGD("to send ack and crc is:0x%x\n", crc32value); + sendDataOneway(COMM_DEV_SERIAL, ackcmd, 12, 0x00000000); +} + +unsigned int CFbcProtocol::GetCrc32(unsigned char *InStr, unsigned int len) +{ + unsigned int Crc = 0xffffffff; + for (int i = 0; i < (int)len; i++) { + Crc = (Crc >> 8) ^ mCrc32Table[(Crc & 0xFF) ^ InStr[i]]; + } + + Crc ^= 0xFFFFFFFF; + return Crc; +} + +unsigned int CFbcProtocol::Calcrc32(unsigned int crc, const unsigned char *ptr, unsigned int buf_len) +{ + static const unsigned int s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, + 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344, 0xd6d6a3e8, + 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c}; + unsigned int crcu32 = crc; + //if (buf_len < 0) + // return 0; + if (!ptr) return 0; + crcu32 = ~crcu32; + while (buf_len--) { + unsigned char b = *ptr++; + crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; + crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; + } + return ~crcu32; +} + +int CFbcProtocol::sendDataOneway(int devno, unsigned char *pData, int dataLen, int flags __unused) +{ + int ret = -1; + if (COMM_DEV_CEC == devno) + ret = mHdmiCec.writeFile(pData, dataLen); + else if (COMM_DEV_SERIAL == devno) + ret = mSerialPort.writeFile(pData, dataLen); + return ret; +} + +//timeout ms +int CFbcProtocol::sendDataAndWaitReply(int devno, int waitForDevno, int waitForCmd, unsigned char *pData, int dataLen, int timeout, unsigned char *pReData, int *reDataLen, int flags) +{ + int ret = sendDataOneway(devno, pData, dataLen, flags); + if (ret < 0) return ret; + + mReplyList.WaitDevNo = waitForDevno; + mReplyList.WaitCmd = waitForCmd; + mReplyList.WaitTimeOut = timeout; + mReplyList.reDataLen = 0; + mReplyList.replyData = mpRevDataBuf; + LOGD("wait dev:%d, cmd:0x%x, timeout:%d", mReplyList.WaitDevNo, mReplyList.WaitCmd, mReplyList.WaitTimeOut); + + mLock.lock(); + ret = mReplyList.WaitReplyCondition.waitRelative(mLock, timeout);//wait reply + LOGD("%s, %d, wait reply return = %d", __FUNCTION__, __LINE__, ret); + mLock.unlock(); + + if (mReplyList.reDataLen > 0) { //data have come in + *reDataLen = mReplyList.reDataLen; + memcpy(pReData, mReplyList.replyData, mReplyList.reDataLen); + mReplyList.reDataLen = 0; + return *reDataLen; + } else { + //timeout,not to wait continue + mReplyList.WaitDevNo = -1; + mReplyList.WaitCmd = 0xff; + return -1;//timeout but data not come. + } + return 0; +} + +int CFbcProtocol::closeAll() +{ + mSerialPort.CloseDevice(); + return 0; +} + +int CFbcProtocol::SetUpgradeFlag(int flag) +{ + mUpgradeFlag = flag; + return 0; +} + +int CFbcProtocol::uartReadStream(unsigned char *retData, int rd_max_len, int timeout) +{ + int readLen = 0, bufIndex = 0, haveRead = 0; + long startTime = getTime(); + + do { + readLen = mSerialPort.readFile(retData + bufIndex, rd_max_len - haveRead); + haveRead += readLen; + bufIndex += readLen; + if (haveRead == rd_max_len) { + return haveRead; + } + + LOGD("readLen = %d, haveRead = %d\n", readLen, haveRead); + + if (getTime() - startTime > timeout) + return haveRead; + } while (true); + + return haveRead; +} + +int CFbcProtocol::uartReadData(unsigned char *retData, int *retLen) +{ + unsigned char tempBuf[512]; + int cmdLen = 0; + int bufIndex = 0; + int readLen = 0; + + if (retData == NULL) { + LOGD("the retData is NULL"); + return 0; + } + + //leader codes 2 byte + memset(tempBuf, 0, sizeof(tempBuf)); + do { + readLen = mSerialPort.readFile(tempBuf + 0, 1); + if (tempBuf[0] == 0x5A) { + bufIndex = 1; + readLen = mSerialPort.readFile(tempBuf + 1, 1); + if (tempBuf[1] == 0x5A) { + bufIndex = 2; + LOGD("leading code coming..."); + break; + } + } + } while (true); + + //data len 2 byte + int needRead = 2, haveRead = 0; + do { + readLen = mSerialPort.readFile(tempBuf + bufIndex, needRead - haveRead); + haveRead += readLen; + bufIndex += readLen; + if (haveRead == needRead) { + break; + } + } while (true); + + //little endian + cmdLen = (tempBuf[3] << 8) + tempBuf[2]; + //cmd data cmdLen - 2 -2 + needRead = cmdLen - 4, haveRead = 0; + LOGD("cmdLen is:%d\n", cmdLen); + + do { + readLen = mSerialPort.readFile(tempBuf + bufIndex, needRead - haveRead); + haveRead += readLen; + bufIndex += readLen; + if (readLen > 0) { + LOGD("data readLen is:%d\n", readLen); + } + if (haveRead == needRead) { + break; + } + } while (true); + + unsigned int crc = 0; + if (cmdLen > 4) { + crc = Calcrc32(0, tempBuf, cmdLen - 4);//not include crc 4byte + } + unsigned int bufCrc = tempBuf[cmdLen - 4] | + tempBuf[cmdLen - 3] << 8 | + tempBuf[cmdLen - 2] << 16 | + tempBuf[cmdLen - 1] << 24; + if (crc == bufCrc) { + memcpy(retData, tempBuf, cmdLen % 512); + *retLen = cmdLen; + return cmdLen; + } + + return -1; +} + +int CFbcProtocol::processData(COMM_DEV_TYPE_E fromDev, unsigned char *pData, int dataLen) +{ + __u16 key_code = 0; + switch (fromDev) { + case COMM_DEV_CEC: { + if (mReplyList.WaitDevNo == fromDev && mReplyList.WaitCmd == pData[1]) { + mReplyList.reDataLen = dataLen; + memcpy(mReplyList.replyData, pData, dataLen); + mReplyList.WaitReplyCondition.signal(); + } + } + break; + + case COMM_DEV_SERIAL: { + if (mReplyList.WaitDevNo == fromDev && mReplyList.WaitCmd == pData[5]) { + mReplyList.reDataLen = dataLen; + memcpy(mReplyList.replyData, pData, dataLen); + mReplyList.WaitReplyCondition.signal(); + } else { + //unsigned char cmd = pData[5]; + if (mbSendKeyCode) { + if (0x14 == pData[5]) { + key_code =(key_code | (pData[7]<<8)) | pData[6]; + LOGD("to signal wait dataLen:0x%x, cmdId:0x%x , ,key:%d\n", dataLen, pData[5],key_code); + mCVirtualInput.sendVirtualkeyEvent(key_code); + } + } + } + } + break; + } + return 0; +} + +bool CFbcProtocol::threadLoop() +{ + unsigned char readFrameBuf[512]; + while (!exitPending()) { //requietexit() or requietexitWait() not call + while (mUpgradeFlag == 1) { + usleep(1000 * 1000); + } + + int num = mEpoll.wait(); + + while (mUpgradeFlag == 1) { + usleep(1000 * 1000); + } + + for (int i = 0; i < num; ++i) { + int fd = (mEpoll)[i].data.fd; + /** + * EPOLLIN event + */ + if ((mEpoll)[i].events & EPOLLIN) { + if (fd == mHdmiCec.getFd()) { //ce-----------------------------c + int bufIndex = 0; + int needRead = 4; + int haveRead = 0; + int idx = 0, readLen = 0; + do { + readLen = mHdmiCec.readFile(readFrameBuf + bufIndex, needRead - haveRead); + haveRead += readLen; + bufIndex += readLen; + //if(haveRead == needRead) break; + } while (0); + + if (readLen > 0) { + processData(COMM_DEV_CEC, readFrameBuf, readLen); + } else { + } + } else if (fd == mSerialPort.getFd()) { + //seria---------------------------l + int cmdLen = 0, idx = 0; + LOGD("serial data come"); + memset(readFrameBuf, 0, 512); + int ret = uartReadData(readFrameBuf, &cmdLen); + + if (ret == -1) { //data error + sendAckCmd(false); + } else if (readFrameBuf[4] == 0x80) { //ack + LOGD("is ack come"); +#ifdef TV_RESEND_UMUTE_TO_FBC + if (((readFrameBuf[7] << 8) | readFrameBuf[6]) == 0x8001 && + readFrameBuf[5] == AUDIO_CMD_SET_MUTE) { + LOGD("resend unmute to 101 avoid 101 receiving unmute timeout\n"); + Fbc_Set_Value_INT8(COMM_DEV_SERIAL, AUDIO_CMD_SET_MUTE, 1); + } +#endif + } else { //not ack + sendAckCmd(true); + processData(COMM_DEV_SERIAL, readFrameBuf, cmdLen); + } + } + } + + /** + * EPOLLOUT event + */ + //if ((mEpoll)[i].events & EPOLLOUT) { + //} + } + } + //exit + //return true, run again, return false,not run. + LOGD("thread exited..........\n"); + return false; +} + +int CFbcProtocol::fbcSetBatchValue(COMM_DEV_TYPE_E toDev, unsigned char *cmd_buf, int count) +{ + LOGV("%s, dev_type=%d, cmd_id=%d, count=%d, mUpgradeFlag=%d", __FUNCTION__, toDev, *cmd_buf, count, mUpgradeFlag); + if (mUpgradeFlag == 1) { + return 0; + } + + if ( 512 <= count) { + return -1; + } + + if (toDev == COMM_DEV_CEC) { + unsigned char cmd[512], rxbuf[512]; + int rxlen = 0, idx = 0; + memset(cmd, 0, 512); + memset(rxbuf, 0, 512); + cmd[0] = 0x40; + for (idx = 0; idx < count; idx++) { + cmd[idx + 1] = cmd_buf[idx]; + } + sendDataOneway(COMM_DEV_CEC, cmd, count + 1, 0); + } else if (toDev == COMM_DEV_SERIAL) { + int crc32value = 0; + unsigned char write_buf[512]; + unsigned char rxbuf[512]; + int rxlen = 0, idx = 0; + + //leading code + write_buf[0] = 0x5a; + write_buf[1] = 0x5a; + //package length from begin to end + write_buf[2] = (count + 9) & 0xFF; + write_buf[3] = ((count + 9) >> 8) & 0xFF; + //Ack byte : 0x80-> ack package;0x00->normal package; + write_buf[4] = 0x00; + + for (idx = 0; idx < count; idx++) { + write_buf[idx + 5] = cmd_buf[idx]; + } + //crc32 little Endian + crc32value = Calcrc32(0, write_buf, count + 5); + write_buf[count + 5] = (crc32value >> 0) & 0xFF; + write_buf[count + 6] = (crc32value >> 8) & 0xFF; + write_buf[count + 7] = (crc32value >> 16) & 0xFF; + write_buf[count + 8] = (crc32value >> 24) & 0xFF; + + sendDataOneway(COMM_DEV_SERIAL, write_buf, count + 9, 0); + } + return 0; +} + +int CFbcProtocol::fbcGetBatchValue(COMM_DEV_TYPE_E fromDev, unsigned char *cmd_buf, int count) +{ + LOGV("%s, dev_type=%d, cmd_id=%d, count=%d, mUpgradeFlag=%d", __FUNCTION__, fromDev, *cmd_buf, count, mUpgradeFlag); + if (mUpgradeFlag == 1) { + return 0; + } + + if ( 512 <= count) { + return -1; + } + int ret = 0; + // TODO: read value + if (fromDev == COMM_DEV_CEC) { + unsigned char cmd[512], rxbuf[512]; + int rxlen = 0, idx = 0; + memset(cmd, 0, 512); + memset(rxbuf, 0, 512); + cmd[0] = 0x40; + cmd[1] = cmd_buf[0]; + sendDataAndWaitReply(COMM_DEV_CEC, COMM_DEV_CEC, cmd[1], cmd, count + 1, 0, rxbuf, &rxlen, 0); + + if (rxlen > 2) { + for (idx = 0; idx < rxlen; idx++) { + cmd_buf[idx] = cmd[idx + 1]; + } + } + } else if (fromDev == COMM_DEV_SERIAL) { + int crc32value = 0, idx = 0, rxlen = 0; + unsigned char write_buf[512]; + unsigned char rxbuf[512]; + memset(write_buf, 0, 512); + memset(rxbuf, 0, 512); + + //leading code + write_buf[0] = 0x5a; + write_buf[1] = 0x5a; + //package length from begin to end + write_buf[2] = (count + 9) & 0xFF; + write_buf[3] = ((count + 9) >> 8) & 0xFF; + //Ack byte + write_buf[4] = 0x00; + //cmd ID + for (idx = 0; idx < count; idx++) { + write_buf[idx + 5] = cmd_buf[idx]; + } + //crc32 little Endian + crc32value = Calcrc32(0, write_buf, count + 5); + write_buf[count + 5] = (crc32value >> 0) & 0xFF; + write_buf[count + 6] = (crc32value >> 8) & 0xFF; + write_buf[count + 7] = (crc32value >> 16) & 0xFF; + write_buf[count + 8] = (crc32value >> 24) & 0xFF; + sendDataAndWaitReply(COMM_DEV_SERIAL, COMM_DEV_SERIAL, write_buf[5], write_buf, write_buf[2], 2000, rxbuf, &rxlen, 0); + + if (rxlen > 9) { + for (idx = 0; idx < (rxlen - 9); idx++) { + cmd_buf[idx] = rxbuf[idx + 5]; + } + } + ret = rxlen; + } + + return ret; +} + +void CFbcProtocol::CFbcMsgQueue::handleMessage ( CMessage &msg ) +{ + LOGD ( "%s, CFbcProtocol::CFbcMsgQueue::handleMessage type = %d", __FUNCTION__, msg.mType ); + //msg.mType is TV_MSG_COMMON or TV_MSG_SEND_KEY +} + diff --git a/tv/tvserver/tvfbclinker/CFbcUpgrade.cpp b/tv/tvserver/tvfbclinker/CFbcUpgrade.cpp new file mode 100644 index 0000000..96d2a78 --- a/dev/null +++ b/tv/tvserver/tvfbclinker/CFbcUpgrade.cpp @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CFbcUpgrade" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/prctl.h> +#include <fcntl.h> +#include <errno.h> +#include <CTvLog.h> + +#include "CFbcUpgrade.h" + +static CFbcUpgrade *mInstance; + +CFbcUpgrade *getFbcUpgradeInstance() +{ + if (mInstance == NULL) + mInstance = new CFbcUpgrade(); + + return mInstance; +} + +CFbcUpgrade::CFbcUpgrade() +{ + mUpgradeMode = CC_UPGRADE_MODE_MAIN; + mFileName[0] = 0; + + mOPTotalSize = 0; + mBinFileSize = 0; + mBinFileBuf = NULL; + mUpgradeBlockSize = 0x10000; + //mNewBaudRate = 115200*2;//Default AdjustUpgradeSpeed baudRate + mNewBaudRate = 0; + + mpObserver = NULL; + mState = STATE_STOPED; + mCfbcIns = GetFbcProtocolInstance(); + mCfbcIns->SetUpgradeFlag(0); +} + +CFbcUpgrade::~CFbcUpgrade() +{ + if (mBinFileBuf != NULL) { + delete mBinFileBuf; + mBinFileBuf = NULL; + } +} + +int CFbcUpgrade::start() +{ + if (mState == STATE_STOPED || mState == STATE_ABORT + || mState == STATE_FINISHED) { + mCfbcIns->SetUpgradeFlag(1); + this->run("CFbcUpgrade"); + } else { + mCfbcIns->SetUpgradeFlag(0); + LOGD("%s, Upgrade is running now...\n", __FUNCTION__); + } + + return 0; +} + +int CFbcUpgrade::stop() +{ + requestExit(); + mState = STATE_STOPED; + + return 0; +} + +void CFbcUpgrade::SetUpgradeBaudRate(unsigned int baudRate) +{ + mNewBaudRate = baudRate; +} + +int CFbcUpgrade::SetUpgradeFileName(char *file_name) +{ + if (NULL == file_name) + return -1; + + strcpy(mFileName, file_name); + + return 0; +} + +int CFbcUpgrade::SetUpgradeBlockSize(int block_size) +{ + mUpgradeBlockSize = block_size; + + return 0; +} + +//TODO, from fbc3 mode is invalid, partition describe upgrade infomation +int CFbcUpgrade::SetUpgradeMode(int mode) +{ + int tmp_val = 0; + + tmp_val = mUpgradeMode; + mUpgradeMode = mode; + + return tmp_val; +} + +int CFbcUpgrade::AddCRCToDataBuf(unsigned char data_buf[], int data_len) +{ + unsigned int tmp_crc = 0; + + tmp_crc = mCfbcIns->Calcrc32(0, data_buf, data_len); + + data_buf[data_len + 0] = (tmp_crc >> 0) & 0xFF; + data_buf[data_len + 1] = (tmp_crc >> 8) & 0xFF; + data_buf[data_len + 2] = (tmp_crc >> 16) & 0xFF; + data_buf[data_len + 3] = (tmp_crc >> 24) & 0xFF; + + return 0; +} + +CFbcUpgrade::partition_info_t* CFbcUpgrade::getPartitionInfoUpgFile(int section, + int partition) +{ + unsigned int offset = 0; + partition_info_t* ret = NULL; + + if (PARTITION_FIRST_BOOT == partition) { + offset = FIRST_BOOT_INFO_OFFSET; + } else if ((section < SECTION_NUM) && (partition < PARTITION_NUM)) { + offset = section ? SECTION_1_INFO_OFFSET : SECTION_0_INFO_OFFSET; + offset += PARTITION_INFO_SIZE * (partition - 1); + } + + ret = reinterpret_cast<partition_info_t*>(mBinFileBuf + offset); + + return ret; +} + +bool CFbcUpgrade::parseUpgradeInfo(const int section, const int partition, + int &start, int &length) +{ + bool ret = true; + partition_info_t *info = NULL; + + if (SECTION_0 == section) { + info = getPartitionInfoUpgFile(section, partition); + + switch (partition) { + case PARTITION_FIRST_BOOT: + case PARTITION_SECOND_BOOT: + case PARTITION_SUSPEND: + case PARTITION_UPDATE: + start = info->code_offset; + length = info->code_size + info->data_size; + break; + case PARTITION_MAIN: + start = info->code_offset; + length = info->code_size + info->data_size + info->spi_code_size + + info->readonly_size + info->audio_param_size + + info->sys_param_size; + break; + case PARTITION_PQ: + case PARTITION_USER: + //case PARTITION_FACTORY: + start = info->data_offset; + length = info->data_size; + break; + default: + ret = false; + break; + } + } else { + ret = false; + } + + //LOGD("%s, start:%08x, length:%08x\n", __FUNCTION__, start, length); + + return ret; +} + +bool CFbcUpgrade::initBlocksInfo(std::list<sectionInfo> &mList) +{ + int currentPartition = 0; + int start = 0, length = 0; + bool ret = true; + + mList.clear(); + + //TODO - Only PcTool factory mode support upgrade KEY, FIRST_BOOT, FIRST_BOOT_INFO + /* + mList.push_back(sectionInfo(KEY_OFFSET, KEY_SIZE, "key")); + mOPTotalSize += KEY_SIZE; + mList.push_back(sectionInfo(FIRST_BOOT_INFO_OFFSET, FIRST_BOOT_INFO_SIZE, "first boot info")); + mOPTotalSize += FIRST_BOOT_INFO_SIZE; + */ + mList.push_back(sectionInfo(SECTION_0_INFO_OFFSET, SECTION_INFO_SIZE)); + mOPTotalSize += SECTION_INFO_SIZE; + + for (currentPartition = PARTITION_SECOND_BOOT; + currentPartition < PARTITION_NUM; currentPartition++) { + if (!parseUpgradeInfo(SECTION_0, currentPartition, start, length)) { + ret = false; + mList.clear(); + break; + } + + mList.push_back(sectionInfo(start, length)); + mOPTotalSize += length; + } + + return ret; +} + +bool CFbcUpgrade::sendUpgradeCmd(int &ret_code) +{ + int cmdLen; + bool ret = true; + unsigned int cmd; + + if (mNewBaudRate != 0) { + cmd = FBC_REBOOT_UPGRADE_AUTO_SPEED; + cmdLen = 14; + } + else { + cmd = FBC_REBOOT_UPGRADE; + cmdLen = 10; + } + + mDataBuf[0] = 0x5A; + mDataBuf[1] = 0x5A; + mDataBuf[2] = cmdLen + 4; + mDataBuf[3] = 0x00; + mDataBuf[4] = 0x00; + mDataBuf[5] = cmd; + mDataBuf[6] = 0x88; + mDataBuf[7] = 0x88; + mDataBuf[8] = 0x88; + mDataBuf[9] = 0x88; + + if (mNewBaudRate != 0) + memcpy (mDataBuf + 10, &mNewBaudRate, 4); + + AddCRCToDataBuf(mDataBuf, cmdLen); + + if (mCfbcIns->sendDataOneway(COMM_DEV_SERIAL, mDataBuf, cmdLen + 4, 0) + <= 0) { + LOGD ("sendUpgradeCmd failure!!!\n"); + ret_code = ERR_SERIAL_CONNECT; + ret = false; + } + + return ret; +} + +bool CFbcUpgrade::checkUpgradeConfigure(int &ret_code) +{ + bool ret = true; + + if (mUpgradeBlockSize != 0x10000) { + ret_code = ERR_NOT_CORRECT_UPGRADE_BLKSIZE; + ret = false; + LOGD("%s() - blockSize:%d not support\n", __func__, mUpgradeBlockSize); + } + + if (mUpgradeMode < 0) { + ret_code = ERR_NOT_SUPPORT_UPGRADE_MDOE; + ret = false; + LOGD("%s() - upgradeMode:%d not support\n", __func__, mUpgradeMode); + } + + return ret; +} + +bool CFbcUpgrade::check_partition(unsigned char *fileBuff, partition_info_t *info) +{ + unsigned int crc = 0; + int crc_flag = 0; + bool ret = true; + + if (info) { + if (info->code_offset && info->code_size) { + crc = mCfbcIns->Calcrc32(crc, fileBuff + info->code_offset, info->code_size); + crc_flag = 1; + } + + if (info->data_offset && info->data_size) { + crc = mCfbcIns->Calcrc32(crc, fileBuff + info->data_offset, info->data_size); + crc_flag = 1; + } + + if (0 == crc_flag || crc != info->crc) + ret = false; + } + + return ret; +} + + +bool CFbcUpgrade::loadUpgradeFile(int &ret_code, + std::list<sectionInfo> &partitionList) +{ + struct stat tmp_st; + bool ret = true; + + int file_handle = open(mFileName, O_RDONLY); + + if (file_handle < 0) { + LOGE("%s, Can't Open file %s\n", __FUNCTION__, mFileName); + ret_code = ERR_OPEN_BIN_FILE; + ret = false; + } + + if (ret && (-1 == stat(mFileName, &tmp_st))) { + ret_code = ERR_OPEN_BIN_FILE; + ret = false; + } + + if (ret && tmp_st.st_size != 0x200000 && tmp_st.st_size != 0x400000) { + LOGE("%s, don't support %d size upgrade binary!\n", __FUNCTION__, + tmp_st.st_size); + ret_code = ERR_BIN_FILE_SIZE; + ret = false; + } + + if (ret) { + mBinFileSize = tmp_st.st_size; + lseek(file_handle, 0, SEEK_SET); + + mBinFileBuf = new unsigned char[mBinFileSize]; + + if (mBinFileBuf) { + memset(mBinFileBuf, 0, mBinFileSize); + int rw_size = read(file_handle, mBinFileBuf, mBinFileSize); + + if (rw_size != mBinFileSize || rw_size <= 0) { + LOGE("%s, read file %s error(%d, %d)\n", __FUNCTION__, + mFileName, mBinFileSize, rw_size); + ret = false; + ret_code = ERR_READ_BIN_FILE; + } + } else { + LOGE("%s, Malloc mBinFileBuf failure\n", __FUNCTION__); + ret = false; + ret_code = ERR_OPEN_BIN_FILE; + } + + close(file_handle); + } + + if (ret && !initBlocksInfo(partitionList)) { + ret_code = ERR_OPEN_BIN_FILE; + ret = false; + } + + if (ret) { + partition_info_t *info = getPartitionInfoUpgFile(SECTION_0, PARTITION_FIRST_BOOT); + + if (!check_partition(mBinFileBuf, info)) { + ret_code = ERR_DATA_CRC_ERROR; + ret = false; + } + } + + return ret; +} + +bool CFbcUpgrade::AdjustUpgradeSpeed() +{ + bool ret = true; + + LOGD ("%s:%d Use baudRate:%d\n", __func__, __LINE__, mNewBaudRate); + + if (mNewBaudRate) { + mCfbcIns = GetFbcProtocolInstance(); + + if (mCfbcIns != NULL) { + ResetFbcProtocolInstance(); + + mCfbcIns = GetFbcProtocolInstance(mNewBaudRate); + + if (mCfbcIns != NULL) + mCfbcIns->SetUpgradeFlag(1); + else + ret = false; + } + else { + ret = false; + } + } + + return ret; +} + +bool CFbcUpgrade::threadLoop() +{ + unsigned char tmp_buf[128] = { 0 }; + std::list<sectionInfo> partitionList; + int start = 0, length = 0, rate = 0; + int currentWriteLength = 0, allPartitionWriteLength = 0; + int count = 0, reSendTimes = 0, ret_count = 0; + int ret_code = 0, cmd_len = 0; + bool ret = true, prepare_success = false; + + LOGD("%s, entering...\n", "TV"); + prctl(PR_SET_NAME, (unsigned long) "CFbcUpgrade thread loop"); + + if (NULL == mpObserver) + ret = false; + + if (ret && !checkUpgradeConfigure(ret_code)) + ret = false; + + if (ret && !loadUpgradeFile(ret_code, partitionList)) + ret = false; + + if (ret && !sendUpgradeCmd(ret_code)) + ret = false; + + LOGD("%s(), line:%d, upgradeFileName:%s, blkSize:%d\n", __func__, __LINE__, + mFileName, mUpgradeBlockSize); + + if (mNewBaudRate != 0) { + if (ret && !AdjustUpgradeSpeed()) { + LOGD ("AdjustUpgradeSpeed failure\n"); + ret_code = ERR_SERIAL_CONNECT; + ret = false; + } + } + + if (ret) { + prepare_success = true; + usleep(delayAfterRebootUs); + + for (std::list<sectionInfo>::iterator itor = partitionList.begin(); + !exitPending() && itor != partitionList.end(); *itor++) { + + mState = STATE_RUNNING; + currentWriteLength = 0; + + start = static_cast<sectionInfo>(*itor).start; + length = static_cast<sectionInfo>(*itor).length; + + //TODO - Avoid too old fbc fireware to upgrade successful. + if (0x49030 == start) { + start = 0x49000; + length += 0x30; + } + + LOGD("start:%08x, length:%08x\n", start, length); + + while (!exitPending() && (currentWriteLength < length)) { + + count = (mUpgradeBlockSize <= (length - currentWriteLength) ? + mUpgradeBlockSize : length - currentWriteLength); + + memcpy(mDataBuf, mBinFileBuf + start, count); + sprintf((char *) tmp_buf, "upgrade 0x%x 0x%x\n", start, count); + + cmd_len = strlen((char *) tmp_buf); + LOGD("%s, line:%d, cmd:%s. cmd_len:%d\n", __func__, __LINE__, (char*)tmp_buf, cmd_len); + if (ret + && (mCfbcIns->sendDataOneway(COMM_DEV_SERIAL, tmp_buf, cmd_len, 0) <= 0)) { + ret = false; + LOGD("Send cmd data error\n"); + } + else { + usleep(200 * 1000); + } + + if (ret + && (mCfbcIns->sendDataOneway(COMM_DEV_SERIAL, mDataBuf, count, 0) <= 0)) { + ret = false; + LOGD("Send %x upgrade data %02x,%02x,%02x ... error\n", count, mDataBuf[0], mDataBuf[1], mDataBuf[2]); + } else { + AddCRCToDataBuf(mDataBuf, count); + usleep(500 * 1000); + } + + if (ret + && (mCfbcIns->sendDataOneway(COMM_DEV_SERIAL, mDataBuf + count, 4, 0) <= 0)) { + ret = false; + LOGD("Send crc data error\n"); + } + + if (ret) { + int tmp_flag = 0; + memset(mDataBuf, 0, CC_UPGRADE_DATA_BUF_SIZE); + + ret_count = mCfbcIns->uartReadStream(mDataBuf, + CC_UPGRADE_DATA_BUF_SIZE, 2000); + + for (int i = 0; i < ret_count - 3; i++) { + if ((0x5A == mDataBuf[i]) && (0x5A == mDataBuf[i + 1]) + && (0x5A == mDataBuf[i + 2])) { + LOGD("%s, fbc write data at 0x%x ok!\n", + __FUNCTION__, start); + tmp_flag = 1; + break; + } + } + + if (0 == tmp_flag) { + reSendTimes++; + + mpObserver->onUpgradeStatus(mState, ERR_SERIAL_CONNECT); + LOGE("%s, fbc write data at 0x%x error! rewrite!\n", + __FUNCTION__, start); + + if (reSendTimes > 3) { + mState = STATE_ABORT; + ret_code = ERR_SERIAL_CONNECT; + requestExit(); + LOGE("%s, we have rewrite more than %d times, abort.\n", + __FUNCTION__, 3); + break; + } + } else { + reSendTimes = 0; + currentWriteLength += count; + allPartitionWriteLength += count; + start += count; + rate = (++allPartitionWriteLength) * 100 / mOPTotalSize; + } + + usleep(100 * 1000); + } else { + mState = STATE_ABORT; + ret_code = ERR_SERIAL_CONNECT; + requestExit(); + } + } + } + } + + LOGD("ret_code:%d\n", ret_code); + + if (mBinFileBuf != NULL) { + delete mBinFileBuf; + mBinFileBuf = NULL; + } + + LOGD("%s, exiting...\n", "TV"); + + //Avoid upgrade not start, but get this instance to upgrade again. + mState = STATE_STOPED; + mCfbcIns->SetUpgradeFlag(0); + mpObserver->onUpgradeStatus(mState, ret_code); + + if (prepare_success) { + sprintf((char *) tmp_buf, "reboot\n"); + cmd_len = strlen((char *) tmp_buf); + + if (ret_code != ERR_SERIAL_CONNECT) + mCfbcIns->sendDataOneway(COMM_DEV_SERIAL, tmp_buf, cmd_len, 0); + + usleep(500 * 1000); + mState = STATE_FINISHED; + + system("reboot"); + LOGD ("Reboot system...\n"); + } + + return false; +} diff --git a/tv/tvserver/tvfbclinker/CHdmiCecCmd.cpp b/tv/tvserver/tvfbclinker/CHdmiCecCmd.cpp new file mode 100644 index 0000000..91ddc0d --- a/dev/null +++ b/tv/tvserver/tvfbclinker/CHdmiCecCmd.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CHdmiCec" + +#include "CHdmiCecCmd.h" +CHdmiCec::CHdmiCec() +{ +} + +CHdmiCec::~CHdmiCec() +{ +} + +int CHdmiCec::readFile(unsigned char *pBuf __unused, unsigned int uLen __unused) +{ + int ret = 0; + //ret = read(mFd, pBuf, uLen); + return ret; +} + diff --git a/tv/tvserver/tvfbclinker/CSerialPort.cpp b/tv/tvserver/tvfbclinker/CSerialPort.cpp new file mode 100644 index 0000000..6914a14 --- a/dev/null +++ b/tv/tvserver/tvfbclinker/CSerialPort.cpp @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CSerialPort" + +#include "CSerialPort.h" +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <termios.h> +#include <errno.h> + +static int com_read_data(int hComm, unsigned char *pData, unsigned int uLen) +{ + char inbuff[uLen]; + char buff[uLen]; + char tempbuff[uLen]; + int i = 0, j = 0; + + memset(inbuff, '\0', uLen); + memset(buff, '\0', uLen); + memset(tempbuff, '\0', uLen); + + if (hComm < 0) { + return -1; + } + + char *p = inbuff; + + fd_set readset; + struct timeval tv; + int MaxFd = 0; + + unsigned int c = 0; + int z, k; + + do { + FD_ZERO(&readset); + FD_SET(hComm, &readset); + MaxFd = hComm + 1; + tv.tv_sec = 0; + tv.tv_usec = 100000; + do { + z = select(MaxFd, &readset, 0, 0, &tv); + } while (z == -1 && errno == EINTR); + + if (z == -1) { + hComm = -1; + break; + } + + if (z == 0) { + hComm = -1; + break; + } + + if (FD_ISSET(hComm, &readset)) { + z = read(hComm, buff, uLen - c); + c += z; + + if (z > 0) { + if (z < (signed int) uLen) { + buff[z + 1] = '\0'; + memcpy(p, buff, z); + p += z; + } else { + memcpy(inbuff, buff, z); + } + + memset(buff, '\0', uLen); + } else { + hComm = -1; + } + + if (c >= uLen) { + hComm = -1; + break; + } + } + } while (hComm >= 0); + + memcpy(pData, inbuff, c); + p = NULL; + return c; +} + +CSerialPort::CSerialPort() +{ + mDevId = -1; +} + +//close it +CSerialPort::~CSerialPort() +{ +} + +int CSerialPort::OpenDevice(int serial_dev_id) +{ + int tmp_ret = 0; + const char *dev_file_name = NULL; + + if (getFd() < 0) { + if (serial_dev_id == SERIAL_A) { + dev_file_name = DEV_PATH_S0; + } else if (serial_dev_id == SERIAL_B) { + dev_file_name = DEV_PATH_S1; + } else if (serial_dev_id == SERIAL_C) { + dev_file_name = DEV_PATH_S2; + } + + if (dev_file_name != NULL) { + mDevId = serial_dev_id; + tmp_ret = openFile(dev_file_name); + } + } + + return tmp_ret; +} + +int CSerialPort::CloseDevice() +{ + mDevId = -1; + closeFile(); + return 0; +} + +void CSerialPort::set_speed (int fd, int speed) +{ + int i; + int status; + struct termios Opt; + tcgetattr (fd, &Opt); + for (i = 0; i < (int)(sizeof (speed_arr) / sizeof (int)); i++) { + if (speed == name_arr[i]) { + tcflush (fd, TCIOFLUSH); + cfsetispeed (&Opt, speed_arr[i]); + cfsetospeed (&Opt, speed_arr[i]); + status = tcsetattr (fd, TCSANOW, &Opt); + if (status != 0) { + perror ("tcsetattr fd1"); + return; + } + tcflush (fd, TCIOFLUSH); + } + } +} + +int CSerialPort::set_Parity (int fd, int databits, int stopbits, int parity) +{ + struct termios options; + if (tcgetattr (fd, &options) != 0) { + perror ("SetupSerial 1"); + return (0); + } + options.c_cflag &= ~CSIZE; + switch (databits) { + case 7: + options.c_cflag |= CS7; + break; + case 8: + options.c_cflag |= CS8; + break; + default: + fprintf (stderr, "Unsupported data size\n"); + return (0); + } + switch (parity) { + case 'n': + case 'N': + options.c_cflag &= ~PARENB; /* Clear parity enable */ + options.c_iflag &= ~INPCK; /* Enable parity checking */ + break; + case 'o': + case 'O': + options.c_cflag |= (PARODD | PARENB); + options.c_iflag |= INPCK; /* Disnable parity checking */ + break; + case 'e': + case 'E': + options.c_cflag |= PARENB; /* Enable parity */ + options.c_cflag &= ~PARODD; + options.c_iflag |= INPCK; /* Disnable parity checking */ + break; + case 'S': + case 's': /*as no parity */ + options.c_cflag &= ~PARENB; + options.c_cflag &= ~CSTOPB; + break; + default: + fprintf (stderr, "Unsupported parity\n"); + return (0); + } + + switch (stopbits) { + case 1: + options.c_cflag &= ~CSTOPB; + break; + case 2: + options.c_cflag |= CSTOPB; + break; + default: + fprintf (stderr, "Unsupported stop bits\n"); + return (0); + } + /* Set input parity option */ + if (parity != 'n') + options.c_iflag |= INPCK; + tcflush (fd, TCIFLUSH); + options.c_cc[VTIME] = 150; + options.c_cc[VMIN] = 0; /* Update the options and do it NOW */ + //qd to set raw mode, which is copied from web + options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP + | INLCR | IGNCR | ICRNL | IXON); + options.c_oflag &= ~OPOST; + options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + options.c_cflag &= ~(CSIZE | PARENB); + options.c_cflag |= CS8; + + if (tcsetattr (fd, TCSANOW, &options) != 0) { + perror ("SetupSerial 3"); + return (0); + } + return (1); +} + +int CSerialPort::setup_serial(unsigned int baud_rate) +{ + set_speed(mFd, baud_rate); + set_Parity(mFd, 8, 1, 'N'); + return 0; +} + +int CSerialPort::set_opt(int speed, int db, int sb, char pb, int overtime, bool raw_mode) +{ + int i = 0; + struct termios old_cfg, new_cfg; + if (mFd <= 0) { + //LOGE("not open dev, when set opt"); + return -1; + } + //first get it + if (tcgetattr(mFd, &old_cfg) != 0) { + //LOGE("get serial attr error mFd = %d(%s)!\n", mFd, strerror(errno)); + return -1; + } + + //set speed + for (i = 0; i < (int)(sizeof(speed_arr) / sizeof(int)); i++) { + if (speed == name_arr[i]) { + cfsetispeed(&new_cfg, speed_arr[i]); + cfsetospeed(&new_cfg, speed_arr[i]); + break; + } + } + + setdatabits(&new_cfg, db); + setstopbits(&new_cfg, sb); + setparity(&new_cfg, pb); + + if (overtime >= 0) { + new_cfg.c_cc[VTIME] = overtime / 100; + new_cfg.c_cc[VMIN] = 0; /* Update the options and do it NOW */ + } + + if (raw_mode) { + cfmakeraw(&new_cfg); + } + + //clear + tcflush(mFd, TCIOFLUSH); + if (tcsetattr(mFd, TCSANOW, &new_cfg) < 0) { + //LOGE("%s, set serial attr error(%s)!\n", "TV", strerror(errno)); + return -1; + } + //clear,let be avail + tcflush(mFd, TCIOFLUSH); + return 0; +} + +int CSerialPort::writeFile(const unsigned char *pData, unsigned int uLen) +{ + unsigned int len; + len = write(mFd, pData, uLen); + if (len == uLen) { + return len; + } else { + tcflush(mFd, TCOFLUSH); + //LOGE("write data failed and tcflush hComm\n"); + return -1; + } +} + +int CSerialPort::readFile(unsigned char *pBuf, unsigned int uLen) +{ + //using non-block mode + return com_read_data(mFd, pBuf, uLen); +} + +int CSerialPort::setdatabits(struct termios *s, int db) +{ + if (db == 5) { + s->c_cflag = (s->c_cflag & ~CSIZE) | (CS5 & CSIZE); + } else if (db == 6) { + s->c_cflag = (s->c_cflag & ~CSIZE) | (CS6 & CSIZE); + } else if (db == 7) { + s->c_cflag = (s->c_cflag & ~CSIZE) | (CS7 & CSIZE); + } else if (db == 8) { + s->c_cflag = (s->c_cflag & ~CSIZE) | (CS8 & CSIZE); + } else { + //LOGE("Unsupported data size!\n"); + } + return 0; +} + +int CSerialPort::setstopbits(struct termios *s, int sb) +{ + if (sb == 1) { + s->c_cflag &= ~CSTOPB; + } else if (sb == 2) { + s->c_cflag |= CSTOPB; + } else { + //LOGE("Unsupported stop bits!\n"); + } + return 0; +} + +int CSerialPort::setparity(struct termios *s, char pb) +{ + if (pb == 'n' || pb == 'N') { + s->c_cflag &= ~PARENB; /* Clear parity enable */ + s->c_cflag &= ~INPCK; /* Enable parity checking */ + } else if (pb == 'o' || pb == 'O') { + s->c_cflag |= (PARODD | PARENB); + s->c_cflag |= INPCK; /* Disable parity checking */ + } else if (pb == 'e' || pb == 'E') { + s->c_cflag |= PARENB; /* Enable parity */ + s->c_cflag &= ~PARODD; + s->c_iflag |= INPCK; /* Disable parity checking */ + } else if (pb == 's' || pb == 'S') { + s->c_cflag &= ~PARENB; + s->c_cflag &= ~CSTOPB; + s->c_cflag |= INPCK; /* Disable parity checking */ + } else { + //LOGE("Unsupported parity!\n"); + } + return 0; +} + diff --git a/tv/tvserver/tvfbclinker/CVirtualInput.cpp b/tv/tvserver/tvfbclinker/CVirtualInput.cpp new file mode 100644 index 0000000..78fd551 --- a/dev/null +++ b/tv/tvserver/tvfbclinker/CVirtualInput.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CVirtualInput" + +#include "CVirtualInput.h" +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <CTvLog.h> + +CVirtualInput::CVirtualInput() +{ + setup_uinput_device(); +} + +CVirtualInput::~CVirtualInput() +{ + close(uinp_fd); +} + +int CVirtualInput::setup_uinput_device() +{ + struct uinput_user_dev uinp; // uInput device structure + // Open the input device + uinp_fd = open(DEV_UINPUT, O_WRONLY | O_NDELAY); + if (uinp_fd < 0) { + LOGE("Unable to open /dev/uinput!!!\n"); + return -1; + } + + memset(&uinp, 0, sizeof(uinp)); // Intialize the uInput device to NULL + strncpy(uinp.name, "FBC key event", UINPUT_MAX_NAME_SIZE); + uinp.id.version = 1; + uinp.id.bustype = BUS_VIRTUAL; + + // Setup the uinput device + ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY); + ioctl(uinp_fd, UI_SET_EVBIT, EV_REL); + for (int i = 0; i < 256; i++) { + ioctl(uinp_fd, UI_SET_KEYBIT, i); + } + + /* Create input device into input sub-system */ + write(uinp_fd, &uinp, sizeof(uinp)); + if (ioctl(uinp_fd, UI_DEV_CREATE)) { + LOGE("Unable to create UINPUT device.\n"); + return -1; + } + return 1; +} + +void CVirtualInput::sendVirtualkeyEvent(__u16 key_code) +{ + struct input_event event; + if (uinp_fd < 0) { + LOGE("uinput not open, sendVirtualkeyEvent failed!!!\n"); + return; + } + // Report BUTTON CLICK - PRESS event + memset(&event, 0, sizeof(event)); + gettimeofday(&event.time, NULL); + event.type = EV_KEY; + event.code = key_code; + event.value = 1; + write(uinp_fd, &event, sizeof(event)); + + event.type = EV_SYN; + event.code = SYN_REPORT; + event.value = 0; + write(uinp_fd, &event, sizeof(event)); + + // Report BUTTON CLICK - RELEASE event + memset(&event, 0, sizeof(event)); + gettimeofday(&event.time, NULL); + event.type = EV_KEY; + event.code = key_code; + event.value = 0; + + write(uinp_fd, &event, sizeof(event)); + event.type = EV_SYN; + event.code = SYN_REPORT; + event.value = 0; + write(uinp_fd, &event, sizeof(event)); +} + diff --git a/tv/tvserver/tvfbclinker/include/CFbcHelper.h b/tv/tvserver/tvfbclinker/include/CFbcHelper.h new file mode 100644 index 0000000..b75c9d4 --- a/dev/null +++ b/tv/tvserver/tvfbclinker/include/CFbcHelper.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _C_FBC_HELPER_H_ +#define _C_FBC_HELPER_H_ + +typedef enum COMM_DEV_TYPE_NO { + COMM_DEV_CEC = 0, + COMM_DEV_SERIAL = 1, +} COMM_DEV_TYPE_E; + +enum fbc_command_t { + FBC_REBOOT_UPGRADE_AUTO_SPEED = 0, + FBC_REBOOT_UPGRADE = 0x1, + FBC_USER_SETTING_DEFAULT = 0x02, + FBC_USER_SETTING_SET, + FBC_GET_HDCP_KEY, + FBC_PANEL_POWER, + FBC_SUSPEND_POWER, + //TOP CMD num:6 + VPU_CMD_INIT = 0x8, //parameter num 0 + VPU_CMD_ENABLE, //parameter num 1;bit0~6:module;bit7:enable(1) or disable(0) + VPU_CMD_BYPASS, //parameter num 1;bit0~6:module;bit7:bypass(1) or not(0) + VPU_CMD_OUTPUT_MUX, //parameter num 1;1:lvds;2:vx1;3:minilvds + VPU_CMD_TIMING, //parameter num 1;reference vpu_timing_t + VPU_CMD_SOURCE, //parameter num 1;reference vpu_source_t + VPU_CMD_GAMMA_MOD, //parameter num 1;reference vpu_gammamod_t + VPU_CMD_D2D3 = 0xf, //0xf:D2D3 + // + + CMD_BRIDGE_SW_VER = 0x10, + CMD_DEVICE_ID, + CMD_CLIENT_TYPE, + CMD_DEVICE_NUM, + CMD_ACTIVE_KEY, + CMD_ACTIVE_STATUS, + CMD_PANEL_INFO, + CMD_LVDS_SSG_SET, + + CMD_DBG_REGISTER_ACCESS = 0x18, + CMD_DBG_MEMORY_ACCESS, + CMD_DBG_SPI_ACCESS, + CMD_DBG_VPU_MEMORY_ACCESS, + CMD_DBG_MEMORY_TRANSFER, + CMD_INPUT_DOWN, + CMD_INPUT_UP, + CMD_FBC_MAIN_CODE_VERSION, + + //0x1f reserved + //PQ+debug CMD num:32 + VPU_CMD_NATURE_LIGHT_EN = 0x20, //0 or 1;on or off ???? + VPU_CMD_BACKLIGHT_EN, //0 or 1;on or off + VPU_CMD_BRIGHTNESS, //parameter num 2;parameter1:distinguish two modules;parameter2:ui value + VPU_CMD_CONTRAST, //parameter num 2;parameter1:distinguish two modules;parameter2:ui value + VPU_CMD_BACKLIGHT, //parameter num 1; + VPU_CMD_RES1, //reserved + VPU_CMD_SATURATION, //parameter num 1; + VPU_CMD_DYNAMIC_CONTRAST, //0 or 1;?? + VPU_CMD_PICTURE_MODE, //?? + VPU_CMD_PATTERN_EN, //0 or 1;on or off + VPU_CMD_PATTEN_SEL, //0x2a parameter num 1;PATTEN SELECT + VPU_CMD_RES2, + VPU_CMD_GAMMA_PATTERN, + VPU_CMD_RES4, + VPU_CMD_RES5, + VPU_CMD_USER_VMUTE = 0x2e, + VPU_CMD_USER_GAMMA, + //0x30:sound_mode_def + VPU_CMD_COLOR_TEMPERATURE_DEF = 0x31, //def:factory setting + VPU_CMD_BRIGHTNESS_DEF, + VPU_CMD_CONTRAST_DEF, + VPU_CMD_COLOR_DEF, + VPU_CMD_HUE_DEF, + VPU_CMD_BACKLIGHT_DEF, + VPU_CMD_RES7, + VPU_CMD_AUTO_LUMA_EN = 0x38,//0 or 1;on or off;appoint to backlight? + VPU_CMD_HIST, //parameter num 0;read hist info + VPU_CMD_BLEND, //parameter num ?; + VPU_CMD_DEMURA, //parameter num ?; + VPU_CMD_CSC, //parameter num ?; + VPU_CMD_CM2, //parameter num 1;index + VPU_CMD_GAMMA, //parameter num 1;index + VPU_CMD_SRCIF, + //WB CMD num:10 + VPU_CMD_RED_GAIN_DEF = 0x40, + VPU_CMD_GREEN_GAIN_DEF, + VPU_CMD_BLUE_GAIN_DEF, + VPU_CMD_PRE_RED_OFFSET_DEF, + VPU_CMD_PRE_GREEN_OFFSET_DEF, + VPU_CMD_PRE_BLUE_OFFSET_DEF, + VPU_CMD_POST_RED_OFFSET_DEF, + VPU_CMD_POST_GREEN_OFFSET_DEF, + VPU_CMD_POST_BLUE_OFFSET_DEF, + VPU_CMD_EYE_PROTECTION, + VPU_CMD_WB = 0x4a, + //DNLP PARM + VPU_CMD_DNLP_PARM, + VPU_CMD_WB_VALUE, + VPU_CMD_GRAY_PATTERN, + VPU_CMD_BURN, + CMD_HDMI_STAT, + VPU_CMD_READ = 0x80, + //VPU_CMD_HUE_ADJUST, //parameter num 1; + //VPU_CMD_WB, //parameter num 3;one parameter include two items so that six items can all be included + VPU_CMD_MAX = 50,//temp define 50 // + + //audio cmd + AUDIO_CMD_SET_SOURCE = 0x50, + AUDIO_CMD_SET_MASTER_VOLUME, + AUDIO_CMD_SET_CHANNEL_VOLUME, + AUDIO_CMD_SET_SUBCHANNEL_VOLUME, + AUDIO_CMD_SET_MASTER_VOLUME_GAIN, + AUDIO_CMD_SET_CHANNEL_VOLUME_INDEX, + AUDIO_CMD_SET_VOLUME_BAR, + AUDIO_CMD_SET_MUTE, + AUDIO_CMD_SET_EQ_MODE, + AUDIO_CMD_SET_BALANCE, + AUDIO_CMD_GET_SOURCE, + AUDIO_CMD_GET_MASTER_VOLUME, + AUDIO_CMD_GET_CHANNEL_VOLUME, + AUDIO_CMD_GET_SUBCHANNEL_VOLUME, + AUDIO_CMD_GET_MASTER_VOLUME_GAIN, + AUDIO_CMD_GET_CHANNEL_VOLUME_INDEX, + AUDIO_CMD_GET_VOLUME_BAR, + AUDIO_CMD_GET_MUTE, + AUDIO_CMD_GET_EQ_MODE, + AUDIO_CMD_GET_BALANCE, + + VPU_CMD_SET_ELEC_MODE = 0x64, + CMD_SET_LED_MODE = 0x65, + + CMD_SET_FACTORY_SN = 0x66, + CMD_GET_FACTORY_SN, + CMD_COMMUNICATION_TEST, + CMD_CLR_SETTINGS_DEFAULT, + CMD_BLUETOOTH_I2S_STATUS = 0x6a, + CMD_PANEL_ON_OFF = 0x6b, + + CMD_HDMI_REG = 0x70, + CMD_SET_PROJECT_SELECT = 0x71, + CMD_GET_PROJECT_SELECT = 0x72, + CMD_SET_LOCKN_DISABLE = 0x73, //0x73 + CMD_SET_SPLIT_SCREEN_DEMO = 0X74, + + CMD_FBC_RELEASE = 0x75, + + CMD_SET_UBOOT_STAGE = 0x7b, + + CMD_SET_AUTO_BACKLIGHT_ONFF = 0x85, + CMD_GET_AUTO_BACKLIGHT_ONFF = 0x86, + + CMD_SET_ENTER_PCMODE = 0x88, + +}; + +typedef enum fbc_upgrade_mode { + CC_UPGRADE_MODE_BOOT_MAIN = 0, + CC_UPGRADE_MODE_BOOT, + CC_UPGRADE_MODE_MAIN, + CC_UPGRADE_MODE_COMPACT_BOOT, + CC_UPGRADE_MODE_ALL, + CC_UPGRADE_MODE_MAIN_PQ_WB, + CC_UPGRADE_MODE_ALL_PQ_WB, + CC_UPGRADE_MODE_MAIN_WB, + CC_UPGRADE_MODE_ALL_WB, + CC_UPGRADE_MODE_MAIN_PQ, + CC_UPGRADE_MODE_ALL_PQ, + CC_UPGRADE_MODE_PQ_WB_ONLY, + CC_UPGRADE_MODE_WB_ONLY, + CC_UPGRADE_MODE_PQ_ONLY, + CC_UPGRADE_MODE_CUR_PQ_BIN, + CC_UPGRADE_MODE_ALL_PQ_BIN, + CC_UPGRADE_MODE_BURN, + CC_UPGRADE_MODE_DUMMY +} fbc_upgrade_mode_t; + +class IUpgradeFBCObserver { +public: + IUpgradeFBCObserver() {}; + virtual ~IUpgradeFBCObserver() {}; + virtual void onUpgradeStatus(int state, int param) = 0; +}; + +/** + * @Function sendCommandToFBC(unsigned char *data, int count, int flag) + * @Description send special command from tv to fbc. + * @Param data COMM_DEV_TYPE_E + fbc_command_t + values + * @Param count count of values from {@Param data} + * @Param flag 1 get value from fbc, 0 set value to fbc + * @Return -1 failed, 0 successful + */ +extern int sendCommandToFBC(unsigned char *data, int count, int flag); + +/** +* @Function startFBCUpgrade(char *file_name, int mode, int upgrade_blk_size) +* @Description upgrade fbc from tv. +* @Param file_name name of fbc bin. +* @Param blk_size upgrade block size (min is 4KB) +* @Param mode one type of enum fbc_upgrade_mode_t, default is all(value = 4). +* @Return -1 failed, 0 successful +*/ +extern int startFBCUpgrade(char *file_name, int blk_size, int mode = 4); + +extern int setUpgradeFbcObserver(IUpgradeFBCObserver *pOb); + +#endif diff --git a/tv/tvserver/tvfbclinker/include/CFbcLinker.h b/tv/tvserver/tvfbclinker/include/CFbcLinker.h new file mode 100644 index 0000000..ef33745 --- a/dev/null +++ b/tv/tvserver/tvfbclinker/include/CFbcLinker.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _C_FBC_LINKER_H_ +#define _C_FBC_LINKER_H_ + +#include "CFbcHelper.h" +#include "CFbcProtocol.h" +#include "CFbcUpgrade.h" + + +class CFbcLinker { +public: + CFbcLinker(); + ~CFbcLinker(); + + int sendCommandToFBC(unsigned char *data, int count, int flag); + int startFBCUpgrade(char *file_name, int mode, int blk_size); + int setUpgradeFbcObserver(IUpgradeFBCObserver *pOb); + +private: + CFbcUpgrade *pUpgradeIns; + CFbcProtocol *pProtocolIns; +}; + +extern CFbcLinker *getFbcLinkerInstance(); + +#endif diff --git a/tv/tvserver/tvfbclinker/include/CFbcProtocol.h b/tv/tvserver/tvfbclinker/include/CFbcProtocol.h new file mode 100644 index 0000000..0e33d19 --- a/dev/null +++ b/tv/tvserver/tvfbclinker/include/CFbcProtocol.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _C_FBC_PROTOCOL_H_ +#define _C_FBC_PROTOCOL_H_ + +#include <sys/time.h> + +#include "CFbcHelper.h" +#include "CHdmiCecCmd.h" +#include "CMsgQueue.h" +#include "CSerialPort.h" +#include <utils/Thread.h> +#include "CVirtualInput.h" +#include "zepoll.h" + + +typedef struct REQUEST_REPLY_CMD { + Condition WaitReplyCondition; + int WaitDevNo; + int WaitCmd; + int WaitTimeOut; + unsigned char *replyData; + int reDataLen; +} REQUEST_REPLY_S; + +class CFbcProtocol: public Thread { +public: + //friend class CTvMsgQueue; + class CFbcMsgQueue: public CMsgQueueThread { + public: + static const int TV_MSG_COMMON = 0; + static const int TV_MSG_SEND_KEY = 1; + private: + virtual void handleMessage ( CMessage &msg ); + }; + CFbcProtocol(); + ~CFbcProtocol(); + int start(unsigned int baud_rate); + //--------------------------------------------- + + //--------------------------------------------- + void testUart(); + int handleCmd(COMM_DEV_TYPE_E fromDev, int cmd[], int *pRetValue); + int fbcGetBatchValue(COMM_DEV_TYPE_E toDev, unsigned char *cmd_buf, int count); + int fbcSetBatchValue(COMM_DEV_TYPE_E fromDev, unsigned char *cmd_buf, int count); + int sendDataOneway(int devno, unsigned char *pData, int dataLen, int flags); + int sendDataAndWaitReply(int devno, int waitForDevno, int waitForCmd, unsigned char *pData, int dataLen, int timeout, unsigned char *pReData, int *reDataLen, int flags); + int closeAll(); + int SetUpgradeFlag(int flag); + int uartReadStream(unsigned char *retData, int rd_max_len, int timeout); + unsigned int Calcrc32(unsigned int crc, const unsigned char *ptr, unsigned int buf_len); + +private: + //now,just one item in list,haha... + void showTime(struct timeval *_time); + long getTime(void); + void initCrc32Table(); + void sendAckCmd(bool isOk); + unsigned int GetCrc32(unsigned char *InStr, unsigned int len); + int processData(COMM_DEV_TYPE_E fromDev, unsigned char *PData, int dataLen); + int uartReadData(unsigned char *retData, int *retLen); + bool threadLoop(); + + int mUpgradeFlag; + CHdmiCec mHdmiCec; + CSerialPort mSerialPort; + Epoll mEpoll; + mutable Mutex mLock; + REQUEST_REPLY_S mReplyList; + //list + epoll_event m_event; + unsigned char *mpRevDataBuf; + unsigned int mCrc32Table[256]; + bool mbSendKeyCode; + CVirtualInput mCVirtualInput; + CFbcMsgQueue mFbcMsgQueue; + int mbDownHaveSend; + + int mbFbcKeyEnterDown; + nsecs_t mFbcEnterKeyDownTime; +}; + +extern CFbcProtocol *GetFbcProtocolInstance(unsigned int baud_rate = 115200); +extern void ResetFbcProtocolInstance(); + +#endif diff --git a/tv/tvserver/tvfbclinker/include/CFbcUpgrade.h b/tv/tvserver/tvfbclinker/include/CFbcUpgrade.h new file mode 100644 index 0000000..02e9b86 --- a/dev/null +++ b/tv/tvserver/tvfbclinker/include/CFbcUpgrade.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __TV_UPGRADE_FBC_H__ +#define __TV_UPGRADE_FBC_H__ + +#include "CFbcHelper.h" +#include "CFbcProtocol.h" +#include <utils/Thread.h> +#include <list> +#include <string> + +#define CC_UPGRADE_MAX_BLOCK_LEN (0x10000) +#define CC_UPGRADE_DATA_BUF_SIZE (CC_UPGRADE_MAX_BLOCK_LEN + 4) + +class CFbcUpgrade: public Thread { +public: + CFbcUpgrade(); + ~CFbcUpgrade(); + + int start(); + int stop(); + void SetUpgradeBaudRate(unsigned int baudRate); + int SetUpgradeFileName(char *file_name); + int SetUpgradeBlockSize(int block_size); + int SetUpgradeMode(int mode); + + void setObserver(IUpgradeFBCObserver *pOb) + { + mpObserver = pOb; + }; + + + enum + { + SECTION_0 = 0, + SECTION_1, + SECTION_NUM, + }; + + enum + { + PARTITION_FIRST_BOOT = 0, + PARTITION_SECOND_BOOT, + PARTITION_SUSPEND, + PARTITION_UPDATE, + PARTITION_MAIN, + PARTITION_PQ, + PARTITION_USER, + //PARTITION_FACTORY, + PARTITION_NUM, + }; + + struct partition_info_t + { + public: + unsigned code_offset; + unsigned code_size; + unsigned data_offset; + unsigned data_size; + unsigned bss_offset; + unsigned bss_size; + unsigned readonly_offset; + unsigned readonly_size; + unsigned char signature[256]; + unsigned spi_code_offset; + unsigned spi_code_size; + unsigned audio_param_offset; + unsigned audio_param_size; + unsigned sys_param_offset; + unsigned sys_param_size; + unsigned crc; + unsigned char sha[32]; + } ; + + class sectionInfo + { + public: + int start; + int length; + std::string name; + bool checkAble; + + sectionInfo(int start = 0, int length = 0, std::string name = "", bool checkAble = false) + { + this->start = start; + this->length = length; + this->name = name; + this->checkAble = checkAble; + } + }; + +private: + bool threadLoop(); + bool AdjustUpgradeSpeed(); + bool parseUpgradeInfo(const int section, const int partition, int &start, int &length); + bool initBlocksInfo(std::list<sectionInfo> &mList); + bool sendUpgradeCmd(int &ret_code); + bool checkUpgradeConfigure(int &ret_code); + bool loadUpgradeFile(int &ret_code, std::list<sectionInfo> &partitionList); + bool check_partition(unsigned char *fileBuff, partition_info_t *info); + int AddCRCToDataBuf(unsigned char data_buf[], int data_len); + partition_info_t* getPartitionInfoUpgFile(int section, int partition); + + int mState; + int mUpgradeMode; + int mOPTotalSize; + int mBinFileSize; + int mUpgradeBlockSize; + unsigned char *mBinFileBuf; + unsigned int mNewBaudRate; + char mFileName[256]; + unsigned char mDataBuf[CC_UPGRADE_DATA_BUF_SIZE]; + IUpgradeFBCObserver *mpObserver; + CFbcProtocol *mCfbcIns; + + const int delayAfterRebootUs = 20000 * 1000; + + const int LAYOUT_VERSION_OFFSET = 0x40000; + const int LAYOUT_VERSION_SIZE = 0x1000; + const int KEY_OFFSET = 0x0; + const int KEY_SIZE = 0x41000; + const int PARTITION_INFO_SIZE = 0x200; + const int FIRST_BOOT_INFO_OFFSET = 0x41000; + const int FIRST_BOOT_INFO_SIZE = 0x1000; + const int SECTION_INFO_SIZE = 0x1000; + const int SECTION_0_INFO_OFFSET = 0x42000; + const int SECTION_1_INFO_OFFSET = 0x43000; + const int FIRST_BOOT_OFFSET = 0x44000; + const int FIRST_BOOT_SIZE = 0x5000; + const int SECTION_SIZE = 0xAD000; + const int SECTION_0_OFFSET = 0x49000; + const int SECTION_1_OFFSET = 0xF6000; + + enum UpgradeState { + STATE_STOPED = 0, + STATE_RUNNING, + STATE_FINISHED, + STATE_ABORT + }; + + enum FBCUpgradeErrorCode { + ERR_SERIAL_CONNECT = -1, + ERR_OPEN_BIN_FILE = -2, + ERR_BIN_FILE_SIZE = -3, + ERR_READ_BIN_FILE = -4, + ERR_NOT_SUPPORT_UPGRADE_MDOE = -5, + ERR_NOT_CORRECT_UPGRADE_BLKSIZE = -6, + ERR_DATA_CRC_ERROR = -7, + }; +}; + +extern CFbcUpgrade *getFbcUpgradeInstance(); +#endif //__TV_UPGRADE_FBC_H__ diff --git a/tv/tvserver/tvfbclinker/include/CHdmiCecCmd.h b/tv/tvserver/tvfbclinker/include/CHdmiCecCmd.h new file mode 100644 index 0000000..f18b795 --- a/dev/null +++ b/tv/tvserver/tvfbclinker/include/CHdmiCecCmd.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#include "CFile.h" + +static const char *CEC_PATH = "/dev/aocec"; +class CHdmiCec: public CFile { +public: + CHdmiCec(); + ~CHdmiCec(); + int readFile(unsigned char *pBuf, unsigned int uLen); +}; diff --git a/tv/tvserver/tvfbclinker/include/CSerialPort.h b/tv/tvserver/tvfbclinker/include/CSerialPort.h new file mode 100644 index 0000000..20ac169 --- a/dev/null +++ b/tv/tvserver/tvfbclinker/include/CSerialPort.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __CSERIAL_STREAM__ +#define __CSERIAL_STREAM__ +#include "CFile.h" +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <pthread.h> +#include <termios.h> +#include <errno.h> + + +static const int speed_arr[] = {B230400, B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300}; +static const int name_arr[] = { 230400, 115200, 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300}; +static const char *DEV_PATH_S0 = "/dev/ttyS0"; +static const char *DEV_PATH_S1 = "/dev/ttyS1"; +static const char *DEV_PATH_S2 = "/dev/ttyS2"; + +enum SerialDeviceID { + SERIAL_A = 0, + SERIAL_B, + SERIAL_C, +}; + +class CSerialPort: public CFile { +public: + CSerialPort(); + ~CSerialPort(); + + int OpenDevice(int serial_dev_id); + int CloseDevice(); + + int writeFile(const unsigned char *pData, unsigned int uLen); + int readFile(unsigned char *pBuf, unsigned int uLen); + int set_opt(int speed, int db, int sb, char pb, int overtime, bool raw_mode); + int setup_serial(unsigned int baud_rate); + int getDevId() + { + return mDevId; + }; + +private: + int setdatabits(struct termios *s, int db); + int setstopbits(struct termios *s, int sb); + int setparity(struct termios *s, char pb); + int set_Parity (int fd, int databits, int stopbits, int parity); + void set_speed (int fd, int speed); + + int mDevId; +}; +#endif diff --git a/tv/tvserver/tvfbclinker/include/CVirtualInput.h b/tv/tvserver/tvfbclinker/include/CVirtualInput.h new file mode 100644 index 0000000..78a9254 --- a/dev/null +++ b/tv/tvserver/tvfbclinker/include/CVirtualInput.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _VIRTUAL_INPUT_H +#define _VIRTUAL_INPUT_H +#include <linux/input.h> +#include <linux/uinput.h> + +#define DEV_UINPUT "/dev/uinput" + +class CVirtualInput { +public: + CVirtualInput(); + ~CVirtualInput(); + void sendVirtualkeyEvent(__u16 key_code); + +private: + bool threadLoop(); + int setup_uinput_device(); + int uinp_fd; +}; +#endif diff --git a/tv/tvserver/tvserver/Android.mk b/tv/tvserver/tvserver/Android.mk new file mode 100644 index 0000000..deddeef --- a/dev/null +++ b/tv/tvserver/tvserver/Android.mk @@ -0,0 +1,120 @@ +# Copyright (c) 2014 Amlogic, Inc. All rights reserved. +# +# This source code is subject to the terms and conditions defined in the +# file 'LICENSE' which is part of this source code package. +# +# Description: makefile + +LOCAL_PATH:= $(call my-dir) + + +DVB_PATH := $(wildcard external/dvb) +ifeq ($(DVB_PATH), ) + DVB_PATH := $(wildcard $(BOARD_AML_VENDOR_PATH)/external/dvb) +endif +ifeq ($(DVB_PATH), ) + DVB_PATH := $(wildcard $(BOARD_AML_VENDOR_PATH)/dvb) +endif + +LIB_ZVBI_PATH := $(wildcard external/libzvbi) +ifeq ($(LIB_ZVBI_PATH), ) + LIB_ZVBI_PATH := $(wildcard $(BOARD_AML_VENDOR_PATH)/external/libzvbi) +endif + +LIB_TV_UTILS := $(LOCAL_PATH)/../tvutils +LIB_TV_BINDER := $(LOCAL_PATH)/../../frameworks/libtvbinder + +AM_LIBPLAYER_PATH := $(wildcard $(BOARD_AML_VENDOR_PATH)/frameworks/av/LibPlayer) +LIB_SQLITE_PATH := $(wildcard external/sqlite) + + +#tvserver +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES:= \ + main_tvserver.cpp \ + DroidTvServer.cpp \ + DroidTvServiceIntf.cpp \ + MemoryLeakTrackUtil.cpp + +LOCAL_SHARED_LIBRARIES += \ + vendor.amlogic.hardware.tvserver@1.0_vendor \ + vendor.amlogic.hardware.systemcontrol@1.0_vendor \ + libbase \ + libhidlbase \ + libhidltransport \ + libhidlmemory \ + android.hidl.allocator@1.0 \ + libutils \ + libbinder \ + libcutils \ + liblog \ + libtvbinder \ + libtv + +LOCAL_C_INCLUDES := \ + system/libhidl/transport/include/hidl \ + system/libhidl/libhidlmemory/include \ + $(LOCAL_PATH)/../libtv \ + $(LOCAL_PATH)/../libtv/tvdb \ + $(LOCAL_PATH)/../libtv/tv \ + $(LOCAL_PATH)/../libtv/include \ + $(LOCAL_PATH)/../libtv/gpio \ + $(LOCAL_PATH)/../tvfbclinker/include \ + $(LIB_TV_UTILS)/include \ + $(LIB_SQLITE_PATH)/dist + +LOCAL_C_INCLUDES += \ + $(BOARD_AML_VENDOR_PATH)/frameworks/services/systemcontrol/PQ/include \ + system/extras/ext4_utils \ + $(LIB_TV_BINDER)/include \ + system/media/audio_effects/include \ + hardware/amlogic/audio/libTVaudio + +ifeq ($(wildcard hardware/amlogic/media),hardware/amlogic/media) +$(info "have hardware/amlogic/media") +AML_DEC_PATH := $(wildcard hardware/amlogic/media) +LOCAL_C_INCLUDES += \ + $(AML_DEC_PATH)/amadec/include \ + $(AML_DEC_PATH)/amcodec/include +else +AML_DEC_PATH := $(wildcard $(BOARD_AML_VENDOR_PATH)/frameworks/av/LibPlayer) +LOCAL_C_INCLUDES += \ + $(AML_DEC_PATH)/amadec/include \ + $(AML_DEC_PATH)/amcodec/include \ + $(AML_DEC_PATH)/amffmpeg \ + $(AML_DEC_PATH)/amplayer +endif + +LOCAL_CFLAGS += -DTARGET_BOARD_$(strip $(TVAPI_TARGET_BOARD_VERSION)) + +#DVB define +ifeq ($(BOARD_HAS_ADTV),true) +LOCAL_CFLAGS += -DSUPPORT_ADTV + +LOCAL_SHARED_LIBRARIES += \ + libam_mw \ + libam_adp \ + libam_ver + +LOCAL_C_INCLUDES += \ + $(DVB_PATH)/include/am_adp \ + $(DVB_PATH)/include/am_mw \ + $(DVB_PATH)/include/am_ver \ + $(DVB_PATH)/android/ndk/include \ + $(LIB_ZVBI_PATH)/ntsc_decode/include \ + $(LIB_ZVBI_PATH)/ntsc_decode/include/ntsc_dmx \ + $(LIB_ZVBI_PATH)/src +endif + +LOCAL_MODULE:= tvserver + +LOCAL_INIT_RC := tvserver.rc + +ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK) +LOCAL_PROPRIETARY_MODULE := true +endif + +include $(BUILD_EXECUTABLE) diff --git a/tv/tvserver/tvserver/DroidTvServer.cpp b/tv/tvserver/tvserver/DroidTvServer.cpp new file mode 100644 index 0000000..16512a9 --- a/dev/null +++ b/tv/tvserver/tvserver/DroidTvServer.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2016 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/15 + * @par function description: + * - 1 droidlogic tvserver daemon, hwbiner implematation + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "HIDLServer" + +#include <inttypes.h> +#include <string> +#include <binder/Parcel.h> +#include <cutils/properties.h> +#include <android/hidl/allocator/1.0/IAllocator.h> +#include <android/hidl/memory/1.0/IMemory.h> +#include <hidlmemory/mapping.h> + +#include "CTvLog.h" +#include "DroidTvServer.h" + +namespace vendor { +namespace amlogic { +namespace hardware { +namespace tvserver { +namespace V1_0 { +namespace implementation { + +using ::android::hidl::allocator::V1_0::IAllocator; +using ::android::hidl::memory::V1_0::IMemory; + +DroidTvServer::DroidTvServer() : mDeathRecipient(new DeathRecipient(this)) { + mTvServiceIntf = new DroidTvServiceIntf(); + mTvServiceIntf->setListener(this); +} + +DroidTvServer::~DroidTvServer() { + delete mTvServiceIntf; +} + +void DroidTvServer::onEvent(const TvHidlParcel &hidlParcel) { + int clientSize = mClients.size(); + + ALOGI("onEvent event:%d, client size:%d", hidlParcel.msgType, clientSize); + +#if 0 + sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem"); + if (ashmemAllocator == nullptr) { + ALOGE("can not get ashmem service"); + return; + } + + size_t size = p.dataSize(); + android::hardware::hidl_memory hidlMemory; + auto res = ashmemAllocator->allocate(size, [&](bool success, const android::hardware::hidl_memory& memory) { + if (!success) { + ALOGE("ashmem allocate size:%d fail", size); + } + hidlMemory = memory; + }); + + if (!res.isOk()) { + ALOGE("ashmem allocate result fail"); + return; + } + + sp<IMemory> memory = android::hardware::mapMemory(hidlMemory); + void* data = memory->getPointer(); + memory->update(); + // update memory however you wish after calling update and before calling commit + memcpy(data, p.data(), size); + memory->commit(); +#endif + for (int i = 0; i < clientSize; i++) { + if (mClients[i] != nullptr) { + ALOGI("%s, client cookie:%d notifyCallback", __FUNCTION__, i); + mClients[i]->notifyCallback(hidlParcel); + } + } +} + +Return<void> DroidTvServer::lock() { + return Void(); +} + +Return<void> DroidTvServer::unlock() { + return Void(); +} + +Return<void> DroidTvServer::disconnect() { + return Void(); +} + +Return<int32_t> DroidTvServer::processCmd(int32_t type, int32_t size) { + #if 0 + Parcel p; + + sp<IMemory> memory = android::hardware::mapMemory(parcelMem); + void* data = memory->getPointer(); + //memory->update(); + // update memory however you wish after calling update and before calling commit + p.write(data, size); + int ret = mTvServiceIntf->processCmd(p); + //memory->commit(); + return ret; + #endif + return 0; +} + +Return<int32_t> DroidTvServer::startTv() { + return mTvServiceIntf->startTv(); +} + +Return<int32_t> DroidTvServer::stopTv() { + return mTvServiceIntf->stopTv(); +} + +Return<int32_t> DroidTvServer::switchInputSrc(int32_t inputSrc) { + return mTvServiceIntf->switchInputSrc(inputSrc); +} + +Return<int32_t> DroidTvServer::getInputSrcConnectStatus(int32_t inputSrc) { + return mTvServiceIntf->getInputSrcConnectStatus(inputSrc); +} + +Return<int32_t> DroidTvServer::getCurrentInputSrc() { + return mTvServiceIntf->getCurrentInputSrc(); +} + +Return<int32_t> DroidTvServer::getHdmiAvHotplugStatus() { + return mTvServiceIntf->getHdmiAvHotplugStatus(); +} + +Return<void> DroidTvServer::getSupportInputDevices(getSupportInputDevices_cb _hidl_cb) { + std::string devices = mTvServiceIntf->getSupportInputDevices(); + _hidl_cb(0/*don't use*/, devices); + return Void(); +} + +Return<void> DroidTvServer::getCurSignalInfo(getCurSignalInfo_cb _hidl_cb) { + SignalInfo info; + mTvServiceIntf->getCurSignalInfo(info.fmt, info.transFmt, info.status, info.frameRate); + + _hidl_cb(info); + return Void(); +} + +Return<int32_t> DroidTvServer::setMiscCfg(const hidl_string& key, const hidl_string& val) { + return mTvServiceIntf->setMiscCfg(key, val); +} + +Return<void> DroidTvServer::getMiscCfg(const hidl_string& key, const hidl_string& def, getMiscCfg_cb _hidl_cb) { + std::string cfg = mTvServiceIntf->getMiscCfg(key, def); + + ALOGI("%s, key:%s def:%s, cfg:%s", __FUNCTION__, key.c_str(), def.c_str(), cfg.c_str()); + _hidl_cb(cfg); + return Void(); +} + +Return<int32_t> DroidTvServer::getHdmiPorts() { + return mTvServiceIntf->getHdmiPorts(); +} + +Return<int32_t> DroidTvServer::isDviSIgnal() { + return mTvServiceIntf->getHdmiPorts(); +} + +Return<int32_t> DroidTvServer::isVgaTimingInHdmi() { + return mTvServiceIntf->getHdmiPorts(); +} + + +Return<void> DroidTvServer::setCallback(const sp<ITvServerCallback>& callback, ConnectType type) { + if ((int)type > (int)ConnectType::TYPE_TOTAL - 1) { + ALOGE("%s don't support type:%d", __FUNCTION__, (int)type); + return Void(); + } + + if (callback != nullptr) { + if (mClients[(int)type] != nullptr) { + ALOGW("%s this type:%s had a callback, cover it", __FUNCTION__, getConnectTypeStr(type)); + mClients[(int)type]->unlinkToDeath(mDeathRecipient); + } + + mClients[(int)type] = callback; + Return<bool> linkResult = callback->linkToDeath(mDeathRecipient, (int)type); + bool linkSuccess = linkResult.isOk() ? static_cast<bool>(linkResult) : false; + if (!linkSuccess) { + ALOGW("Couldn't link death recipient for type: %s", getConnectTypeStr(type)); + } + + ALOGI("%s client type:%s, client size:%d", __FUNCTION__, getConnectTypeStr(type), (int)mClients.size()); + } + + if (!mListenerStarted) { + mTvServiceIntf->startListener(); + mListenerStarted= true; + } + + return Void(); +} + +const char* DroidTvServer::getConnectTypeStr(ConnectType type) { + switch (type) { + case ConnectType::TYPE_HAL: + return "HAL"; + case ConnectType::TYPE_EXTEND: + return "EXTEND"; + default: + return "unknown type"; + } +} + +void DroidTvServer::handleServiceDeath(uint32_t type) { + ALOGI("tvserver daemon client:%s died", getConnectTypeStr((ConnectType)type)); + mClients[type].clear(); +} + +DroidTvServer::DeathRecipient::DeathRecipient(sp<DroidTvServer> server) + : droidTvServer(server) {} + +void DroidTvServer::DeathRecipient::serviceDied( + uint64_t cookie, + const wp<::android::hidl::base::V1_0::IBase>& /*who*/) { + ALOGE("droid tvserver daemon a client died cookie:%d", (int)cookie); + + uint32_t type = static_cast<uint32_t>(cookie); + droidTvServer->handleServiceDeath(type); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace tvserver +} // namespace hardware +} // namespace amlogic +} // namespace vendor diff --git a/tv/tvserver/tvserver/DroidTvServer.h b/tv/tvserver/tvserver/DroidTvServer.h new file mode 100644 index 0000000..c3d27c9 --- a/dev/null +++ b/tv/tvserver/tvserver/DroidTvServer.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2016 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/15 + * @par function description: + * - 1 droidlogic tvserver daemon, hwbiner implematation + */ + +#ifndef ANDROID_DROIDLOGIC_HDMI_CEC_V1_0_H +#define ANDROID_DROIDLOGIC_HDMI_CEC_V1_0_H + +#include <binder/IBinder.h> +#include <utils/Mutex.h> +#include <vector> +#include <map> + +#include "DroidTvServiceIntf.h" +#include <vendor/amlogic/hardware/tvserver/1.0/ITvServer.h> + +namespace vendor { +namespace amlogic { +namespace hardware { +namespace tvserver { +namespace V1_0 { +namespace implementation { + +using ::vendor::amlogic::hardware::tvserver::V1_0::ITvServer; +using ::vendor::amlogic::hardware::tvserver::V1_0::ITvServerCallback; +using ::vendor::amlogic::hardware::tvserver::V1_0::ConnectType; +using ::vendor::amlogic::hardware::tvserver::V1_0::SignalInfo; +using ::vendor::amlogic::hardware::tvserver::V1_0::TvHidlParcel; +using ::vendor::amlogic::hardware::tvserver::V1_0::Result; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hidl::memory::V1_0::IMemory; +using ::android::sp; + +using namespace android; + +class DroidTvServer : public ITvServer, public TvServiceNotify { +public: + DroidTvServer(); + virtual ~DroidTvServer(); + + Return<void> disconnect() override; + + Return<void> lock() override; + + Return<void> unlock() override; + + Return<int32_t> processCmd(int32_t type, int32_t size) override; + + Return<int32_t> startTv() override; + Return<int32_t> stopTv() override; + Return<int32_t> switchInputSrc(int32_t inputSrc) override; + Return<int32_t> getInputSrcConnectStatus(int32_t inputSrc) override; + Return<int32_t> getCurrentInputSrc() override; + Return<int32_t> getHdmiAvHotplugStatus() override; + Return<void> getSupportInputDevices(getSupportInputDevices_cb _hidl_cb) override; + Return<int32_t> getHdmiPorts() override; + + Return<void> getCurSignalInfo(getCurSignalInfo_cb _hidl_cb) override; + Return<int32_t> setMiscCfg(const hidl_string& key, const hidl_string& val) override; + Return<void> getMiscCfg(const hidl_string& key, const hidl_string& def, getMiscCfg_cb _hidl_cb) override; + + Return<int32_t> isDviSIgnal() override; + Return<int32_t> isVgaTimingInHdmi() override; + + + Return<void> setCallback(const sp<ITvServerCallback>& callback, ConnectType type) override; + + virtual void onEvent(const TvHidlParcel &hidlParcel); + +private: + + const char* getConnectTypeStr(ConnectType type); + + // Handle the case where the callback registered for the given type dies + void handleServiceDeath(uint32_t type); + + bool mDebug = false; + bool mListenerStarted = false; + DroidTvServiceIntf *mTvServiceIntf; + std::map<uint32_t, sp<ITvServerCallback>> mClients; + + mutable Mutex mLock; + + class DeathRecipient : public android::hardware::hidl_death_recipient { + public: + DeathRecipient(sp<DroidTvServer> server); + + // hidl_death_recipient interface + virtual void serviceDied(uint64_t cookie, + const ::android::wp<::android::hidl::base::V1_0::IBase>& who) override; + + private: + sp<DroidTvServer> droidTvServer; + }; + + sp<DeathRecipient> mDeathRecipient; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace tvserver +} // namespace hardware +} // namespace amlogic +} // namespace vendor +#endif /* ANDROID_DROIDLOGIC_HDMI_CEC_V1_0_H */ diff --git a/tv/tvserver/tvserver/DroidTvServiceIntf.cpp b/tv/tvserver/tvserver/DroidTvServiceIntf.cpp new file mode 100644 index 0000000..58a89c2 --- a/dev/null +++ b/tv/tvserver/tvserver/DroidTvServiceIntf.cpp @@ -0,0 +1,2189 @@ +/* + * Copyright (C) 2016 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/16 + * @par function description: + * - 1 droidlogic tvservice interface + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "HIDLIntf" + +#include <utils/Log.h> +#include <binder/IServiceManager.h> +#include <binder/IPCThreadState.h> +#include <utils/String16.h> +#include <utils/Errors.h> +#include <binder/MemoryBase.h> +#include <binder/MemoryHeapBase.h> +#include <ITvService.h> +#include <hardware/hardware.h> +#include "DroidTvServiceIntf.h" +#include <cutils/atomic.h> +#include <cutils/properties.h> +#include <stdint.h> +#include <CTvLog.h> +#include <tvconfig.h> +#include <tvutils.h> +#include <tvsetting/CTvSetting.h> +#include <tv/CTvFactory.h> +#include <audio/CTvAudio.h> +#include <version/version.h> +#include "tvcmd.h" +#include <tvdb/CTvRegion.h> +#include "MemoryLeakTrackUtil.h" +extern "C" { +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <pthread.h> +#include <signal.h> +#ifdef SUPPORT_ADTV +#include "am_ver.h" +#endif +} + +#include "DroidTvServiceIntf.h" + +using namespace android; + +DroidTvServiceIntf::DroidTvServiceIntf() +{ + //mpScannerClient = NULL; + mpTv = new CTv(); + mpTv->setTvObserver(this); + mpTv->OpenTv(); +} + +DroidTvServiceIntf::~DroidTvServiceIntf() +{ + //mpScannerClient = NULL; + /* + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + LOGW("some client still connect it!"); + } + }*/ + + if (mpTv != NULL) { + delete mpTv; + mpTv = NULL; + } +} + +void DroidTvServiceIntf::startListener() { + mpTv->startTvDetect(); +} + +void DroidTvServiceIntf::onTvEvent(const CTvEv &ev) +{ + int type = ev.getEvType(); + LOGD("DroidTvServiceIntf::onTvEvent ev type = %d", type); + switch (type) { + case CTvEv::TV_EVENT_SCANNER: { + CTvScanner::ScannerEvent *pScannerEv = (CTvScanner::ScannerEvent *) (&ev); + //if (mpScannerClient != NULL) { + //sp<Client> ScannerClient = mpScannerClient.promote(); + //if (ScannerClient != 0) { + Parcel p; + LOGD("scanner evt type:%d freq:%d vid:%d acnt:%d scnt:%d", + pScannerEv->mType, pScannerEv->mFrequency, pScannerEv->mVid, pScannerEv->mAcnt, pScannerEv->mScnt); + p.writeInt32(pScannerEv->mType); + p.writeInt32(pScannerEv->mPercent); + p.writeInt32(pScannerEv->mTotalChannelCount); + p.writeInt32(pScannerEv->mLockedStatus); + p.writeInt32(pScannerEv->mChannelIndex); + p.writeInt32(pScannerEv->mFrequency); + p.writeString16(String16(pScannerEv->mProgramName)); + p.writeInt32(pScannerEv->mprogramType); + p.writeString16(String16(pScannerEv->mParas)); + p.writeInt32(pScannerEv->mStrength); + p.writeInt32(pScannerEv->mSnr); + //ATV + p.writeInt32(pScannerEv->mVideoStd); + p.writeInt32(pScannerEv->mAudioStd); + p.writeInt32(pScannerEv->mIsAutoStd); + //DTV + p.writeInt32(pScannerEv->mMode); + p.writeInt32(pScannerEv->mSymbolRate); + p.writeInt32(pScannerEv->mModulation); + p.writeInt32(pScannerEv->mBandwidth); + p.writeInt32(pScannerEv->mReserved); + p.writeInt32(pScannerEv->mTsId); + p.writeInt32(pScannerEv->mONetId); + p.writeInt32(pScannerEv->mServiceId); + p.writeInt32(pScannerEv->mVid); + p.writeInt32(pScannerEv->mVfmt); + p.writeInt32(pScannerEv->mAcnt); + for (int i = 0; i < pScannerEv->mAcnt; i++) + p.writeInt32(pScannerEv->mAid[i]); + for (int i = 0; i < pScannerEv->mAcnt; i++) + p.writeInt32(pScannerEv->mAfmt[i]); + for (int i = 0; i < pScannerEv->mAcnt; i++) + p.writeString16(String16(pScannerEv->mAlang[i])); + for (int i = 0; i < pScannerEv->mAcnt; i++) + p.writeInt32(pScannerEv->mAtype[i]); + for (int i = 0; i < pScannerEv->mAcnt; i++) + p.writeInt32(pScannerEv->mAExt[i]); + p.writeInt32(pScannerEv->mPcr); + p.writeInt32(pScannerEv->mScnt); + for (int i = 0; i < pScannerEv->mScnt; i++) + p.writeInt32(pScannerEv->mStype[i]); + for (int i = 0; i < pScannerEv->mScnt; i++) + p.writeInt32(pScannerEv->mSid[i]); + for (int i = 0; i < pScannerEv->mScnt; i++) + p.writeInt32(pScannerEv->mSstype[i]); + for (int i = 0; i < pScannerEv->mScnt; i++) + p.writeInt32(pScannerEv->mSid1[i]); + for (int i = 0; i < pScannerEv->mScnt; i++) + p.writeInt32(pScannerEv->mSid2[i]); + for (int i = 0; i < pScannerEv->mScnt; i++) + p.writeString16(String16(pScannerEv->mSlang[i])); + p.writeInt32(pScannerEv->mFree_ca); + p.writeInt32(pScannerEv->mScrambled); + p.writeInt32(pScannerEv->mScanMode); + p.writeInt32(pScannerEv->mSdtVer); + p.writeInt32(pScannerEv->mSortMode); + + p.writeInt32(pScannerEv->mLcnInfo.net_id); + p.writeInt32(pScannerEv->mLcnInfo.ts_id); + p.writeInt32(pScannerEv->mLcnInfo.service_id); + for (int i=0; i<MAX_LCN; i++) { + p.writeInt32(pScannerEv->mLcnInfo.visible[i]); + p.writeInt32(pScannerEv->mLcnInfo.lcn[i]); + p.writeInt32(pScannerEv->mLcnInfo.valid[i]); + } + p.writeInt32(pScannerEv->mMajorChannelNumber); + p.writeInt32(pScannerEv->mMinorChannelNumber); + p.writeInt32(pScannerEv->mSourceId); + p.writeInt32(pScannerEv->mAccessControlled); + p.writeInt32(pScannerEv->mHidden); + p.writeInt32(pScannerEv->mHideGuide); + p.writeString16(String16(pScannerEv->mVct)); + + //mNotifyListener->onEvent(SCAN_EVENT_CALLBACK, p); + //} + //} + break; + } + + case CTvEv::TV_EVENT_EPG: { + CTvEpg::EpgEvent *pEpgEvent = (CTvEpg::EpgEvent *) (&ev); + Parcel p; + p.writeInt32(pEpgEvent->type); + p.writeInt32(pEpgEvent->time); + p.writeInt32(pEpgEvent->programID); + p.writeInt32(pEpgEvent->channelID); + //mNotifyListener->onEvent(EPG_EVENT_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_HDMI_IN_CAP: { + /* + TvHidlParcel hidlParcel; + + CTvScreenCapture::CapEvent *pCapEvt = (CTvScreenCapture::CapEvent *)(&ev); + + hidlParcel.msgType = VFRAME_BMP_EVENT_CALLBACK; + + ALOGI("TV_EVENT_HDMI_IN_CAP size:%d", sizeof(CTvScreenCapture::CapEvent)); + + hidlParcel.bodyInt.resize(4); + hidlParcel.bodyInt[0] = pCapEvt->mFrameNum; + hidlParcel.bodyInt[1] = pCapEvt->mFrameSize; + hidlParcel.bodyInt[2] = pCapEvt->mFrameWide; + hidlParcel.bodyInt[3] = pCapEvt->mFrameHeight; + + mNotifyListener->onEvent(hidlParcel); + */ + break; + } + + case CTvEv::TV_EVENT_AV_PLAYBACK: { + TvHidlParcel hidlParcel; + hidlParcel.msgType = DTV_AV_PLAYBACK_CALLBACK; + + TvEvent::AVPlaybackEvent *pEv = (TvEvent::AVPlaybackEvent *)(&ev); + + hidlParcel.bodyInt.resize(2); + hidlParcel.bodyInt[0] = pEv->mMsgType; + hidlParcel.bodyInt[1] = pEv->mProgramId; + + mNotifyListener->onEvent(hidlParcel); + break; + } + + case CTvEv::TV_EVENT_SIGLE_DETECT: { + TvEvent::SignalInfoEvent *pEv = (TvEvent::SignalInfoEvent *)(&ev); + Parcel p; + p.writeInt32(pEv->mTrans_fmt); + p.writeInt32(pEv->mFmt); + p.writeInt32(pEv->mStatus); + p.writeInt32(pEv->mReserved); + //mNotifyListener->onEvent(SIGLE_DETECT_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_SUBTITLE: { + TvEvent::SubtitleEvent *pEv = (TvEvent::SubtitleEvent *)(&ev); + Parcel p; + p.writeInt32(pEv->pic_width); + p.writeInt32(pEv->pic_height); + //mNotifyListener->onEvent(SUBTITLE_UPDATE_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_ADC_CALIBRATION: { + TvEvent::ADCCalibrationEvent *pEv = (TvEvent::ADCCalibrationEvent *)(&ev); + Parcel p; + p.writeInt32(pEv->mState); + //mNotifyListener->onEvent(ADC_CALIBRATION_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_VGA: {//VGA + TvEvent::VGAEvent *pEv = (TvEvent::VGAEvent *)(&ev); + Parcel p; + p.writeInt32(pEv->mState); + //mNotifyListener->onEvent(VGA_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_SOURCE_CONNECT: { + TvHidlParcel hidlParcel; + hidlParcel.msgType = SOURCE_CONNECT_CALLBACK; + + TvEvent::SourceConnectEvent *pEv = (TvEvent::SourceConnectEvent *)(&ev); + + hidlParcel.bodyInt.resize(2); + hidlParcel.bodyInt[0] = pEv->mSourceInput; + hidlParcel.bodyInt[1] = pEv->connectionState; + + LOGD("source connect input: =%d state: =%d", pEv->mSourceInput, pEv->connectionState); + mNotifyListener->onEvent(hidlParcel); + break; + } + + case CTvEv::TV_EVENT_HDMIRX_CEC: { + TvEvent::HDMIRxCECEvent *pEv = (TvEvent::HDMIRxCECEvent *)(&ev); + Parcel p; + p.writeInt32(pEv->mDataCount); + for (int j = 0; j < pEv->mDataCount; j++) { + p.writeInt32(pEv->mDataBuf[j]); + } + //mNotifyListener->onEvent(HDMIRX_CEC_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_UPGRADE_FBC: { + TvEvent::UpgradeFBCEvent *pEv = (TvEvent::UpgradeFBCEvent *)(&ev); + Parcel p; + p.writeInt32(pEv->mState); + p.writeInt32(pEv->param); + //mNotifyListener->onEvent(UPGRADE_FBC_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_SERIAL_COMMUNICATION: { + TvEvent::SerialCommunicationEvent *pEv = (TvEvent::SerialCommunicationEvent *)(&ev); + Parcel p; + p.writeInt32(pEv->mDevId); + p.writeInt32(pEv->mDataCount); + for (int j = 0; j < pEv->mDataCount; j++) { + p.writeInt32(pEv->mDataBuf[j]); + } + //mNotifyListener->onEvent(SERIAL_COMMUNICATION_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_2d4G_HEADSET: { + TvEvent::HeadSetOf2d4GEvent *pEv = (TvEvent::HeadSetOf2d4GEvent *)(&ev); + LOGD("SendDtvStats status: =%d para2: =%d", pEv->state, pEv->para); + Parcel p; + p.writeInt32(pEv->state); + p.writeInt32(pEv->para); + //mNotifyListener->onEvent(HEADSET_STATUS_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_SCANNING_FRAME_STABLE: { + TvEvent::ScanningFrameStableEvent *pEv = (TvEvent::ScanningFrameStableEvent *)(&ev); + LOGD("Scanning Frame is stable!"); + Parcel p; + p.writeInt32(pEv->CurScanningFreq); + //mNotifyListener->onEvent(SCANNING_FRAME_STABLE_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_FRONTEND: { + TvEvent::FrontendEvent *pEv = (TvEvent::FrontendEvent *)(&ev); + Parcel p; + p.writeInt32(pEv->mStatus); + p.writeInt32(pEv->mFrequency); + p.writeInt32(pEv->mParam1); + p.writeInt32(pEv->mParam2); + p.writeInt32(pEv->mParam3); + p.writeInt32(pEv->mParam4); + p.writeInt32(pEv->mParam5); + p.writeInt32(pEv->mParam6); + p.writeInt32(pEv->mParam7); + p.writeInt32(pEv->mParam8); + //mNotifyListener->onEvent(FRONTEND_EVENT_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_RECORDER: { + TvEvent::RecorderEvent *pEv = (TvEvent::RecorderEvent *)(&ev); + Parcel p; + p.writeString16(String16(pEv->mId)); + p.writeInt32(pEv->mStatus); + p.writeInt32(pEv->mError); + //mNotifyListener->onEvent(RECORDER_EVENT_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_RRT: { + CTvRrt::RrtEvent *pRrtEvent = (CTvRrt::RrtEvent *) (&ev); + Parcel p; + p.writeInt32(pRrtEvent->satus); + //mNotifyListener->onEvent(RRT_EVENT_CALLBACK, p); + break; + } + + case CTvEv::TV_EVENT_EAS: { + CTvEas::EasEvent *pEasEvent = (CTvEas::EasEvent *) (&ev); + Parcel p; + p.writeInt32(pEasEvent->eas_section_count); + p.writeInt32(pEasEvent->table_id); + p.writeInt32(pEasEvent->extension); + p.writeInt32(pEasEvent->version); + p.writeInt32(pEasEvent->current_next); + p.writeInt32(pEasEvent->sequence_num); + p.writeInt32(pEasEvent->protocol_version); + p.writeInt32(pEasEvent->eas_event_id); + p.writeInt32(pEasEvent->eas_orig_code[0]); + p.writeInt32(pEasEvent->eas_orig_code[1]); + p.writeInt32(pEasEvent->eas_orig_code[2]); + p.writeInt32(pEasEvent->eas_event_code_len); + for (int j=0;j<pEasEvent->eas_event_code_len;j++) { + p.writeInt32(pEasEvent->eas_event_code[j]); + } + p.writeInt32(pEasEvent->alert_message_time_remaining); + p.writeInt32(pEasEvent->event_start_time); + p.writeInt32(pEasEvent->event_duration); + p.writeInt32(pEasEvent->alert_priority); + p.writeInt32(pEasEvent->details_OOB_source_ID); + p.writeInt32(pEasEvent->details_major_channel_number); + p.writeInt32(pEasEvent->details_minor_channel_number); + p.writeInt32(pEasEvent->audio_OOB_source_ID); + p.writeInt32(pEasEvent->location_count); + for (int j=0;j<pEasEvent->location_count;j++) { + p.writeInt32(pEasEvent->location[j].i_state_code); + p.writeInt32(pEasEvent->location[j].i_country_subdiv); + p.writeInt32(pEasEvent->location[j].i_country_code); + } + p.writeInt32(pEasEvent->exception_count); + for (int j=0;j<pEasEvent->exception_count;j++) { + p.writeInt32(pEasEvent->exception[j].i_in_band_refer); + p.writeInt32(pEasEvent->exception[j].i_exception_major_channel_number); + p.writeInt32(pEasEvent->exception[j].i_exception_minor_channel_number); + p.writeInt32(pEasEvent->exception[j].exception_OOB_source_ID); + } + p.writeInt32(pEasEvent->multi_text_count); + for (int j=0;j<pEasEvent->multi_text_count;j++) { + p.writeInt32(pEasEvent->multi_text[j].lang[0]); + p.writeInt32(pEasEvent->multi_text[j].lang[1]); + p.writeInt32(pEasEvent->multi_text[j].lang[2]); + p.writeInt32(pEasEvent->multi_text[j].i_type); + p.writeInt32(pEasEvent->multi_text[j].i_compression_type); + p.writeInt32(pEasEvent->multi_text[j].i_mode); + p.writeInt32(pEasEvent->multi_text[j].i_number_bytes); + for (int k=0;k<pEasEvent->multi_text[j].i_number_bytes;k++) { + p.writeInt32(pEasEvent->multi_text[j].compressed_str[k]); + } + } + p.writeInt32(pEasEvent->descriptor_text_count); + for (int j=0;j<pEasEvent->descriptor_text_count;j++) { + p.writeInt32(pEasEvent->descriptor[j].i_tag); + p.writeInt32(pEasEvent->descriptor[j].i_length); + for (int k=0;k<pEasEvent->descriptor[j].i_length;k++) { + p.writeInt32(pEasEvent->descriptor[j].p_data[k]); + } + } + //mNotifyListener->onEvent(EAS_EVENT_CALLBACK, p); + break; + } + + default: + break; + } +} + +int DroidTvServiceIntf::startTv() { + return mpTv->StartTvLock(); +} + +int DroidTvServiceIntf::stopTv() { + return mpTv->StopTvLock(); +} + +int DroidTvServiceIntf::switchInputSrc(int32_t inputSrc) { + LOGD("switchInputSrc sourceId= 0x%x", inputSrc); + return mpTv->SetSourceSwitchInput((tv_source_input_t)inputSrc); +} + +int DroidTvServiceIntf::getInputSrcConnectStatus(int32_t inputSrc) { + return mpTv->GetSourceConnectStatus((tv_source_input_t)inputSrc); +} + +int DroidTvServiceIntf::getCurrentInputSrc() { + return (int)mpTv->GetCurrentSourceInputVirtualLock(); +} + +int DroidTvServiceIntf::getHdmiAvHotplugStatus() { + return mpTv->GetHdmiAvHotplugDetectOnoff(); +} + +std::string DroidTvServiceIntf::getSupportInputDevices() { + const char *valueStr = config_get_str(CFG_SECTION_TV, CGF_DEFAULT_INPUT_IDS, "null"); + LOGD("get support input devices = %s", valueStr); + return std::string(valueStr); +} + +int DroidTvServiceIntf::getHdmiPorts() { + return config_get_int(CFG_SECTION_TV, CGF_DEFAULT_HDMI_PORTS, 0); +} + +void DroidTvServiceIntf::getCurSignalInfo(int &fmt, int &transFmt, int &status, int &frameRate) { + tvin_info_t siginfo = mpTv->GetCurrentSignalInfo(); + int frame_rate = mpTv->getHDMIFrameRate(); + + fmt = siginfo.fmt; + transFmt = siginfo.trans_fmt; + status = siginfo.status; + frameRate = frame_rate; +} + +int DroidTvServiceIntf::setMiscCfg(const std::string& key, const std::string& val) { + //LOGD("setMiscCfg key = %s, val = %s", key.c_str(), val.c_str()); + return config_set_str(CFG_SECTION_TV, key.c_str(), val.c_str()); +} + +std::string DroidTvServiceIntf::getMiscCfg(const std::string& key, const std::string& def) { + const char *value = config_get_str(CFG_SECTION_TV, key.c_str(), def.c_str()); + //LOGD("getMiscCfg key = %s, def = %s, value = %s", key.c_str(), def.c_str(), value); + return std::string(value); +} + +int DroidTvServiceIntf::isDviSIgnal() { + return mpTv->IsDVISignal(); +} + +int DroidTvServiceIntf::isVgaTimingInHdmi() { + return mpTv->isVgaFmtInHdmi(); +} + +int DroidTvServiceIntf::processCmd(const Parcel &p) { + unsigned char dataBuf[512] = {0}; + int ret = -1; + int cmd = p.readInt32(); + + LOGD("processCmd cmd=%d", cmd); + switch (cmd) { + // Tv function + case OPEN_TV: + break; + + case CLOSE_TV: + ret = mpTv->CloseTv(); + break; + + case START_TV: + //int mode = p.readInt32(); + ret = mpTv->StartTvLock(); + mIsStartTv = true; + break; + + case STOP_TV: + ret = mpTv->StopTvLock(); + mIsStartTv = false; + break; + case GET_TV_STATUS: + ret = (int)mpTv->GetTvStatus(); + break; + case GET_LAST_SOURCE_INPUT: + ret = (int)mpTv->GetLastSourceInput(); + break; + case GET_CURRENT_SOURCE_INPUT: + ret = (int)mpTv->GetCurrentSourceInputLock(); + break; + + case GET_CURRENT_SOURCE_INPUT_VIRTUAL: + ret = (int)mpTv->GetCurrentSourceInputVirtualLock(); + break; + + case GET_CURRENT_SIGNAL_INFO: + /* + tvin_info_t siginfo = mpTv->GetCurrentSignalInfo(); + int frame_rate = mpTv->getHDMIFrameRate(); + r->writeInt32(siginfo.trans_fmt); + r->writeInt32(siginfo.fmt); + r->writeInt32(siginfo.status); + r->writeInt32(frame_rate); + */ + break; + + case SET_SOURCE_INPUT: { + int sourceinput = p.readInt32(); + LOGD(" SetSourceInput sourceId= %x", sourceinput); + ret = mpTv->SetSourceSwitchInput((tv_source_input_t)sourceinput); + break; + } + case SET_SOURCE_INPUT_EXT: { + int sourceinput = p.readInt32(); + int vsourceinput = p.readInt32(); + LOGD(" SetSourceInputExt vsourceId= %d sourceId=%d", vsourceinput, sourceinput); + ret = mpTv->SetSourceSwitchInput((tv_source_input_t)vsourceinput, (tv_source_input_t)sourceinput); + break; + } + case DO_SUSPEND: { + int type = p.readInt32(); + ret = mpTv->DoSuspend(type); + break; + } + case DO_RESUME: { + int type = p.readInt32(); + ret = mpTv->DoResume(type); + break; + } + case IS_DVI_SIGNAL: + ret = mpTv->IsDVISignal(); + break; + + case IS_VGA_TIMEING_IN_HDMI: + ret = mpTv->isVgaFmtInHdmi(); + break; + + case SET_PREVIEW_WINDOW_MODE: + ret = mpTv->setPreviewWindowMode(p.readInt32() == 1); + break; + + case SET_PREVIEW_WINDOW: { + tvin_window_pos_t win_pos; + win_pos.x1 = p.readInt32(); + win_pos.y1 = p.readInt32(); + win_pos.x2 = p.readInt32(); + win_pos.y2 = p.readInt32(); + ret = (int)mpTv->SetPreviewWindow(win_pos); + break; + } + + case GET_SOURCE_CONNECT_STATUS: { + int source_input = p.readInt32(); + ret = mpTv->GetSourceConnectStatus((tv_source_input_t)source_input); + break; + } + + case GET_SOURCE_INPUT_LIST: + /* + const char *value = config_get_str(CFG_SECTION_TV, CGF_DEFAULT_INPUT_IDS, "null"); + r->writeString16(String16(value)); + */ + break; + + //Tv function END + + // HDMI + case SET_HDMI_EDID_VER: { + int hdmi_port_id = p.readInt32(); + int edid_ver = p.readInt32(); + ret = mpTv->SetHdmiEdidVersion((tv_hdmi_port_id_t)hdmi_port_id, (tv_hdmi_edid_version_t)edid_ver); + break; + } + case SET_HDCP_KEY_ENABLE: { + int enable = p.readInt32(); + ret = mpTv->SetHdmiHDCPSwitcher((tv_hdmi_hdcpkey_enable_t)enable); + break; + } + case SET_HDMI_COLOR_RANGE_MODE: { + int range_mode = p.readInt32(); + ret = mpTv->SetHdmiColorRangeMode((tv_hdmi_color_range_t)range_mode); + break; + } + case GET_HDMI_COLOR_RANGE_MODE: + ret = mpTv->GetHdmiColorRangeMode(); + break; + + // HDMI END + + // AUDIO & AUDIO MUTE + case SET_AUDIO_MUTE_FOR_TV: { + int status = p.readInt32(); + if (status != mpTv->GetAudioMuteForTv()) { + ret = mpTv->SetAudioMuteForTv(status); + } + break; + } + case SET_AUDIO_MUTEKEY_STATUS: { + int status = p.readInt32(); + ret = mpTv->SetAudioMuteForSystem(status); + break; + } + case GET_AUDIO_MUTEKEY_STATUS: + ret = mpTv->GetAudioMuteForSystem(); + break; + + case SET_AUDIO_AVOUT_MUTE_STATUS: { + int status = p.readInt32(); + ret = mpTv->SetAudioAVOutMute(status); + break; + } + case GET_AUDIO_AVOUT_MUTE_STATUS: + ret = mpTv->GetAudioAVOutMute(); + break; + + case SET_AUDIO_SPDIF_MUTE_STATUS: { + int status = p.readInt32(); + ret = mpTv->SetAudioSPDIFMute(status); + break; + } + case GET_AUDIO_SPDIF_MUTE_STATUS: + ret = mpTv->GetAudioSPDIFMute(); + break; + + // AUDIO MASTER VOLUME + case SET_AUDIO_MASTER_VOLUME: { + int vol = p.readInt32(); + ret = mpTv->SetAudioMasterVolume(vol); + break; + } + case GET_AUDIO_MASTER_VOLUME: + ret = mpTv->GetAudioMasterVolume(); + break; + case SAVE_CUR_AUDIO_MASTER_VOLUME: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioMasterVolume(vol); + break; + } + case GET_CUR_AUDIO_MASTER_VOLUME: + ret = mpTv->GetCurAudioMasterVolume(); + break; + //AUDIO BALANCE + case SET_AUDIO_BALANCE: { + int vol = p.readInt32(); + ret = mpTv->SetAudioBalance(vol); + break; + } + case GET_AUDIO_BALANCE: + ret = mpTv->GetAudioBalance(); + break; + + case SAVE_CUR_AUDIO_BALANCE: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioBalance(vol); + break; + } + case GET_CUR_AUDIO_BALANCE: + ret = mpTv->GetCurAudioBalance(); + break; + + //AUDIO SUPPERBASS VOLUME + case SET_AUDIO_SUPPER_BASS_VOLUME: { + int vol = p.readInt32(); + ret = mpTv->SetAudioSupperBassVolume(vol); + break; + } + case GET_AUDIO_SUPPER_BASS_VOLUME: + ret = mpTv->GetAudioSupperBassVolume(); + break; + + case SAVE_CUR_AUDIO_SUPPER_BASS_VOLUME: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioSupperBassVolume(vol); + break; + } + case GET_CUR_AUDIO_SUPPER_BASS_VOLUME: + ret = mpTv->GetCurAudioSupperBassVolume(); + break; + + //AUDIO SUPPERBASS SWITCH + case SET_AUDIO_SUPPER_BASS_SWITCH: { + int vol = p.readInt32(); + ret = mpTv->SetAudioSupperBassSwitch(vol); + break; + } + case GET_AUDIO_SUPPER_BASS_SWITCH: + ret = mpTv->GetAudioSupperBassSwitch(); + break; + + case SAVE_CUR_AUDIO_SUPPER_BASS_SWITCH: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioSupperBassSwitch(vol); + break; + } + case GET_CUR_AUDIO_SUPPER_BASS_SWITCH: + ret = mpTv->GetCurAudioSupperBassSwitch(); + break; + + //AUDIO SRS SURROUND SWITCH + case SET_AUDIO_SRS_SURROUND: { + int vol = p.readInt32(); + ret = mpTv->SetAudioSRSSurround(vol); + mpTv->RefreshAudioMasterVolume(SOURCE_MAX); + break; + } + case GET_AUDIO_SRS_SURROUND: + ret = mpTv->GetAudioSRSSurround(); + break; + + case SAVE_CUR_AUDIO_SRS_SURROUND: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioSrsSurround(vol); + break; + } + case GET_CUR_AUDIO_SRS_SURROUND: + ret = mpTv->GetCurAudioSRSSurround(); + break; + + //AUDIO SRS DIALOG CLARITY + case SET_AUDIO_SRS_DIALOG_CLARITY: { + int vol = p.readInt32(); + ret = mpTv->SetAudioSrsDialogClarity(vol); + mpTv->RefreshAudioMasterVolume(SOURCE_MAX); + break; + } + case GET_AUDIO_SRS_DIALOG_CLARITY: { + ret = mpTv->GetAudioSrsDialogClarity(); + break; + } + case SAVE_CUR_AUDIO_SRS_DIALOG_CLARITY: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioSrsDialogClarity(vol); + break; + } + case GET_CUR_AUDIO_SRS_DIALOG_CLARITY: + ret = mpTv->GetCurAudioSrsDialogClarity(); + break; + + //AUDIO SRS TRUBASS + case SET_AUDIO_SRS_TRU_BASS: { + int vol = p.readInt32(); + ret = mpTv->SetAudioSrsTruBass(vol); + mpTv->RefreshAudioMasterVolume(SOURCE_MAX); + break; + } + case GET_AUDIO_SRS_TRU_BASS: + ret = mpTv->GetAudioSrsTruBass(); + break; + + case SAVE_CUR_AUDIO_SRS_TRU_BASS: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioSrsTruBass(vol); + break; + } + case GET_CUR_AUDIO_SRS_TRU_BASS: + ret = mpTv->GetCurAudioSrsTruBass(); + break; + + //AUDIO BASS + case SET_AUDIO_BASS_VOLUME: { + int vol = p.readInt32(); + ret = mpTv->SetAudioBassVolume(vol); + break; + } + case GET_AUDIO_BASS_VOLUME: + ret = mpTv->GetAudioBassVolume(); + break; + + case SAVE_CUR_AUDIO_BASS_VOLUME: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioBassVolume(vol); + break; + } + + case GET_CUR_AUDIO_BASS_VOLUME: + ret = mpTv->GetCurAudioBassVolume(); + break; + + //AUDIO TREBLE + case SET_AUDIO_TREBLE_VOLUME: { + int vol = p.readInt32(); + ret = mpTv->SetAudioTrebleVolume(vol); + break; + } + case GET_AUDIO_TREBLE_VOLUME: + ret = mpTv->GetAudioTrebleVolume(); + break; + + case SAVE_CUR_AUDIO_TREBLE_VOLUME: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioTrebleVolume(vol); + break; + } + case GET_CUR_AUDIO_TREBLE_VOLUME: + ret = mpTv->GetCurAudioTrebleVolume(); + break; + + //AUDIO SOUND MODE + case SET_AUDIO_SOUND_MODE: { + int vol = p.readInt32(); + ret = mpTv->SetAudioSoundMode(vol); + break; + } + case GET_AUDIO_SOUND_MODE: + ret = mpTv->GetAudioSoundMode(); + break; + + case SAVE_CUR_AUDIO_SOUND_MODE: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioSoundMode(vol); + break; + } + case GET_CUR_AUDIO_SOUND_MODE: + ret = mpTv->GetCurAudioSoundMode(); + break; + + //AUDIO WALL EFFECT + case SET_AUDIO_WALL_EFFECT: { + int vol = p.readInt32(); + ret = mpTv->SetAudioWallEffect(vol); + break; + } + case GET_AUDIO_WALL_EFFECT: + ret = mpTv->GetAudioWallEffect(); + break; + + case SAVE_CUR_AUDIO_WALL_EFFECT: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioWallEffect(vol); + break; + } + case GET_CUR_AUDIO_WALL_EFFECT: + ret = mpTv->GetCurAudioWallEffect(); + break; + + //AUDIO EQ MODE + case SET_AUDIO_EQ_MODE: { + int vol = p.readInt32(); + ret = mpTv->SetAudioEQMode(vol); + break; + } + case GET_AUDIO_EQ_MODE: + ret = mpTv->GetAudioEQMode(); + break; + + case SAVE_CUR_AUDIO_EQ_MODE: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioEQMode(vol); + break; + } + case GET_CUR_AUDIO_EQ_MODE: + ret = mpTv->GetCurAudioEQMode(); + break; + + //AUDIO EQ GAIN + case GET_AUDIO_EQ_RANGE: { + int buf[2]; + ret = mpTv->GetAudioEQRange(buf); + //r->writeInt32(2); + //r->writeInt32(buf[0]); + //r->writeInt32(buf[1]); + //r->writeInt32(ret); + break; + } + case GET_AUDIO_EQ_BAND_COUNT: + ret = mpTv->GetAudioEQBandCount(); + break; + + case SET_AUDIO_EQ_GAIN: { + int buf[128] = {0}; + int bufSize = p.readInt32(); + for (int i = 0; i < bufSize; i++) { + buf[i] = p.readInt32(); + } + ret = mpTv->SetAudioEQGain(buf); + break; + } + case GET_AUDIO_EQ_GAIN: { + int buf[128] = {0}; + ret = mpTv->GetAudioEQGain(buf); + int bufSize = mpTv->GetAudioEQBandCount(); + for (int i = 0; i < bufSize; i++) { + //r->writeInt32(buf[i]); + } + //r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_EQ_GAIN: { + int buf[128] = {0}; + int bufSize = p.readInt32(); + for (int i = 0; i < bufSize; i++) { + buf[i] = p.readInt32(); + } + ret = mpTv->SaveCurAudioEQGain(buf); + break; + } + case GET_CUR_EQ_GAIN: { + int buf[128] = {0}; + ret = mpTv->GetCurAudioEQGain(buf); + int bufSize = mpTv->GetAudioEQBandCount(); + //r->writeInt32(bufSize); + for (int i = 0; i < bufSize; i++) { + //r->writeInt32(buf[i]); + } + break; + } + case SET_AUDIO_EQ_SWITCH: { + int tmpVal = p.readInt32(); + ret = mpTv->SetAudioEQSwitch(tmpVal); + break; + } + // AUDIO SPDIF SWITCH + case SET_AUDIO_SPDIF_SWITCH: { + int tmp_val = p.readInt32(); + ret = mpTv->SetAudioSPDIFSwitch(tmp_val); + break; + } + case SAVE_CUR_AUDIO_SPDIF_SWITCH: { + int tmp_val = p.readInt32(); + ret = mpTv->SaveCurAudioSPDIFSwitch(tmp_val); + break; + } + case GET_CUR_AUDIO_SPDIF_SWITCH: + ret = mpTv->GetCurAudioSPDIFSwitch(); + break; + + //AUDIO SPDIF MODE + case SET_AUDIO_SPDIF_MODE: { + int vol = p.readInt32(); + int progId = p.readInt32(); + int audioTrackId = p.readInt32(); + ret = mpTv->SetAudioSPDIFMode(vol); + mpTv->ResetAudioDecoderForPCMOutput(); + break; + } + case SAVE_CUR_AUDIO_SPDIF_MODE: { + int vol = p.readInt32(); + ret = mpTv->SaveCurAudioSPDIFMode(vol); + break; + } + case GET_CUR_AUDIO_SPDIF_MODE: + ret = mpTv->GetCurAudioSPDIFMode(); + break; + + case SET_AMAUDIO_OUTPUT_MODE: { + int tmp_val = p.readInt32(); + ret = mpTv->SetAmAudioOutputMode(tmp_val); + break; + } + case SET_AMAUDIO_MUSIC_GAIN: { + int tmp_val = p.readInt32(); + ret = mpTv->SetAmAudioMusicGain(tmp_val); + break; + } + case SET_AMAUDIO_LEFT_GAIN: { + int tmp_val = p.readInt32(); + ret = mpTv->SetAmAudioLeftGain(tmp_val); + break; + } + case SET_AMAUDIO_RIGHT_GAIN: { + int tmp_val = p.readInt32(); + ret = mpTv->SetAmAudioRightGain(tmp_val); + break; + } + case SET_AMAUDIO_PRE_GAIN: { + float tmp_val = p.readFloat(); + ret = mpTv->setAmAudioPreGain(tmp_val); + break; + } + case SET_AMAUDIO_PRE_MUTE: { + int tmp_val = p.readInt32(); + ret = mpTv->setAmAudioPreMute(tmp_val); + break; + } + case GET_AMAUDIO_PRE_MUTE: + ret = mpTv->getAmAudioPreMute(); + break; + + case SELECT_LINE_IN_CHANNEL: { + int channel = p.readInt32(); + ret = mpTv->AudioLineInSelectChannel(channel); + LOGD("SELECT_LINE_IN_CHANNEL: channel = %d; ret = %d.\n", channel, ret); + break; + } + case SET_LINE_IN_CAPTURE_VOL: { + int l_vol = p.readInt32(); + int r_vol = p.readInt32(); + ret = mpTv->AudioSetLineInCaptureVolume(l_vol, r_vol); + break; + } + case SET_AUDIO_VOL_COMP: { + int tmpVal = p.readInt32(); + ret = mpTv->SetCurProgramAudioVolumeCompensationVal(tmpVal); + break; + } + case GET_AUDIO_VOL_COMP: + ret = mpTv->GetAudioVolumeCompensationVal(-1); + break; + + case SET_AUDIO_VIRTUAL: { + int enable = p.readInt32(); + int level = p.readInt32(); + ret = mpTv->SetAudioVirtualizer(enable, level); + break; + } + case GET_AUDIO_VIRTUAL_ENABLE: + ret = mpTv->GetAudioVirtualizerEnable(); + break; + + case GET_AUDIO_VIRTUAL_LEVEL: + ret = mpTv->GetAudioVirtualizerLevel(); + break; + // AUDIO END + + // SSM + case SSM_INIT_DEVICE: + ret = mpTv->Tv_SSMRestoreDefaultSetting();//mpTv->Tv_SSMInitDevice(); + break; + + case SSM_SAVE_POWER_ON_OFF_CHANNEL: { + int tmpPowerChanNum = p.readInt32(); + ret = SSMSavePowerOnOffChannel(tmpPowerChanNum); + break; + } + case SSM_READ_POWER_ON_OFF_CHANNEL: { + ret = SSMReadPowerOnOffChannel(); + break; + } + case SSM_SAVE_SOURCE_INPUT: { + int tmpSouceInput = p.readInt32(); + ret = SSMSaveSourceInput(tmpSouceInput); + break; + } + case SSM_READ_SOURCE_INPUT: + ret = SSMReadSourceInput(); + break; + + case SSM_SAVE_LAST_SOURCE_INPUT: { + int tmpLastSouceInput = p.readInt32(); + ret = SSMSaveLastSelectSourceInput(tmpLastSouceInput); + break; + } + case SSM_READ_LAST_SOURCE_INPUT: + ret = SSMReadLastSelectSourceInput(); + break; + + case SSM_SAVE_SYS_LANGUAGE: { + int tmpVal = p.readInt32(); + ret = SSMSaveSystemLanguage(tmpVal); + break; + } + case SSM_READ_SYS_LANGUAGE: { + ret = SSMReadSystemLanguage(); + break; + } + case SSM_SAVE_AGING_MODE: { + int tmpVal = p.readInt32(); + ret = SSMSaveAgingMode(tmpVal); + break; + } + case SSM_READ_AGING_MODE: + ret = SSMReadAgingMode(); + break; + + case SSM_SAVE_PANEL_TYPE: { + int tmpVal = p.readInt32(); + ret = SSMSavePanelType(tmpVal); + break; + } + case SSM_READ_PANEL_TYPE: + ret = SSMReadPanelType(); + break; + + case SSM_SAVE_MAC_ADDR: { + int size = p.readInt32(); + for (int i = 0; i < size; i++) { + dataBuf[i] = p.readInt32(); + } + ret = KeyData_SaveMacAddress(dataBuf); + break; + } + case SSM_READ_MAC_ADDR: { + ret = KeyData_ReadMacAddress(dataBuf); + int size = KeyData_GetMacAddressDataLen(); + //r->writeInt32(size); + for (int i = 0; i < size; i++) { + //r->writeInt32(dataBuf[i]); + } + //r->writeInt32(ret); + break; + } + case SSM_SAVE_BAR_CODE: { + int size = p.readInt32(); + for (int i = 0; i < size; i++) { + dataBuf[i] = p.readInt32(); + } + ret = KeyData_SaveBarCode(dataBuf); + break; + } + case SSM_READ_BAR_CODE: { + ret = KeyData_ReadBarCode(dataBuf); + int size = KeyData_GetBarCodeDataLen(); + //r->writeInt32(size); + for (int i = 0; i < size; i++) { + //r->writeInt32(dataBuf[i]); + } + break; + } + case SSM_SAVE_HDCPKEY: { + int size = p.readInt32(); + for (int i = 0; i < size; i++) { + dataBuf[i] = p.readInt32(); + } + ret = SSMSaveHDCPKey(dataBuf); + break; + } + case SSM_READ_HDCPKEY: { + ret = SSMReadHDCPKey(dataBuf); + int size = SSMGetHDCPKeyDataLen(); + //r->writeInt32(size); + for (int i = 0; i < size; i++) { + //r->writeInt32(dataBuf[i]); + } + break; + } + case SSM_SAVE_POWER_ON_MUSIC_SWITCH: { + int tmpVal = p.readInt32(); + ret = SSMSavePowerOnMusicSwitch(tmpVal); + break; + } + case SSM_READ_POWER_ON_MUSIC_SWITCH: + ret = SSMReadPowerOnMusicSwitch(); + break; + + case SSM_SAVE_POWER_ON_MUSIC_VOL: { + int tmpVal = p.readInt32(); + ret = SSMSavePowerOnMusicVolume(tmpVal); + break; + } + case SSM_READ_POWER_ON_MUSIC_VOL: + ret = SSMReadPowerOnMusicVolume(); + break; + case SSM_SAVE_SYS_SLEEP_TIMER: { + int tmpVal = p.readInt32(); + ret = SSMSaveSystemSleepTimer(tmpVal); + break; + } + case SSM_READ_SYS_SLEEP_TIMER: + ret = SSMReadSystemSleepTimer(); + break; + + case SSM_SAVE_INPUT_SRC_PARENTAL_CTL: { + int tmpSourceIndex = p.readInt32(); + int tmpCtlFlag = p.readInt32(); + ret = SSMSaveInputSourceParentalControl(tmpSourceIndex, tmpCtlFlag); + break; + } + case SSM_READ_INPUT_SRC_PARENTAL_CTL: { + int tmpSourceIndex = p.readInt32(); + ret = SSMReadInputSourceParentalControl(tmpSourceIndex); + break; + } + case SSM_SAVE_PARENTAL_CTL_SWITCH: { + int tmpSwitchFlag = p.readInt32(); + ret = SSMSaveParentalControlSwitch(tmpSwitchFlag); + break; + } + case SSM_READ_PARENTAL_CTL_SWITCH: { + ret = SSMReadParentalControlSwitch(); + break; + } + case SSM_SAVE_PARENTAL_CTL_PASS_WORD: { + String16 pass_wd_str = p.readString16(); + ret = SSMSaveParentalControlPassWord((unsigned char *)pass_wd_str.string(), pass_wd_str.size() * sizeof(unsigned short)); + break; + } + case SSM_GET_CUSTOMER_DATA_START: + ret = SSMGetCustomerDataStart(); + break; + + case SSM_GET_CUSTOMER_DATA_LEN: + ret = SSMGetCustomerDataLen(); + break; + + case SSM_SAVE_STANDBY_MODE: { + int tmp_val = p.readInt32(); + ret = SSMSaveStandbyMode(tmp_val); + break; + } + case SSM_READ_STANDBY_MODE: + ret = SSMReadStandbyMode(); + break; + + case SSM_SAVE_LOGO_ON_OFF_FLAG: { + int tmpSwitchFlag = p.readInt32(); + ret = SSMSaveLogoOnOffFlag(tmpSwitchFlag); + break; + } + case SSM_READ_LOGO_ON_OFF_FLAG: + ret = SSMReadLogoOnOffFlag(); + break; + + case SSM_SAVE_HDMIEQ_MODE: { + int tmpSwitchFlag = p.readInt32(); + ret = SSMSaveHDMIEQMode(tmpSwitchFlag); + break; + } + case SSM_READ_HDMIEQ_MODE: + ret = SSMReadHDMIEQMode(); + break; + + case SSM_SAVE_HDMIINTERNAL_MODE: { + int tmp_val = p.readInt32(); + ret = SSMSaveHDMIInternalMode(tmp_val); + break; + } + case SSM_READ_HDMIINTERNAL_MODE: + ret = SSMReadHDMIInternalMode(); + break; + + case SSM_SAVE_GLOBAL_OGOENABLE: { + int tmp_val = p.readInt32(); + ret = SSMSaveGlobalOgoEnable(tmp_val); + break; + } + case SSM_READ_GLOBAL_OGOENABLE: + ret = SSMReadGlobalOgoEnable(); + break; + + case SSM_SAVE_NON_STANDARD_STATUS: { + int tmp_val = p.readInt32(); + ret = SSMSaveNonStandardValue(tmp_val); + break; + } + case SSM_READ_NON_STANDARD_STATUS: + ret = SSMReadNonStandardValue(); + break; + + case SSM_SAVE_ADB_SWITCH_STATUS: { + int tmp_val = p.readInt32(); + ret = SSMSaveAdbSwitchValue(tmp_val); + break; + } + case SSM_READ_ADB_SWITCH_STATUS: + ret = SSMReadAdbSwitchValue(); + break; + + case SSM_SET_HDCP_KEY: + ret = SSMSetHDCPKey(); + break; + + case SSM_REFRESH_HDCPKEY: + ret = SSMRefreshHDCPKey(); + break; + + case SSM_SAVE_CHROMA_STATUS: { + int tmp_val = p.readInt32(); + ret = SSMSaveChromaStatus(tmp_val); + break; + } + case SSM_SAVE_CA_BUFFER_SIZE: { + int tmp_val = p.readInt32(); + ret = SSMSaveCABufferSizeValue(tmp_val); + break; + } + case SSM_READ_CA_BUFFER_SIZE: + ret= SSMReadCABufferSizeValue(); + break; + + case SSM_GET_ATV_DATA_START: + ret = SSMGetATVDataStart(); + break; + + case SSM_GET_ATV_DATA_LEN: + ret = SSMGetATVDataLen(); + break; + + case SSM_GET_VPP_DATA_START: + ret = SSMGetVPPDataStart(); + break; + + case SSM_GET_VPP_DATA_LEN: + ret = SSMGetVPPDataLen(); + break; + + case SSM_SAVE_NOISE_GATE_THRESHOLD_STATUS: { + int tmp_val = p.readInt32(); + ret = SSMSaveNoiseGateThresholdValue(tmp_val); + break; + } + case SSM_READ_NOISE_GATE_THRESHOLD_STATUS: + ret = SSMReadNoiseGateThresholdValue(); + break; + + case SSM_SAVE_HDMI_EDID_VER: { + int port_id = p.readInt32(); + int ver = p.readInt32(); + ret = SSMSaveHDMIEdidMode((tv_hdmi_port_id_t)port_id, (tv_hdmi_edid_version_t)ver); + break; + } + case SSM_READ_HDMI_EDID_VER: { + int port_id = p.readInt32(); + ret = SSMReadHDMIEdidVersion((tv_hdmi_port_id_t)port_id); + break; + } + case SSM_SAVE_HDCP_KEY_ENABLE: { + int enable = p.readInt32(); + ret = SSMSaveHDMIHdcpSwitcher(enable); + break; + } + case SSM_READ_HDCP_KEY_ENABLE: + ret = SSMReadHDMIHdcpSwitcher(); + break; + // SSM END + + //MISC + case MISC_CFG_SET: { + String8 key(p.readString16()); + String8 value(p.readString16()); + + ret = config_set_str(CFG_SECTION_TV, key.string(), value.string()); + break; + } + case MISC_CFG_GET: { + String8 key(p.readString16()); + String8 def(p.readString16()); + + const char *value = config_get_str(CFG_SECTION_TV, key.string(), def.string()); + //r->writeString16(String16(value)); + break; + } + case MISC_SET_WDT_USER_PET: { + int counter = p.readInt32(); + ret = TvMisc_SetUserCounter(counter); + break; + } + case MISC_SET_WDT_USER_COUNTER: { + int counter_time_out = p.readInt32(); + ret = TvMisc_SetUserCounterTimeOut(counter_time_out); + break; + } + case MISC_SET_WDT_USER_PET_RESET_ENABLE: { + int enable = p.readInt32(); + ret = TvMisc_SetUserPetResetEnable(enable); + break; + } + case MISC_GET_TV_API_VERSION: { + // write tvapi version info + const char *str = tvservice_get_git_branch_info(); + //r->writeString16(String16(str)); + + str = tvservice_get_git_version_info(); + //r->writeString16(String16(str)); + + str = tvservice_get_last_chaned_time_info(); + //r->writeString16(String16(str)); + + str = tvservice_get_build_time_info(); + //r->writeString16(String16(str)); + + str = tvservice_get_build_name_info(); + //r->writeString16(String16(str)); + break; + } + case MISC_GET_DVB_API_VERSION: { + // write dvb version info + //const char *str = dvb_get_git_branch_info(); + //r->writeString16(String16(str)); + + //str = dvb_get_git_version_info(); + //r->writeString16(String16(str)); + + //str = dvb_get_last_chaned_time_info(); + //r->writeString16(String16(str)); + + //str = dvb_get_build_time_info(); + //r->writeString16(String16(str)); + + //str = dvb_get_build_name_info(); + //r->writeString16(String16(str)); + break; + } + //MISC END + + // EXTAR + case ATV_GET_CURRENT_PROGRAM_ID: + ret = mpTv->getATVProgramID(); + break; + + case DTV_GET_CURRENT_PROGRAM_ID: + ret = mpTv->getDTVProgramID(); + break; + + case ATV_SAVE_PROGRAM_ID: { + int progID = p.readInt32(); + mpTv->saveATVProgramID(progID); + break; + } + case SAVE_PROGRAM_ID: { + int type = p.readInt32(); + int progID = p.readInt32(); + if (type == CTvProgram::TYPE_DTV) + mpTv->saveDTVProgramID(progID); + else if (type == CTvProgram::TYPE_RADIO) + mpTv->saveRadioProgramID(progID); + else + mpTv->saveATVProgramID(progID); + break; + } + case GET_PROGRAM_ID: { + int type = p.readInt32(); + int id; + if (type == CTvProgram::TYPE_DTV) + id = mpTv->getDTVProgramID(); + else if (type == CTvProgram::TYPE_RADIO) + id = mpTv->getRadioProgramID(); + else + id = mpTv->getATVProgramID(); + ret = id; + break; + } + + case ATV_GET_MIN_MAX_FREQ: { + int min, max; + int tmpRet = mpTv->getATVMinMaxFreq(&min, &max); + //r->writeInt32(min); + //r->writeInt32(max); + //r->writeInt32(tmpRet); + break; + } + case DTV_GET_SCAN_FREQUENCY_LIST: { + Vector<sp<CTvChannel> > out; + ret = CTvRegion::getChannelListByName((char *)"CHINA,Default DTMB ALL", out); + //r->writeInt32(out.size()); + for (int i = 0; i < (int)out.size(); i++) { + //r->writeInt32(out[i]->getID()); + //r->writeInt32(out[i]->getFrequency()); + //r->writeInt32(out[i]->getLogicalChannelNum()); + } + break; + } + case DTV_GET_SCAN_FREQUENCY_LIST_MODE: { + int mode = p.readInt32(); + Vector<sp<CTvChannel> > out; + ret = CTvRegion::getChannelListByName((char *)CTvScanner::getDtvScanListName(mode), out); + //r->writeInt32(out.size()); + for (int i = 0; i < (int)out.size(); i++) { + //r->writeInt32(out[i]->getID()); + //r->writeInt32(out[i]->getFrequency()); + //r->writeInt32(out[i]->getLogicalChannelNum()); + } + break; + } + case DTV_GET_CHANNEL_INFO: { + int dbID = p.readInt32(); + channel_info_t chan_info; + ret = mpTv->getChannelInfoBydbID(dbID, chan_info); + //r->writeInt32(chan_info.freq); + //r->writeInt32(chan_info.uInfo.dtvChanInfo.strength); + //r->writeInt32(chan_info.uInfo.dtvChanInfo.quality); + //r->writeInt32(chan_info.uInfo.dtvChanInfo.ber); + break; + } + case ATV_GET_CHANNEL_INFO: { + int dbID = p.readInt32(); + channel_info_t chan_info; + ret = mpTv->getChannelInfoBydbID(dbID, chan_info); + //r->writeInt32(chan_info.freq); + //r->writeInt32(chan_info.uInfo.atvChanInfo.finefreq); + //r->writeInt32(chan_info.uInfo.atvChanInfo.videoStd); + //r->writeInt32(chan_info.uInfo.atvChanInfo.audioStd); + //r->writeInt32(chan_info.uInfo.atvChanInfo.isAutoStd); + break; + } + case ATV_SCAN_MANUAL: { + int startFreq = p.readInt32(); + int endFreq = p.readInt32(); + int videoStd = p.readInt32(); + int audioStd = p.readInt32(); + ret = mpTv->atvMunualScan(startFreq, endFreq, videoStd, audioStd); + //mTvService->mpScannerClient = this; + break; + } + + case ATV_SCAN_AUTO: { + int videoStd = p.readInt32(); + int audioStd = p.readInt32(); + int searchType = p.readInt32(); + int procMode = p.readInt32(); + ret = mpTv->atvAutoScan(videoStd, audioStd, searchType, procMode); + //mTvService->mpScannerClient = this; + break; + } + case DTV_SCAN_MANUAL: { + int freq = p.readInt32(); + ret = mpTv->dtvManualScan(freq, freq); + //mTvService->mpScannerClient = this; + break; + } + case DTV_SCAN_MANUAL_BETWEEN_FREQ: { + int beginFreq = p.readInt32(); + int endFreq = p.readInt32(); + int modulation = p.readInt32(); + ret = mpTv->dtvManualScan(beginFreq, endFreq, modulation); + //mTvService->mpScannerClient = this; + break; + } + case DTV_SCAN_AUTO: { + ret = mpTv->dtvAutoScan(); + //mTvService->mpScannerClient = this; + break; + } + case DTV_SCAN: { + int mode = p.readInt32(); + int scanmode = p.readInt32(); + int freq = p.readInt32(); + int para1 = p.readInt32(); + int para2 = p.readInt32(); + ret = mpTv->dtvScan(mode, scanmode, freq, freq, para1, para2); + //mTvService->mpScannerClient = this; + break; + } + case STOP_PROGRAM_PLAY: + ret = mpTv->stopPlayingLock(); + break; + + case ATV_DTV_SCAN_PAUSE: + ret = mpTv->pauseScan(); + break; + + case ATV_DTV_SCAN_RESUME: + ret = mpTv->resumeScan(); + break; + + case ATV_DTV_GET_SCAN_STATUS: + ret = mpTv->getScanStatus(); + break; + + case ATV_DTV_SCAN_OPERATE_DEVICE : { + int type = p.readInt32(); + mpTv->operateDeviceForScan(type); + break; + } + case DTV_SET_TEXT_CODING: { + String8 coding(p.readString16()); + mpTv->setDvbTextCoding((char *)coding.string()); + break; + } + + case TV_CLEAR_ALL_PROGRAM: { + int arg0 = p.readInt32(); + + ret = mpTv->clearAllProgram(arg0); + //mTvService->mpScannerClient = this; + break; + } + + case HDMIRX_GET_KSV_INFO: { + int data[2] = {0, 0}; + ret = mpTv->GetHdmiHdcpKeyKsvInfo(data); + //r->writeInt32(data[0]); + //r->writeInt32(data[1]); + break; + } + + case STOP_SCAN: + mpTv->stopScanLock(); + break; + + case DTV_GET_SNR: + ret = mpTv->getFrontendSNR(); + break; + + case DTV_GET_BER: + ret = mpTv->getFrontendBER(); + break; + + case DTV_GET_STRENGTH: + ret = mpTv->getFrontendSignalStrength(); + break; + + case DTV_GET_AUDIO_TRACK_NUM: { + int programId = p.readInt32(); + ret = mpTv->getAudioTrackNum(programId); + break; + } + case DTV_GET_AUDIO_TRACK_INFO: { + int progId = p.readInt32(); + int aIdx = p.readInt32(); + int aFmt = -1; + String8 lang; + ret = mpTv->getAudioInfoByIndex(progId, aIdx, &aFmt, lang); + //r->writeInt32(aFmt); + //r->writeString16(String16(lang)); + break; + } + case DTV_SWITCH_AUDIO_TRACK: { + int aPid = p.readInt32(); + int aFmt = p.readInt32(); + int aParam = p.readInt32(); + ret = mpTv->switchAudioTrack(aPid, aFmt, aParam); + break; + } + case DTV_SET_AUDIO_AD: { + int aEnable = p.readInt32(); + int aPid = p.readInt32(); + int aFmt = p.readInt32(); + ret = mpTv->setAudioAD(aEnable, aPid, aFmt); + break; + } + case DTV_GET_CURR_AUDIO_TRACK_INDEX: { + int currAduIdx = -1; + int progId = p.readInt32(); + CTvProgram prog; + CTvProgram::selectByID(progId, prog); + currAduIdx = prog.getCurrAudioTrackIndex(); + //r->writeInt32(currAduIdx); + break; + } + case DTV_SET_AUDIO_CHANNEL_MOD: { + int audioChannelIdx = p.readInt32(); + mpTv->setAudioChannel(audioChannelIdx); + break; + } + case DTV_GET_AUDIO_CHANNEL_MOD: { + int currChannelMod = mpTv->getAudioChannel(); + //r->writeInt32(currChannelMod); + break; + } + case DTV_GET_CUR_FREQ: { + int progId = p.readInt32(); + CTvProgram prog; + CTvChannel channel; + + int iRet = CTvProgram::selectByID(progId, prog); + if (0 != iRet) return -1; + prog.getChannel(channel); + int freq = channel.getFrequency(); + //r->writeInt32(freq); + break; + } + case DTV_GET_EPG_UTC_TIME: { + int utcTime = mpTv->getTvTime(); + //r->writeInt32(utcTime); + break; + } + case DTV_GET_EPG_INFO_POINT_IN_TIME: { + int progid = p.readInt32(); + int utcTime = p.readInt32(); + CTvProgram prog; + int ret = CTvProgram::selectByID(progid, prog); + CTvEvent ev; + ret = ev.getProgPresentEvent(prog.getSrc(), prog.getID(), utcTime, ev); + //r->writeString16(String16(ev.getName())); + //r->writeString16(String16(ev.getDescription())); + //r->writeString16(String16(ev.getExtDescription())); + //r->writeInt32(ev.getStartTime()); + //r->writeInt32(ev.getEndTime()); + //r->writeInt32(ev.getSubFlag()); + //r->writeInt32(ev.getEventId()); + break; + } + case DTV_GET_EPG_INFO_DURATION: { + Vector<sp<CTvEvent> > epgOut; + int progid = p.readInt32(); + int iUtcStartTime = p.readInt32(); + int iDurationTime = p.readInt32(); + CTvProgram prog; + CTvEvent ev; + int iRet = CTvProgram::selectByID(progid, prog); + if (0 != iRet) { + break; + } + iRet = ev.getProgScheduleEvents(prog.getSrc(), prog.getID(), iUtcStartTime, iDurationTime, epgOut); + if (0 != iRet) { + break; + } + int iObOutSize = epgOut.size(); + if (0 == iObOutSize) { + break; + } + + //r->writeInt32(iObOutSize); + for (int i = 0; i < iObOutSize; i ++) { + //r->writeString16(String16(epgOut[i]->getName())); + //r->writeString16(String16(epgOut[i]->getDescription())); + //r->writeString16(String16(ev.getExtDescription())); + //r->writeInt32(epgOut[i]->getStartTime()); + //r->writeInt32(epgOut[i]->getEndTime()); + //r->writeInt32(epgOut[i]->getSubFlag()); + //r->writeInt32(epgOut[i]->getEventId()); + } + break; + } + case DTV_SET_PROGRAM_NAME: { + CTvProgram prog; + int progid = p.readInt32(); + String16 tmpName = p.readString16(); + String8 strName = String8(tmpName); + prog.updateProgramName(progid, strName); + break; + } + case DTV_SET_PROGRAM_SKIPPED: { + CTvProgram prog; + int progid = p.readInt32(); + bool bSkipFlag = p.readInt32(); + prog.setSkipFlag(progid, bSkipFlag); + break; + } + case DTV_SET_PROGRAM_FAVORITE: { + CTvProgram prog; + int progid = p.readInt32(); + bool bFavorite = p.readInt32(); + prog.setFavoriteFlag(progid, bFavorite); + break; + } + case DTV_DETELE_PROGRAM: { + CTvProgram prog; + int progid = p.readInt32(); + prog.deleteProgram(progid); + break; + } + case SET_BLACKOUT_ENABLE: { + int enable = p.readInt32(); + mpTv->setBlackoutEnable(enable); + break; + } + case START_AUTO_BACKLIGHT: + mpTv->setAutoBackLightStatus(1); + break; + + case STOP_AUTO_BACKLIGHT: + mpTv->setAutoBackLightStatus(0); + break; + + case IS_AUTO_BACKLIGHTING: { + int on = mpTv->getAutoBackLightStatus(); + break; + } + + case GET_AVERAGE_LUMA: + ret = mpTv->getAverageLuma(); + break; + + case GET_AUTO_BACKLIGHT_DATA: { + int buf[128] = {0}; + int size = mpTv->getAutoBacklightData(buf); + //r->writeInt32(size); + for (int i = 0; i < size; i++) { + //r->writeInt32(buf[i]); + } + break; + } + case SET_AUTO_BACKLIGHT_DATA: + ret = mpTv->setAutobacklightData(String8(p.readString16())); + break; + + case SSM_READ_BLACKOUT_ENABLE: { + int enable = mpTv->getSaveBlackoutEnable(); + //r->writeInt32(enable); + break; + } + case DTV_SWAP_PROGRAM: { + CTvProgram prog; + int firstProgId = p.readInt32(); + int secondProgId = p.readInt32(); + CTvProgram::selectByID(firstProgId, prog); + int firstChanOrderNum = prog.getChanOrderNum(); + CTvProgram::selectByID(secondProgId, prog); + int secondChanOrderNum = prog.getChanOrderNum(); + prog.swapChanOrder(firstProgId, firstChanOrderNum, secondProgId, secondChanOrderNum); + break; + } + case DTV_SET_PROGRAM_LOCKED: { + CTvProgram prog; + int progid = p.readInt32(); + bool bLocked = p.readInt32(); + prog.setLockFlag(progid, bLocked); + break; + } + case DTV_GET_FREQ_BY_PROG_ID: { + int freq = 0; + int progid = p.readInt32(); + CTvProgram prog; + ret = CTvProgram::selectByID(progid, prog); + if (ret != 0) return -1; + CTvChannel channel; + prog.getChannel(channel); + freq = channel.getFrequency(); + break; + } + case DTV_GET_BOOKED_EVENT: { + CTvBooking tvBook; + Vector<sp<CTvBooking> > vTvBookOut; + tvBook.getBookedEventList(vTvBookOut); + int iObOutSize = vTvBookOut.size(); + if (0 == iObOutSize) { + break; + } + //r->writeInt32(iObOutSize); + for (int i = 0; i < iObOutSize; i ++) { + //r->writeString16(String16(vTvBookOut[i]->getProgName())); + //r->writeString16(String16(vTvBookOut[i]->getEvtName())); + //r->writeInt32(vTvBookOut[i]->getStartTime()); + //r->writeInt32(vTvBookOut[i]->getDurationTime()); + //r->writeInt32(vTvBookOut[i]->getBookId()); + //r->writeInt32(vTvBookOut[i]->getProgramId()); + //r->writeInt32(vTvBookOut[i]->getEventId()); + } + break; + } + case SET_FRONTEND_PARA: { + frontend_para_set_t feParms; + //feParms.mode = (fe_type_t)p.readInt32(); + feParms.freq = p.readInt32(); + feParms.videoStd = (atv_video_std_t)p.readInt32(); + feParms.audioStd = (atv_audio_std_t)p.readInt32(); + feParms.para1 = p.readInt32(); + feParms.para2 = p.readInt32(); + mpTv->resetFrontEndPara(feParms); + break; + } + case PLAY_PROGRAM: { + int mode = p.readInt32(); + int freq = p.readInt32(); + if (mode == TV_FE_ANALOG) { + int videoStd = p.readInt32(); + int audioStd = p.readInt32(); + int fineTune = p.readInt32(); + int audioCompetation = p.readInt32(); + mpTv->playAtvProgram(freq, videoStd, audioStd, fineTune, audioCompetation); + } else { + int para1 = p.readInt32(); + int para2 = p.readInt32(); + int vid = p.readInt32(); + int vfmt = p.readInt32(); + int aid = p.readInt32(); + int afmt = p.readInt32(); + int pcr = p.readInt32(); + int audioCompetation = p.readInt32(); + mpTv->playDtvProgram(mode, freq, para1, para2, vid, vfmt, aid, afmt, pcr, audioCompetation); + } + break; + } + case GET_PROGRAM_LIST: { + Vector<sp<CTvProgram> > out; + int type = p.readInt32(); + int skip = p.readInt32(); + CTvProgram::selectByType(type, skip, out); + /* + r->writeInt32(out.size()); + for (int i = 0; i < (int)out.size(); i++) { + r->writeInt32(out[i]->getID()); + r->writeInt32(out[i]->getChanOrderNum()); + r->writeInt32(out[i]->getMajor()); + r->writeInt32(out[i]->getMinor()); + r->writeInt32(out[i]->getProgType()); + r->writeString16(String16(out[i]->getName())); + r->writeInt32(out[i]->getProgSkipFlag()); + r->writeInt32(out[i]->getFavoriteFlag()); + r->writeInt32(out[i]->getVideo()->getFormat()); + CTvChannel ch; + out[i]->getChannel(ch); + r->writeInt32(ch.getDVBTSID()); + r->writeInt32(out[i]->getServiceId()); + r->writeInt32(out[i]->getVideo()->getPID()); + r->writeInt32(out[i]->getVideo()->getPID()); + + int audioTrackSize = out[i]->getAudioTrackSize(); + r->writeInt32(audioTrackSize); + for (int j = 0; j < audioTrackSize; j++) { + r->writeString16(String16(out[i]->getAudio(j)->getLang())); + r->writeInt32(out[i]->getAudio(j)->getFormat()); + r->writeInt32(out[i]->getAudio(j)->getPID()); + } + Vector<CTvProgram::Subtitle *> mvSubtitles = out[i]->getSubtitles(); + int subTitleSize = mvSubtitles.size(); + r->writeInt32(subTitleSize); + if (subTitleSize > 0) { + for (int k = 0; k < subTitleSize; k++) { + r->writeInt32(mvSubtitles[k]->getPID()); + r->writeString16(String16(mvSubtitles[k]->getLang())); + r->writeInt32(mvSubtitles[k]->getCompositionPageID()); + r->writeInt32(mvSubtitles[k]->getAncillaryPageID()); + } + } + r->writeInt32(ch.getFrequency()); + } + */ + break; + } + case DTV_GET_VIDEO_FMT_INFO: { + int srcWidth = 0; + int srcHeight = 0; + int srcFps = 0; + int srcInterlace = 0; + int iRet = -1; + + /* + iRet == mpTv->getVideoFormatInfo(&srcWidth, &srcHeight, &srcFps, &srcInterlace); + r->writeInt32(srcWidth); + r->writeInt32(srcHeight); + r->writeInt32(srcFps); + r->writeInt32(srcInterlace); + r->writeInt32(iRet); + */ + } + break; + + case DTV_GET_AUDIO_FMT_INFO: { + int iRet = -1; + int fmt[2]; + int sample_rate[2]; + int resolution[2]; + int channels[2]; + int lpepresent[2]; + int frames; + int ab_size; + int ab_data; + int ab_free; + iRet == mpTv->getAudioFormatInfo(fmt, sample_rate, resolution, channels, + lpepresent, &frames, &ab_size, &ab_data, &ab_free); + /* + r->writeInt32(fmt[0]); + r->writeInt32(fmt[1]); + r->writeInt32(sample_rate[0]); + r->writeInt32(sample_rate[1]); + r->writeInt32(resolution[0]); + r->writeInt32(resolution[1]); + r->writeInt32(channels[0]); + r->writeInt32(channels[1]); + r->writeInt32(lpepresent[0]); + r->writeInt32(lpepresent[1]); + r->writeInt32(frames); + r->writeInt32(ab_size); + r->writeInt32(ab_data); + r->writeInt32(ab_free); + r->writeInt32(iRet); + */ + } + break; + + case HDMIAV_HOTPLUGDETECT_ONOFF: + ret = mpTv->GetHdmiAvHotplugDetectOnoff(); + break; + + case HANDLE_GPIO: { + String8 strName(p.readString16()); + int is_out = p.readInt32(); + int edge = p.readInt32(); + ret = mpTv->handleGPIO((char *)strName.string(), is_out, edge); + break; + } + case SET_LCD_ENABLE: { + int enable = p.readInt32(); + ret = mpTv->setLcdEnable(enable); + break; + } + case GET_ALL_TV_DEVICES: + //const char *value = config_get_str(CFG_SECTION_TV, CGF_DEFAULT_INPUT_IDS, "null"); + //r->writeCString(value); + break; + + case GET_HDMI_PORTS: + ret = config_get_int(CFG_SECTION_TV, CGF_DEFAULT_HDMI_PORTS, 0); + break; + + case TV_CLEAR_FRONTEND: { + int para = p.readInt32(); + ret = mpTv->clearFrontEnd(para); + break; + } + case TV_SET_FRONTEND: { + int force = p.readInt32(); + String8 feparas(p.readString16()); + ret = mpTv->setFrontEnd(feparas, (force != 0)); + break; + } + case PLAY_PROGRAM_2: { + String8 feparas(p.readString16()); + int vid = p.readInt32(); + int vfmt = p.readInt32(); + int aid = p.readInt32(); + int afmt = p.readInt32(); + int pcr = p.readInt32(); + int audioCompetation = p.readInt32(); + mpTv->playDtvProgram(feparas.string(), vid, vfmt, aid, afmt, pcr, audioCompetation); + break; + } + case TV_SCAN_2: { + String8 feparas(p.readString16()); + String8 scanparas(p.readString16()); + ret = mpTv->Scan(feparas.string(), scanparas.string()); + //mTvService->mpScannerClient = this; + break; + } + case SET_AUDIO_OUTMODE: { + int mode = p.readInt32(); + ret = SetAudioOutmode(mode); + break; + } + + case GET_AUDIO_OUTMODE: + ret = GetAudioOutmode(); + break; + + case GET_AUDIO_STREAM_OUTMODE: + ret = GetAudioStreamOutmode(); + break; + + case SET_AMAUDIO_VOLUME: { + int volume = p.readInt32(); + ret = mpTv->setAmAudioVolume(float (volume)); + break; + } + case GET_AMAUDIO_VOLUME: + ret = (int)mpTv->getAmAudioVolume(); + break; + + case SAVE_AMAUDIO_VOLUME: { + int volume = p.readInt32(); + int source = p.readInt32(); + ret = mpTv->saveAmAudioVolume(volume, source); + break; + } + case GET_SAVE_AMAUDIO_VOLUME: { + int source = p.readInt32(); + ret = mpTv->getSaveAmAudioVolume(source); + break; + } + case DTV_UPDATE_RRT: { + int freq = p.readInt32(); + int modulation = p.readInt32(); + int mode = p.readInt32(); + ret = mpTv->Tv_RrtUpdate(freq, modulation, mode); + break; + } + case DTV_SEARCH_RRT: { + int rating_region_id = p.readInt32(); + int dimension_id = p.readInt32(); + int value_id = p.readInt32(); + rrt_select_info_t rrt_info; + ret = mpTv->Tv_RrtSearch(rating_region_id, dimension_id, value_id, &rrt_info); + //r->writeInt32(rrt_info.dimensions_name_count); + int count = rrt_info.dimensions_name_count; + if (count != 0) { + //r->writeString16(String16(rrt_info.dimensions_name)); + } + //r->writeInt32(rrt_info.rating_region_name_count); + count = rrt_info.rating_region_name_count; + if (count != 0) { + //r->writeString16(String16(rrt_info.rating_region_name)); + } + //r->writeInt32(rrt_info.rating_value_text_count); + count = rrt_info.rating_value_text_count; + if (count != 0) { + //r->writeString16(String16(rrt_info.rating_value_text)); + } + break; + } + + case DTV_UPDATE_EAS: + ret = mpTv->Tv_Easupdate(); + break; + // EXTAR END + + //NEWPLAY/RECORDING + case DTV_RECORDING_CMD: + ret = mpTv->doRecordingCommand(p.readInt32(), String8(p.readString16()).string(), String8(p.readString16()).string()); + break; + + case DTV_PLAY_CMD: + ret = mpTv->doPlayCommand(p.readInt32(), String8(p.readString16()).string(), String8(p.readString16()).string()); + break; + + default: + break; + } + + return ret; +} + +void DroidTvServiceIntf::setListener(const sp<TvServiceNotify>& listener) { + mNotifyListener = listener; +} + + + +status_t DroidTvServiceIntf::dump(int fd, const Vector<String16>& args) +{ +#if 0 + String8 result; + if (!checkCallingPermission(String16("android.permission.DUMP"))) { + char buffer[256]; + snprintf(buffer, 256, "Permission Denial: " + "can't dump system_control from pid=%d, uid=%d\n", + IPCThreadState::self()->getCallingPid(), + IPCThreadState::self()->getCallingUid()); + result.append(buffer); + } else { + AutoMutex _l(mServiceLock); + if (args.size() > 0) { + for (int i = 0; i < (int)args.size(); i ++) { + if (args[i] == String16("-s")) { + String8 section(args[i+1]); + String8 key(args[i+2]); + const char *value = config_get_str(section, key, ""); + result.appendFormat("section:[%s] key:[%s] value:[%s]\n", section.string(), key.string(), value); + } + else if (args[i] == String16("-h")) { + result.append( + "\ntv service use to control the tv logical \n\n" + "usage: dumpsys tvservice [-s <SECTION> <KEY>][-m][-h] \n" + "-s: get config string \n" + " SECTION:[TV|ATV|SourceInputMap|SETTING|FBCUART]\n" + "-m: track native heap memory\n" + "-h: help \n\n"); + } + else if (args[i] == String16("-m")) { + dumpMemoryAddresses(fd); + } + } + } + else { + /* + result.appendFormat("client num = %d\n", mUsers); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + result.appendFormat("client[%d] pid = %d\n", i, c->getPid()); + } + } + } + */ + + mpTv->dump(result); + } + } + write(fd, result.string(), result.size()); +#endif + return NO_ERROR; +} + diff --git a/tv/tvserver/tvserver/DroidTvServiceIntf.h b/tv/tvserver/tvserver/DroidTvServiceIntf.h new file mode 100644 index 0000000..b8085cc --- a/dev/null +++ b/tv/tvserver/tvserver/DroidTvServiceIntf.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2016 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/16 + * @par function description: + * - 1 droidlogic tvservice interface + */ + +#ifndef ANDROID_DROID_TV_TVSERVICE_INTF_H +#define ANDROID_DROID_TV_TVSERVICE_INTF_H + +//#include <include/Tv.h> +#include <utils/threads.h> +#include <utils/Vector.h> +#include <stdint.h> +#include <tv/CTv.h> + +#include <vendor/amlogic/hardware/tvserver/1.0/ITvServer.h> + +using namespace android; + +using ::vendor::amlogic::hardware::tvserver::V1_0::TvHidlParcel; + +class TvServiceNotify : virtual public RefBase { +public: + TvServiceNotify() {} + virtual ~TvServiceNotify(){} + virtual void onEvent(const TvHidlParcel &hidlParcel) = 0; +}; + +class DroidTvServiceIntf: public CTv::TvIObserver { +public: + DroidTvServiceIntf(); + virtual ~DroidTvServiceIntf(); + int processCmd(const Parcel &p); + void setListener(const sp<TvServiceNotify>& listener); + virtual void onTvEvent(const CTvEv &ev); + + void startListener(); + int startTv(); + int stopTv(); + int switchInputSrc(int32_t inputSrc); + int getInputSrcConnectStatus(int32_t inputSrc); + int getCurrentInputSrc(); + int getHdmiAvHotplugStatus(); + std::string getSupportInputDevices(); + int getHdmiPorts(); + void getCurSignalInfo(int &fmt, int &transFmt, int &status, int &frameRate); + int setMiscCfg(const std::string& key, const std::string& val); + std::string getMiscCfg(const std::string& key, const std::string& def); + + int isDviSIgnal(); + int isVgaTimingInHdmi(); + + virtual status_t dump(int fd, const Vector<String16>& args); + + //wp<Client> mpScannerClient; + //wp<Client> mpSubClient; + //Vector< wp<Client> > mClients; + +private: + bool mIsStartTv; + CTv *mpTv; + sp<TvServiceNotify> mNotifyListener; +}; + +#endif/*ANDROID_DROID_TV_TVSERVICE_INTF_H*/ diff --git a/tv/tvserver/tvserver/MemoryLeakTrackUtil.cpp b/tv/tvserver/tvserver/MemoryLeakTrackUtil.cpp new file mode 100644 index 0000000..33badeb --- a/dev/null +++ b/tv/tvserver/tvserver/MemoryLeakTrackUtil.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> + +#include "MemoryLeakTrackUtil.h" + +/* + * The code here originally resided in MediaPlayerService.cpp and was + * shamelessly copied over to support memory leak tracking from + * multiple places. + */ +namespace android { + +#if defined(__arm__) + +extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize, + size_t* infoSize, size_t* totalMemory, size_t* backtraceSize); + +extern "C" void free_malloc_leak_info(uint8_t* info); + +// Use the String-class below instead of String8 to allocate all memory +// beforehand and not reenter the heap while we are examining it... +struct MyString8 { + static const size_t MAX_SIZE = 256 * 1024; + + MyString8() + : mPtr((char *)malloc(MAX_SIZE)) { + *mPtr = '\0'; + } + + ~MyString8() { + free(mPtr); + } + + void append(const char *s) { + strncat(mPtr, s, MAX_SIZE - size() - 1); + } + + const char *string() const { + return mPtr; + } + + size_t size() const { + return strlen(mPtr); + } + + void clear() { + *mPtr = '\0'; + } + +private: + char *mPtr; + + MyString8(const MyString8 &); + MyString8 &operator=(const MyString8 &); +}; + +void dumpMemoryAddresses(int fd) +{ + const size_t SIZE = 256; + char buffer[SIZE]; + MyString8 result; + + typedef struct { + size_t size; + size_t dups; + intptr_t * backtrace; + } AllocEntry; + + uint8_t *info = NULL; + size_t overallSize = 0; + size_t infoSize = 0; + size_t totalMemory = 0; + size_t backtraceSize = 0; + + get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize); + if (info) { + uint8_t *ptr = info; + size_t count = overallSize / infoSize; + + snprintf(buffer, SIZE, " Allocation count %i\n", count); + result.append(buffer); + snprintf(buffer, SIZE, " Total memory %i\n", totalMemory); + result.append(buffer); + + AllocEntry * entries = new AllocEntry[count]; + + for (size_t i = 0; i < count; i++) { + // Each entry should be size_t, size_t, intptr_t[backtraceSize] + AllocEntry *e = &entries[i]; + + e->size = *reinterpret_cast<size_t *>(ptr); + ptr += sizeof(size_t); + + e->dups = *reinterpret_cast<size_t *>(ptr); + ptr += sizeof(size_t); + + e->backtrace = reinterpret_cast<intptr_t *>(ptr); + ptr += sizeof(intptr_t) * backtraceSize; + } + + // Now we need to sort the entries. They come sorted by size but + // not by stack trace which causes problems using diff. + bool moved; + do { + moved = false; + for (size_t i = 0; i < (count - 1); i++) { + AllocEntry *e1 = &entries[i]; + AllocEntry *e2 = &entries[i+1]; + + bool swap = e1->size < e2->size; + if (e1->size == e2->size) { + for (size_t j = 0; j < backtraceSize; j++) { + if (e1->backtrace[j] == e2->backtrace[j]) { + continue; + } + swap = e1->backtrace[j] < e2->backtrace[j]; + break; + } + } + if (swap) { + AllocEntry t = entries[i]; + entries[i] = entries[i+1]; + entries[i+1] = t; + moved = true; + } + } + } while (moved); + + write(fd, result.string(), result.size()); + result.clear(); + + for (size_t i = 0; i < count; i++) { + AllocEntry *e = &entries[i]; + + snprintf(buffer, SIZE, "size %8i, dup %4i, ", e->size, e->dups); + result.append(buffer); + for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) { + if (ct) { + result.append(", "); + } + snprintf(buffer, SIZE, "0x%08x", e->backtrace[ct]); + result.append(buffer); + } + result.append("\n"); + + write(fd, result.string(), result.size()); + result.clear(); + } + + delete[] entries; + free_malloc_leak_info(info); + } +} + +#else +// Does nothing +void dumpMemoryAddresses(int fd __unused) {} + +#endif +} // namespace android diff --git a/tv/tvserver/tvserver/MemoryLeakTrackUtil.h b/tv/tvserver/tvserver/MemoryLeakTrackUtil.h new file mode 100644 index 0000000..5dd9a28 --- a/dev/null +++ b/tv/tvserver/tvserver/MemoryLeakTrackUtil.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef MEMORY_LEAK_TRACK_UTIL_H +#define MEMORY_LEAK_TRACK_UTIL_H + +namespace android { +/* + * Dump the memory address of the calling process to the given fd. + */ +extern void dumpMemoryAddresses(int fd); + +}; + +#endif // MEMORY_LEAK_TRACK_UTIL_H diff --git a/tv/tvserver/tvserver/TvService.cpp b/tv/tvserver/tvserver/TvService.cpp new file mode 100644 index 0000000..ff597c2 --- a/dev/null +++ b/tv/tvserver/tvserver/TvService.cpp @@ -0,0 +1,3708 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "TvService" + +#include <utils/Log.h> +#include <binder/IServiceManager.h> +#include <binder/IPCThreadState.h> +#include <utils/String16.h> +#include <utils/Errors.h> +#include <binder/MemoryBase.h> +#include <binder/MemoryHeapBase.h> +#include <ITvService.h> +#include <hardware/hardware.h> +#include "TvService.h" +#include <cutils/atomic.h> +#include <cutils/properties.h> +#include <stdint.h> +#include <CTvLog.h> +#include <tvconfig.h> +#include <tvutils.h> +#include <tvsetting/CTvSetting.h> +#include <tv/CTvFactory.h> +#include <audio/CTvAudio.h> +#include <version/version.h> +#include "tvcmd.h" +#include <tvdb/CTvRegion.h> +#include "MemoryLeakTrackUtil.h" +extern "C" { +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <pthread.h> +#include <signal.h> +#ifdef SUPPORT_ADTV +#include "am_ver.h" +#endif +} + +static int getCallingPid() +{ + return IPCThreadState::self()->getCallingPid(); +} + +void TvService::instantiate() +{ + android::status_t ret = defaultServiceManager()->addService(String16("tvservice"), new TvService()); + if (ret != android::OK) { + LOGE("Couldn't register tv service!"); + } + LOGD("instantiate add tv service result:%d", ret); +} + +TvService::TvService() :BnTvService() +{ + mpScannerClient = NULL; + mUsers = 0; + mpTv = new CTv(); + mpTv->setTvObserver(this); + mCapVidFrame.setObserver(this); + mpTv->OpenTv(); +} + +TvService::~TvService() +{ + mpScannerClient = NULL; + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + LOGW("some client still connect it!"); + } + } + + if (mpTv != NULL) { + delete mpTv; + mpTv = NULL; + } +} + +void TvService::onTvEvent(const CTvEv &ev) +{ + int type = ev.getEvType(); + LOGD("TvService::onTvEvent ev type = %d", type); + switch (type) { + case CTvEv::TV_EVENT_COMMOM: + break; + + case CTvEv::TV_EVENT_SCANNER: { + CTvScanner::ScannerEvent *pScannerEv = (CTvScanner::ScannerEvent *) (&ev); + if (mpScannerClient != NULL) { + sp<Client> ScannerClient = mpScannerClient.promote(); + if (ScannerClient != 0) { + Parcel p; + LOGD("scanner evt type:%d freq:%d vid:%d acnt:%d scnt:%d", + pScannerEv->mType, pScannerEv->mFrequency, pScannerEv->mVid, pScannerEv->mAcnt, pScannerEv->mScnt); + p.writeInt32(pScannerEv->mType); + p.writeInt32(pScannerEv->mPercent); + p.writeInt32(pScannerEv->mTotalChannelCount); + p.writeInt32(pScannerEv->mLockedStatus); + p.writeInt32(pScannerEv->mChannelIndex); + p.writeInt32(pScannerEv->mFrequency); + p.writeString16(String16(pScannerEv->mProgramName)); + p.writeInt32(pScannerEv->mprogramType); + p.writeString16(String16(pScannerEv->mParas)); + p.writeInt32(pScannerEv->mStrength); + p.writeInt32(pScannerEv->mSnr); + //ATV + p.writeInt32(pScannerEv->mVideoStd); + p.writeInt32(pScannerEv->mAudioStd); + p.writeInt32(pScannerEv->mIsAutoStd); + //DTV + p.writeInt32(pScannerEv->mMode); + p.writeInt32(pScannerEv->mSymbolRate); + p.writeInt32(pScannerEv->mModulation); + p.writeInt32(pScannerEv->mBandwidth); + p.writeInt32(pScannerEv->mReserved); + p.writeInt32(pScannerEv->mTsId); + p.writeInt32(pScannerEv->mONetId); + p.writeInt32(pScannerEv->mServiceId); + p.writeInt32(pScannerEv->mVid); + p.writeInt32(pScannerEv->mVfmt); + p.writeInt32(pScannerEv->mAcnt); + for (int i = 0; i < pScannerEv->mAcnt; i++) + p.writeInt32(pScannerEv->mAid[i]); + for (int i = 0; i < pScannerEv->mAcnt; i++) + p.writeInt32(pScannerEv->mAfmt[i]); + for (int i = 0; i < pScannerEv->mAcnt; i++) + p.writeString16(String16(pScannerEv->mAlang[i])); + for (int i = 0; i < pScannerEv->mAcnt; i++) + p.writeInt32(pScannerEv->mAtype[i]); + for (int i = 0; i < pScannerEv->mAcnt; i++) + p.writeInt32(pScannerEv->mAExt[i]); + p.writeInt32(pScannerEv->mPcr); + p.writeInt32(pScannerEv->mScnt); + for (int i = 0; i < pScannerEv->mScnt; i++) + p.writeInt32(pScannerEv->mStype[i]); + for (int i = 0; i < pScannerEv->mScnt; i++) + p.writeInt32(pScannerEv->mSid[i]); + for (int i = 0; i < pScannerEv->mScnt; i++) + p.writeInt32(pScannerEv->mSstype[i]); + for (int i = 0; i < pScannerEv->mScnt; i++) + p.writeInt32(pScannerEv->mSid1[i]); + for (int i = 0; i < pScannerEv->mScnt; i++) + p.writeInt32(pScannerEv->mSid2[i]); + for (int i = 0; i < pScannerEv->mScnt; i++) + p.writeString16(String16(pScannerEv->mSlang[i])); + p.writeInt32(pScannerEv->mFree_ca); + p.writeInt32(pScannerEv->mScrambled); + p.writeInt32(pScannerEv->mScanMode); + p.writeInt32(pScannerEv->mSdtVer); + p.writeInt32(pScannerEv->mSortMode); + + p.writeInt32(pScannerEv->mLcnInfo.net_id); + p.writeInt32(pScannerEv->mLcnInfo.ts_id); + p.writeInt32(pScannerEv->mLcnInfo.service_id); + for (int i=0; i<MAX_LCN; i++) { + p.writeInt32(pScannerEv->mLcnInfo.visible[i]); + p.writeInt32(pScannerEv->mLcnInfo.lcn[i]); + p.writeInt32(pScannerEv->mLcnInfo.valid[i]); + } + p.writeInt32(pScannerEv->mMajorChannelNumber); + p.writeInt32(pScannerEv->mMinorChannelNumber); + p.writeInt32(pScannerEv->mSourceId); + p.writeInt32(pScannerEv->mAccessControlled); + p.writeInt32(pScannerEv->mHidden); + p.writeInt32(pScannerEv->mHideGuide); + p.writeString16(String16(pScannerEv->mVct)); + + ScannerClient->notifyCallback(SCAN_EVENT_CALLBACK, p); + } + } + break; + } + + case CTvEv::TV_EVENT_EPG: { + CTvEpg::EpgEvent *pEpgEvent = (CTvEpg::EpgEvent *) (&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pEpgEvent->type); + p.writeInt32(pEpgEvent->time); + p.writeInt32(pEpgEvent->programID); + p.writeInt32(pEpgEvent->channelID); + c->getTvClient()->notifyCallback(EPG_EVENT_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_HDMI_IN_CAP: { + CTvScreenCapture::CapEvent *pCapEvt = (CTvScreenCapture::CapEvent *)(&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pCapEvt->mFrameNum); + p.writeInt32(pCapEvt->mFrameSize); + p.writeInt32(pCapEvt->mFrameWide); + p.writeInt32(pCapEvt->mFrameHeight); + c->getTvClient()->notifyCallback(VFRAME_BMP_EVENT_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_AV_PLAYBACK: { + TvEvent::AVPlaybackEvent *pEv = (TvEvent::AVPlaybackEvent *)(&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c!= 0) { + Parcel p; + p.writeInt32(pEv->mMsgType); + p.writeInt32(pEv->mProgramId); + c->getTvClient()->notifyCallback(DTV_AV_PLAYBACK_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_SIGLE_DETECT: { + TvEvent::SignalInfoEvent *pEv = (TvEvent::SignalInfoEvent *)(&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pEv->mTrans_fmt); + p.writeInt32(pEv->mFmt); + p.writeInt32(pEv->mStatus); + p.writeInt32(pEv->mReserved); + c->getTvClient()->notifyCallback(SIGLE_DETECT_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_SUBTITLE: { + TvEvent::SubtitleEvent *pEv = (TvEvent::SubtitleEvent *)(&ev); + sp<Client> c = mpSubClient.promote(); + if (c != NULL) { + Parcel p; + p.writeInt32(pEv->pic_width); + p.writeInt32(pEv->pic_height); + c->notifyCallback(SUBTITLE_UPDATE_CALLBACK, p); + } + break; + } + + case CTvEv::TV_EVENT_ADC_CALIBRATION: { + TvEvent::ADCCalibrationEvent *pEv = (TvEvent::ADCCalibrationEvent *)(&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pEv->mState); + c->getTvClient()->notifyCallback(ADC_CALIBRATION_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_VGA: {//VGA + TvEvent::VGAEvent *pEv = (TvEvent::VGAEvent *)(&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pEv->mState); + c->getTvClient()->notifyCallback(VGA_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_SOURCE_CONNECT: { + TvEvent::SourceConnectEvent *pEv = (TvEvent::SourceConnectEvent *)(&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pEv->mSourceInput); + p.writeInt32(pEv->connectionState); + c->getTvClient()->notifyCallback(SOURCE_CONNECT_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_HDMIRX_CEC: { + TvEvent::HDMIRxCECEvent *pEv = (TvEvent::HDMIRxCECEvent *)(&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pEv->mDataCount); + for (int j = 0; j < pEv->mDataCount; j++) { + p.writeInt32(pEv->mDataBuf[j]); + } + c->getTvClient()->notifyCallback(HDMIRX_CEC_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_UPGRADE_FBC: { + TvEvent::UpgradeFBCEvent *pEv = (TvEvent::UpgradeFBCEvent *)(&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pEv->mState); + p.writeInt32(pEv->param); + c->getTvClient()->notifyCallback(UPGRADE_FBC_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_SERIAL_COMMUNICATION: { + TvEvent::SerialCommunicationEvent *pEv = (TvEvent::SerialCommunicationEvent *)(&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pEv->mDevId); + p.writeInt32(pEv->mDataCount); + for (int j = 0; j < pEv->mDataCount; j++) { + p.writeInt32(pEv->mDataBuf[j]); + } + c->getTvClient()->notifyCallback(SERIAL_COMMUNICATION_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_2d4G_HEADSET: { + TvEvent::HeadSetOf2d4GEvent *pEv = (TvEvent::HeadSetOf2d4GEvent *)(&ev); + LOGD("SendDtvStats status: =%d para2: =%d", pEv->state, pEv->para); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pEv->state); + p.writeInt32(pEv->para); + c->getTvClient()->notifyCallback(HEADSET_STATUS_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_SCANNING_FRAME_STABLE: { + TvEvent::ScanningFrameStableEvent *pEv = (TvEvent::ScanningFrameStableEvent *)(&ev); + LOGD("Scanning Frame is stable!"); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pEv->CurScanningFreq); + c->getTvClient()->notifyCallback(SCANNING_FRAME_STABLE_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_FRONTEND: { + TvEvent::FrontendEvent *pEv = (TvEvent::FrontendEvent *)(&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pEv->mStatus); + p.writeInt32(pEv->mFrequency); + p.writeInt32(pEv->mParam1); + p.writeInt32(pEv->mParam2); + p.writeInt32(pEv->mParam3); + p.writeInt32(pEv->mParam4); + p.writeInt32(pEv->mParam5); + p.writeInt32(pEv->mParam6); + p.writeInt32(pEv->mParam7); + p.writeInt32(pEv->mParam8); + c->getTvClient()->notifyCallback(FRONTEND_EVENT_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_RECORDER: { + TvEvent::RecorderEvent *pEv = (TvEvent::RecorderEvent *)(&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c!= 0) { + Parcel p; + p.writeString16(String16(pEv->mId)); + p.writeInt32(pEv->mStatus); + p.writeInt32(pEv->mError); + c->getTvClient()->notifyCallback(RECORDER_EVENT_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_RRT: { + CTvRrt::RrtEvent *pRrtEvent = (CTvRrt::RrtEvent *) (&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + p.writeInt32(pRrtEvent->satus); + c->getTvClient()->notifyCallback(RRT_EVENT_CALLBACK, p); + } + } + } + break; + } + + case CTvEv::TV_EVENT_EAS: { + CTvEas::EasEvent *pEasEvent = (CTvEas::EasEvent *) (&ev); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + Parcel p; + int j, k; + p.writeInt32(pEasEvent->eas_section_count); + p.writeInt32(pEasEvent->table_id); + p.writeInt32(pEasEvent->extension); + p.writeInt32(pEasEvent->version); + p.writeInt32(pEasEvent->current_next); + p.writeInt32(pEasEvent->sequence_num); + p.writeInt32(pEasEvent->protocol_version); + p.writeInt32(pEasEvent->eas_event_id); + p.writeInt32(pEasEvent->eas_orig_code[0]); + p.writeInt32(pEasEvent->eas_orig_code[1]); + p.writeInt32(pEasEvent->eas_orig_code[2]); + p.writeInt32(pEasEvent->eas_event_code_len); + for (j=0;j<pEasEvent->eas_event_code_len;j++) { + p.writeInt32(pEasEvent->eas_event_code[j]); + } + p.writeInt32(pEasEvent->alert_message_time_remaining); + p.writeInt32(pEasEvent->event_start_time); + p.writeInt32(pEasEvent->event_duration); + p.writeInt32(pEasEvent->alert_priority); + p.writeInt32(pEasEvent->details_OOB_source_ID); + p.writeInt32(pEasEvent->details_major_channel_number); + p.writeInt32(pEasEvent->details_minor_channel_number); + p.writeInt32(pEasEvent->audio_OOB_source_ID); + p.writeInt32(pEasEvent->location_count); + for (j=0;j<pEasEvent->location_count;j++) { + p.writeInt32(pEasEvent->location[j].i_state_code); + p.writeInt32(pEasEvent->location[j].i_country_subdiv); + p.writeInt32(pEasEvent->location[j].i_country_code); + } + p.writeInt32(pEasEvent->exception_count); + for (j=0;j<pEasEvent->exception_count;j++) { + p.writeInt32(pEasEvent->exception[j].i_in_band_refer); + p.writeInt32(pEasEvent->exception[j].i_exception_major_channel_number); + p.writeInt32(pEasEvent->exception[j].i_exception_minor_channel_number); + p.writeInt32(pEasEvent->exception[j].exception_OOB_source_ID); + } + p.writeInt32(pEasEvent->multi_text_count); + for (j=0;j<pEasEvent->multi_text_count;j++) { + p.writeInt32(pEasEvent->multi_text[j].lang[0]); + p.writeInt32(pEasEvent->multi_text[j].lang[1]); + p.writeInt32(pEasEvent->multi_text[j].lang[2]); + p.writeInt32(pEasEvent->multi_text[j].i_type); + p.writeInt32(pEasEvent->multi_text[j].i_compression_type); + p.writeInt32(pEasEvent->multi_text[j].i_mode); + p.writeInt32(pEasEvent->multi_text[j].i_number_bytes); + for (k=0;k<pEasEvent->multi_text[j].i_number_bytes;k++) { + p.writeInt32(pEasEvent->multi_text[j].compressed_str[k]); + } + } + p.writeInt32(pEasEvent->descriptor_text_count); + for (j=0;j<pEasEvent->descriptor_text_count;j++) { + p.writeInt32(pEasEvent->descriptor[j].i_tag); + p.writeInt32(pEasEvent->descriptor[j].i_length); + for (k=0;k<pEasEvent->descriptor[j].i_length;k++) { + p.writeInt32(pEasEvent->descriptor[j].p_data[k]); + } + } + c->getTvClient()->notifyCallback(EAS_EVENT_CALLBACK, p); + } + } + } + break; + } + + default: + break; + } +} + +sp<ITv> TvService::connect(const sp<ITvClient> &tvClient) +{ + int callingPid = getCallingPid(); + LOGD("TvService::connect (pid %d, client %p)", callingPid, IInterface::asBinder(tvClient).get()); + + AutoMutex _l(mServiceLock); + sp<Client> newclient; + bool haveclient = false; + + int clientSize = mClients.size(); + for (int i = 0; i < clientSize; i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> currentClient = client.promote(); + if (currentClient != 0) { + sp<ITvClient> currentTvClient(currentClient->getTvClient()); + if (IInterface::asBinder(tvClient) == IInterface::asBinder(currentTvClient)) { + LOGD("TvService::connect (pid %d, same client %p) is reconnecting...", callingPid, IInterface::asBinder(tvClient).get()); + newclient = currentClient; + haveclient = true; + } + } else { + LOGE("TvService::connect client (pid %d) not exist", callingPid); + client.clear(); + mClients.removeAt(i); + clientSize--; + } + } + } + + if ( haveclient ) { + return newclient; + } + + newclient = new Client(this, tvClient, callingPid, mpTv); + mClients.add(newclient); + return newclient; +} + +void TvService::removeClient(const sp<ITvClient> &tvClient) +{ + int callingPid = getCallingPid(); + + AutoMutex _l(mServiceLock); + int clientSize = mClients.size(); + for (int i = 0; i < clientSize; i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> currentClient = client.promote(); + if (currentClient != 0) { + sp<ITvClient> currentTvClient(currentClient->getTvClient()); + if (IInterface::asBinder(tvClient) == IInterface::asBinder(currentTvClient)) { + LOGD("find client , and remove it pid = %d, client = %p i=%d", callingPid, IInterface::asBinder(tvClient).get(), i); + client.clear(); + mClients.removeAt(i); + break; + } + } else { + LOGW("removeclient currentClient is NULL (pid %d)", callingPid); + client.clear(); + mClients.removeAt(i); + clientSize--; + } + } + } + + LOGD("removeClient (pid %d) done", callingPid); +} + +void TvService::incUsers() +{ + android_atomic_inc(&mUsers); +} + +void TvService::decUsers() +{ + android_atomic_dec(&mUsers); +} + +TvService::Client::Client(const sp<TvService> &tvService, const sp<ITvClient> &tvClient, pid_t clientPid, CTv *pTv) +{ + mTvService = tvService; + mTvClient = tvClient; + mClientPid = clientPid; + tvService->incUsers(); + mpTv = pTv; + mIsStartTv = false; +} + +TvService::Client::~Client() +{ + if (mIsStartTv) { + mpTv->StopTvLock(); + mIsStartTv = false; + } + + int callingPid = getCallingPid(); + // tear down client + LOGD("Client::~Client(pid %d, client %p)", callingPid, IInterface::asBinder(getTvClient()).get()); + // make sure we tear down the hardware + //mClientPid = callingPid; + //disconnect(); + mTvService->decUsers(); +} + +status_t TvService::Client::checkPid() +{ + int callingPid = getCallingPid(); + if (mClientPid == callingPid) + return NO_ERROR; + LOGD("Attempt to use locked tv (client %p) from different process " + " (old pid %d, new pid %d)", IInterface::asBinder(getTvClient()).get(), mClientPid, callingPid); + return -EBUSY; +} + +status_t TvService::Client::lock() +{ + int callingPid = getCallingPid(); + LOGD("lock from pid %d (mClientPid %d)", callingPid, mClientPid); + AutoMutex _l(mLock); + // lock tv to this client if the the tv is unlocked + if (mClientPid == 0) { + mClientPid = callingPid; + return NO_ERROR; + } + // returns NO_ERROR if the client already owns the tv, -EBUSY otherwise + return checkPid(); +} + +status_t TvService::Client::unlock() +{ + int callingPid = getCallingPid(); + LOGD("unlock from pid %d (mClientPid %d)", callingPid, mClientPid); + AutoMutex _l(mLock); + // allow anyone to use tv + status_t result = checkPid(); + if (result == NO_ERROR) { + mClientPid = 0; + // we need to remove the reference so that when app goes + // away, the reference count goes to 0. + mTvClient.clear(); + } + return result; +} + +status_t TvService::Client::connect(const sp<ITvClient> &client) +{ + int callingPid = getCallingPid(); + LOGD("Client::connect E (pid %d, client %p)", callingPid, IInterface::asBinder(client).get()); + + { + AutoMutex _l(mLock); + if (mClientPid != 0 && checkPid() != NO_ERROR) { + LOGW("Tried to connect to locked tv (old pid %d, new pid %d)", mClientPid, callingPid); + return -EBUSY; + } + + // did the client actually change? + if ((mTvClient != NULL) && (IInterface::asBinder(client) == IInterface::asBinder(mTvClient))) { + LOGD("Connect to the same client"); + return NO_ERROR; + } + + mTvClient = client; + LOGD("Connect to the new client (pid %d, client %p)", callingPid, IInterface::asBinder(client).get()); + } + + mClientPid = callingPid; + return NO_ERROR; +} + +void TvService::Client::disconnect() +{ + int callingPid = getCallingPid(); + + LOGD("Client::disconnect() E (pid %d client %p)", callingPid, IInterface::asBinder(getTvClient()).get()); + + AutoMutex _l(mLock); + if (mClientPid <= 0) { + LOGE("tv is unlocked (mClientPid = %d), don't tear down hardware", mClientPid); + return; + } + if (checkPid() != NO_ERROR) { + LOGE("Different client - don't disconnect"); + return; + } + + mTvService->removeClient(mTvClient); + mTvService->decUsers(); + + LOGD("Client::disconnect() X (pid %d)", callingPid); +} + +status_t TvService::Client::createVideoFrame(const sp<IMemory> &shareMem __unused, + int iSourceMode __unused, int iCapVideoLayerOnly __unused) +{ +#if 0 + LOGD(" mem=%d size=%d", shareMem->pointer() == NULL, shareMem->size()); + LOGD("iSourceMode :%d iCapVideoLayerOnly = %d \n", iSourceMode, iCapVideoLayerOnly); + int Len = 0; + AutoMutex _l(mLock); + mTvService->mCapVidFrame.InitVCap(shareMem); + + if ((1 == iSourceMode) && (1 == iCapVideoLayerOnly)) { + mTvService->mCapVidFrame.CapMediaPlayerVideoLayerOnly(1920, 1080); +#if 0 + mTvService->mCapVidFrame.SetVideoParameter(1920, 1080, 50); + mTvService->mCapVidFrame.VideoStart(); + mTvService->mCapVidFrame.GetVideoData(&Len); + mTvService->mCapVidFrame.VideoStop(); +#endif + } else if (2 == iSourceMode && 0 == iCapVideoLayerOnly) { + mTvService->mCapVidFrame.CapOsdAndVideoLayer(1920, 1080); + } else if (2 == iSourceMode && 1 == iCapVideoLayerOnly) { + mTvService->mCapVidFrame.CapMediaPlayerVideoLayerOnly(1920, 1080); + } else { + LOGD("=============== NOT SUPPORT=======================\n"); + } + mTvService->mCapVidFrame.DeinitVideoCap(); +#endif + LOGE("do not support this function"); + return 0; +} + +status_t TvService::Client::createSubtitle(const sp<IMemory> &shareMem) +{ + LOGD("createSubtitle pid = %d, mem=%d size=%d", getCallingPid(), shareMem->pointer() == NULL, shareMem->size()); + mpTv->mSubtitle.setBuffer((char *)shareMem->pointer()); + mTvService->mpSubClient = this; + //pSub = new CTvSubtitle(share_mem, this); + //pSub->run(); + return 0; +} + +status_t TvService::Client::processCmd(const Parcel &p, Parcel *r) +{ + unsigned char dataBuf[512] = {0}; + int *ptrData = NULL; + + int cmd = p.readInt32(); + + LOGD("enter client=%d cmd=%d", getCallingPid(), cmd); + switch (cmd) { + // Tv function + case OPEN_TV: { + break; + } + case CLOSE_TV: { + int ret = mpTv->CloseTv(); + r->writeInt32(ret); + break; + } + case START_TV: { + int mode = p.readInt32(); + int ret = mpTv->StartTvLock(); + mIsStartTv = true; + r->writeInt32(ret); + break; + } + case STOP_TV: { + int ret = mpTv->StopTvLock(); + r->writeInt32(ret); + mIsStartTv = false; + break; + } + case GET_TV_STATUS: { + int ret = (int)mpTv->GetTvStatus(); + r->writeInt32(ret); + break; + } + case GET_LAST_SOURCE_INPUT: { + int ret = (int)mpTv->GetLastSourceInput(); + r->writeInt32(ret); + break; + } + case GET_CURRENT_SOURCE_INPUT: { + int ret = (int)mpTv->GetCurrentSourceInputLock(); + r->writeInt32(ret); + break; + } + case GET_CURRENT_SOURCE_INPUT_VIRTUAL: { + int ret = (int)mpTv->GetCurrentSourceInputVirtualLock(); + r->writeInt32(ret); + break; + } + case GET_CURRENT_SIGNAL_INFO: { + tvin_info_t siginfo = mpTv->GetCurrentSignalInfo(); + int frame_rate = mpTv->getHDMIFrameRate(); + r->writeInt32(siginfo.trans_fmt); + r->writeInt32(siginfo.fmt); + r->writeInt32(siginfo.status); + r->writeInt32(frame_rate); + break; + } + case SET_SOURCE_INPUT: { + int sourceinput = p.readInt32(); + LOGD(" SetSourceInput sourceId= %x", sourceinput); + int ret = mpTv->SetSourceSwitchInput((tv_source_input_t)sourceinput); + r->writeInt32(ret); + break; + } + case SET_SOURCE_INPUT_EXT: { + int sourceinput = p.readInt32(); + int vsourceinput = p.readInt32(); + LOGD(" SetSourceInputExt vsourceId= %d sourceId=%d", vsourceinput, sourceinput); + int ret = mpTv->SetSourceSwitchInput((tv_source_input_t)vsourceinput, (tv_source_input_t)sourceinput); + r->writeInt32(ret); + break; + } + case DO_SUSPEND: { + int type = p.readInt32(); + int ret = mpTv->DoSuspend(type); + r->writeInt32(ret); + break; + } + case DO_RESUME: { + int type = p.readInt32(); + int ret = mpTv->DoResume(type); + r->writeInt32(ret); + break; + } + case IS_DVI_SIGNAL: { + int ret = mpTv->IsDVISignal(); + r->writeInt32(ret); + break; + } + case IS_VGA_TIMEING_IN_HDMI: { + int ret = mpTv->isVgaFmtInHdmi(); + r->writeInt32(ret); + break; + } + case SET_PREVIEW_WINDOW_MODE: { + bool mode = (p.readInt32() == 1); + int ret = mpTv->setPreviewWindowMode(mode); + r->writeInt32(ret); + break; + } + case SET_PREVIEW_WINDOW: { + tvin_window_pos_t win_pos; + win_pos.x1 = p.readInt32(); + win_pos.y1 = p.readInt32(); + win_pos.x2 = p.readInt32(); + win_pos.y2 = p.readInt32(); + int ret = (int)mpTv->SetPreviewWindow(win_pos); + r->writeInt32(ret); + break; + } + + case GET_SOURCE_CONNECT_STATUS: { + int source_input = p.readInt32(); + int ret = mpTv->GetSourceConnectStatus((tv_source_input_t)source_input); + r->writeInt32(ret); + break; + } + + case GET_SOURCE_INPUT_LIST: { + const char *value = config_get_str(CFG_SECTION_TV, CGF_DEFAULT_INPUT_IDS, "null"); + r->writeString16(String16(value)); + break; + } + //Tv function END + + // HDMI + case SET_HDMI_EDID_VER: { + int hdmi_port_id = p.readInt32(); + int edid_ver = p.readInt32(); + int tmpRet = mpTv->SetHdmiEdidVersion((tv_hdmi_port_id_t)hdmi_port_id, (tv_hdmi_edid_version_t)edid_ver); + r->writeInt32(tmpRet); + break; + } + case SET_HDCP_KEY_ENABLE: { + int enable = p.readInt32(); + int tmpRet = mpTv->SetHdmiHDCPSwitcher((tv_hdmi_hdcpkey_enable_t)enable); + r->writeInt32(tmpRet); + break; + } + case SET_HDMI_COLOR_RANGE_MODE: { + int range_mode = p.readInt32(); + int tmpRet = mpTv->SetHdmiColorRangeMode((tv_hdmi_color_range_t)range_mode); + r->writeInt32(tmpRet); + break; + } + case GET_HDMI_COLOR_RANGE_MODE: { + int tmpRet = mpTv->GetHdmiColorRangeMode(); + r->writeInt32(tmpRet); + break; + } + // HDMI END + + // PQ + case SET_BRIGHTNESS: { + int brightness = p.readInt32(); + int tv_source_input = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->Tv_SetBrightness(brightness, (tv_source_input_t)tv_source_input, is_save); + r->writeInt32(ret); + break; + } + case GET_BRIGHTNESS: { + int tv_source_input = p.readInt32(); + LOGD("GET_BRIGHTNESS source type:%d", tv_source_input); + int ret = mpTv->Tv_GetBrightness((tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SAVE_BRIGHTNESS: { + int brightness = p.readInt32(); + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_SaveBrightness(brightness, (tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SET_CONTRAST: { + int contrast = p.readInt32(); + int tv_source_input = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->Tv_SetContrast(contrast, (tv_source_input_t)tv_source_input, is_save); + r->writeInt32(ret); + break; + } + case GET_CONTRAST: { + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_GetContrast((tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SAVE_CONTRAST: { + int contrast = p.readInt32(); + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_SaveContrast(contrast, (tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SET_SATUATION: { + int satuation = p.readInt32(); + int tv_source_input = p.readInt32(); + int fmt = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->Tv_SetSaturation(satuation, (tv_source_input_t)tv_source_input, (tvin_sig_fmt_t)fmt, is_save); + r->writeInt32(ret); + break; + } + case GET_SATUATION: { + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_GetSaturation((tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SAVE_SATUATION: { + int satuation = p.readInt32(); + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_SaveSaturation(satuation, (tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SET_HUE: { + int hue = p.readInt32(); + int tv_source_input = p.readInt32(); + int fmt = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->Tv_SetHue(hue, (tv_source_input_t)tv_source_input, (tvin_sig_fmt_t)fmt, is_save); + r->writeInt32(ret); + break; + } + case GET_HUE: { + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_GetHue((tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SAVE_HUE: { + int hue = p.readInt32(); + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_SaveHue(hue, (tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SET_PQMODE: { + int mode = p.readInt32(); + int tv_source_input = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->Tv_SetPQMode((vpp_picture_mode_t)mode, (tv_source_input_t)tv_source_input, is_save); + r->writeInt32(ret); + break; + } + case GET_PQMODE: { + int tv_source_input = p.readInt32(); + int ret = (int)mpTv->Tv_GetPQMode((tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SAVE_PQMODE: { + int mode = p.readInt32(); + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_SavePQMode((vpp_picture_mode_t)mode, (tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SET_SHARPNESS: { + int value = p.readInt32(); + int tv_source_input = p.readInt32(); + int en = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->Tv_SetSharpness(value, (tv_source_input_t)tv_source_input, en, is_save); + r->writeInt32(ret); + break; + } + case GET_SHARPNESS: { + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_GetSharpness((tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SAVE_SHARPNESS: { + int value = p.readInt32(); + int tv_source_input = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->Tv_SaveSharpness(value, (tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SET_BACKLIGHT: { + int value = p.readInt32(); + int tv_source_input = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->Tv_SetBacklight(value, (tv_source_input_t)tv_source_input, is_save); + r->writeInt32(ret); + break; + } + case GET_BACKLIGHT: { + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_GetBacklight((tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SAVE_BACKLIGHT: { + int value = p.readInt32(); + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_SaveBacklight ( value, (tv_source_input_t)tv_source_input ); + r->writeInt32(ret); + break; + } + case SET_BACKLIGHT_SWITCH: { + int value = p.readInt32(); + int ret = mpTv->Tv_SetBacklight_Switch(value); + r->writeInt32(ret); + break; + } + case GET_BACKLIGHT_SWITCH: { + int ret = mpTv->Tv_GetBacklight_Switch(); + r->writeInt32(ret); + break; + } + case SET_COLOR_TEMPERATURE: { + int mode = p.readInt32(); + int tv_source_input = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->Tv_SetColorTemperature((vpp_color_temperature_mode_t)mode, (tv_source_input_t)tv_source_input, is_save); + r->writeInt32(ret); + break; + } + case GET_COLOR_TEMPERATURE: { + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_GetColorTemperature((tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SAVE_COLOR_TEMPERATURE: { + int mode = p.readInt32(); + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_SaveColorTemperature ( (vpp_color_temperature_mode_t)mode, (tv_source_input_t)tv_source_input ); + r->writeInt32(ret); + break; + } + case SET_DISPLAY_MODE: { + int mode = p.readInt32(); + int tv_source_input = p.readInt32(); + int fmt = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->Tv_SetDisplayMode((vpp_display_mode_t)mode, (tv_source_input_t)tv_source_input, (tvin_sig_fmt_t)fmt, is_save); + r->writeInt32(ret); + break; + } + case GET_DISPLAY_MODE: { + int tv_source_input = p.readInt32(); + int ret = (int)mpTv->Tv_GetDisplayMode((tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SAVE_DISPLAY_MODE: { + int mode = p.readInt32(); + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_SaveDisplayMode((vpp_display_mode_t)mode, (tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SET_EYE_PROTETION_MODE: { + int enable = p.readInt32(); + int ret = mpTv->setEyeProtectionMode(enable); + r->writeInt32(ret); + break; + } + case GET_EYE_PROTETION_MODE: { + bool ret = mpTv->getEyeProtectionMode(); + r->writeInt32(ret); + break; + } + case SET_GAMMA: { + int gamma_curve = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->setGamma((vpp_gamma_curve_t)gamma_curve, is_save); + r->writeInt32(ret); + break; + } + case SET_NOISE_REDUCTION_MODE: { + int mode = p.readInt32(); + int tv_source_input = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->Tv_SetNoiseReductionMode((vpp_noise_reduction_mode_t)mode, (tv_source_input_t)tv_source_input, is_save); + r->writeInt32(ret); + break; + } + case GET_NOISE_REDUCTION_MODE: { + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_GetNoiseReductionMode((tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SAVE_NOISE_REDUCTION_MODE: { + int mode = p.readInt32(); + int tv_source_input = p.readInt32(); + int ret = mpTv->Tv_SaveNoiseReductionMode((vpp_noise_reduction_mode_t)mode, (tv_source_input_t)tv_source_input); + r->writeInt32(ret); + break; + } + case SET_VIDEO_AXIS: { + int x = p.readInt32(); + int y = p.readInt32(); + int width = p.readInt32(); + int height = p.readInt32(); + int ret = mpTv->SetVideoAxis(x, y, width, height); + r->writeInt32(ret); + break; + } + // PQ END + + // FACTORY + case FACTORY_SETPQMODE_BRIGHTNESS: { + int tv_source_input = p.readInt32(); + int pq_mode = p.readInt32(); + int brightness = p.readInt32(); + int ret = mpTv->mFactoryMode.setPQModeBrightness(tv_source_input, pq_mode, brightness); + r->writeInt32(ret); + break; + } + case FACTORY_GETPQMODE_BRIGHTNESS: { + int tv_source_input = p.readInt32(); + int pq_mode = p.readInt32(); + int ret = mpTv->mFactoryMode.getPQModeBrightness(tv_source_input, pq_mode); + r->writeInt32(ret); + break; + } + case FACTORY_SETPQMODE_CONTRAST: { + int tv_source_input = p.readInt32(); + int pq_mode = p.readInt32(); + int contrast = p.readInt32(); + int ret = mpTv->mFactoryMode.setPQModeContrast(tv_source_input, pq_mode, contrast); + r->writeInt32(ret); + break; + } + case FACTORY_GETPQMODE_CONTRAST: { + int tv_source_input = p.readInt32(); + int pq_mode = p.readInt32(); + int ret = mpTv->mFactoryMode.getPQModeContrast(tv_source_input, pq_mode); + r->writeInt32(ret); + break; + } + case FACTORY_SETPQMODE_SATURATION: { + int tv_source_input = p.readInt32(); + int pq_mode = p.readInt32(); + int saturation = p.readInt32(); + int ret = mpTv->mFactoryMode.setPQModeSaturation(tv_source_input, pq_mode, saturation); + r->writeInt32(ret); + break; + } + case FACTORY_GETPQMODE_SATURATION: { + int tv_source_input = p.readInt32(); + int pq_mode = p.readInt32(); + int ret = mpTv->mFactoryMode.getPQModeSaturation(tv_source_input, pq_mode); + r->writeInt32(ret); + break; + } + case FACTORY_SETPQMODE_HUE: { + int tv_source_input = p.readInt32(); + int pq_mode = p.readInt32(); + int hue = p.readInt32(); + int ret = mpTv->mFactoryMode.setPQModeHue(tv_source_input, pq_mode, hue); + r->writeInt32(ret); + break; + } + case FACTORY_GETPQMODE_HUE: { + int tv_source_input = p.readInt32(); + int pq_mode = p.readInt32(); + int ret = mpTv->mFactoryMode.getPQModeHue(tv_source_input, pq_mode); + r->writeInt32(ret); + break; + } + case FACTORY_SETPQMODE_SHARPNESS: { + int tv_source_input = p.readInt32(); + int pq_mode = p.readInt32(); + int sharpness = p.readInt32(); + int ret = mpTv->mFactoryMode.setPQModeSharpness(tv_source_input, pq_mode, sharpness); + r->writeInt32(ret); + break; + } + case FACTORY_GETPQMODE_SHARPNESS: { + int tv_source_input = p.readInt32(); + int pq_mode = p.readInt32(); + int ret = mpTv->mFactoryMode.getPQModeSharpness(tv_source_input, pq_mode); + r->writeInt32(ret); + break; + } + case FACTORY_SETTESTPATTERN: { + int pattern = p.readInt32(); + int ret = mpTv->mFactoryMode.setTestPattern(pattern); + r->writeInt32(ret); + break; + } + case FACTORY_GETTESTPATTERN: { + int ret = mpTv->mFactoryMode.getTestPattern(); + r->writeInt32(ret); + break; + } + case FACTORY_SETPATTERN_YUV: { + int blend = p.readInt32(); + int y = p.readInt32(); + int u = p.readInt32(); + int v = p.readInt32(); + int ret = mpTv->mFactoryMode.setScreenColor(blend, y, u, v); + r->writeInt32(ret); + break; + } + case FACTORY_RESETPQMODE: { + int ret = mpTv->mFactoryMode.resetPQMode(); + r->writeInt32(ret); + break; + } + case FACTORY_RESETCOLORTEMP: { + int ret = mpTv->mFactoryMode.resetColorTemp(); + r->writeInt32(ret); + break; + } + case FACTORY_RESETPAMAMSDEFAULT: { + int ret = mpTv->mFactoryMode.setParamsDefault(); + r->writeInt32(ret); + break; + } + case FACTORY_SETDDRSSC: { + int setp = p.readInt32(); + int ret = mpTv->mFactoryMode.setDDRSSC(setp); + r->writeInt32(ret); + break; + } + case FACTORY_GETDDRSSC: { + int ret = mpTv->mFactoryMode.getDDRSSC(); + r->writeInt32(ret); + break; + } + case FACTORY_SETLVDSSSC: { + int setp = p.readInt32(); + int ret = mpTv->mFactoryMode.setLVDSSSC(setp); + r->writeInt32(ret); + break; + } + case FACTORY_GETLVDSSSC: { + int ret = mpTv->mFactoryMode.getLVDSSSC(); + r->writeInt32(ret); + break; + } + case FACTORY_SETNOLINEPARAMS: { + noline_params_t params; + int noline_params_type = p.readInt32(); + int tv_source_input = p.readInt32(); + params.osd0 = p.readInt32(); + params.osd25 = p.readInt32(); + params.osd50 = p.readInt32(); + params.osd75 = p.readInt32(); + params.osd100 = p.readInt32(); + int ret = mpTv->mFactoryMode.setNolineParams(noline_params_type, tv_source_input, params); + r->writeInt32(ret); + break; + } + case FACTORY_GETNOLINEPARAMS: { + int noline_params_type = p.readInt32(); + int tv_source_input = p.readInt32(); + noline_params_t params = mpTv->mFactoryMode.getNolineParams(noline_params_type, tv_source_input); + r->writeInt32(params.osd0); + r->writeInt32(params.osd25); + r->writeInt32(params.osd50); + r->writeInt32(params.osd75); + r->writeInt32(params.osd100); + break; + } + case FACTORY_SETOVERSCAN: { + tvin_cutwin_t cutwin_t; + int tv_source_input = p.readInt32(); + int fmt = p.readInt32(); + int trans_fmt = p.readInt32(); + cutwin_t.hs = p.readInt32(); + cutwin_t.he = p.readInt32(); + cutwin_t.vs = p.readInt32(); + cutwin_t.ve = p.readInt32(); + int ret = mpTv->mFactoryMode.setOverscan(tv_source_input, fmt, trans_fmt, cutwin_t); + r->writeInt32(ret); + break; + } + case FACTORY_GETOVERSCAN: { + int tv_source_input = p.readInt32(); + int fmt = p.readInt32(); + int trans_fmt = p.readInt32(); + tvin_cutwin_t cutwin_t = mpTv->mFactoryMode.getOverscan(tv_source_input, fmt, trans_fmt); + r->writeInt32(cutwin_t.hs); + r->writeInt32(cutwin_t.he); + r->writeInt32(cutwin_t.vs); + r->writeInt32(cutwin_t.ve); + break; + } + case FACTORY_SET_OUT_DEFAULT: { + int ret = mpTv->Tv_SSMFacRestoreDefaultSetting(); + r->writeInt32(ret); + break; + } + case FACTORY_CLEAN_ALL_TABLE_FOR_PROGRAM: { + int ret = mpTv->ClearAnalogFrontEnd(); + mpTv->clearDbAllProgramInfoTable(); + r->writeInt32(ret); + break; + } + case FACTORY_SET_GAMMA_PATTERN: { + tcon_gamma_table_t gamma_r, gamma_g, gamma_b; + memset(gamma_r.data, (unsigned short)(p.readInt32()<<2), 256); + memset(gamma_g.data, (unsigned short)(p.readInt32()<<2), 256); + memset(gamma_b.data, (unsigned short)(p.readInt32()<<2), 256); + int ret = mpTv->mFactoryMode.setGamma(gamma_r, gamma_g, gamma_b); + r->writeInt32(ret); + break; + } + case FACTORY_SET_RGB_PATTERN: { + int pr = p.readInt32(); + int pg = p.readInt32(); + int pb = p.readInt32(); + int ret = mpTv->mFactoryMode.setRGBPattern(pr, pg, pb); + r->writeInt32(ret); + break; + } + case FACTORY_GET_RGB_PATTERN: { + int ret = mpTv->mFactoryMode.getRGBPattern(); + r->writeInt32(ret); + break; + } + // FACTORY END + + // AUDIO & AUDIO MUTE + case SET_AUDIO_MUTE_FOR_TV: { + int status = p.readInt32(); + if (status != mpTv->GetAudioMuteForTv()) { + int ret = mpTv->SetAudioMuteForTv(status); + r->writeInt32(ret); + } + break; + } + case SET_AUDIO_MUTEKEY_STATUS: { + int status = p.readInt32(); + int ret = mpTv->SetAudioMuteForSystem(status); + r->writeInt32(ret); + break; + } + case GET_AUDIO_MUTEKEY_STATUS: { + int ret = mpTv->GetAudioMuteForSystem(); + r->writeInt32(ret); + break; + } + case SET_AUDIO_AVOUT_MUTE_STATUS: { + int status = p.readInt32(); + int ret = mpTv->SetAudioAVOutMute(status); + r->writeInt32(ret); + break; + } + case GET_AUDIO_AVOUT_MUTE_STATUS: { + int ret = mpTv->GetAudioAVOutMute(); + r->writeInt32(ret); + break; + } + case SET_AUDIO_SPDIF_MUTE_STATUS: { + int status = p.readInt32(); + int ret = mpTv->SetAudioSPDIFMute(status); + r->writeInt32(ret); + break; + } + case GET_AUDIO_SPDIF_MUTE_STATUS: { + int ret = mpTv->GetAudioSPDIFMute(); + r->writeInt32(ret); + break; + } + // AUDIO MASTER VOLUME + case SET_AUDIO_MASTER_VOLUME: { + int vol = p.readInt32(); + int ret = mpTv->SetAudioMasterVolume(vol); + r->writeInt32(ret); + break; + } + case GET_AUDIO_MASTER_VOLUME: { + int ret = mpTv->GetAudioMasterVolume(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_MASTER_VOLUME: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioMasterVolume(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_MASTER_VOLUME: { + int ret = mpTv->GetCurAudioMasterVolume(); + r->writeInt32(ret); + break; + } + //AUDIO BALANCE + case SET_AUDIO_BALANCE: { + int vol = p.readInt32(); + int ret = mpTv->SetAudioBalance(vol); + r->writeInt32(ret); + break; + } + case GET_AUDIO_BALANCE: { + int ret = mpTv->GetAudioBalance(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_BALANCE: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioBalance(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_BALANCE: { + int ret = mpTv->GetCurAudioBalance(); + r->writeInt32(ret); + break; + } + //AUDIO SUPPERBASS VOLUME + case SET_AUDIO_SUPPER_BASS_VOLUME: { + int vol = p.readInt32(); + int ret = mpTv->SetAudioSupperBassVolume(vol); + r->writeInt32(ret); + break; + } + case GET_AUDIO_SUPPER_BASS_VOLUME: { + int ret = mpTv->GetAudioSupperBassVolume(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_SUPPER_BASS_VOLUME: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioSupperBassVolume(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_SUPPER_BASS_VOLUME: { + int ret = mpTv->GetCurAudioSupperBassVolume(); + r->writeInt32(ret); + break; + } + //AUDIO SUPPERBASS SWITCH + case SET_AUDIO_SUPPER_BASS_SWITCH: { + int vol = p.readInt32(); + int ret = mpTv->SetAudioSupperBassSwitch(vol); + r->writeInt32(ret); + break; + } + case GET_AUDIO_SUPPER_BASS_SWITCH: { + int ret = mpTv->GetAudioSupperBassSwitch(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_SUPPER_BASS_SWITCH: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioSupperBassSwitch(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_SUPPER_BASS_SWITCH: { + int ret = mpTv->GetCurAudioSupperBassSwitch(); + r->writeInt32(ret); + break; + } + //AUDIO SRS SURROUND SWITCH + case SET_AUDIO_SRS_SURROUND: { + int vol = p.readInt32(); + int ret = mpTv->SetAudioSRSSurround(vol); + mpTv->RefreshAudioMasterVolume(SOURCE_MAX); + r->writeInt32(ret); + break; + } + case GET_AUDIO_SRS_SURROUND: { + int ret = mpTv->GetAudioSRSSurround(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_SRS_SURROUND: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioSrsSurround(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_SRS_SURROUND: { + int ret = mpTv->GetCurAudioSRSSurround(); + r->writeInt32(ret); + break; + } + //AUDIO SRS DIALOG CLARITY + case SET_AUDIO_SRS_DIALOG_CLARITY: { + int vol = p.readInt32(); + int ret = mpTv->SetAudioSrsDialogClarity(vol); + mpTv->RefreshAudioMasterVolume(SOURCE_MAX); + r->writeInt32(ret); + break; + } + case GET_AUDIO_SRS_DIALOG_CLARITY: { + int ret = mpTv->GetAudioSrsDialogClarity(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_SRS_DIALOG_CLARITY: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioSrsDialogClarity(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_SRS_DIALOG_CLARITY: { + int ret = mpTv->GetCurAudioSrsDialogClarity(); + r->writeInt32(ret); + break; + } + //AUDIO SRS TRUBASS + case SET_AUDIO_SRS_TRU_BASS: { + int vol = p.readInt32(); + int ret = mpTv->SetAudioSrsTruBass(vol); + mpTv->RefreshAudioMasterVolume(SOURCE_MAX); + r->writeInt32(ret); + break; + } + case GET_AUDIO_SRS_TRU_BASS: { + int ret = mpTv->GetAudioSrsTruBass(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_SRS_TRU_BASS: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioSrsTruBass(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_SRS_TRU_BASS: { + int ret = mpTv->GetCurAudioSrsTruBass(); + r->writeInt32(ret); + break; + } + //AUDIO BASS + case SET_AUDIO_BASS_VOLUME: { + int vol = p.readInt32(); + int ret = mpTv->SetAudioBassVolume(vol); + r->writeInt32(ret); + break; + } + case GET_AUDIO_BASS_VOLUME: { + int ret = mpTv->GetAudioBassVolume(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_BASS_VOLUME: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioBassVolume(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_BASS_VOLUME: { + int ret = mpTv->GetCurAudioBassVolume(); + r->writeInt32(ret); + break; + } + //AUDIO TREBLE + case SET_AUDIO_TREBLE_VOLUME: { + int vol = p.readInt32(); + int ret = mpTv->SetAudioTrebleVolume(vol); + r->writeInt32(ret); + break; + } + case GET_AUDIO_TREBLE_VOLUME: { + int ret = mpTv->GetAudioTrebleVolume(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_TREBLE_VOLUME: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioTrebleVolume(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_TREBLE_VOLUME: { + int ret = mpTv->GetCurAudioTrebleVolume(); + r->writeInt32(ret); + break; + } + //AUDIO SOUND MODE + case SET_AUDIO_SOUND_MODE: { + int vol = p.readInt32(); + int ret = mpTv->SetAudioSoundMode(vol); + r->writeInt32(ret); + break; + } + case GET_AUDIO_SOUND_MODE: { + int ret = mpTv->GetAudioSoundMode(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_SOUND_MODE: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioSoundMode(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_SOUND_MODE: { + int ret = mpTv->GetCurAudioSoundMode(); + r->writeInt32(ret); + break; + } + //AUDIO WALL EFFECT + case SET_AUDIO_WALL_EFFECT: { + int vol = p.readInt32(); + int ret = mpTv->SetAudioWallEffect(vol); + r->writeInt32(ret); + break; + } + case GET_AUDIO_WALL_EFFECT: { + int ret = mpTv->GetAudioWallEffect(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_WALL_EFFECT: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioWallEffect(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_WALL_EFFECT: { + int ret = mpTv->GetCurAudioWallEffect(); + r->writeInt32(ret); + break; + } + //AUDIO EQ MODE + case SET_AUDIO_EQ_MODE: { + int vol = p.readInt32(); + int ret = mpTv->SetAudioEQMode(vol); + r->writeInt32(ret); + break; + } + case GET_AUDIO_EQ_MODE: { + int ret = mpTv->GetAudioEQMode(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_EQ_MODE: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioEQMode(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_EQ_MODE: { + int ret = mpTv->GetCurAudioEQMode(); + r->writeInt32(ret); + break; + } + //AUDIO EQ GAIN + case GET_AUDIO_EQ_RANGE: { + int buf[2]; + int ret = mpTv->GetAudioEQRange(buf); + r->writeInt32(2); + r->writeInt32(buf[0]); + r->writeInt32(buf[1]); + r->writeInt32(ret); + break; + } + case GET_AUDIO_EQ_BAND_COUNT: { + int ret = mpTv->GetAudioEQBandCount(); + r->writeInt32(ret); + break; + } + case SET_AUDIO_EQ_GAIN: { + int buf[128] = {0}; + int bufSize = p.readInt32(); + for (int i = 0; i < bufSize; i++) { + buf[i] = p.readInt32(); + } + int ret = mpTv->SetAudioEQGain(buf); + r->writeInt32(ret); + break; + } + case GET_AUDIO_EQ_GAIN: { + int buf[128] = {0}; + int ret = mpTv->GetAudioEQGain(buf); + int bufSize = mpTv->GetAudioEQBandCount(); + r->writeInt32(bufSize); + for (int i = 0; i < bufSize; i++) { + r->writeInt32(buf[i]); + } + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_EQ_GAIN: { + int buf[128] = {0}; + int bufSize = p.readInt32(); + for (int i = 0; i < bufSize; i++) { + buf[i] = p.readInt32(); + } + int ret = mpTv->SaveCurAudioEQGain(buf); + r->writeInt32(ret); + break; + } + case GET_CUR_EQ_GAIN: { + int buf[128] = {0}; + int ret = mpTv->GetCurAudioEQGain(buf); + int bufSize = mpTv->GetAudioEQBandCount(); + r->writeInt32(bufSize); + for (int i = 0; i < bufSize; i++) { + r->writeInt32(buf[i]); + } + r->writeInt32(ret); + break; + } + case SET_AUDIO_EQ_SWITCH: { + int tmpVal = p.readInt32(); + int ret = mpTv->SetAudioEQSwitch(tmpVal); + r->writeInt32(ret); + break; + } + // AUDIO SPDIF SWITCH + case SET_AUDIO_SPDIF_SWITCH: { + int tmp_val = p.readInt32(); + int ret = mpTv->SetAudioSPDIFSwitch(tmp_val); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_SPDIF_SWITCH: { + int tmp_val = p.readInt32(); + int ret = mpTv->SaveCurAudioSPDIFSwitch(tmp_val); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_SPDIF_SWITCH: { + int ret = mpTv->GetCurAudioSPDIFSwitch(); + r->writeInt32(ret); + break; + } + //AUDIO SPDIF MODE + case SET_AUDIO_SPDIF_MODE: { + int vol = p.readInt32(); + int progId = p.readInt32(); + int audioTrackId = p.readInt32(); + int ret = mpTv->SetAudioSPDIFMode(vol); + mpTv->ResetAudioDecoderForPCMOutput(); + r->writeInt32(ret); + break; + } + case SAVE_CUR_AUDIO_SPDIF_MODE: { + int vol = p.readInt32(); + int ret = mpTv->SaveCurAudioSPDIFMode(vol); + r->writeInt32(ret); + break; + } + case GET_CUR_AUDIO_SPDIF_MODE: { + int ret = mpTv->GetCurAudioSPDIFMode(); + r->writeInt32(ret); + break; + } + case SET_AMAUDIO_OUTPUT_MODE: { + int tmp_val = p.readInt32(); + int ret = mpTv->SetAmAudioOutputMode(tmp_val); + r->writeInt32(ret); + break; + } + case SET_AMAUDIO_MUSIC_GAIN: { + int tmp_val = p.readInt32(); + int ret = mpTv->SetAmAudioMusicGain(tmp_val); + r->writeInt32(ret); + break; + } + case SET_AMAUDIO_LEFT_GAIN: { + int tmp_val = p.readInt32(); + int ret = mpTv->SetAmAudioLeftGain(tmp_val); + r->writeInt32(ret); + break; + } + case SET_AMAUDIO_RIGHT_GAIN: { + int tmp_val = p.readInt32(); + int ret = mpTv->SetAmAudioRightGain(tmp_val); + r->writeInt32(ret); + break; + } + case SET_AMAUDIO_PRE_GAIN: { + float tmp_val = p.readFloat(); + int ret = mpTv->setAmAudioPreGain(tmp_val); + r->writeInt32(ret); + break; + } + case SET_AMAUDIO_PRE_MUTE: { + int tmp_val = p.readInt32(); + int ret = mpTv->setAmAudioPreMute(tmp_val); + r->writeInt32(ret); + break; + } + case GET_AMAUDIO_PRE_MUTE: { + int ret = mpTv->getAmAudioPreMute(); + r->writeInt32(ret); + break; + } + case SELECT_LINE_IN_CHANNEL: { + int channel = p.readInt32(); + int ret = mpTv->AudioLineInSelectChannel(channel); + r->writeInt32(ret); + LOGD("SELECT_LINE_IN_CHANNEL: channel = %d; ret = %d.\n", channel, ret); + break; + } + case SET_LINE_IN_CAPTURE_VOL: { + int l_vol = p.readInt32(); + int r_vol = p.readInt32(); + int ret = mpTv->AudioSetLineInCaptureVolume(l_vol, r_vol); + r->writeInt32(ret); + break; + } + case SET_AUDIO_VOL_COMP: { + int tmpVal = p.readInt32(); + int ret = mpTv->SetCurProgramAudioVolumeCompensationVal(tmpVal); + r->writeInt32(ret); + break; + } + case GET_AUDIO_VOL_COMP: { + int ret = mpTv->GetAudioVolumeCompensationVal(-1); + r->writeInt32(ret); + break; + } + case SET_AUDIO_VIRTUAL: { + int enable = p.readInt32(); + int level = p.readInt32(); + int ret = mpTv->SetAudioVirtualizer(enable, level); + r->writeInt32(ret); + break; + } + case GET_AUDIO_VIRTUAL_ENABLE: { + int ret = mpTv->GetAudioVirtualizerEnable(); + r->writeInt32(ret); + break; + } + case GET_AUDIO_VIRTUAL_LEVEL: { + int ret = mpTv->GetAudioVirtualizerLevel(); + r->writeInt32(ret); + break; + } + // AUDIO END + + // SSM + case SSM_INIT_DEVICE: { + int tmpRet = 0; + tmpRet = mpTv->Tv_SSMRestoreDefaultSetting();//mpTv->Tv_SSMInitDevice(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_POWER_ON_OFF_CHANNEL: { + int tmpPowerChanNum = p.readInt32(); + int tmpRet; + tmpRet = SSMSavePowerOnOffChannel(tmpPowerChanNum); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_POWER_ON_OFF_CHANNEL: { + int tmpRet = 0; + tmpRet = SSMReadPowerOnOffChannel(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_SOURCE_INPUT: { + int tmpSouceInput = p.readInt32(); + int tmpRet; + tmpRet = SSMSaveSourceInput(tmpSouceInput); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_SOURCE_INPUT: { + int tmpRet = 0; + tmpRet = SSMReadSourceInput(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_LAST_SOURCE_INPUT: { + int tmpLastSouceInput = p.readInt32(); + int tmpRet; + tmpRet = SSMSaveLastSelectSourceInput(tmpLastSouceInput); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_LAST_SOURCE_INPUT: { + int tmpRet = 0; + tmpRet = SSMReadLastSelectSourceInput(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_SYS_LANGUAGE: { + int tmpVal = p.readInt32(); + int tmpRet; + tmpRet = SSMSaveSystemLanguage(tmpVal); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_SYS_LANGUAGE: { + int tmpRet = 0; + tmpRet = SSMReadSystemLanguage(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_AGING_MODE: { + int tmpVal = p.readInt32(); + int tmpRet; + tmpRet = SSMSaveAgingMode(tmpVal); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_AGING_MODE: { + int tmpRet = 0; + tmpRet = SSMReadAgingMode(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_PANEL_TYPE: { + int tmpVal = p.readInt32(); + int tmpRet; + tmpRet = SSMSavePanelType(tmpVal); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_PANEL_TYPE: { + int tmpRet = 0; + tmpRet = SSMReadPanelType(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_MAC_ADDR: { + int size = p.readInt32(); + for (int i = 0; i < size; i++) { + dataBuf[i] = p.readInt32(); + } + int ret = KeyData_SaveMacAddress(dataBuf); + r->writeInt32(ret); + break; + } + case SSM_READ_MAC_ADDR: { + int ret = KeyData_ReadMacAddress(dataBuf); + int size = KeyData_GetMacAddressDataLen(); + r->writeInt32(size); + for (int i = 0; i < size; i++) { + r->writeInt32(dataBuf[i]); + } + r->writeInt32(ret); + break; + } + case SSM_SAVE_BAR_CODE: { + int size = p.readInt32(); + for (int i = 0; i < size; i++) { + dataBuf[i] = p.readInt32(); + } + int ret = KeyData_SaveBarCode(dataBuf); + r->writeInt32(ret); + break; + } + case SSM_READ_BAR_CODE: { + int ret = KeyData_ReadBarCode(dataBuf); + int size = KeyData_GetBarCodeDataLen(); + r->writeInt32(size); + for (int i = 0; i < size; i++) { + r->writeInt32(dataBuf[i]); + } + r->writeInt32(ret); + break; + } + case SSM_SAVE_HDCPKEY: { + int size = p.readInt32(); + for (int i = 0; i < size; i++) { + dataBuf[i] = p.readInt32(); + } + int ret = SSMSaveHDCPKey(dataBuf); + r->writeInt32(ret); + break; + } + case SSM_READ_HDCPKEY: { + int ret = SSMReadHDCPKey(dataBuf); + int size = SSMGetHDCPKeyDataLen(); + r->writeInt32(size); + for (int i = 0; i < size; i++) { + r->writeInt32(dataBuf[i]); + } + r->writeInt32(ret); + break; + } + case SSM_SAVE_POWER_ON_MUSIC_SWITCH: { + int tmpVal = p.readInt32(); + int tmpRet; + tmpRet = SSMSavePowerOnMusicSwitch(tmpVal); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_POWER_ON_MUSIC_SWITCH: { + int tmpRet = 0; + tmpRet = SSMReadPowerOnMusicSwitch(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_POWER_ON_MUSIC_VOL: { + int tmpVal = p.readInt32(); + int tmpRet; + tmpRet = SSMSavePowerOnMusicVolume(tmpVal); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_POWER_ON_MUSIC_VOL: { + int tmpRet = 0; + tmpRet = SSMReadPowerOnMusicVolume(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_SYS_SLEEP_TIMER: { + int tmpVal = p.readInt32(); + int tmpRet; + tmpRet = SSMSaveSystemSleepTimer(tmpVal); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_SYS_SLEEP_TIMER: { + int tmpRet = 0; + tmpRet = SSMReadSystemSleepTimer(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_INPUT_SRC_PARENTAL_CTL: { + int tmpSourceIndex = p.readInt32(); + int tmpCtlFlag = p.readInt32(); + int tmpRet; + tmpRet = SSMSaveInputSourceParentalControl(tmpSourceIndex, tmpCtlFlag); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_INPUT_SRC_PARENTAL_CTL: { + int tmpSourceIndex = p.readInt32(); + int tmpRet = 0; + tmpRet = SSMReadInputSourceParentalControl(tmpSourceIndex); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_PARENTAL_CTL_SWITCH: { + int tmpSwitchFlag = p.readInt32(); + int tmpRet; + tmpRet = SSMSaveParentalControlSwitch(tmpSwitchFlag); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_PARENTAL_CTL_SWITCH: { + int tmpRet = 0; + tmpRet = SSMReadParentalControlSwitch(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_PARENTAL_CTL_PASS_WORD: { + String16 pass_wd_str = p.readString16(); + int tmpRet = SSMSaveParentalControlPassWord((unsigned char *)pass_wd_str.string(), pass_wd_str.size() * sizeof(unsigned short)); + r->writeInt32(tmpRet); + break; + } + case SSM_GET_CUSTOMER_DATA_START: { + int tmpRet = SSMGetCustomerDataStart(); + r->writeInt32(tmpRet); + break; + } + case SSM_GET_CUSTOMER_DATA_LEN: { + int tmpRet = SSMGetCustomerDataLen(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_STANDBY_MODE: { + int tmp_val = p.readInt32(); + int tmpRet = SSMSaveStandbyMode(tmp_val); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_STANDBY_MODE: { + int tmpRet = SSMReadStandbyMode(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_LOGO_ON_OFF_FLAG: { + int tmpSwitchFlag = p.readInt32(); + int tmpRet = SSMSaveLogoOnOffFlag(tmpSwitchFlag); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_LOGO_ON_OFF_FLAG: { + int tmpRet = SSMReadLogoOnOffFlag(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_HDMIEQ_MODE: { + int tmpSwitchFlag = p.readInt32(); + int tmpRet = SSMSaveHDMIEQMode(tmpSwitchFlag); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_HDMIEQ_MODE: { + int tmpRet = SSMReadHDMIEQMode(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_HDMIINTERNAL_MODE: { + int tmp_val = p.readInt32(); + int tmpRet = SSMSaveHDMIInternalMode(tmp_val); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_HDMIINTERNAL_MODE: { + int tmpRet = SSMReadHDMIInternalMode(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_GLOBAL_OGOENABLE: { + int tmp_val = p.readInt32(); + int tmpRet = SSMSaveGlobalOgoEnable(tmp_val); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_GLOBAL_OGOENABLE: { + int tmpRet = SSMReadGlobalOgoEnable(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_NON_STANDARD_STATUS: { + int tmp_val = p.readInt32(); + int tmpRet = SSMSaveNonStandardValue(tmp_val); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_NON_STANDARD_STATUS: { + int tmpRet = SSMReadNonStandardValue(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_ADB_SWITCH_STATUS: { + int tmp_val = p.readInt32(); + int tmpRet = SSMSaveAdbSwitchValue(tmp_val); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_ADB_SWITCH_STATUS: { + int tmpRet = SSMReadAdbSwitchValue(); + r->writeInt32(tmpRet); + break; + } + case SSM_SET_HDCP_KEY: { + int tmpRet = SSMSetHDCPKey(); + r->writeInt32(tmpRet); + break; + } + case SSM_REFRESH_HDCPKEY: { + int tmpRet = SSMRefreshHDCPKey(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_CHROMA_STATUS: { + int tmp_val = p.readInt32(); + int tmpRet = SSMSaveChromaStatus(tmp_val); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_CA_BUFFER_SIZE: { + int tmp_val = p.readInt32(); + int tmpRet = SSMSaveCABufferSizeValue(tmp_val); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_CA_BUFFER_SIZE: { + int tmpRet = SSMReadCABufferSizeValue(); + r->writeInt32(tmpRet); + break; + } + case SSM_GET_ATV_DATA_START: { + int tmpRet = SSMGetATVDataStart(); + r->writeInt32(tmpRet); + break; + } + case SSM_GET_ATV_DATA_LEN: { + int tmpRet = SSMGetATVDataLen(); + r->writeInt32(tmpRet); + break; + } + case SSM_GET_VPP_DATA_START: { + int tmpRet = SSMGetVPPDataStart(); + r->writeInt32(tmpRet); + break; + } + case SSM_GET_VPP_DATA_LEN: { + int tmpRet = SSMGetVPPDataLen(); + r->writeInt32(tmpRet); + break; + } + case SSM_SAVE_NOISE_GATE_THRESHOLD_STATUS: { + int tmp_val = p.readInt32(); + int tmpRet = SSMSaveNoiseGateThresholdValue(tmp_val); + r->writeInt32(tmpRet); + break; + } + case SSM_READ_NOISE_GATE_THRESHOLD_STATUS: { + int tmpRet = SSMReadNoiseGateThresholdValue(); + r->writeInt32(tmpRet); + break; + } + + case SSM_SAVE_HDMI_EDID_VER: { + int ret = -1; + int port_id = p.readInt32(); + int ver = p.readInt32(); + ret = SSMSaveHDMIEdidMode((tv_hdmi_port_id_t)port_id, (tv_hdmi_edid_version_t)ver); + r->writeInt32(ret); + break; + } + case SSM_READ_HDMI_EDID_VER: { + int ret = -1; + int port_id = p.readInt32(); + ret = SSMReadHDMIEdidVersion((tv_hdmi_port_id_t)port_id); + r->writeInt32(ret); + break; + } + case SSM_SAVE_HDCP_KEY_ENABLE: { + int ret = -1; + int enable = p.readInt32(); + ret = SSMSaveHDMIHdcpSwitcher(enable); + r->writeInt32(ret); + break; + } + case SSM_READ_HDCP_KEY_ENABLE: { + int ret = -1; + ret = SSMReadHDMIHdcpSwitcher(); + r->writeInt32(ret); + break; + } + // SSM END + + //MISC + case MISC_CFG_SET: { + String8 key(p.readString16()); + String8 value(p.readString16()); + + int tmpRet = config_set_str(CFG_SECTION_TV, key.string(), value.string()); + r->writeInt32(tmpRet); + break; + } + case MISC_CFG_GET: { + String8 key(p.readString16()); + String8 def(p.readString16()); + + const char *value = config_get_str(CFG_SECTION_TV, key.string(), def.string()); + r->writeString16(String16(value)); + break; + } + case MISC_SET_WDT_USER_PET: { + int counter = p.readInt32(); + int ret = TvMisc_SetUserCounter(counter); + r->writeInt32(ret); + break; + } + case MISC_SET_WDT_USER_COUNTER: { + int counter_time_out = p.readInt32(); + int ret = TvMisc_SetUserCounterTimeOut(counter_time_out); + r->writeInt32(ret); + break; + } + case MISC_SET_WDT_USER_PET_RESET_ENABLE: { + int enable = p.readInt32(); + int ret = TvMisc_SetUserPetResetEnable(enable); + r->writeInt32(ret); + break; + } + case MISC_GET_TV_API_VERSION: { + // write tvapi version info + const char *str = tvservice_get_git_branch_info(); + r->writeString16(String16(str)); + + str = tvservice_get_git_version_info(); + r->writeString16(String16(str)); + + str = tvservice_get_last_chaned_time_info(); + r->writeString16(String16(str)); + + str = tvservice_get_build_time_info(); + r->writeString16(String16(str)); + + str = tvservice_get_build_name_info(); + r->writeString16(String16(str)); + break; + } + case MISC_GET_DVB_API_VERSION: { + // write dvb version info + const char *str = dvb_get_git_branch_info(); + r->writeString16(String16(str)); + + str = dvb_get_git_version_info(); + r->writeString16(String16(str)); + + str = dvb_get_last_chaned_time_info(); + r->writeString16(String16(str)); + + str = dvb_get_build_time_info(); + r->writeString16(String16(str)); + + str = dvb_get_build_name_info(); + r->writeString16(String16(str)); + break; + } + //MISC END + + // EXTAR + case DTV_SUBTITLE_INIT: { + int bitmapWidth = p.readInt32(); + int bitmapHeight = p.readInt32(); + r->writeInt32(mpTv->mSubtitle.sub_init(bitmapWidth, bitmapHeight)); + break; + } + case DTV_SUBTITLE_LOCK: { + r->writeInt32(mpTv->mSubtitle.sub_lock()); + break; + } + case DTV_SUBTITLE_UNLOCK: { + r->writeInt32(mpTv->mSubtitle.sub_unlock()); + break; + } + case DTV_GET_SUBTITLE_SWITCH: { + r->writeInt32(mpTv->mSubtitle.sub_switch_status()); + break; + } + case DTV_START_SUBTITLE: { + int dmx_id = p.readInt32(); + int pid = p.readInt32(); + int page_id = p.readInt32(); + int anc_page_id = p.readInt32(); + r->writeInt32(mpTv->mSubtitle.sub_start_dvb_sub(dmx_id, pid, page_id, anc_page_id)); + break; + } + case DTV_STOP_SUBTITLE: { + r->writeInt32(mpTv->mSubtitle.sub_stop_dvb_sub()); + break; + } + case DTV_GET_SUBTITLE_INDEX: { + int progId = p.readInt32(); + CTvProgram prog; + CTvProgram::selectByID(progId, prog); + r->writeInt32(prog.getSubtitleIndex(progId)); + break; + } + case DTV_SET_SUBTITLE_INDEX: { + int progId = p.readInt32(); + int index = p.readInt32(); + CTvProgram prog; + CTvProgram::selectByID(progId, prog); + r->writeInt32(prog.setSubtitleIndex(progId, index)); + break; + } + case ATV_GET_CURRENT_PROGRAM_ID: { + int atvLastProgramId = mpTv->getATVProgramID(); + r->writeInt32(atvLastProgramId); + break; + } + case DTV_GET_CURRENT_PROGRAM_ID: { + int dtvLastProgramId = mpTv->getDTVProgramID(); + r->writeInt32(dtvLastProgramId); + break; + } + case ATV_SAVE_PROGRAM_ID: { + int progID = p.readInt32(); + int retCnt = 0; + mpTv->saveATVProgramID(progID); + r->writeInt32(retCnt); + break; + } + case SAVE_PROGRAM_ID: { + int type = p.readInt32(); + int progID = p.readInt32(); + int retCnt = 0; + if (type == CTvProgram::TYPE_DTV) + mpTv->saveDTVProgramID(progID); + else if (type == CTvProgram::TYPE_RADIO) + mpTv->saveRadioProgramID(progID); + else + mpTv->saveATVProgramID(progID); + r->writeInt32(retCnt); + break; + } + case GET_PROGRAM_ID: { + int type = p.readInt32(); + int id; + if (type == CTvProgram::TYPE_DTV) + id = mpTv->getDTVProgramID(); + else if (type == CTvProgram::TYPE_RADIO) + id = mpTv->getRadioProgramID(); + else + id = mpTv->getATVProgramID(); + r->writeInt32(id); + break; + } + + case ATV_GET_MIN_MAX_FREQ: { + int min, max; + int tmpRet = mpTv->getATVMinMaxFreq(&min, &max); + r->writeInt32(min); + r->writeInt32(max); + r->writeInt32(tmpRet); + break; + } + case DTV_GET_SCAN_FREQUENCY_LIST: { + Vector<sp<CTvChannel> > out; + int tmpRet = CTvRegion::getChannelListByName((char *)"CHINA,Default DTMB ALL", out); + r->writeInt32(out.size()); + for (int i = 0; i < (int)out.size(); i++) { + r->writeInt32(out[i]->getID()); + r->writeInt32(out[i]->getFrequency()); + r->writeInt32(out[i]->getLogicalChannelNum()); + } + r->writeInt32(tmpRet); + break; + } + case DTV_GET_SCAN_FREQUENCY_LIST_MODE: { + int mode = p.readInt32(); + Vector<sp<CTvChannel> > out; + int tmpRet = CTvRegion::getChannelListByName((char *)CTvScanner::getDtvScanListName(mode), out); + r->writeInt32(out.size()); + for (int i = 0; i < (int)out.size(); i++) { + r->writeInt32(out[i]->getID()); + r->writeInt32(out[i]->getFrequency()); + r->writeInt32(out[i]->getLogicalChannelNum()); + } + r->writeInt32(tmpRet); + break; + } + case DTV_GET_CHANNEL_INFO: { + int dbID = p.readInt32(); + channel_info_t chan_info; + int ret = mpTv->getChannelInfoBydbID(dbID, chan_info); + r->writeInt32(chan_info.freq); + r->writeInt32(chan_info.uInfo.dtvChanInfo.strength); + r->writeInt32(chan_info.uInfo.dtvChanInfo.quality); + r->writeInt32(chan_info.uInfo.dtvChanInfo.ber); + r->writeInt32(ret); + break; + } + case ATV_GET_CHANNEL_INFO: { + int dbID = p.readInt32(); + channel_info_t chan_info; + int ret = mpTv->getChannelInfoBydbID(dbID, chan_info); + r->writeInt32(chan_info.freq); + r->writeInt32(chan_info.uInfo.atvChanInfo.finefreq); + r->writeInt32(chan_info.uInfo.atvChanInfo.videoStd); + r->writeInt32(chan_info.uInfo.atvChanInfo.audioStd); + r->writeInt32(chan_info.uInfo.atvChanInfo.isAutoStd); + r->writeInt32(ret); + break; + } + case ATV_SCAN_MANUAL: { + int tmpRet = 0; + int startFreq = p.readInt32(); + int endFreq = p.readInt32(); + int videoStd = p.readInt32(); + int audioStd = p.readInt32(); + tmpRet = mpTv->atvMunualScan(startFreq, endFreq, videoStd, audioStd); + mTvService->mpScannerClient = this; + r->writeInt32(tmpRet); + break; + } + + case ATV_SCAN_AUTO: { + int videoStd = p.readInt32(); + int audioStd = p.readInt32(); + int searchType = p.readInt32(); + int procMode = p.readInt32(); + int tmpRet = mpTv->atvAutoScan(videoStd, audioStd, searchType, procMode); + mTvService->mpScannerClient = this; + r->writeInt32(tmpRet); + break; + } + case DTV_SCAN_MANUAL: { + int freq = p.readInt32(); + int tmpRet = mpTv->dtvManualScan(freq, freq); + mTvService->mpScannerClient = this; + r->writeInt32(tmpRet); + break; + } + case DTV_SCAN_MANUAL_BETWEEN_FREQ: { + int beginFreq = p.readInt32(); + int endFreq = p.readInt32(); + int modulation = p.readInt32(); + int tmpRet = mpTv->dtvManualScan(beginFreq, endFreq, modulation); + mTvService->mpScannerClient = this; + r->writeInt32(tmpRet); + break; + } + case DTV_SCAN_AUTO: { + int tmpRet = mpTv->dtvAutoScan(); + mTvService->mpScannerClient = this; + r->writeInt32(tmpRet); + break; + } + case DTV_SCAN: { + int mode = p.readInt32(); + int scanmode = p.readInt32(); + int freq = p.readInt32(); + int para1 = p.readInt32(); + int para2 = p.readInt32(); + int tmpRet = mpTv->dtvScan(mode, scanmode, freq, freq, para1, para2); + mTvService->mpScannerClient = this; + r->writeInt32(tmpRet); + break; + } + case STOP_PROGRAM_PLAY: { + int tmpRet = mpTv->stopPlayingLock(); + r->writeInt32(tmpRet); + break; + } + case ATV_DTV_SCAN_PAUSE: { + int tmpRet = mpTv->pauseScan(); + r->writeInt32(tmpRet); + break; + } + case ATV_DTV_SCAN_RESUME: { + int tmpRet = mpTv->resumeScan(); + r->writeInt32(tmpRet); + break; + } + case ATV_DTV_GET_SCAN_STATUS: { + int tmpRet = mpTv->getScanStatus(); + r->writeInt32(tmpRet); + break; + } + case ATV_DTV_SCAN_OPERATE_DEVICE : { + int type = p.readInt32(); + mpTv->operateDeviceForScan(type); + break; + } + case DTV_SET_TEXT_CODING: { + String8 coding(p.readString16()); + mpTv->setDvbTextCoding((char *)coding.string()); + break; + } + + case TV_CLEAR_ALL_PROGRAM: { + int arg0 = p.readInt32(); + + int tmpRet = mpTv->clearAllProgram(arg0); + mTvService->mpScannerClient = this; + r->writeInt32(tmpRet); + break; + } + + case HDMIRX_GET_KSV_INFO: { + int data[2] = {0, 0}; + int tmpRet = mpTv->GetHdmiHdcpKeyKsvInfo(data); + r->writeInt32(tmpRet); + r->writeInt32(data[0]); + r->writeInt32(data[1]); + break; + } + case FACTORY_FBC_UPGRADE: { + String8 strName(p.readString16()); + int mode = p.readInt32(); + int blkSize = p.readInt32(); + int ret = mpTv->StartUpgradeFBC((char *)strName.string(), mode, blkSize); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_BRIGHTNESS: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetBrightness(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_BRIGHTNESS: { + int ret = mpTv->mFactoryMode.fbcGetBrightness(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_CONTRAST: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetContrast(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_CONTRAST: { + int ret = mpTv->mFactoryMode.fbcGetContrast(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_SATURATION: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetSaturation(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_SATURATION: { + int ret = mpTv->mFactoryMode.fbcGetSaturation(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_HUE: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetHueColorTint(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_HUE: { + int ret = mpTv->mFactoryMode.fbcGetHueColorTint(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_BACKLIGHT: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetBacklight(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_BACKLIGHT: { + int ret = mpTv->mFactoryMode.fbcGetBacklight(); + r->writeInt32(ret); + break; + } + case FACTORY_FBC_SET_BACKLIGHT_EN : { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcBacklightOnOffSet(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_BACKLIGHT_EN: { + int ret = mpTv->mFactoryMode.fbcBacklightOnOffGet(); + r->writeInt32(ret); + break; + } + case FACTORY_FBC_SET_LVDS_SSG: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcLvdsSsgSet(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_ELEC_MODE: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetElecMode(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_ELEC_MODE: { + int ret = mpTv->mFactoryMode.fbcGetElecMode(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_PIC_MODE: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetPictureMode(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_PIC_MODE: { + int ret = mpTv->mFactoryMode.fbcGetPictureMode(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_TEST_PATTERN: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetTestPattern(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_TEST_PATTERN: { + int ret = mpTv->mFactoryMode.fbcGetTestPattern(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_GAIN_RED: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetGainRed(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_GAIN_RED: { + int ret = mpTv->mFactoryMode.fbcGetGainRed(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_GAIN_GREEN: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetGainGreen(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_GAIN_GREEN: { + int ret = mpTv->mFactoryMode.fbcGetGainGreen(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_GAIN_BLUE: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetGainBlue(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_GAIN_BLUE: { + int ret = mpTv->mFactoryMode.fbcGetGainBlue(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_OFFSET_RED: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetOffsetRed(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_OFFSET_RED: { + int ret = mpTv->mFactoryMode.fbcGetOffsetRed(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_OFFSET_GREEN: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetOffsetGreen(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_OFFSET_GREEN: { + int ret = mpTv->mFactoryMode.fbcGetOffsetGreen(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_OFFSET_BLUE: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcSetOffsetBlue(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_OFFSET_BLUE: { + int ret = mpTv->mFactoryMode.fbcGetOffsetBlue(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_COLORTEMP_MODE: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcColorTempModeSet(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_COLORTEMP_MODE: { + int ret = mpTv->mFactoryMode.fbcColorTempModeGet(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_SET_WB_INIT: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.fbcWBInitialSet(value); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_WB_INIT: { + int ret = mpTv->mFactoryMode.fbcWBInitialGet(); + r->writeInt32(ret); + break; + } + + case FACTORY_FBC_GET_MAINCODE_VERSION: { + char sw_version[64]; + char build_time[64]; + char git_version[64]; + char git_branch[64]; + char build_name[64]; + CFbcCommunication *fbcIns = GetSingletonFBC(); + if (fbcIns != NULL) { + fbcIns->cfbc_Get_FBC_MAINCODE_Version(COMM_DEV_SERIAL, sw_version, build_time, git_version, git_branch, build_name); + r->writeString16(String16(sw_version)); + r->writeString16(String16(build_time)); + r->writeString16(String16(git_version)); + r->writeString16(String16(git_branch)); + r->writeString16(String16(build_name)); + } else { + r->writeString16(String16("No FBC")); + r->writeString16(String16("No FBC")); + r->writeString16(String16("No FBC")); + r->writeString16(String16("No FBC")); + r->writeString16(String16("No FBC")); + } + break; + } + case FACTORY_SET_SN: { + char StrFactSN[256] = {0}; + String16 strTemFactorySn = p.readString16(); + String8 strFactorySn = String8(strTemFactorySn); + sprintf((char *)StrFactSN, "%s", strFactorySn.string()); + CFbcCommunication *fbcIns = GetSingletonFBC(); + if (fbcIns != NULL) { + int iRet = fbcIns->cfbc_Set_FBC_Factory_SN(COMM_DEV_SERIAL, (const char *)StrFactSN); + r->writeInt32(iRet); + } else { + r->writeInt32(-1); + } + break; + } + case FACTORY_GET_SN: { + char factorySerialNumber[256] = {0}; + memset((void *)factorySerialNumber, 0, 256); + CFbcCommunication *fbcIns = GetSingletonFBC(); + if (fbcIns != NULL) { + fbcIns->cfbc_Get_FBC_Factory_SN(COMM_DEV_SERIAL, factorySerialNumber); + r->writeString16(String16(factorySerialNumber)); + } else { + r->writeString16(String16("No FBC")); + } + break; + } + case FACTORY_FBC_PANEL_GET_INFO: { + char panel_model[64]; + CFbcCommunication *fbcIns = GetSingletonFBC(); + if (fbcIns != NULL) { + fbcIns->cfbc_Get_FBC_Get_PANel_INFO(COMM_DEV_SERIAL, panel_model); + r->writeString16(String16(panel_model)); + } else { + r->writeString16(String16("")); + } + break; + } + case FACTORY_FBC_PANEL_POWER_SWITCH: { + int value = p.readInt32(); + CFbcCommunication *fbcIns = GetSingletonFBC(); + if (fbcIns != NULL) { + int ret = fbcIns->cfbc_Set_FBC_panel_power_switch(COMM_DEV_SERIAL, value); + r->writeInt32(ret); + } else { + r->writeInt32(-1); + } + break; + } + case FACTORY_FBC_PANEL_SUSPEND: { + int value = p.readInt32(); + CFbcCommunication *fbcIns = GetSingletonFBC(); + if (fbcIns != NULL) { + int ret = fbcIns->cfbc_Set_FBC_suspend(COMM_DEV_SERIAL, value); + r->writeInt32(ret); + } else { + r->writeInt32(-1); + } + break; + } + case FACTORY_FBC_PANEL_USER_SETTING_DEFAULT: { + int value = p.readInt32(); + CFbcCommunication *fbcIns = GetSingletonFBC(); + if (fbcIns != NULL) { + int ret = fbcIns->cfbc_Set_FBC_User_Setting_Default(COMM_DEV_SERIAL, value); + r->writeInt32(ret); + } else { + r->writeInt32(-1); + } + break; + } + case FACTORY_WHITE_BALANCE_SET_GAIN_RED: { + int tv_source_input = p.readInt32(); + int colortemp_mode = p.readInt32(); + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceGainRedSet(tv_source_input, colortemp_mode, value); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_GET_GAIN_RED: { + int tv_source_input = p.readInt32(); + int colortemp_mode = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceGainRedGet(tv_source_input, colortemp_mode); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_SET_GAIN_GREEN: { + int tv_source_input = p.readInt32(); + int colortemp_mode = p.readInt32(); + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceGainGreenSet(tv_source_input, colortemp_mode, value); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_GET_GAIN_GREEN: { + int tv_source_input = p.readInt32(); + int colortemp_mode = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceGainGreenGet(tv_source_input, colortemp_mode); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_SET_GAIN_BLUE: { + int tv_source_input = p.readInt32(); + int colortemp_mode = p.readInt32(); + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceGainBlueSet(tv_source_input, colortemp_mode, value); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_GET_GAIN_BLUE: { + int tv_source_input = p.readInt32(); + int colortemp_mode = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceGainBlueGet(tv_source_input, colortemp_mode); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_SET_OFFSET_RED: { + int tv_source_input = p.readInt32(); + int colortemp_mode = p.readInt32(); + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceOffsetRedSet(tv_source_input, colortemp_mode, value); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_GET_OFFSET_RED: { + int tv_source_input = p.readInt32(); + int colortemp_mode = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceOffsetRedGet(tv_source_input, colortemp_mode); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_SET_OFFSET_GREEN: { + int tv_source_input = p.readInt32(); + int colortemp_mode = p.readInt32(); + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceOffsetGreenSet(tv_source_input, colortemp_mode, value); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_GET_OFFSET_GREEN: { + int tv_source_input = p.readInt32(); + int colortemp_mode = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceOffsetGreenGet(tv_source_input, colortemp_mode); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_SET_OFFSET_BLUE: { + int tv_source_input = p.readInt32(); + int colortemp_mode = p.readInt32(); + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceOffsetBlueSet(tv_source_input, colortemp_mode, value); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_GET_OFFSET_BLUE: { + int tv_source_input = p.readInt32(); + int colortemp_mode = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceOffsetBlueGet(tv_source_input, colortemp_mode); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_GET_COLOR_TMP: { + int tv_source_input = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceColorTempModeGet(tv_source_input); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_SET_COLOR_TMP: { + int tv_source_input = p.readInt32(); + int Tempmode = p.readInt32(); + int is_save = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceColorTempModeSet(tv_source_input, Tempmode, is_save); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_SAVE_PRAMAS: { + int tv_source_input = p.readInt32(); + int mode = p.readInt32(); + int r_gain = p.readInt32(); + int g_gain = p.readInt32(); + int b_gain = p.readInt32(); + int r_offset = p.readInt32(); + int g_offset = p.readInt32(); + int b_offset = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalancePramSave(tv_source_input, mode, r_gain, g_gain, b_gain, r_offset, g_offset, b_offset); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_OPEN_GRAY_PATTERN: { + int ret = mpTv->mFactoryMode.whiteBalanceGrayPatternOpen(); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_CLOSE_GRAY_PATTERN: { + int ret = mpTv->mFactoryMode.whiteBalanceGrayPatternClose(); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_SET_GRAY_PATTERN: { + int value = p.readInt32(); + int ret = mpTv->mFactoryMode.whiteBalanceGrayPatternSet(value); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_GET_GRAY_PATTERN: { + int ret = mpTv->mFactoryMode.whiteBalanceGrayPatternGet(); + r->writeInt32(ret); + break; + } + case FACTORY_WHITE_BALANCE_GET_ALL_PRAMAS: { + int mode = p.readInt32(); + tcon_rgb_ogo_t params; + int ret = mpTv->mFactoryMode.getColorTemperatureParams((vpp_color_temperature_mode_t)mode, ¶ms); + r->writeInt32(ret); + r->writeInt32(params.r_gain); + r->writeInt32(params.g_gain); + r->writeInt32(params.b_gain); + r->writeInt32(params.r_post_offset); + r->writeInt32(params.g_post_offset); + r->writeInt32(params.b_post_offset); + break; + } + case STOP_SCAN: { + mpTv->stopScanLock(); + break; + } + case DTV_GET_SNR: { + int tmpRet = mpTv->getFrontendSNR(); + r->writeInt32(tmpRet); + break; + } + case DTV_GET_BER: { + int tmpRet = mpTv->getFrontendBER(); + r->writeInt32(tmpRet); + break; + } + case DTV_GET_STRENGTH: { + int tmpRet = mpTv->getFrontendSignalStrength(); + r->writeInt32(tmpRet); + break; + } + case DTV_GET_AUDIO_TRACK_NUM: { + int programId = p.readInt32(); + int retCnt = mpTv->getAudioTrackNum(programId); + r->writeInt32(retCnt); + break; + } + case DTV_GET_AUDIO_TRACK_INFO: { + int progId = p.readInt32(); + int aIdx = p.readInt32(); + int aFmt = -1; + String8 lang; + int iRet = mpTv->getAudioInfoByIndex(progId, aIdx, &aFmt, lang); + r->writeInt32(aFmt); + r->writeString16(String16(lang)); + break; + } + case DTV_SWITCH_AUDIO_TRACK: { + int aPid = p.readInt32(); + int aFmt = p.readInt32(); + int aParam = p.readInt32(); + int ret = mpTv->switchAudioTrack(aPid, aFmt, aParam); + r->writeInt32(ret); + break; + } + case DTV_SET_AUDIO_AD: { + int aEnable = p.readInt32(); + int aPid = p.readInt32(); + int aFmt = p.readInt32(); + int ret = mpTv->setAudioAD(aEnable, aPid, aFmt); + r->writeInt32(ret); + break; + } + case DTV_GET_CURR_AUDIO_TRACK_INDEX: { + int currAduIdx = -1; + int progId = p.readInt32(); + CTvProgram prog; + CTvProgram::selectByID(progId, prog); + currAduIdx = prog.getCurrAudioTrackIndex(); + r->writeInt32(currAduIdx); + break; + } + case DTV_SET_AUDIO_CHANNEL_MOD: { + int audioChannelIdx = p.readInt32(); + mpTv->setAudioChannel(audioChannelIdx); + break; + } + case DTV_GET_AUDIO_CHANNEL_MOD: { + int currChannelMod = mpTv->getAudioChannel(); + r->writeInt32(currChannelMod); + break; + } + case DTV_GET_CUR_FREQ: { + int progId = p.readInt32(); + CTvProgram prog; + CTvChannel channel; + + int iRet = CTvProgram::selectByID(progId, prog); + if (0 != iRet) return -1; + prog.getChannel(channel); + int freq = channel.getFrequency(); + r->writeInt32(freq); + break; + } + case DTV_GET_EPG_UTC_TIME: { + int utcTime = mpTv->getTvTime(); + r->writeInt32(utcTime); + break; + } + case DTV_GET_EPG_INFO_POINT_IN_TIME: { + int progid = p.readInt32(); + int utcTime = p.readInt32(); + CTvProgram prog; + int ret = CTvProgram::selectByID(progid, prog); + CTvEvent ev; + ret = ev.getProgPresentEvent(prog.getSrc(), prog.getID(), utcTime, ev); + r->writeString16(String16(ev.getName())); + r->writeString16(String16(ev.getDescription())); + r->writeString16(String16(ev.getExtDescription())); + r->writeInt32(ev.getStartTime()); + r->writeInt32(ev.getEndTime()); + r->writeInt32(ev.getSubFlag()); + r->writeInt32(ev.getEventId()); + break; + } + case DTV_GET_EPG_INFO_DURATION: { + Vector<sp<CTvEvent> > epgOut; + int progid = p.readInt32(); + int iUtcStartTime = p.readInt32(); + int iDurationTime = p.readInt32(); + CTvProgram prog; + CTvEvent ev; + int iRet = CTvProgram::selectByID(progid, prog); + if (0 != iRet) { + break; + } + iRet = ev.getProgScheduleEvents(prog.getSrc(), prog.getID(), iUtcStartTime, iDurationTime, epgOut); + if (0 != iRet) { + break; + } + int iObOutSize = epgOut.size(); + if (0 == iObOutSize) { + break; + } + + r->writeInt32(iObOutSize); + for (int i = 0; i < iObOutSize; i ++) { + r->writeString16(String16(epgOut[i]->getName())); + r->writeString16(String16(epgOut[i]->getDescription())); + r->writeString16(String16(ev.getExtDescription())); + r->writeInt32(epgOut[i]->getStartTime()); + r->writeInt32(epgOut[i]->getEndTime()); + r->writeInt32(epgOut[i]->getSubFlag()); + r->writeInt32(epgOut[i]->getEventId()); + } + break; + } + case DTV_SET_PROGRAM_NAME: { + CTvProgram prog; + int progid = p.readInt32(); + String16 tmpName = p.readString16(); + String8 strName = String8(tmpName); + prog.updateProgramName(progid, strName); + break; + } + case DTV_SET_PROGRAM_SKIPPED: { + CTvProgram prog; + int progid = p.readInt32(); + bool bSkipFlag = p.readInt32(); + prog.setSkipFlag(progid, bSkipFlag); + break; + } + case DTV_SET_PROGRAM_FAVORITE: { + CTvProgram prog; + int progid = p.readInt32(); + bool bFavorite = p.readInt32(); + prog.setFavoriteFlag(progid, bFavorite); + break; + } + case DTV_DETELE_PROGRAM: { + CTvProgram prog; + int progid = p.readInt32(); + prog.deleteProgram(progid); + break; + } + case SET_BLACKOUT_ENABLE: { + int enable = p.readInt32(); + mpTv->setBlackoutEnable(enable); + break; + } + case START_AUTO_BACKLIGHT: { + mpTv->setAutoBackLightStatus(1); + break; + } + case STOP_AUTO_BACKLIGHT: { + mpTv->setAutoBackLightStatus(0); + break; + } + case IS_AUTO_BACKLIGHTING: { + int on = mpTv->getAutoBackLightStatus(); + r->writeInt32(on); + break; + } + case GET_AVERAGE_LUMA: { + int ret = mpTv->getAverageLuma(); + r->writeInt32(ret); + break; + } + case GET_AUTO_BACKLIGHT_DATA: { + int buf[128] = {0}; + int size = mpTv->getAutoBacklightData(buf); + r->writeInt32(size); + for (int i = 0; i < size; i++) { + r->writeInt32(buf[i]); + } + break; + } + case SET_AUTO_BACKLIGHT_DATA: { + int ret = mpTv->setAutobacklightData(String8(p.readString16())); + r->writeInt32(ret); + break; + } + + case SSM_READ_BLACKOUT_ENABLE: { + int enable = mpTv->getSaveBlackoutEnable(); + r->writeInt32(enable); + break; + } + case DTV_SWAP_PROGRAM: { + CTvProgram prog; + int firstProgId = p.readInt32(); + int secondProgId = p.readInt32(); + CTvProgram::selectByID(firstProgId, prog); + int firstChanOrderNum = prog.getChanOrderNum(); + CTvProgram::selectByID(secondProgId, prog); + int secondChanOrderNum = prog.getChanOrderNum(); + prog.swapChanOrder(firstProgId, firstChanOrderNum, secondProgId, secondChanOrderNum); + break; + } + case DTV_SET_PROGRAM_LOCKED: { + CTvProgram prog; + int progid = p.readInt32(); + bool bLocked = p.readInt32(); + prog.setLockFlag(progid, bLocked); + break; + } + case DTV_GET_FREQ_BY_PROG_ID: { + int freq = 0; + int progid = p.readInt32(); + CTvProgram prog; + int ret = CTvProgram::selectByID(progid, prog); + if (ret != 0) return -1; + CTvChannel channel; + prog.getChannel(channel); + freq = channel.getFrequency(); + r->writeInt32(freq); + break; + } + case DTV_GET_BOOKED_EVENT: { + CTvBooking tvBook; + Vector<sp<CTvBooking> > vTvBookOut; + tvBook.getBookedEventList(vTvBookOut); + int iObOutSize = vTvBookOut.size(); + if (0 == iObOutSize) { + break; + } + r->writeInt32(iObOutSize); + for (int i = 0; i < iObOutSize; i ++) { + r->writeString16(String16(vTvBookOut[i]->getProgName())); + r->writeString16(String16(vTvBookOut[i]->getEvtName())); + r->writeInt32(vTvBookOut[i]->getStartTime()); + r->writeInt32(vTvBookOut[i]->getDurationTime()); + r->writeInt32(vTvBookOut[i]->getBookId()); + r->writeInt32(vTvBookOut[i]->getProgramId()); + r->writeInt32(vTvBookOut[i]->getEventId()); + } + break; + } + case SET_FRONTEND_PARA: { + int ret = -1; + frontend_para_set_t feParms; + feParms.mode = (fe_type_t)p.readInt32(); + feParms.freq = p.readInt32(); + feParms.videoStd = (atv_video_std_t)p.readInt32(); + feParms.audioStd = (atv_audio_std_t)p.readInt32(); + feParms.para1 = p.readInt32(); + feParms.para2 = p.readInt32(); + mpTv->resetFrontEndPara(feParms); + r->writeInt32(ret); + break; + } + case PLAY_PROGRAM: { + int mode = p.readInt32(); + int freq = p.readInt32(); + if (mode == TV_FE_ANALOG) { + int videoStd = p.readInt32(); + int audioStd = p.readInt32(); + int fineTune = p.readInt32(); + int audioCompetation = p.readInt32(); + mpTv->playAtvProgram(freq, videoStd, audioStd, fineTune, audioCompetation); + } else { + int para1 = p.readInt32(); + int para2 = p.readInt32(); + int vid = p.readInt32(); + int vfmt = p.readInt32(); + int aid = p.readInt32(); + int afmt = p.readInt32(); + int pcr = p.readInt32(); + int audioCompetation = p.readInt32(); + mpTv->playDtvProgram(mode, freq, para1, para2, vid, vfmt, aid, afmt, pcr, audioCompetation); + } + break; + } + case GET_PROGRAM_LIST: { + Vector<sp<CTvProgram> > out; + int type = p.readInt32(); + int skip = p.readInt32(); + CTvProgram::selectByType(type, skip, out); + r->writeInt32(out.size()); + for (int i = 0; i < (int)out.size(); i++) { + r->writeInt32(out[i]->getID()); + r->writeInt32(out[i]->getChanOrderNum()); + r->writeInt32(out[i]->getMajor()); + r->writeInt32(out[i]->getMinor()); + r->writeInt32(out[i]->getProgType()); + r->writeString16(String16(out[i]->getName())); + r->writeInt32(out[i]->getProgSkipFlag()); + r->writeInt32(out[i]->getFavoriteFlag()); + r->writeInt32(out[i]->getVideo()->getFormat()); + CTvChannel ch; + out[i]->getChannel(ch); + r->writeInt32(ch.getDVBTSID()); + r->writeInt32(out[i]->getServiceId()); + r->writeInt32(out[i]->getVideo()->getPID()); + r->writeInt32(out[i]->getVideo()->getPID()); + + int audioTrackSize = out[i]->getAudioTrackSize(); + r->writeInt32(audioTrackSize); + for (int j = 0; j < audioTrackSize; j++) { + r->writeString16(String16(out[i]->getAudio(j)->getLang())); + r->writeInt32(out[i]->getAudio(j)->getFormat()); + r->writeInt32(out[i]->getAudio(j)->getPID()); + } + Vector<CTvProgram::Subtitle *> mvSubtitles = out[i]->getSubtitles(); + int subTitleSize = mvSubtitles.size(); + r->writeInt32(subTitleSize); + if (subTitleSize > 0) { + for (int k = 0; k < subTitleSize; k++) { + r->writeInt32(mvSubtitles[k]->getPID()); + r->writeString16(String16(mvSubtitles[k]->getLang())); + r->writeInt32(mvSubtitles[k]->getCompositionPageID()); + r->writeInt32(mvSubtitles[k]->getAncillaryPageID()); + } + } + r->writeInt32(ch.getFrequency()); + } + break; + } + case DTV_GET_VIDEO_FMT_INFO: { + int srcWidth = 0; + int srcHeight = 0; + int srcFps = 0; + int srcInterlace = 0; + int iRet = -1; + + iRet == mpTv->getVideoFormatInfo(&srcWidth, &srcHeight, &srcFps, &srcInterlace); + r->writeInt32(srcWidth); + r->writeInt32(srcHeight); + r->writeInt32(srcFps); + r->writeInt32(srcInterlace); + r->writeInt32(iRet); + } + break; + + case DTV_GET_AUDIO_FMT_INFO: { + int iRet = -1; + int fmt[2]; + int sample_rate[2]; + int resolution[2]; + int channels[2]; + int lpepresent[2]; + int frames; + int ab_size; + int ab_data; + int ab_free; + iRet == mpTv->getAudioFormatInfo(fmt, sample_rate, resolution, channels, + lpepresent, &frames, &ab_size, &ab_data, &ab_free); + r->writeInt32(fmt[0]); + r->writeInt32(fmt[1]); + r->writeInt32(sample_rate[0]); + r->writeInt32(sample_rate[1]); + r->writeInt32(resolution[0]); + r->writeInt32(resolution[1]); + r->writeInt32(channels[0]); + r->writeInt32(channels[1]); + r->writeInt32(lpepresent[0]); + r->writeInt32(lpepresent[1]); + r->writeInt32(frames); + r->writeInt32(ab_size); + r->writeInt32(ab_data); + r->writeInt32(ab_free); + r->writeInt32(iRet); + } + break; + + case HDMIAV_HOTPLUGDETECT_ONOFF: { + int flag = mpTv->GetHdmiAvHotplugDetectOnoff(); + r->writeInt32(flag); + break; + } + case HANDLE_GPIO: { + String8 strName(p.readString16()); + int is_out = p.readInt32(); + int edge = p.readInt32(); + int ret = mpTv->handleGPIO((char *)strName.string(), is_out, edge); + r->writeInt32(ret); + break; + } + case SET_LCD_ENABLE: { + int enable = p.readInt32(); + int ret = mpTv->setLcdEnable(enable); + r->writeInt32(ret); + break; + } + case GET_ALL_TV_DEVICES: { + const char *value = config_get_str(CFG_SECTION_TV, CGF_DEFAULT_INPUT_IDS, "null"); + r->writeCString(value); + break; + } + case GET_HDMI_PORTS: { + int value = config_get_int(CFG_SECTION_TV, CGF_DEFAULT_HDMI_PORTS, 0); + r->writeInt32(value); + break; + } + case TV_CLEAR_FRONTEND: { + int para = p.readInt32(); + int tmpRet = mpTv->clearFrontEnd(para); + r->writeInt32(tmpRet); + break; + } + case TV_SET_FRONTEND: { + int force = p.readInt32(); + String8 feparas(p.readString16()); + int tmpRet = mpTv->setFrontEnd(feparas, (force != 0)); + r->writeInt32(tmpRet); + break; + } + case PLAY_PROGRAM_2: { + String8 feparas(p.readString16()); + int vid = p.readInt32(); + int vfmt = p.readInt32(); + int aid = p.readInt32(); + int afmt = p.readInt32(); + int pcr = p.readInt32(); + int audioCompetation = p.readInt32(); + mpTv->playDtvProgram(feparas.string(), vid, vfmt, aid, afmt, pcr, audioCompetation); + break; + } + case TV_SCAN_2: { + String8 feparas(p.readString16()); + String8 scanparas(p.readString16()); + int ret = mpTv->Scan(feparas.string(), scanparas.string()); + mTvService->mpScannerClient = this; + r->writeInt32(ret); + break; + } + case SET_AUDIO_OUTMODE: { + int mode = p.readInt32(); + int ret = SetAudioOutmode(mode); + r->writeInt32(ret); + break; + } + case GET_AUDIO_OUTMODE: { + int ret = GetAudioOutmode(); + r->writeInt32(ret); + break; + } + case GET_AUDIO_STREAM_OUTMODE: { + int ret = GetAudioStreamOutmode(); + r->writeInt32(ret); + break; + } + case SET_AMAUDIO_VOLUME: { + int volume = p.readInt32(); + int ret = mpTv->setAmAudioVolume(float (volume)); + r->writeInt32(ret); + break; + } + case GET_AMAUDIO_VOLUME: { + float volume = mpTv->getAmAudioVolume(); + r->writeInt32(int (volume)); + break; + } + case SAVE_AMAUDIO_VOLUME: { + int volume = p.readInt32(); + int source = p.readInt32(); + int ret = mpTv->saveAmAudioVolume(volume, source); + r->writeInt32(ret); + break; + } + case GET_SAVE_AMAUDIO_VOLUME: { + int source = p.readInt32(); + int volume = mpTv->getSaveAmAudioVolume(source); + r->writeInt32(volume); + break; + } + case DTV_UPDATE_RRT: { + int freq = p.readInt32(); + int modulation = p.readInt32(); + int mode = p.readInt32(); + int ret = mpTv->Tv_RrtUpdate(freq, modulation, mode); + r->writeInt32(ret); + break; + } + case DTV_SEARCH_RRT: { + int rating_region_id = p.readInt32(); + int dimension_id = p.readInt32(); + int value_id = p.readInt32(); + rrt_select_info_t rrt_info; + int ret = mpTv->Tv_RrtSearch(rating_region_id, dimension_id, value_id, &rrt_info); + r->writeInt32(rrt_info.dimensions_name_count); + int count = rrt_info.dimensions_name_count; + if (count != 0) { + r->writeString16(String16(rrt_info.dimensions_name)); + } + r->writeInt32(rrt_info.rating_region_name_count); + count = rrt_info.rating_region_name_count; + if (count != 0) { + r->writeString16(String16(rrt_info.rating_region_name)); + } + r->writeInt32(rrt_info.rating_value_text_count); + count = rrt_info.rating_value_text_count; + if (count != 0) { + r->writeString16(String16(rrt_info.rating_value_text)); + } + r->writeInt32(ret); + break; + } + + case DTV_UPDATE_EAS: { + int ret = mpTv->Tv_Easupdate(); + r->writeInt32(ret); + break; + } + // EXTAR END + + //NEWPLAY/RECORDING + case DTV_RECORDING_CMD: { + int ret = mpTv->doRecordingCommand(p.readInt32(), String8(p.readString16()).string(), String8(p.readString16()).string()); + r->writeInt32(ret); + }break; + case DTV_PLAY_CMD: { + int ret = mpTv->doPlayCommand(p.readInt32(), String8(p.readString16()).string(), String8(p.readString16()).string()); + r->writeInt32(ret); + }break; + + default: + LOGD("default"); + break; + } + + LOGD("exit client=%d cmd=%d", getCallingPid(), cmd); + return 0; +} + +int TvService::Client::notifyCallback(const int &msgtype, const Parcel &p) +{ + mTvClient->notifyCallback(msgtype, p); + return 0; +} + +status_t TvService::dump(int fd, const Vector<String16>& args) +{ + String8 result; + if (!checkCallingPermission(String16("android.permission.DUMP"))) { + char buffer[256]; + snprintf(buffer, 256, "Permission Denial: " + "can't dump system_control from pid=%d, uid=%d\n", + IPCThreadState::self()->getCallingPid(), + IPCThreadState::self()->getCallingUid()); + result.append(buffer); + } else { + AutoMutex _l(mServiceLock); + if (args.size() > 0) { + for (int i = 0; i < (int)args.size(); i ++) { + if (args[i] == String16("-s")) { + String8 section(args[i+1]); + String8 key(args[i+2]); + const char *value = config_get_str(section, key, ""); + result.appendFormat("section:[%s] key:[%s] value:[%s]\n", section.string(), key.string(), value); + } + else if (args[i] == String16("-h")) { + result.append( + "\ntv service use to control the tv logical \n\n" + "usage: dumpsys tvservice [-s <SECTION> <KEY>][-m][-h] \n" + "-s: get config string \n" + " SECTION:[TV|ATV|SourceInputMap|SETTING|FBCUART]\n" + "-m: track native heap memory\n" + "-h: help \n\n"); + } + else if (args[i] == String16("-m")) { + dumpMemoryAddresses(fd); + } + } + } + else { + result.appendFormat("client num = %d\n", mUsers); + for (int i = 0; i < (int)mClients.size(); i++) { + wp<Client> client = mClients[i]; + if (client != 0) { + sp<Client> c = client.promote(); + if (c != 0) { + result.appendFormat("client[%d] pid = %d\n", i, c->getPid()); + } + } + } + + mpTv->dump(result); + } + } + write(fd, result.string(), result.size()); + return NO_ERROR; +} + diff --git a/tv/tvserver/tvserver/TvService.h b/tv/tvserver/tvserver/TvService.h new file mode 100644 index 0000000..811d483 --- a/dev/null +++ b/tv/tvserver/tvserver/TvService.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef ANDROID_SERVERS_TV_TVSERVICE_H +#define ANDROID_SERVERS_TV_TVSERVICE_H + +#include <ITvService.h> +//#include <include/Tv.h> +#include <utils/threads.h> +#include <utils/Vector.h> +#include <stdint.h> +#include <tv/CTv.h> +#include "tv/CTvScreenCapture.h" + +using namespace android; + +class TvService: public BnTvService , public CTv::TvIObserver, public CTvScreenCapture::TvIObserver { +public: + class Client: public BnTv { + public: + Client(const sp<TvService> &tvService, const sp<ITvClient> &tvClient, pid_t clientPid, CTv *pTv); + virtual ~Client(); + virtual void disconnect(); + virtual status_t connect(const sp<ITvClient> &client); + virtual status_t lock(); + virtual status_t unlock(); + virtual status_t processCmd(const Parcel &p, Parcel *r); + virtual status_t createSubtitle(const sp<IMemory> &share_mem); + virtual status_t createVideoFrame(const sp<IMemory> &share_mem, int iSourceMode, int iCapVideoLayerOnly); + + // our client... + const sp<ITvClient> &getTvClient() const + { + return mTvClient; + } + + int notifyCallback(const int &msgtype, const Parcel &p); + int getPid() { + return mClientPid; + } + + private: + //friend class CTv; + //friend class TvService; + status_t checkPid(); + + mutable Mutex mLock; + sp<TvService> mTvService; + sp<ITvClient> mTvClient; + pid_t mClientPid; + CTv *mpTv; + bool mIsStartTv; + };//end client + + static void instantiate(); + + virtual sp<ITv> connect(const sp<ITvClient> &tvClient); + virtual void onTvEvent(const CTvEv &ev); + void removeClient(const sp<ITvClient> &tvClient); + + virtual status_t dump(int fd, const Vector<String16>& args); + + wp<Client> mpScannerClient; + wp<Client> mpSubClient; + Vector< wp<Client> > mClients; + +private: + TvService(); + virtual ~TvService(); + + virtual void incUsers(); + virtual void decUsers(); + + volatile int32_t mUsers; + CTv *mpTv; + CTvScreenCapture mCapVidFrame; + mutable Mutex mServiceLock; +}; + +#endif diff --git a/tv/tvserver/tvserver/main_tvserver.cpp b/tv/tvserver/tvserver/main_tvserver.cpp new file mode 100644 index 0000000..8857753 --- a/dev/null +++ b/tv/tvserver/tvserver/main_tvserver.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2016 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/15 + * @par function description: + * - 1 droidlogic tvserver daemon + */ + +#define LOG_TAG "tvserver" + +#include <binder/IPCThreadState.h> +#include <binder/ProcessState.h> +#include <binder/IServiceManager.h> +#include <cutils/properties.h> +#include <HidlTransportSupport.h> + +#include "TvService.h" +#include "DroidTvServer.h" + +using namespace android; +using ::android::hardware::configureRpcThreadpool; +using ::vendor::amlogic::hardware::tvserver::V1_0::implementation::DroidTvServer; +using ::vendor::amlogic::hardware::tvserver::V1_0::implementation::ITvServer; +using ::vendor::amlogic::hardware::tvserver::V1_0::ITvServer; + + +int main(int argc __unused, char** argv __unused) +{ + bool treble = property_get_bool("persist.tvserver.treble", true); + if (treble) { + android::ProcessState::initWithDriver("/dev/vndbinder"); + } + + ALOGI("tvserver daemon starting in %s mode", treble?"treble":"normal"); + configureRpcThreadpool(4, false); + sp<ProcessState> proc(ProcessState::self()); + + if (treble) { + sp<ITvServer> hidltvserver = new DroidTvServer(); + if (hidltvserver == nullptr) { + ALOGE("Cannot create ITvServer service"); + } else if (hidltvserver->registerAsService() != OK) { + ALOGE("Cannot register ITvServer service."); + } else { + ALOGI("Treble ITvServer service created."); + } + } + else { + //TvService::instantiate(); + } + + /* + * This thread is just going to process Binder transactions. + */ + IPCThreadState::self()->joinThreadPool(); +} diff --git a/tv/tvserver/tvserver/tv_callback.h b/tv/tvserver/tvserver/tv_callback.h new file mode 100644 index 0000000..5c49367 --- a/dev/null +++ b/tv/tvserver/tvserver/tv_callback.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef TV_CALLBACK +#define TV_CALLBACK +#include "tvapi/android/tv/CTv.h" +class TvCallback : public CTv::TvIObserver { +public: + TvCallback(void *data) + { + mPri = data; + } + ~TvCallback() + { + } + void onTvEvent (int32_t msgType, const Parcel &p); +private: + void *mPri; +}; +#endif diff --git a/tv/tvserver/tvserver/tvserver.rc b/tv/tvserver/tvserver/tvserver.rc new file mode 100644 index 0000000..f1b8477 --- a/dev/null +++ b/tv/tvserver/tvserver/tvserver.rc @@ -0,0 +1,7 @@ +on post-fs + restorecon_recursive /param + +service tvd /vendor/bin/tvserver + class core + user root + group system diff --git a/tv/tvserver/tvtests/Android.mk b/tv/tvserver/tvtests/Android.mk new file mode 100644 index 0000000..66fd72c --- a/dev/null +++ b/tv/tvserver/tvtests/Android.mk @@ -0,0 +1,32 @@ +# Copyright (c) 2014 Amlogic, Inc. All rights reserved. +# +# This source code is subject to the terms and conditions defined in the +# file 'LICENSE' which is part of this source code package. +# +# Description: makefile + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LIB_TV_BINDER_PATH := $(LOCAL_PATH)/../../frameworks/libtvbinder + +LOCAL_SRC_FILES:= \ + android_tvtest.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libutils \ + libbinder \ + libtvbinder \ + libnativehelper \ + libandroid_runtime \ + liblog + +LOCAL_C_INCLUDES += \ + bionic/libc/include \ + $(LIB_TV_BINDER_PATH)/include + +LOCAL_MODULE:= tvtest + +include $(BUILD_EXECUTABLE) + diff --git a/tv/tvserver/tvtests/android_tvtest.cpp b/tv/tvserver/tvtests/android_tvtest.cpp new file mode 100644 index 0000000..a636003 --- a/dev/null +++ b/tv/tvserver/tvtests/android_tvtest.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "Tv-JNI" + +#include <utils/Log.h> +#include <TvClient.h> +#include <binder/IMemory.h> +#include <binder/Parcel.h> + +using namespace android; + +void usage(char *processname) +{ + fprintf(stderr, "Usage: %s <cmd num> [arg1]... [argn]\n", processname); + return; +} + + +int main(int argc, char **argv) +{ + if (argc < 2) + usage(argv[0]); + sp<TvClient> tv = TvClient::connect(); + int cmd = atoi(argv[1]); + int arg1 = atoi(argv[2]); + //send cmd + Parcel p, r; + p.writeInt32(cmd); + p.writeInt32(arg1); + tv->processCmd(p, &r); + //exit + tv.clear(); + return 0; +} diff --git a/tv/tvserver/tvtests/ssm_test.cpp b/tv/tvserver/tvtests/ssm_test.cpp new file mode 100644 index 0000000..e05fa15 --- a/dev/null +++ b/tv/tvserver/tvtests/ssm_test.cpp @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <android/log.h> + +#include "ssm_api.h" + +#define LOG_TAG "ssm_test" +#include "CTvLog.h" + +// The follow is R/W test struct declare. +// The size of it is 11 when it aligned with 1 Byte +// and is 16 when it aligned with 4 Bytes. +// You should use the 1 Byte aligned mode when R/W ssm by using struct. + +#if 1 // memory aligned with 1 Bytes +typedef struct tagS_TEST_STRUCT { + char tmp_ch0; + char tmp_ch1; + int tmp_val0; + unsigned char tmp_ch2; + unsigned char tmp_ch3; + unsigned char tmp_ch4; + short tmp_short0; +} __attribute__((packed)) S_TEST_STRUCT; +#else // memory aligned with 4 Bytes +typedef struct tagS_TEST_STRUCT { + char tmp_ch0; + char tmp_ch1; + int tmp_val0; + unsigned char tmp_ch2; + unsigned char tmp_ch3; + unsigned char tmp_ch4; + short tmp_short0; +} S_TEST_STRUCT; +#endif + +static void TestRWOneByte(int tmp_rw_offset, int tmp_w_val, unsigned char tmp_w_ch); +static void TestRWNBytes(int tmp_rw_offset); +static void TestRWOneStruct(int tmp_rw_offset); + +int main() +{ + TestRWOneByte(0, 1, -1); + TestRWOneByte(1, 2, -2); + TestRWOneByte(30, 3, -3); + TestRWOneByte(31, -1, 1); + TestRWOneByte(32, -2, 2); + TestRWOneByte(33, -3, 3); + + TestRWNBytes(31); + + TestRWOneStruct(0); +} + +static void TestRWOneByte(int tmp_rw_offset, int tmp_w_val, unsigned char tmp_w_ch) +{ + int tmp_r_val = 0; + unsigned char tmp_r_ch = 0; + + LOGD("\n\n"); + LOGD("**************Test R/W One Byte **************\n\n"); + + LOGD("tmp_rw_offset = %d.\n", tmp_rw_offset); + + SSMWriteOneByte(tmp_rw_offset, tmp_w_ch); + SSMReadOneByte(tmp_rw_offset, &tmp_r_ch); + LOGD("tmp_w_ch = %d, tmp_r_ch = %d.\n", tmp_w_ch, tmp_r_ch); + + SSMWriteOneByte(tmp_rw_offset, tmp_w_val); + SSMReadOneByte(tmp_rw_offset, &tmp_r_val); + LOGD("tmp_w_val = %d, tmp_r_val = %d.\n", tmp_w_val, tmp_r_val); +} + +static void TestRWNBytes(int tmp_rw_offset) +{ + int i = 0, tmp_op_buf_size = 0; + int device_size = 0, tmp_w_page_size = 0, tmp_r_page_size = 0; + int *tmp_op_int_w_buf = NULL, *tmp_op_int_r_buf = NULL; + unsigned char *tmp_op_char_w_buf = NULL, *tmp_op_char_r_buf = NULL; + + LOGD("\n\n"); + LOGD("**************Test R/W N Bytes **************\n\n"); + + SSMGetDeviceTotalSize(&device_size); + SSMGetDeviceWritePageSize(&tmp_w_page_size); + SSMGetDeviceReadPageSize(&tmp_r_page_size); + + if (tmp_w_page_size < tmp_r_page_size) { + tmp_op_buf_size = tmp_w_page_size * 2 / 3; + } else if (tmp_r_page_size < tmp_w_page_size) { + tmp_op_buf_size = tmp_r_page_size * 2 / 3; + } else { + tmp_op_buf_size = tmp_w_page_size; + } + + if (tmp_op_buf_size > device_size) { + tmp_op_buf_size = device_size; + } + + if (tmp_op_buf_size > 0) { + LOGD("tmp_rw_offset = %d.\n", tmp_rw_offset); + + tmp_op_char_w_buf = new unsigned char[tmp_op_buf_size]; + if (tmp_op_char_w_buf != NULL) { + tmp_op_char_r_buf = new unsigned char[tmp_op_buf_size]; + if (tmp_op_char_r_buf != NULL) { + for (i = 0; i < tmp_op_buf_size; i++) { + tmp_op_char_w_buf[i] = (tmp_op_buf_size / 2) - i; + LOGD("tmp_op_char_w_buf[%d] = %d\n", i, tmp_op_char_w_buf[i]); + } + SSMWriteNTypes(tmp_rw_offset, tmp_op_buf_size, tmp_op_char_w_buf); + + for (i = 0; i < tmp_op_buf_size; i++) { + tmp_op_char_r_buf[i] = 0; + } + SSMReadNTypes(tmp_rw_offset, tmp_op_buf_size, tmp_op_char_r_buf); + + for (i = 0; i < tmp_op_buf_size; i++) { + LOGD("tmp_op_char_r_buf[%d] = %d\n", i, tmp_op_char_r_buf[i]); + } + + delete tmp_op_char_r_buf; + tmp_op_char_r_buf = NULL; + } + + delete tmp_op_char_w_buf; + tmp_op_char_w_buf = NULL; + } + + tmp_op_int_w_buf = new int[tmp_op_buf_size]; + if (tmp_op_int_w_buf != NULL) { + tmp_op_int_r_buf = new int[tmp_op_buf_size]; + if (tmp_op_int_r_buf != NULL) { + for (i = 0; i < tmp_op_buf_size; i++) { + tmp_op_int_w_buf[i] = (tmp_op_buf_size / 2) - i; + LOGD("tmp_op_int_w_buf[%d] = %d\n", i, tmp_op_int_w_buf[i]); + } + SSMWriteNTypes(tmp_rw_offset, tmp_op_buf_size, tmp_op_int_w_buf); + + for (i = 0; i < tmp_op_buf_size; i++) { + tmp_op_int_r_buf[i] = 0; + } + SSMReadNTypes(tmp_rw_offset, tmp_op_buf_size, tmp_op_int_r_buf); + + for (i = 0; i < tmp_op_buf_size; i++) { + LOGD("tmp_op_int_r_buf[%d] = %d\n", i, tmp_op_int_r_buf[i]); + } + + delete tmp_op_int_r_buf; + tmp_op_int_r_buf = NULL; + } + + delete tmp_op_int_w_buf; + tmp_op_int_w_buf = NULL; + } + } +} + +static void TestRWOneStruct(int tmp_rw_offset) +{ + S_TEST_STRUCT TestWriteStruct, TestReadStruct; + + LOGD("\n\n"); + LOGD("**************Test R/W One Struct **************\n\n"); + + LOGD("tmp_rw_offset = %d.\n", tmp_rw_offset); + + TestWriteStruct.tmp_ch0 = -9; + TestWriteStruct.tmp_ch1 = -8; + TestWriteStruct.tmp_val0 = 9; + TestWriteStruct.tmp_ch2 = 255; + TestWriteStruct.tmp_ch3 = 254; + TestWriteStruct.tmp_ch4 = 250; + TestWriteStruct.tmp_short0 = -9; + + SSMWriteNTypes(tmp_rw_offset, sizeof(S_TEST_STRUCT), (unsigned char *) &TestWriteStruct); + + LOGD("\n\n"); + LOGD("write struct length = %d.\n", sizeof(S_TEST_STRUCT)); + LOGD("TestWriteStruct.tmp_ch0 = %d.\n", TestWriteStruct.tmp_ch0); + LOGD("TestWriteStruct.tmp_ch1 = %d.\n", TestWriteStruct.tmp_ch1); + LOGD("TestWriteStruct.tmp_val0 = %d.\n", TestWriteStruct.tmp_val0); + LOGD("TestWriteStruct.tmp_ch2 = %d.\n", TestWriteStruct.tmp_ch2); + LOGD("TestWriteStruct.tmp_ch3 = %d.\n", TestWriteStruct.tmp_ch3); + LOGD("TestWriteStruct.tmp_ch4 = %d.\n", TestWriteStruct.tmp_ch4); + LOGD("TestWriteStruct.tmp_short0 = %d.\n", TestWriteStruct.tmp_short0); + + TestReadStruct.tmp_ch0 = 0; + TestReadStruct.tmp_ch1 = 0; + TestReadStruct.tmp_val0 = 0; + TestReadStruct.tmp_ch2 = 0; + TestReadStruct.tmp_ch3 = 0; + TestWriteStruct.tmp_ch4 = 0; + TestWriteStruct.tmp_short0 = 0; + + SSMReadNTypes(tmp_rw_offset, sizeof(S_TEST_STRUCT), (unsigned char *) &TestReadStruct); + + LOGD("\n\n"); + LOGD("read struct length = %d.\n", sizeof(S_TEST_STRUCT)); + LOGD("TestReadStruct.tmp_ch0 = %d.\n", TestReadStruct.tmp_ch0); + LOGD("TestReadStruct.tmp_ch1 = %d.\n", TestReadStruct.tmp_ch1); + LOGD("TestReadStruct.tmp_val0 = %d.\n", TestReadStruct.tmp_val0); + LOGD("TestReadStruct.tmp_ch2 = %d.\n", TestReadStruct.tmp_ch2); + LOGD("TestReadStruct.tmp_ch3 = %d.\n", TestReadStruct.tmp_ch3); + LOGD("TestReadStruct.tmp_ch4 = %d.\n", TestReadStruct.tmp_ch4); + LOGD("TestReadStruct.tmp_short0 = %d.\n", TestReadStruct.tmp_short0); +} diff --git a/tv/tvserver/tvutils/Android.mk b/tv/tvserver/tvutils/Android.mk new file mode 100644 index 0000000..cc1e1c7 --- a/dev/null +++ b/tv/tvserver/tvutils/Android.mk @@ -0,0 +1,49 @@ +# Copyright (c) 2014 Amlogic, Inc. All rights reserved. +# +# This source code is subject to the terms and conditions defined in the +# file 'LICENSE' which is part of this source code package. +# +# Description: makefile + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LIB_VENDOR := $(wildcard $(BOARD_AML_VENDOR_PATH)) +LIB_SQLITE_PATH := $(wildcard external/sqlite) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + CFile.cpp \ + CTvLog.cpp \ + CMsgQueue.cpp \ + CSqlite.cpp \ + serial_base.cpp \ + serial_operate.cpp \ + tvutils.cpp \ + zepoll.cpp \ + tvconfig/CIniFile.cpp \ + tvconfig/tvconfig.cpp + +LOCAL_C_INCLUDES += \ + $(BOARD_AML_VENDOR_PATH)/frameworks/services/systemcontrol/PQ/include \ + $(BOARD_AML_VENDOR_PATH)/frameworks/services \ + $(LIB_SQLITE_PATH)/dist \ + $(BOARD_AML_VENDOR_PATH)/tv/tvserver/libtv/include \ + external/jsoncpp/include + +LOCAL_SHARED_LIBRARIES += \ + vendor.amlogic.hardware.systemcontrol@1.0_vendor \ + libsystemcontrolservice \ + liblog + +LOCAL_STATIC_LIBRARIES += \ + libjsoncpp + +LOCAL_MODULE:= libtv_utils + +ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK) +LOCAL_PROPRIETARY_MODULE := true +endif + +include $(BUILD_STATIC_LIBRARY) diff --git a/tv/tvserver/tvutils/CFile.cpp b/tv/tvserver/tvutils/CFile.cpp new file mode 100644 index 0000000..b7d9f74 --- a/dev/null +++ b/tv/tvserver/tvutils/CFile.cpp @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CFile" +//#define LOG_NDEBUG 0 + +#include "include/CFile.h" +#include "include/CTvLog.h" + +#include <stdlib.h> + +CFile::CFile() +{ + mPath[0] = '\0'; + mFd = -1; +} + +CFile::~CFile() +{ + closeFile(); +} + +CFile::CFile(const char *path) +{ + strcpy(mPath, path); + mFd = -1; +} + +int CFile::openFile(const char *path) +{ + LOGV("openFile = %s", path); + if (mFd < 0) { + const char *openPath = mPath; + if (path != NULL) + strcpy(mPath, path); + + if (strlen(openPath) <= 0) { + LOGW("openFile openPath is NULL, path:%s", path); + return -1; + } + mFd = open(openPath, O_RDWR); + if (mFd < 0) { + LOGW("open file(%s) fail", openPath); + return -1; + } + } + + return mFd; +} + +int CFile::closeFile() +{ + if (mFd > 0) { + close(mFd); + mFd = -1; + } + return 0; +} + +int CFile::writeFile(const unsigned char *pData, int uLen) +{ + int ret = -1; + if (mFd > 0) + ret = write(mFd, pData, uLen); + + return ret; +} + +int CFile::readFile(void *pBuf, int uLen) +{ + int ret = 0; + if (mFd > 0) { + ret = read(mFd, pBuf, uLen); + } + return ret; +} + +int CFile::copyTo(const char *dstPath) +{ + if (strlen(mPath) <= 0) + return -1; + int dstFd; + if (mFd == -1) { + if ((mFd = open(mPath, O_RDONLY)) == -1) { + LOGE("Open %s Error:%s/n", mPath, strerror(errno)); + return -1; + } + } + + if ((dstFd = open(dstPath, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) == -1) { + LOGE("Open %s Error:%s/n", dstPath, strerror(errno)); + } + + int bytes_read, bytes_write; + char buffer[BUFFER_SIZE]; + char *ptr; + int ret = 0; + while ((bytes_read = read(mFd, buffer, BUFFER_SIZE))) { + if ((bytes_read == -1) && (errno != EINTR)) { + ret = -1; + break; + } else if (bytes_read > 0) { + ptr = buffer; + while ((bytes_write = write(dstFd, ptr, bytes_read))) { + if ((bytes_write == -1) && (errno != EINTR)) { + ret = -1; + break; + } + else if (bytes_write == bytes_read) { + ret = 0; + break; + } + else if (bytes_write > 0) { + ptr += bytes_write; + bytes_read -= bytes_write; + } + } + if (bytes_write == -1) { + ret = -1; + break; + } + } + } + fsync(dstFd); + close(dstFd); + return ret; +} + + +int CFile::delFile(const char *path) +{ + if (strlen(path) <= 0) return -1; + if (unlink(path) != 0) { + LOGD("delete file(%s) err=%s", path, strerror(errno)); + return -1; + } + return 0; +} + +int CFile::delFile() +{ + if (strlen(mPath) <= 0) return -1; + if (unlink(mPath) != 0) { + LOGD("delete file(%s) err=%s", mPath, strerror(errno)); + return -1; + } + return 0; +} + + +int CFile::getFileAttrValue(const char *path) +{ + int value; + + int fd = open(path, O_RDONLY); + if (fd <= 0) { + LOGE("open (%s)ERROR!!error = -%s- \n", path, strerror ( errno )); + } + char s[8]; + read(fd, s, sizeof(s)); + close(fd); + value = atoi(s); + return value; +} + +int CFile::setFileAttrValue(const char *path, int value) +{ + FILE *fp = fopen ( path, "w" ); + + if ( fp == NULL ) { + LOGW ( "Open %s error(%s)!\n", path, strerror ( errno ) ); + return -1; + } + fprintf ( fp, "%d", value ); + fclose ( fp ); + return 0; +} + +int CFile::getFileAttrStr(const char *path __unused, char *str __unused) +{ + return 0; +} + +int CFile::setFileAttrStr(const char *path, const char *str) +{ + FILE *fp = fopen ( path, "w" ); + + if ( fp == NULL ) { + LOGW ( "Open %s error(%s)!\n", path, strerror ( errno ) ); + return -1; + } + fprintf ( fp, "%s", str ); + fclose ( fp ); + return 0; +} diff --git a/tv/tvserver/tvutils/CMsgQueue.cpp b/tv/tvserver/tvutils/CMsgQueue.cpp new file mode 100644 index 0000000..e355997 --- a/dev/null +++ b/tv/tvserver/tvutils/CMsgQueue.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CMessage" + +#include "include/CMsgQueue.h" +#include <include/CTvLog.h> +#include <utils/Timers.h> + +CMessage::CMessage() +{ + mDelayMs = 0; + mWhenMs = 0; +} + +CMessage::~CMessage() +{ +} + +CMsgQueueThread::CMsgQueueThread() +{ +} + +CMsgQueueThread::~CMsgQueueThread() +{ + requestExitAndWait(); +} + +nsecs_t CMsgQueueThread::getNowMs() +{ + return systemTime(SYSTEM_TIME_MONOTONIC) / 1000000; +} + +void CMsgQueueThread::sendMsg(CMessage &msg) +{ + AutoMutex _l(mLockQueue); + msg.mWhenMs = getNowMs() + msg.mDelayMs;// + int i = 0; + while (i < (int)m_v_msg.size() && m_v_msg[i].mWhenMs <= msg.mWhenMs) i++; //find the index that will insert(i) + m_v_msg.insertAt(msg, i);//insert at index i + CMessage msg1 = m_v_msg[0]; + LOGD("sendmsg now = %lld msg[0] when = %lld", getNowMs(), msg1.mWhenMs); + // + //if(i == 0)// is empty or new whenMS is at index 0, low all ms in list. so ,need to wakeup loop, to get new delay time. + mGetMsgCondition.signal(); +} + +void CMsgQueueThread::removeMsg(CMessage &msg) +{ + AutoMutex _l(mLockQueue); + int beforeSize = (int)m_v_msg.size(); + for (int i = 0; i < (int)m_v_msg.size(); i++) { + const CMessage &_msg = m_v_msg.itemAt(i); + if (_msg.mType == msg.mType) { + m_v_msg.removeAt(i); + } + } + //some msg removeed + if (beforeSize > (int)m_v_msg.size()) + mGetMsgCondition.signal(); +} + +void CMsgQueueThread::clearMsg() +{ + AutoMutex _l(mLockQueue); + m_v_msg.clear(); +} + +int CMsgQueueThread::startMsgQueue() +{ + AutoMutex _l(mLockQueue); + this->run("CMsgQueueThread"); + return 0; +} + +bool CMsgQueueThread::threadLoop() +{ + int sleeptime = 100;//ms + while (!exitPending()) { //requietexit() or requietexitWait() not call + mLockQueue.lock(); + while (m_v_msg.size() == 0) { //msg queue is empty + mGetMsgCondition.wait(mLockQueue);//first unlock,when return,lock again,so need,call unlock + } + mLockQueue.unlock(); + //get delay time + CMessage msg; + nsecs_t delayMs = 0, nowMS = 0; + do { //wait ,until , the lowest time msg's whentime is low nowtime, to go on + if (m_v_msg.size() <= 0) { + LOGD("msg size is 0, break"); + break; + } + mLockQueue.lock();//get msg ,first lock. + msg = m_v_msg[0];//get first + mLockQueue.unlock(); + + delayMs = msg.mWhenMs - getNowMs(); + if (delayMs > 0) { + mLockQueue.lock();//get msg ,first lock. + int ret = mGetMsgCondition.waitRelative(mLockQueue, delayMs); + mLockQueue.unlock(); + } else { + break; + } + } while (true); //msg[0], timeout + + if (m_v_msg.size() > 0) { + mLockQueue.lock();// + msg = m_v_msg[0]; + m_v_msg.removeAt(0); + mLockQueue.unlock();// + //handle it + handleMessage(msg); + } + + //usleep(sleeptime * 1000); + } + //exit + //return true, run again, return false,not run. + return false; +} diff --git a/tv/tvserver/tvutils/CSqlite.cpp b/tv/tvserver/tvutils/CSqlite.cpp new file mode 100644 index 0000000..7c685fd --- a/dev/null +++ b/tv/tvserver/tvutils/CSqlite.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CSqlite" + +#include "include/CSqlite.h" +#include "include/CTvLog.h" + +using namespace android; + +CSqlite::CSqlite() +{ + mHandle = NULL; +} + +CSqlite::~CSqlite() +{ +#ifdef SUPPORT_ADTV + if (mHandle != NULL) { + sqlite3_close(mHandle); + mHandle = NULL; + } +#endif +} + +bool CSqlite::integrityCheck() +{ +#ifdef SUPPORT_ADTV + char *err; + int rval = sqlite3_exec(mHandle, "PRAGMA integrity_check;", sqlite3_exec_callback, NULL, &err); + if (rval != SQLITE_OK) { + LOGE(" val = %d, msg = %s!\n", rval, sqlite3_errmsg(mHandle)); + return false; + } +#endif + return true; +} + +int CSqlite::sqlite3_exec_callback(void *data __unused, int nColumn, char **colValues __unused, char **colNames __unused) +{ + LOGD("sqlite3_exec_callback, nums = %d", nColumn); + //for (int i = 0; i < nColumn; i++) { + // LOGD("%s\t", colValues[i]); + //} + return 0; +} + +int CSqlite::openDb(const char *path) +{ +#ifdef SUPPORT_ADTV + if (sqlite3_open(path, &mHandle) != SQLITE_OK) { + LOGD("open db(%s) error", path); + mHandle = NULL; + return -1; + } +#endif + return 0; +} + +int CSqlite::closeDb() +{ + int rval = 0; +#ifdef SUPPORT_ADTV + if (mHandle != NULL) { + rval = sqlite3_close(mHandle); + mHandle = NULL; + } +#endif + return rval; +} + +void CSqlite::setHandle(sqlite3 *h) +{ + mHandle = h; +} + +sqlite3 *CSqlite::getHandle() +{ + return mHandle; +} + +int CSqlite::select(const char *sql, CSqlite::Cursor &c) +{ +#ifdef SUPPORT_ADTV + int col, row; + char **pResult = NULL; + char *errmsg; + assert(mHandle && sql); + + if (strncmp(sql, "select", 6)) + return -1; + //LOGD("sql=%s", sql); + if (sqlite3_get_table(mHandle, sql, &pResult, &row, &col, &errmsg) != SQLITE_OK) { + LOGD("errmsg=%s", errmsg); + if (pResult != NULL) + sqlite3_free_table(pResult); + return -1; + } + + //LOGD("row=%d, col=%d", row, col); + c.Init(pResult, row, col); +#endif + return 0; +} + +void CSqlite::insert() +{ +} + +bool CSqlite::exeSql(const char *sql) +{ +#ifdef SUPPORT_ADTV + char *errmsg; + if (sql == NULL) return false; + if (sqlite3_exec(mHandle, sql, NULL, NULL, &errmsg) != SQLITE_OK) { + LOGE("exeSql=: %s error=%s", sql, errmsg ? errmsg : "Unknown"); + if (errmsg) + sqlite3_free(errmsg); + return false; + } +#endif + //LOGD("sql=%s", sql); + return true; +} + +bool CSqlite::beginTransaction() +{ + return exeSql("begin;"); +} + +bool CSqlite::commitTransaction() +{ + return exeSql("commit;"); +} + +bool CSqlite::rollbackTransaction() +{ + return exeSql("rollback;"); +} + +void CSqlite::del() +{ +} + +void CSqlite::update() +{ +} + +void CSqlite::xxtable() +{ +} + diff --git a/tv/tvserver/tvutils/CTvLog.cpp b/tv/tvserver/tvutils/CTvLog.cpp new file mode 100644 index 0000000..5efd144 --- a/dev/null +++ b/tv/tvserver/tvutils/CTvLog.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#include "include/CTvLog.h" +#include <android/log.h> + +int __tv_log_print(int prio, const char *tag, const char *tv_tag, const char *fmt, ...) +{ + char buf[DEFAULT_LOG_BUFFER_LEN]; + sprintf(buf, "[%s]:", tv_tag); + int tv_tag_len = strlen(buf); + + va_list ap; + va_start(ap, fmt); + vsnprintf(buf + tv_tag_len, DEFAULT_LOG_BUFFER_LEN - tv_tag_len, fmt, ap); + + return __android_log_write(prio, tag, buf); +} + diff --git a/tv/tvserver/tvutils/include/CFile.h b/tv/tvserver/tvutils/include/CFile.h new file mode 100644 index 0000000..5a473c7 --- a/dev/null +++ b/tv/tvserver/tvutils/include/CFile.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef C_FILE_H +#define C_FILE_H + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#define CC_MAX_FILE_PATH_LEN (256) + +#define BUFFER_SIZE 1024 + +class CFile { +public: + CFile(const char *path); + CFile(); + virtual ~CFile(); + virtual int openFile(const char *path); + virtual int closeFile(); + virtual int writeFile(const unsigned char *pData, int uLen); + virtual int readFile(void *pBuf, int uLen); + int copyTo(const char *dstPath); + static int delFile(const char *path); + static int getFileAttrValue(const char *path); + static int setFileAttrValue(const char *path, int value); + static int getFileAttrStr(const char *path, char *str); + static int setFileAttrStr(const char *path, const char *str); + int delFile(); + int flush(); + int seekTo(); + int seekToBegin(); + int seekToEnd(); + int getLength(); + int getFd() + { + return mFd; + }; +protected: + char mPath[CC_MAX_FILE_PATH_LEN]; + int mFd; +}; +#endif diff --git a/tv/tvserver/tvutils/include/CIniFile.h b/tv/tvserver/tvutils/include/CIniFile.h new file mode 100644 index 0000000..6d578f5 --- a/dev/null +++ b/tv/tvserver/tvutils/include/CIniFile.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef INI_FILE_H_ +#define INI_FILE_H_ + +static const int MAX_INI_FILE_LINE_LEN = 512; + +typedef enum _LINE_TYPE { + LINE_TYPE_SECTION = 0, + LINE_TYPE_KEY, + LINE_TYPE_COMMENT, +} LINE_TYPE; + +typedef struct _LINE { + LINE_TYPE type; + char Text[MAX_INI_FILE_LINE_LEN]; + int LineLen; + char *pKeyStart; + char *pKeyEnd; + char *pValueStart; + char *pValueEnd; + struct _LINE *pNext; +} LINE; + +typedef struct _SECTION { + LINE *pLine; + struct _SECTION *pNext; +} SECTION; + + +class CIniFile { +public: + //const int MAX_SECTION_NAME_LEN = 16; + //const int MAX_KEY_NAME_LEN = 64; + //const int MAX_VALUE_LEN = 512; + + CIniFile(); + ~CIniFile(); + int LoadFromFile(const char *filename); + + int SaveToFile(const char *filename = NULL); + + int SetString(const char *section, const char *key, const char *value); + int SetInt(const char *section, const char *key, int value); + + const char *GetString(const char *section, const char *key, const char *def_value); + int GetInt(const char *section, const char *key, int def_value); + float GetFloat(const char *section, const char *key, float def_value); + int SetFloat(const char *section, const char *key, float value); + +private: + LINE_TYPE getLineType(char *Str); + void allTrim(char *Str); + + SECTION *getSection(const char *section); + LINE *getKeyLineAtSec(SECTION *pSec, const char *key); + + void FreeAllMem(); + int InsertSection(SECTION *pSec); + int InsertKeyLine(SECTION *pSec, LINE *line); + char mpFileName[256]; + FILE *m_pIniFile; + LINE *mpFirstLine; + SECTION *mpFirstSection; +}; +#endif //end of INI_FILE_H_ diff --git a/tv/tvserver/tvutils/include/CMsgQueue.h b/tv/tvserver/tvutils/include/CMsgQueue.h new file mode 100644 index 0000000..35ebd64 --- a/dev/null +++ b/tv/tvserver/tvutils/include/CMsgQueue.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#include <utils/Thread.h> +#include <utils/Vector.h> +using namespace android; +#if !defined(_C_MSG_QUEUE_H) +#define _C_MSG_QUEUE_H + +class CMessage { +public: + CMessage(); + ~CMessage(); + nsecs_t mDelayMs;//delay times , MS + nsecs_t mWhenMs;//when, the msg will handle + int mType; + void *mpData; + unsigned char mpPara[5120]; +}; + +class CMsgQueueThread: public Thread { +public: + CMsgQueueThread(); + virtual ~CMsgQueueThread(); + int startMsgQueue(); + void sendMsg(CMessage &msg); + void removeMsg(CMessage &msg); + void clearMsg(); +private: + bool threadLoop(); + nsecs_t getNowMs();//get system time , MS + virtual void handleMessage(CMessage &msg) = 0; + + // + Vector<CMessage> m_v_msg; + Condition mGetMsgCondition; + mutable Mutex mLockQueue; +}; + +/*class CHandler +{ + pubulic: + CHandler(CMsgQueueThread& msgQueue); + ~CHandler(); + void sendMsg(); + void removeMsg(); + private: + virtual void handleMessage(CMessage &msg); +};*/ + +#endif diff --git a/tv/tvserver/tvutils/include/CSqlite.h b/tv/tvserver/tvutils/include/CSqlite.h new file mode 100644 index 0000000..11a231a --- a/dev/null +++ b/tv/tvserver/tvutils/include/CSqlite.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#if !defined(_CSQLITE_H_) +#define _CSQLITE_H_ +#include <unistd.h> +#include <stdlib.h> +#include <utils/String8.h> +#include <utils/Vector.h> +#include <utils/RefBase.h> +#include <sqlite3.h> +using namespace android; +class CSqlite { +public: + class Cursor { + public: + void Init(char **data, int cow, int col) + { + if (mData != NULL) + sqlite3_free_table(mData); + + mData = data; + mCurRowIndex = 0; + mRowNums = cow; + mColNums = col; + mIsClosed = false; + } + Cursor() + { + mData = NULL; + mCurRowIndex = 0; + mRowNums = 0; + mColNums = 0; + mIsClosed = false; + } + + /*Cursor(Cursor& c) + { + data = c.data; + mCurRowIndex = 0; + mRowNums = c.mRowNums; + mColNums = c.mColNums; + mIsClosed = false; + } + + Cursor& operator = (const Cursor& c) + { + data = c.data; + mCurRowIndex = 0; + mRowNums = c.mRowNums; + mColNums = c.mColNums; + mIsClosed = false; + return *this; + }*/ + ~Cursor() + { + close(); + } + //Row nums + int getCount() + { + return mRowNums; + } + + int getPosition(); + + bool move(int offset); + + bool moveToPosition(int position); + + bool moveToFirst() + { + if (mRowNums <= 0) return false; + mCurRowIndex = 0; + return true; + } + + bool moveToLast(); + + bool moveToNext() + { + if (mCurRowIndex >= mRowNums - 1)return false; + mCurRowIndex++; + return true; + } + + bool moveToPrevious(); + + int getColumnIndex(const char *columnName) + { + int index = 0; + for (int i = 0; i < mColNums; i++) { + if (strcmp(columnName, mData[i]) == 0) + return index; + index++; + } + + return -1; + } + + //String getColumnName(int columnIndex); + //String[] getColumnNames(); + int getColumnCount(); + int getString(char *str, int columnIndex) + { + if (columnIndex >= mColNums || str == NULL) return -1; + strcpy(str, mData[mColNums * (mCurRowIndex + 1) + columnIndex]); + return 0; + } + String8 getString(int columnIndex) + { + if (columnIndex >= mColNums) return String8(""); + return String8(mData[mColNums * (mCurRowIndex + 1) + columnIndex]); + } + + int getInt(int columnIndex) + { + //if(columnIndex >= mColNums || str == NULL) return -1; + return atoi(mData[mColNums * (mCurRowIndex + 1) + columnIndex]); + } + unsigned long int getUInt(int columnIndex) + { + return strtoul(mData[mColNums * (mCurRowIndex + 1) + columnIndex], NULL, 10); + } + double getF(int columnIndex) + { + return atof(mData[mColNums * (mCurRowIndex + 1) + columnIndex]); + } + int getType(int columnIndex); + void close() + { + if (mData != NULL) + sqlite3_free_table(mData); + + mData = NULL; + mCurRowIndex = 0; + mRowNums = 0; + mIsClosed = true; + } + bool isClosed() + { + return mIsClosed; + } + private: + char **mData; + int mCurRowIndex; + int mRowNums; + int mColNums; + bool mIsClosed; + }; +public: + CSqlite(); + virtual ~CSqlite(); + int openDb(const char *path); + int closeDb(); + void setHandle(sqlite3 *h); + sqlite3 *getHandle(); + bool integrityCheck(); + int select(const char *sql, Cursor &); + bool exeSql(const char *sql); + void insert(); + void del(); + void update(); + void xxtable(); + bool beginTransaction(); + bool commitTransaction(); + bool rollbackTransaction(); + void dbsync() + { + sync(); + }; +private: + static int sqlite3_exec_callback(void *data, int nColumn, char **colValues, char **colNames); + sqlite3 *mHandle; +}; +#endif //CSQLITE diff --git a/tv/tvserver/tvutils/include/CTvLog.h b/tv/tvserver/tvutils/include/CTvLog.h new file mode 100644 index 0000000..e1ac93b --- a/dev/null +++ b/tv/tvserver/tvutils/include/CTvLog.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#include <utils/Log.h> +#include <string.h> + +#ifndef _C_TV_LOG_H_ +#define _C_TV_LOG_H_ + + +//1024 + 128 +#define DEFAULT_LOG_BUFFER_LEN 1152 + +extern int __tv_log_print(int prio, const char *tag, const char *tv_tag, const char *fmt, ...); + +#ifdef LOG_TV_TAG +#ifndef LOGD +#define LOGD(...) \ + __tv_log_print(ANDROID_LOG_DEBUG, LOG_TAG, LOG_TV_TAG, __VA_ARGS__) +#endif + +#ifndef LOGE +#define LOGE(...) \ + __tv_log_print(ANDROID_LOG_ERROR, LOG_TAG, LOG_TV_TAG, __VA_ARGS__) +#endif + +#ifndef LOGW +#define LOGW(...) \ + __tv_log_print(ANDROID_LOG_WARN, LOG_TAG, LOG_TV_TAG, __VA_ARGS__) +#endif + +#if LOG_NDEBUG +#define LOGV(...) \ + do {if (0) { __tv_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, LOG_TV_TAG, __VA_ARGS__);} } while(0) +#else +#define LOGV(...) \ + __tv_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, LOG_TV_TAG, __VA_ARGS__) +#endif + +#else +#define LOGD(...) ALOGD(__VA_ARGS__) +#define LOGE(...) ALOGE(__VA_ARGS__) +#define LOGV(...) ALOGV(__VA_ARGS__) +#define LOGW(...) ALOGW(__VA_ARGS__) +#endif//end #ifdef LOG_TV_TAG + +#endif//end #ifndef _C_TV_LOG_H_ diff --git a/tv/tvserver/tvutils/include/serial_base.h b/tv/tvserver/tvutils/include/serial_base.h new file mode 100644 index 0000000..9afd6aa --- a/dev/null +++ b/tv/tvserver/tvutils/include/serial_base.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __SERIAL_BASE_H__ +#define __SERIAL_BASE_H__ + +extern int com_a_open_dev(); +extern int com_b_open_dev(); +extern int com_a_close_dev(); +extern int com_b_close_dev(); +extern int com_a_get_dev(); +extern int com_b_get_dev(); +extern int com_a_set_opt(int speed, int db, int sb, int pb, int timeout, int raw_mode); +extern int com_b_set_opt(int speed, int db, int sb, int pb, int timeout, int raw_mode); +extern int com_a_write_data(const unsigned char *pData, unsigned int uLen); +extern int com_b_write_data(const unsigned char *pData, unsigned int uLen); +extern int com_a_read_data(char *pData, unsigned int uLen); +extern int com_b_read_data(char *pData, unsigned int uLen); + +#endif//__SERIAL_BASE_H__ diff --git a/tv/tvserver/tvutils/include/serial_operate.h b/tv/tvserver/tvutils/include/serial_operate.h new file mode 100644 index 0000000..5109d03 --- a/dev/null +++ b/tv/tvserver/tvutils/include/serial_operate.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __SERIAL_OPERATE_H__ +#define __SERIAL_OPERATE_H__ +#include <utils/Thread.h> + +using namespace android; +class CTv2d4GHeadSetDetect: public Thread { + +public: + CTv2d4GHeadSetDetect(); + ~CTv2d4GHeadSetDetect(); + + int startDetect(); + + class IHeadSetObserver { + public: + IHeadSetObserver() {}; + virtual ~IHeadSetObserver() {}; + virtual void onHeadSetDetect(int state __unused, int para __unused) { + }; + virtual void onThermalDetect(int state __unused) { + }; + }; + + void setObserver ( IHeadSetObserver *pOb ) { + mpObserver = pOb; + }; + +private: + bool threadLoop(); + IHeadSetObserver *mpObserver; + +}; + +#endif//__SERIAL_OPERATE_H__ diff --git a/tv/tvserver/tvutils/include/tvconfig.h b/tv/tvserver/tvutils/include/tvconfig.h new file mode 100644 index 0000000..ee02e93 --- a/dev/null +++ b/tv/tvserver/tvutils/include/tvconfig.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef __TVCONFIG_API_H__ +#define __TVCONFIG_API_H__ + +#define CC_CFG_KEY_STR_MAX_LEN (128) +#define CC_CFG_VALUE_STR_MAX_LEN (512) + +//for tv config +#define CFG_SECTION_TV "TV" +#define CFG_SECTION_ATV "ATV" +#define CFG_SECTION_SRC_INPUT "SourceInputMap" +#define CFG_SECTION_SETTING "SETTING" +#define CFG_SECTION_FBCUART "FBCUART" + +#define CFG_BLUE_SCREEN_COLOR "tvin.bluescreen.color" + +#define CGF_DEFAULT_INPUT_IDS "tv.source.input.ids.default" +#define CGF_DEFAULT_HDMI_PORTS "tv.source.input.hdmi.ports" +#define CFG_DTV_MODE "dtv.mode" +#define CFG_SSM_HDMI_AV_DETECT "ssm.hdmi_av.hotplug.detect.en" +#define CFG_SSM_HDMI_EDID_EN "ssm.handle.hdmi.edid.en" + +#define CFG_ATV_FREQ_LIST "atv.get.min.max.freq" +#define CFG_DTV_SCAN_SORT_MODE "dtv.scan.sort.mode" +#define CFG_DTV_CHECK_SCRAMBLE_MODE "dtv.check.scramble.mode" + +#define CFG_TVIN_KERNELPET_DISABLE "tvin.kernelpet_disable" +#define CFG_TVIN_KERNELPET_TIMEROUT "tvin.kernelpet.timeout" +#define CFG_TVIN_USERPET "tvin.userpet" +#define CFG_TVIN_USERPET_TIMEROUT "tvin.userpet.timeout" +#define CFG_TVIN_USERPET_RESET "tvin.userpet.reset" + +#define CFG_TVIN_DISPLAY_FREQ_AUTO "tvin.autoset.displayfreq" +#define CFG_TVIN_DB_REG "tvin.db.reg.en" +#define CFG_TVIN_THERMAL_THRESHOLD_ENABLE "tvin.thermal.threshold.enable" +#define CFG_TVIN_THERMAL_THRESHOLD_VALUE "tvin.thermal.threshold.value" +#define CFG_TVIN_THERMAL_FBC_NORMAL_VALUE "tvin.thermal.fbc.normal.value" +#define CFG_TVIN_THERMAL_FBC_COLD_VALUE "tvin.thermal.fbc.cold.value" +#define CFG_TVIN_ATV_DISPLAY_SNOW "tvin.atv.display.snow" + +#define CFG_AUDIO_SRS_SOURROUND_GAIN "audio.srs.sourround.gain" +#define CFG_AUDIO_SRS_INPUT_GAIN "audio.srs.input.gain" +#define CFG_AUDIO_SRS_OUTPUT_GAIN "audio.srs.output.gain" +#define CFG_AUDIO_SRS_TRUBASS_GAIN "audio.srs.trubass.gain" +#define CFG_AUDIO_SRS_TRUBASS_SPEAKERSIZE "audio.srs.trubass.speakersize" +#define CFG_AUDIO_SRS_CLARITY_GAIN "audio.srs.dialogclarity.gain" +#define CFG_AUDIO_SRS_DEFINITION_GAIN "audio.srs.definition.gain" +#define CFG_AUDIO_SRS_SOURROUND_MASTER_GAIN "audio.srs.sourround.ampmaster.gain" +#define CFG_AUDIO_SRS_CLARITY_MASTER_GAIN "audio.srs.dialogclarity.ampmaster.gain" +#define CFG_AUDIO_SRS_TRUBASS_MASTER_GAIN "audio.srs.trubass.ampmaster.gain" +#define CFG_AUDIO_SRS_TRUBASS_CLARITY_MASTER_GAIN "audio.srs.trubass.dialogclarity.ampmaster.gain" + +#define CFG_AUDIO_PRE_GAIN_FOR_ATV "audio.pre.gain.for.atv" +#define CFG_AUDIO_PRE_GAIN_FOR_DTV "audio.pre.gain.for.dtv" +#define CFG_AUDIO_PRE_GAIN_FOR_AV "audio.pre.gain.for.av" +#define CFG_AUDIO_PRE_GAIN_FOR_HDMI "audio.pre.gain.for.hdmi" +#define CFG_AUDIO_MASTER_VOL "audio.master.vol" +#define CFG_AUDIO_BALANCE_MAX_VOL "audio.balance.max.vol" + +#define CFG_FBC_PANEL_INFO "fbc.get.panelinfo" +#define CFG_FBC_USED "platform.havefbc" + +#define CFG_CAHNNEL_DB "tv.channel.db" +#define DEF_VALUE_CAHNNEL_DB "/param/dtv.db" + +//for tv property +#define PROP_DEF_CAPTURE_NAME "snd.card.default.card.capture" +#define PROP_AUDIO_CARD_NUM "snd.card.totle.num" + +#define UBOOTENV_OUTPUTMODE "ubootenv.var.outputmode" +#define UBOOTENV_HDMIMODE "ubootenv.var.hdmimode" +#define UBOOTENV_LCD_REVERSE "ubootenv.var.lcd_reverse" +#define UBOOTENV_CONSOLE "ubootenv.var.console" +#define UBOOTENV_PROJECT_INFO "ubootenv.var.project_info" +#define UBOOTENV_AMPINDEX "ubootenv.var.ampindex" + +//for tv sysfs +#define SYS_SPDIF_MODE_DEV_PATH "/sys/class/audiodsp/digital_raw" +#define SYS_VECM_DNLP_ADJ_LEVEL "/sys/module/am_vecm/parameters/dnlp_adj_level" + +#define SYS_AUIDO_DSP_AC3_DRC "/sys/class/audiodsp/ac3_drc_control" +#define SYS_AUIDO_DIRECT_RIGHT_GAIN "/sys/class/amaudio2/aml_direct_right_gain" +#define SYS_AUIDO_DIRECT_LEFT_GAIN "/sys/class/amaudio2/aml_direct_left_gain" + +#define SYS_VIDEO_FRAME_HEIGHT "/sys/class/video/frame_height" +#define SYS_VIDEO_SCALER_PATH_SEL "/sys/class/video/video_scaler_path_sel" + +#define SYS_DROILOGIC_DEBUG "/sys/class/amlogic/debug" +#define SYS_ATV_DEMOD_DEBUG "/sys/class/amlatvdemod/atvdemod_debug" + +#define SYS_SCAN_TO_PRIVATE_DB "tuner.device.scan.to.private.db.en" +#define CFG_AUDIO_VIRTUAL_ENABLE "audio.virtual.enable" +#define CFG_AUDIO_VIRTUAL_LEVEL "audio.virtual.level" + +extern int tv_config_load(const char *file_name); +extern int tv_config_unload(); +extern int tv_config_save(); + +//[TV] section +extern int config_set_str(const char *section, const char *key, const char *value); +extern const char *config_get_str(const char *section, const char *key, const char *def_value); +extern int config_get_int(const char *section, const char *key, const int def_value); +extern int config_set_int(const char *section, const char *key, const int value); +extern float config_get_float(const char *section, const char *key, const float def_value); +extern int config_set_float(const char *section, const char *key, const int value); + +#endif //__TVCONFIG_API_H__ diff --git a/tv/tvserver/tvutils/include/tvutils.h b/tv/tvserver/tvutils/include/tvutils.h new file mode 100644 index 0000000..80ee478 --- a/dev/null +++ b/tv/tvserver/tvutils/include/tvutils.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef _TV_UTILS_H_ +#define _TV_UTILS_H_ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <utils/Mutex.h> +#include <string> +#include <map> +#include "PQType.h" + +#ifndef DVB_SUCCESS +#define DVB_SUCCESS (0) +#endif + +#ifndef DVB_FAILURE +#define DVB_FAILURE (-1) +#endif + +#define SYS_STR_LEN 1024 +#define AUDIO_OUTMODE_PATH "/sys/module/atvdemod_fe/parameters/aud_mode" +#define ATVDEMODE_DEBUG_PATH "/sys/class/amlatvdemod/atvdemod_debug" +#define AUDIO_STREAM_OUTMODE_PATH "/sys/module/atvdemod_fe/parameters/signal_audmode" + +int tvReadSysfs(const char *path, char *value); +int tvWriteSysfs(const char *path, const char *value); +int tvWriteSysfs(const char *path, int value, int base=10); +int tvWriteDisplayMode(const char *mode); +//add for PQ +int tvResetLastVppSettingsSourceType(void); +int tvLoadPQSettings(source_input_param_t source_input_param); +int tvLoadCpqLdimRegs(void); +int tvSSMReadNTypes(int id, int data_len, int *data_buf, int offset); +int tvSSMWriteNTypes(int id, int data_len, int data_buf, int offset); +int tvGetActualAddr(int id); +int tvGetActualSize(int id); + +int tvSetPQMode ( vpp_picture_mode_t mode, int is_save, int is_autoswitch); +vpp_picture_mode_t tvGetPQMode ( void ); +int tvSavePQMode ( vpp_picture_mode_t mode); +int tvGetPQParams(source_input_param_t source_input_param, vpp_picture_mode_t pq_mode, vpp_pq_para_t *pq_para); +int tvGetAutoSwitchPCModeFlag(void); + +int tvSetBrightness ( int brightness, int is_save ); +int tvGetBrightness ( void ); +int tvSaveBrightness ( int brightness); +int tvSetContrast ( int contrast, int is_save ); +int tvGetContrast ( void ); +int tvSaveContrast ( int contrast ); +int tvSetSaturation ( int satuation, int is_save ); +int tvGetSaturation ( void ); +int tvSaveSaturation ( int satuation ); +int tvSetHue ( int hue, int is_save ); +int tvGetHue ( void ); +int tvSaveHue ( int hue ); +int tvSetSharpness ( int value, int en, int is_save ); +int tvGetSharpness ( void ); +int tvSaveSharpness ( int value ); +int tvSetColorTemperature ( vpp_color_temperature_mode_t mode, int is_save ); +int tvGetColorTemperature ( void ); +int tvSaveColorTemperature ( vpp_color_temperature_mode_t mode ); +int tvSetColorTemperatureParams(vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t params); +int tvGetColorTemperatureParams(vpp_color_temperature_mode_t Tempmode, pq_color_param_t id); +int tvSaveColorTemperatureParams(vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t params); +int tvSetNoiseReductionMode ( vpp_noise_reduction_mode_t mode, int is_save ); +int tvGetNoiseReductionMode ( void ); +int tvSaveNoiseReductionMode ( vpp_noise_reduction_mode_t mode ); +int tvSetGamma(int gamma_curve, int is_save); +int tvGetGamma(void); +int tvSetEyeProtectionMode(source_input_param_t source_input_param, int enable); +int tvGetEyeProtectionMode(void); +int tvGetDisplayMode(source_input_param_t source_input_param); +int tvFactoryResetNonlinear(void); +int tvGetOverscanParam(source_input_param_t source_input_param, tvin_cutwin_param_t id); + +int tvFactoryResetPQMode(void); +int tvFactoryResetColorTemp(void); +int tvFactorySetPQParam(source_input_param_t source_input_param, int pq_mode, vpp_pq_param_t id, int value); +int tvFactoryGetPQParam(source_input_param_t source_input_param, int pq_mode, vpp_pq_param_t id); +int tvFactorySetColorTemperatureParam(int colortemperature_mode, pq_color_param_t id, int value); +int tvFactoryGetColorTemperatureParam(int colortemperature_mode, pq_color_param_t id); +int tvFactorySaveColorTemperatureParam(int colortemperature_mode, pq_color_param_t id, int value); +int tvFactorySetOverscanParam(source_input_param_t source_input_param, tvin_cutwin_t cutwin_t); +int tvFactoryGetOverscanParam(source_input_param_t source_input_param, int id); +int tvFactorySetNolineParams(source_input_param_t source_input_param, int type, noline_params_t noline_params); +int tvFactoryGetNolineParams(source_input_param_t source_input_param, int type, int id); +int tvFactorySetGamma(int gamma_r, int gamma_g, int gamma_b); +int tvFactorySetParamsDefault(void); +int tvFactorySSMRestore(void); +int tvSSMRecovery(void); +int tvGetSSMStatus(void); +int tvSetPLLValues(source_input_param_t source_input_param); +int tvSetCVD2Values(source_input_param_t source_input_param); +int tvSetPQConfig(Set_Flag_Cmd_t id, int value); +int tvSetCurrentSourceInfo(tv_source_input_t tv_source_input, tv_source_input_type_t source_type,tvin_port_t source_port, + tvin_sig_fmt_t sig_fmt, is_3d_type_t is3d, tvin_trans_fmt_t trans_fmt); + +//PQ end + +extern int Tv_MiscRegs(const char *cmd); + +extern int TvMisc_SetLVDSSSC(int val); +extern int TvMisc_SetUserCounterTimeOut(int timeout); +extern int TvMisc_SetUserCounter(int count); +extern int TvMisc_SetUserPetResetEnable(int enable); +extern int TvMisc_SetSystemPetResetEnable(int enable); +extern int TvMisc_SetSystemPetEnable(int enable); +extern int TvMisc_SetSystemPetCounter(int count); +extern int SetAudioOutmode(int mode); +extern int GetAudioOutmode(); +extern int GetAudioStreamOutmode(); + +extern void TvMisc_EnableWDT(bool kernelpet_disable, unsigned int userpet_enable, unsigned int kernelpet_timeout, unsigned int userpet_timeout, unsigned int userpet_reset); +extern void TvMisc_DisableWDT(unsigned int userpet_enable); +extern int GetTvDBDefineSize(); + +extern int Set_Fixed_NonStandard(int value); + + +extern int TvMisc_DeleteDirFiles(const char *strPath, int flag); + +extern bool isFileExist(const char *file_name); +extern int GetPlatformHaveDDFlag(); +extern int getBootEnv(const char *key, char *value, const char *def_val); +extern void setBootEnv(const char *key, const char *value); +extern int readSysfs(const char *path, char *value); +extern void writeSysfs(const char *path, const char *value); +extern int GetFileAttrIntValue(const char *fp, int flag = O_RDWR); + +template<typename T1, typename T2> +int ArrayCopy(T1 dst_buf[], T2 src_buf[], int copy_size) +{ + int i = 0; + + for (i = 0; i < copy_size; i++) { + dst_buf[i] = src_buf[i]; + } + + return 0; +}; + + +typedef std::map<std::string, std::string> STR_MAP; + +extern void jsonToMap(STR_MAP &m, const std::string &j); +extern void mapToJson(std::string &j, const STR_MAP &m); +extern void mapToJson(std::string &j, const STR_MAP &m, const std::string &k); +extern void mapToJsonAppend(std::string &j, const STR_MAP &m, const std::string &k); + +class Paras { +protected: + STR_MAP mparas; + +public: + Paras() {} + Paras(const Paras ¶s):mparas(paras.mparas) {} + Paras(const char *paras) { jsonToMap(mparas, std::string(paras)); } + Paras(const STR_MAP ¶s):mparas(paras) {} + + void clear() { mparas.clear(); } + + int getInt (const char *key, int def) const; + void setInt(const char *key, int v); + + const std::string toString() { std::string s; mapToJson(s, mparas); return s; } + + Paras operator + (const Paras &p); + Paras& operator = (const Paras &p) { mparas = p.mparas; return *this; }; +}; + +float getUptimeSeconds(); + +extern int jsonGetInt(const char *json, const char *obj, const char *value, int def); +extern const std::string jsonGetString(const char *json, const char *obj, const char *value, const char *def); + +extern int paramGetInt(const char *param, const char *section, const char *value, int def); +extern const std::string paramGetString(const char *param, const char *section, const char *value, const char *def); + +inline const char *toReadable(const char *s) { return s? s : "null"; } + +extern bool propertyGetBool(const char *prop, bool def); + +#endif //__TV_MISC_H__ diff --git a/tv/tvserver/tvutils/include/zepoll.h b/tv/tvserver/tvutils/include/zepoll.h new file mode 100644 index 0000000..2b97861 --- a/dev/null +++ b/tv/tvserver/tvutils/include/zepoll.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: header file + */ + +#ifndef EPOLL_H +#define EPOLL_H + +#include <sys/epoll.h> +#include <unistd.h> + +class Epoll { +public: + /** + * + */ + enum EPOLL_OP {ADD = EPOLL_CTL_ADD, MOD = EPOLL_CTL_MOD, DEL = EPOLL_CTL_DEL}; + + Epoll(int _max = 30, int maxevents = 20); + ~Epoll(); + int create(); + int add(int fd, epoll_event *event); + int mod(int fd, epoll_event *event); + int del(int fd, epoll_event *event); + void setTimeout(int timeout); + void setMaxEvents(int maxevents); + int wait(); + const epoll_event *events() const; + const epoll_event &operator[](int index) + { + return backEvents[index]; + } +private: + bool isValid() const; + int max; + int epoll_fd; + int epoll_timeout; + int epoll_maxevents; + epoll_event *backEvents; +}; + + + + +#endif //EPOLL_H + diff --git a/tv/tvserver/tvutils/serial_base.cpp b/tv/tvserver/tvutils/serial_base.cpp new file mode 100644 index 0000000..a593db8 --- a/dev/null +++ b/tv/tvserver/tvutils/serial_base.cpp @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "serial_base" + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <pthread.h> +#include <termios.h> +#include <errno.h> + +#include "include/serial_base.h" +#include "include/CTvLog.h" + +#define CS_SERIAL_A_DEV_PATH "/dev/ttyS0" +#define CS_SERIAL_B_DEV_PATH "/dev/ttyS1" + +static int gSerialAHandle = -1; +static pthread_mutex_t serial_a_op_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t serial_a_r_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t serial_a_w_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t serial_a_speed_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t serial_a_parity_mutex = PTHREAD_MUTEX_INITIALIZER; + +static int gSerialBHandle = -1; +static pthread_mutex_t serial_b_op_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t serial_b_r_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t serial_b_w_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t serial_b_speed_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t serial_b_parity_mutex = PTHREAD_MUTEX_INITIALIZER; + +static int speed_arr[] = { B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, }; +static int name_arr[] = { 115200, 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, }; + +static int open_com_dev(int *dev_handle, char *dev_path) +{ + if (*dev_handle < 0) { + *dev_handle = open(dev_path, O_RDWR); + if (*dev_handle < 0) { + LOGE("%s, Can't Open Serial Port %s", "TV", dev_path); + } + } + + return *dev_handle; +} + +static int close_com_dev(int *dev_handle) +{ + if (*dev_handle >= 0) { + close(*dev_handle); + *dev_handle = -1; + } + + return 0; +} + +static __inline__ int cfsetdatabits(struct termios *s, int db) +{ + if (db == 5) { + s->c_cflag = (s->c_cflag & ~CSIZE) | (CS5 & CSIZE); + } else if (db == 6) { + s->c_cflag = (s->c_cflag & ~CSIZE) | (CS6 & CSIZE); + } else if (db == 7) { + s->c_cflag = (s->c_cflag & ~CSIZE) | (CS7 & CSIZE); + } else if (db == 8) { + s->c_cflag = (s->c_cflag & ~CSIZE) | (CS8 & CSIZE); + } else { + LOGE("%s, Unsupported data size!\n", "TV"); + } + + return 0; +} + +static __inline__ int cfsetstopbits(struct termios *s, int sb) +{ + if (sb == 1) { + s->c_cflag &= ~CSTOPB; + } else if (sb == 2) { + s->c_cflag |= CSTOPB; + } else { + LOGE("%s, Unsupported stop bits!\n", "TV"); + } + + return 0; +} + +static __inline__ int cfsetparity(struct termios *s, int pb) +{ + if (pb == 'n' || pb == 'N') { + s->c_cflag &= ~PARENB; /* Clear parity enable */ + s->c_cflag &= ~INPCK; /* Enable parity checking */ + } else if (pb == 'o' || pb == 'O') { + s->c_cflag |= (PARODD | PARENB); + s->c_cflag |= INPCK; /* Disable parity checking */ + } else if (pb == 'e' || pb == 'E') { + s->c_cflag |= PARENB; /* Enable parity */ + s->c_cflag &= ~PARODD; + s->c_iflag |= INPCK; /* Disable parity checking */ + } else if (pb == 's' || pb == 'S') { + s->c_cflag &= ~PARENB; + s->c_cflag &= ~CSTOPB; + s->c_cflag |= INPCK; /* Disable parity checking */ + } else { + LOGE("%s, Unsupported parity!\n", "TV"); + } + + return 0; +} + +static int gOriAttrGetFlag = 0; +static struct termios gOriAttrValue; +static __inline__ int com_get_attr(int fd, struct termios *s) +{ + if (gOriAttrGetFlag == 0) { + if (tcgetattr(fd, s) != 0) { + return -1; + } + + gOriAttrGetFlag = 1; + gOriAttrValue = *s; + } + + *s = gOriAttrValue; + + return 0; +} + +static int com_set_opt(int hComm, int speed, int db, int sb, int pb, int to, int raw_mode) +{ + int i = 0; + struct termios tmpOpt; + + if (com_get_attr(hComm, &tmpOpt) != 0) { + LOGE("%s, get serial attr error(%s)!\n", "TV", strerror(errno)); + return -1; + } + + for (i = 0; i < (int)(sizeof(speed_arr) / sizeof(int)); i++) { + if (speed == name_arr[i]) { + cfsetispeed(&tmpOpt, speed_arr[i]); + cfsetospeed(&tmpOpt, speed_arr[i]); + break; + } + } + + cfsetdatabits(&tmpOpt, db); + cfsetstopbits(&tmpOpt, sb); + cfsetparity(&tmpOpt, pb); + + if (to >= 0) { + tmpOpt.c_cc[VTIME] = to; + tmpOpt.c_cc[VMIN] = 0; /* Update the options and do it NOW */ + } + + if (raw_mode == 1) { + cfmakeraw(&tmpOpt); + } + + tcflush(hComm, TCIOFLUSH); + if (tcsetattr(hComm, TCSANOW, &tmpOpt) < 0) { + LOGE("%s, set serial attr error(%s)!\n", "TV", strerror(errno)); + return -1; + } + tcflush(hComm, TCIOFLUSH); + + return 0; +} + +static int com_write_data(int hComm, const unsigned char *pData, unsigned int uLen) +{ + unsigned int len; + + if (hComm < 0) { + return -1; + } + + if (pData == NULL) { + return -1; + } + + LOGD("%s, write %d bytes\n", "TV", uLen); + + len = write(hComm, pData, uLen); + if (len == uLen) { + LOGD("%s, write data success\n", "TV"); + return len; + } else { + tcflush(hComm, TCOFLUSH); + LOGE("%s, write data failed and tcflush hComm\n", "TV"); + return -1; + } +} + +static int com_read_data(int hComm, char *pData, unsigned int uLen) +{ + char inbuff[uLen]; + char buff[uLen]; + char tempbuff[uLen]; + int i = 0, j = 0; + + memset(inbuff, '\0', uLen); + memset(buff, '\0', uLen); + memset(tempbuff, '\0', uLen); + + if (hComm < 0) { + return -1; + } + + char *p = inbuff; + + fd_set readset; + struct timeval tv; + int MaxFd = 0; + + unsigned int c = 0; + int z, k; + + do { + FD_ZERO(&readset); + FD_SET(hComm, &readset); + MaxFd = hComm + 1; + tv.tv_sec = 0; + tv.tv_usec = 100000; + do { + z = select(MaxFd, &readset, 0, 0, &tv); + } while (z == -1 && errno == EINTR); + + if (z == -1) { + hComm = -1; + break; + } + + if (z == 0) { + hComm = -1; + break; + } + + if (FD_ISSET(hComm, &readset)) { + z = read(hComm, buff, uLen - c); +#if 0 + for (k = 0; k < z; k++) { + LOGD("%s, inbuff[%d]:%02X", "TV", k, buff[k]); + } +#endif + c += z; + + if (z > 0) { + if (z < (signed int) uLen) { + buff[z + 1] = '\0'; + memcpy(p, buff, z); + p += z; + } else { + memcpy(inbuff, buff, z); + } + + memset(buff, '\0', uLen); + } else { + hComm = -1; + } + + if (c >= uLen) { + hComm = -1; + break; + } + } + } while (hComm >= 0); + + memcpy(pData, inbuff, c); + p = NULL; + return c; +} + +int com_a_open_dev() +{ + int tmp_ret = 0; + + pthread_mutex_lock(&serial_a_op_mutex); + + tmp_ret = open_com_dev(&gSerialAHandle, (char *)CS_SERIAL_A_DEV_PATH); + + pthread_mutex_unlock(&serial_a_op_mutex); + + return tmp_ret; +} + +int com_b_open_dev() +{ + int tmp_ret = 0; + + pthread_mutex_lock(&serial_b_op_mutex); + + tmp_ret = open_com_dev(&gSerialBHandle, (char *)CS_SERIAL_B_DEV_PATH); + + pthread_mutex_unlock(&serial_b_op_mutex); + + return tmp_ret; +} + +int com_a_close_dev() +{ + int tmp_ret = 0; + + pthread_mutex_lock(&serial_a_op_mutex); + + tmp_ret = close_com_dev(&gSerialAHandle); + + pthread_mutex_unlock(&serial_a_op_mutex); + + return tmp_ret; +} + +int com_b_close_dev() +{ + int tmp_ret = 0; + + pthread_mutex_lock(&serial_b_op_mutex); + + tmp_ret = close_com_dev(&gSerialBHandle); + + pthread_mutex_unlock(&serial_b_op_mutex); + + return tmp_ret; +} + +int com_a_get_dev() +{ + int tmp_ret = 0; + + pthread_mutex_lock(&serial_a_op_mutex); + + tmp_ret = gSerialAHandle; + + pthread_mutex_unlock(&serial_a_op_mutex); + + return tmp_ret; +} + +int com_b_get_dev() +{ + int tmp_ret = 0; + + pthread_mutex_lock(&serial_b_op_mutex); + + tmp_ret = gSerialBHandle; + + pthread_mutex_unlock(&serial_b_op_mutex); + + return tmp_ret; +} + +int com_a_set_opt(int speed, int db, int sb, int pb, int to, int raw_mode) +{ + int tmp_ret = 0; + + pthread_mutex_lock(&serial_a_parity_mutex); + + if (com_a_get_dev() < 0) { + pthread_mutex_unlock(&serial_a_parity_mutex); + return -1; + } + + tmp_ret = com_set_opt(gSerialAHandle, speed, db, sb, pb, to, raw_mode); + + pthread_mutex_unlock(&serial_a_parity_mutex); + + return tmp_ret; +} + +int com_b_set_opt(int speed, int db, int sb, int pb, int to, int raw_mode) +{ + int tmp_ret = 0; + + pthread_mutex_lock(&serial_b_parity_mutex); + + if (com_b_get_dev() < 0) { + pthread_mutex_unlock(&serial_b_parity_mutex); + return -1; + } + + tmp_ret = com_set_opt(gSerialBHandle, speed, db, sb, pb, to, raw_mode); + + pthread_mutex_unlock(&serial_b_parity_mutex); + + return tmp_ret; +} + +int com_a_write_data(const unsigned char *pData, unsigned int uLen) +{ + int tmp_ret = 0; + + pthread_mutex_lock(&serial_a_w_mutex); + + if (com_a_get_dev() < 0) { + pthread_mutex_unlock(&serial_a_w_mutex); + return -1; + } + + LOGD("%s, write %d bytes\n", "TV", uLen); + + tmp_ret = com_write_data(gSerialAHandle, pData, uLen); + + pthread_mutex_unlock(&serial_a_w_mutex); + + return tmp_ret; +} + +int com_b_write_data(const unsigned char *pData, unsigned int uLen) +{ + int tmp_ret = 0; + + pthread_mutex_lock(&serial_b_w_mutex); + + if (com_b_get_dev() < 0) { + pthread_mutex_unlock(&serial_b_w_mutex); + return -1; + } + + LOGD("%s, write %d bytes\n", "TV", uLen); + + tmp_ret = com_write_data(gSerialBHandle, pData, uLen); + + pthread_mutex_unlock(&serial_b_w_mutex); + + return tmp_ret; +} + +int com_a_read_data(char *pData, unsigned int uLen) +{ + int tmp_ret = 0; + + pthread_mutex_lock(&serial_a_r_mutex); + + if (com_a_get_dev() < 0) { + pthread_mutex_unlock(&serial_a_r_mutex); + return -1; + } + + tmp_ret = com_read_data(gSerialAHandle, pData, uLen); + + pthread_mutex_unlock(&serial_a_r_mutex); + + return tmp_ret; +} + +int com_b_read_data(char *pData, unsigned int uLen) +{ + int tmp_ret = 0; + + pthread_mutex_lock(&serial_b_r_mutex); + + if (com_b_get_dev() < 0) { + pthread_mutex_unlock(&serial_b_r_mutex); + return -1; + } + + tmp_ret = com_read_data(gSerialBHandle, pData, uLen); + + pthread_mutex_unlock(&serial_b_r_mutex); + + return tmp_ret; +} diff --git a/tv/tvserver/tvutils/serial_operate.cpp b/tv/tvserver/tvutils/serial_operate.cpp new file mode 100644 index 0000000..8eafdad --- a/dev/null +++ b/tv/tvserver/tvutils/serial_operate.cpp @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "serial_operate" + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <pthread.h> +#include <termios.h> +#include <errno.h> +#include <linux/hidraw.h> + +#include "include/serial_base.h" +#include "include/serial_operate.h" +#include "include/CTvLog.h" + +//****************************************************** +#ifndef HIDIOCSFEATURE +#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len) +#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len) +#endif +#define product_nid 0x00e0 +//#define product_nid 0x00e0 + +#define vendor_id 0x1A1D +#define ENDPOINT 3 + +#define EVENT_2_4G_HEADSET_ON 0 +#define EVENT_2_4G_HEADSET_OFF 1 + +CTv2d4GHeadSetDetect::CTv2d4GHeadSetDetect() +{ +} + +CTv2d4GHeadSetDetect::~CTv2d4GHeadSetDetect() +{ +} + +int CTv2d4GHeadSetDetect::startDetect() +{ + this->run("CTv2d4GHeadSetDetect"); + + return 0; +} + +bool CTv2d4GHeadSetDetect::threadLoop() +{ + int i = 0, rd_len = 0; + int thread_cmd_dly_tm = 1000 * 1000; + int tvThermal_cnt = 0, fd = 0; + char data[10] = "0"; + + LOGD("%s, entering...\n", __FUNCTION__); + + //SetSerialBThreadExecFlag(1); + + //********************************* + int hidraw_fd; + unsigned char buf[32]; + char phybuf[256]; + struct hidraw_devinfo info; + int read_size = 0; + bool debug = true; + char device[68]; + int HeadsetConnectState = false; + + int curdeviceID = -1; + for (int deviceID = 0; deviceID < 5; deviceID++) { + sprintf(device, "/dev/hidraw%d", deviceID); + LOGD(" thread device =%s ", device ); + if ((hidraw_fd = open(device, O_RDWR)) < 0 ) { + LOGD("cann't open path:%s!!!\n", device); + continue; + } + memset(phybuf, 0x0, 256); + LOGD("AAAAAAAAAAAAAA:%s!!!\n", device); + if (ioctl(hidraw_fd, HIDIOCGRAWINFO, &info) >= 0 && + ioctl(hidraw_fd, HIDIOCGRAWPHYS(256), phybuf) >= 0) { + LOGD("\t %d, product id = 0x%04x \n", __LINE__, info.product); + LOGD("\t %d, vendor id = 0x%04x \n", __LINE__, info.vendor); + int len = strlen(phybuf); + if (phybuf[len - 1] - '0' == ENDPOINT) { + if (info.vendor == vendor_id) { + curdeviceID = deviceID; + LOGD("\t product id = 0x%04x \n", info.product); + LOGD("\t vendor id = 0x%04x\n", info.vendor); + break; + } + } + } + close(hidraw_fd); + } + if (curdeviceID == -1) + return 0; + + sprintf(device, "/dev/hidraw%d", curdeviceID); + LOGD(" thread device =%s ", device ); + if ( (hidraw_fd = open(device, O_RDWR | O_NONBLOCK) ) < 0 ) { + printf("cann't open path:%s!!!\n", device); + return 0; + } + int checkvalue[300] ; + int countcheck = 0; + int count = 0; + int ritemcounts = 15; + //**************************************** + + while ( !exitPending() ) { //requietexit() or requietexitWait() not call + //loop codes + //LOGD("while 2.4G %s ", __FUNCTION__); + + memset(buf, 0x0, 32); + for (int ritem = 0; ritem < ritemcounts ; ritem++ ) { + read_size = read(hidraw_fd, buf, 32); + //for (int i = 0; i < 32; i++) + //ALOGD("read_size %d ", read_size); + if (debug) { + count ++; + if (count == 3000) { + LOGD("%02x %02x %02x %02x %02x %02x ", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + count = 0; + } + } + if (read_size < 0 ) { + + } + + checkvalue[countcheck] = buf[4] & 0x1f; + if (countcheck == 299) { + int checkcountvalue = 0; + for (int icheck = 0; icheck < countcheck ; icheck++ ) + checkcountvalue += checkvalue[icheck]; + // LOGD("checkcountvalue = %d",checkcountvalue); + if (checkcountvalue <= 5 * 4) { + if (HeadsetConnectState == true) { + if (debug) { + LOGD("headset connect false"); + LOGD("headset connect false"); + } + + mpObserver->onHeadSetDetect(0, 0); + //usleep(1000 * 200); + } + HeadsetConnectState = false; + } else if (checkcountvalue >= 200 * 4) { + if (HeadsetConnectState == false) { + if (debug) { + LOGD("headset connect true"); + LOGD("headset connect true"); + } + mpObserver->onHeadSetDetect(1, 0); + //usleep(1000 * 200); + } + HeadsetConnectState = true; + } + countcheck = 0; + } + countcheck ++; + + // bit 0: headset mic in/off; bit 1:headset on/off; bit 2: headphone on/off; bit 3: soundbar on/off ;bit 4: subwoofer on/off + /* else if (buf[4] & 0x1f) + { + if (HeadsetConnectState == false) + { + if (debug) + { + ALOGD("headset connect true"); + ALOGD("headset connect true"); + } + android::TvService::getIntance()->SendDtvStats(1,0,0,0,0,0); + //usleep(1000 * 200); + } + HeadsetConnectState = true; + } + else + { + if (HeadsetConnectState == true) + { + if (debug) + { + ALOGD("headset connect false"); + ALOGD("headset connect false"); + } + android::TvService::getIntance()->SendDtvStats(2,0,0,0,0,0); + //usleep(1000 * 200); + } + HeadsetConnectState = false; + }*/ + } + { + //added for fbc thermal setting + tvThermal_cnt++; + if (tvThermal_cnt == 300) { //60 sec + tvThermal_cnt = 0; + fd = open("/sys/class/thermal/thermal_zone0/temp", O_RDONLY); + if (fd < 0) { + LOGE("ERROR: failed to open file error: %d\n", errno); + } else { + read(fd, data, sizeof(data)); + close(fd); + LOGD("thermal temp data = %s ~~~~~~\n", data); + int x = 0; + x = atoi(data); + mpObserver->onThermalDetect(x); + LOGD("int data :%d\n", x); + } + } + } + usleep(1000 * 200); + } + //exit + //return true, run again, return false,not run. + return false; +} + + diff --git a/tv/tvserver/tvutils/tvconfig/CIniFile.cpp b/tv/tvserver/tvutils/tvconfig/CIniFile.cpp new file mode 100644 index 0000000..0e1ebe7 --- a/dev/null +++ b/tv/tvserver/tvutils/tvconfig/CIniFile.cpp @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "CIniFile" +//#define LOG_NDEBUG 0 + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include <ctype.h> +#include <include/CTvLog.h> + +#include "include/CIniFile.h" + +CIniFile::CIniFile() +{ + mpFirstSection = NULL; + mpFileName[0] = '\0'; + m_pIniFile = NULL; + mpFirstLine = NULL; +} + +CIniFile::~CIniFile() +{ + LOGD("CIniFile::~CIniFile()"); + FreeAllMem(); +} + +int CIniFile::LoadFromFile(const char *filename) +{ + char lineStr[MAX_INI_FILE_LINE_LEN]; + char *pStr; + LINE *pCurLINE = NULL; + SECTION *pCurSection = NULL; + + FreeAllMem(); + + if (filename == NULL) { + return -1; + } + + LOGD("LoadFromFile name = %s", filename); + strcpy(mpFileName, filename); + if ((m_pIniFile = fopen (mpFileName, "r")) == NULL) { + return -1; + } + + while (fgets (lineStr, MAX_INI_FILE_LINE_LEN, m_pIniFile) != NULL) { + allTrim(lineStr); + + LINE *pLINE = new LINE(); + pLINE->pKeyStart = pLINE->Text; + pLINE->pKeyEnd = pLINE->Text; + pLINE->pValueStart = pLINE->Text; + pLINE->pValueEnd = pLINE->Text; + pLINE->pNext = NULL; + pLINE->type = getLineType(lineStr); + //LOGD("getline=%s len=%d type=%d", lineStr, strlen(lineStr), pLINE->type); + strcpy(pLINE->Text, lineStr); + pLINE->LineLen = strlen(pLINE->Text); + + //head + if (mpFirstLine == NULL) { + mpFirstLine = pLINE; + } else { + pCurLINE->pNext = pLINE; + } + + pCurLINE = pLINE; + + switch (pCurLINE->type) { + case LINE_TYPE_SECTION: { + SECTION *pSec = new SECTION(); + pSec->pLine = pLINE; + pSec->pNext = NULL; + if (mpFirstSection == NULL) { //first section + mpFirstSection = pSec; + } else { + pCurSection->pNext = pSec; + } + pCurSection = pSec; + break; + } + case LINE_TYPE_KEY: { + char *pM = strchr(pCurLINE->Text, '='); + pCurLINE->pKeyStart = pCurLINE->Text; + pCurLINE->pKeyEnd = pM - 1; + pCurLINE->pValueStart = pM + 1; + pCurLINE->pValueEnd = pCurLINE->Text + pCurLINE->LineLen - 1; + break; + } + case LINE_TYPE_COMMENT: + default: + break; + } + } + + fclose (m_pIniFile); + m_pIniFile = NULL; + return 0; +} + +int CIniFile::SaveToFile(const char *filename) +{ + const char *filepath = NULL; + FILE *pFile = NULL; + + if (filename == NULL) { + if (strlen(mpFileName) == 0) { + LOGD("error save file is null"); + return -1; + } else { + filepath = mpFileName; + } + } else { + filepath = filename; + } + //LOGD("Save to file name = %s", file); + + if ((pFile = fopen (filepath, "wb")) == NULL) { + LOGD("Save to file open error = %s", filepath); + return -1; + } + + LINE *pCurLine = NULL; + for (pCurLine = mpFirstLine; pCurLine != NULL; pCurLine = pCurLine->pNext) { + fprintf (pFile, "%s\r\n", pCurLine->Text); + } + + fflush(pFile); + fsync(fileno(pFile)); + fclose(pFile); + return 0; +} + +int CIniFile::SetString(const char *section, const char *key, const char *value) +{ + SECTION *pNewSec = NULL; + LINE *pNewSecLine = NULL; + LINE *pNewKeyLine = NULL; + + SECTION *pSec = getSection(section); + if (pSec == NULL) { + pNewSec = new SECTION(); + pNewSecLine = new LINE(); + pNewKeyLine = new LINE(); + + pNewKeyLine->type = LINE_TYPE_KEY; + pNewSecLine->type = LINE_TYPE_SECTION; + + + sprintf(pNewSecLine->Text, "[%s]", section); + pNewSec->pLine = pNewSecLine; + + InsertSection(pNewSec); + + int keylen = strlen(key); + sprintf(pNewKeyLine->Text, "%s=%s", key, value); + pNewKeyLine->LineLen = strlen(pNewKeyLine->Text); + pNewKeyLine->pKeyStart = pNewKeyLine->Text; + pNewKeyLine->pKeyEnd = pNewKeyLine->pKeyStart + keylen - 1; + pNewKeyLine->pValueStart = pNewKeyLine->pKeyStart + keylen + 1; + pNewKeyLine->pValueEnd = pNewKeyLine->Text + pNewKeyLine->LineLen - 1; + + InsertKeyLine(pNewSec, pNewKeyLine); + + } else { //find section + LINE *pLine = getKeyLineAtSec(pSec, key); + if (pLine == NULL) { //, not find key + pNewKeyLine = new LINE(); + pNewKeyLine->type = LINE_TYPE_KEY; + + int keylen = strlen(key); + sprintf(pNewKeyLine->Text, "%s=%s", key, value); + pNewKeyLine->LineLen = strlen(pNewKeyLine->Text); + pNewKeyLine->pKeyStart = pNewKeyLine->Text; + pNewKeyLine->pKeyEnd = pNewKeyLine->pKeyStart + keylen - 1; + pNewKeyLine->pValueStart = pNewKeyLine->pKeyStart + keylen + 1; + pNewKeyLine->pValueEnd = pNewKeyLine->Text + pNewKeyLine->LineLen - 1; + + InsertKeyLine(pSec, pNewKeyLine); + } else { //all find, change it + sprintf(pLine->Text, "%s=%s", key, value); + pLine->LineLen = strlen(pLine->Text); + pLine->pValueEnd = pLine->Text + pLine->LineLen - 1; + } + } + + //save + SaveToFile(NULL); + return 0; +} + +int CIniFile::SetInt(const char *section, const char *key, int value) +{ + char tmp[64]; + sprintf(tmp, "%d", value); + SetString(section, key, tmp); + return 0; +} + +const char *CIniFile::GetString(const char *section, const char *key, const char *def_value) +{ + SECTION *pSec = getSection(section); + if (pSec == NULL) return def_value; + LINE *pLine = getKeyLineAtSec(pSec, key); + if (pLine == NULL) return def_value; + + return pLine->pValueStart; +} + +int CIniFile::GetInt(const char *section, const char *key, int def_value) +{ + const char *num = GetString(section, key, NULL); + if (num != NULL) { + return atoi(num); + } + return def_value; +} + +int CIniFile::SetFloat(const char *section, const char *key, float value) +{ + char tmp[64]; + sprintf(tmp, "%.2f", value); + SetString(section, key, tmp); + return 0; +} + +float CIniFile::GetFloat(const char *section, const char *key, float def_value) +{ + const char *num = GetString(section, key, NULL); + if (num != NULL) { + return atof(num); + } + return def_value; +} + +LINE_TYPE CIniFile::getLineType(char *Str) +{ + LINE_TYPE type = LINE_TYPE_COMMENT; + if (strchr(Str, '#') != NULL) { + type = LINE_TYPE_COMMENT; + } else if ( (strstr (Str, "[") != NULL) && (strstr (Str, "]") != NULL) ) { /* Is Section */ + type = LINE_TYPE_SECTION; + } else { + if (strstr (Str, "=") != NULL) { + type = LINE_TYPE_KEY; + } else { + type = LINE_TYPE_COMMENT; + } + } + return type; +} + +void CIniFile::FreeAllMem() +{ + //line + LINE *pCurLine = NULL; + LINE *pNextLine = NULL; + for (pCurLine = mpFirstLine; pCurLine != NULL;) { + pNextLine = pCurLine->pNext; + delete pCurLine; + pCurLine = pNextLine; + } + mpFirstLine = NULL; + //section + SECTION *pCurSec = NULL; + SECTION *pNextSec = NULL; + for (pCurSec = mpFirstSection; pCurSec != NULL;) { + pNextSec = pCurSec->pNext; + delete pCurSec; + pCurSec = pNextSec; + } + mpFirstSection = NULL; +} + +int CIniFile::InsertSection(SECTION *pSec) +{ + //insert it to sections list ,as first section + pSec->pNext = mpFirstSection; + mpFirstSection = pSec; + //insert it to lines list, at first + pSec->pLine->pNext = mpFirstLine; + mpFirstLine = pSec->pLine; + return 0; +} + +int CIniFile::InsertKeyLine(SECTION *pSec, LINE *line) +{ + LINE *line1 = pSec->pLine; + LINE *line2 = line1->pNext; + line1->pNext = line; + line->pNext = line2; + return 0; +} + +SECTION *CIniFile::getSection(const char *section) +{ + //section + for (SECTION *psec = mpFirstSection; psec != NULL; psec = psec->pNext) { + if (strncmp((psec->pLine->Text) + 1, section, strlen(section)) == 0) + return psec; + } + return NULL; +} + +LINE *CIniFile::getKeyLineAtSec(SECTION *pSec, const char *key) +{ + //line + for (LINE *pline = pSec->pLine->pNext; (pline != NULL && pline->type != LINE_TYPE_SECTION); pline = pline->pNext) { + if (pline->type == LINE_TYPE_KEY) { + if (strncmp(pline->Text, key, strlen(key)) == 0) + return pline; + } + } + return NULL; +} + +void CIniFile::allTrim(char *Str) +{ + char *pStr; + pStr = strchr (Str, '\n'); + if (pStr != NULL) { + *pStr = 0; + } + int Len = strlen(Str); + if ( Len > 0 ) { + if ( Str[Len - 1] == '\r' ) { + Str[Len - 1] = '\0'; + } + } + pStr = Str; + while (*pStr != '\0') { + if (*pStr == ' ') { + char *pTmp = pStr; + while (*pTmp != '\0') { + *pTmp = *(pTmp + 1); + pTmp++; + } + } else { + pStr++; + } + } + return; +} + diff --git a/tv/tvserver/tvutils/tvconfig/tvconfig.conf b/tv/tvserver/tvutils/tvconfig/tvconfig.conf new file mode 100644 index 0000000..d18fbca --- a/dev/null +++ b/tv/tvserver/tvutils/tvconfig/tvconfig.conf @@ -0,0 +1,30 @@ +#ssm configure +ro.tv.ssm.device_01_cfg = e2prom,/dev/i2c-0,0x1000,0,0xFFF,0x20,0x20,0x50,1,-1 +ssm.writeprotect.gpio = b,8,1 + +#audio config +audio.tv.card.id = hw:AMLM2 +audio.tv.card.name = AML-M2 +audio.amp.analog.mute.gpio = b,8,1 +audio.headset.mute.gpio = x,30,1 +audio.avout.mute.gpio = x,69,0 +audio.initaudio.gpioctl = b,8,1,x,30,0,b,5,1,x,69,1,x,68,0,x,67,1,x,66,0,x,65,1,x,64,0,x,63,1,x,62,0,x,61,1,x,60,0,x,59,1,x,58,0,x,57,1,x,56,0,x,55,1,x,54,0,x,53,1,x,52,0,x,51,1,x,50,0,x,49,1,x,48,0,x,47,1,x,46,0,x,45,1,x,44,0,x,43,1,x,42,0,x,41,1,x,40,0,x,39,0,x,38,0,x,37,1,x,36,0,x,35,1,x,34,0,x,33,1,x,32,0,x,31,1,x,30,0,x,29,1,x,28,0,x,27,1,x,26,0,x,25,1,x,24,0,x,23,1,x,22,0,x,21,1,x,20,0,x,19,1,x,18,0,x,17,1,x,16,0,x,15,1,x,14,0,x,13,1,x,12,0,x,11,1,x,10,0,x,9,1,x,8,0 +audio.amplifier.biquad00.data = 0x04, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,0x80, 0xC4, 0x96, 0x7F, 0x3B, 0x6A, 0x7F, 0x3A, 0xD3, 0x81, 0x87, 0xFD, 0x3F, 0x9D, 0xB5,0x8D, 0x18, 0x8C, 0x67, 0x10, 0x01, 0x72, 0xE7, 0x74, 0x96, 0x03, 0x40, 0x41, 0x76, 0x5F,0xAC, 0xE8, 0xCE, 0x32, 0x55, 0xB8, 0x53, 0x17, 0x32, 0xC1, 0xEA, 0x5F, 0x45, 0xDF, 0xF4, +audio.amplifier.biquad01.data = 0x04, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,0x8D, 0x18, 0x8C, 0x67, 0x10, 0x01, 0x72, 0xE7, 0x74, 0x96, 0x03, 0x40, 0x41, 0x76, 0x5F,0xAC, 0xE8, 0xCE, 0x32, 0x55, 0xB8, 0x53, 0x17, 0x32, 0xC1, 0xEA, 0x5F, 0x45, 0xDF, 0xF4, + +#tvin config +tvin.log.cfg = log_error,log_debug + +#vpp config +vpp.log.cfg = log_error,log_debug + +#misc config +misc.log.cfg = log_error,log_debug +misc.lastselsrc.show.cfg = TV,AV1,AV2,YPBPR1,YPBPR2,HDMI1,HDMI1,HDMI2,VGA,MPEG,DTV + +#tvservice config +tvservice.log.cfg = log_error + +#atv config +atv.fac.defchaninfo = 13,8,49750000,0,1,0,0,0,0,0,136250000,2,1,0,0,0,0,0,160250000,0,1,0,0,0,0,0,168250000,0,1,0,0,0,0,0,416250000,0,1,0,0,0,0,0,456250000,1,1,0,0,0,0,0,471250000,3,2,0,0,0,0,0,863250000,0,1,0,0,0,0,0,49750000,0,1,0,0,0,0,0,217250000,2,1,0,0,0,0,0,471250000,3,2,0,0,0,0,0,527250000,1,1,0,0,0,0,0,783250000,0,1,0,0,0,0,0, +atv.log.cfg = log_error,log_channelsearch_error,log_channelsearch_debug,log_channelselect_error,log_channelselect_debug
\ No newline at end of file diff --git a/tv/tvserver/tvutils/tvconfig/tvconfig.cpp b/tv/tvserver/tvutils/tvconfig/tvconfig.cpp new file mode 100644 index 0000000..b3ec180 --- a/dev/null +++ b/tv/tvserver/tvutils/tvconfig/tvconfig.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "tvconfig" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include "include/tvconfig.h" + +#include "include/CTvLog.h" +#include "include/CIniFile.h" +static const char *TV_SECTION = "TV"; +//INI_CONFIG* mpConfig = NULL; +static char mpFilePath[256] = {0}; + +static CIniFile *pIniFile = NULL; +int tv_config_load(const char *file_name) +{ + if (pIniFile != NULL) + delete pIniFile; + + pIniFile = new CIniFile(); + pIniFile->LoadFromFile(file_name); + strcpy(mpFilePath, file_name); + return 0; +} + +int tv_config_unload() +{ + if (pIniFile != NULL) + delete pIniFile; + return 0; +} + + +int config_set_str(const char *section, const char *key, const char *value) +{ + return pIniFile->SetString(section, key, value); +} + +const char *config_get_str(const char *section, const char *key, const char *def_value) +{ + return pIniFile->GetString(section, key, def_value); +} + +int config_get_int(const char *section, const char *key, const int def_value) +{ + return pIniFile->GetInt(section, key, def_value); +} + +int config_set_int(const char *section, const char *key, const int value) +{ + pIniFile->SetInt(section, key, value); + return 0; +} + +float config_get_float(const char *section, const char *key, const float def_value) +{ + return pIniFile->GetFloat(section, key, def_value); +} + +int config_set_float(const char *section, const char *key, const int value) +{ + pIniFile->SetFloat(section, key, value); + return 0; +} + diff --git a/tv/tvserver/tvutils/tvutils.cpp b/tv/tvserver/tvutils/tvutils.cpp new file mode 100644 index 0000000..01f6fe0 --- a/dev/null +++ b/tv/tvserver/tvutils/tvutils.cpp @@ -0,0 +1,1404 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#define LOG_TAG "tvserver" +#define LOG_TV_TAG "tvutils" + +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <fcntl.h> +#include <ctype.h> +#include <sys/prctl.h> +#include <stdlib.h> +#include <android/log.h> +#include <cutils/android_reboot.h> +#include <cutils/properties.h> +#include <dirent.h> + +#include <utils/threads.h> +#include <binder/IServiceManager.h> +#include <systemcontrol/SystemControlClient.h> + +#include "include/tvconfig.h" +#include "include/tvutils.h" +#include "include/CTvLog.h" + +#include <vector> +#include <map> +#include <string> +using namespace android; + +static pthread_mutex_t file_attr_control_flag_mutex = PTHREAD_MUTEX_INITIALIZER; + +static pthread_t UserPet_ThreadId = 0; +static unsigned char is_turnon_user_pet_thread = false; +static unsigned char is_user_pet_thread_start = false; +static unsigned int user_counter = 0; +static unsigned int user_pet_terminal = 1; + +static Mutex amLock; +static sp<SystemControlClient> sysctrlClient = nullptr; +static const sp<SystemControlClient> &getSystemControlService() +{ + Mutex::Autolock _l(amLock); + if (sysctrlClient == nullptr) { + sysctrlClient = new SystemControlClient(); + } + ALOGE_IF(sysctrlClient == nullptr, "no System Control Service!?"); + + return sysctrlClient; +} + +int getBootEnv(const char *key, char *value, const char *def_val) +{ + const sp<SystemControlClient> sws = getSystemControlService(); + if (sws != nullptr) { + std::string v; + if (sws->getBootEnv(key, v)) { + strcpy(value, v.c_str()); + return 0; + } + } + + strcpy(value, def_val); + return -1; +} + +void setBootEnv(const char *key, const char *value) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + sws->setBootEnv(key, value); + } +} + +int writeSys(const char *path, const char *val) { + int fd; + + if ((fd = open(path, O_RDWR)) < 0) { + LOGE("writeSys, open %s error(%s)", path, strerror (errno)); + return -1; + } + + LOGD("write %s, val:%s\n", path, val); + + int len = write(fd, val, strlen(val)); + close(fd); + return len; +} + +int readSys(const char *path, char *buf, int count) { + int fd, len; + + if ( NULL == buf ) { + LOGE("buf is NULL"); + return -1; + } + + if ((fd = open(path, O_RDONLY)) < 0) { + LOGE("readSys, open %s error(%s)", path, strerror (errno)); + return -1; + } + + len = read(fd, buf, count); + if (len < 0) { + LOGE("read %s error, %s\n", path, strerror(errno)); + goto exit; + } + + int i , j; + for (i = 0, j = 0; i <= len -1; i++) { + //change '\0' to 0x20(spacing), otherwise the string buffer will be cut off ,if the last char is '\0' should not replace it + if (0x0 == buf[i] && i < len - 1) { + buf[i] = 0x20; + } + /* delete all the character of '\n' */ + if (0x0a != buf[i]) { + buf[j++] = buf[i]; + } + } + buf[j] = 0x0; + + //LOGI("read %s, result length:%d, val:%s\n", path, len, buf); + +exit: + close(fd); + return len; +} + +int tvReadSysfs(const char *path, char *value) { +#ifdef USE_SYSTEM_CONTROL + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + std::string v; + if (sws->readSysfs(path, v)) { + strcpy(value, v.c_str()); + return 0; + } + } + return -1; +#else + char buf[SYS_STR_LEN+1] = {0}; + int len = readSys(path, (char*)buf, SYS_STR_LEN); + strcpy(value, buf); + return len; +#endif +} + +int tvWriteSysfs(const char *path, const char *value) { +#ifdef USE_SYSTEM_CONTROL + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + sws->writeSysfs(path, value); + } + return 0; +#else + return writeSys(path, value); +#endif +} + +int tvWriteSysfs(const char *path, int value, int base) +{ + char str_value[64] = {0}; + if (base == 16) { + sprintf(str_value, "0x%-x", value); + } else { + sprintf(str_value, "%d", value); + } + LOGD("tvWriteSysfs, str_value = %s", str_value); +#ifdef USE_SYSTEM_CONTROL + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + sws->writeSysfs(path, str_value); + } + return 0; +#else + return writeSys(path, str_value); +#endif +} + +int tvWriteDisplayMode(const char *mode) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + sws->setSinkOutputMode(mode); + } + return 0; +} + +//Add for PQ +int tvResetLastVppSettingsSourceType(void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + sws->resetLastPQSettingsSourceType(); + } + return 0; +} + +int tvLoadPQSettings(source_input_param_t source_input_param) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + sws->loadPQSettings(source_input_param); + } + return 0; +} + +int tvLoadCpqLdimRegs(void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + sws->loadCpqLdimRegs(); + } + return 0; +} + +int tvSSMReadNTypes(int id, int data_len, int *data_buf, int offset) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + int tmp_val = 0; + tmp_val = sws->sysSSMReadNTypes(id, data_len, offset); + *data_buf = tmp_val; + } + return 0; +} + +int tvSSMWriteNTypes(int id, int data_len, int data_buf, int offset) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + sws->sysSSMWriteNTypes(id, data_len, data_buf, offset); + } + return 0; + +} + +int tvGetActualAddr(int id) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + sws->getActualAddr(id); + } + return 0; + +} + +int tvGetActualSize(int id) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + sws->getActualSize(id); + } + return 0; + +} + +int tvSetPQMode ( vpp_picture_mode_t mode, int is_save, int is_autoswitch) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + + if (sws != nullptr) { + sws->setPQmode((int)mode, is_save, is_autoswitch); + } + + return 0; +} + +vpp_picture_mode_t tvGetPQMode ( void ) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return (vpp_picture_mode_t)sws->getPQmode(); + } + + return VPP_PICTURE_MODE_MAX; +} + +int tvSavePQMode ( vpp_picture_mode_t mode ) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + + if (sws != nullptr) { + return sws->savePQmode(mode); + } + + return -1; +} + +int tvGetPQParams(source_input_param_t source_input_param, vpp_picture_mode_t pq_mode, vpp_pq_para_t *pq_para) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + + if (sws != nullptr) { + vpp_pq_para_t tmp_value; + tmp_value.brightness = sws->getPQParams(source_input_param, pq_mode, BRIGHTNESS); + tmp_value.contrast = sws->getPQParams(source_input_param, pq_mode, CONTRAST); + tmp_value.hue = sws->getPQParams(source_input_param, pq_mode, HUE); + tmp_value.nr = sws->getPQParams(source_input_param, pq_mode, NR); + tmp_value.saturation = sws->getPQParams(source_input_param, pq_mode, SATURATION); + tmp_value.sharpness = sws->getPQParams(source_input_param, pq_mode, SHARPNESS); + tmp_value.backlight = sws->getPQParams(source_input_param, pq_mode, BACKLIGHT); + + *pq_para = tmp_value; + return 0; + } + + return -1; +} + +int tvGetAutoSwitchPCModeFlag(void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getAutoSwitchPCModeFlag(); + } + + return -1; +} + +int tvSetBrightness(int brightness, int is_save) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setBrightness(brightness, is_save); + } + return -1; +} + +int tvGetBrightness ( void ) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getBrightness(); + } + + return -1; +} + +int tvSaveBrightness ( int brightness ) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->saveBrightness(brightness); + } + + return -1; +} + +int tvSetContrast ( int contrast, int is_save ) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setContrast(contrast, is_save); + } + + return -1; +} + +int tvGetContrast (void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getContrast(); + } + + return -1; +} + +int tvSaveContrast (int contrast) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->saveContrast(contrast); + } + + return -1; +} + +int tvSetSaturation (int satuation, int is_save) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setSaturation(satuation, is_save); + } + + return -1; +} + +int tvGetSaturation (void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getSaturation(); + } + + return -1; +} + +int tvSaveSaturation (int satuation) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->saveSaturation(satuation); + } + + return -1; +} + +int tvSetHue (int hue, int is_save) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setHue(hue, is_save); + } + + return -1; +} + +int tvGetHue (void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getHue(); + } + + return -1; +} + +int tvSaveHue (int hue) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->saveHue(hue); + } + + return -1; +} + +int tvSetSharpness ( int value, int en, int is_save ) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setSharpness(value, en, is_save); + } + + return -1; +} + +int tvGetSharpness (void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getSharpness(); + } + + return -1; +} + +int tvSaveSharpness (int value) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + sws->saveSharpness(value); + } + + return -1; +} + +int tvSetColorTemperature (vpp_color_temperature_mode_t mode, int is_save) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setColorTemperature(mode, is_save); + } + + return -1; +} + +int tvGetColorTemperature (void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getColorTemperature(); + } + + return -1; +} + +int tvSaveColorTemperature (vpp_color_temperature_mode_t mode) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->saveColorTemperature(mode); + } + + return -1; +} + +int tvSetColorTemperatureParams(vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t params) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setColorTemperatureParam(Tempmode, params); + } + + return -1; +} + +int tvGetColorTemperatureParams(vpp_color_temperature_mode_t Tempmode, pq_color_param_t id) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getColorTemperatureParam((int)Tempmode, (int)id); + } + + return -1; +} + +int tvSaveColorTemperatureParams(vpp_color_temperature_mode_t Tempmode, tcon_rgb_ogo_t params) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->saveColorTemperatureParam((int)Tempmode, params); + } + + return -1; +} + +int tvSetNoiseReductionMode (vpp_noise_reduction_mode_t mode, int is_save) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setNoiseReductionMode(mode, is_save); + } + + return -1; +} + +int tvGetNoiseReductionMode (void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getNoiseReductionMode(); + } + + return -1; +} + +int tvSaveNoiseReductionMode ( vpp_noise_reduction_mode_t mode) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->saveNoiseReductionMode(mode); + } + + return -1; +} + +int tvSetGamma(int gamma_curve, int is_save) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setGammaValue(gamma_curve, is_save); + } + + return -1; +} + +int tvGetGamma(void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getGammaValue(); + } + + return -1; +} + +int tvSetEyeProtectionMode(source_input_param_t source_input_param, int enable) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setEyeProtectionMode(source_input_param, enable); + } + + return -1; +} + +int tvGetEyeProtectionMode(void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getEyeProtectionMode(); + } + + return -1; +} + +int tvGetDisplayMode(source_input_param_t source_input_param) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getDisplayMode(source_input_param); + } + + return -1; +} + +int tvFactoryResetNonlinear(void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factoryResetNonlinear(); + } + + return -1; +} + +int tvGetOverscanParam(source_input_param_t source_input_param, tvin_cutwin_param_t id) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getOverscanParam(source_input_param, (int)id); + } + + return -1; +} + +int tvFactoryResetPQMode(void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factoryResetPQMode(); + } + + return -1; +} + +int tvFactoryResetColorTemp(void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factoryResetColorTemp(); + } + + return -1; +} + +int tvFactorySetPQParam(source_input_param_t source_input_param, int pq_mode, vpp_pq_param_t id, int value) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factorySetPQParam(source_input_param, pq_mode, id, value); + } + + return -1; +} + +int tvFactoryGetPQParam(source_input_param_t source_input_param, int pq_mode, vpp_pq_param_t id) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factoryGetPQParam(source_input_param, pq_mode, id); + } + + return -1; +} +int tvFactorySetColorTemperatureParam(int colortemperature_mode, pq_color_param_t id, int value) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factorySetColorTemperatureParam(colortemperature_mode, id, value); + } + + return -1; +} +int tvFactoryGetColorTemperatureParam(int colortemperature_mode, pq_color_param_t id) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factoryGetColorTemperatureParam(colortemperature_mode, id); + } + + return -1; +} +int tvFactorySaveColorTemperatureParam(int colortemperature_mode, pq_color_param_t id, int value) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factorySaveColorTemperatureParam(colortemperature_mode, id, value); + } + + return -1; +} + +int tvFactorySetOverscanParam(source_input_param_t source_input_param, tvin_cutwin_t cutwin_t) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factorySetOverscan(source_input_param, cutwin_t.he, cutwin_t.hs, cutwin_t.ve, cutwin_t.vs); + } + + return -1; +} +int tvFactoryGetOverscanParam(source_input_param_t source_input_param, int id) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factoryGetOverscan(source_input_param, id); + } + + return -1; + +} + +int tvFactorySetGamma(int gamma_r, int gamma_g, int gamma_b) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factorySetGamma(gamma_r, gamma_g, gamma_b); + } + + return -1; +} + +int tvFactorySetNolineParams(source_input_param_t source_input_param, int type, noline_params_t noline_params) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factorySetNolineParams(source_input_param, type, noline_params.osd0, noline_params.osd25, + noline_params.osd50, noline_params.osd75, noline_params.osd100); + } + + return -1; +} + +int tvFactoryGetNolineParams(source_input_param_t source_input_param, int type, int id) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factoryGetNolineParams(source_input_param, type, id); + } + + return -1; +} + +int tvFactorySetParamsDefault(void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factorySetParamsDefault(); + } + + return -1; + +} + +int tvFactorySSMRestore(void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->factorySSMRestore(); + } + + return -1; + +} + +int tvSSMRecovery(void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->SSMRecovery(); + } + + return -1; +} + +int tvGetSSMStatus(void) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->getSSMStatus(); + } + + return -1; +} + +int tvSetPLLValues(source_input_param_t source_input_param) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setPLLValues(source_input_param); + } + + return -1; +} + +int tvSetCVD2Values(source_input_param_t source_input_param) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setCVD2Values(source_input_param); + } + + return -1; +} + +int tvSetPQConfig(Set_Flag_Cmd_t id, int value) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + return sws->setPQConfig(id, value); + } + + return -1; +} + +int tvSetCurrentSourceInfo(tv_source_input_t tv_source_input, tv_source_input_type_t source_type,tvin_port_t source_port, + tvin_sig_fmt_t sig_fmt, is_3d_type_t is3d, tvin_trans_fmt_t trans_fmt) +{ + const sp<SystemControlClient> &sws = getSystemControlService(); + if (sws != nullptr) { + source_input_param_t source_input_param; + source_input_param.source_input = tv_source_input; + source_input_param.source_type = source_type; + source_input_param.source_port = source_port; + source_input_param.sig_fmt = sig_fmt; + source_input_param.is3d = is3d; + source_input_param.trans_fmt = trans_fmt; + + return sws->setCurrentSourceInfo(source_input_param); + } + return -1; +} +//PQ end + +int Tv_MiscRegs(const char *cmd) +{ + FILE *fp = NULL; + fp = fopen("/sys/class/register/reg", "w"); + + if (fp != NULL && cmd != NULL) { + fprintf(fp, "%s", cmd); + } else { + LOGE("Open /sys/class/register/reg ERROR(%s)!!\n", strerror(errno)); + fclose(fp); + return -1; + } + fclose(fp); + return 0; +} + +int TvMisc_SetLVDSSSC(int val) +{ + FILE *fp; + + fp = fopen("/sys/class/lcd/ss", "w"); + if (fp != NULL) { + fprintf(fp, "%d", val); + fclose(fp); + } else { + LOGE("open /sys/class/lcd/ss ERROR(%s)!!\n", strerror(errno)); + return -1; + } + return 0; +} + +int TvMisc_SetUserCounterTimeOut(int timeout) +{ + FILE *fp; + + fp = fopen("/sys/devices/platform/aml_wdt/user_pet_timeout", "w"); + if (fp != NULL) { + fprintf(fp, "%d", timeout); + fclose(fp); + } else { + LOGE("=OSD CPP=> open /sys/devices/platform/aml_wdt/user_pet_timeout ERROR(%s)!!\n", strerror(errno)); + return -1; + } + return 0; +} + +int TvMisc_SetUserCounter(int count) +{ + FILE *fp; + + fp = fopen("/sys/module/aml_wdt/parameters/user_pet", "w"); + if (fp != NULL) { + fprintf(fp, "%d", count); + fclose(fp); + } else { + LOGE("=OSD CPP=> open /sys/devices/platform/aml_wdt/user_pet ERROR(%s)!!\n", strerror(errno)); + return -1; + } + + fclose(fp); + + return 0; +} + +int TvMisc_SetUserPetResetEnable(int enable) +{ + FILE *fp; + + fp = fopen("/sys/module/aml_wdt/parameters/user_pet_reset_enable", "w"); + + if (fp != NULL) { + fprintf(fp, "%d", enable); + fclose(fp); + } else { + LOGE("=OSD CPP=> open /sys/devices/platform/aml_wdt/user_pet_reset_enable ERROR(%s)!!\n", strerror(errno)); + return -1; + } + + fclose(fp); + + return 0; +} + +int TvMisc_SetSystemPetResetEnable(int enable) +{ + FILE *fp; + + fp = fopen("/sys/devices/platform/aml_wdt/reset_enable", "w"); + + if (fp != NULL) { + fprintf(fp, "%d", enable); + fclose(fp); + } else { + LOGE("=OSD CPP=> open /sys/devices/platform/aml_wdt/reset_enable ERROR(%s)!!\n", strerror(errno)); + return -1; + } + + fclose(fp); + + return 0; +} + +int TvMisc_SetSystemPetEnable(int enable) +{ + FILE *fp; + + fp = fopen("/sys/devices/platform/aml_wdt/ping_enable", "w"); + + if (fp != NULL) { + fprintf(fp, "%d", enable); + fclose(fp); + } else { + LOGE("=OSD CPP=> open /sys/devices/platform/aml_wdt/ping_enable ERROR(%s)!!\n", strerror(errno)); + return -1; + } + + fclose(fp); + + return 0; +} + +int SetAudioOutmode(int mode){ + char val[32] = {0}; + sprintf(val, "%d", mode); + int len = tvWriteSysfs(AUDIO_OUTMODE_PATH, val); + if (len > 0) { + char temp[] = "audout_mode"; + tvWriteSysfs(ATVDEMODE_DEBUG_PATH,temp); + } + return 0; +} + +int GetAudioOutmode(){ + char mode[32] = {0}; + tvReadSysfs(AUDIO_OUTMODE_PATH, mode); + return atoi(mode); +} + +int GetAudioStreamOutmode(){ + char mode[32] = {0}; + char temp[] = "signal_audmode"; + tvWriteSysfs(ATVDEMODE_DEBUG_PATH,temp); + tvReadSysfs(AUDIO_STREAM_OUTMODE_PATH, mode); + return atoi(mode); +} + +int TvMisc_SetSystemPetCounterTimeOut(int timeout) +{ + FILE *fp; + + fp = fopen("/sys/devices/platform/aml_wdt/wdt_timeout", "w"); + + if (fp != NULL) { + fprintf(fp, "%d", timeout); + fclose(fp); + } else { + LOGE("=OSD CPP=> open /sys/devices/platform/aml_wdt/wdt_timeout ERROR(%s)!!\n", strerror(errno)); + return -1; + } + + fclose(fp); + + return 0; +} + +//0-turn off +//1-force non-standard +//2-force normal +int Set_Fixed_NonStandard(int value) +{ + int fd = -1, ret = -1; + char set_vale[32] = {0}; + + sprintf(set_vale, "%d", value); + + fd = open("/sys/module/tvin_afe/parameters/force_nostd", O_RDWR); + if (fd >= 0) { + ret = write(fd, set_vale, strlen(set_vale)); + } + + if (ret <= 0) { + LOGE("%s -> set /sys/module/tvin_afe/parameters/force_nostd error(%s)!\n", CFG_SECTION_TV, strerror(errno)); + } + + close(fd); + return ret; +} + +static void *UserPet_TreadRun(void *data __unused) +{ + while (is_turnon_user_pet_thread == true) { + if (is_user_pet_thread_start == true) { + usleep(1000 * 1000); + if (++user_counter == 0xffffffff) + user_counter = 1; + TvMisc_SetUserCounter(user_counter); + } else { + usleep(10000 * 1000); + } + } + if (user_pet_terminal == 1) { + user_counter = 0; + } else { + user_counter = 1; + } + TvMisc_SetUserCounter(user_counter); + return ((void *) 0); +} + +static int UserPet_CreateThread(void) +{ + int ret = 0; + pthread_attr_t attr; + struct sched_param param; + + is_turnon_user_pet_thread = true; + is_user_pet_thread_start = true; + + pthread_attr_init(&attr); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + param.sched_priority = 1; + pthread_attr_setschedparam(&attr, ¶m); + ret = pthread_create(&UserPet_ThreadId, &attr, &UserPet_TreadRun, NULL); + pthread_attr_destroy(&attr); + return ret; +} + +static void UserPet_KillThread(void) +{ + int i = 0, dly = 600; + is_turnon_user_pet_thread = false; + is_user_pet_thread_start = false; + for (i = 0; i < 2; i++) { + usleep(dly * 1000); + } + pthread_join(UserPet_ThreadId, NULL); + UserPet_ThreadId = 0; + LOGD("%s, done.", CFG_SECTION_TV); +} + +void TvMisc_EnableWDT(bool kernelpet_disable, unsigned int userpet_enable, + unsigned int kernelpet_timeout, unsigned int userpet_timeout, unsigned int userpet_reset) +{ + TvMisc_SetSystemPetCounterTimeOut(kernelpet_timeout); + TvMisc_SetSystemPetEnable(1); + if (kernelpet_disable) { + TvMisc_SetSystemPetResetEnable(0); + } else { + TvMisc_SetSystemPetResetEnable(1); + } + if (userpet_enable) { + TvMisc_SetUserCounterTimeOut(userpet_timeout); + TvMisc_SetUserPetResetEnable(userpet_reset); + UserPet_CreateThread(); + } else { + TvMisc_SetUserCounter(0); + TvMisc_SetUserPetResetEnable(0); + } +} + +void TvMisc_DisableWDT(unsigned int userpet_enable) +{ + if (userpet_enable) { + user_pet_terminal = 0; + UserPet_KillThread(); + } +} + +/*---------------delete dir---------------*/ +int TvMisc_DeleteDirFiles(const char *strPath, int flag) +{ + int status; + char tmp[256]; + switch (flag) { + case 0: + sprintf(tmp, "rm -f %s", strPath); + LOGE("%s", tmp); + system(tmp); + break; + case 1: + sprintf(tmp, "cd %s", strPath); + LOGE("%s", tmp); + status = system(tmp); + if (status > 0 || status < 0) + return -1; + sprintf(tmp, "cd %s;rm -rf *", strPath); + system(tmp); + LOGE("%s", tmp); + break; + case 2: + sprintf(tmp, "rm -rf %s", strPath); + LOGE("%s", tmp); + system(tmp); + break; + } + return 0; +} + +//check file exist or not +bool isFileExist(const char *file_name) +{ + struct stat tmp_st; + + return stat(file_name, &tmp_st) == 0; +} + +int GetPlatformHaveDDFlag() +{ + const char *config_value; + + config_value = config_get_str(CFG_SECTION_TV, "platform.havedd", "null"); + if (strcmp(config_value, "true") == 0 || strcmp(config_value, "1") == 0) { + return 1; + } + + return 0; +} + +int GetFileAttrIntValue(const char *fp, int flag) +{ + int fd = -1, ret = -1; + int temp = -1; + char temp_str[32]; + + memset(temp_str, 0, 32); + + fd = open(fp, flag); + + if (fd <= 0) { + LOGE("open %s ERROR(%s)!!\n", fp, strerror(errno)); + return -1; + } + + if (read(fd, temp_str, sizeof(temp_str)) > 0) { + if (sscanf(temp_str, "%d", &temp) >= 0) { + LOGD("%s -> get %s value =%d!\n", "TV", fp, temp); + close(fd); + return temp; + } else { + LOGE("%s -> get %s value error(%s)\n", "TV", fp, strerror(errno)); + close(fd); + return -1; + } + } + + close(fd); + return -1; +} + + + +/* +void split(const std::string &s, std::vector<std::string> &v, const std::string &c) +{ + std::string::size_type pos1, pos2; + pos2 = s.find(c); + pos1 = 0; + while (std::string::npos != pos2) + { + v.push_back(s.substr(pos1, pos2-pos1)); + + pos1 = pos2 + c.size(); + pos2 = s.find(c, pos1); + } + if (pos1 != s.length()) + v.push_back(s.substr(pos1)); +} +void stringToMap(std::map<std::string, std::string> &m, const std::string &s) +{ + std::vector<std::string> nvpairs; + split(s, nvpairs, "&"); + for (std::vector<std::string>::iterator it = nvpairs.begin(); it != nvpairs.end(); it++) { + std::vector<std::string> nv; + split(*it, nv, "="); + if (nv.size() == 2) + m.insert(std::map<std::string, std::string>::value_type(nv[0], nv[1])); + } +} + +void mapToString(std::string &s, const std::map<std::string, std::string> &m) +{ + for (std::map<std::string, std::string>::const_iterator it = m.begin(); it != m.end(); ++it) { + if (!s.empty()) + s.append("&"); + s.append(it->first); + s.append("="); + s.append(it->second); + } +} +*/ + +#include "json/json.h" + +void jsonToMap(STR_MAP &m, const std::string &j) +{ + Json::Reader reader; + Json::Value root; + Json::FastWriter writer; + + if (!reader.parse(j, root)) + return; + + for (Json::Value::iterator it = root.begin(); it != root.end(); it++) { + std::string v(writer.write(*it)); + if (v.compare(v.size()-1, 1, "\n") == 0) + v.erase(v.size()-1); + if (v[0] == '\"') + m.insert(STR_MAP::value_type(it.key().asString(), v.substr(1, v.size()-2))); + else + m.insert(STR_MAP::value_type(it.key().asString(), v)); + } +} + +void mapToJson(std::string &j, const STR_MAP &m) +{ + int has_member = 0; + + if (m.empty()) + return; + + j.append("{"); + for (STR_MAP::const_iterator it = m.begin(); it != m.end(); ++it) { + if (has_member) + j.append(","); + j.append("\"").append(it->first).append("\":").append(it->second); + has_member = 1; + } + j.append("}"); +} + +void mapToJson(std::string &j, const STR_MAP &m, const std::string &k) +{ + if (m.empty()) + return; + + if (k.size()) + j.append("\"").append(k).append("\":"); + + mapToJson(j, m); +} + +void mapToJsonAppend(std::string &j, const STR_MAP &m, const std::string &k) +{ + if (m.empty()) + return; + + int append = 0; + + if (!j.empty()) { + append = 1; + j.replace(j.size()-1, 1, 1, ','); + } + + mapToJson(j, m, k); + + if (append) + j.append("}"); +} + +Paras Paras::operator + (const Paras &p) +{ + Paras pnew(*this); + for (STR_MAP::const_iterator it = p.mparas.begin(); it != p.mparas.end(); ++it) + pnew.mparas.insert(*it); + return pnew; +} + +int Paras::getInt(const char *key, int def) const +{ + STR_MAP::const_iterator it = mparas.find(std::string(key)); + if (it == mparas.end()) + return def; + return atoi(it->second.c_str()); +} + +void Paras::setInt(const char *key, int v) +{ + char cs[64]; + sprintf(cs, "%d", v); + STR_MAP::iterator it = mparas.find(std::string(key)); + if (it != mparas.end()) { + it->second.assign(cs); + } else { + std::pair<std::map<std::string, std::string>::iterator, bool> ret; + ret = mparas.insert(std::pair<std::string, std::string>(std::string(key), std::string(cs))); + if (ret.second == false) { + LOGE("error: map can not insert"); + } + } +} + +float getUptimeSeconds() { + timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + + return (float)(ts.tv_sec +(float)ts.tv_nsec / 1000000000); +} + +int jsonGetInt(const char *json, const char *obj, const char *value, int def) +{ + Json::Reader reader; + Json::Value root; + + if (!reader.parse(json, json + strlen(json), root)) { + LOGD("parse fail:(%s)", json); + return def; + } + if (obj && strlen(obj)) + return root.get(obj, Json::Value()).get(value, def).asInt(); + return root.get(value, def).asInt(); +} + +static const std::string toString(Json::Value v) +{ + if (!v.isObject()) + return v.asString(); + + Json::FastWriter writer; + writer.omitEndingLineFeed(); + return writer.write(v); +} + +const std::string jsonGetString(const char *json, const char *obj, const char *value, const char *def) +{ + Json::Reader reader; + Json::Value root; + + if (!reader.parse(json, json + strlen(json), root)) { + LOGD("parse fail:(%s)", json); + return def; + } + if (obj && strlen(obj)) + return toString(root.get(obj, Json::Value()).get(value, def)); + return toString(root.get(value, def)); +} + +int paramGetInt(const char *param, const char *section, const char *value, int def) { + if (!param || !strlen(param)) + return def; + return jsonGetInt(param, section, value, def); +} + +const std::string paramGetString(const char *param, const char *section, const char *value, const char *def) { + if (!param || !strlen(param)) + return def; + return jsonGetString(param, section, value, def); +} + +bool propertyGetBool(const char *prop, bool def) { + return property_get_bool(prop, def ? 1 : 0) ? true : false; +} + diff --git a/tv/tvserver/tvutils/zepoll.cpp b/tv/tvserver/tvutils/zepoll.cpp new file mode 100644 index 0000000..0e563a6 --- a/dev/null +++ b/tv/tvserver/tvutils/zepoll.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2014 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Description: c++ file + */ + +#include "include/zepoll.h" + +Epoll::Epoll(int _max, int maxevents): max(_max), + epoll_fd(-1), + epoll_timeout(-1), + epoll_maxevents(maxevents), + backEvents(0) +{ + +} + +Epoll::~Epoll() +{ + if (isValid()) { + close(epoll_fd); + } + delete[] backEvents; +} + + +inline +bool Epoll::isValid() const +{ + return epoll_fd > 0; +} + +void Epoll::setTimeout(int timeout) +{ + epoll_timeout = timeout; +} + +inline +void Epoll::setMaxEvents(int maxevents) +{ + epoll_maxevents = maxevents; +} + +inline +const epoll_event *Epoll::events() const +{ + return backEvents; +} + + + +int Epoll::create() +{ + epoll_fd = ::epoll_create(max); + if (isValid()) { + backEvents = new epoll_event[epoll_maxevents]; + } + return epoll_fd; +} + +int Epoll::add(int fd, epoll_event *event) +{ + if (isValid()) { + return ::epoll_ctl(epoll_fd, ADD, fd, event); + } + return -1; + +} + +int Epoll::mod(int fd, epoll_event *event) +{ + if (isValid()) { + return ::epoll_ctl(epoll_fd, MOD, fd, event); + } + return -1; + +} + +int Epoll::del(int fd, epoll_event *event) +{ + if (isValid()) { + return ::epoll_ctl(epoll_fd, DEL, fd, event); + } + return -1; +} + +int Epoll::wait() +{ + if (isValid()) { + return ::epoll_wait(epoll_fd, backEvents, epoll_maxevents, epoll_timeout); + } + return -1; +} |