static gboolean gst_hdv1394src_stop (GstBaseSrc * bsrc) { GstHDV1394Src *src = GST_HDV1394SRC (bsrc); close (READ_SOCKET (src)); close (WRITE_SOCKET (src)); READ_SOCKET (src) = -1; WRITE_SOCKET (src) = -1; iec61883_mpeg2_close (src->iec61883mpeg2); #if 0 raw1394_stop_iso_rcv (src->handle, src->channel); #endif if (src->use_avc) { raw1394handle_t avc_handle = raw1394_new_handle_on_port (src->port); /* pause and stop the VCR */ if (avc_handle) { if (!avc1394_vcr_is_recording (avc_handle, src->avc_node) && (avc1394_vcr_is_playing (avc_handle, src->avc_node) != AVC1394_VCR_OPERAND_PLAY_FORWARD_PAUSE)) avc1394_vcr_pause (avc_handle, src->avc_node); avc1394_vcr_stop (avc_handle, src->avc_node); raw1394_destroy_handle (avc_handle); } else { GST_WARNING_OBJECT (src, "Starting VCR via avc1394 failed: %s", g_strerror (errno)); } } raw1394_destroy_handle (src->handle); return TRUE; }
int main(int argc, char **argv) { /* Command line parsing */ int opt; unsigned port = 0; unsigned step = 128; enum { INVALID, PEEK, POKE, SCREEN } mode = INVALID; const char *name = strippath(argv[0]); if (strcmp(name, "fw_peek") == 0) { mode = PEEK; } else if (strcmp(name, "fw_poke") == 0) { mode = POKE; #ifndef NO_FW_SCREEN } else if (strcmp(name, "fw_screen") == 0) { mode = SCREEN; #endif } if (mode == INVALID) { fprintf(stderr, "Could not decide, whether we are fw_peek or fw_poke.\n"); return EXIT_FAILURE; } while ((opt = getopt(argc, argv, "p:b:")) != -1) { switch (opt) { case 'p': port = strtoul(optarg, 0, 0); break; case 'b': step = strtoul(optarg, 0, 0); break; default: goto print_usage; } } if (((mode == PEEK) && (argc - optind) != 3) || ((mode == POKE) && (argc - optind) != 2) || ((mode == SCREEN) && (argc - optind) != 5)) { print_usage: fprintf(stderr, (mode == PEEK) ? usage_peek : (mode == POKE) ? usage_poke : usage_screen, name); return EXIT_FAILURE; } uint64_t guid = strtoull(argv[optind], NULL, 0); uint64_t address = strtoull(argv[optind + 1], NULL, 0); uint64_t length; uint32_t width, height, depth; if (mode == PEEK) length = strtoull(argv[optind + 2], NULL, 0); if (mode == SCREEN) { width = strtoul(argv[optind + 2], NULL, 0); height = strtoul(argv[optind + 3], NULL, 0); depth = strtoul(argv[optind + 4], NULL, 0); length = 1ULL * depth / 8 * width * height; } raw1394handle_t fw_handle = raw1394_new_handle_on_port(port); if (fw_handle == NULL) { perror("raw1394_new_handle_on_port"); return EXIT_FAILURE; } nodeid_t target; // 63 is broadcast. Ignore that. if (guid < 63) { // GUID is actually a node number. target = LOCAL_BUS | (nodeid_t)guid; } else { for (unsigned no = 0; no < 63; no++) { nodeid_t test_node = LOCAL_BUS | (nodeid_t)no; uint32_t guid_hi; uint32_t guid_lo; int res = raw1394_read(fw_handle, test_node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 4*4, 4, &guid_lo); if (res != 0) { perror("read guid_lo"); return -1; } res = raw1394_read(fw_handle, test_node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 3*4, 4, &guid_hi); if (res != 0) { perror("read guid_hi"); return -1; } uint64_t test_guid = (uint64_t)ntohl(guid_hi) << 32 | ntohl(guid_lo); if (test_guid == guid) { target = test_node; goto target_found; } } return -1; target_found: ; } quadlet_t buf[step/sizeof(quadlet_t)]; switch (mode) { case SCREEN: #ifndef NO_FW_SCREEN { if (SDL_Init(SDL_INIT_VIDEO) < 0) { perror("init sdl"); return -1; } SDL_Surface *screen = SDL_SetVideoMode(width, height, depth, SDL_SWSURFACE); if (!screen) { perror("sdl video mode"); return -1; } while (true) { quadlet_t * buf = reinterpret_cast<quadlet_t *>(screen->pixels); for (uint64_t cur = address; cur < address+length; cur += step, buf += step/sizeof(quadlet_t)) { size_t size = (cur + step > address+length) ? (address+length - cur) : step; int res = raw1394_read(fw_handle, target, cur, size, buf); if (res != 0) { perror("read data"); return EXIT_FAILURE; } } SDL_UpdateRect(screen, 0, 0, width, height); SDL_Delay(500); SDL_Event event; if (SDL_PollEvent(&event)) if (event.type == SDL_QUIT) exit(1); } } break; #else abort(); #endif // NO_FW_SCREEN case PEEK: for (uint64_t cur = address; cur < address+length; cur += step) { size_t size = (cur + step > address+length) ? (address+length - cur) : step; int tries = 5; again: int res = raw1394_read(fw_handle, target, cur, size, buf); if (res != 0) { if (tries-- > 0) goto again; perror("read data"); return EXIT_FAILURE; } if (write(STDOUT_FILENO, buf, size) < 0) { perror("write"); return EXIT_FAILURE; } } break; case POKE: for (uint64_t cur = address;;cur += step) { ssize_t size = read(STDIN_FILENO, buf, step); if (size == 0) break; if (size < 0) { perror("read"); return EXIT_FAILURE; } int res = raw1394_write(fw_handle, target, cur, size, buf); if (res != 0) { perror("write data"); return EXIT_FAILURE; } if (size < step) break; } } return 0; }
int main(int argc, char **argv) { /* Command line parsing */ int opt; unsigned port = 0; unsigned step = 128; enum { INVALID, PEEK, POKE } mode = INVALID; const char *name = strippath(argv[0]); if (strcmp(name, "fw_peek") == 0) { mode = PEEK; } else if (strcmp(name, "fw_poke") == 0) { mode = POKE; } if (mode == INVALID) { fprintf(stderr, "Could not decide, whether we are fw_peek or fw_poke.\n"); return EXIT_FAILURE; } while ((opt = getopt(argc, argv, "p:b:")) != -1) { switch (opt) { case 'p': port = strtoul(optarg, 0, 0); break; case 'b': step = strtoul(optarg, 0, 0); break; default: goto print_usage; } } if (((mode == PEEK) && (argc - optind) != 3) || ((mode == POKE) && (argc - optind) != 2)) { print_usage: fprintf(stderr, (mode == PEEK) ? usage_peek : usage_poke, name); return EXIT_FAILURE; } uint64_t guid = strtoull(argv[optind], NULL, 0); uint64_t address = strtoull(argv[optind + 1], NULL, 0); uint64_t length; if (mode == PEEK) length = strtoull(argv[optind + 2], NULL, 0); raw1394handle_t fw_handle = raw1394_new_handle_on_port(port); if (fw_handle == NULL) { perror("raw1394_new_handle_on_port"); return EXIT_FAILURE; } nodeid_t target; // 63 is broadcast. Ignore that. if (guid < 63) { // GUID is actually a node number. target = LOCAL_BUS | (nodeid_t)guid; } else { for (unsigned no = 0; no < 63; no++) { nodeid_t test_node = LOCAL_BUS | (nodeid_t)no; uint32_t guid_hi; uint32_t guid_lo; int res = raw1394_read(fw_handle, test_node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 4*4, 4, &guid_lo); if (res != 0) { perror("read guid_lo"); return -1; } res = raw1394_read(fw_handle, test_node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 3*4, 4, &guid_hi); if (res != 0) { perror("read guid_hi"); return -1; } uint64_t test_guid = (uint64_t)ntohl(guid_hi) << 32 | ntohl(guid_lo); if (test_guid == guid) { target = test_node; goto target_found; } } return -1; target_found: ; } quadlet_t buf[step/sizeof(quadlet_t)]; switch (mode) { case PEEK: for (uint64_t cur = address; cur < address+length; cur += step) { size_t size = (cur + step > address+length) ? (address+length - cur) : step; int tries = 5; again: int res = raw1394_read(fw_handle, target, cur, size, buf); if (res != 0) { if (tries-- > 0) goto again; perror("read data"); return EXIT_FAILURE; } if (write(STDOUT_FILENO, buf, size) < 0) { perror("write"); return EXIT_FAILURE; } } break; case POKE: for (uint64_t cur = address;;cur += step) { ssize_t size = read(STDIN_FILENO, buf, step); if (size == 0) break; if (size < 0) { perror("read"); return EXIT_FAILURE; } int res = raw1394_write(fw_handle, target, cur, size, buf); if (res != 0) { perror("write data"); return EXIT_FAILURE; } if (size < step) break; } } return 0; }
static gboolean gst_hdv1394src_start (GstBaseSrc * bsrc) { GstHDV1394Src *src = GST_HDV1394SRC (bsrc); int control_sock[2]; src->connected = FALSE; if (socketpair (PF_UNIX, SOCK_STREAM, 0, control_sock) < 0) goto socket_pair; READ_SOCKET (src) = control_sock[0]; WRITE_SOCKET (src) = control_sock[1]; if (fcntl (READ_SOCKET (src), F_SETFL, O_NONBLOCK) < 0) GST_ERROR_OBJECT (src, "failed to make read socket non-blocking: %s", g_strerror (errno)); if (fcntl (WRITE_SOCKET (src), F_SETFL, O_NONBLOCK) < 0) GST_ERROR_OBJECT (src, "failed to make write socket non-blocking: %s", g_strerror (errno)); src->handle = raw1394_new_handle (); if (!src->handle) { if (errno == EACCES) goto permission_denied; else if (errno == ENOENT) goto not_found; else goto no_handle; } src->num_ports = raw1394_get_port_info (src->handle, src->pinfo, 16); if (src->num_ports == 0) goto no_ports; if (src->use_avc || src->port == -1) src->avc_node = gst_hdv1394src_discover_avc_node (src); /* lets destroy handle and create one on port this is more reliable than setting port on the existing handle */ raw1394_destroy_handle (src->handle); src->handle = raw1394_new_handle_on_port (src->port); if (!src->handle) goto cannot_set_port; raw1394_set_userdata (src->handle, src); raw1394_set_bus_reset_handler (src->handle, gst_hdv1394src_bus_reset); { nodeid_t m_node = (src->avc_node | 0xffc0); int m_channel = -1; int m_bandwidth = 0; int m_outputPort = -1; int m_inputPort = -1; m_channel = iec61883_cmp_connect (src->handle, m_node, &m_outputPort, raw1394_get_local_id (src->handle), &m_inputPort, &m_bandwidth); if (m_channel >= 0) { src->channel = m_channel; } } if ((src->iec61883mpeg2 = iec61883_mpeg2_recv_init (src->handle, gst_hdv1394src_iec61883_receive, src)) == NULL) goto cannot_initialise_dv; #if 0 raw1394_set_iso_handler (src->handle, src->channel, gst_hdv1394src_iso_receive); #endif GST_DEBUG_OBJECT (src, "successfully opened up 1394 connection"); src->connected = TRUE; if (iec61883_mpeg2_recv_start (src->iec61883mpeg2, src->channel) != 0) goto cannot_start; #if 0 if (raw1394_start_iso_rcv (src->handle, src->channel) < 0) goto cannot_start; #endif if (src->use_avc) { raw1394handle_t avc_handle = raw1394_new_handle_on_port (src->port); GST_LOG ("We have an avc_handle"); /* start the VCR */ if (avc_handle) { if (!avc1394_vcr_is_recording (avc_handle, src->avc_node) && avc1394_vcr_is_playing (avc_handle, src->avc_node) != AVC1394_VCR_OPERAND_PLAY_FORWARD) { GST_LOG ("Calling avc1394_vcr_play()"); avc1394_vcr_play (avc_handle, src->avc_node); } raw1394_destroy_handle (avc_handle); } else { GST_WARNING_OBJECT (src, "Starting VCR via avc1394 failed: %s", g_strerror (errno)); } } return TRUE; socket_pair: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL), GST_ERROR_SYSTEM); return FALSE; } permission_denied: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM); return FALSE; } not_found: { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), GST_ERROR_SYSTEM); return FALSE; } no_handle: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("can't get raw1394 handle (%s)", g_strerror (errno))); return FALSE; } no_ports: { raw1394_destroy_handle (src->handle); src->handle = NULL; GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), ("no ports available for raw1394")); return FALSE; } cannot_set_port: { GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL), ("can't set 1394 port %d", src->port)); return FALSE; } cannot_start: { raw1394_destroy_handle (src->handle); src->handle = NULL; iec61883_mpeg2_close (src->iec61883mpeg2); src->iec61883mpeg2 = NULL; GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("can't start 1394 iso receive")); return FALSE; } cannot_initialise_dv: { raw1394_destroy_handle (src->handle); src->handle = NULL; GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("can't initialise iec61883 hdv")); return FALSE; } }
int cpi_enumerate_devices( unicap_device_t *device, int index ) { raw1394handle_t raw1394handle; int numcards; struct raw1394_portinfo portinfo[16]; int current_index = 0; int card = 0; /* TRACE( "dcam_enumerate_devices ( i = %d ) \n", index ); */ raw1394handle = raw1394_new_handle(); if( !raw1394handle ) { if( !errno ) { TRACE( "dcam: no kernel support\n" ); return STATUS_NO_DEVICE; } else { TRACE( "dcam: can' t get handle\n" ); return STATUS_NO_DEVICE; } } numcards = raw1394_get_port_info( raw1394handle, portinfo, 16 ); if( !numcards ) { TRACE( "dcam: no 1394 cards!\n" ); raw1394_destroy_handle( raw1394handle ); return STATUS_NO_DEVICE; } else if( numcards < 0 ) { raw1394_destroy_handle( raw1394handle ); return STATUS_NO_DEVICE; } raw1394_destroy_handle( raw1394handle ); // go through all present cards, search for cameras for( card = 0; card < numcards; card++ ) { int nodecount; int node = 0; if( ( raw1394handle = raw1394_new_handle_on_port( card ) ) == 0 ) { return STATUS_NO_DEVICE; } raw1394_set_userdata( raw1394handle, 0 ); TRACE( "dcam: probing card %d\n", card ); nodecount = raw1394_get_nodecount( raw1394handle ); for( node = 0; node < nodecount; node++ ) { int unit_directory_count; int directory; TRACE( "dcam: probing node %d\n", node ); // shortcut since most devices only have 1 unit directory if( _dcam_is_compatible( raw1394handle, node, 0 ) ) { if( index == current_index ) { unicap_status_t status; status = _dcam_get_device_info( raw1394handle, node, 0, device ); if( status == STATUS_SUCCESS ) { TRACE( "found dcam\n" ); // got the device with the index we want raw1394_destroy_handle( raw1394handle ); return status; } else { TRACE( "can not get device info!\n" ); } } current_index++; continue; } unit_directory_count = _dcam_get_directory_count( raw1394handle, node ); if( unit_directory_count <= 1 ) { TRACE( "directory count <= 1 for node: %d\n", node ); continue; // try next device } // scan through all directories of this device for( directory = 1; directory < unit_directory_count; directory++ ) { if( _dcam_is_compatible( raw1394handle, node, directory ) ) { if( index == current_index ) { unicap_status_t status; status = _dcam_get_device_info( raw1394handle, node, directory, device ); if( status == STATUS_SUCCESS ) { // got the device with the index we want raw1394_destroy_handle( raw1394handle ); return status; } } current_index++; } }// for( directory.. }// for( node.. raw1394_destroy_handle( raw1394handle ); }// for( card.. return STATUS_NO_DEVICE; }