📄 dc1394_capture.c
字号:
// we first have to verify that channels/bandwidth have been allocated. err=dc1394_allocate_iso_channel_and_bandwidth(camera); DC1394_ERR_RTN(err,"Could not allocate ISO channel and bandwidth!"); err=_dc1394_capture_basic_setup(camera); DC1394_ERR_RTN(err,"Could not setup capture"); /* fprintf(stderr,"qpf: %d qpp: %d size [%d x %d]\n", craw->capture.quadlets_per_frame, craw->capture.quadlets_per_packet, craw->capture.frame_width, craw->capture.frame_height); */ craw->capture.capture_buffer= (uchar_t*)malloc(craw->capture.quadlets_per_frame*4); if (craw->capture.capture_buffer == NULL) { printf("(%s) unable to allocate memory for capture buffer\n", __FILE__); return DC1394_MEMORY_ALLOCATION_FAILURE; } else camera->capture_is_set=1; return err;}dc1394error_tdc1394_capture_setup_dma(dc1394camera_t *camera, uint_t num_dma_buffers, dc1394ring_buffer_policy_t policy){ DC1394_CAST_CAMERA_TO_LINUX(craw, camera); dc1394error_t err; // we first have to verify that channels/bandwidth have been allocated. err=dc1394_allocate_iso_channel_and_bandwidth(camera); DC1394_ERR_RTN(err,"Could not allocate ISO channel and bandwidth!"); err=_dc1394_capture_basic_setup(camera); DC1394_ERR_RTN(err,"Could not setup capture"); craw->capture.ring_buffer_policy = policy; // the capture_is_set flag is set inside this function: err=_dc1394_capture_dma_setup (camera, num_dma_buffers); DC1394_ERR_RTN(err,"Could not setup DMA capture"); return err;}/***************************************************** CAPTURE_STOP*****************************************************/dc1394error_t dc1394_capture_stop(dc1394camera_t *camera) { DC1394_CAST_CAMERA_TO_LINUX(craw, camera); if (camera->capture_is_set>0) { switch (camera->capture_is_set) { case 1: // RAW 1394 if (craw->capture.capture_buffer != NULL) { free(craw->capture.capture_buffer); craw->capture.capture_buffer=NULL; } break; case 2: // DMA (VIDEO1394) // unlisten if (ioctl(craw->capture.dma_fd, VIDEO1394_IOC_UNLISTEN_CHANNEL, &(camera->iso_channel)) < 0) return DC1394_IOCTL_FAILURE; // release if (craw->capture.dma_ring_buffer) { munmap((void*)craw->capture.dma_ring_buffer,craw->capture.dma_buffer_size); } _dc1394_num_using_fd[camera->port]--; if (_dc1394_num_using_fd[camera->port] == 0) { while (close(craw->capture.dma_fd) != 0) { printf("(%s) waiting for dma_fd to close\n", __FILE__); sleep(1); } } // this dma_device file is allocated by the strdup() function and can be freed here without problems. free(craw->capture.dma_device_file); craw->capture.dma_device_file=NULL; break; default: return DC1394_INVALID_CAPTURE_MODE; break; } // capture is not set anymore camera->capture_is_set=0; dc1394_free_iso_channel_and_bandwidth(camera); // free the additional capture handle raw1394_destroy_handle(craw->capture.handle); } else { return DC1394_CAPTURE_IS_NOT_SET; } return DC1394_SUCCESS;}/**************************************************** CAPTURE*****************************************************/dc1394error_t dc1394_capture(dc1394camera_t **cams, uint_t num) { int i, j; _dc1394_all_captured= num; dc1394capture_t * captures[num]; /* this first routine does the setup- sets up the global variables needed in the handler, sets the iso handler, tells the 1394 subsystem to listen for iso packets */ for (i = 0; i < num; i++) { DC1394_CAST_CAMERA_TO_LINUX(craw, cams[i]); captures[i] = &(craw->capture); } for (i= 0; i < num; i++) { // we are about to use the iso channels, so set the capture flag // cams[i]->capture_is_set=1; _dc1394_buffer[cams[i]->iso_channel]= (int*)captures[i]->capture_buffer; if (raw1394_set_iso_handler(captures[i]->handle, cams[i]->iso_channel, _dc1394_video_iso_handler) < 0) { /* error handling- for some reason something didn't work, so we have to reset everything....*/ printf("(%s:%d) error!\n",__FILE__, __LINE__); for (j= i - 1; j > -1; j--) { raw1394_stop_iso_rcv(captures[i]->handle, cams[j]->iso_channel); raw1394_set_iso_handler(captures[i]->handle, cams[j]->iso_channel, NULL); } return DC1394_RAW1394_CAPTURE_FAILURE; } //fprintf(stderr,"handle: 0x%x\n",(unsigned int)cams[i]->handle); _dc1394_frame_captured[cams[i]->iso_channel] = 0; _dc1394_quadlets_per_frame[cams[i]->iso_channel] = captures[i]->quadlets_per_frame; _dc1394_quadlets_per_packet[cams[i]->iso_channel] = captures[i]->quadlets_per_packet; //fprintf(stderr,"starting reception...\n"); //fprintf(stderr,"handle: 0x%x\n",(unsigned int)cams[i]->handle); if (raw1394_start_iso_rcv(captures[i]->handle,cams[i]->iso_channel) < 0) { /* error handling- for some reason something didn't work, so we have to reset everything....*/ fprintf(stderr,"(%s:%d) error!\n", __FILE__, __LINE__); for (j= 0; j < num; j++) { raw1394_stop_iso_rcv(captures[i]->handle, cams[j]->iso_channel); raw1394_set_iso_handler(captures[i]->handle, cams[j]->iso_channel, NULL); } return DC1394_RAW1394_CAPTURE_FAILURE; } } //fprintf(stderr,"data loop...\n"); /* now we iterate till the data is here*/ while (_dc1394_all_captured != 0) { //fprintf(stderr,"iter "); raw1394_loop_iterate(captures[0]->handle); } //fprintf(stderr,"data loop...\n"); /* now stop the subsystem from listening*/ for (i= 0; i < num; i++) { raw1394_stop_iso_rcv(captures[i]->handle, cams[i]->iso_channel); raw1394_set_iso_handler(captures[i]->handle,cams[i]->iso_channel, NULL); // we are not listening anymore, release the capture flags // cams[i]->capture_is_set=0; } return DC1394_SUCCESS;}dc1394error_tdc1394_capture_dma(dc1394camera_t **cameras, uint_t num, dc1394video_policy_t policy) { struct video1394_wait vwait; int i; int cb; int j; int result=-1; int last_buffer_orig; int extra_buf; dc1394capture_t * captures[num]; //fprintf(stderr,"test0\n"); for (i = 0; i < num; i++) { DC1394_CAST_CAMERA_TO_LINUX(craw, cameras[i]); captures[i] = &(craw->capture); } for (i= 0; i < num; i++) { last_buffer_orig = captures[i]->dma_last_buffer; cb = (captures[i]->dma_last_buffer + 1) % captures[i]->num_dma_buffers; captures[i]->dma_last_buffer = cb; vwait.channel = cameras[i]->iso_channel; vwait.buffer = cb; switch (policy) { case DC1394_VIDEO1394_POLL: result=ioctl(captures[i]->dma_fd, VIDEO1394_IOC_LISTEN_POLL_BUFFER, &vwait); break; case DC1394_VIDEO1394_WAIT: default: result=ioctl(captures[i]->dma_fd, VIDEO1394_IOC_LISTEN_WAIT_BUFFER, &vwait); break; } //fprintf(stderr,"test1\n"); if ( result != 0) { captures[i]->dma_last_buffer = last_buffer_orig; if ((policy==DC1394_VIDEO1394_POLL) && (errno == EINTR)) { // when no frames is present, say so. return DC1394_NO_FRAME; } else { printf("(%s) VIDEO1394_IOC_LISTEN_WAIT/POLL_BUFFER ioctl failed!\n", __FILE__); captures[i]->dma_last_buffer++; //Ringbuffer-index or counter? return DC1394_IOCTL_FAILURE; } } //fprintf(stderr,"test2\n"); extra_buf = vwait.buffer; if (captures[i]->ring_buffer_policy==DC1394_RING_BUFFER_LAST) { if (extra_buf > 0) { for (j = 0; j < extra_buf; j++) { vwait.buffer = (cb + j) % captures[i]->num_dma_buffers; if (ioctl(captures[i]->dma_fd, VIDEO1394_IOC_LISTEN_QUEUE_BUFFER, &vwait) < 0) { printf("(%s) VIDEO1394_IOC_LISTEN_QUEUE_BUFFER failed in multi capture!\n", __FILE__); return DC1394_IOCTL_FAILURE; } } captures[i]->dma_last_buffer = (cb + extra_buf) % captures[i]->num_dma_buffers; /* Get the corresponding filltime: */ vwait.buffer = captures[i]->dma_last_buffer; if(ioctl(captures[i]->dma_fd, VIDEO1394_IOC_LISTEN_POLL_BUFFER, &vwait) < 0) { printf("(%s) VIDEO1394_IOC_LISTEN_POLL_BUFFER failed in multi capture!\n", __FILE__); return DC1394_IOCTL_FAILURE; } } } //fprintf(stderr,"test3\n"); /* point to the next buffer in the dma ringbuffer */ captures[i]->capture_buffer = (uchar_t*)(captures[i]->dma_ring_buffer + captures[i]->dma_last_buffer * captures[i]->dma_frame_size); captures[i]->filltime = vwait.filltime; captures[i]->num_dma_buffers_behind = extra_buf; } return DC1394_SUCCESS;}/**************************************************** dc1394_dma_done_with_buffer This allows the driver to use the buffer previously handed to the user by dc1394_dma_*_capture*****************************************************/dc1394error_t dc1394_capture_dma_done_with_buffer(dc1394camera_t *camera) { DC1394_CAST_CAMERA_TO_LINUX(craw, camera); struct video1394_wait vwait; if (craw->capture.dma_last_buffer == -1) return DC1394_SUCCESS; vwait.channel= camera->iso_channel; vwait.buffer= craw->capture.dma_last_buffer; if (ioctl(craw->capture.dma_fd, VIDEO1394_IOC_LISTEN_QUEUE_BUFFER, &vwait) < 0) { printf("(%s) VIDEO1394_IOC_LISTEN_QUEUE_BUFFER failed in done with buffer!\n", __FILE__); return DC1394_IOCTL_FAILURE; } return DC1394_SUCCESS;}/* functions to access the capture data */uchar_t*dc1394_capture_get_dma_buffer(dc1394camera_t *camera){ DC1394_CAST_CAMERA_TO_LINUX(craw, camera); return craw->capture.capture_buffer;}struct timeval*dc1394_capture_get_dma_filltime(dc1394camera_t *camera){ DC1394_CAST_CAMERA_TO_LINUX(craw, camera); return &(craw->capture.filltime);}uint_tdc1394_capture_get_width(dc1394camera_t *camera){ DC1394_CAST_CAMERA_TO_LINUX(craw, camera); return craw->capture.frame_width;}uint_tdc1394_capture_get_height(dc1394camera_t *camera){ DC1394_CAST_CAMERA_TO_LINUX(craw, camera); return craw->capture.frame_height;}uint_tdc1394_capture_get_bytes_per_frame(dc1394camera_t *camera){ DC1394_CAST_CAMERA_TO_LINUX(craw, camera); return craw->capture.quadlets_per_frame*4;}uint_tdc1394_capture_get_frames_behind(dc1394camera_t *camera){ DC1394_CAST_CAMERA_TO_LINUX(craw, camera); return craw->capture.num_dma_buffers_behind;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -