Files
2026-08-24 10:03:24 +08:00

347 lines
12 KiB
C++

/*
* 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_MODULE_TAG "TV"
#define LOG_CLASS_TAG "CTvDevicesPollDetect"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include "CTvin.h"
#include "CTvDevicesPollDetect.h"
#include "CTvLog.h"
#include "tvutils.h"
CTvDevicesPollDetect::CTvDevicesPollDetect()
{
m_event.events = 0;
m_avin_status[0].status = AVIN_STATUS_IN;
m_avin_status[0].channel = AVIN_CHANNEL1;
m_avin_status[1].status = AVIN_STATUS_IN;
m_avin_status[1].channel = AVIN_CHANNEL1;
m_hdmi_status = 0;
mpObserver = NULL;
mVdinDetectFd = -1;
mVdin2DetectFd = -1;
if (mEpoll.create() < 0) {
return;
}
//avin hot plug
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 hot plug
if (mHdmiDetectFile.openFile(HDMI_DETECT_PATH) > 0) {
m_event.data.fd = mHdmiDetectFile.getFd();
m_event.events = EPOLLIN | EPOLLET;
mEpoll.add(mHdmiDetectFile.getFd(), &m_event);
}
//signal status
mVdinDetectFd= CTvin::getInstance()->Tvin_GetVdinDeviceFd();
if (mVdinDetectFd > 0) {
m_event.data.fd = mVdinDetectFd;
m_event.events = EPOLLIN | EPOLLET;
mEpoll.add(mVdinDetectFd, &m_event);
}
if (isFileExist(VDIN2_DEV_PATH)) {
mVdin2DetectFd = CTvin::getInstance(VDIN2)->Tvin_GetVdinDeviceFd();
if (mVdin2DetectFd > 0) {
m_event.data.fd = mVdin2DetectFd;
m_event.events = EPOLLIN | EPOLLET;
mEpoll.add(mVdin2DetectFd, &m_event);
}
}
}
CTvDevicesPollDetect::~CTvDevicesPollDetect()
{
}
int CTvDevicesPollDetect::startDetect()
{
int ret;
pthread_t thread_id;
ret = pthread_create(&thread_id, NULL, TvDevicesPollDetectThread, (void *)this);
if (ret != 0) {
LOGE("CTvDevicesPollDetect create thread fail\n");
ret = -1;
} else {
LOGD("CTvDevicesPollDetect thread id (%lu) done\n", thread_id);
ret = 0;
}
return ret;
}
void* CTvDevicesPollDetect::TvDevicesPollDetectThread(void *param)
{
CTvDevicesPollDetect *pThis = (CTvDevicesPollDetect *)param;
pThis->ThreadLoop();
return NULL;
}
const char* CTvDevicesPollDetect::inputToName(tv_source_input_t srcInput) {
const char* inputName[] = {
/*"INVALID",*/
"TV",
"AV1",
"AV2",
"YPBPR1",
"YPBPR2",
"HDMI1",
"HDMI2",
"HDMI3",
"HDMI4",
"VGA,",
"MPEG",
"SVIDEO",
"IPTV",
"DUMMY",
"SPDIF",
"MAX"
};
if (SOURCE_INVALID == srcInput)
return "INVALID";
else
return inputName[srcInput];
}
int CTvDevicesPollDetect::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 CTvDevicesPollDetect::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 CTvDevicesPollDetect::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 = SOURCE_PLUG_IN;
} else {
PlugStatus = SOURCE_PLUG_OUT;
}
break;
}
}//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 = SOURCE_PLUG_IN;
} else {
PlugStatus = SOURCE_PLUG_OUT;
}
break;
}
default:
LOGD("%s; Not support source :%s\n", __FUNCTION__, inputToName(source_input));
break;
}
LOGD("%s: source :%s, status:%s\n", __FUNCTION__, inputToName(source_input), (SOURCE_PLUG_IN == PlugStatus)?"plug in":"plug out");
return PlugStatus;
}
void* CTvDevicesPollDetect::ThreadLoop()
{
//init status
mHdmiDetectFile.readFile((void *)(&m_hdmi_status), sizeof(int));
mAvinDetectFile.readFile((void *)(&m_avin_status), sizeof(struct report_data_s) * 2);
LOGD("%s: hdmi = 0x%x avin[0].status = %d, avin[1].status = %d\n", __FUNCTION__, m_hdmi_status, m_avin_status[0].status, m_avin_status[1].status);
while (1) {
int num = mEpoll.wait();
for (int i = 0; i < num; ++i) {
int fd = (mEpoll)[i].data.fd;
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].status != m_avin_status[i].status) {
if (status[i].status == AVIN_STATUS_IN) {
plug = SOURCE_PLUG_IN;
} else {
plug = 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);
} else {
LOGE("mpObserver is NULL\n");
}
}//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 = SOURCE_PLUG_IN;
} else {
source = ChipHdmiPortMaptoSourceInput(HDMI_DETECT_STATUS_BIT_A);
plug = SOURCE_PLUG_OUT;
}
if (mpObserver != NULL) {
mpObserver->onSourceConnect(source, plug);
} else {
LOGE("mpObserver is NULL\n");
}
}
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 = SOURCE_PLUG_IN;
} else {
source = ChipHdmiPortMaptoSourceInput(HDMI_DETECT_STATUS_BIT_B);
plug = SOURCE_PLUG_OUT;
}
if (mpObserver != NULL) {
mpObserver->onSourceConnect(source, plug);
} else {
LOGE("mpObserver is NULL\n");
}
}
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 = SOURCE_PLUG_IN;
} else {
source = ChipHdmiPortMaptoSourceInput(HDMI_DETECT_STATUS_BIT_C);
plug = SOURCE_PLUG_OUT;
}
if (mpObserver != NULL) {
mpObserver->onSourceConnect(source, plug);
} else {
LOGE("mpObserver is NULL\n");
}
}
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 = SOURCE_PLUG_IN;
} else {
source = ChipHdmiPortMaptoSourceInput(HDMI_DETECT_STATUS_BIT_D);
plug = SOURCE_PLUG_OUT;
}
if (mpObserver != NULL) {
mpObserver->onSourceConnect(source, plug);
} else {
LOGE("mpObserver is NULL\n");
}
}
m_hdmi_status = hdmi_status;
}else if ( fd == mVdinDetectFd ) {
LOGD("VDIN detected\n");
if (mpObserver != NULL) {
mpObserver->onVdinSignalChange();
} else {
LOGE("mpObserver is NULL\n");
}
} else if ( fd == mVdin2DetectFd) {
LOGD("VDIN2 detected\n");
if (mpObserver != NULL) {
mpObserver->onVdin2SignalChange();
}
}
if ((mEpoll)[i].events & EPOLLOUT) {
}
}
}
}//exit
LOGD("CTvDevicesPollDetect, exiting...\n");
}