本文共 68823 字,大约阅读时间需要 229 分钟。
【倒车影像】代码流程分析
一、Service初始化 dls_reverse_svr
先来看下Android.mk。
@ /hardware/libhardware/modules/reverse/reversing_video/Android.mkLOCAL_SRC_FILES:= \ reverse_service/dls_reverse_svr_main.cpp \ reverse_service/DLSVehicleSignalService.cpp \ reverse_service/IDLSVehicleSignalService.cpp \ reverse_service/IReverseClient.cpp \ reverse_service/IDLSAnimationClient.cpp \ reverse_service/dls_message_queue.cpp \ reverse_service/dls_thread.cpp \ reverse_service/dls_task_thread.cpp \ reverse_service/touch_ev.cpp \# version is msm8937_32goLOCAL_CFLAGS += -D_ANDROID_8_1_LOCAL_MODULE:= dls_reverse_svrinclude $(BUILD_EXECUTABLE)
可以看到整个倒车影像服务是以可执行程序执行的,名字为 /system/bin/dls_reverse_svr
其执行的地方为:
//@ /system/core/rootdir/init.rc## for reverse module service dls_reverse /system/bin/dls_reverse_svr class late_start user root group root-----------------------------------------------------------------------------------------//@ /device/qcom/common/base.mkP_LIBS += dls_reverse_svr-----------------------------------------------------------------------------------------//@ file_contexts/system/bin/dls_reverse_svr u:object_r:dls_reverse_svr_exec:s0-----------------------------------------------------------------------------------------//@ dls_reverse_svr.tetype dls_reverse_svr, coredomain;type dls_reverse_svr_exec, exec_type, file_type;init_daemon_domain(dls_reverse_svr)allow init dls_reverse_svr_exec:file getattr;allow dls_reverse_svr init:unix_stream_socket connectto;allow dls_reverse_svr mcu_device:chr_file { ioctl open read write };allow dls_reverse_svr property_socket:sock_file write;allow dls_reverse_svr self:capability { net_admin dac_override };allow dls_reverse_svr self:netlink_socket { bind create setopt };allow dls_reverse_svr servicemanager:binder { call transfer };allow dls_reverse_svr sysfs:file write;allow dls_reverse_svr sysfs:file rw_file_perms;allow dls_reverse_svr hal_graphics_composer_default:{ file lnk_file } r_file_perms;allow dls_reverse_svr hal_graphics_composer_default:dir r_dir_perms;allow dls_reverse_svr cameraserver:{ file lnk_file } r_file_perms;allow dls_reverse_svr cameraserver:dir r_dir_perms;allow dls_reverse_svr mm-qcamerad:{ file lnk_file } r_file_perms;allow dls_reverse_svr mm-qcamerad:dir r_dir_perms;allow servicemanager dls_reverse_svr:dir search;allow servicemanager dls_reverse_svr:file { open read };allow servicemanager dls_reverse_svr:process getattr;
接下来,我们进入它的 main( ) ,来看下干了啥。
@ /hardware/libhardware/modules/reverse/reversing_video/reverse_service/dls_reverse_svr_main.cpp#include#include #include #include #include "include/DLSVehicleSignalService.h"#include #include using namespace p_dls;using namespace android;int main(int argc, char **argv) { (void)argc; (void)argv; // 1. 将当前process 线程设定为 UI主线程,value=-4 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY); sp proc(ProcessState::self()); // 2. 获取系统默认的 ServiceManager sp sm(defaultServiceManager()); // 3. 注册一个名为 dls_vehicle_signal_service 的service sm->addService(String16(DLSVehicleSignalService::getServiceName()), new DLSVehicleSignalService); ========> return "dls_vehicle_signal_service"; ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); return 0;}
1.1 服务初始化 DLSVehicleSignalService()
-
在构造函数中,调用
initFunc()
进行初始化 -
将当前状态设置为
STATE_HIDE
,即 OFF 状态 -
初始化
保存在全局变量reverse_video
对象,用于控制 Camera 的开关,reverse_video* reverse_video::sInstance = 0;
中 -
初始化
保存在全局变量UIController
对象,用于控制 UI 的显示UIController* UIController::mInstance = 0;
中 -
初始化
保存在全局变量reverse_control
线程,用于监听和控制 Camera 的状态reverse_control* reverse_control::sInstance = 0;
中 -
初始化
保存在全局变量dls_task_thread
线程,用于控制进入和退出dls,dls_task_thread* dls_task_thread::sInstance = 0;
中 -
初始化 UI Windows 显示
@ libhardware/modules/reverse/reversing_video/reverse_service/DLSVehicleSignalService.cppDLSVehicleSignalService::DLSVehicleSignalService(){ initFunc(); DLSVehicleSignalService::sInstance = this;}/****************************************************************** * use: init the vehicle service **********/void DLSVehicleSignalService::initFunc(){ ALOGI("2019-1-11 DLSVehicleSignalService is starting "); loadVehicleConfig(); //Step 0: reverseControlByJava = false; mReverseClient = NULL; // 1. 将当前状态设置为 STATE_HIDE ,即 OFF 状态 mConditionState = ReverseStateManager::STATE_HIDE; // Step 1: In this order to create threads // 2. 初始化 `reverse_video` 对象,用于控制 Camera 的开关, // 保存在全局变量 `reverse_video* reverse_video::sInstance = 0;` 中 reverse_video::getInstance(); // 3. 初始化 `UIController` 对象,用于控制 UI 的显示, // 保存在全局变量 `UIController* UIController::mInstance = 0;` 中 UIController::getController(); // Step 2: In this order to start threads // 4. 初始化 reverse_control 线程,用于监听和控制 Camera 的状态。 // 保存在全局变量 reverse_control* reverse_control::sInstance = 0; 中 mController = reverse_control::createController(); ==============> + void reverse_control::onFirstRef(){ + ALOGD("onFirstRef reverse_control"); + run("DLS_MessageReceiver", PRIORITY_DISPLAY); + } <============== // 5. 初始化 dls_task_thread 线程,用于控制进入和退出dls, // 保存在全局变量 dls_task_thread* dls_task_thread::sInstance = 0; 中 mReverseTask = dls_task_thread::getReverseTask(); ==============> + void dls_task_thread::onFirstRef() + { + ALOGD("onFirstRef dls_task_thread"); + run("DLS_ReverseTask", PRIORITY_DISPLAY); + } <============== // 6. 初始化 UI Windows 显示 UIController::getController()->initAllWindows(); /*Trigger boot animation tmprialy*/ //property_set("ctl.start", "dls_bootanim"); //mReverseTask->addTask(dls_task_thread::CMD_TEST_MODE); ALOGI("DLSVehicleSignalService started over.");}
1.1.1 初始化倒车影像UI 显示 UIController::initAllWindows()
@ libhardware/modules/reverse/reversing_video/reverse_pdc/wl_32go/UIController_32go.cppvoid UIController::initAllWindows(){ if (RADAR_SHOW_STYLE_CN202S_1920x720 == mShowStyle) { mErrorWindow = new ErrorWindow(WIN_ERROR_ID, (char*)"ErrorWindow"); mWindowManager->addWindow(mErrorWindow, WIN_ERROR_ID); mRvcSDWindow = new RvcSDWindow(WIN_SD_RVC_ID, (char*)"RvcSDWindow"); mWindowManager->addWindow(mRvcSDWindow, WIN_SD_RVC_ID); mRadarWindow = new RadarWindow(WIN_RADAR_ID, (char*)"RadarWindow"); mWindowManager->addWindow(mRadarWindow, WIN_RADAR_ID); } else if (RADAR_SHOW_STYLE_CN202S_800x480 == mShowStyle) { mErrorWindow_800x480 = new ErrorWindow_800x480(WIN_ERROR_ID, (char*)"ErrorWindow"); mWindowManager->addWindow(mErrorWindow_800x480, WIN_ERROR_ID); mRvcSDWindow_800x480 = new RvcSDWindow_800x480(WIN_SD_RVC_ID, (char*)"RvcSDWindow"); mWindowManager->addWindow(mRvcSDWindow_800x480, WIN_SD_RVC_ID); mRadarWindow_800x480 = new RadarWindow_800x480(WIN_RADAR_ID, (char*)"RadarWindow"); mWindowManager->addWindow(mRadarWindow_800x480, WIN_RADAR_ID); } mWindowManager->showWindow(WIN_SD_RVC_ID);}
1.1.2 绘制 UI 显示控件 createWindowContent()
绘制 UI 显示控件,并对这些控件设置监听函数 setOnClickListener()
void RadarWindow::createWindowContent(){ int car_x = (DLS_LCD_WIDTH - CAR_VIEW_WIDTH) / 2; int car_y = 270 - 20;//(DLS_APP_HEIGHT - CAR_VIEW_HEIGHT) / 2; int radarView_x = (DLS_LCD_WIDTH - DLS_APP_WIDTH) / 2; carView = new ImageView(car_x, car_y, CAR_VIEW_WIDTH, CAR_VIEW_HEIGHT, (char*)"CarView", ID_CARVIEW); carView->setImageSrc((char*)"images/32go/p_32go_car_left.png", ImageResource::PIC_INDEX_CAR); radarTipsView = new TextView(DLS_APP_WIDTH + DLS_CAMERA_WIDTH, 0, 240, 720, (char*)"Tips"); radarTipsView->setImageZHSrc((char*)"images/32go/p_32go_radar_repair_tip_cn.png", ImageResource::PIC_INDEX_RADAR_TIPS); radarTipsView->setImageENSrc((char*)"images/32go/p_32go_radar_repair_tip_en.png", ImageResource::PIC_INDEX_RADAR_TIPS_EN); radarView = new RadarView(radarView_x, 0, DLS_APP_WIDTH, DLS_APP_HEIGHT, ID_RADAR_VIEW, 0, 0, (300+660), (350 - 20)); radarView->setZoneBgColor(0x29, 0x2A, 0x2E); xkeyButton = new ImageButton(50, (DLS_LCD_HEIGHT - 150), 100, 100, ID_XKEY_BUTTON, (char*)"XKeyButton"); xkeyButton->setNormalImageSrc((char*)"images/32go/p_32go_xbutton_normal.png", ImageResource::PIC_INDEX_XBUTTON_NORMAL); xkeyButton->setPressImageSrc((char*)"images/32go/p_32go_xbutton_pressed.png", ImageResource::PIC_INDEX_XBUTTON_PRESSED); xkeyButton->setOnClickListener(this); addView(xkeyButton); addView(carView); carView->setOnClickListener(this); addView(radarTipsView); radarTipsView->setVisibility(false); addView(radarView); //front left pdcFrontL_AreaAlertView = new ImageView(0, 0, RADAR_ALERT_VIEW_WIDTH, RADAR_ALERT_VIEW_HEIGHT, (char*)"pdcFrontL_AreaAlertView"); pdcFrontL_AreaAlertView->setImageSrc((char*)"images/32go/p_32go_radar_fail_alert.png", ImageResource::PIC_INDEX_RADAR_FAIL_ALERT); //front right pdcFrontR_AreaAlertView = new ImageView(0, 0, RADAR_ALERT_VIEW_WIDTH, RADAR_ALERT_VIEW_HEIGHT, (char*)"pdcFrontR_AreaAlertView"); pdcFrontR_AreaAlertView->setImageSrc((char*)"images/32go/p_32go_radar_fail_alert.png", ImageResource::PIC_INDEX_RADAR_FAIL_ALERT); //rear left pdcRearL_AreaAlertView = new ImageView((698-30+7), (DLS_LCD_HEIGHT - 512 - 40), RADAR_ALERT_VIEW_WIDTH, RADAR_ALERT_VIEW_HEIGHT, (char*)"pdcRearL_AreaAlertView"); pdcRearL_AreaAlertView->setImageSrc((char*)"images/32go/p_32go_radar_fail_alert.png", ImageResource::PIC_INDEX_RADAR_FAIL_ALERT); //rear right pdcRearR_AreaAlertView = new ImageView((948-20-3), (DLS_LCD_HEIGHT - 512 - 40), RADAR_ALERT_VIEW_WIDTH, RADAR_ALERT_VIEW_HEIGHT, (char*)"pdcRearR_AreaAlertView"); pdcRearR_AreaAlertView->setImageSrc((char*)"images/32go/p_32go_radar_fail_alert.png", ImageResource::PIC_INDEX_RADAR_FAIL_ALERT); //rear left middle pdcRearLM_AreaAlertView = new ImageView((773 - 28), (DLS_LCD_HEIGHT - 568 - 62), RADAR_ALERT_VIEW_WIDTH, RADAR_ALERT_VIEW_HEIGHT, (char*)"pdcRearLM_AreaAlertView"); pdcRearLM_AreaAlertView->setImageSrc((char*)"images/32go/p_32go_radar_fail_alert.png", ImageResource::PIC_INDEX_RADAR_FAIL_ALERT); //rear right middle pdcRearRM_AreaAlertView = new ImageView((870 - 10), (DLS_LCD_HEIGHT - 568 - 62), RADAR_ALERT_VIEW_WIDTH, RADAR_ALERT_VIEW_HEIGHT, (char*)"pdcRearRM_AreaAlertView"); pdcRearRM_AreaAlertView->setImageSrc((char*)"images/32go/p_32go_radar_fail_alert.png", ImageResource::PIC_INDEX_RADAR_FAIL_ALERT); addView(pdcFrontL_AreaAlertView); addView(pdcFrontR_AreaAlertView); addView(pdcRearL_AreaAlertView); addView(pdcRearLM_AreaAlertView); addView(pdcRearRM_AreaAlertView); addView(pdcRearR_AreaAlertView); pdcFrontL_AreaAlertView->setVisibility(false); pdcFrontR_AreaAlertView->setVisibility(false); pdcRearL_AreaAlertView->setVisibility(false); pdcRearR_AreaAlertView->setVisibility(false); pdcRearLM_AreaAlertView->setVisibility(false); pdcRearRM_AreaAlertView->setVisibility(false);}
二、倒车影像控制线程 reverse_control
2.1 线程初始化 reverse_control::readyToRun()
在线程初始化完毕,开始进入 threadLoop()
前,会调用 reverse_control::readyToRun()
,主要工作如下:
- 初始化
p uevent
, 绑这下netlink socket,设备描述符保存在d_sig_fd_sets.sigdet_uevent_fd
中 - 并打开
"dev/sigdet0"
节点 ,把设备描述符保存在d_sig_fd_sets.sigdet_get_fd
中 - 调用
initReverseDataByIoctl()
- 获取车机
acc ,baterry, pdc, Can board,reverseStat
e 这些信息,根投当前车机状态来更新倒车影像的mMessageQueue
@ libhardware/modules/reverse/reversing_video/reverse_service/wl_32go/reverse_control_32go.cppstatus_t reverse_control::readyToRun(){ ALOGD("reverse_control readyToRun"); initReceiver(); =====================> + // 1. 初始化 p uevent,相关设备描述符保存在 d_sig_fd_sets.sigdet_uevent_fd 中 + d_sig_fd_sets.sigdet_uevent_fd = p_uevent_init(NETLINK_CIS_SIGDET); + // 2. 打开 "dev/sigdet0" 节点 ,把设备描述符保存在 d_sig_fd_sets.sigdet_get_fd 中 + d_sig_fd_sets.sigdet_get_fd = open(SIGDET_FD_PATH,O_RDWR); + ALOGD("reverse_control init ===sigdet_get_fd : %d, sigdet_uevent_fd: %d", + d_sig_fd_sets.sigdet_get_fd, d_sig_fd_sets.sigdet_uevent_fd); <===================== // 3. 获取车机 acc ,baterry, pdc, Can board,reverseState 这些信息,根投当前车机状态来更新倒车影像的 mMessageQueue initReverseDataByIoctl(); return NO_ERROR;}
2.1.1 Event Socket 初始化 p_uevent_init()
- 创建
NETLINK socket
,protocol
协议为NETLINK_CIS_SIGDET
- 配置
socket receve buff size
为128 * 1024
- 绑定 socket
@ libhardware/modules/libpuevent/p_uevent.cint p_uevent_init(int protocol){ struct sockaddr_nl addr; int sz = 128 * 1024; memset(&addr, 0, sizeof(addr)); addr.nl_family = AF_NETLINK; addr.nl_pid = getpid(); addr.nl_groups = 1;// addr.nl_groups = getpid(); ALOGD("protocol=%d, addr.nl_pid=%d \n", protocol, addr.nl_pid); // 1. 创建 NETLINK socket, protocol 为 NETLINK_CIS_SIGDET s = socket(PF_NETLINK, SOCK_DGRAM, protocol); // 2. 配置 socket receve buff size 为 128 * 1024 setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)); // 3. 绑定 socket ret = bind(s, (struct sockaddr *) &addr, sizeof(addr)); return s;}
2.1.2 更新倒车影像状态 initReverseDataByIoctl()
- 变量初始化
- 向
"dev/sigdet0"
发送SIGDET_GET_ACC_STATE
命令 获取ACC
状态,保存在m_acc_state
中 - 向
"dev/sigdet0"
发送SIGDET_GET_REVERSE_STATE
命令获取倒车影像的状态,状态保存在m_reverse_gear_state
中 - 向
"dev/sigdet0"
发送SIGDET_GET_CANB_STATE
命令获取 Can board 状态,保存在m_canb_state
中 - 向
"dev/sigdet0"
发送SIGDET_GET_BATTERY_STATE
命令 get battery state,保存在m_battery_state
中 - 向
"dev/sigdet0"
发送SIGDET_GET_BATTERY_STATE
命令 get PDC state
@ libhardware/modules/reverse/reversing_video/reverse_service/wl_32go/reverse_control_32go.cppvoid reverse_control::initReverseDataByIoctl(){ // 1. 变量初始化 resetDataModel(); // 2. 如果打开 "dev/sigdet0" 节点成功的话 if (-1 != d_sig_fd_sets.sigdet_get_fd) { unsigned char accState[2] = { 0x00, 0x00}; // 2.1 向"dev/sigdet0" 发送 SIGDET_GET_ACC_STATE 命令 获取 ACC 状态 // get ACC state if ((ret = ioctl(d_sig_fd_sets.sigdet_get_fd, SIGDET_GET_ACC_STATE, accState)) == 0){ if(accState[0] == 1){ m_acc_state = accState[1]; m_acc_state_valid = true; ALOGE("%s - SIGDET_GET_ACC_STATE , ACC State = %d", __FUNCTION__,m_acc_state); } } // 2.2 向"dev/sigdet0" 发送 SIGDET_GET_REVERSE_STATE 命令获取倒车影像的状态 get reverse state unsigned char reverseState[2] = { 0x01, 0x07}; if ((ret = ioctl(d_sig_fd_sets.sigdet_get_fd, SIGDET_GET_REVERSE_STATE, reverseState)) == 0){ ALOGD("%s - get reverse state reverseState[0]:%d, reverseState[1]:%d", __FUNCTION__, reverseState[0], reverseState[1]); if(reverseState[0] == 1){ m_reverse_gear_state = reverseState[1]; m_reverse_gear_state_valid = true; } } // get can board state // 2.3 向"dev/sigdet0" 发送 SIGDET_GET_CANB_STATE 命令获取 Can board 状态,保存在 m_canb_state 中 unsigned char canbState[2] = { 0x0}; m_canb_state = 0; //init value m_canb_state_valid = false; for(i=0; i<3; i++){ if ((ret = ioctl(d_sig_fd_sets.sigdet_get_fd, SIGDET_GET_CANB_STATE, canbState)) == 0){ if(canbState[0] == 1){ m_canb_state = canbState[1]; m_canb_state_valid = true; } break; } ALOGW("%s - SIGDET_GET_CANB_STATE %d", __FUNCTION__, m_canb_state); // 2.4 向"dev/sigdet0" 发送 SIGDET_GET_BATTERY_STATE 命令 get battery state ret = -1; unsigned char batteryState[2] = { 0x00, 0x00}; if ((ret = ioctl(d_sig_fd_sets.sigdet_get_fd, SIGDET_GET_BATTERY_STATE, batteryState)) == 0) { if(batteryState[0] == 1) { m_battery_state = batteryState[1]; m_battery_state_valid = true; } } // 2.5 向"dev/sigdet0" 发送 SIGDET_GET_BATTERY_STATE 命令 get PDC state ret = -1; unsigned char pdcState[3] = { 0x02, 0x02, 0x00}; if ((ret = ioctl(d_sig_fd_sets.sigdet_get_fd, SIGDET_GET_FRONT_PDC, pdcState)) == 0) { ALOGW("%s - SIGDET_GET_PDC_STATE success, ret = %d", __FUNCTION__, ret); } } // on first boot; default battery normal //comment it by vence @20190118 for test demo updateReverseCondition(true); =====================> + accState = m_acc_state; + gearState = m_reverse_gear_state; + batteryState = m_battery_state; + + bool condition_acc_test_result = (accState >= STATE_CARKEY_ACC); + bool condition_gear_test_result = (gearState == GEAR_R_OR_REVERSE_ON); + bool condition_battery_test_result = (batteryState == BATTERY_NORMAL_LEVEL1); + + mLastAccCondition = condition_acc_test_result; + mLastBatteryCondition = condition_battery_test_result; + mLastGearCondition = condition_gear_test_result; + judgReverseCondition(); <=====================}
2.1.2.1 judgReverseCondition()
- 根据当前车机状态向更新mMessageQueue中的消息,从而更新倒车影像的状态
@ libhardware/modules/reverse/reversing_video/reverse_service/wl_32go/reverse_control_32go.cppbool reverse_control::judgReverseCondition(){ int temp_reverseState = mIsInReverse; int temp_condition_acc = mLastAccCondition; bool temp_condition_gear = mLastGearCondition;//true mean reverse gear is on int temp_condition_battery = mLastBatteryCondition; bool actions_processed = false; if (ReverseConfig::CAMERA_TYPE_ORIGINAL == ReverseConfig::getConfigs()->getCameraSelect()) { //tmpDelayTime = DELAY_TIME_FOR_REVERSE_IN_ORIGNAL; //ALOGW("Using orignal camera..."); } // 1. 根据当前车机状态向更新mMessageQueue中的消息,从而更新倒车影像的状态 /// ///pre test if(mMessageQueue->hasMessage(mHandler, MSG_ENTER_REVERSE)){ if(!temp_condition_acc || !temp_condition_battery || !temp_condition_gear){ ALOGD("%s ... Cancel ... [ENTER REVERSE] From MessageQueue", __FUNCTION__); mMessageQueue->removeMessages(mHandler, MSG_ENTER_REVERSE); } } if(mMessageQueue->hasMessage(mHandler, MSG_EXIT_REVERSE)){ if(temp_condition_acc && temp_condition_battery && temp_condition_gear){ ALOGD("%s ... Cancel ... [EXIT REVERSE] From MessageQueue", __FUNCTION__); mMessageQueue->removeMessages(mHandler, MSG_EXIT_REVERSE); } } /// ///actions take if((!temp_condition_acc || !temp_condition_gear || !temp_condition_battery ) && mIsInReverse){ ALOGD("%s Condition :: [EXIT REVERSE]", __FUNCTION__); if(!mMessageQueue->hasMessage(mHandler, MSG_EXIT_REVERSE)){ mMessageQueue->sendMessageDelay(450, MSG_EXIT_REVERSE, mHandler); actions_processed = true; } } if((!temp_condition_acc || !temp_condition_gear || !temp_condition_battery ) && false == mIsInReverse && true == mRunningEnterReverseProcess){ //meet exit-reverse condition, and in non-reverse state, but an enter-reverse process is running ALOGD("%s Condition-patch :: [EXIT REVERSE]", __FUNCTION__); if(!mMessageQueue->hasMessage(mHandler, MSG_EXIT_REVERSE)) { mMessageQueue->sendMessageDelay(450, MSG_EXIT_REVERSE, mHandler);//200 actions_processed = true; } } if(temp_condition_acc && temp_condition_battery && temp_condition_gear && !mIsInReverse){ ALOGD("%s Condition :: [ENTER REVERSE]", __FUNCTION__); onResetDataByEnterReverse(); if(!mMessageQueue->hasMessage(mHandler, MSG_ENTER_REVERSE)){ mMessageQueue->sendMessageDelay(450, MSG_ENTER_REVERSE, mHandler);//200 actions_processed = true; } } if(temp_condition_acc && temp_condition_battery && temp_condition_gear && true == mIsInReverse && true == mRunningExitReverseProcess) { //meet reverse condition, and in reverse state, but an exit-reverse process is running ALOGD("%s Condition-patch :: [ENTER REVERSE]", __FUNCTION__); onResetDataByEnterReverse(); if(!mMessageQueue->hasMessage(mHandler, MSG_ENTER_REVERSE)) { mMessageQueue->sendMessageDelay(450, MSG_ENTER_REVERSE, mHandler);//200 actions_processed = true; } } return true;}
2.2 线程自循环 reverse_control::threadLoop()
在 service 初始化成功后,就开始监听系统消息了
-
调用
p_uevent_next_event()
开始循环poll 监听NETLINK_CIS_SIGDET
的socket event 事件 event 消息 -
一个调试demon
如果接收到CAN 消息,mEventData[0] = 0x85
,mEventData[0]=4
, 则说时是进入倒车影像 根据mEventData[3]
判断开还是关倒车影像 -
根据监听到的socket event 事件做相关处理,我们此处重点看下
当有状态更新时,调用CMD_REVERSE_CAN_STATE
updateReverseCondition()
来更新倒车影像状态 事件包括:CMD_ACC_STATE
、CMD_FRONT_PDC_VALUE
、CMD_REAR_PDC_VALUE
、CMD_REVERSE_CAN_STATE
、CMD_BATTERY_STATE
、CMD_PASWORK_STATE
、CMD_SPEED_VALUE
、CMD_SWA_STATE
@ libhardware/modules/reverse/reversing_video/reverse_service/wl_32go/reverse_control_32go.cppbool reverse_control::threadLoop(){ memset(mEventData, 0, BUFFER_LENGTH); // 1. 调用 `p_uevent_next_event()` 开始循环poll 监听 `NETLINK_CIS_SIGDET` 的socket event 事件 event 消息 ret = p_uevent_next_event(mEventData, BUFFER_LENGTH, d_sig_fd_sets.sigdet_uevent_fd); ALOGI("[P_UEVENT_EVENT] 0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x", mEventData[0], mEventData[1], mEventData[2], mEventData[3], mEventData[4], mEventData[5], mEventData[6], mEventData[7], mEventData[8], mEventData[9]);#if 0 { // 2. 一个调试demon, for demo only if(ret > 2){ int mCmdID = mEventData[0]; // 2.1 如果接收到CAN 消息, mEventData[0] = 0x85, mEventData[0]=4, 则说时是进入倒车影像 if (CMD_REVERSE_CAN_STATE == mCmdID) { //0x85-0x4-0x0-0x0-0x2-0x4-0x0-0x0-0x0-0x0 normal 2gear //0x85-0x4-0x0-0x1-0x13-0x4-0x0-0x0-0x0-0x0 reverse if(4 == mEventData[1]) { unsigned char reverse_state = mEventData[3]; // 2.2 根据 mEventData[3] 判断开还是关倒车影像 if (GEAR_R_OR_REVERSE_ON == reverse_state){ ALOGD("%s test mode: switch Camera View ON",__FUNCTION__); dls_task_thread::getReverseTask()->addTask(dls_task_thread::CMD_TEST_MODE); }else{ ALOGD("%s test mode: switch Camera View OFF",__FUNCTION__); dls_task_thread::getReverseTask()->addTask(dls_task_thread::CMD_TEST_MODE_2); } } } } }#endif if(ret > 2) { int mCmdID = mEventData[0]; // 3. 根据 mEventData[0] 第一个字节 判断event 命令 switch(mCmdID) //cmd id { case CMD_ACC_STATE: // 0x01 { /* 0x1-0x1- 0x3-0x0-0x0-0x0-0x0-0x0-0x0-0x0 START 0x1-0x1- 0x1-0x0-0x0-0x0-0x0-0x0-0x0-0x0 ACC */ //ACC State if(mEventData[1] == 1){ //length switch(mEventData[2]){ //acc value case STATE_CARKEY_OFF: case STATE_CARKEY_ACC: case STATE_CARKEY_RUN: case STATE_CARKEY_START: ALOGD("%s : got acc state %d",__FUNCTION__, mEventData[2]); m_acc_state = mEventData[2]; m_acc_state_valid = true; updateReverseCondition(true); //更新倒车影像状态 break; } } break; case CMD_FRONT_PDC_VALUE: //0x86 processPDCData(DISPLAY_INDEX_FRONT); UIController::getController()->updatePdcInfo(mEventData, DISPLAY_INDEX_FRONT); break; case CMD_REAR_PDC_VALUE: // 0x87 processPDCData(DISPLAY_INDEX_REAR); UIController::getController()->updatePdcInfo(mEventData, DISPLAY_INDEX_REAR); break; case CMD_REVERSE_CAN_STATE: // 0x85 // 倒车影像CAN 消息 { /********************************************************** 0x85-0x4- 0x0-0x0-0x2-0x4-0x0-0x0-0x0-0x0 normal 2gear 0x85-0x4- 0x0-0x1-0x13-0x4-0x0-0x0-0x0-0x0 reverse gear position valid (1byte) + reverse state (1byte)+ gear pos(1byte) + gear select mode (1byte) ************************************************************/ if(4 == mEventData[1]){ //length match unsigned char reverse_state = mEventData[3]; if (GEAR_R_OR_REVERSE_ON == reverse_state){ // 0 -- false 1 ---- true ALOGD("%s : reverse gear is ON",__FUNCTION__); m_reverse_gear_state = GEAR_R_OR_REVERSE_ON; }else{ ALOGD("%s : reverse gear is OFF",__FUNCTION__); m_reverse_gear_state = GEAR_P_OR_REVERSE_OFF; } m_reverse_gear_state_valid = true; updateReverseCondition(true); //test //UIController::getController()->updateDegreeInfo(20); } } break; case CMD_BATTERY_STATE:{ //Battery State 0x03 /********************************************************** 0x3-0x1 -0x0-0x0-0x0-0x0-0x0-0x0-0x0-0x0 ************************************************************/ if(mEventData[1] == 1) { m_battery_state = mEventData[2]; m_battery_state_valid = true; } updateReverseCondition(false); } break; case CMD_PASWORK_STATE: //PASWorkCmd State#if 0 m_pas_work_state = mEventData[2]; m_pas_work_state_valid = true; updateReverseCondition(true);#endif break; case CMD_SPEED_VALUE: { // 0x81 /** speed factor:0.015625 0x81-0x07-0x00-0x0c-0x80-0x01-0x00-0x00-0x00-0x00 (50km/h) **/ if(mEventData[1] == 7){ if (0x00 == mEventData[2]){ //speed field is valid unsigned short speed; speed = (mEventData[3] << 8) | mEventData[4]; float speed_f = (float)speed; speed_f *= 0.015625f; m_vehicle_speed = (int)speed_f; m_vehicle_speed_valid = true; ALOGD("%s : got speed is %d",__FUNCTION__, m_vehicle_speed); /** for test updateReverseCondition(true); **/ } } } break; case CMD_SWA_STATE:{ /** Steer Wheel Angle factor:0.0625 0x83-0x3-0x0-0x01-0x23-0x0-0x0-0x0-0x0-0x0 (-2047.9375 ~ + 2047.9375) **/ if(mEventData[1] == 3){ if(mEventData[2] == 0){ //swa field is valid short swa_value; swa_value = (mEventData[3] << 8) | mEventData[4]; float swa_f = (float)swa_value; swa_f *= 0.0625f; m_swa_value = swa_f; ALOGD("%s : got swa is %f",__FUNCTION__, m_swa_value); if (m_swa_value > 554.4 )//2047.9375 m_swa_value = 554.4; else if (m_swa_value < -554.4) m_swa_value = -554.4 ; //assume max angnle is 30 deg of front wheel //30.48 ~ 34.75 m_swa_value = (m_swa_value *30.48f)/554.4f; m_swa_value_valid = true; int swa_val_int = (int)m_swa_value; swa_val_int = -swa_val_int;//exchange +- Jira: L0001M-2888 ALOGD("%s : final calced swa angle is %f, pass to low layer is %d",__FUNCTION__, m_swa_value, swa_val_int); UIController::getController()->updateDegreeInfo(swa_val_int); =====> mRvcSDWindow->updateDegree(degree); } } } break; default: onMessageReceive(mEventData); break; } } return true;//return true, mean this function will be called again.}
2.2.1 Uevent 监听 p_uevent_next_event
循环 poll 监听 NETLINK_CIS_SIGDET
的socket event 事件
@ libhardware/modules/libpuevent/p_uevent.cint p_uevent_next_event(char* buffer, int buffer_length, int fd){ while (1) { struct pollfd fds; fds.fd = fd; fds.events = POLLIN; fds.revents = 0; nr = poll(&fds, 1, -1); int i; if(nr > 0 && fds.revents == POLLIN) { int count = recv(fd, buffer, buffer_length, 0); // for(i=0;i0) { return count; } } } return 0;}
三、线程 dls_task_thread
3.1 线程自循环
- 等待mCommandQueue 事件到
- 处理事件
@ libhardware/modules/reverse/reversing_video/reverse_service/dls_task_thread.cppbool dls_task_thread::threadLoop(){ pthread_mutex_lock(&mTaskLock); while (mCommandQueue.empty()) pthread_cond_wait(&mTaskCondition, &mTaskLock); deque ::iterator pIter; mRunTaskQueue.clear(); for (pIter = mCommandQueue.begin(); pIter != mCommandQueue.end(); pIter++) { mRunTaskQueue.push_back(*pIter); } // clear mCommandQueue.clear(); pthread_mutex_unlock(&mTaskLock); deque ::iterator pExecIter; for(pExecIter = mRunTaskQueue.begin(); pExecIter != mRunTaskQueue.end(); pExecIter++) { switch(*pExecIter) { case CMD_ENTER_REVERSE: processEnterReverse(); break; case CMD_EXIT_REVERSE: processExitReverse(); break; case CMD_ENTER_EOL_MODE: processEnterEolMode(); break; case CMD_EXIT_EOL_MODE: processExitEolMode(); break; case CMD_SET_LANGUAGE_EN: ReverseConfig::getConfigs()->setLanguageEN(); break; case CMD_SET_LANGUAGE_ZH: ReverseConfig::getConfigs()->setLanguageZH();break; case CMD_SWITCH_TO_ERROR_PAGE: processSwitchToErrorPage(); break; case CMD_SWITCH_TO_VIDEO_PAGE: processSwitchToVideoPage(); break; case CMD_RESTART_CAMERA: processReStartCamera(); break; case CMD_RESTART_CAMERA_SILENT: processReStartCameraSilent(); break; case CMD_RESTART_CAMERA_NEXT: processReStartCameraNext(); break; case CMD_TEST_MODE: processTestMode(); break; case CMD_TEST_MODE_2: processTestMode2(); break; case CMD_TEST_MODE_SHOW_CAMERA: processTestShowCamera(); break; case CMD_TEST_MODE_HIDE_CAMERA: processTestHideCamera(); break; case CMD_ENTER_RADAR_SHOW: processEnterRadarShow(); break; case CMD_EXIT_RADAR_SHOW: processExitRadarShow(); break; default: break; } } return true;}
3.2 进入倒车影像 processEnterReverse()
-
在
通过mStateManager->notifyEnterPreReverseState()
中BpReverseClient
代理调用BnReverseClient
的onPrepareReverseChange()
onPrepareReverseChange()
函数定义在class IReverseClient
中,定义在include/IReverseClient.h
中class BnReverseClient
继承自class IReverseClient
, 接下来看下,谁继承了BnReverseClient
,就知道onPrepareReverseChange()
函数实际处理的地方。 -
调用
BnReverseClient
的onPrepareReverseChange()
,参数传递PRE_STATE_ENTER
、PRE_STATE_EXIT
-
调用
requestCamera()
打开Camera
@ libhardware/modules/reverse/reversing_video/reverse_service/dls_task_thread.cppvoid dls_task_thread::processEnterReverse(){ //Pre state callback policy to be compatible with previous versions of the Java layer mStateManager->notifyEnterPreReverseState(); =====================> + //通过 BpReverseClient 代理调用 BnReverseClient 的 onPrepareReverseChange(),参数传递 PRE_STATE_ENTER + //onPrepareReverseChange() 函数定义在 class IReverseClient 中,定义在include/IReverseClient.h中 + //class BnReverseClient 继承自 class IReverseClient, + //接下来看下,谁继承了 BnReverseClient ,就知道onPrepareReverseChange() 函数实际处理的地方。 + + //@ libhardware/modules/reverse/reversing_video/reverse_service/IReverseClient.cpp + class BpReverseClient: public BpInterface+ { + virtual void onPrepareReverseChange(int state){ + Parcel data, reply; + data.writeInterfaceToken(IReverseClient::getInterfaceDescriptor()); + data.writeInt32(state); + remote()->transact(BnReverseClient::ON_PER_REVERSE_STATE_CHANGE, data, &reply); + } + status_t BnReverseClient::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) + { + switch(code) { + case ON_PER_REVERSE_STATE_CHANGE: { + CHECK_INTERFACE(IReverseClient, data, reply); + int state = data.readInt32(); + onPrepareReverseChange(state); + return NO_ERROR; + } break; <===================== mStateManager->notifyExitPreReverseState(); =====================> + 和前同一样,通过 BpReverseClient 代理调用 BnReverseClient 的 onPrepareReverseChange(),参数传递 PRE_STATE_EXIT <===================== mController->setEnterReverseState(); =====> mIsInReverse = true; mController->EnterReverseProcessDone(); =====> mRunningEnterReverseProcess = false; if(ReverseConfig::getConfigs()->getCameraSelect() != ReverseConfig::CAMERA_TYPE_NONE){ if(ReverseConfig::getConfigs()->getCameraClarity() == ReverseConfig::CAMERA_SD){ //Standard Mode if (ReverseConfig::getConfigs()->getReverseController() == ReverseConfig::REVERSE_DP_CONTROLLER_AVM) { ALOGD("[AVM Mode -- SD] Enter Reverse"); }else{ ALOGD("[RVC Mode -- SD] Enter Reverse"); //mCameraStable = true; //todo: need to check camera if is ok // 打开 Camera bool res = mReverseVideo->requestCamera(); ============> mCameraHideSurface = false; return requestCameraImpl(true); <============ if(res){ ALOGD("[UI-PAGE] SD RVC Video"); mUIController->prepareSDCameraPage(); mStateManager->enterShowWithVideoDelay(); mUIController->showGUI(); }else{ ALOGD("[UI-PAGE] SD RVC Error"); mUIController->prepareNoVideoPage(); mStateManager->enterShowWithNoVideoDelay(); mUIController->showGUI(); } } } }}
3.2.1 打开摄像头 mReverseVideo->requestCamera()
- 创建pthread ,运行函数
reverse_video::threadLoop()
- 阻塞等待Camera 初始化完毕
mCameraInitDoneCondition.wait(mCameraInitDoneLock);
- 等待 360ms ,同步 Camera thread 出图
@ libhardware/modules/reverse/reversing_video/reverse_video/reverse_video.cpp// use: turn on camera, return true mean ok, false mean errorbool reverse_video::requestCamera(){ mCameraHideSurface = false; return requestCameraImpl(true);}/*************************************************** * use: the impl of request camera * @aWaitCameraInitDone: true ----- the function will block until camera is inited done * false ----- not wait * return true mean ok, false mean error * note: if aWaitCameraInitDone is true, the return result is the camera init result. * Otherwise only return the general result. ******/bool reverse_video::requestCameraImpl(bool aWaitCameraInitDone){ ALOGI("[reverse_video] %s +++", __FUNCTION__); if (true == mCameraThreadRunning) return true;//thread has already in the running state. mCameraThreadRunning = true; pthread_attr_init(&attr); pthread_attr_setschedpolicy(&attr, SCHED_FIFO); param.sched_priority = sched_get_priority_max(SCHED_FIFO); pthread_attr_setschedparam(&attr, ¶m); mReqQuit = false;//reset it mCameraInitDone = false; // 创建pthread ,运行函数 reverse_video::threadLoop() int ret = pthread_create(&mThreadID, &attr, reverse_video::threadLoop, this); ==============> + // libhardware/modules/reverse/reversing_video/reverse_video/reverse_video.cpp + void* reverse_video::threadLoop(void* args) + { + reverse_video* me = (reverse_video*) args; + me->do_jobs(); + ==========> + mCameraIsPoweredOn = false; + do_job_of_openCamera(); + mCameraThreadRunning = false; + <========== + return NULL; + } <============= ALOGI("[reverse_video] %s thread created ok", __FUNCTION__); if (true == aWaitCameraInitDone) { // 阻塞等待Camera 初始化完毕 ALOGI("[reverse_video] %s waiting camera initing -----", __FUNCTION__); rc = mCameraInitDoneCondition.wait(mCameraInitDoneLock); // 等待 360ms ,同步 Camera thread 出图 usleep(360 * 1000);//sync with camea thread ALOGI("[reverse_video] %s mCameraInitDone =%d -----", __FUNCTION__, mCameraInitDone); return mCameraInitDone; } ALOGI("[reverse_video] %s -----", __FUNCTION__); return true;}
3.2.1.1 打开摄像头线程开始预览 do_job_of_openCamera()
-
实例化
RearCamera()
对象,将mCameraInitDone
标志位设置为 false -
通过 binder 获取 名为
"media.camera"
的CameraService服务,调用getNumberOfCameras()
获取 Camera 个数,下发参数CAMERA_TYPE_ALL
-
调用
cameraRear->mCameraService->connectLegacy()
函数开始连接Camera, 获得CameraDevice
的设备操作函数 -
调用
getParameters()
获得当前Camera 参数 -
配置对焦模式,接着调用
setParameters()
下发参数 -
配置 Display 宽高,根据 preview size 创建 Surface
-
在配置好对应的参数后,开始调用
startPreview()
, 成功后,发送mCameraInitDoneCondition.broadcast()
广播 -
start to monitor vdloss, 开始正常显示camera
-
等待 camera 退出信号
-
stop monitor
-
调用
stopPreview()
,disconnect()
, 下电
@ libhardware/modules/reverse/reversing_video/reverse_video/reverse_video.cppvoid reverse_video::do_job_of_openCamera(void){ ALOGI("[reverse_video] %s +++", __FUNCTION__); ::android::binder::Status rc; ALOGV("main begin"); // 1. 实例化 RearCamera() 对象 spcameraRear = new RearCamera(); // 2. 将 mCameraInitDone 标志位设置为 false mCameraInitDone = false; cameraRear->SetUp(); =================> + // 通过 binder 获取 名为 "media.camera" 的camera service + sp sm = defaultServiceManager(); + sp binder = sm->getService(String16("media.camera")); + mCameraService = interface_cast (binder); + + // 调用getNumberOfCameras() 获取 Camera 个数,下发参数 CAMERA_TYPE_ALL + rc = mCameraService->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_ALL, &numCameras); + ALOGV("numCameras=%d",numCameras); + ==============> + // 服务"media.camera"位于 @ /frameworks/av/services/camera/libcameraservice/CameraService.h + static char const* getServiceName() { return "media.camera"; } + + // @ /frameworks/av/camera/cameraserver/main_cameraserver.cpp + CameraService::instantiate(); + <============== + + mComposerClient = new SurfaceComposerClient; + mComposerClient->initCheck(); + =======> return mStatus; <================= int32_t cameraId = 0; sp previewSurface; sp surfaceControl; sp cameraDevice; String16 cameraIdStr = String16(String8::format("%d", cameraId)); bool isSupported = false; rc = cameraRear->mCameraService->supportsCameraApi(cameraIdStr,hardware::ICameraService::API_VERSION_1, &isSupported); =================> @ av/services/camera/libcameraservice/common/CameraProviderManager.cpp deviceVersion = getDeviceVersion(id); <================= int halVersion = 0x100; // 调用 cameraRear->mCameraService->connectLegacy() 函数开始连接Camera, 获得 CameraDevice 的设备操作函数 for (int try_time = 0; try_time < 30; try_time++) { rc = cameraRear->mCameraService->connectLegacy(cameraRear, cameraId, halVersion, String16("ReverseCamera"),hardware::ICameraService::USE_CALLING_UID, /*out*/&cameraDevice); if (cameraDevice != nullptr){ ALOGD("[reverse_video] %s ---, accquire cameraDevice OK , try_times=%d!", __FUNCTION__, try_time); break; } usleep(200 * 1000); } // 调用getParameters()获得当前Camera 参数 CameraParameters params(cameraDevice->getParameters()); // 配置对焦模式 String8 focusModes(params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES)); bool isAFSupported = false; const char *focusMode = nullptr; if (focusModes.contains(CameraParameters::FOCUS_MODE_AUTO)) { // If supported 'auto' should be set by default isAFSupported = true; } else if (focusModes.contains(CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE)) { isAFSupported = true; focusMode = CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE; } else if (focusModes.contains(CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO)) { isAFSupported = true; focusMode = CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO; } else if (focusModes.contains(CameraParameters::FOCUS_MODE_MACRO)) { isAFSupported = true; focusMode = CameraParameters::FOCUS_MODE_MACRO; } if (nullptr != focusMode) { params.set(CameraParameters::KEY_FOCUS_MODE, focusMode); cameraDevice->setParameters(params.flatten()); //ASSERT_EQ(NO_ERROR, cameraDevice->setParameters(params.flatten())); } // 配置 Display 宽高 int32_t nDisplayWidth = DLS_CAMERA_WIDTH; int32_t nDisplayHeight = DLS_CAMERA_HEIGHT; /*** sp primaryDisplay = cameraRear->mComposerClient->getBuiltInDisplay( ISurfaceComposer::eDisplayIdMain); DisplayInfo displayInfo; status_t ret = cameraRear->mComposerClient->getDisplayInfo( primaryDisplay, &displayInfo); nDisplayWidth = displayInfo.w; nDisplayHeight = displayInfo.h; ***/ // 根据 preview size 创建 Surface,及配置 surface参数 int previewWidth, previewHeight; params.getPreviewSize(&previewWidth, &previewHeight); //ASSERT_TRUE((0 < previewWidth) && (0 < previewHeight)); ALOGV("previewWidth=%d,previewHeight=%d",previewWidth,previewHeight); surfaceControl = cameraRear->mComposerClient->createSurface( String8("Rear Camera Surface"),nDisplayWidth, nDisplayHeight, CameraParameters::previewFormatToEnum(params.getPreviewFormat()), GRALLOC_USAGE_HW_RENDER); //ASSERT_TRUE(nullptr != surfaceControl.get()); //ASSERT_TRUE(surfaceControl->isValid()); int32_t w = 0; int32_t h = 0; int32_t x = 0; int32_t y = 0; FixScaling(0, nDisplayWidth, nDisplayHeight, previewWidth, previewHeight, w, h, x, y); ALOGV("surfaceControl.get()=%d,surfaceControl->isValid()=%d",nullptr != surfaceControl.get(),surfaceControl->isValid()); SurfaceComposerClient::openGlobalTransaction(); surfaceControl->setLayer(DLS_CAMERA_SURFACE_LAYER_INDEX); surfaceControl->setAlpha(DLS_VIDEO_ALPHA); //set transparent are#if 0 const Rect top_area(0, 0, DLS_LCD_WIDTH, DLS_TOP_TITLE_HEIGHT); const Rect bottom_area(0, DLS_LCD_HEIGHT - DLS_BOTTOM_TITLE_HEIGHT, DLS_LCD_WIDTH, DLS_LCD_HEIGHT); Region region(top_area); region.orSelf(bottom_area); surfaceControl->setTransparentRegionHint(region);#endif surfaceControl->setPosition(DLS_APP_WIDTH, y + DLS_TOP_TITLE_HEIGHT); surfaceControl->setSize(w, h);#ifndef FEATURE_CAMERA_VIEW_SUPPORT if (false == mCameraHideSurface) { ALOGI("[reverse_video] %s Create with SHOW!!", __FUNCTION__); surfaceControl->show(); }else{ ALOGI("[reverse_video] %s Create with HIDE!!", __FUNCTION__); surfaceControl->hide(); }#else surfaceControl->hide();#endif //ASSERT_EQ(NO_ERROR, surfaceControl->setLayer(0x7fffffff)); //ASSERT_EQ(NO_ERROR, surfaceControl->show()); SurfaceComposerClient::closeGlobalTransaction(); previewSurface = surfaceControl->getSurface(); cameraDevice->setPreviewTarget( previewSurface->getIGraphicBufferProducer()); //ASSERT_TRUE(previewSurface != NULL); //ASSERT_EQ(NO_ERROR, cameraDevice->setPreviewTarget( // previewSurface->getIGraphicBufferProducer())); cameraDevice->setPreviewCallbackFlag(CAMERA_FRAME_CALLBACK_FLAG_CAMCORDER); cameraDevice->setParameters(params.flatten()); mCameraInitDoneLock.lock(); mCameraInitDone = true; mCameraInitDoneLock.unlock(); mCameraInitDoneCondition.broadcast(); // 在配置好对应的参数后,开始调用 startPreview(), 成功后,发送mCameraInitDoneCondition.broadcast() 广播 if (NO_ERROR != cameraDevice->startPreview()) { ALOGD("[reverse_video] %s ---, startPreview Failed!", __FUNCTION__); mCameraInitDoneCondition.broadcast(); return ; } //start to monitor vdloss VideoLossMonitor::getVideoLossMonitor()->startMonitor(); ===================> + start_camera_NGF_Monitor(); + =======> + ret = pthread_create(&pid, NULL, camera_NGF_main, NULL); + ------> + static void * camera_NGF_main(void * arg) { + (void)arg; + int ret; + ret = camera_NGF_init(); + ---------> + - epollfd = epoll_create(MAX_EPOLL_EVENTS); //4 + - uevent_fd = uevent_open_socket(64*1024, true); + - fcntl(uevent_fd, F_SETFL, O_NONBLOCK); + - camera_NGF_register_event(uevent_fd, camera_NGF_uevent_event, EVENT_WAKEUP_FD); + <--------- + camera_NGF_mainloop(); + return NULL; + } <+=================== //cameraRear->waitForPreviewStart(); mCameraIsPoweredOn = true;//camera is poweron OK!! mCameraSurfaceControlLock.lock(); mCameraSurfaceControl = surfaceControl; mCameraSurfaceControlLock.unlock(); ALOGI("[reverse_video] %s Video Working!!", __FUNCTION__); // 等待 camera 退出信号 { status_t rc = NO_ERROR; Mutex::Autolock l(mReqQuitLock); while (0 == mReqQuit) { rc = mReqQuitCondition.wait(mReqQuitLock); } } //stop monitor VideoLossMonitor::getVideoLossMonitor()->stopMonitor(); // // 调用 stopPreview(), disconnect(), 下电 cameraDevice->stopPreview(); rc = cameraDevice->disconnect(); mCameraIsPoweredOn = false; //camera is poweroff OK!! mCameraSurfaceControlLock.lock(); mCameraSurfaceControl.clear(); mCameraSurfaceControl = NULL; mCameraSurfaceControlLock.unlock(); cameraRear->TearDown(); cameraRear.clear(); ALOGI("[reverse_video] %s --- Quit", __FUNCTION__);}
3.2.1.1.1 CameraService::getNumberOfCameras()
下发的 type = CAMERA_TYPE_ALL,
直接返回 mNumberOfCameras 的值,该值是在CameraService 初始化时赋值的。@ /frameworks/av/services/camera/libcameraservice/CameraService.cppStatus CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) { switch (type) { case CAMERA_TYPE_BACKWARD_COMPATIBLE: *numCameras = mNumberOfNormalCameras; break; case CAMERA_TYPE_ALL: *numCameras = mNumberOfCameras; break; } return Status::ok();}
3.2.1.1.2 connectLegacy()
@ /frameworks/av/camera/Camera.cppstatus_t Camera::connectLegacy(int cameraId, int halVersion, const String16& clientPackageName,int clientUid,sp& camera){ ALOGV("%s: connect legacy camera device", __FUNCTION__); sp c = new Camera(cameraId); sp<::android::hardware::ICameraClient> cl = c; status_t status = NO_ERROR; const sp<::android::hardware::ICameraService>& cs = CameraBaseT::getCameraService(); binder::Status ret; if (cs != nullptr) { ret = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName, clientUid, /*out*/&(c->mCamera)); } if (ret.isOk() && c->mCamera != nullptr) { IInterface::asBinder(c->mCamera)->linkToDeath(c); c->mStatus = NO_ERROR; camera = c; } return status;}
调用 CameraService::connectLegacy()
@ frameworks/av/services/camera/libcameraservice/CameraService.cppStatus CameraService::connectLegacy( const sp& cameraClient, int cameraId, int halVersion,const String16& clientPackageName, int clientUid, /*out*/ sp * device) { ret = connectHelper (cameraClient, id, halVersion, clientPackageName, clientUid, USE_CALLING_PID, API_1, /*legacyMode*/ true, /*shimUpdateOnly*/ false, /*out*/client); *device = client; return ret;}
@/frameworks/av/services/camera/libcameraservice/CameraService.cpptemplateStatus CameraService::connectHelper(const sp & cameraCb, const String8& cameraId, int halVersion, const String16& clientPackageName, int clientUid, int clientPid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly, /*out*/sp & device) { // give flashlight a chance to close devices if necessary. mFlashlight->prepareDeviceOpen(cameraId); int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing); if(!(ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid, clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,/*out*/&tmp)).isOk()) { return ret; } =====================> + // frameworks/av/services/camera/libcameraservice/api1/ <==================== err = client->initialize(mCameraProviderManager); =====================> + // frameworks/av/services/camera/libcameraservice/api1/ <==================== device = client; return ret;}
四、CameraService 服务初始化
这一块,详细可以参考之前写的文章:《》
五、数据流回调 dataCallback()
在前面第三章 do_job_of_open()
函数中调用 startpreview()
后,接下来就等着Camera 底层通过回调上报Camera预览数据了。
dataCallback()
之后的情况, 至于从 startpreview()
之后,底层的详细实现,我们在《【高通SDM660平台】Camera onPreview 流程》 中再详细分析。 好,开始吧。
当底层有视频数据时,就会调用camera 的回调函数dataCallback()
,可以看到在倒车影像中,
dataCallback()
函数是重写父类BnCameraClient
中的方法。 当有数据到达,且data 不为空时,说明有 preview 数据了,发送 mCameraInitDoneCondition
广播,
dls_camera_NewPreviewDataArrived()
转发数据 @ \hardware\libhardware\modules\reverse\reversing_video\reverse_video\reverse_video.cppclass RearCamera : public ::android::hardware::BnCameraClient { public: //CameraClient interface void dataCallback(int32_t msgType, const sp&, camera_frame_metadata_t *) override; void dataCallbackTimestamp(nsecs_t, int32_t, const sp &) override { };void RearCamera::dataCallback(int32_t msgType, const sp & data, camera_frame_metadata_t *) { static int once = 0; ALOGV("[lhy_reverse][%s][%d] msgType=%d", __func__,__LINE__, msgType); switch (msgType) { case CAMERA_MSG_PREVIEW_FRAME: { #if 0 unsigned char *buff = NULL; ssize_t size; size = (ssize_t)data->size(); buff = (unsigned char *)data->pointer(); if (0 == once){ once = 1; FILE * fp; fp = fopen("/system/bin/preview.dat", "wb"); if (fp){ fwrite(buff, 1, size, fp); fclose(fp); } }#endif // 当有数据到达,且data 不为空时,说明有preview 数据了,发送 mCameraInitDoneCondition 广播, // 且调用 dls_camera_NewPreviewDataArrived() 转发数据 if (data != nullptr){ reverse_video::getInstance()->notifyCameraPreviewDataArrived();//need optmized ===============> mCameraInitDone = true; mCameraInitDoneCondition.broadcast(); dls_camera_NewPreviewDataArrived((unsigned char *)data->pointer(), (ssize_t)data->size()); ===============> gs_camera_previewdata_listener(gs_camera_previewdata_listener_data, aData, aDataLen); } Mutex::Autolock l(mPreviewLock); mPreviewBufferCount++; mPreviewCondition.broadcast(); break; } case CAMERA_MSG_COMPRESSED_IMAGE: { Mutex::Autolock l(mSnapshotLock); mSnapshotNotification = true; //TODO: Add checks on incoming Jpeg mSnapshotCondition.broadcast(); break; } default: ALOGV("%s: msgType: %d", __FUNCTION__, msgType); }};
从代码中,我们知道 ,gs_camera_previewdata_listener
是一个函数指针,在初始化时被赋值:
// \hardware\libhardware\modules\reverse\reversing_video\reverse_utils\ReverseMisc.cppstatic dls_camera_preview_data_cb_fun_ptr gs_camera_previewdata_listener = NULL;void dls_camera_register_PreviewDataListener(dls_camera_preview_data_cb_fun_ptr aFun, void * aUserData){ gs_camera_previewdata_listener = aFun; gs_camera_previewdata_listener_data = aUserData; ALOGE("%s registered OK!!", __FUNCTION__);}void CameraView::init(){ dls_camera_register_PreviewDataListener(CameraView_OnPreviewData, this);}
由此可知,Camera Preview Data 其实是调用 CameraView_OnPreviewData()
转发过去的。
5.1 保存数据到 mPreviewBuffer 中
在真正读取数据之前,我们先做如下操作:
- 检查数据大小
- 在读数据前,对数据进行上锁,如果不能 lock 成功,则直接返回
- 锁成功后,开始 copy 视频 buff 到
mPreviewBuffer
中,然后解锁 - 更新从开机到现在的时间,保存在
mYuvTexBuffer_timestamp
中
// \hardware\libhardware\modules\reverse\reversing_video\reverse_ui\CameraView.cppstatic void CameraView_OnPreviewData(void * aUserData, unsigned char * aData, int aDataLen){ CameraView * me= (CameraView*)aUserData; me->OnNewCameraPreviewData(aData, aDataLen);}void CameraView::OnNewCameraPreviewData(unsigned char * aData, int aDataLen){ //ALOGD("%s new preview data+++", __FUNCTION__);/** if (true == mNewCameraData){ ALOGD("%s Drop frame!!", __FUNCTION__); return; } **/ //ALOGD("%s new data!!",__FUNCTION__); // 1. 检查数据大小 if (aDataLen > (DLS_CAMERA_PREVIEW_WIDTH * DLS_CAMERA_PREVIEW_HEIGHT * 3/2)){ ALOGE("%s aDataLen is too large!! aDataLen=%d, Limit=%d", __FUNCTION__, aDataLen, (DLS_CAMERA_PREVIEW_WIDTH * DLS_CAMERA_PREVIEW_HEIGHT * 3/2)); return; } // 2. 在读数据前,对数据进行上锁,如果不能lock 成功,则直接返回 if (0 != mNewCameraDataLock.tryLock()) return; // 3. 锁成功后,开始copy 视频buff 到 mPreviewBuffer 中,然后解锁 //mNewCameraDataLock.lock(); memcpy(mPreviewBuffer, aData, aDataLen); mNewCameraData = true; mNewCameraDataLock.unlock(); mYuvTexBuffer_timestamp = uptimeMillis(); // 4. 更新从开机到现在的时间,保存在mYuvTexBuffer_timestamp 中#if 0 if (false == mRedrawNotificationSent) { mRedrawNotificationSentLock.lock(); mRedrawNotificationSent = true; mRedrawNotificationSentLock.unlock(); RenderThread::getRenderThread()->triggerRedrawOperation(); //ALOGD("%s call triggerRedrawOperation!",__FUNCTION__); }#endif //ALOGD("%s new data done!!",__FUNCTION__); //ALOGD("%s new preview data---", __FUNCTION__);}
这样 preview数据就成功保存在mPreviewBuffer
中了,
mPreviewBuffer = new unsigned char[2048* 2048 * 3/2];
5.2 在 CameraView::preDraw() 准备开始显示
@ \hardware\libhardware\modules\reverse\reversing_video\reverse_ui\CameraView.cppvoid CameraView::preDraw(AssetManager& assets){ (void)assets; if(checkVisible()) { if (true == mInitDone) { generateFrame(); renderFrame(); } } }
5.2.1 处理数据 generateFrame()
- 初始化
gs_yv12_VVBuffer
、gs_yv12_UUBuffer
、mYuvTexBuffer
三块BUFF - 获取系统开机到现在的时间,减去保存buff时记录的时间,如果时间差大于1000ms,则认为数据是不新鲜的
- 将
mPreviewBuffer
中的数据转换为 YUV420SP 格式的数据,保存在 buf 中 - 处理数据,将数据从 yuv420sp_nv21 处理为 yuv420p_yv12 格式
- 置位标志位
@ \hardware\libhardware\modules\reverse\reversing_video\reverse_ui\CameraView.cppvoid CameraView::generateFrame(){ // 1. 初始化 gs_yv12_VVBuffer、gs_yv12_UUBuffer、mYuvTexBuffer 三块BUFF InitAfterGotCameraParameter(); ======================> + TNY_LCD_WIDTH = DLS_CAMERA_PREVIEW_WIDTH; + TNY_LCD_HEIGHT = DLS_CAMERA_PREVIEW_HEIGHT; + + TNY_Y_STRIDE = ((TNY_LCD_WIDTH + 0xf) & ~0xf); + TNY_NV21_UV_STRIDE = ((TNY_LCD_WIDTH + 0xf) & ~0xf); + TNY_YV12_V_STRIDE = ((TNY_Y_STRIDE /2 + 0xf) & ~0xf); + TNY_YV12_U_STRIDE = TNY_YV12_V_STRIDE; + + gs_yv12_VVBuffer = new unsigned char[TNY_YV12_V_STRIDE * TNY_LCD_HEIGHT / 2]; + gs_yv12_UUBuffer = new unsigned char[TNY_YV12_U_STRIDE * TNY_LCD_HEIGHT / 2]; + + mYuvTexBuffer = new GraphicBuffer(DLS_CAMERA_PREVIEW_WIDTH, + DLS_CAMERA_PREVIEW_HEIGHT, HAL_PIXEL_FORMAT_YV12, + GraphicBuffer::USAGE_HW_TEXTURE |GraphicBuffer::USAGE_SW_WRITE_RARELY); + ALOGE("%s: width=%d height=%d", __FUNCTION__, + DLS_CAMERA_PREVIEW_WIDTH , DLS_CAMERA_PREVIEW_HEIGHT); <====================== // 2. 获取系统开机到现在的时间,减去保存buff时记录的时间,如果时间差大于1000ms,则认为数据是不新鲜的 int64_t now_ms = uptimeMillis(); int64_t diff_ms = (now_ms - mYuvTexBuffer_timestamp);#ifndef TEST_LOCAL_YUV_DATA if (diff_ms > 1000){ ALOGD("%s new data is stale!!",__FUNCTION__); return; }#endif // 3. 将 mPreviewBuffer 中的数据转换为 YUV420SP 格式的数据,保存在 buf 中 char* buf = NULL; status_t err = mYuvTexBuffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf)); mNewCameraDataLock.lock(); if (1 == DLS_FEATURE_CAMERA_VIEW_ALIGN4_TO_ALIGN16){ trans_yuv420sp_align4_to_align16(mPreviewBuffer, (unsigned char*)buf, DLS_CAMERA_PREVIEW_WIDTH, DLS_CAMERA_PREVIEW_HEIGHT); }else{ memcpy(buf, mPreviewBuffer, DLS_CAMERA_PREVIEW_WIDTH * DLS_CAMERA_PREVIEW_HEIGHT * 3/2); } mNewCameraData = false; mNewCameraDataLock.unlock(); // 4. 处理数据,将数据从 yuv420sp_nv21 处理为 yuv420p_yv12 格式 trans_yuv420sp_nv21_to_yuv420p_yv12((unsigned char*)buf); err = mYuvTexBuffer->unlock(); // 5. 置位标志位 mYuvTexBufferReady = true;}
在 trans_yuv420sp_nv21_to_yuv420p_yv12 中
/******************************************************* 420sp nv21 NV21 YYYY YYYY VUVU ==>420P yv21: YYYY YYYY VV UU *******************************************************/void CameraView::trans_yuv420sp_nv21_to_yuv420p_yv12(unsigned char * aData){ int i, j; int y_stride = TNY_Y_STRIDE; int nv21_uv_stride = TNY_NV21_UV_STRIDE; int yv21_v_stride = TNY_YV12_V_STRIDE; int yv21_u_stride = TNY_YV12_U_STRIDE; unsigned char * pNV21_VUBase = aData + (y_stride * TNY_LCD_HEIGHT); unsigned char * pYV12_TargetVBase = aData + (y_stride * TNY_LCD_HEIGHT); unsigned char * pYV12_TargetUBase = pYV12_TargetVBase + yv21_v_stride * (TNY_LCD_HEIGHT / 2); int yv12_v_count = 0; int yv12_u_count = 0; int yv12_vu_line = 0; //fill all vv & uu for (i = 0; i < TNY_LCD_HEIGHT / 2; i++,yv12_vu_line++){ for (j = 0; j < TNY_LCD_WIDTH / 2; j++){ pYV12_TargetVBase[yv12_v_count++] = pNV21_VUBase[nv21_uv_stride * i + j * 2]; if ( (yv21_v_stride - (yv12_v_count - yv21_v_stride * yv12_vu_line))<=(yv21_v_stride - TNY_LCD_WIDTH / 2)) { yv12_v_count = yv21_v_stride * (yv12_vu_line +1); //printf("yv12_v_count=%d\n", yv12_v_count); } gs_yv12_UUBuffer[yv12_u_count++] = pNV21_VUBase[nv21_uv_stride * i + j * 2 + 1]; if ( (yv21_u_stride - (yv12_u_count - yv21_u_stride * yv12_vu_line)) <= (yv21_v_stride - TNY_LCD_WIDTH / 2)) { yv12_u_count = (yv12_u_count + 0xf) & ~0xf; //printf("yv12_u_count=%d\n", yv12_u_count); } } } //printf("final yv12_v_count=%d\n", yv12_v_count); //printf("final yv12_u_count=%d\n", yv12_u_count); //fillback memcpy(pYV12_TargetUBase, gs_yv12_UUBuffer, TNY_YV12_U_STRIDE * TNY_LCD_HEIGHT / 2);}
5.2.2 renderFrame()
@ \hardware\libhardware\modules\reverse\reversing_video\reverse_ui\CameraView.cppvoid CameraView::renderFrame(){ if (false == mYuvTexBufferReady) { ALOGD("%s no buffer is ready!",__FUNCTION__); return; } // setupYuvTexSurface(eglGetCurrentDisplay(), eglGetCurrentContext()); glUseProgram(mProgram); checkGlError("mProgram"); if (RADAR_SHOW_STYLE_CN202S_800x480 == dls_get_RadarShowStyle()){ if (720 == DLS_CAMERA_PREVIEW_WIDTH && 480 == DLS_CAMERA_PREVIEW_HEIGHT) { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_800x480_CAMERA_720x480); } else if (640 == DLS_CAMERA_PREVIEW_WIDTH && 480 == DLS_CAMERA_PREVIEW_HEIGHT) { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_800x480_CAMERA_640x480); } else { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_800x480_CAMERA_720x480); } } else { if (1 == DLS_FEATURE_CAMERA_VIEW_FULL_SCREEN) { if (1 == DLS_FEATURE_CAMERA_VIEW_FULL_SCREEN_PATCH_220C_AVM) { if (1 == DLS_FEATURE_CAMERA_VIEW_FULL_SCREEN_CLIP_1280x720_AVM) { if (true == dls_is_in_statusbar_show_mode() && 1 == DLS_FEATURE_AUTO_SHOW_STATUS_BAR_CHANGE_VIDEO_SIZE) { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_CLIP_1280x720_FULLSCREEN_AVM_Patch_220C_statusbar); } else { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_CLIP_1280x720_FULLSCREEN_AVM_Patch_220C); } } else { if (true == dls_is_in_statusbar_show_mode() && 1 == DLS_FEATURE_AUTO_SHOW_STATUS_BAR_CHANGE_VIDEO_SIZE) { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_FULLSCREEN_AVM_Patch_220C_statusbar); } else { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_FULLSCREEN_AVM_Patch_220C); } } } else if (1 == DLS_FEATURE_CAMERA_VIEW_FULL_SCREEN_PATCH_202M_AVM) { if (true == dls_is_in_statusbar_show_mode() && 1 == DLS_FEATURE_AUTO_SHOW_STATUS_BAR_CHANGE_VIDEO_SIZE) { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_FULLSCREEN_AVM_Patch_202M_statusbar); } else { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_FULLSCREEN_AVM_Patch_202M); } }else if(1 == DLS_FEATURE_CAMERA_VIEW_FULL_SCREEN_PATCH_210S_AVM){ if (true == dls_is_in_statusbar_show_mode() && 1 == DLS_FEATURE_AUTO_SHOW_STATUS_BAR_CHANGE_VIDEO_SIZE) { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_FULLSCREEN_AVM_Patch_210S_statusbar); } else { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_FULLSCREEN_AVM_Patch_210S); } } else { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_FULLSCREEN); } } else if (720 == DLS_CAMERA_PREVIEW_WIDTH && 480 == DLS_CAMERA_PREVIEW_HEIGHT) { if (RADAR_SHOW_STYLE_960x1280 == dls_get_RadarShowStyle()) { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_960x1280_CAMERA_720x480); } else if (1 == DLS_FEATURE_CAMERA_DISPLAY_CENTER) { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_CAMERA_720x480_CENTER); } else if (1 == DLS_FEATURE_CAMERA_VIEW__PATCH_300S) { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1280x720_CAMERA_720x480); } else if (1 == DLS_FEATURE_CAMERA_VIEW__PATCH_210S) { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_CAMERA_720x480_210S); } else { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_CAMERA_720x480); } } else if (640 == DLS_CAMERA_PREVIEW_WIDTH && 480 == DLS_CAMERA_PREVIEW_HEIGHT) { if (RADAR_SHOW_STYLE_960x1280 == dls_get_RadarShowStyle()) { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_960x1280_CAMERA_640x480); } else { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_CAMERA_640x480); } } else if (1 == DLS_FEATURE_CAMERA_VIEW__PATCH_210S) { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_CAMERA_720x480_210S); } else { glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices_LCD_1920x720_CAMERA_720x480); } } checkGlError("glVertexAttribPointer"); glEnableVertexAttribArray(mPositionHandle); checkGlError("glEnableVertexAttribArray"); //vence add it @20190215 glVertexAttribPointer(mTexCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, gTexCoordVertices); checkGlError("glVertexAttribPointer"); glEnableVertexAttribArray(mTexCoordHandle); checkGlError("glEnableVertexAttribArray"); glUniform1i(mYuvTexSamplerHandle, 0); checkGlError("glUniform1i");/** GLclampf tmpColor[4]; tmpColor[0] = 1.0; tmpColor[1] = 0.0; tmpColor[2] = 0.0; tmpColor[3] = 1.0f; glUniform4fv(mMyColorHandle, 1, tmpColor); checkGlError("mMyColorHandle"); **/ glBindTexture(GL_TEXTURE_EXTERNAL_OES, mYuvTex); checkGlError("glBindTexture"); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); checkGlError("glDrawArrays"); glDeleteTextures(1, &(mYuvTex));#if 0 mRedrawNotificationSentLock.lock(); mRedrawNotificationSent = false; mRedrawNotificationSentLock.unlock();#endif //mYuvTexBufferReady = false;}
六、MessageQueue
先来看下 MessageQueue的定义。
可以看出,MessageQueue 是一个继承自 Thread 的class。
@ /hardware/libhardware/modules/reverse/reversing_video/reverse_utils/header/MessageQueue.h#ifndef ANDROID_MESSAGEQUEUE_H#define ANDROID_MESSAGEQUEUE_H#include "ReverseLooper.h"using namespace android;namespace p_dls { class MessageQueue: public Thread{ public: static MessageQueue* createMessageQueue(); virtual ~MessageQueue(); void sendMessage(int msgID, const sp& messageHandler); void sendMessageDelay(int timeout, int msgID, const sp & messageHandler); void removeMessages(const sp & handler); void removeMessages(const sp & handler, int what); bool hasMessage(const sp & handler, int what); private: static MessageQueue* sInstance; MessageQueue(); virtual bool threadLoop(); virtual status_t readyToRun(); virtual void onFirstRef(); sp mLooper; };}#endif //ANDROID_MESSAGEQUEUE_H
6.1 MessageQueue::onFirstRef()
在初始化 MessageQueue 对象时会自动调用 onFirstRef(),在该函数中,主要工作就是 将当前线程跑起来
@ hardware/libhardware/modules/reverse/reversing_video/reverse_utils/MessageQueue.cppvoid MessageQueue::onFirstRef(){ ALOGD("onFirstRef MessageQueue"); run("DLS_MessageQueue", PRIORITY_DISPLAY); }
6.2 线程自循环 MessageQueue::threadLoop()
@ /hardware/libhardware/modules/reverse/reversing_video/reverse_utils/MessageQueue.cppbool MessageQueue::threadLoop(){ ALOGD("Message Queue Enter ThreadLoop to poll Message"); mLooper->pollOnce(-1); return true; }@ /hardware/libhardware/modules/reverse/reversing_video/reverse_utils/header/ReverseLooper.hint pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);inline int pollOnce(int timeoutMillis) { return pollOnce(timeoutMillis, NULL, NULL, NULL);}@ /hardware/libhardware/modules/reverse/reversing_video/reverse_utils/ReverseLooper.cppint ReverseLooper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { int result = 0; for (;;) { while (mResponseIndex < mResponses.size()) { const Response& response = mResponses.itemAt(mResponseIndex++); int ident = response.request.ident; if (ident >= 0) { int fd = response.request.fd; int events = response.events; void* data = response.request.data; ALOGD("%p ~ pollOnce - returning signalled identifier %d: fd=%d, events=0x%x, data=%p", this, ident, fd, events, data); if (outFd != NULL) *outFd = fd; if (outEvents != NULL) *outEvents = events; if (outData != NULL) *outData = data; return ident; } } if (result != 0) { ALOGD("%p ~ pollOnce - returning result %d", this, result); if (outFd != NULL) *outFd = 0; if (outEvents != NULL) *outEvents = 0; if (outData != NULL) *outData = NULL; return result; } result = pollInner(timeoutMillis); }}
6.2.1 ReverseLooper::pollInner()
int ReverseLooper::pollInner(int timeoutMillis) { ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis); // Adjust the timeout based on when the next message is due. if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime); if (messageTimeoutMillis >= 0 && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) { timeoutMillis = messageTimeoutMillis; } ALOGD("%p ~ pollOnce - next message in %" PRId64 "ns, adjusted timeout: timeoutMillis=%d", this, mNextMessageUptime - now, timeoutMillis); } // Poll. int result = POLL_WAKE; mResponses.clear(); mResponseIndex = 0; // We are about to idle. mPolling = true; struct epoll_event eventItems[EPOLL_MAX_EVENTS]; int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis); // No longer idling. mPolling = false; // Acquire lock. mLock.lock(); // Rebuild epoll set if needed. if (mEpollRebuildRequired) { mEpollRebuildRequired = false; rebuildEpollLocked(); goto Done; } // Handle all events. ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount); for (int i = 0; i < eventCount; i++) { int fd = eventItems[i].data.fd; uint32_t epollEvents = eventItems[i].events; if (fd == mWakeEventFd) { if (epollEvents & EPOLLIN) { awoken(); ========> TEMP_FAILURE_RETRY(read(mWakeEventFd, &counter, sizeof(uint64_t))); } } else { ssize_t requestIndex = mRequests.indexOfKey(fd); if (requestIndex >= 0) { int events = 0; if (epollEvents & EPOLLIN) events |= EVENT_INPUT; if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT; if (epollEvents & EPOLLERR) events |= EVENT_ERROR; if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP; pushResponse(events, mRequests.valueAt(requestIndex)); } } }Done: ; // Invoke pending message callbacks. mNextMessageUptime = LLONG_MAX; while (mMessageEnvelopes.size() != 0) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0); if (messageEnvelope.uptime <= now) { // Remove the envelope from the list. // We keep a strong reference to the handler until the call to handleMessage // finishes. Then we drop it so that the handler can be deleted *before* // we reacquire our lock. { // obtain handler sphandler = messageEnvelope.handler; Message message = messageEnvelope.message; mMessageEnvelopes.removeAt(0); mSendingMessage = true; mLock.unlock(); ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",this, handler.get(), message.what); handler->handleMessage(message); } // release handler mLock.lock(); mSendingMessage = false; result = POLL_CALLBACK; } else { // The last message left at the head of the queue determines the next wakeup time. mNextMessageUptime = messageEnvelope.uptime; break; } } // Release lock. mLock.unlock(); // Invoke all response callbacks. for (size_t i = 0; i < mResponses.size(); i++) { Response& response = mResponses.editItemAt(i); if (response.request.ident == POLL_CALLBACK) { int fd = response.request.fd; int events = response.events; void* data = response.request.data;#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p", this, response.request.callback.get(), fd, events, data);#endif // Invoke the callback. Note that the file descriptor may be closed by // the callback (and potentially even reused) before the function returns so // we need to be a little careful when removing the file descriptor afterwards. int callbackResult = response.request.callback->handleEvent(fd, events, data); if (callbackResult == 0) { removeFd(fd, response.request.seq); } // Clear the callback reference in the response structure promptly because we // will not clear the response vector itself until the next poll. response.request.callback.clear(); result = POLL_CALLBACK; } } return result;}
七、知识扩展
7.1 Android 线程优先级
ANDROID_PRIORITY_LOWEST 19 可以使用最后的ANDROID_PRIORITY_BACKGROUND 10 用于background tasksANDROID_PRIORITY_NORMAL 0 大部分线程都以这个优先级运行ANDROID_PRIORITY_FOREGROUND -2 用户正在交互的线程ANDROID_PRIORITY_DISPLAY -4 UI主线程ANDROID_PRIORITY_URGENT_DISPLAY -8 这个值由HAL_PRIORITY_URGENT_DISPLAY来指定,当前版本中是-8。只在部分紧急状态下使用ANDROID_PRIORITY_AUDIO -16 正常情况下的声音线程ANDROID_PRIORITY_URGENT_AUDIO -19 声音线程(通常情况不用)ANDROID_PRIORITY_HIGHEST -20 最高优先级,禁止使用ANDROID_PRIORITY_DEFAULT 0 默认情况下就是ANDROID_PRIORITY_NORMALANDROID_PRIORITY_MORE_FAVORABLE -1 在上述优先级的基础上,用于加大优先级ANDROID_PRIORITY_LESS_FAVORABLE +1 在上述优先级的基础上,用于减小优先级
数值越大的,优先级越小。因为各等级间的数值并不是连续的,
我们可以通过ANDROID_PRIORITY_MORE_FAVORABLE(-1)
来适当地提高优先级, 或者是利用ANDROID_PRIORITY_LESS_FAVORABLE(+1)
来降低优先级。 转载地址:https://ciellee.blog.csdn.net/article/details/105735455 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!