static void * comp_proc(void * para) { int i, j; int fd; int channel; int n_buffers = 0; unsigned int length, offset; int index, num; struct buffer_av buf_av; int result; struct pollfd pfd; unsigned int buf_index; unsigned int buf_num; char * packet_addr; struct packet_header pkt_header; Query_Buf_Res * buffers = NULL; //用于保存获取视频数据 Spct_Data comp_data; int got_video[CHS_PER_CARD]; int got_audio[CHS_PER_CARD]; struct timeval v_time_stamp[CHS_PER_CARD]; struct timeval a_time_stamp[CHS_PER_CARD]; unsigned int last_vtstamp[CHS_PER_CARD]; unsigned int last_atstamp[CHS_PER_CARD]; unsigned int duration; DebugPrintf("thread compress\n"); Ip_Cam_Device * ipcam = (Ip_Cam_Device *) para; memset(&buf_av, 0, sizeof(buf_av)); memset(&got_video, 0, sizeof(got_video)); memset(&got_audio, 0, sizeof(got_audio)); memset(&last_vtstamp, 0, sizeof(last_vtstamp)); memset(&last_atstamp, 0, sizeof(last_atstamp)); fd = ipcam->comp_fd; action_fd = fd; n_buffers = request_buffer(fd); buffers = calloc(n_buffers, sizeof(* buffers)); if(!buffers) EXIT("Out of memory."); for(i = 0; i < n_buffers; ++i) { if(query_buffer(fd, i, &length, &offset) != 0) EXIT("VIDIOC_QUERYBUF"); buffers[i].length = length; buffers[i].start = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset); DebugPrintf("buffers[%d].start = 0x%x\n",i, buffers[i].start); if(MAP_FAILED == buffers[i].start) EXIT("mmap"); } for(index = 0; index < n_buffers; index++) if(queue_buffer(fd, index) != 0) EXIT("VIDIOC_QBUF"); if(streaming_on(fd) != 0) EXIT("VIDIOC_STREAMON"); DebugPrintf("card stream on================================\n"); pfd.fd = fd; pfd.events = POLLIN; int comp_proc_count = 0; //set_action(fd, catch_sen); // fd threshold time /*检测ipcam是否处于运行状态*/ while(ipcam->status == CAM_STATUS_RUN) { comp_proc_count++; /*定时打印信息*/ if(comp_proc_count == 3000) { comp_proc_count = 0; PrintScreen("\n----- comp_proc thread running -----\n"); } //IsSetaction(fd); /*一个结构体,函数阻塞时间为15s*/ result = poll(&pfd, 1, 15000); /*函数调用失败*/ if(result < 0) DebugPrintf("pool ing errro ==================\n"); /*在规定时间内没有检测到可读套接字*/ if(result == 0) { DebugPrintf("pool ing time out --------------\n"); exit(1); } if(result < 0) continue; if(result == 0) continue; dequeue_buffer(fd, &buf_av); buf_index = buf_av.buf_index; buf_num = buf_av.length; for(i = 0; i < CHS_PER_CARD; i++) { index = buf_index & 0xff; num = buf_num & 0xff; buf_index >>= 8; buf_num >>= 8; if(index != 0xff) { /*DATA PACKET*/ channel = i; for(j = 0, packet_addr = buffers[index].start; j < num; j++) { /*s数据包处理,动态处理就在此实现*/ parse_packet(&packet_addr, &pkt_header); //pkt_header.motion_addr, 4 * 9 /*捕捉到动作*/ if(pkt_header.motion_flag) { #if RELEASE_MODE #else PrintScreen("\n-------------receive a motion------------\n\n"); #endif catchonemotion = 1; is_action = 1; } if (pkt_header.videolost_flag) { //DebugPrintf("video lost\n"); } if(pkt_header.audio_flag) {//length if(!got_audio[channel]) { got_audio[channel] = 1; //a_time_stamp[channel] = buf_av.timestamp; a_time_stamp[channel].tv_usec = ((pkt_header.audio_timestamp % 32768) * 1000ULL * 1000ULL) >> 15; a_time_stamp[channel].tv_sec = (pkt_header.audio_timestamp >> 15) + (a_time_stamp[channel].tv_usec / 1000000); a_time_stamp[channel].tv_usec %= 1000000; } else { duration = pkt_header.audio_timestamp - last_atstamp[channel]; a_time_stamp[channel].tv_usec += ((duration % 32768) * 1000ULL * 1000ULL) >> 15; a_time_stamp[channel].tv_sec += (duration >> 15) + (a_time_stamp[channel].tv_usec / 1000000); a_time_stamp[channel].tv_usec %= 1000000; } last_atstamp[channel] = pkt_header.audio_timestamp; //DebugPrintf("audio frame\n"); comp_data.channel = channel; comp_data.type = DATA_AUDIO; comp_data.flags = 0; comp_data.timestamp = a_time_stamp[channel]; comp_data.size = pkt_header.audio_length; comp_data.data = pkt_header.audio_addr; ipcam->fun(ipcam->datahandler, &comp_data); } if(pkt_header.video_flag) { if(!got_video[channel]) { got_video[channel] = 1; //v_time_stamp[channel] = buf_av.timestamp; v_time_stamp[channel].tv_usec = ((pkt_header.video_timestamp % 32768) * 1000ULL * 1000ULL) >> 15; v_time_stamp[channel].tv_sec = (pkt_header.video_timestamp >> 15) + (v_time_stamp[channel].tv_usec / 1000000); v_time_stamp[channel].tv_usec %= 1000000; } else { duration = pkt_header.video_timestamp - last_vtstamp[channel]; v_time_stamp[channel].tv_usec += ((duration % 32768) * 1000ULL * 1000ULL) >> 15; v_time_stamp[channel].tv_sec += (duration >> 15) + (v_time_stamp[channel].tv_usec / 1000000); v_time_stamp[channel].tv_usec %= 1000000; } last_vtstamp[channel] = pkt_header.video_timestamp; comp_data.channel = channel; comp_data.type = DATA_VIDEO; comp_data.flags = pkt_header.video_type; comp_data.timestamp = v_time_stamp[channel]; comp_data.size = pkt_header.video_length; comp_data.data = pkt_header.video_addr; ipcam->fun(ipcam->datahandler, &comp_data); }
int main(int argc, char **argv) { int shmid; int i,j; char in_str[16]; process_arguments(argc, argv); /* open the camera device */ if( (camera_fd = open(psz_video_dev, O_RDWR)) < 0 ) { char error_buf[256]; sprintf(error_buf, "open() %s", psz_video_dev); perror(error_buf); exit(-1); } get_caps(); get_format(); if( b_verbose ) printf("Device opened.\n"); if( b_verbose ) { printf("Video device:\t\t%s\n", psz_video_dev); print_caps(); print_format(); printf("Ouput directory:\t%s\n", psz_output_dir); printf("Image format:\t\t%s\n",str_formats[e_outfmt]); printf("\n"); printf("Opening device %s\n", psz_video_dev); if( b_named_filename ) { printf("Ouput filename:\t%s\n", psz_output_filename); } else if( b_named_pipe ) { printf("Using named pipe %s\n", psz_named_pipe); } if( b_shared_mem ) printf("Using shared memory. key = %i\n", shared_mem_key); } if( b_printinfo ) { printf("Device info:\n"); print_caps(); print_format(); close(camera_fd); exit(EXIT_SUCCESS); } (void)signal(SIGINT, exit_program); if( b_shared_mem && b_named_pipe ) { printf("WARNING: shared memory and named pipe can't be used together. Use more instances of camshot. Defaulting to named pipe.\n"); b_shared_mem = 0; } if( b_named_pipe ) { int ret_val = mkfifo(psz_named_pipe, 0666); if ((ret_val == -1) && (errno != EEXIST)) { perror("Error creating the named pipe"); exit(EXIT_FAILURE); } } if( req_width && req_height ) { if( b_verbose ) printf("Trying to set resolution to %ux%u.\n", req_width, req_height); if( set_width_height(req_width,req_height) == -1 ) printf("Unable to set the desired resolution.\n"); else if( b_verbose ) printf("Resolution set to %ux%u\n", req_width, req_height); } else { get_format(); req_width = camera_format.fmt.pix.width; req_height = camera_format.fmt.pix.height; } if( b_shared_mem ) { if((shmid = shmget(shared_mem_key, req_width*req_height*3, IPC_CREAT | 0666)) < 0) { perror("Error getting shared memory id"); exit(EXIT_FAILURE); } if((p_shm = (uint8_t *)shmat(shmid, NULL, 0)) == (void *) -1) { perror("Error getting shared memory ptr"); exit(EXIT_FAILURE); } shm_sem = semget((key_t)shared_mem_key, 1, IPC_CREAT | 0666); sem_set(&shm_sem); if( b_verbose ) printf("Shared memory ID: %i\nSemaphore ID: %i\n", shmid, shm_sem); } total_buffers = req_mmap_buffers(2); /* start the capture */ streaming_on(); /* let the camera self adjust by 'ignoring' 200 complete buffer queues */ printf("Letting the camera automaticaly adjust the picture:"); for(i=0; i<AUTO_ADJUST_TURNS; i++) { for(j=0; j<total_buffers; j++) { int ready_buf = dequeue_buffer(); /* don't queue the last buffers */ if( i<AUTO_ADJUST_TURNS-1 ) queue_buffer(ready_buf); } printf("."); fflush(stdout); } printf("Done.\n"); if( b_shared_mem || b_named_pipe ) { pthread_create(&stream_thread, NULL, &stream_func, NULL); while(1) { pthread_join(stream_thread, NULL); } } else { pthread_create(&capture_thread, NULL, &capture_func, NULL); } if( b_named_filename ) { usleep(200000); pthread_mutex_lock(&cond_mutex); pthread_cond_signal(&condition); pthread_mutex_unlock(&cond_mutex); usleep(200000); exit_program(SIGINT); fflush(stdout); return 0; } while( in_str[0] != 'q' ) { printf("Command (h for help): "); fflush(stdout); if( fgets(in_str, 16, stdin) == NULL ) { printf("Got NULL! Try again.\n"); continue; } switch(in_str[0]) { case 'x': pthread_mutex_lock(&cond_mutex); pthread_cond_signal(&condition); pthread_mutex_unlock(&cond_mutex); break; case 'h': printf("\nCommands:\n"); printf("\tx\tCapture a picture from camera.\n"); printf("\th\tPrints this help.\n"); printf("\tq\tQuits the program.\n"); printf("\n"); break; case 'q': case '\n': break; default: fprintf(stderr, "Unknown command %c\n", in_str[0]); break; } } /* Clean up */ exit_program(SIGINT); return 0; }