1719 lines
56 KiB
C++
1719 lines
56 KiB
C++
/*
|
||
* Copyright (c) 2019 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:
|
||
*/
|
||
#define LOG_MODULE_TAG "TV"
|
||
#define LOG_CLASS_TAG "CTv"
|
||
|
||
#include <stdint.h>
|
||
#include <string.h>
|
||
|
||
#include "CTv.h"
|
||
#include "tvutils.h"
|
||
#include "TvConfigManager.h"
|
||
#include "CTvLog.h"
|
||
#include "CVpp.h"
|
||
#include <sys/ioctl.h>
|
||
#include <chrono>
|
||
#include "CVrr.h"
|
||
#ifndef USE_AMVIDEO
|
||
#include "video_tunnel.h"
|
||
#endif
|
||
|
||
/*
|
||
static tv_hdmi_edid_version_t Hdmi1CurrentEdidVer = HDMI_EDID_VER_14;
|
||
static tv_hdmi_edid_version_t Hdmi2CurrentEdidVer = HDMI_EDID_VER_14;
|
||
static tv_hdmi_edid_version_t Hdmi3CurrentEdidVer = HDMI_EDID_VER_14;
|
||
static tv_hdmi_edid_version_t Hdmi4CurrentEdidVer = HDMI_EDID_VER_14;
|
||
*/
|
||
#define NEW_FRAME_TIME_OUT_COUNT 10
|
||
|
||
//PORT_NUM define as 3 in the kernel.
|
||
#define K_PORT_NUM (3)
|
||
|
||
CTv::CTv()
|
||
{
|
||
mpObserver = NULL;
|
||
UenvInit();
|
||
const char* tvConfigFilePath = getenv(CFG_TV_CONFIG_FILE_PATH_STR);
|
||
if (!tvConfigFilePath) {
|
||
LOGD("%s: read tvconfig file path failed!\n", __FUNCTION__);
|
||
tvConfigFilePath = CONFIG_FILE_PATH_DEF;
|
||
} else {
|
||
LOGD("%s: tvconfig file path is %s!\n", __FUNCTION__, tvConfigFilePath);
|
||
}
|
||
LoadConfigFile(tvConfigFilePath);
|
||
|
||
const char * value;
|
||
value = ConfigGetStr( CFG_SECTION_TV, CFG_TVIN_ATV_DISPLAY_SNOW, "null" );
|
||
if (strcmp(value, "enable") == 0 ) {
|
||
mATVDisplaySnow = true;
|
||
} else {
|
||
mATVDisplaySnow = false;
|
||
}
|
||
LOGD("%s: load mATVDisplaySnow status [%d]!\n", __FUNCTION__, mATVDisplaySnow);
|
||
|
||
mpAmVideo = new CAmVideo();
|
||
mpTvin = CTvin::getInstance();
|
||
mpTvin->Tvin_AddVideoPath(TV_PATH_VDIN_AMLVIDEO2_PPMGR_DEINTERLACE_AMVIDEO);
|
||
mpTvin->Tvin_LoadSourceInputToPortMap();
|
||
if (IsSupportPIP()) {
|
||
mpPipTvin = CTvin::getInstance(VDIN2);
|
||
mpPipTvin->Tvin_LoadSourceInputToPortMap();
|
||
mpTvSubDisplayadapter = new CTvDisplayadapter(SUB_WINDOW);
|
||
}
|
||
mpTvMainDisplayadapter = new CTvDisplayadapter(MAIN_WINDOW);
|
||
mpHDMIRxManager = new CHDMIRxManager();
|
||
// update cec port sequence from hdmi tv config.
|
||
mpHDMIRxManager->SetHdmiPortCecPhysicAddr();
|
||
mpTvWayland = new CTvWayland();
|
||
|
||
tvin_info_t signalInfo;
|
||
signalInfo.trans_fmt = TVIN_TFMT_2D;
|
||
signalInfo.fmt = TVIN_SIG_FMT_NULL;
|
||
signalInfo.status = TVIN_SIG_STATUS_NULL;
|
||
signalInfo.cfmt = TVIN_COLOR_FMT_MAX;
|
||
signalInfo.signal_type= 0;
|
||
signalInfo.fps = 60;
|
||
signalInfo.is_dvi = 0;
|
||
signalInfo.aspect_ratio = TVIN_ASPECT_NULL;
|
||
SetCurrenSourceInfo(signalInfo);
|
||
SetCurrentPipSourceInfo(signalInfo);
|
||
|
||
//EDID load
|
||
int edidAutoLoadEnable = ConfigGetInt(CFG_SECTION_HDMI, CFG_HDMI_EDID_AUTO_LOAD_EN, 1);
|
||
if (edidAutoLoadEnable == 1) {
|
||
LOGD("%s: EDID data load by tvserver!\n", __FUNCTION__);
|
||
mInitEdid = true;
|
||
const char* buf = GetUenv(HDMI_UBOOT_EDID_VERSION);
|
||
if (buf == NULL) {
|
||
const char* edidDefaultVersion = ConfigGetStr(CFG_SECTION_HDMI, CFG_HDMI_EDID_DEFAULT_VERSION, "1.4");
|
||
int edidSetValue = 0;
|
||
if (strcmp(edidDefaultVersion, "2.0") == 0 ) {
|
||
LOGD("%s: Set EDID default version to 2.0!\n", __FUNCTION__);
|
||
/*
|
||
Hdmi1CurrentEdidVer = HDMI_EDID_VER_20;
|
||
Hdmi2CurrentEdidVer = HDMI_EDID_VER_20;
|
||
Hdmi3CurrentEdidVer = HDMI_EDID_VER_20;
|
||
Hdmi4CurrentEdidVer = HDMI_EDID_VER_20;
|
||
*/
|
||
for (int i = 0;i < 4; i ++)
|
||
edidSetValue |= (1 << (4*i));
|
||
}
|
||
SetUenv(HDMI_UBOOT_EDID_VERSION, std::to_string(edidSetValue).c_str());
|
||
}
|
||
if (GetHdmiDlgEnabled()) {
|
||
mDlgVisionEnableState = true;
|
||
}
|
||
bool dolbyVisionEnableState = GetDolbyVisionSupportStatus();
|
||
LoadEdidDataWithPort(0, dolbyVisionEnableState);
|
||
} else {
|
||
LOGD("%s: EDID data load by customer!\n", __FUNCTION__);
|
||
}
|
||
mTvDevicesPollDetect.setObserver(this);
|
||
mTvDevicesPollDetect.startDetect();
|
||
mTvMsgQueue = new CTvMsgQueue(this);
|
||
mTvMsgQueue->startMsgQueue();
|
||
mLastScreenMode = -1;
|
||
|
||
//panel tconless init
|
||
CTvPanel *mPanel = CTvPanel::getInstance();
|
||
mPanel->AM_PANEL_Init();
|
||
}
|
||
|
||
CTv::~CTv()
|
||
{
|
||
if (mpTvin != NULL) {
|
||
mpTvin->Tvin_RemoveVideoPath(TV_PATH_TYPE_TVIN);
|
||
delete mpTvin;
|
||
mpTvin = NULL;
|
||
}
|
||
|
||
if (mpHDMIRxManager != NULL) {
|
||
delete mpHDMIRxManager;
|
||
mpHDMIRxManager = NULL;
|
||
}
|
||
|
||
if (mpAmVideo != NULL) {
|
||
delete mpAmVideo;
|
||
mpAmVideo = NULL;
|
||
}
|
||
|
||
mpObserver = NULL;
|
||
UnloadConfigFile();
|
||
}
|
||
|
||
int CTv::StartTv(tv_source_input_t source)
|
||
{
|
||
LOGD("%s: source = %d!\n", __FUNCTION__, source);
|
||
int ret = 0;
|
||
|
||
if (SOURCE_MPEG == source) {
|
||
LOGD("%s: new source is %d! RETURN\n", __FUNCTION__,source);
|
||
return ret;
|
||
}
|
||
|
||
#ifndef USE_AMVIDEO
|
||
meson_fd = meson_vt_open();
|
||
if (meson_fd < 0) {
|
||
LOGE("%s: meson_vt_open failed.\n", __FUNCTION__);
|
||
}
|
||
#endif
|
||
|
||
mpTvWayland->setMainTunnelId(0);
|
||
mpTvWayland->startMainVideo();
|
||
mpTvWayland->commitAll();
|
||
|
||
//main source set 0, 0 as default
|
||
mpTvMainDisplayadapter->TV_setDisplayadapterParam(0,0);
|
||
mpTvMainDisplayadapter->TV_dispAdptCreateLayer();
|
||
mpTvMainDisplayadapter->TV_dispAdptSetLayerZorder(0);
|
||
|
||
int freerun_mode = 0;
|
||
mpAmVideo->AmVideoDeviceIOCtl(AMSTREAM_IOC_SET_FREERUN_MODE, &freerun_mode);
|
||
//CVpp::getInstance()->setVideoaxis();//when open source set video axis full screen
|
||
|
||
tvin_port_t source_port = mpTvin->Tvin_GetSourcePortBySourceInput(source);
|
||
ret = mpTvin->Tvin_OpenPort(source_port);
|
||
mCurrentSource = source;
|
||
mCurrentSourceType = mpTvin->Tvin_SourceInputToSourceInputType(mCurrentSource);
|
||
#ifdef HAVE_AUDIO
|
||
CTvAudio::getInstance()->create_audio_patch(TV_CHANNEL_MAIN, mapSourcetoAudiotupe(source));
|
||
|
||
if (AvAudioMode && SOURCE_TYPE_AV == mCurrentSourceType) {
|
||
CTvAudio::getInstance()->set_audio_av_audio_only_enabled(true);
|
||
CTvAudio::getInstance()->set_audio_av_mute(false);
|
||
} else {
|
||
CTvAudio::getInstance()->set_audio_av_mute(true);
|
||
}
|
||
|
||
#endif
|
||
return ret;
|
||
}
|
||
|
||
int CTv::StopTv(tv_source_input_t source)
|
||
{
|
||
LOGD("%s: source = %d!\n", __FUNCTION__, source);
|
||
int ret = 0;
|
||
if (SOURCE_MPEG == source) {
|
||
LOGD("%s:current source is %d! return\n", __FUNCTION__,source);
|
||
return ret;
|
||
}
|
||
|
||
#ifndef USE_AMVIDEO
|
||
if (meson_fd >= 0) {
|
||
meson_vt_close(meson_fd);
|
||
meson_fd = -1;
|
||
}
|
||
#endif
|
||
|
||
#ifdef HAVE_AUDIO
|
||
CTvAudio::getInstance()->release_audio_patch(TV_CHANNEL_MAIN);
|
||
CTvAudio::getInstance()->set_audio_av_mute(false);
|
||
#endif
|
||
|
||
mpTvWayland->stopMainVideo();
|
||
if (mCurrentPipSource == SOURCE_INVALID) {
|
||
mpTvWayland->shutdown();
|
||
}
|
||
|
||
mpTvMainDisplayadapter->TV_dispAdptDestroyLayer();
|
||
controlScreenColor(VIDEO_LAYER_STATUS_DISABLE);
|
||
mpAmVideo->SetVideoGlobalOutputMode(VIDEO_GLOBAL_OUTPUT_MODE_DISABLE);
|
||
mpTvin->Tvin_StopDecoder();
|
||
tvin_port_t source_port = mpTvin->Tvin_GetSourcePortBySourceInput(source);
|
||
mpTvin->Tvin_ClosePort(source_port);
|
||
|
||
mVdinWorkMode = VDIN_WORK_MODE_VFM;
|
||
mCurrentSource = SOURCE_INVALID;
|
||
mCurrentSourceType = SOURCE_TYPE_MPEG;
|
||
tvin_info_t tempSignalInfo;
|
||
tempSignalInfo.trans_fmt = TVIN_TFMT_2D;
|
||
tempSignalInfo.fmt = TVIN_SIG_FMT_NULL;
|
||
tempSignalInfo.status = TVIN_SIG_STATUS_NULL;
|
||
tempSignalInfo.cfmt = TVIN_COLOR_FMT_MAX;
|
||
tempSignalInfo.signal_type= 0;
|
||
tempSignalInfo.fps = 60;
|
||
tempSignalInfo.is_dvi = 0;
|
||
tempSignalInfo.aspect_ratio = TVIN_ASPECT_NULL;
|
||
SetCurrenSourceInfo(tempSignalInfo);
|
||
|
||
return ret;
|
||
}
|
||
|
||
int CTv::SwitchSource(tv_source_input_t dest_source)
|
||
{
|
||
if (dest_source != mCurrentSource) {
|
||
StopTv(mCurrentSource);
|
||
StartTv(dest_source);
|
||
} else {
|
||
LOGD("same source,no need switch!\n");
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
tv_source_input_t CTv::GetCurrentSource() {
|
||
return mCurrentSource;
|
||
}
|
||
|
||
void CTv::onSourceConnect(int source, int connect_status)
|
||
{
|
||
LOGD("onSourceConnect: source = %d, connect_status= %d!\n", source, connect_status);
|
||
//To do
|
||
TvEvent::SourceConnectEvent event;
|
||
event.mSourceInput = source;
|
||
event.connectionState = connect_status;
|
||
sendTvEvent(event);
|
||
}
|
||
|
||
void CTv::onVdinSignalChange()
|
||
{
|
||
vdin_event_info_s SignalEventInfo;
|
||
memset(&SignalEventInfo, 0, sizeof(vdin_event_info_s));
|
||
int ret = mpTvin->Tvin_GetSignalEventInfo(&SignalEventInfo);
|
||
if (ret < 0) {
|
||
LOGD("Get vidn event error!\n");
|
||
} else {
|
||
tv_source_input_type_t source_type = mpTvin->Tvin_SourceInputToSourceInputType(mCurrentSource);
|
||
tvin_sig_change_flag_t vdinEventType = (tvin_sig_change_flag_t)SignalEventInfo.event_sts;
|
||
switch (vdinEventType) {
|
||
case TVIN_SIG_CHG_SDR2HDR:
|
||
case TVIN_SIG_CHG_HDR2SDR:
|
||
case TVIN_SIG_CHG_DV2NO:
|
||
case TVIN_SIG_CHG_NO2DV: {
|
||
LOGD("%s: hdr info change!\n", __FUNCTION__);
|
||
tvin_info_t vdinSignalInfo;
|
||
memset(&vdinSignalInfo, 0, sizeof(tvin_info_t));
|
||
ret = mpTvin->Tvin_GetSignalInfo(&vdinSignalInfo);
|
||
if (ret < 0) {
|
||
LOGD("%s: Get vidn event error!\n", __FUNCTION__);
|
||
} else {
|
||
if ((mCurrentSignalInfo.status == TVIN_SIG_STATUS_STABLE) && (mCurrentSignalInfo.signal_type != vdinSignalInfo.signal_type)) {
|
||
if (source_type == SOURCE_TYPE_HDMI) {
|
||
//tvSetCurrentHdrInfo(vdinSignalInfo.signal_type);
|
||
}
|
||
mCurrentSignalInfo.signal_type = vdinSignalInfo.signal_type;
|
||
} else {
|
||
LOGD("%s: hdmi signal don't stable!\n", __FUNCTION__);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case TVIN_SIG_CHG_COLOR_FMT:
|
||
LOGD("%s: no need do any thing for colorFmt change!\n", __FUNCTION__);
|
||
break;
|
||
case TVIN_SIG_CHG_RANGE:
|
||
LOGD("%s: no need do any thing for colorRange change!\n", __FUNCTION__);
|
||
break;
|
||
case TVIN_SIG_CHG_BIT:
|
||
LOGD("%s: no need do any thing for color bit deepth change!\n", __FUNCTION__);
|
||
break;
|
||
case TVIN_SIG_CHG_VS_FRQ:
|
||
LOGD("%s: no need do any thing for VS_FRQ change!\n", __FUNCTION__);
|
||
break;
|
||
case TVIN_SIG_CHG_STS:
|
||
LOGD("%s: vdin signal status change!\n", __FUNCTION__);
|
||
onSigStatusChange();
|
||
break;
|
||
case TVIN_SIG_CHG_AFD: {
|
||
LOGD("%s: AFD info change!\n", __FUNCTION__);
|
||
if (source_type == SOURCE_TYPE_HDMI) {
|
||
tvin_info_t newSignalInfo;
|
||
memset(&newSignalInfo, 0, sizeof(tvin_info_t));
|
||
int ret = mpTvin->Tvin_GetSignalInfo(&newSignalInfo);
|
||
if (ret < 0) {
|
||
LOGD("%s: Get Signal Info error!\n", __FUNCTION__);
|
||
} else {
|
||
if ((newSignalInfo.status == TVIN_SIG_STATUS_STABLE)
|
||
&& (mCurrentSignalInfo.aspect_ratio != newSignalInfo.aspect_ratio)) {
|
||
mCurrentSignalInfo.aspect_ratio = newSignalInfo.aspect_ratio;
|
||
//tvSetCurrentAspectRatioInfo(newSignalInfo.aspect_ratio);
|
||
} else {
|
||
LOGD("%s: signal not stable or same AFD info!\n", __FUNCTION__);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case TVIN_SIG_CHG_DV_ALLM:
|
||
LOGD("%s: allm info change!\n", __FUNCTION__);
|
||
if (source_type == SOURCE_TYPE_HDMI) {
|
||
onSigDvAllmChange();
|
||
} else {
|
||
LOGD("%s: not hdmi source!\n", __FUNCTION__);
|
||
}
|
||
break;
|
||
case TVIN_SIG_CHG_VRR:
|
||
LOGD("%s: vrr change!\n", __FUNCTION__);
|
||
if (source_type == SOURCE_TYPE_HDMI) {
|
||
onSigVrrChange();
|
||
} else {
|
||
LOGD("%s: not hdmi source!\n", __FUNCTION__);
|
||
}
|
||
break;
|
||
case TVIN_SIG_CHG_QMS: {
|
||
if (GetHdmiQmsEnabled()) {
|
||
LOGD("%s: QMS change!\n", __FUNCTION__);
|
||
vdin_qms_param_t qmsInfo;
|
||
memset(&qmsInfo, 0, sizeof(vdin_qms_param_t));
|
||
int ret = mpTvin->VDIN_GetQmsParm(&qmsInfo);
|
||
if (ret < 0) {
|
||
LOGD("%s: Get QMS Info error!\n", __FUNCTION__);
|
||
} else if (TVIN_SIG_STATUS_STABLE == mCurrentSignalInfo.status) {
|
||
LOGD("%s: send QMS change event,qms_en:%d, qms_fr:%d, qms_base_fr: %d, fps: %d!\n",
|
||
__FUNCTION__,qmsInfo.qms_en, qmsInfo.qms_fr, qmsInfo.qms_base_fr, mCurrentSignalInfo.fps);
|
||
TvEvent::QMSEvent ev;
|
||
ev.qms_en = (int)qmsInfo.qms_en;
|
||
ev.qms_fps = (int)qmsInfo.qms_fr;
|
||
ev.qms_base_fps = qmsInfo.qms_en ? (int)qmsInfo.qms_base_fr:(int)(mCurrentSignalInfo.fps * 1000);
|
||
sendTvEvent ( ev );
|
||
} else {
|
||
LOGD("%s: invalid qms event!\n", __FUNCTION__);
|
||
}
|
||
} else {
|
||
LOGD("%s: qms switch closed!\n", __FUNCTION__);
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
LOGD("%s: invalid vdin event!\n", __FUNCTION__);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void CTv::onSigDvAllmChange(void)
|
||
{
|
||
tvin_latency_s AllmInfo;
|
||
|
||
int ret = mpTvin->Tvin_GetAllmInfo(&AllmInfo);
|
||
if (ret < 0) {
|
||
LOGE("%s: mpTvin->Tvin_GetAllmInfo() failed!\n", __FUNCTION__);
|
||
return;
|
||
}
|
||
|
||
TvEvent::SignalDvAllmEvent event;
|
||
event.allm_mode = static_cast<int>(AllmInfo.allm_mode);
|
||
event.it_content = AllmInfo.it_content ? 1 : 0;
|
||
event.cn_type = AllmInfo.cn_type;
|
||
sendTvEvent(event);
|
||
}
|
||
|
||
int CTv::GetCurrentSourceAllmInfo(tvin_latency_s *info)
|
||
{
|
||
int ret = mpTvin->Tvin_GetAllmInfo(info);
|
||
if (ret < 0) {
|
||
LOGE("%s: mpTvin->Tvin_GetAllmInfo() failed!\n", __FUNCTION__);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
void CTv::onSigVrrChange(void)
|
||
{
|
||
vdin_vrr_freesync_param_s vrrparm;
|
||
|
||
int ret = mpTvin->VDIN_GetVrrFreesyncParm(&vrrparm);
|
||
if (ret < 0) {
|
||
LOGE("%s: mpTvin->VDIN_GetVrrFreesyncParm() failed!\n", __FUNCTION__);
|
||
return;
|
||
}
|
||
|
||
TvEvent::SignalVrrEvent event;
|
||
event.cur_vrr_status = vrrparm.cur_vrr_status;
|
||
sendTvEvent(event);
|
||
}
|
||
|
||
vdin_vrr_mode_t CTv::GetHdmiVrrMode() {
|
||
vdin_vrr_freesync_param_s vrrparm;
|
||
int ret = mpTvin->VDIN_GetVrrFreesyncParm(&vrrparm);
|
||
if (ret < 0) {
|
||
LOGE("%s: mpTvin->VDIN_GetVrrFreesyncParm() failed!\n", __FUNCTION__);
|
||
return (vdin_vrr_mode_t)0;
|
||
}
|
||
return (vdin_vrr_mode_t)vrrparm.cur_vrr_status;
|
||
}
|
||
|
||
void CTv::onSigStatusChange(void)
|
||
{
|
||
LOGD("%s\n", __FUNCTION__);
|
||
tvin_info_s tempSignalInfo;
|
||
int ret = mpTvin->Tvin_GetSignalInfo(&tempSignalInfo);
|
||
if (ret < 0) {
|
||
LOGD("Get Signal Info error!\n");
|
||
return;
|
||
} else {
|
||
SetCurrenSourceInfo(tempSignalInfo);
|
||
LOGD("sig_fmt is %d, status is %d, isDVI is %d, hdr_info is 0x%x\n",
|
||
mCurrentSignalInfo.fmt, mCurrentSignalInfo.status, mCurrentSignalInfo.is_dvi, mCurrentSignalInfo.signal_type);
|
||
if ( mCurrentSignalInfo.status == TVIN_SIG_STATUS_STABLE ) {
|
||
setDisplayCrop(MAIN_WINDOW);
|
||
onSigToStable();
|
||
} else if (mCurrentSignalInfo.status == TVIN_SIG_STATUS_UNSTABLE ) {
|
||
onSigToUnstable();
|
||
} else if ( mCurrentSignalInfo.status == TVIN_SIG_STATUS_NOTSUP ) {
|
||
onSigToUnSupport();
|
||
} else if ( mCurrentSignalInfo.status == TVIN_SIG_STATUS_NOSIG ) {
|
||
onSigToNoSig();
|
||
} else {
|
||
LOGD("%s: invalid signal status!\n",__FUNCTION__);
|
||
}
|
||
|
||
return;
|
||
}
|
||
}
|
||
|
||
int CTv::SetCurrenSourceInfo(tvin_info_t sig_info)
|
||
{
|
||
mCurrentSignalInfo.trans_fmt = sig_info.trans_fmt;
|
||
mCurrentSignalInfo.fmt = sig_info.fmt;
|
||
mCurrentSignalInfo.status = sig_info.status;
|
||
mCurrentSignalInfo.cfmt = sig_info.cfmt;
|
||
mCurrentSignalInfo.signal_type= sig_info.signal_type;
|
||
mCurrentSignalInfo.fps = sig_info.fps;
|
||
mCurrentSignalInfo.is_dvi = sig_info.is_dvi;
|
||
mCurrentSignalInfo.aspect_ratio = sig_info.aspect_ratio;
|
||
|
||
return 0;
|
||
}
|
||
|
||
tvin_info_t CTv::GetCurrentSourceInfo(void)
|
||
{
|
||
LOGD("mCurrentSource = %d, trans_fmt is %d,fmt is %d, status is %d.\n",
|
||
mCurrentSource, mCurrentSignalInfo.trans_fmt, mCurrentSignalInfo.fmt, mCurrentSignalInfo.status);
|
||
return mCurrentSignalInfo;
|
||
}
|
||
|
||
int CTv::setTvObserver ( TvIObserver *ob )
|
||
{
|
||
LOGD("%s\n", __FUNCTION__);
|
||
if (ob != NULL) {
|
||
mpObserver = ob;
|
||
} else {
|
||
LOGD("%s: Observer is NULL.\n", __FUNCTION__);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
int CTv::SetEdidData(tv_source_input_t source, char *data)
|
||
{
|
||
LOGD("%s\n", __FUNCTION__);
|
||
int ret = -1;
|
||
if (data == NULL) {
|
||
LOGD("%s: data is NULL.\n", __FUNCTION__);
|
||
} else {
|
||
unsigned char edidData[REAL_EDID_DATA_SIZE];
|
||
memcpy(edidData, data, REAL_EDID_DATA_SIZE);
|
||
tvin_port_id_t portId = mpTvin->Tvin_GetHdmiPortIdBySourceInput(source);
|
||
ret = mpHDMIRxManager->UpdataEdidDataWithPort(portId, edidData);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
int CTv::GetEdidData(tv_source_input_t source, char *data)
|
||
{
|
||
char edidData[REAL_EDID_DATA_SIZE];
|
||
char edidFileName[100] = {0};
|
||
int port = (int)source - SOURCE_HDMI1 + 1;
|
||
int edidVer = (GetEdidVersion(source) == HDMI_EDID_VER_20)?20:14;
|
||
char dv_support[4] = {0};
|
||
|
||
const char *edidFilePath = ConfigGetStr(CFG_SECTION_HDMI, CFG_HDMI_EDID_FILE_PATH, "/vendor/etc/tvconfig/hdmi");
|
||
|
||
if (GetDolbyVisionSupportStatus() == 1)
|
||
strcpy(dv_support, "_dv");
|
||
|
||
memset(edidData, 0, REAL_EDID_DATA_SIZE);
|
||
sprintf(edidFileName, "%s/port%d_%d%s.bin", edidFilePath, port, edidVer, dv_support);
|
||
LOGD("%s: EDID file: %s\n", __FUNCTION__, edidFileName);
|
||
ReadDataFromFile(edidFileName, 0, REAL_EDID_DATA_SIZE, edidData);
|
||
memcpy(data, edidData, REAL_EDID_DATA_SIZE);
|
||
return 0;
|
||
}
|
||
|
||
#define MMC_DEVICE ("/dev/mmcblk0")
|
||
#define PANEL_ID_OFFSET 0x9000004
|
||
int CTv::GetPanelSize()
|
||
{
|
||
int fd, len, panelSize=0;
|
||
off_t offset = 0L;
|
||
char buf[2] = {0}, psize[8]={0};
|
||
|
||
if ((fd = open(MMC_DEVICE, O_RDONLY)) < 0) {
|
||
LOGE("open %s error(%s)", MMC_DEVICE, strerror (errno));
|
||
return 0;
|
||
}
|
||
|
||
offset = lseek (fd, PANEL_ID_OFFSET, SEEK_SET);
|
||
if ( offset != PANEL_ID_OFFSET ) {
|
||
LOGE("Failed to seek. offset[0x%x] requested[0x%x]\n", (uint32_t)offset, PANEL_ID_OFFSET);
|
||
close(fd);
|
||
return 0;
|
||
}
|
||
|
||
len = read(fd, buf, 2);
|
||
if (len < 0) {
|
||
LOGE("Read %s error, %s\n", MMC_DEVICE, strerror(errno));
|
||
close(fd);
|
||
return 0;
|
||
}
|
||
sprintf(psize, "%d", buf[1]);
|
||
panelSize = atoi(psize);
|
||
|
||
close(fd);
|
||
return panelSize;
|
||
}
|
||
|
||
int CTv::LoadEdidData(int isNeedBlackScreen, int isDolbyVisionEnable)
|
||
{
|
||
if (isNeedBlackScreen == 1) {
|
||
mpTvin->Tvin_StopDecoder();
|
||
}
|
||
|
||
char edidLoadBuf[(TVIN_PORT_ID_MAX - 1) * 2 * REAL_EDID_DATA_SIZE];
|
||
char edidFileName[100] = {0};
|
||
int loadNum = 1;
|
||
int i = 0;
|
||
tvin_port_t tvin_port = TVIN_PORT_NULL;
|
||
ui_hdmi_port_id_t ui_port = UI_HDMI_PORT_ID_MAX;
|
||
tv_source_input_t source_input;
|
||
const char *edidFilePath = ConfigGetStr(CFG_SECTION_HDMI,
|
||
CFG_HDMI_EDID_FILE_PATH,
|
||
"/vendor/etc/tvconfig/hdmi");
|
||
LOGD("%s: sizeof edidLoadBuf:[%d] isDolbyVisionEnable = %d.\n",
|
||
__FUNCTION__,
|
||
sizeof(edidLoadBuf),
|
||
isDolbyVisionEnable);
|
||
memset(edidLoadBuf, 0, sizeof(edidLoadBuf));
|
||
for (loadNum = (int)TVIN_PORT_ID_1; loadNum < (int)TVIN_PORT_ID_MAX; loadNum++) {
|
||
tvin_port = mpTvin->Tvin_GetVdinPortByVdinPortID((tvin_port_id_t)loadNum);
|
||
source_input = mpTvin->Tvin_PortToSourceInput(tvin_port);
|
||
ui_port = mpTvin->Tvin_GetUIHdmiPortIdBySourceInput(source_input);
|
||
LOGD("%s:tvin port ID:%d tvin_port:0x%x source_input:%d ui_port:%d\n",
|
||
__FUNCTION__,
|
||
loadNum,
|
||
tvin_port,
|
||
source_input,
|
||
ui_port);
|
||
|
||
// Load EDID 1.4 then load EDID 2.0.
|
||
for (i = 0; i < 2; i++) {
|
||
/* sprintf will add a null-terminated character ('\0') at the end of
|
||
the formatted string. So, do not need to memset the buffer.*/
|
||
sprintf(edidFileName, "%s/port%d_%s%s.bin",
|
||
edidFilePath,
|
||
ui_port,
|
||
i ? "20" : "14",
|
||
isDolbyVisionEnable ? "_dv" : "");
|
||
if (!isFileExist(edidFileName))
|
||
sprintf(edidFileName, "%s/port%d_%s%s.bin",
|
||
edidFilePath,
|
||
UI_HDMI_PORT_ID_1,
|
||
i ? "20" : "14",
|
||
isDolbyVisionEnable ? "_dv" : "");
|
||
ReadDataFromFile(edidFileName,
|
||
0,
|
||
REAL_EDID_DATA_SIZE,
|
||
edidLoadBuf + (2 * loadNum - 2 + i) * REAL_EDID_DATA_SIZE);
|
||
LOGD("%s:File:%s\n", __FUNCTION__, edidFileName);
|
||
}
|
||
}
|
||
int ret = mpHDMIRxManager->HdmiRxEdidDataSwitch(2 * K_PORT_NUM, edidLoadBuf);
|
||
if (ret == 0) {
|
||
ui_hdmi_port_id_t portId = UI_HDMI_PORT_ID_MAX;
|
||
int edidSetValue = 0;
|
||
int portEdidVersion = 0;
|
||
for (int i=SOURCE_HDMI1;i<SOURCE_VGA;i++) {
|
||
portId = mpTvin->Tvin_GetUIHdmiPortIdBySourceInput((tv_source_input_t)i);
|
||
portEdidVersion = GetEdidVersion((tv_source_input_t)i);
|
||
edidSetValue |= (portEdidVersion << (4*portId - 4));
|
||
}
|
||
LOGD("%s:[edidSetValue:0x%x]", __FUNCTION__, edidSetValue);
|
||
//for HDMI feature(allm,vrr,qms) status init
|
||
const char *buf = GetUenv(HDMI_UBOOT_EDID_FEATURE);
|
||
int value = 0;
|
||
int allmEnable = 0;
|
||
int VrrEnable = 0;
|
||
int QmsEnable = 0;
|
||
if (buf) {
|
||
value = atoi(buf);
|
||
allmEnable = (value & 1);
|
||
VrrEnable = ((value >> 1) & 1);
|
||
QmsEnable = ((value >> 2) & 1);
|
||
LOGD("%s init HDMI feature status allmEnable:%d, VrrEnable:%d, QmsEnable:%d.\n",
|
||
__FUNCTION__, allmEnable, VrrEnable, QmsEnable);
|
||
mpHDMIRxManager->SetHDMIFeatureInit(allmEnable, VrrEnable, QmsEnable);
|
||
} else {
|
||
allmEnable = mpHDMIRxManager->GetAllmEnabled();
|
||
VrrEnable = mpHDMIRxManager->GetVrrEnabled();
|
||
QmsEnable = mpHDMIRxManager->GetQmsEnabled();
|
||
value = ((QmsEnable << 2)|(VrrEnable << 1)|allmEnable);
|
||
LOGD("%s HDMI feature uenv unexist, save it allmEnable:%d, VrrEnable:%d, QmsEnable:%d.\n",
|
||
__FUNCTION__ , allmEnable, VrrEnable, QmsEnable);
|
||
SetUenv(HDMI_UBOOT_EDID_FEATURE, std::to_string(value).c_str());
|
||
}
|
||
|
||
LOGD("%s [UI sequence] edidSetValue:0x%x\n", __FUNCTION__, edidSetValue);
|
||
ret = mpHDMIRxManager->HdmiRxEdidVerSwitch(edidSetValue);
|
||
} else {
|
||
LOGE("%s failed!\n", __FUNCTION__);
|
||
}
|
||
|
||
return ret;
|
||
|
||
}
|
||
|
||
int CTv::LoadEdidDataWithPort(int isNeedBlackScreen, int isDolbyVisionEnable)
|
||
{
|
||
int ret = 0;
|
||
if (isNeedBlackScreen == 1) {
|
||
mpTvin->Tvin_StopDecoder();
|
||
}
|
||
|
||
char edidFileName[100] = {0};
|
||
int loadNum = 1;
|
||
int i = 0;
|
||
tvin_port_t tvin_port = TVIN_PORT_NULL;
|
||
ui_hdmi_port_id_t ui_port = UI_HDMI_PORT_ID_MAX;
|
||
tv_source_input_t source_input;
|
||
const char *edidFilePath = ConfigGetStr(CFG_SECTION_HDMI,
|
||
CFG_HDMI_EDID_FILE_PATH,
|
||
"/vendor/etc/tvconfig/hdmi");
|
||
|
||
const char *subString = "21";
|
||
bool support21Edid = hasFileWithSubstring(edidFilePath, subString);
|
||
LOGD("%s: isDolbyVisionEnable = [%d], support21Edid = [%d].\n",
|
||
__FUNCTION__, isDolbyVisionEnable, support21Edid);
|
||
|
||
char fileSuffix_14[32] = {0};
|
||
char fileSuffix_20[32] = {0};
|
||
char fileSuffix_21[32] = {0};
|
||
if (isDolbyVisionEnable) {
|
||
strcat(fileSuffix_14, "_dv");
|
||
strcat(fileSuffix_20, "_dv");
|
||
}
|
||
|
||
if (mDlgVisionEnableState) {
|
||
strcat(fileSuffix_20, "_dlg");
|
||
}
|
||
|
||
if (support21Edid) {
|
||
strcpy(fileSuffix_21, fileSuffix_20);
|
||
strcpy(fileSuffix_20, fileSuffix_14);
|
||
}
|
||
|
||
LOGD("%s: 1.4 edid suffix:[%s], 2.0 edid suffix:[%s], 2.1 edid suffix:[%s]\n", __FUNCTION__,
|
||
fileSuffix_14, fileSuffix_20, fileSuffix_21);
|
||
|
||
for (loadNum = (int)TVIN_PORT_ID_1; loadNum < (int)TVIN_PORT_ID_MAX; loadNum++) {
|
||
tvin_port = mpTvin->Tvin_GetVdinPortByVdinPortID((tvin_port_id_t)loadNum);
|
||
source_input = mpTvin->Tvin_PortToSourceInput(tvin_port);
|
||
ui_port = mpTvin->Tvin_GetUIHdmiPortIdBySourceInput(source_input);
|
||
LOGD("%s:tvin port ID:%d tvin_port:0x%x source_input:%d ui_port:%d\n",
|
||
__FUNCTION__,
|
||
loadNum,
|
||
tvin_port,
|
||
source_input,
|
||
ui_port);
|
||
|
||
char edidLoadBuf[3 * REAL_EDID_DATA_SIZE_MAX];
|
||
memset(edidLoadBuf, 0, sizeof(edidLoadBuf));
|
||
int edid_14_size = 0;
|
||
int edid_20_size = 0;
|
||
int edid_21_size = 0;
|
||
|
||
// Load EDID 1.4 then load EDID 2.1 last 2.0
|
||
for (i = 0; i < 3; i++) {
|
||
/* sprintf will add a null-terminated character ('\0') at the end of
|
||
the formatted string. So, do not need to memset the buffer.*/
|
||
sprintf(edidFileName, "%s/port%d_%s%s.bin",
|
||
edidFilePath,
|
||
ui_port,
|
||
i ? (i == 1 ? "21" : "20") : "14",
|
||
i ? (i == 1 ? fileSuffix_21 : fileSuffix_20) : fileSuffix_14);
|
||
if (!isFileExist(edidFileName)) {
|
||
|
||
LOGD("%s: %s, file unexist\n", __FUNCTION__, edidFileName);
|
||
if (i == 2 && support21Edid) {
|
||
LOGD("%s: only load edid 1.4 & 2.1\n", __FUNCTION__);
|
||
break;
|
||
}
|
||
|
||
sprintf(edidFileName, "%s/port%d_%s%s.bin",
|
||
edidFilePath,
|
||
ui_port,
|
||
i ? "20" : "14",
|
||
"");
|
||
}
|
||
|
||
if (i == 0) {
|
||
edid_14_size = GetFileSize(edidFileName);
|
||
} else if (i == 1) {
|
||
edid_21_size = GetFileSize(edidFileName);
|
||
} else if (i == 2) {
|
||
edid_20_size = GetFileSize(edidFileName);
|
||
}
|
||
|
||
ReadDataFromFile(edidFileName,
|
||
0,
|
||
i? (i == 1 ? edid_21_size : edid_20_size) : edid_14_size,
|
||
i? (i == 1 ? (edidLoadBuf + edid_14_size) : (edidLoadBuf + edid_14_size + edid_21_size)) : edidLoadBuf);
|
||
LOGD("%s:File:%s\n", __FUNCTION__, edidFileName);
|
||
}
|
||
edidLoadBuf[edid_14_size +edid_21_size + edid_20_size] = '\0';
|
||
|
||
int type = mpHDMIRxManager->GetHdmiRxLoadEdidType(edid_14_size, edid_21_size, edid_20_size);
|
||
mpHDMIRxManager->HdmiRxLoadEdidDataWithPort(loadNum, type, edid_14_size+edid_21_size+edid_20_size, (unsigned char*)edidLoadBuf);
|
||
}
|
||
|
||
if (mInitEdid) {
|
||
tvin_port_id_t portId = TVIN_PORT_ID_MAX;
|
||
int edidSetValue = 0;
|
||
int portEdidVersion = 0;
|
||
for (int i=SOURCE_HDMI1;i<SOURCE_VGA;i++) {
|
||
portId = mpTvin->Tvin_GetHdmiPortIdBySourceInput((tv_source_input_t)i);
|
||
portEdidVersion = GetEdidVersion((tv_source_input_t)i);
|
||
edidSetValue |= (portEdidVersion << (4*portId - 4));
|
||
}
|
||
LOGD("%s:[edidSetValue:0x%x]", __FUNCTION__, edidSetValue);
|
||
//for HDMI feature(allm,vrr,qms) status init
|
||
const char *buf = GetUenv(HDMI_UBOOT_EDID_FEATURE);
|
||
int value = 0;
|
||
int allmEnable = 0;
|
||
int VrrEnable = 0;
|
||
int QmsEnable = 0;
|
||
if (buf) {
|
||
value = atoi(buf);
|
||
allmEnable = (value & 1);
|
||
VrrEnable = ((value >> 1) & 1);
|
||
QmsEnable = ((value >> 2) & 1);
|
||
LOGD("%s init HDMI feature status allmEnable:%d, VrrEnable:%d, QmsEnable:%d.\n",
|
||
__FUNCTION__, allmEnable, VrrEnable, QmsEnable);
|
||
mpHDMIRxManager->SetHDMIFeatureInit(allmEnable, VrrEnable, QmsEnable);
|
||
} else {
|
||
allmEnable = mpHDMIRxManager->GetAllmEnabled();
|
||
VrrEnable = mpHDMIRxManager->GetVrrEnabled();
|
||
QmsEnable = mpHDMIRxManager->GetQmsEnabled();
|
||
value = ((QmsEnable << 2)|(VrrEnable << 1)|allmEnable);
|
||
LOGD("%s HDMI feature uenv unexist, save it allmEnable:%d, VrrEnable:%d, QmsEnable%d.\n",
|
||
__FUNCTION__ , allmEnable, VrrEnable, QmsEnable);
|
||
SetUenv(HDMI_UBOOT_EDID_FEATURE, std::to_string(value).c_str());
|
||
}
|
||
|
||
LOGD("%s [UI sequence] edidSetValue:0x%x\n", __FUNCTION__, edidSetValue);
|
||
ret = mpHDMIRxManager->HdmiRxEdidVerSwitch(edidSetValue);
|
||
}
|
||
mInitEdid = false;
|
||
|
||
for (int i=TVIN_PORT_ID_1;i<TVIN_PORT_ID_MAX;i++) {
|
||
mpHDMIRxManager->HdmiRxEdidUpdateWithPort(i);
|
||
}
|
||
|
||
return ret;
|
||
|
||
}
|
||
|
||
int CTv::SetEdidVersion(tv_source_input_t source, int edidVer)
|
||
{
|
||
LOGD("%s: setSource: %d, setVersion: %d\n", __FUNCTION__, source, edidVer);
|
||
int ret = -1;
|
||
int currentVersion = GetEdidVersion(source);
|
||
if (currentVersion != edidVer) {
|
||
mpTvin->Tvin_StopDecoder();
|
||
tvin_port_id_t portId = TVIN_PORT_ID_MAX;
|
||
int edidSetValue = 0;
|
||
//We have already set the port map to kernel.So we should use UI sequence.
|
||
int portEdidVersion = 0;
|
||
for (int i=SOURCE_HDMI1;i<SOURCE_VGA;i++) {
|
||
portId = mpTvin->Tvin_GetHdmiPortIdBySourceInput((tv_source_input_t)i);
|
||
if (i == source) {
|
||
portEdidVersion = edidVer;
|
||
} else {
|
||
portEdidVersion = GetEdidVersion((tv_source_input_t)i);
|
||
}
|
||
edidSetValue |= (portEdidVersion << (4*portId - 4));
|
||
}
|
||
LOGD("%s [UI sequence] edidSetValue:0x%x\n", __FUNCTION__, edidSetValue);
|
||
ret = mpHDMIRxManager->HdmiRxEdidVerSwitch(edidSetValue);
|
||
if (mCurrentSource == source) {
|
||
//mpHDMIRxManager->HDMIRxDeviceIOCtl(HDMI_IOC_EDID_UPDATE);
|
||
tvin_port_id_t port = mpTvin->Tvin_GetHdmiPortIdBySourceInput(mCurrentSource);
|
||
mpHDMIRxManager->HdmiRxEdidUpdateWithPort((int)port);
|
||
}
|
||
if (ret < 0) {
|
||
LOGE("%s failed.\n", __FUNCTION__);
|
||
ret = -1;
|
||
} else {
|
||
/*
|
||
switch (source) {
|
||
case SOURCE_HDMI1:
|
||
Hdmi1CurrentEdidVer = edidVer;
|
||
break;
|
||
case SOURCE_HDMI2:
|
||
Hdmi2CurrentEdidVer = edidVer;
|
||
break;
|
||
case SOURCE_HDMI3:
|
||
Hdmi3CurrentEdidVer = edidVer;
|
||
break;
|
||
case SOURCE_HDMI4:
|
||
Hdmi4CurrentEdidVer = edidVer;
|
||
break;
|
||
default:
|
||
LOGD("%s: not hdmi source.\n", __FUNCTION__);
|
||
break;
|
||
}
|
||
*/
|
||
SetUenv(HDMI_UBOOT_EDID_VERSION, std::to_string(edidSetValue).c_str());
|
||
}
|
||
} else {
|
||
LOGD("%s: same EDID version, no need set.\n", __FUNCTION__);
|
||
ret = 0;
|
||
}
|
||
|
||
return ret;
|
||
|
||
}
|
||
|
||
int CTv::GetEdidVersion(tv_source_input_t source)
|
||
{
|
||
//TODO:add user setting read/write flow
|
||
int retValue = HDMI_EDID_VER_14;
|
||
const char *buf = GetUenv(HDMI_UBOOT_EDID_VERSION);
|
||
int version = 0;
|
||
tvin_port_id_t port_id = TVIN_PORT_ID_MAX;
|
||
if (buf) {
|
||
version = atoi(buf);
|
||
}
|
||
port_id = mpTvin->Tvin_GetHdmiPortIdBySourceInput(source);
|
||
switch (port_id) {
|
||
case TVIN_PORT_ID_1:
|
||
//retValue = Hdmi1CurrentEdidVer;
|
||
retValue = version & 0xf;
|
||
break;
|
||
case TVIN_PORT_ID_2:
|
||
//retValue = Hdmi2CurrentEdidVer;
|
||
retValue = (version >> 4) & 0xf;
|
||
break;
|
||
case TVIN_PORT_ID_3:
|
||
//retValue = Hdmi3CurrentEdidVer;
|
||
retValue = (version >> 8) & 0xf;
|
||
break;
|
||
case TVIN_PORT_ID_4:
|
||
//retValue = Hdmi4CurrentEdidVer;
|
||
retValue = (version >> 12) & 0xf;
|
||
break;
|
||
default:
|
||
LOGD("%s: not hdmi source.\n", __FUNCTION__);
|
||
break;
|
||
}
|
||
return retValue;
|
||
}
|
||
|
||
int CTv::SetVdinWorkMode(vdin_work_mode_t vdinWorkMode)
|
||
{
|
||
mVdinWorkMode = vdinWorkMode;
|
||
return 0;
|
||
}
|
||
|
||
int CTv::GetHdmiSPDInfo(tv_source_input_t source, char* data, size_t datalen)
|
||
{
|
||
if (mCurrentSource < SOURCE_HDMI1 || mCurrentSource > SOURCE_HDMI4) {
|
||
LOGE("Current source is not HDMI input source.\n");
|
||
return -1;
|
||
}
|
||
if (source != mCurrentSource) {
|
||
LOGE("%d is not current input source, skipped.\n", source);
|
||
return -1;
|
||
}
|
||
|
||
int ret = -1;
|
||
struct spd_infoframe_st spd;
|
||
|
||
memset(&spd, 0, sizeof(spd));
|
||
ret = mpHDMIRxManager->HdmiRxGetSPDInfoframe(&spd);
|
||
if (ret < 0) {
|
||
LOGE("Get SPD infoframe from HDMIRX manager failed.\n");
|
||
} else {
|
||
if (datalen > sizeof(spd)) {
|
||
memcpy(data, &spd, sizeof(spd));
|
||
} else {
|
||
memcpy(data, &spd, datalen);
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
int CTv::GetFrontendInfo(tvin_frontend_info_t *frontendInfo)
|
||
{
|
||
int ret = -1;
|
||
if (frontendInfo == NULL) {
|
||
LOGD("%s: param is NULL.\n", __FUNCTION__);
|
||
} else {
|
||
ret = mpTvin->Tvin_GetFrontendInfo(frontendInfo);
|
||
/*LOGD("%s: scan mode:%d, colorfmt:%d, fps:%d, width:%d, height:%d, colordepth:%d.\n", __FUNCTION__, frontendInfo->scan_mode, frontendInfo->cfmt,
|
||
frontendInfo->fps,frontendInfo->width,frontendInfo->height,frontendInfo->colordepth);*/
|
||
}
|
||
|
||
if (ret < 0) {
|
||
LOGE("%s failed.\n", __FUNCTION__);
|
||
} else {
|
||
LOGD("%s success.\n", __FUNCTION__);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
int CTv::SetCurrentSourceColorRange(tvin_color_range_t range_mode)
|
||
{
|
||
int ret = -1;
|
||
if ((range_mode >= TVIN_COLOR_RANGE_MAX) || (range_mode <TVIN_COLOR_RANGE_AUTO)) {
|
||
LOGD("%s: invalid range mode.\n", __FUNCTION__);
|
||
} else {
|
||
ret = mpTvin->Tvin_SetColorRangeMode(range_mode);
|
||
}
|
||
|
||
if (ret < 0) {
|
||
LOGE("%s failed.\n", __FUNCTION__);
|
||
} else {
|
||
LOGD("%s success.\n", __FUNCTION__);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
tvin_color_range_t CTv::GetCurrentSourceColorRange()
|
||
{
|
||
int ret = mpTvin->Tvin_GetColorRangeMode();
|
||
LOGD("%s: mode is %d.\n", __FUNCTION__, ret);
|
||
|
||
return (tvin_color_range_t)ret;
|
||
}
|
||
|
||
int CTv::GetSourceConnectStatus(tv_source_input_t source)
|
||
{
|
||
return mTvDevicesPollDetect.GetSourceConnectStatus(source);
|
||
}
|
||
|
||
int CTv::SetEdidBoostOn(int bBoostOn)
|
||
{
|
||
int ret = -1;
|
||
if (mBoostOn == bBoostOn ) {
|
||
LOGD("%s: same EDIDs are loaded for %d, no more action\n", __FUNCTION__, bBoostOn);
|
||
return 0;
|
||
} else {
|
||
LOGD("%s: mBoostOn=%d to be switched to %d\n", __FUNCTION__, mBoostOn, bBoostOn);
|
||
// pass flag for dynamic loading EDID data, switch data to kernel and switch version.
|
||
mBoostOn = bBoostOn;
|
||
ret = LoadEdidDataWithPort(0, mDolbyVisionEnableState);
|
||
return ret;
|
||
}
|
||
}
|
||
|
||
void CTv::onSigToStable()
|
||
{
|
||
LOGD("%s: mVdinWorkMode is %d\n", __FUNCTION__, mVdinWorkMode);
|
||
mpTvin->Tvin_StartDecoder(mCurrentSignalInfo);
|
||
|
||
#ifdef HAVE_AUDIO
|
||
tv_source_input_type_t sourceType = mpTvin->Tvin_SourceInputToSourceInputType(mCurrentSource);
|
||
LOGD("%s: mCurrent sourceType[%d], is_dvi[%d]\n", __FUNCTION__, sourceType, mCurrentSignalInfo.is_dvi);
|
||
if (SOURCE_TYPE_HDMI == sourceType && mCurrentSignalInfo.is_dvi) {
|
||
LOGD("%s: DVI signal, change audio to linein\n", __FUNCTION__);
|
||
CTvAudio::getInstance()->release_audio_patch(TV_CHANNEL_MAIN);
|
||
CTvAudio::getInstance()->create_audio_patch(TV_CHANNEL_MAIN, AUDIO_DEVICE_IN_LINE);
|
||
}
|
||
|
||
CTvAudio::getInstance()->set_audio_av_mute(false);
|
||
#endif
|
||
|
||
CMessage msg;
|
||
msg.mDelayMs = std::chrono::milliseconds(0);
|
||
msg.mType = CTvMsgQueue::TV_MSG_ENABLE_VIDEO_LATER;
|
||
msg.mpPara[0] = 5;
|
||
mTvMsgQueue->sendMsg ( msg );
|
||
|
||
//send signal to apk
|
||
TvEvent::SignalDetectEvent event;
|
||
event.mSourceInput = mCurrentSource;
|
||
event.mFmt = mCurrentSignalInfo.fmt;
|
||
event.mTrans_fmt = mCurrentSignalInfo.trans_fmt;
|
||
event.mStatus = mCurrentSignalInfo.status;
|
||
event.mDviFlag = mCurrentSignalInfo.is_dvi;
|
||
event.mhdr_info = mCurrentSignalInfo.signal_type;
|
||
sendTvEvent(event);
|
||
|
||
tv_source_input_type_t source_type = mpTvin->Tvin_SourceInputToSourceInputType(mCurrentSource);
|
||
if (source_type == SOURCE_TYPE_HDMI && true == GetHdmiQmsEnabled()) {
|
||
sendQmsEvent();
|
||
}
|
||
|
||
}
|
||
|
||
void CTv::onSigToUnstable()
|
||
{
|
||
|
||
controlScreenColor(VIDEO_LAYER_STATUS_DISABLE);
|
||
mpTvin->Tvin_StopDecoder();
|
||
|
||
#ifdef HAVE_AUDIO
|
||
if (!(AvAudioMode && SOURCE_TYPE_AV == mCurrentSourceType))
|
||
CTvAudio::getInstance()->set_audio_av_mute(true);
|
||
#endif
|
||
|
||
LOGD("signal to Unstable!\n");
|
||
//To do
|
||
}
|
||
|
||
void CTv::onSigToUnSupport()
|
||
{
|
||
LOGD("%s\n", __FUNCTION__);
|
||
|
||
controlScreenColor(VIDEO_LAYER_STATUS_DISABLE);
|
||
mpTvin->Tvin_StopDecoder();
|
||
|
||
#ifdef HAVE_AUDIO
|
||
if (!(AvAudioMode && SOURCE_TYPE_AV == mCurrentSourceType))
|
||
CTvAudio::getInstance()->set_audio_av_mute(true);
|
||
#endif
|
||
|
||
TvEvent::SignalDetectEvent event;
|
||
event.mSourceInput = mCurrentSource;
|
||
event.mFmt = mCurrentSignalInfo.fmt;
|
||
event.mTrans_fmt = mCurrentSignalInfo.trans_fmt;
|
||
event.mStatus = mCurrentSignalInfo.status;
|
||
event.mDviFlag = mCurrentSignalInfo.is_dvi;
|
||
event.mhdr_info = mCurrentSignalInfo.signal_type;
|
||
sendTvEvent(event);
|
||
//To do
|
||
}
|
||
|
||
void CTv::onSigToNoSig()
|
||
{
|
||
LOGD("%s\n", __FUNCTION__);
|
||
|
||
if (needSnowEffect()) {
|
||
SetSnowShowEnable(true);
|
||
mpTvin->Tvin_StartDecoder(mCurrentSignalInfo);
|
||
controlScreenColor(VIDEO_LAYER_STATUS_ENABLE);
|
||
|
||
} else {
|
||
LOGD("%s video layer has disabled \n", __FUNCTION__);
|
||
controlScreenColor(VIDEO_LAYER_STATUS_DISABLE);
|
||
mpTvin->Tvin_StopDecoder();
|
||
|
||
#ifdef HAVE_AUDIO
|
||
if (!(AvAudioMode && SOURCE_TYPE_AV == mCurrentSourceType))
|
||
CTvAudio::getInstance()->set_audio_av_mute(true);
|
||
#endif
|
||
}
|
||
|
||
TvEvent::SignalDetectEvent event;
|
||
event.mSourceInput = mCurrentSource;
|
||
event.mFmt = mCurrentSignalInfo.fmt;
|
||
event.mTrans_fmt = mCurrentSignalInfo.trans_fmt;
|
||
event.mStatus = mCurrentSignalInfo.status;
|
||
event.mDviFlag = mCurrentSignalInfo.is_dvi;
|
||
event.mhdr_info = mCurrentSignalInfo.signal_type;
|
||
sendTvEvent (event);
|
||
//To do
|
||
}
|
||
|
||
bool CTv::needSnowEffect()
|
||
{
|
||
bool isEnable = false;
|
||
LOGD("%s: mCurrentSource = [%d].\n", __FUNCTION__,mCurrentSource);
|
||
if ((SOURCE_TV == mCurrentSource) && mATVDisplaySnow ) {
|
||
isEnable = true;
|
||
LOGD("%s: ATV:snow display is enabled.\n", __FUNCTION__);
|
||
} else {
|
||
LOGD("%s: ATV:snow display is disabled.\n", __FUNCTION__);
|
||
}
|
||
|
||
return isEnable;
|
||
}
|
||
|
||
int CTv::SetSnowShowEnable(bool enable)
|
||
{
|
||
LOGD("%s: enable = [%d]\n", __FUNCTION__ , enable);
|
||
if (enable) {
|
||
mLastScreenMode = CVpp::getInstance()->getVideoScreenMode();
|
||
LOGD("%s: Get LastScreenMode = %d\n", __FUNCTION__, mLastScreenMode);
|
||
CVpp::getInstance()->setVideoScreenMode(1);//while show snow,need show full screen
|
||
} else {
|
||
LOGD("%s: Set LastScreenMode = %d\n", __FUNCTION__, mLastScreenMode);
|
||
CVpp::getInstance()->setVideoScreenMode(mLastScreenMode);
|
||
}
|
||
return mpTvin->Tvin_SwitchSnow(enable);
|
||
}
|
||
|
||
int CTv::sendTvEvent(CTvEvent &event)
|
||
{
|
||
LOGD("%s\n", __FUNCTION__);
|
||
|
||
if (mpObserver != NULL) {
|
||
mpObserver->onTvEvent(event);
|
||
} else {
|
||
LOGD("%s: Observer is NULL.\n", __FUNCTION__);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
#ifdef HAVE_AUDIO
|
||
int CTv::mapSourcetoAudiotupe(tv_source_input_t dest_source)
|
||
{
|
||
int ret = -1;
|
||
switch (dest_source) {
|
||
case SOURCE_TV:
|
||
ret = AUDIO_DEVICE_IN_TV_TUNER;
|
||
break;
|
||
case SOURCE_AV1:
|
||
case SOURCE_AV2:
|
||
ret = AUDIO_DEVICE_IN_LINE;
|
||
break;
|
||
case SOURCE_HDMI1:
|
||
case SOURCE_HDMI2:
|
||
case SOURCE_HDMI3:
|
||
case SOURCE_HDMI4:
|
||
ret = AUDIO_DEVICE_IN_HDMI;
|
||
break;
|
||
case SOURCE_SPDIF:
|
||
ret = AUDIO_DEVICE_IN_SPDIF;
|
||
break;
|
||
default:
|
||
ret = AUDIO_DEVICE_IN_LINE;
|
||
break;
|
||
}
|
||
return ret;
|
||
}
|
||
#endif
|
||
|
||
bool CTv::GetDolbyVisionSupportStatus(void) {
|
||
//return dv support info from current platform device, not display device.
|
||
char buf[1024+1] = {0};
|
||
int fd, len;
|
||
bool ret = false;
|
||
|
||
/*bit0: 0-> efuse, 1->no efuse; */
|
||
/*bit1: 1-> ko loaded*/
|
||
/*bit2: 1-> value updated*/
|
||
/*bit3: 1-> tv */
|
||
int supportInfo = 0;
|
||
|
||
constexpr int dvDriverEnabled = (1 << 2);
|
||
constexpr int dvSupported = ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3 ));
|
||
|
||
if ((fd = open(SYS_DOLBYVISION_SUPPORT_INFO, O_RDONLY)) < 0) {
|
||
LOGE("open %s fail.\n", SYS_DOLBYVISION_SUPPORT_INFO);
|
||
return false;
|
||
} else {
|
||
if ((len = read(fd, buf, 1024)) < 0) {
|
||
LOGE("read %s error: %s\n", SYS_DOLBYVISION_SUPPORT_INFO, strerror(errno));
|
||
ret = false;
|
||
} else if (sscanf(buf, "%d", &supportInfo) == 1) {
|
||
if ((supportInfo & dvDriverEnabled) == 0) {
|
||
LOGD("%s is not ready\n",SYS_DOLBYVISION_SUPPORT_INFO);
|
||
}
|
||
ret = ((supportInfo & dvSupported) == dvSupported) ? true : false;
|
||
}
|
||
|
||
close(fd);
|
||
return ret;
|
||
}
|
||
}
|
||
|
||
int CTv::SetHdmiAllmEnabled(bool enable)
|
||
{
|
||
LOGD("%s: [%s]\n", __FUNCTION__, enable == 1?"enable":"disable");
|
||
const char *buf = GetUenv(HDMI_UBOOT_EDID_FEATURE);
|
||
int saveValue = 0;
|
||
if (buf) {
|
||
saveValue = atoi(buf);
|
||
if ((saveValue & 0x1) == enable) {
|
||
LOGD("%s: same status return!\n", __FUNCTION__);
|
||
return 0;
|
||
}
|
||
}
|
||
muteVideoOnHDMISource();
|
||
saveValue = enable|(saveValue & ~0b1);
|
||
SetUenv(HDMI_UBOOT_EDID_FEATURE, std::to_string(saveValue).c_str());
|
||
return mpHDMIRxManager->SetAllmEnabled(enable);
|
||
}
|
||
|
||
bool CTv::GetHdmiAllmEnabled()
|
||
{
|
||
bool ret = mpHDMIRxManager->GetAllmEnabled();
|
||
LOGD("%s: [%d]\n", __FUNCTION__, ret);
|
||
return ret;
|
||
}
|
||
|
||
bool CTv::GetHdmiVrrSupport()
|
||
{
|
||
bool ret = false;
|
||
ret = CVrr::getInstance()->GetVrrSupport();
|
||
return ret;
|
||
}
|
||
|
||
int CTv::SetHdmiVrrEnabled(bool enable)
|
||
{
|
||
LOGD("%s: [%s]\n", __FUNCTION__, enable == 1?"enable":"disable");
|
||
const char*buf = GetUenv(HDMI_UBOOT_EDID_FEATURE);
|
||
int saveValue = 0;
|
||
if (buf) {
|
||
saveValue = atoi(buf);
|
||
if ((saveValue >> 1) == enable) {
|
||
LOGD("%s: same status return!\n", __FUNCTION__);
|
||
return 0;
|
||
}
|
||
}
|
||
muteVideoOnHDMISource();
|
||
saveValue = (enable << 1)|(saveValue & ~0b10);
|
||
SetUenv(HDMI_UBOOT_EDID_FEATURE, std::to_string(saveValue).c_str());
|
||
return mpHDMIRxManager->SetVrrEnabled(enable);
|
||
}
|
||
|
||
bool CTv::GetHdmiVrrEnabled()
|
||
{
|
||
bool ret = mpHDMIRxManager->GetVrrEnabled();
|
||
LOGD("%s: [%d]\n", __FUNCTION__, ret);
|
||
return ret;
|
||
}
|
||
|
||
bool CTv::GetHdmiQmsSupport()
|
||
{
|
||
int ret = 0;
|
||
ret = ConfigGetInt(CFG_SECTION_HDMI, CFG_HDMI_QMS_SUPPORT, 0);
|
||
LOGD("%s:%d !\n",__FUNCTION__, ret);
|
||
return ret?true:false;
|
||
}
|
||
|
||
int CTv::SetHdmiQmsEnabled (bool enable) {
|
||
int ret = -1;
|
||
LOGD("%s: Set QMS enable = [%d]\n", __FUNCTION__, enable);
|
||
const char*buf = GetUenv(HDMI_UBOOT_EDID_FEATURE);
|
||
int saveValue = 0;
|
||
if (buf) {
|
||
saveValue = atoi(buf);
|
||
if (((saveValue >> 2) & 1) == enable) {
|
||
LOGD("%s: same status return!\n", __FUNCTION__);
|
||
return 0;
|
||
}
|
||
}
|
||
saveValue = (enable << 2)|(saveValue & ~0b100);
|
||
SetUenv(HDMI_UBOOT_EDID_FEATURE, std::to_string(saveValue).c_str());
|
||
// RX request:
|
||
//qms_func_ctrl only close qms, reopen qms need reload edid
|
||
if (enable) {
|
||
char buf[8] = {0};
|
||
sprintf(buf, "%d", enable);
|
||
tvWriteSysfs(QMS_FUNC_CTRL_PATH, buf);
|
||
bool dolbyVisionEnableState = GetDolbyVisionSupportStatus();
|
||
ret = LoadEdidDataWithPort(1, dolbyVisionEnableState);
|
||
return ret;
|
||
} else {
|
||
return mpHDMIRxManager->SetQmsEnabled(enable);
|
||
}
|
||
|
||
}
|
||
|
||
bool CTv::GetHdmiQmsEnabled(void) {
|
||
int qmsEnable = 0;
|
||
const char*buf = GetUenv(HDMI_UBOOT_EDID_FEATURE);
|
||
int saveValue = 0;
|
||
if (buf) {
|
||
saveValue = atoi(buf);
|
||
qmsEnable = ((saveValue >> 2) & 1);
|
||
}
|
||
LOGD("%s:QMS status [%d] !\n",__FUNCTION__,qmsEnable);
|
||
return (bool)qmsEnable;
|
||
}
|
||
|
||
void CTv::sendQmsEvent(void)
|
||
{
|
||
LOGD("%s\n", __FUNCTION__);
|
||
vdin_qms_param_t qmsInfo;
|
||
memset(&qmsInfo, 0, sizeof(vdin_qms_param_t));
|
||
int ret = mpTvin->VDIN_GetQmsParm(&qmsInfo);
|
||
if (ret < 0) {
|
||
LOGD("%s: Get QMS Info error!\n", __FUNCTION__);
|
||
} else {
|
||
if ((int)qmsInfo.qms_en == 0) {
|
||
LOGD("%s: non-qms signal,return!\n", __FUNCTION__);
|
||
return;
|
||
}
|
||
LOGD("%s: send QMS change event, new fps:%d!\n", __FUNCTION__, qmsInfo.qms_fr);
|
||
TvEvent::QMSEvent ev;
|
||
ev.qms_en = (int)qmsInfo.qms_en;
|
||
ev.qms_fps = (int)qmsInfo.qms_fr;
|
||
ev.qms_base_fps = (int)qmsInfo.qms_base_fr;
|
||
sendTvEvent ( ev );
|
||
}
|
||
}
|
||
|
||
int CTv::SetHdmiDlgEnabled(bool enable)
|
||
{
|
||
int ret = -1;
|
||
if (GetHdmiDlgSupport()) {
|
||
LOGD("%s:update DLG EDID status, new status = [%d]!\n",__FUNCTION__,enable);
|
||
mDlgVisionEnableState = enable;
|
||
bool dolbyVisionEnableState = GetDolbyVisionSupportStatus();
|
||
ret = LoadEdidDataWithPort(0, dolbyVisionEnableState);
|
||
if ( 0 == ret ) {
|
||
LOGD("%s:update DLG EDID status success!\n",__FUNCTION__);
|
||
const char*buf = GetUenv(HDMI_UBOOT_EDID_FEATURE);
|
||
int saveValue = 0;
|
||
if (buf) {
|
||
saveValue = atoi(buf);
|
||
if (((saveValue >> 3) & 1) == enable) {
|
||
LOGD("%s: same status return!\n", __FUNCTION__);
|
||
return ret;
|
||
}
|
||
}
|
||
saveValue = (enable << 3)|(saveValue & ~0b1000);
|
||
SetUenv(HDMI_UBOOT_EDID_FEATURE, std::to_string(saveValue).c_str());
|
||
} else {
|
||
LOGD("%s:update DLG EDID status fail!\n",__FUNCTION__);
|
||
}
|
||
}else {
|
||
LOGE("%s:unsupport DLG func,return !\n",__FUNCTION__);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
bool CTv::GetHdmiDlgEnabled()
|
||
{
|
||
int dlgEnable = 0;
|
||
const char*buf = GetUenv(HDMI_UBOOT_EDID_FEATURE);
|
||
int saveValue = 0;
|
||
if (buf) {
|
||
saveValue = atoi(buf);
|
||
dlgEnable = ((saveValue >> 3) & 1);
|
||
}
|
||
LOGD("%s:QMS status [%d] !\n",__FUNCTION__,dlgEnable);
|
||
return (bool)dlgEnable;
|
||
}
|
||
|
||
bool CTv::GetHdmiDlgSupport()
|
||
{
|
||
bool ret = false;
|
||
char buf[1024] = {0};
|
||
ret = tvReadSysfs(DLG_FUNC_PATH, buf);
|
||
LOGD("%s: %s\n", __FUNCTION__, buf);
|
||
if (ret < 0) {
|
||
LOGD("%s: read /sys/class/display/cap error, return!\n",__FUNCTION__);
|
||
return ret;
|
||
}
|
||
|
||
std::string parm = buf;
|
||
|
||
//if 4k1k && 4k2k exist,support dlg
|
||
std::string support4K1K = "3840x1080";
|
||
//The format of 4K2K includes the following variants
|
||
std::string support4K2K_1 = "3840x2160";
|
||
std::string support4K2K_2 = "2160p60hz";
|
||
std::string support4K2K_3 = "4k2k60hz";
|
||
if ((parm.find(support4K1K) != -1)
|
||
&& ((parm.find(support4K2K_1) != -1)
|
||
|| (parm.find(support4K2K_2) != -1)
|
||
|| (parm.find(support4K2K_3) != -1))) {
|
||
LOGD("%s: find exist!\n",__FUNCTION__);
|
||
ret = true;
|
||
}else{
|
||
LOGD("%s: unsupport DLG func,return!\n",__FUNCTION__);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
void CTv::muteVideoOnHDMISource() {
|
||
if (mCurrentSource < SOURCE_HDMI1 || mCurrentSource > SOURCE_HDMI4) {
|
||
return;
|
||
}
|
||
controlScreenColor(VIDEO_LAYER_STATUS_DISABLE);
|
||
}
|
||
|
||
int CTv::GetCurrentStdInfo (struct tvin_std_s *info)
|
||
{
|
||
int ret = 0;
|
||
memset(info, 0 , sizeof(struct tvin_std_s));
|
||
info->source = mCurrentSource;
|
||
info->edid_version = GetEdidVersion(mCurrentSource);
|
||
info->allm_enabled = GetHdmiAllmEnabled();
|
||
info->vrr_enabled = GetHdmiVrrEnabled();
|
||
info->qms_enabled = GetHdmiQmsEnabled();
|
||
LOGD("%s: source:[%d], edid_version:[%d], allm:[%d], vrr:[%d], qms:[%d]",__FUNCTION__,
|
||
info->source, info->edid_version, info->allm_enabled, info->vrr_enabled, info->qms_enabled);
|
||
return ret;
|
||
}
|
||
|
||
void CTv::isVideoFrameAvailable(unsigned int u32NewFrameCount)
|
||
{
|
||
unsigned int u32TimeOutCount = 0;
|
||
unsigned int frameCount = 0;
|
||
while (true) {
|
||
frameCount = (unsigned int)mpAmVideo->GetVideoFrameCount();
|
||
if (frameCount >= u32NewFrameCount) {
|
||
LOGD("%s video available\n", __FUNCTION__);
|
||
break;
|
||
} else {
|
||
if (u32TimeOutCount >= NEW_FRAME_TIME_OUT_COUNT) {
|
||
LOGD("%s Not available frame\n", __FUNCTION__);
|
||
break;
|
||
}
|
||
}
|
||
LOGD("%s new frame count = %d, get time = %d\n",__FUNCTION__, frameCount, u32TimeOutCount);
|
||
usleep(50*1000);
|
||
u32TimeOutCount++;
|
||
}
|
||
controlScreenColor(VIDEO_LAYER_STATUS_ENABLE);
|
||
mpAmVideo->SetVideoGlobalOutputMode(VIDEO_GLOBAL_OUTPUT_MODE_ENABLE);
|
||
}
|
||
|
||
int CTv::SetAudioDecoderId(int channel, int id)
|
||
{
|
||
#ifdef HAVE_AUDIO
|
||
CTvAudio::getInstance()->set_audio_decoder_id(channel, id);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
int CTv::SetAvAudioModeEnabled (bool enable)
|
||
{
|
||
LOGD("%s endable = %s\n",__FUNCTION__, enable ? "enable":"disable");
|
||
AvAudioMode = enable;
|
||
return 0;
|
||
}
|
||
|
||
bool CTv::IsSupportPIP()
|
||
{
|
||
bool ret = false;
|
||
if (isFileExist("/dev/vdin2")) {
|
||
LOGD("%s: support HDMI PIP\n",__FUNCTION__);
|
||
ret = true;
|
||
} else {
|
||
LOGD("%s: unsupport HDMI PIP\n",__FUNCTION__);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
int CTv::SetCurrentPipSourceInfo(tvin_info_t sig_info)
|
||
{
|
||
mCurrentPipSignalInfo.trans_fmt = sig_info.trans_fmt;
|
||
mCurrentPipSignalInfo.fmt = sig_info.fmt;
|
||
mCurrentPipSignalInfo.status = sig_info.status;
|
||
mCurrentPipSignalInfo.cfmt = sig_info.cfmt;
|
||
mCurrentPipSignalInfo.signal_type= sig_info.signal_type;
|
||
mCurrentPipSignalInfo.fps = sig_info.fps;
|
||
mCurrentPipSignalInfo.is_dvi = sig_info.is_dvi;
|
||
mCurrentPipSignalInfo.aspect_ratio = sig_info.aspect_ratio;
|
||
|
||
return 0;
|
||
}
|
||
|
||
void CTv::setDisplayCrop(int source)
|
||
{
|
||
tvin_frontend_info_t frontendInfo;
|
||
tv_rect crop;
|
||
memset(&crop, 0, sizeof(tv_rect));
|
||
if (source == MAIN_WINDOW) {
|
||
mpTvin->Tvin_GetFrontendInfo(&frontendInfo);
|
||
crop.w = frontendInfo.width;
|
||
crop.h = frontendInfo.height;
|
||
mpTvMainDisplayadapter->TV_dispAdptSetLayerSourceCrop(crop);
|
||
} else if (source == SUB_WINDOW && mpTvSubDisplayadapter != nullptr) {
|
||
mpPipTvin->Tvin_GetFrontendInfo(&frontendInfo);
|
||
crop.w = frontendInfo.width;
|
||
crop.h = frontendInfo.height;
|
||
mpTvSubDisplayadapter->TV_dispAdptSetLayerSourceCrop(crop);
|
||
}
|
||
}
|
||
|
||
int CTv::StartTvInPIP ( tv_source_input_t source )
|
||
{
|
||
if (nullptr == mpPipTvin) {
|
||
LOGD("%s: unsupport PIP return!\n", __FUNCTION__);
|
||
return 0;
|
||
}
|
||
|
||
LOGD("%s: source = %d!\n", __FUNCTION__, source);
|
||
int ret = 0;
|
||
|
||
mpTvWayland->setPipTunnelId(1);
|
||
mpTvWayland->startPipVideo();
|
||
mpTvWayland->commitAll();
|
||
|
||
//sub source set 1, 3 as default
|
||
mpTvMainDisplayadapter->TV_setDisplayadapterParam(1,3);
|
||
mpTvMainDisplayadapter->TV_dispAdptCreateLayer();
|
||
//value limit in {0,64} and big than main
|
||
mpTvMainDisplayadapter->TV_dispAdptSetLayerZorder(1);
|
||
|
||
tvin_port_t source_port = mpPipTvin->Tvin_GetSourcePortBySourceInput(source);
|
||
ret = mpPipTvin->Tvin_OpenPort(source_port);
|
||
mCurrentPipSource = source;
|
||
#ifdef HAVE_AUDIO
|
||
int Audiotupe = mapSourcetoAudiotupe(source);
|
||
if (Audiotupe == AUDIO_DEVICE_IN_HDMI) {
|
||
Audiotupe = AUDIO_DEVICE_IN_HDMI1;
|
||
}
|
||
CTvAudio::getInstance()->create_audio_patch(TV_CHANNEL_SUB, Audiotupe);
|
||
#endif
|
||
return ret;
|
||
}
|
||
|
||
int CTv::StopTvInPIP ( tv_source_input_t source )
|
||
{
|
||
if (nullptr == mpPipTvin) {
|
||
LOGD("%s: unsupport PIP return!\n", __FUNCTION__);
|
||
return 0;
|
||
}
|
||
|
||
LOGD("%s: source = %d!\n", __FUNCTION__, source);
|
||
int ret = 0;
|
||
#ifdef HAVE_AUDIO
|
||
CTvAudio::getInstance()->release_audio_patch(TV_CHANNEL_SUB);
|
||
#endif
|
||
|
||
|
||
mpTvWayland->stopPipVideo();
|
||
if (mCurrentSource == SOURCE_INVALID) {
|
||
mpTvWayland->shutdown();
|
||
}
|
||
|
||
mpPipTvin->Tvin_StopDecoder();
|
||
tvin_port_t source_port = mpPipTvin->Tvin_GetSourcePortBySourceInput(source);
|
||
mpPipTvin->Tvin_ClosePort(source_port);
|
||
|
||
mCurrentPipSource = SOURCE_INVALID;
|
||
tvin_info_t tempSignalInfo;
|
||
tempSignalInfo.trans_fmt = TVIN_TFMT_2D;
|
||
tempSignalInfo.fmt = TVIN_SIG_FMT_NULL;
|
||
tempSignalInfo.status = TVIN_SIG_STATUS_NULL;
|
||
tempSignalInfo.cfmt = TVIN_COLOR_FMT_MAX;
|
||
tempSignalInfo.signal_type= 0;
|
||
tempSignalInfo.fps = 60;
|
||
tempSignalInfo.is_dvi = 0;
|
||
tempSignalInfo.aspect_ratio = TVIN_ASPECT_NULL;
|
||
SetCurrentPipSourceInfo(tempSignalInfo);
|
||
|
||
return ret;
|
||
}
|
||
|
||
void CTv::onVdin2SignalChange()
|
||
{
|
||
if (mCurrentPipSource == SOURCE_INVALID) {
|
||
LOGD("%s: none opened source,return!\n",__FUNCTION__);
|
||
return;
|
||
}
|
||
|
||
vdin_event_info_s SignalEventInfo;
|
||
memset(&SignalEventInfo, 0, sizeof(vdin_event_info_s));
|
||
int ret = mpPipTvin->Tvin_GetSignalEventInfo(&SignalEventInfo);
|
||
if (ret < 0) {
|
||
LOGD("%s: Get vidn event error!\n",__FUNCTION__);
|
||
} else {
|
||
tv_source_input_type_t source_type = mpPipTvin->Tvin_SourceInputToSourceInputType(mCurrentSource);
|
||
tvin_sig_change_flag_t vdinEventType = (tvin_sig_change_flag_t)SignalEventInfo.event_sts;
|
||
switch (vdinEventType) {
|
||
case TVIN_SIG_CHG_STS:
|
||
LOGD("%s: vdin2 signal status change!\n", __FUNCTION__);
|
||
onPipSigStatusChange();
|
||
break;
|
||
default:
|
||
LOGD("%s: invalid vdin event!\n", __FUNCTION__);
|
||
break;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
void CTv::onPipSigStatusChange(void)
|
||
{
|
||
LOGD("%s\n", __FUNCTION__);
|
||
tvin_info_s tempSignalInfo;
|
||
int ret = mpPipTvin->Tvin_GetSignalInfo(&tempSignalInfo);
|
||
if (ret < 0) {
|
||
LOGD("%s: Get Signal Info error!\n",__FUNCTION__);
|
||
return;
|
||
} else {
|
||
SetCurrentPipSourceInfo(tempSignalInfo);
|
||
LOGD("sig_fmt is %d, status is %d, isDVI is %d, hdr_info is 0x%x\n",
|
||
mCurrentPipSignalInfo.fmt, mCurrentPipSignalInfo.status, mCurrentPipSignalInfo.is_dvi, mCurrentPipSignalInfo.signal_type);
|
||
if ( mCurrentPipSignalInfo.status == TVIN_SIG_STATUS_STABLE ) {
|
||
setDisplayCrop(SUB_WINDOW);
|
||
mpPipTvin->Tvin_StartDecoder(mCurrentPipSignalInfo);
|
||
} else if (mCurrentPipSignalInfo.status == TVIN_SIG_STATUS_UNSTABLE ) {
|
||
mpPipTvin->Tvin_StopDecoder();
|
||
} else if ( mCurrentPipSignalInfo.status == TVIN_SIG_STATUS_NOTSUP ) {
|
||
mpPipTvin->Tvin_StopDecoder();
|
||
} else if ( mCurrentPipSignalInfo.status == TVIN_SIG_STATUS_NOSIG ) {
|
||
mpPipTvin->Tvin_StopDecoder();
|
||
} else {
|
||
LOGD("%s: invalid signal status!\n",__FUNCTION__);
|
||
return;
|
||
}
|
||
|
||
// send PIP signal detect event to APK
|
||
TvEvent::PipSignalDetectEvent pipEvent;
|
||
pipEvent.mSourceInput = mCurrentPipSource;
|
||
pipEvent.mFmt = mCurrentPipSignalInfo.fmt;
|
||
pipEvent.mTrans_fmt = mCurrentPipSignalInfo.trans_fmt;
|
||
pipEvent.mStatus = mCurrentPipSignalInfo.status;
|
||
pipEvent.mDviFlag = mCurrentPipSignalInfo.is_dvi;
|
||
pipEvent.mhdr_info = mCurrentPipSignalInfo.signal_type;
|
||
sendTvEvent(pipEvent);
|
||
return;
|
||
}
|
||
}
|
||
|
||
CTv::CTvMsgQueue::CTvMsgQueue(CTv *tv)
|
||
{
|
||
mpTv = tv;
|
||
}
|
||
|
||
CTv::CTvMsgQueue::~CTvMsgQueue()
|
||
{
|
||
}
|
||
|
||
void CTv::CTvMsgQueue::handleMessage ( CMessage &msg )
|
||
{
|
||
LOGD ("%s, CTv::CTvMsgQueue::handleMessage type = %d\n", __FUNCTION__, msg.mType);
|
||
|
||
switch ( msg.mType ) {
|
||
case TV_MSG_ENABLE_VIDEO_LATER: {
|
||
int fc = msg.mpPara[0];
|
||
mpTv->isVideoFrameAvailable(fc);
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
int CTv::controlScreenColor(int status)
|
||
{
|
||
LOGD ("%s, CTv::controlScreenColor status = %d\n", __FUNCTION__, status);
|
||
#ifdef USE_AMVIDEO
|
||
mpAmVideo->SetVideoLayerStatus(status);
|
||
#else
|
||
switch (status) {
|
||
case VIDEO_LAYER_STATUS_ENABLE:
|
||
meson_vt_set_solid_color(meson_fd, 0, VT_CMD_COLOR_BLACK, VT_CMD_COLOR_DATA_DISABLE);
|
||
break;
|
||
case VIDEO_LAYER_STATUS_DISABLE:
|
||
meson_vt_set_solid_color(meson_fd, 0, VT_CMD_COLOR_BLACK, VT_CMD_COLOR_DATA_ALWAYS);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
#endif
|
||
return 0;
|
||
}
|