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);
原文:https://www.cnblogs.com/Pitter99/p/6113951.html