zoukankan      html  css  js  c++  java
  • 线程学习

     

    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);
    

     

  • 相关阅读:
    atitit.为什么技术的选择方法java超过.net有前途
    HDU 4022 Bombing STL 模拟题
    定制XP引导屏幕背景图像和替换windows这句话
    《STL源代码分析》---stl_heap.h读书笔记
    2015在大型多人在线游戏市场报告
    于Unity3D调用安卓AlertDialog
    jQuery整理笔记5----jQuery大事
    推断字符串数组里面是空的
    软测试-数据结构
    2014第18周三
  • 原文地址:https://www.cnblogs.com/Pitter99/p/6113951.html
Copyright © 2011-2022 走看看