线程学习
pthread_create函数:/*创建一个线程*/
原型:int pthread_create((pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
用法:#include <pthread.h>
功能:创建线程(实际上就是确定调用该线程函数的入口点),在线程创建以后,就开始运行相关的线程函数。
说明:thread:线程标识符;
attr:线程属性设置,可以用NULL,表示使用默认的属性;
start_routine:线程运行函数的起始地址;
arg:传递给start_routine的参数,NULL表示无参数;
返回值:成功,返回0;出错,返回-1。
pthread_join函数:/*等待子线程执行完毕,函数的调用者在等待子线程退出后才继续执行! */
pthread_exit函数:
线程通过调用pthread_exit函数终止执行,就如同进程在结束时调用exit函数一样。这个函数的作用是,终止调用它的线程并返回一个指向某个对象的指针。
pthread_exit ("thread all done"); // 重点看 pthread_exit() 的参数,是一个字串,这个参数的指针可以通过
xxxx
在高通原始代码中,打开 dump 后,预览会很卡顿,这使得不方便重现问题,利用多线程优化 dump 数据:
声明:
diff --git a/QCamera2HWI.h b/QCamera2HWI.h old mode 100644 new mode 100755 index df10cc8..54b9e0a --- a/QCamera2HWI.h +++ b/QCamera2HWI.h @@ -323,6 +323,13 @@ typedef struct { uint32_t frame_index; // frame index for the buffer } qcamera_callback_argm_t; +typedef struct { + QCameraStream *stream; + mm_camera_buf_def_t *frame; + uint32_t dump_type; + cam_dimension_t dim; +} qcamera_dumpdata_t; + class QCameraCbNotifier { public: #if defined(SAMSUNG_CAMERA) @@ -433,6 +440,8 @@ public: cam_pp_offline_src_config_t *config); static int prepare_preview(struct camera_device *); static int prepare_snapshot(struct camera_device *device); + static void *dumpPreviewFrameToFile_thread(void *dump); + static void *dumpSnapshotFrameToFile_thread(void *dump); public: QCamera2HardwareInterface(uint32_t cameraId); @@ -491,6 +500,9 @@ public: uint32_t getCameraId() { return mCameraId; }; void getParams(QCameraParameters **pParm) {*pParm = &mParameters;}; private: + int streamDataCBdump(int ); + int processDumpDataNotify(qcamera_dumpdata_t *dumpdata,int type); + void dumpThreadexit(int ); int setPreviewWindow(struct preview_stream_ops *window); int setCallBacks( camera_notify_callback notify_cb, @@ -785,8 +797,8 @@ private: QCameraPostProcessor m_postprocessor; // post processor QCameraThermalAdapter &m_thermalAdapter; QCameraCbNotifier m_cbNotifier; - pthread_mutex_t m_lock; - pthread_cond_t m_cond; + pthread_mutex_t m_lock,m_previewlock,m_snapshotlock; + pthread_cond_t m_cond,m_previewcond,m_snapshotcond; api_result_list *m_apiResultList; QCameraMemoryPool m_memoryPool; @@ -1264,6 +1276,10 @@ private: // void setHighBrightnessModeOfLCD(int on, char *prevHBM, char *prevAutoHBM); #endif #endif // SAMSUNG_CAMERA + QCameraQueue mDataQ,mPreviewDataQ,mSnapshotDataQ; + QCameraCmdThread mProcTh,mPreviewProcTh,mSnapshotProcTh; + bool m_bSnapshotThreadActive,m_bPreviewThreadActive; // if thread is active + }; }; // namespace qcamera
实现:
1.
diff --git a/QCamera2HWICallbacks.cpp b/QCamera2HWICallbacks.cpp old mode 100644 new mode 100755 index 7cafc86..2c4d383 --- a/QCamera2HWICallbacks.cpp +++ b/QCamera2HWICallbacks.cpp + +void QCamera2HardwareInterface::dumpThreadexit(int type) +{ + if (type == CAM_STREAM_TYPE_PREVIEW) { + if (m_bPreviewThreadActive == true){ + if (NO_ERROR != mPreviewProcTh.sendCmd(CAMERA_CMD_TYPE_EXIT, FALSE, FALSE)){ + ALOGE("%s: c9000 send dump thread exit msg fail\n", __func__); + } + ALOGE("%s: c9000 send dump preview thread exit msg success \n", __func__); + mPreviewProcTh.exit(); + m_bPreviewThreadActive = false; + } + }else if (type == CAM_STREAM_TYPE_SNAPSHOT) + { + if (m_bSnapshotThreadActive == true){ + if( NO_ERROR != mSnapshotProcTh.sendCmd(CAMERA_CMD_TYPE_EXIT, FALSE, FALSE)){ + ALOGE("%s: c9000 send dump thread exit msg fail\n", __func__); + } + ALOGE("%s: c9000 send dump snapshot thread exit msg success \n", __func__); + mSnapshotProcTh.exit(); + m_bSnapshotThreadActive = false; + } + } +} +
2.
+int32_t QCamera2HardwareInterface::processDumpDataNotify(qcamera_dumpdata_t *dumpdata,int type ) +{ + int ret = NO_ERROR; + ALOGE("%s: c9000 \n", __func__); + if (type == CAM_STREAM_TYPE_PREVIEW) + { + if (m_bPreviewThreadActive && mPreviewDataQ.enqueue((void *)dumpdata)) { + ALOGE("%s: c9000 send dump preview data msg sending \n", __func__); + if (NO_ERROR != mPreviewProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE)){ + ALOGE("%s: c9000 send dump preview data msg fail\n", __func__); + ret = -1; + } + } else { + ALOGE("%s: c9000 preview stream thread is not active, no ops here", __func__); + } + }else if (type == CAM_STREAM_TYPE_SNAPSHOT) + { + if (m_bSnapshotThreadActive && mSnapshotDataQ.enqueue((void *)dumpdata)) { + ALOGE("%s: c9000 send dump snapshot data msg sending \n", __func__); + if( NO_ERROR != mSnapshotProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE)){ + ALOGE("%s: c9000 send dump snapshot data msg fail\n", __func__); + ret = -1; + } + } else { + ALOGE("%s: c9000 snapshot stream thread is not active, no ops here", __func__); + } + } + return ret; +} +
3.
+int QCamera2HardwareInterface::streamDataCBdump(int type) +{ + int32_t rc = 0; + ALOGE("[KPI Perf] %s: c9000 E", __func__); + if(type == CAM_STREAM_TYPE_PREVIEW){ + mPreviewDataQ.init(); + rc = mPreviewProcTh.launch(dumpPreviewFrameToFile_thread, this); + if (rc == NO_ERROR) { + m_bPreviewThreadActive = true; + }else return -1; + pthread_mutex_init(&m_previewlock, NULL); + pthread_cond_init(&m_previewcond, NULL); + }else if(type == CAM_STREAM_TYPE_SNAPSHOT){ + mSnapshotDataQ.init(); + rc = mSnapshotProcTh.launch(dumpSnapshotFrameToFile_thread, this); + if (rc == NO_ERROR) { + m_bSnapshotThreadActive = true; + }else return -1; + pthread_mutex_init(&m_snapshotlock, NULL); + pthread_cond_init(&m_snapshotcond, NULL); + } + ALOGE("[KPI Perf] %s: c9000 dump active ? (%d %d)X", __func__,m_bPreviewThreadActive,m_bSnapshotThreadActive); + return rc; +} +
4.
+void *QCamera2HardwareInterface::dumpPreviewFrameToFile_thread(void *data) +{ + /* add dataQ and cmd thread */ + int running = 1; + int ret; + QCamera2HardwareInterface *pme = reinterpret_cast <QCamera2HardwareInterface *> (data); + QCameraCmdThread *cmdThread = &pme->mPreviewProcTh; + qcamera_dumpdata_t *dumpdata = (qcamera_dumpdata_t*)malloc(sizeof(qcamera_dumpdata_t)); + QCameraStream *stream = (QCameraStream*)malloc(sizeof(QCameraStream)); + mm_camera_buf_def_t *frame = (mm_camera_buf_def_t*)malloc(sizeof(mm_camera_buf_def_t)); + cam_dimension_t dim; + cmdThread->setName("preview_dumpThread"); + + /* add dump operation */ + char value[PROPERTY_VALUE_MAX]; + uint32_t frm_num = 0; + uint32_t skip_mode = 0; + uint32_t dump_type; + uint32_t dumpFrmCnt; + uint32_t enabled; + camera_cmd_type_t cmd ; + + ALOGE("%s: c9000 E", __func__); + do { + do { + ALOGE("%s: c9000 before wait cmd %d process id : %d thread_id : %d", __func__, cmd,getpid(),gettid()); + ret = cam_sem_wait(&cmdThread->cmd_sem); + if (ret != 0 && errno != EINVAL) { + ALOGE("%s: c9000 cam_sem_wait error (%s)", __func__, strerror(errno)); + return NULL; + } + ALOGE("%s: c9000 after wait cmd %d process id : %d thread_id : %d", __func__, cmd,getpid(),gettid()); + } while (ret != 0); + + cmd = cmdThread->getCmd(); + switch (cmd) { + case CAMERA_CMD_TYPE_DO_NEXT_JOB: + property_get("persist.camera.dumpimg", value, "0"); + enabled = (uint32_t) atoi(value); + pthread_mutex_lock(&pme->m_previewlock); + dumpdata = (qcamera_dumpdata_t *)pme->mPreviewDataQ.dequeue(); + if (NULL == dumpdata) continue; + ALOGE("%s: get c9000 command ,dump type %d received", __func__,dumpdata->dump_type); + + stream = dumpdata->stream; + frame = dumpdata->frame; + dump_type = dumpdata->dump_type; + dim.width = dumpdata->dim.width; + dim.height = dumpdata->dim.height; + + if (NULL == stream || NULL == frame ) { + ALOGE("%s stream or frame object is null", __func__); + return (void *)NULL; ; + } + + dumpFrmCnt = stream->mDumpFrame; + ALOGE("%s: c9000 previewx data cb in dump frm_num:%d thread buf_idx: %d frame_idx: %d ", __func__,frm_num,frame->buf_idx , frame->frame_idx); + + if((enabled & QCAMERA_DUMP_FRM_MASK_ALL)) { + if((enabled & dump_type) && stream && frame) { + frm_num = ((enabled & 0xffff0000) >> 16); + ALOGE("%s c9000 frm_num=%d enabled=%d dump start dumpFrmCnt:%d", __func__,frm_num,enabled,dumpFrmCnt); + if(frm_num == 0) { + frm_num = 0x0000ffff; //default 10 frames + } + if(frm_num > 0x0000ffff) { + frm_num = 0x0000ffff; //256 buffers cycle around + } + skip_mode = ((enabled & 0x0000ff00) >> 8); + if(skip_mode == 0) { + skip_mode = 1; //no-skip + } + if(stream->mDumpSkipCnt == 0) stream->mDumpSkipCnt = 1; + + if( stream->mDumpSkipCnt % skip_mode == 0) { + ALOGE("%s c9000 frm_num=%d dumpFrmCnt=%d dump_type = %d skip_mode:%d mDumpSkipCnt:%d", __func__,frm_num,dumpFrmCnt,dump_type,skip_mode,stream->mDumpSkipCnt); + if((frm_num == 0x0000ffff) && (dumpFrmCnt >= frm_num)) { + dumpFrmCnt = 0;// reset frame count if cycling + } + if (dumpFrmCnt <= frm_num) { + char buf[32]; + char timeBuf[128]; + time_t current_time; + struct tm * timeinfo; + + memset(timeBuf, 0, sizeof(timeBuf)); + + time (¤t_time); + timeinfo = localtime (¤t_time); + memset(buf, 0, sizeof(buf)); + + cam_frame_len_offset_t offset; + memset(&offset, 0, sizeof(cam_frame_len_offset_t)); + stream->getFrameOffset(offset); + + if (NULL != timeinfo) { + strftime(timeBuf, sizeof(timeBuf),QCAMERA_DUMP_FRM_LOCATION "%Y%m%d%H%M%S", timeinfo); + } + String8 filePath(timeBuf); + switch (dump_type) { + case QCAMERA_DUMP_FRM_PREVIEW: + { + snprintf(buf, sizeof(buf), "%dp_%dx%d_%d.yuv",dumpFrmCnt, dim.width, dim.height, frame->frame_idx); + } + break; + default: + ALOGE("%s: Not supported for dumping stream type %d",__func__, dump_type); + return (void *)NULL;; + } + + filePath.append(buf); + FILE *file = fopen(filePath.string(), "wb"); + ssize_t written_len = 0; + if (file != NULL) { + void *data = NULL; + fwrite( (void *)(uint8_t *)frame->buffer,frame->frame_len ,1,file); + CDBG_HIGH("%s: written number of bytes %ld\n", __func__, written_len); + fclose(file); + } else { + ALOGE("%s: fail t open file for image dumping", __func__); + } + dumpFrmCnt++; + } + } + stream->mDumpSkipCnt++; + } + } else { + dumpFrmCnt = 0; + } + stream->mDumpFrame = dumpFrmCnt; + pthread_mutex_unlock(&pme->m_previewlock); + ALOGE("%s: snapshot dump end process id : %d thread_id : %d dumpFrmCnt:%d frame_idx: %d c9000", __func__,getpid(),gettid(),dumpFrmCnt, frame->frame_idx); + break; + + case CAMERA_CMD_TYPE_EXIT: + { + running = 0; + if(dumpdata) { + ALOGE("%s: free 1 err ? ", __func__); + free(dumpdata); + dumpdata = NULL; + } + pme->mPreviewDataQ.flush(); + ALOGE("%s: CAMERA_CMD_TYPE_EXIT and make preview thread no active c9000", __func__); + } + break; + + default: + break; + } + } while (running); + + return (void *)NULL; +} +
5.
+void *QCamera2HardwareInterface::dumpSnapshotFrameToFile_thread(void *data) +{ + /* add dataQ and cmd thread */ + int running = 1; + int ret; + QCamera2HardwareInterface *pme = reinterpret_cast <QCamera2HardwareInterface *> (data); + QCameraCmdThread *cmdThread = &pme->mSnapshotProcTh; + qcamera_dumpdata_t *dumpdata = (qcamera_dumpdata_t*)malloc(sizeof(qcamera_dumpdata_t)); + QCameraStream *stream = (QCameraStream*)malloc(sizeof(QCameraStream)); + mm_camera_buf_def_t *frame = (mm_camera_buf_def_t*)malloc(sizeof(mm_camera_buf_def_t)); + cam_dimension_t dim; + cmdThread->setName("snapshot_dumpThread"); + + /* add dump operation */ + char value[PROPERTY_VALUE_MAX]; + uint32_t frm_num = 0; + uint32_t skip_mode = 0; + uint32_t dump_type; + uint32_t dumpFrmCnt; + uint32_t enabled; + camera_cmd_type_t cmd ; + + ALOGE("%s:c9000 E", __func__); + do { + do { + ALOGE("%s: c9000 before wait cmd %d process id : %d thread_id : %d", __func__, cmd,getpid(),gettid()); + ret = cam_sem_wait(&cmdThread->cmd_sem); + if (ret != 0 && errno != EINVAL) { + ALOGE("%s: c9000 cam_sem_wait error (%s)", __func__, strerror(errno)); + return NULL; + } + ALOGE("%s: c9000 after wait cmd %d process id : %d thread_id : %d", __func__, cmd,getpid(),gettid()); + } while (ret != 0); + + cmd = cmdThread->getCmd(); + switch (cmd) { + case CAMERA_CMD_TYPE_DO_NEXT_JOB: + property_get("persist.camera.dumpimg", value, "0"); + enabled = (uint32_t) atoi(value); + pthread_mutex_lock(&pme->m_snapshotlock); + dumpdata = (qcamera_dumpdata_t *)pme->mSnapshotDataQ.dequeue(); + if (NULL == dumpdata) continue; + ALOGE("%s: get c9000 command ,dump type %d received", __func__,dumpdata->dump_type); + + stream = dumpdata->stream; + frame = dumpdata->frame; + dump_type = dumpdata->dump_type; + dim.width = dumpdata->dim.width; + dim.height = dumpdata->dim.height; + + if (NULL == stream || NULL == frame ) { + ALOGE("%s stream or frame object is null", __func__); + return (void *)NULL; ; + } + + dumpFrmCnt = stream->mDumpFrame; + ALOGE("%s: c9000 previewx data cb in dump frm_num:%d thread buf_idx: %d frame_idx: %d ", __func__,frm_num,frame->buf_idx , frame->frame_idx); + if (true == pme->m_bIntRawEvtPending) { + enabled = QCAMERA_DUMP_FRM_RAW; + } + + if((enabled & QCAMERA_DUMP_FRM_MASK_ALL)) { + if((enabled & dump_type) && stream && frame) { + frm_num = ((enabled & 0xffff0000) >> 16); + ALOGE("%s c9000 frm_num=%d enabled=%d dump start dumpFrmCnt:%d", __func__,frm_num,enabled,dumpFrmCnt); + if(frm_num == 0) { + frm_num = 0x0000ffff; //default 10 frames + } + if(frm_num > 0x0000ffff) { + frm_num = 0x0000ffff; //256 buffers cycle around + } + skip_mode = ((enabled & 0x0000ff00) >> 8); + if(skip_mode == 0) { + skip_mode = 1; //no-skip + } + if(stream->mDumpSkipCnt == 0) + stream->mDumpSkipCnt = 1; + + if( stream->mDumpSkipCnt % skip_mode == 0) { + ALOGE("%s c9000 frm_num=%d dumpFrmCnt=%d dump_type = %d skip_mode:%d mDumpSkipCnt:%d", __func__,frm_num,dumpFrmCnt,dump_type,skip_mode,stream->mDumpSkipCnt); + if((frm_num == 0x0000ffff) && (dumpFrmCnt >= frm_num)) { + dumpFrmCnt = 0; // reset frame count if cycling + } + if (dumpFrmCnt <= frm_num) { + char buf[32]; + char timeBuf[128]; + time_t current_time; + struct tm * timeinfo; + + memset(timeBuf, 0, sizeof(timeBuf)); + + time (¤t_time); + timeinfo = localtime (¤t_time); + memset(buf, 0, sizeof(buf)); + + cam_frame_len_offset_t offset; + memset(&offset, 0, sizeof(cam_frame_len_offset_t)); + stream->getFrameOffset(offset); + + if (NULL != timeinfo) { + strftime(timeBuf, sizeof(timeBuf),QCAMERA_DUMP_FRM_LOCATION "%Y%m%d%H%M%S", timeinfo); + } + String8 filePath(timeBuf); + switch (dump_type) { + case QCAMERA_DUMP_FRM_SNAPSHOT: + { + if (!pme->mParameters.isPostProcScaling()) { + pme->mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim); + } else { + stream->getFrameDimension(dim); + } + snprintf(buf, sizeof(buf), "%ds_%dx%d_%d.yuv",dumpFrmCnt, dim.width, dim.height, frame->frame_idx); + } + break; + case QCAMERA_DUMP_FRM_RAW: + { + pme->mParameters.getStreamDimension(CAM_STREAM_TYPE_RAW, dim); + snprintf(buf, sizeof(buf), "%dr_%dx%d_%d.raw",dumpFrmCnt, dim.width, dim.height, frame->frame_idx); + } + break; + default: + ALOGE("%s: Not supported for dumping stream type %d",__func__, dump_type); + return (void *)NULL;; + } + + filePath.append(buf); + int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777); + //FILE *file = fopen(filePath.string(), "wb"); + ssize_t written_len = 0; + if (file_fd >= 0) { + void *data = NULL; + //fwrite( (void *)(uint8_t *)frame->buffer,frame->frame_len ,1,file); + fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + for (uint32_t i = 0; i < offset.num_planes; i++) { + uint32_t index = offset.mp[i].offset; + if (i > 0) { + index += offset.mp[i-1].len; + } + for (int j = 0; j < offset.mp[i].height; j++) { + data = (void *)((uint8_t *)frame->buffer + index); + written_len += write(file_fd, data,(size_t)offset.mp[i].width); + index += (uint32_t)offset.mp[i].stride; + } + } + CDBG_HIGH("%s: written number of bytes %ld\n", __func__, written_len); + close(file_fd); + //fclose(file); + } else { + ALOGE("%s: fail t open file for image dumping", __func__); + } + if (true == pme->m_bIntRawEvtPending) { + strlcpy(pme->m_BackendFileName, filePath.string(), QCAMERA_MAX_FILEPATH_LENGTH); + pme->mBackendFileSize = (size_t)written_len; + } else { + dumpFrmCnt++; + } + } + } + stream->mDumpSkipCnt++; + } + } else { + dumpFrmCnt = 0; + } + stream->mDumpFrame = dumpFrmCnt; + pthread_mutex_unlock(&pme->m_snapshotlock); + ALOGE("%s: snapshot dump end process id : %d thread_id : %d dumpFrmCnt:%d frame_idx: %d c9000", __func__,getpid(),gettid(),dumpFrmCnt, frame->frame_idx); + break; + + case CAMERA_CMD_TYPE_EXIT: + { + running = 0; + if(dumpdata) { ALOGE("%s: free 1 err ? ", __func__); free(dumpdata) ; dumpdata = NULL ;} + pme->mSnapshotDataQ.flush(); + ALOGE("%s: CAMERA_CMD_TYPE_EXIT and make snapshot thread no active c9000", __func__); + } + break; + default: + break; + } + } while (running); + + return (void *)NULL; +} + +
调用:
1.
diff --git a/QCamera2HWI.cpp b/QCamera2HWI.cpp old mode 100644 new mode 100755 index 4e52a25..b12b738 --- a/QCamera2HWI.cpp +++ b/QCamera2HWI.cpp @@ -1272,6 +1272,7 @@ int QCamera2HardwareInterface::cancel_picture(struct camera_device *device) ret = apiResult.status; } hw->unlockAPI(); + hw->dumpThreadexit(CAM_STREAM_TYPE_SNAPSHOT); CDBG_HIGH("[KPI Perf] %s: X camera id %d", __func__, hw->getCameraId()); return ret; @@ -5008,6 +5009,7 @@ int QCamera2HardwareInterface::stopPreview() } } else { if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) { + dumpThreadexit(CAM_STREAM_TYPE_PREVIEW); rc = stopChannel(QCAMERA_CH_TYPE_PREVIEW); } } @@ -10140,6 +10142,7 @@ int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel, if (streamType == CAM_STREAM_TYPE_RAW) { prepareRawStream(pChannel); } + streamDataCBdump(streamType); QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType); if (pStreamInfo == NULL) { ALOGE("%s: no mem for stream info buf", __func__);
2.
diff --git a/QCamera2HWICallbacks.cpp b/QCamera2HWICallbacks.cpp old mode 100644 new mode 100755 index 7cafc86..2c4d383 --- a/QCamera2HWICallbacks.cpp +++ b/QCamera2HWICallbacks.cpp @@ -225,7 +225,13 @@ void QCamera2HardwareInterface::zsl_channel_cb(mm_camera_super_buf_t *recvd_fram QCameraStream *pStream = pChannel->getStreamByHandle(raw_frame->stream_id); if ( NULL != pStream ) { ALOGW("zsl_channel_cb : Dumping RAW frame index %d", raw_frame->frame_idx); - pme->dumpFrameToFile(pStream, raw_frame, QCAMERA_DUMP_FRM_RAW); + qcamera_dumpdata_t *dumpdata = (qcamera_dumpdata_t *)malloc(sizeof (qcamera_dumpdata_t)); + dumpdata->stream = pStream; + dumpdata->frame = raw_frame; + dumpdata->dump_type = QCAMERA_DUMP_FRM_RAW; + //send msg + pme->processDumpDataNotify(dumpdata,CAM_STREAM_TYPE_SNAPSHOT); + //pme->dumpFrameToFile(pStream, raw_frame, QCAMERA_DUMP_FRM_RAW); } break; } @@ -242,7 +248,13 @@ void QCamera2HardwareInterface::zsl_channel_cb(mm_camera_super_buf_t *recvd_fram QCameraStream *pStream = pChannel->getStreamByHandle(yuv_frame->stream_id); if ( NULL != pStream ) { ALOGW("zsl_channel_cb : Dumping YUV frame index %d", yuv_frame->frame_idx); - pme->dumpFrameToFile(pStream, yuv_frame, QCAMERA_DUMP_FRM_SNAPSHOT); + qcamera_dumpdata_t *dumpdata = (qcamera_dumpdata_t *)malloc(sizeof (qcamera_dumpdata_t)); + dumpdata->stream = pStream; + dumpdata->frame = yuv_frame; + dumpdata->dump_type = QCAMERA_DUMP_FRM_SNAPSHOT; + //send msg + pme->processDumpDataNotify(dumpdata,CAM_STREAM_TYPE_SNAPSHOT); + //pme->dumpFrameToFile(pStream, yuv_frame, QCAMERA_DUMP_FRM_SNAPSHOT); } break; } @@ -1402,9 +1414,17 @@ void QCamera2HardwareInterface::preview_stream_cb_routine(mm_camera_super_buf_t #ifdef TARGET_TS_MAKEUP pme->TsMakeupProcess_Preview(frame,stream); #endif - - if (dump_raw) - pme->dumpFrameToFile(stream, super_frame->bufs[0], QCAMERA_DUMP_FRM_PREVIEW); + ALOGE("%s: c9000 preview data cb buf_idx: %d frame_idx: %d ", __func__,frame->buf_idx , frame->frame_idx); + if(dump_raw){ + qcamera_dumpdata_t *dumpdata = (qcamera_dumpdata_t *)malloc(sizeof (qcamera_dumpdata_t)); + dumpdata->stream = stream; + dumpdata->frame = frame; + dumpdata->dump_type = QCAMERA_DUMP_FRM_PREVIEW; + stream->getFrameDimension(dumpdata->dim); + //send msg + pme->processDumpDataNotify(dumpdata,CAM_STREAM_TYPE_PREVIEW); + //pme->dumpFrameToFile(stream, super_frame->bufs[0], QCAMERA_DUMP_FRM_PREVIEW); + } if (!pme->needProcessPreviewFrame()) { ALOGE("preview_stream_cb_routine: preview is not running, no need to process"); @@ -3900,7 +3920,7 @@ void QCamera2HardwareInterface::metadata_stream_cb_routine(mm_camera_super_buf_t ((metering == CAM_AEC_MODE_WEIGHTED_MATRIX) || (metering == CAM_AEC_MODE_WEIGHTED_CENTER) || (metering == CAM_AEC_MODE_WEIGHTED_SPOT))) { - CDBG("HAL send ae_result value to framework/app, ae_result value is (%d)", *((uint8_t *)POINTER_OF_PARAM(CAM_INTF_META_TOUCH_AE_RESULT, pMetaData))); + ALOGE("HAL send ae_result value to framework/app, ae_result value is (%d) metering%d", *((uint8_t *)POINTER_OF_PARAM(CAM_INTF_META_TOUCH_AE_RESULT, pMetaData)),metering); pme->sendEvtNotify(TOUCH_AE_RESULT_MSG, *((uint8_t *)POINTER_OF_PARAM(CAM_INTF_META_TOUCH_AE_RESULT, pMetaData)), 0); } #endif @@ -5064,6 +5084,426 @@ void QCamera2HardwareInterface::dumpMetadataToFile(QCameraStream *stream, } stream->mDumpMetaFrame = dumpFrmCnt; }
使 dump 保持运行:
/*=========================================================================== * FUNCTION : dumpFrameToFile * @@ -5103,7 +5543,7 @@ void QCamera2HardwareInterface::dumpFrameToFile(QCameraStream *stream, if((enabled & dump_type) && stream && frame) { frm_num = ((enabled & 0xffff0000) >> 16); if(frm_num == 0) { - frm_num = 10; //default 10 frames + frm_num = 256; //default 10 frames } if(frm_num > 256) { frm_num = 256; //256 buffers cycle around @@ -5425,7 +5865,7 @@ void * QCameraCbNotifier::cbNotifyRoutine(void * data) } while (ret != 0);