コード例 #1
0
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);
                    }
コード例 #2
0
ファイル: main.c プロジェクト: gerpayt/camshot
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;
}