status_t QCameraStream_Rdi::getBufferRdi( ) { int err = 0; status_t ret = NO_ERROR; int i, frame_len, y_off, cbcr_off; uint8_t num_planes; cam_ctrl_dimension_t dim; uint32_t planes[VIDEO_MAX_PLANES]; ALOGI("%s : E ", __FUNCTION__); ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim); if(ret != NO_ERROR) { ALOGE("%s: display format %d is not supported", __func__, dim.prev_format); goto end; } mHalCamCtrl->mRdiMemoryLock.lock(); mHalCamCtrl->mRdiMemory.buffer_count = kRdiBufferCount; if(mHalCamCtrl->isZSLMode()) { if(mHalCamCtrl->getZSLQueueDepth() > kRdiBufferCount - 3) mHalCamCtrl->mRdiMemory.buffer_count = mHalCamCtrl->getZSLQueueDepth() + 3; } frame_len = mm_camera_get_msm_frame_len(CAMERA_RDI, myMode, dim.rdi0_width, dim.rdi0_height, OUTPUT_TYPE_R, &num_planes, planes); y_off = 0; cbcr_off = planes[0]; ALOGI("%s: main image: rotation = %d, yoff = %d, cbcroff = %d, size = %d, width = %d, height = %d", __func__, dim.rotation, y_off, cbcr_off, frame_len, dim.rdi0_width, dim.rdi0_height); if (mHalCamCtrl->initHeapMem(&mHalCamCtrl->mRdiMemory, mHalCamCtrl->mRdiMemory.buffer_count, frame_len, y_off, cbcr_off, MSM_PMEM_MAINIMG, NULL,NULL, num_planes, planes) < 0) { ret = NO_MEMORY; goto end; }; ALOGI(" %s : X ",__FUNCTION__); end: mHalCamCtrl->mRdiMemoryLock.unlock(); return NO_ERROR; }
static int mm_camera_stream_util_reg_buf(mm_camera_obj_t * my_obj, mm_camera_stream_t *stream, mm_camera_buf_def_t *vbuf) { int32_t i, rc = MM_CAMERA_OK, j; int *ret; struct v4l2_requestbuffers bufreq; int image_type; uint8_t num_planes; uint32_t planes[VIDEO_MAX_PLANES]; if(vbuf->num > MM_CAMERA_MAX_NUM_FRAMES) { rc = -MM_CAMERA_E_GENERAL; CDBG_ERROR("%s: buf num %d > max limit %d\n", __func__, vbuf->num, MM_CAMERA_MAX_NUM_FRAMES); goto end; } switch(stream->stream_type) { case MM_CAMERA_STREAM_PREVIEW: image_type = OUTPUT_TYPE_P; break; case MM_CAMERA_STREAM_RDI0: image_type = OUTPUT_TYPE_R; break; case MM_CAMERA_STREAM_SNAPSHOT: case MM_CAMERA_STREAM_RAW: image_type = OUTPUT_TYPE_S; break; case MM_CAMERA_STREAM_THUMBNAIL: image_type = OUTPUT_TYPE_T; break; case MM_CAMERA_STREAM_VIDEO: default: image_type = OUTPUT_TYPE_V; break; } stream->frame.frame_len = mm_camera_get_msm_frame_len(stream->cam_fmt, my_obj->current_mode, stream->fmt.fmt.pix.width, stream->fmt.fmt.pix.height, image_type, &num_planes, planes); if(stream->frame.frame_len == 0) { CDBG_ERROR("%s:incorrect frame size = %d\n", __func__, stream->frame.frame_len); rc = -1; goto end; } CDBG("%s frame_len =%d, mum_planes=%d", __func__, stream->frame.frame_len, num_planes); stream->frame.num_frame = vbuf->num; bufreq.count = stream->frame.num_frame; bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; bufreq.memory = V4L2_MEMORY_USERPTR; CDBG("%s: calling VIDIOC_REQBUFS - fd=%d, num_buf=%d, type=%d, memory=%d\n", __func__,stream->fd, bufreq.count, bufreq.type, bufreq.memory); rc = ioctl(stream->fd, VIDIOC_REQBUFS, &bufreq); if (rc < 0) { CDBG_ERROR("%s: fd=%d, ioctl VIDIOC_REQBUFS failed: rc=%d\n", __func__, stream->fd, rc); goto end; } CDBG("%s: stream fd=%d, ioctl VIDIOC_REQBUFS: memtype = %d," "num_frames = %d, rc=%d\n", __func__, stream->fd, bufreq.memory, bufreq.count, rc); for(i = 0; i < vbuf->num; i++){ vbuf->buf.mp[i].idx = i; /* remember the index to stream frame if first time qbuf */ memcpy(&stream->frame.frame[i].frame, &(vbuf->buf.mp[i].frame), sizeof(vbuf->buf.mp[i].frame)); stream->frame.frame[i].idx = i; stream->frame.frame[i].num_planes = vbuf->buf.mp[i].num_planes; for(j = 0; j < vbuf->buf.mp[i].num_planes; j++) { stream->frame.frame[i].planes[j] = vbuf->buf.mp[i].planes[j]; } if(vbuf->buf.mp[i].frame_offset) { stream->frame.frame_offset[i] = vbuf->buf.mp[i].frame_offset; } else { stream->frame.frame_offset[i] = 0; } CDBG("%s: vbuf_mp[%d]num_planes =%d", __func__, i, stream->frame.frame[i].num_planes); rc = mm_camera_stream_qbuf(my_obj, stream, stream->frame.frame[i].idx); if (rc < 0) { CDBG_ERROR("%s: VIDIOC_QBUF rc = %d\n", __func__, rc); goto end; } stream->frame.ref_count[i] = 0; CDBG("%s: stream_fd = %d, frame_fd = %d, frame ID = %d, offset = %d\n", __func__, stream->fd, stream->frame.frame[i].frame.fd, i, stream->frame.frame_offset[i]); } stream->frame.qbuf = 1; end: return rc; }
status_t QCameraStream_Rdi::initRdiBuffers() { status_t ret = NO_ERROR; int width = 0; /* width of channel */ int height = 0; /* height of channel */ uint32_t frame_len = 0; /* frame planner length */ int buffer_num = 4; /* number of buffers for display */ const char *pmem_region; uint8_t num_planes = 0; uint32_t planes[VIDEO_MAX_PLANES]; cam_ctrl_dimension_t dim; ALOGD("%s:BEGIN",__func__); mHalCamCtrl->mRdiMemoryLock.lock(); memset(&mHalCamCtrl->mRdiMemory, 0, sizeof(mHalCamCtrl->mRdiMemory)); mHalCamCtrl->mRdiMemoryLock.unlock(); /* get rdi size, by qury mm_camera*/ memset(&dim, 0, sizeof(cam_ctrl_dimension_t)); ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim); if (MM_CAMERA_OK != ret) { ALOGE("%s: error - can't get camera dimension!", __func__); ALOGE("%s: X", __func__); return BAD_VALUE; }else { width = dim.rdi0_width; height = dim.rdi0_height; } ret = getBufferRdi( ); if(ret != NO_ERROR) { ALOGE("%s: cannot get memory from heap, ret = %d", __func__, ret); return ret; } /* set 4 buffers for display */ memset(&mRdiStreamBuf, 0, sizeof(mRdiStreamBuf)); mHalCamCtrl->mRdiMemoryLock.lock(); this->mRdiStreamBuf.num = mHalCamCtrl->mRdiMemory.buffer_count; this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/ frame_len = mm_camera_get_msm_frame_len(CAMERA_RDI, myMode, dim.rdi0_width, dim.rdi0_height, OUTPUT_TYPE_R, &num_planes, planes); this->mRdiStreamBuf.frame_len = frame_len; memset(&mRdiBuf, 0, sizeof(mRdiBuf)); mRdiBuf.def.buf.mp = new mm_camera_mp_buf_t[mRdiStreamBuf.num]; if (!mRdiBuf.def.buf.mp) { ALOGE("%s Error allocating memory for mplanar struct ", __func__); } memset(mRdiBuf.def.buf.mp, 0, mRdiStreamBuf.num * sizeof(mm_camera_mp_buf_t)); /*allocate memory for the buffers*/ void *vaddr = NULL; for(int i = 0; i < mRdiStreamBuf.num; i++){ if (mHalCamCtrl->mRdiMemory.camera_memory[i] == NULL) continue; mRdiStreamBuf.frame[i].fd = mHalCamCtrl->mRdiMemory.fd[i]; mRdiStreamBuf.frame[i].cbcr_off = planes[0]; mRdiStreamBuf.frame[i].y_off = 0; mRdiStreamBuf.frame[i].path = OUTPUT_TYPE_R; mRdiStreamBuf.frame[i].buffer = (long unsigned int)mHalCamCtrl->mRdiMemory.camera_memory[i]->data; mRdiStreamBuf.frame[i].ion_alloc.len = mHalCamCtrl->mRdiMemory.alloc[i].len; ALOGI("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, " "vaddr = 0x%x", __func__, i, mRdiStreamBuf.frame[i].fd, frame_len, mRdiStreamBuf.frame[i].cbcr_off, mRdiStreamBuf.frame[i].y_off, (uint32_t)mRdiStreamBuf.frame[i].buffer); if (NO_ERROR != mHalCamCtrl->sendMappingBuf( MSM_V4L2_EXT_CAPTURE_MODE_RDI, i, mRdiStreamBuf.frame[i].fd, mHalCamCtrl->mRdiMemory.size, mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING)) { ALOGE("%s: sending mapping data Msg Failed", __func__); } mRdiBuf.def.buf.mp[i].frame = mRdiStreamBuf.frame[i]; mRdiBuf.def.buf.mp[i].frame_offset = mRdiStreamBuf.frame[i].y_off; mRdiBuf.def.buf.mp[i].num_planes = num_planes; /* Plane 0 needs to be set seperately. Set other planes * in a loop. */ mRdiBuf.def.buf.mp[i].planes[0].length = planes[0]; mRdiBuf.def.buf.mp[i].planes[0].m.userptr = mRdiStreamBuf.frame[i].fd; mRdiBuf.def.buf.mp[i].planes[0].data_offset = 0; mRdiBuf.def.buf.mp[i].planes[0].reserved[0] = mRdiBuf.def.buf.mp[i].frame_offset; for (int j = 1; j < num_planes; j++) { mRdiBuf.def.buf.mp[i].planes[j].length = planes[j]; mRdiBuf.def.buf.mp[i].planes[j].m.userptr = mRdiStreamBuf.frame[i].fd; mRdiBuf.def.buf.mp[i].planes[j].data_offset = 0; mRdiBuf.def.buf.mp[i].planes[j].reserved[0] = mRdiBuf.def.buf.mp[i].planes[j-1].reserved[0] + mRdiBuf.def.buf.mp[i].planes[j-1].length; } for (int j = 0; j < num_planes; j++) ALOGI("Planes: %d length: %d userptr: %lu offset: %d\n", j, mRdiBuf.def.buf.mp[i].planes[j].length, mRdiBuf.def.buf.mp[i].planes[j].m.userptr, mRdiBuf.def.buf.mp[i].planes[j].reserved[0]); }/*end of for loop*/ /* register the streaming buffers for the channel*/ mRdiBuf.ch_type = MM_CAMERA_CH_RDI; mRdiBuf.def.num = mRdiStreamBuf.num; mHalCamCtrl->mRdiMemoryLock.unlock(); ALOGD("%s:END",__func__); return NO_ERROR; end: if (MM_CAMERA_OK == ret ) { ALOGV("%s: X - NO_ERROR ", __func__); return NO_ERROR; } ALOGV("%s: out of memory clean up", __func__); /* release the allocated memory */ ALOGV("%s: X - BAD_VALUE ", __func__); return BAD_VALUE; }