Android ION機制_HAL與vendor層共享內(nèi)存_流程簡介

研究導向:

? ? ?open camera過程中有些初始化設置參數(shù)需要從vendor層獲取破加,而vendor與hal隸屬于不同進程疮装,通過ION機制設置共享內(nèi)存來實現(xiàn)不同進程間數(shù)據(jù)共享,下面簡要介紹流程:

在初始化過程中hal層會通過socket將消息發(fā)送至vendor層-通知vendor map共享內(nèi)存渴邦。

ION初始化過程:

vim hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.cpp

int QCamera2HardwareInterface::openCamera()

{

……

if (NULL == gCamCapability[mCameraId]) {

if(NO_ERROR !=?initCapabilities(mCameraId,mCameraHandle)) {//會初始化ION

......

}

}

mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,

camEvtHandle,

(void *) this);

……

pthread_mutex_lock(&m_parm_lock);/* MM-MC-FixString8HeapCorrupt-00+ */

//初始化m_pCapability-從vendor層拿到的camera相關初始化數(shù)據(jù)

?mParameters.init(gCamCapability[mCameraId], mCameraHandle, this, this);

pthread_mutex_unlock(&m_parm_lock);/* MM-MC-FixString8HeapCorrupt-00+ */

mParameters.m_parm_lock_ptr = &m_parm_lock;/* MM-MC-FixString8HeapCorrupt-00+ */

ALOGI("openCamera: m_parm_lock_ptr = 0x%x", mParameters.m_parm_lock_ptr);/* MM-MC-FixString8HeapCorrupt-00+ */

mCameraOpened = true;

gCameraOpened = true;/* MM-CL-CTS-testMultiCameraRelease-00+ */

#ifdef USE_ARCSOFT_FEATURE

if ((NULL != mArcSoft_Feature)&&(mCameraId == 0))/* MM-MC-FixOpenCameraCrash-00+ */

mArcSoft_Feature->imx214_module_source = gCamCapability[0]->fih_imx214_module_source;//MM-YW-Get module source for HAL-00

#endif

return NO_ERROR;

}

int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,

mm_camera_vtbl_t *cameraHandle)

{

ATRACE_CALL();

int rc = NO_ERROR;

QCameraHeapMemory *capabilityHeap = NULL;

/* Allocate memory for capability buffer */

capabilityHeap = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);

rc =?capabilityHeap->allocate(1, sizeof(cam_capability_t)); //1走触、設置ION共享內(nèi)存

......

/* Map memory for capability buffer */

memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));

//2、通過socket通知vendor映射共享內(nèi)存用于進程間通信

rc =?cameraHandle->ops->map_buf(cameraHandle->camera_handle,

CAM_MAPPING_BUF_TYPE_CAPABILITY,

capabilityHeap->getFd(0),

sizeof(cam_capability_t));

if(rc < 0) {

ALOGE("%s: failed to map capability buffer", __func__);

goto map_failed;

}

/* Query Capability */

rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle);

if(rc < 0) {

ALOGE("%s: failed to query capability",__func__);

goto query_failed;

}

gCamCapability[cameraId] = (cam_capability_t *)malloc(sizeof(cam_capability_t));

if (!gCamCapability[cameraId]) {

ALOGE("%s: out of memory", __func__);

goto query_failed;

}

memcpy(gCamCapability[cameraId], DATA_PTR(capabilityHeap,0),

sizeof(cam_capability_t));

//copy the preview sizes and video sizes lists because they

//might be changed later

copyList(gCamCapability[cameraId]->preview_sizes_tbl, savedSizes[cameraId].all_preview_sizes,

gCamCapability[cameraId]->preview_sizes_tbl_cnt);

savedSizes[cameraId].all_preview_sizes_cnt = gCamCapability[cameraId]->preview_sizes_tbl_cnt;

copyList(gCamCapability[cameraId]->video_sizes_tbl, savedSizes[cameraId].all_video_sizes,

gCamCapability[cameraId]->video_sizes_tbl_cnt);

savedSizes[cameraId].all_video_sizes_cnt = gCamCapability[cameraId]->video_sizes_tbl_cnt;

rc = NO_ERROR;

query_failed:

cameraHandle->ops->unmap_buf(cameraHandle->camera_handle,

CAM_MAPPING_BUF_TYPE_CAPABILITY);

……

}

1叭首、設置ION共享內(nèi)存:

vim hardware/qcom/camera/QCamera2/HAL/QCameraMem.cpp

int QCameraHeapMemory::allocate(uint8_t count, size_t size)

{

traceLogAllocStart(size, count, "HeapMemsize");

unsigned int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;

int rc =?alloc(count, size, heap_mask);??//主要填充mMemInfo

if (rc < 0)

return rc;

for (int i = 0; i < count; i ++) {

void *vaddr?=?mmap(NULL, ? //映射共享內(nèi)存

mMemInfo[i].size,

PROT_READ | PROT_WRITE,

MAP_SHARED,

mMemInfo[i].fd, 0);

if (vaddr == MAP_FAILED) {

for (int j = i-1; j >= 0; j --) {

munmap(mPtr[j], mMemInfo[j].size);

mPtr[j] = NULL;

deallocOneBuffer(mMemInfo[j]);

}

return NO_MEMORY;

} else

mPtr[i] = vaddr;

}

if (rc == 0)

?mBufferCount = count;

traceLogAllocEnd((size * count));

return OK;

}

int QCameraMemory::alloc(int count, size_t size, unsigned int heap_id)

{

……s

int new_bufCnt = mBufferCount + count;

traceLogAllocStart(size, count, "Memsize");

……

for (int i = mBufferCount; i < new_bufCnt; i ++) {

if ( NULL == mMemoryPool ) {

CDBG_HIGH("%s : No memory pool available and So allocate new buffer", __func__);

rc =?allocOneBuffer(mMemInfo[i], heap_id, size, m_bCached);

if (rc < 0) {

ALOGE("%s: AllocateIonMemory failed", __func__);

for (int j = i-1; j >= 0; j--)

deallocOneBuffer(mMemInfo[j]);

break;

}

} else {

rc = mMemoryPool->allocateBuffer(mMemInfo[i],

heap_id,

size,

m_bCached,

mStreamType);

if (rc < 0) {

ALOGE("%s: Memory pool allocation failed", __func__);

for (int j = i-1; j >= 0; j--)

mMemoryPool->releaseBuffer(mMemInfo[j],

mStreamType);

break;

}

}

}

traceLogAllocEnd (size * (size_t)count);

return rc;

}

int QCameraMemory::allocOneBuffer(QCameraMemInfo &memInfo,

unsigned int heap_id, size_t size, bool cached)

{

int rc = OK;

struct ion_handle_data handle_data;

struct ion_allocation_data alloc;

struct ion_fd_data ion_info_fd;

int main_ion_fd = 0;

?main_ion_fd?=?open("/dev/ion", O_RDONLY);

if (main_ion_fd < 0) {

ALOGE("Ion dev open failed: %s\n", strerror(errno));

goto ION_OPEN_FAILED;

}

memset(&alloc, 0, sizeof(alloc));

memset(&ion_info_fd, 0, sizeof(ion_info_fd));/* MM-MC-ModifyIonFdInitFlow-00+ */

alloc.len = size;

/* to make it page size aligned */

alloc.len = (alloc.len + 4095U) & (~4095U);

alloc.align = 4096;

if (cached) {

alloc.flags = ION_FLAG_CACHED;

}

alloc.heap_id_mask = heap_id;

rc =?ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);

if (rc < 0) {

ALOGE("ION allocation failed: %s\n", strerror(errno));

goto ION_ALLOC_FAILED;

}

//memset(&ion_info_fd, 0, sizeof(ion_info_fd));/* MM-MC-ModifyIonFdInitFlow-00- */

ion_info_fd.handle = alloc.handle;

rc =?ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);

if (rc < 0) {

ALOGE("ION map failed %s\n", strerror(errno));

goto ION_MAP_FAILED;

}

?memInfo.main_ion_fd = main_ion_fd;

?memInfo.fd = ion_info_fd.fd;

memInfo.handle = ion_info_fd.handle;

memInfo.size = alloc.len;

memInfo.cached = cached;

memInfo.heap_id = heap_id;

CDBG_HIGH("%s : ION buffer %lx with size %d allocated",

__func__, (unsigned long)memInfo.handle, memInfo.size);

return OK;

ION_MAP_FAILED:

memset(&handle_data, 0, sizeof(handle_data));

handle_data.handle = ion_info_fd.handle;

ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);

ION_ALLOC_FAILED:

close(main_ion_fd);

ION_OPEN_FAILED:

return NO_MEMORY;

}

2习勤、通過socket通知vendor映射相應共享內(nèi)存用于進程間通信:

vim hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c

static int32_t?mm_camera_intf_map_buf(uint32_t camera_handle,

uint8_t buf_type,

int fd,

size_t size)

{

int32_t rc = -1;

mm_camera_obj_t * my_obj = NULL;

pthread_mutex_lock(&g_intf_lock);

my_obj = mm_camera_util_get_camera_by_handler(camera_handle);

if(my_obj) {

pthread_mutex_lock(&my_obj->cam_lock);

pthread_mutex_unlock(&g_intf_lock);

rc =?mm_camera_map_buf(my_obj, buf_type, fd, size);

} else {

pthread_mutex_unlock(&g_intf_lock);

}

return rc;

}

vim hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera.c

int32_t?mm_camera_map_buf(mm_camera_obj_t *my_obj,

uint8_t buf_type,

int fd,

size_t size)

{

int32_t rc = 0;

cam_sock_packet_t packet;

memset(&packet, 0, sizeof(cam_sock_packet_t));

packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;

packet.payload.buf_map.type = buf_type;

packet.payload.buf_map.fd = fd;

packet.payload.buf_map.size = size;

rc =?mm_camera_util_sendmsg(my_obj,

&packet,

sizeof(cam_sock_packet_t),

fd);

pthread_mutex_unlock(&my_obj->cam_lock);

return rc;

}

int32_t?mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,

void *msg,

size_t buf_size,

int sendfd)

{

int32_t rc = -1;

uint32_t status;

/* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/

pthread_mutex_lock(&my_obj->msg_lock);

if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) {

/* wait for event that mapping/unmapping is done */

mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);

if (MSM_CAMERA_STATUS_SUCCESS == status) {

rc = 0;

}

}

pthread_mutex_unlock(&my_obj->msg_lock);

return rc;

}

vim hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_sock.c

int?mm_camera_socket_sendmsg(

int fd, ?//socket fd

void *msg,

size_t buf_size,

int sendfd)

{

struct msghdr msgh;

struct iovec iov[1];

struct cmsghdr * cmsghp = NULL;

char control[CMSG_SPACE(sizeof(int))];

if (msg == NULL) {

CDBG("%s: msg is NULL", __func__);

return -1;

}

memset(&msgh, 0, sizeof(msgh));

msgh.msg_name = NULL;

msgh.msg_namelen = 0;

iov[0].iov_base = msg;

iov[0].iov_len = buf_size;

msgh.msg_iov = iov;

msgh.msg_iovlen = 1;

CDBG("%s: iov_len=%llu", __func__,

(unsigned long long int)iov[0].iov_len);

msgh.msg_control = NULL;

msgh.msg_controllen = 0;

/* if sendfd is valid, we need to pass it through control msg */

if( sendfd > 0) {

msgh.msg_control = control;

msgh.msg_controllen = sizeof(control);

cmsghp = CMSG_FIRSTHDR(&msgh);

if (cmsghp != NULL) {

CDBG("%s: Got ctrl msg pointer", __func__);

cmsghp->cmsg_level = SOL_SOCKET;

cmsghp->cmsg_type = SCM_RIGHTS;

cmsghp->cmsg_len = CMSG_LEN(sizeof(int));

*((int *)CMSG_DATA(cmsghp)) = sendfd;

CDBG("%s: cmsg data=%d", __func__, *((int *) CMSG_DATA(cmsghp)));

} else {

CDBG("%s: ctrl msg NULL", __func__);

return -1;

}

}

return?sendmsg(fd, &(msgh), 0);//socket發(fā)送數(shù)據(jù)到vendor通知映射共享內(nèi)存

}

refer: ION機制介紹

http://blog.csdn.net/cosmoslhf/article/details/41209925

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市焙格,隨后出現(xiàn)的幾起案子图毕,更是在濱河造成了極大的恐慌,老刑警劉巖眷唉,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件予颤,死亡現(xiàn)場離奇詭異,居然都是意外死亡冬阳,警方通過查閱死者的電腦和手機荣瑟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來摩泪,“玉大人笆焰,你說我怎么就攤上這事〖樱” “怎么了嚷掠?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長荞驴。 經(jīng)常有香客問我不皆,道長,這世上最難降的妖魔是什么熊楼? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任霹娄,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘犬耻。我一直安慰自己踩晶,他們只是感情好,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布枕磁。 她就那樣靜靜地躺著渡蜻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪计济。 梳的紋絲不亂的頭發(fā)上茸苇,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音沦寂,去河邊找鬼学密。 笑死,一個胖子當著我的面吹牛传藏,可吹牛的內(nèi)容都是我干的腻暮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼漩氨,長吁一口氣:“原來是場噩夢啊……” “哼西壮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起叫惊,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤款青,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后霍狰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抡草,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年蔗坯,在試婚紗的時候發(fā)現(xiàn)自己被綠了康震。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡宾濒,死狀恐怖腿短,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绘梦,我是刑警寧澤橘忱,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站卸奉,受9級特大地震影響钝诚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜榄棵,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一凝颇、第九天 我趴在偏房一處隱蔽的房頂上張望潘拱。 院中可真熱鬧,春花似錦拧略、人聲如沸芦岂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盔腔。三九已至杠茬,卻和暖如春月褥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瓢喉。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工宁赤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人栓票。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓决左,卻偏偏與公主長得像,于是被迫代替她去往敵國和親走贪。 傳聞我的和親對象是個殘疾皇子佛猛,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容