【MSM8937】【倒车影像】代码流程分析
发布日期:2021-06-29 14:51:38 浏览次数:2 分类:技术文章

本文共 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()

  1. 在构造函数中,调用 initFunc()进行初始化

  2. 将当前状态设置为 STATE_HIDE ,即 OFF 状态

  3. 初始化 reverse_video 对象,用于控制 Camera 的开关,

    保存在全局变量 reverse_video* reverse_video::sInstance = 0;

  4. 初始化 UIController 对象,用于控制 UI 的显示

    保存在全局变量 UIController* UIController::mInstance = 0;

  5. 初始化 reverse_control 线程,用于监听和控制 Camera 的状态

    保存在全局变量 reverse_control* reverse_control::sInstance = 0;

  6. 初始化 dls_task_thread 线程,用于控制进入和退出dls,

    保存在全局变量 dls_task_thread* dls_task_thread::sInstance = 0;

  7. 初始化 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(),主要工作如下:

  1. 初始化 p uevent, 绑这下netlink socket,设备描述符保存在 d_sig_fd_sets.sigdet_uevent_fd
  2. 并打开 "dev/sigdet0" 节点 ,把设备描述符保存在 d_sig_fd_sets.sigdet_get_fd
  3. 调用 initReverseDataByIoctl()
  4. 获取车机 acc ,baterry, pdc, Can board,reverseState 这些信息,根投当前车机状态来更新倒车影像的 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()

  1. 创建 NETLINK socket, protocol 协议为 NETLINK_CIS_SIGDET
  2. 配置 socket receve buff size128 * 1024
  3. 绑定 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()

  1. 变量初始化
  2. "dev/sigdet0" 发送 SIGDET_GET_ACC_STATE 命令 获取 ACC 状态,保存在 m_acc_state
  3. "dev/sigdet0" 发送 SIGDET_GET_REVERSE_STATE 命令获取倒车影像的状态,状态保存在 m_reverse_gear_state
  4. "dev/sigdet0" 发送 SIGDET_GET_CANB_STATE 命令获取 Can board 状态,保存在 m_canb_state
  5. "dev/sigdet0" 发送 SIGDET_GET_BATTERY_STATE 命令 get battery state,保存在 m_battery_state
  6. "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()

  1. 根据当前车机状态向更新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 初始化成功后,就开始监听系统消息了

  1. 调用 p_uevent_next_event() 开始循环poll 监听 NETLINK_CIS_SIGDET 的socket event 事件 event 消息

  2. 一个调试demon

    如果接收到CAN 消息, mEventData[0] = 0x85, mEventData[0]=4, 则说时是进入倒车影像
    根据 mEventData[3] 判断开还是关倒车影像

  3. 根据监听到的socket event 事件做相关处理,我们此处重点看下 CMD_REVERSE_CAN_STATE

    当有状态更新时,调用updateReverseCondition() 来更新倒车影像状态
    事件包括:
    CMD_ACC_STATECMD_FRONT_PDC_VALUECMD_REAR_PDC_VALUE
    CMD_REVERSE_CAN_STATECMD_BATTERY_STATECMD_PASWORK_STATE
    CMD_SPEED_VALUECMD_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;i
0) {
return count; } } } return 0;}

三、线程 dls_task_thread

3.1 线程自循环

  1. 等待mCommandQueue 事件到
  2. 处理事件
@ 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()

  1. mStateManager->notifyEnterPreReverseState()

    通过 BpReverseClient 代理调用 BnReverseClientonPrepareReverseChange()
    onPrepareReverseChange() 函数定义在 class IReverseClient 中,定义在include/IReverseClient.h
    class BnReverseClient 继承自 class IReverseClient
    接下来看下,谁继承了 BnReverseClient ,就知道onPrepareReverseChange()函数实际处理的地方。

  2. 调用BnReverseClientonPrepareReverseChange(),参数传递 PRE_STATE_ENTERPRE_STATE_EXIT

  3. 调用 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()

  1. 创建pthread ,运行函数 reverse_video::threadLoop()
  2. 阻塞等待Camera 初始化完毕 mCameraInitDoneCondition.wait(mCameraInitDoneLock);
  3. 等待 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, &param); 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()

  1. 实例化 RearCamera() 对象,将 mCameraInitDone 标志位设置为 false

  2. 通过 binder 获取 名为 "media.camera" 的CameraService服务,调用getNumberOfCameras() 获取 Camera 个数,下发参数 CAMERA_TYPE_ALL

  3. 调用 cameraRear->mCameraService->connectLegacy() 函数开始连接Camera, 获得 CameraDevice 的设备操作函数

  4. 调用getParameters()获得当前Camera 参数

  5. 配置对焦模式,接着调用 setParameters() 下发参数

  6. 配置 Display 宽高,根据 preview size 创建 Surface

  7. 在配置好对应的参数后,开始调用 startPreview(), 成功后,发送mCameraInitDoneCondition.broadcast() 广播

  8. start to monitor vdloss, 开始正常显示camera

  9. 等待 camera 退出信号

  10. stop monitor

  11. 调用 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() 对象 sp
cameraRear = 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.cpptemplate
Status 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 中

在真正读取数据之前,我们先做如下操作:

  1. 检查数据大小
  2. 在读数据前,对数据进行上锁,如果不能 lock 成功,则直接返回
  3. 锁成功后,开始 copy 视频 buff 到 mPreviewBuffer 中,然后解锁
  4. 更新从开机到现在的时间,保存在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()

  1. 初始化 gs_yv12_VVBuffergs_yv12_UUBuffermYuvTexBuffer 三块BUFF
  2. 获取系统开机到现在的时间,减去保存buff时记录的时间,如果时间差大于1000ms,则认为数据是不新鲜的
  3. mPreviewBuffer 中的数据转换为 YUV420SP 格式的数据,保存在 buf 中
  4. 处理数据,将数据从 yuv420sp_nv21 处理为 yuv420p_yv12 格式
  5. 置位标志位
@ \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 sp
handler = 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:图像数据格式介绍 yuv420sp、yuv420sp、yv12、nv12等
下一篇:【高通SDM660平台】(6) --- Camera getParameters 及 setParameters 流程

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月29日 11时55分52秒