线程学习

 

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() 的参数,是一个字串,这个参数的指针可以通过

 

   pthread_join( thread1, &pth_join_ret1);

 

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
", __func__);
+    	    }
+    	    ALOGE("%s: c9000 send dump preview  thread exit msg  success 
", __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
", __func__);
+    	    }
+    	    ALOGE("%s: c9000 send dump snapshot thread exit msg  success 
", __func__);
+    	    mSnapshotProcTh.exit();
+    	    m_bSnapshotThreadActive = false;
+        }
+    }		
+}
+

2.

+int32_t QCamera2HardwareInterface::processDumpDataNotify(qcamera_dumpdata_t  *dumpdata,int type )
+{
+    int ret = NO_ERROR;
+    ALOGE("%s: c9000 
", __func__);
+    if (type == CAM_STREAM_TYPE_PREVIEW) 
+    {
+	if (m_bPreviewThreadActive && mPreviewDataQ.enqueue((void *)dumpdata)) {
+	    ALOGE("%s: c9000 send dump preview data msg sending 
", __func__);
+            if (NO_ERROR != mPreviewProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE)){
+		ALOGE("%s: c9000 send dump preview data msg  fail
", __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 
", __func__);
+            if( NO_ERROR != mSnapshotProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE)){
+		ALOGE("%s: c9000 send dump snapshot data msg  fail
", __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 (&current_time);
+                    	    timeinfo = localtime (&current_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
", __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 (&current_time);
+                    	    timeinfo = localtime (&current_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
", __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