📄 dc1394_capture_macosx.c
字号:
CFUUIDGetUUIDBytes (kIOFireWireIsochChannelInterfaceID)); if (!chan) { fprintf (stderr, "Could not create IsochChannelInterface\n"); return DC1394_FAILURE; } capture->chan = chan; rem_port = (*d)->CreateRemoteIsochPort (d, true, CFUUIDGetUUIDBytes (kIOFireWireRemoteIsochPortInterfaceID)); if (!rem_port) { fprintf (stderr, "Could not create RemoteIsochPortInterface\n"); return DC1394_FAILURE; } capture->rem_port = rem_port; (*rem_port)->SetAllocatePortHandler (rem_port, &allocate_port); (*rem_port)->SetRefCon ((IOFireWireLibIsochPortRef)rem_port, camera); capture->buffers = malloc (capture->num_frames * sizeof (buffer_info)); capture->current = -1; frame_size = capture->quadlets_per_frame * 4; capture->frame_pages = ((frame_size - 1) / getpagesize()) + 1; numdcls = (capture->quadlets_per_frame / capture->quadlets_per_packet + 1) * capture->num_frames; dcl_pool = (*d)->CreateNuDCLPool (d, numdcls, CFUUIDGetUUIDBytes (kIOFireWireNuDCLPoolInterfaceID)); if (!dcl_pool) { fprintf (stderr, "Could not create NuDCLPoolInterface\n"); return DC1394_FAILURE; } capture->dcl_pool = dcl_pool; dcl_program = CreateDCLProgram (camera); if (!dcl_program) { fprintf (stderr, "Could not create DCL Program\n"); return DC1394_FAILURE; } loc_port = (*d)->CreateLocalIsochPort (d, false, dcl_program, kFWDCLSyBitsEvent, 1, 1, nil, 0, &(capture->databuf), 1, CFUUIDGetUUIDBytes (kIOFireWireLocalIsochPortInterfaceID)); if (!loc_port) { fprintf (stderr, "Could not create LocalIsochPortInterface\n"); return DC1394_FAILURE; } capture->loc_port = loc_port; (*chan)->AddListener (chan, (IOFireWireLibIsochPortRef) loc_port); (*chan)->SetTalker (chan, (IOFireWireLibIsochPortRef) rem_port); if ((*chan)->AllocateChannel (chan) != kIOReturnSuccess) { fprintf (stderr, "Could not allocate channel\n"); return DC1394_FAILURE; } if ((*chan)->Start (chan) != kIOReturnSuccess) { fprintf (stderr, "Could not start channel\n"); return DC1394_FAILURE; } camera->capture_is_set=1; return DC1394_SUCCESS;}dc1394error_tdc1394_capture_setup(dc1394camera_t *camera) { return dc1394_capture_setup_dma (camera, 10, 0);}/***************************************************** CAPTURE_STOP*****************************************************/dc1394error_t dc1394_capture_stop(dc1394camera_t *camera) { DC1394_CAST_CAMERA_TO_MACOSX(craw, camera); dc1394capture_t * capture = &(craw->capture); IOVirtualRange * databuf = &(capture->databuf); if (capture->chan) { (*capture->chan)->Stop (capture->chan); (*capture->chan)->ReleaseChannel (capture->chan); } if (databuf->address) munmap ((void *) databuf->address, databuf->length); if (capture->chan) (*capture->chan)->Release (capture->chan); if (capture->loc_port) (*capture->loc_port)->Release (capture->loc_port); if (capture->rem_port) (*capture->rem_port)->Release (capture->rem_port); if (capture->dcl_pool) (*capture->dcl_pool)->Release (capture->dcl_pool); if (capture->buffers) { int i; for (i = 0; i < capture->num_frames; i++) free (capture->buffers[i].dcl_list); free (capture->buffers); } capture->chan = NULL; capture->rem_port = NULL; capture->loc_port = NULL; capture->dcl_pool = NULL; capture->databuf.address = (vm_address_t) NULL; capture->buffers = NULL; camera->capture_is_set=0; return DC1394_SUCCESS;}/**************************************************** CAPTURE*****************************************************/#define NEXT_BUFFER(c,i) (((i) == -1) ? 0 : ((i)+1)%(c)->num_frames)#define PREV_BUFFER(c,i) (((i) == 0) ? (c)->num_frames-1 : ((i)-1))dc1394error_tdc1394_capture_dma(dc1394camera_t **cameras, uint_t num, dc1394video_policy_t policy) { int i; for (i = 0; i < num; i++) { DC1394_CAST_CAMERA_TO_MACOSX(craw, cameras[i]); dc1394capture_t * capture = &(craw->capture); int next = NEXT_BUFFER (capture, capture->current); buffer_info * buffer = capture->buffers + next; while (buffer->status != BUFFER_FILLED) { SInt32 code; dc1394capture_callback_t callback; if (capture->run_loop != CFRunLoopGetCurrent ()) { fprintf (stderr, "Error: capturing from wrong thread\n"); return DC1394_NO_FRAME; } callback = capture->callback; capture->callback = NULL; if (policy == DC1394_VIDEO1394_POLL) code = CFRunLoopRunInMode (capture->run_loop_mode, 0, true); else code = CFRunLoopRunInMode (capture->run_loop_mode, 5, true); capture->callback = callback; //printf ("capture runloop: %ld\n", code); if (policy == DC1394_VIDEO1394_POLL && code != kCFRunLoopRunHandledSource) return DC1394_NO_FRAME; } } for (i = 0; i < num; i++) { DC1394_CAST_CAMERA_TO_MACOSX(craw, cameras[i]); dc1394capture_t * capture = &(craw->capture); int next = NEXT_BUFFER (capture, capture->current); capture->current = next; /* Catch up to the latest buffer if the application desires it */ if (capture->ring_buffer_policy == DC1394_RING_BUFFER_LAST) { SInt32 code; buffer_info * buffer; next = NEXT_BUFFER (capture, capture->current); buffer = capture->buffers + next; do { while (buffer->status == BUFFER_FILLED) { capture->current = next; next = NEXT_BUFFER (capture, capture->current); buffer = capture->buffers + next; } /* Run the first callback that is pending immediately */ code = CFRunLoopRunInMode (capture->run_loop_mode, 0, true); } while (code == kCFRunLoopRunHandledSource); } } return DC1394_SUCCESS;}dc1394error_t dc1394_capture(dc1394camera_t **cams, uint_t num) { int i; for (i = 0; i < num; i++) { if (dc1394_capture_get_dma_buffer (cams[i])) dc1394_capture_dma_done_with_buffer (cams[i]); } return dc1394_capture_dma (cams, num, DC1394_VIDEO1394_WAIT);}/**************************************************** 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_MACOSX(craw, camera); dc1394capture_t * capture = &(craw->capture); int prev = PREV_BUFFER (capture, capture->current); buffer_info * buffer = capture->buffers + capture->current; buffer_info * prev_buffer = capture->buffers + prev; IOFireWireLibNuDCLPoolRef dcl_pool = capture->dcl_pool; IOFireWireLibLocalIsochPortRef loc_port = capture->loc_port; void * dcl_list[2]; if (capture->current == -1 || buffer->status != BUFFER_FILLED) return DC1394_FAILURE; buffer->status = BUFFER_EMPTY; (*dcl_pool)->SetDCLBranch (buffer->dcl_list[0], buffer->dcl_list[0]); (*dcl_pool)->SetDCLBranch (prev_buffer->dcl_list[0], prev_buffer->dcl_list[1]); dcl_list[0] = prev_buffer->dcl_list[0]; dcl_list[1] = buffer->dcl_list[0]; (*loc_port)->Notify (loc_port, kFWNuDCLModifyJumpNotification, dcl_list, 1); (*loc_port)->Notify (loc_port, kFWNuDCLModifyJumpNotification, dcl_list+1, 1); return DC1394_SUCCESS;}/* functions to access the capture data */uchar_t*dc1394_capture_get_dma_buffer(dc1394camera_t *camera){ DC1394_CAST_CAMERA_TO_MACOSX(craw, camera); dc1394capture_t * capture = &(craw->capture); buffer_info * buffer = capture->buffers + capture->current; IOVirtualRange * databuf = &(capture->databuf); if (capture->current == -1 || buffer->status != BUFFER_FILLED) return NULL; return (uchar_t *) (databuf->address + buffer->i * capture->frame_pages * getpagesize() + getpagesize());}struct timeval*dc1394_capture_get_dma_filltime(dc1394camera_t *camera){ DC1394_CAST_CAMERA_TO_MACOSX(craw, camera); dc1394capture_t * capture = &(craw->capture); buffer_info * buffer = capture->buffers + capture->current; return &buffer->filltime;}intdc1394_capture_schedule_with_runloop (dc1394camera_t * camera, CFRunLoopRef run_loop, CFStringRef run_loop_mode){ DC1394_CAST_CAMERA_TO_MACOSX(craw, camera); dc1394capture_t * capture = &(craw->capture); if (camera->capture_is_set) { fprintf (stderr, "Warning: schedule_with_runloop must be called before setup_dma\n"); return -1; } capture->run_loop = run_loop; capture->run_loop_mode = run_loop_mode; return 0;}voiddc1394_capture_set_callback (dc1394camera_t * camera, dc1394capture_callback_t callback, void * user_data){ DC1394_CAST_CAMERA_TO_MACOSX(craw, camera); dc1394capture_t * capture = &(craw->capture); capture->callback = callback; capture->callback_user_data = user_data;}uint_tdc1394_capture_get_width(dc1394camera_t *camera){ DC1394_CAST_CAMERA_TO_MACOSX(craw, camera); return craw->capture.frame_width;}uint_tdc1394_capture_get_height(dc1394camera_t *camera){ DC1394_CAST_CAMERA_TO_MACOSX(craw, camera); return craw->capture.frame_height;}uint_tdc1394_capture_get_bytes_per_frame(dc1394camera_t *camera){ DC1394_CAST_CAMERA_TO_MACOSX(craw, camera); return craw->capture.quadlets_per_frame*4;}uint_tdc1394_capture_get_frames_behind(dc1394camera_t *camera){ //DC1394_CAST_CAMERA_TO_MACOSX(craw, camera); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -