static enum raw1394_iso_disposition dv_recv_handler (raw1394handle_t handle, unsigned char *data, unsigned int len, unsigned char channel, unsigned char tag, unsigned char sy, unsigned int cycle, unsigned int dropped) { struct iec61883_dv *dv = raw1394_get_userdata (handle); enum raw1394_iso_disposition result = RAW1394_ISO_OK; assert (dv != NULL); dv->total_dropped += dropped; if (dv->put_data != NULL && /* only if callback registered */ channel == dv->channel && /* only for selected channel */ len == DIF_BLOCK_SIZE + 8) /* not empty packets */ { if (dv->put_data (data + 8, DIF_BLOCK_SIZE, dropped, dv->callback_data) < 0) result = RAW1394_ISO_ERROR; } if (result == RAW1394_ISO_OK && dropped) result = RAW1394_ISO_DEFER; return result; }
static GstDV1394Src * gst_dv1394src_from_raw1394handle (raw1394handle_t handle) { iec61883_dv_t dv = (iec61883_dv_t) raw1394_get_userdata (handle); iec61883_dv_fb_t dv_fb = (iec61883_dv_fb_t) iec61883_dv_get_callback_data (dv); return GST_DV1394SRC (iec61883_dv_fb_get_callback_data (dv_fb)); }
enum raw1394_iso_disposition firewire_source::raw_receive(raw1394handle_t handle, unsigned char * data, unsigned int len, unsigned char /*channel*/, unsigned char /*tag*/, unsigned char /*sy*/, unsigned int /*cycle*/, unsigned int dropped) { firewire_source * source = static_cast<firewire_source *>(raw1394_get_userdata(handle)); source->receive(data, len, dropped); return RAW1394_ISO_OK; }
static enum raw1394_iso_disposition dv_xmit_handler (raw1394handle_t handle, unsigned char *data, unsigned int *len, unsigned char *tag, unsigned char *sy, int cycle, unsigned int dropped) { struct iec61883_dv *dv = raw1394_get_userdata (handle); struct iec61883_packet *packet; int n_dif_blocks; int result = RAW1394_ISO_OK; assert (dv != NULL); packet = (struct iec61883_packet *) data; n_dif_blocks = iec61883_cip_fill_header (handle, &dv->cip, packet); #ifdef DV_CUSTOM_CIP static const int syt_offset = 3; static int packet_num = 0; static int cip_accum = 0; static int continuity_counter = 0; unsigned int ts; int cip_n = 1; /* PAL defaults */ int cip_d = 16; if (dv->cip.syt_interval == 250) { /* NTSC */ cip_n = 68; cip_d = 1068; } /* generate syt */ if (packet_num == 0) { ts = cycle + syt_offset; if (ts > 8000) ts -= 8000; ts = (ts & 0xF) << 12; } else { ts = 0xFFFF; } packet->syt = htons(ts); packet->dbc = continuity_counter; /* num/denom algorithm to determine empty packet rate */ if (cip_accum > (cip_d - cip_n)) { n_dif_blocks = 0; cip_accum -= (cip_d - cip_n); } else { n_dif_blocks = 1; cip_accum += cip_n; continuity_counter++; if (++packet_num >= dv->cip.syt_interval) { packet_num = 0; } } #endif dv->total_dropped += dropped; *len = n_dif_blocks * DIF_BLOCK_SIZE + 8; *tag = IEC61883_TAG_WITH_CIP; *sy = 0; if (dv->get_data != NULL && dv->get_data (packet->data, n_dif_blocks, dropped, dv->callback_data) < 0) result = RAW1394_ISO_ERROR; return result; }
static enum raw1394_iso_disposition Raw1394Handler(raw1394handle_t handle, unsigned char *data, unsigned int length, unsigned char channel, unsigned char tag, unsigned char sy, unsigned int cycle, unsigned int dropped) { access_t *p_access = NULL; access_sys_t *p_sys = NULL; block_t *p_block = NULL; VLC_UNUSED(channel); VLC_UNUSED(tag); VLC_UNUSED(sy); VLC_UNUSED(cycle); VLC_UNUSED(dropped); p_access = (access_t *) raw1394_get_userdata( handle ); if( !p_access ) return 0; p_sys = p_access->p_sys; /* skip empty packets */ if( length > 16 ) { unsigned char * p = data + 8; int section_type = p[ 0 ] >> 5; /* section type is in bits 5 - 7 */ int dif_sequence = p[ 1 ] >> 4; /* dif sequence number is in bits 4 - 7 */ int dif_block = p[ 2 ]; vlc_mutex_lock( &p_sys->p_ev->lock ); /* if we are at the beginning of a frame, we put the previous frame in our output_queue. */ if( (section_type == 0) && (dif_sequence == 0) ) { vlc_mutex_lock( &p_sys->lock ); if( p_sys->p_ev->p_frame ) { /* Push current frame to p_access thread. */ //p_sys->p_ev->p_frame->i_pts = mdate(); block_ChainAppend( &p_sys->p_frame, p_sys->p_ev->p_frame ); } /* reset list */ p_sys->p_ev->p_frame = block_Alloc( 144000 ); p_sys->p_ev->pp_last = &p_sys->p_frame; vlc_mutex_unlock( &p_sys->lock ); } p_block = p_sys->p_ev->p_frame; if( p_block ) { switch ( section_type ) { case 0: /* 1 Header block */ /* p[3] |= 0x80; // hack to force PAL data */ memcpy( p_block->p_buffer + dif_sequence * 150 * 80, p, 480 ); break; case 1: /* 2 Subcode blocks */ memcpy( p_block->p_buffer + dif_sequence * 150 * 80 + ( 1 + dif_block ) * 80, p, 480 ); break; case 2: /* 3 VAUX blocks */ memcpy( p_block->p_buffer + dif_sequence * 150 * 80 + ( 3 + dif_block ) * 80, p, 480 ); break; case 3: /* 9 Audio blocks interleaved with video */ memcpy( p_block->p_buffer + dif_sequence * 150 * 80 + ( 6 + dif_block * 16 ) * 80, p, 480 ); break; case 4: /* 135 Video blocks interleaved with audio */ memcpy( p_block->p_buffer + dif_sequence * 150 * 80 + ( 7 + ( dif_block / 15 ) + dif_block ) * 80, p, 480 ); break; default: /* we can´t handle any other data */ block_Release( p_block ); p_block = NULL; break; } } vlc_mutex_unlock( &p_sys->p_ev->lock ); }
/* initialized when first header received */ dv1394src->frame_size = 0; dv1394src->buf = NULL; dv1394src->frame = NULL; dv1394src->frame_sequence = 0; dv1394src->provided_clock = gst_1394_clock_new ("dv1394clock"); } static void gst_dv1394src_dispose (GObject * object) { GstDV1394Src *src = GST_DV1394SRC (object); if (src->provided_clock) { g_object_unref (src->provided_clock); } g_free (src->uri); src->uri = NULL; g_free (src->device_name); src->device_name = NULL; G_OBJECT_CLASS (parent_class)->dispose (object); } static void gst_dv1394src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstDV1394Src *filter = GST_DV1394SRC (object); switch (prop_id) { case PROP_PORT: filter->port = g_value_get_int (value); g_free (filter->uri); filter->uri = g_strdup_printf ("dv://%d", filter->port); break; case PROP_CHANNEL: filter->channel = g_value_get_int (value); break; case PROP_SKIP: filter->skip = g_value_get_int (value); break; case PROP_CONSECUTIVE: filter->consecutive = g_value_get_int (value); break; case PROP_DROP_INCOMPLETE: filter->drop_incomplete = g_value_get_boolean (value); break; case PROP_USE_AVC: filter->use_avc = g_value_get_boolean (value); break; case PROP_GUID: filter->guid = g_value_get_uint64 (value); gst_dv1394src_update_device_name (filter); break; default: break; } } static void gst_dv1394src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstDV1394Src *filter = GST_DV1394SRC (object); switch (prop_id) { case PROP_PORT: g_value_set_int (value, filter->port); break; case PROP_CHANNEL: g_value_set_int (value, filter->channel); break; case PROP_SKIP: g_value_set_int (value, filter->skip); break; case PROP_CONSECUTIVE: g_value_set_int (value, filter->consecutive); break; case PROP_DROP_INCOMPLETE: g_value_set_boolean (value, filter->drop_incomplete); break; case PROP_USE_AVC: g_value_set_boolean (value, filter->use_avc); break; case PROP_GUID: g_value_set_uint64 (value, filter->guid); break; case PROP_DEVICE_NAME: g_value_set_string (value, filter->device_name); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static GstClock * gst_dv1394src_provide_clock (GstElement * element) { GstDV1394Src *dv1394src = GST_DV1394SRC (element); return GST_CLOCK_CAST (gst_object_ref (dv1394src->provided_clock)); } static GstStateChangeReturn gst_dv1394_src_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; GstDV1394Src *src = GST_DV1394SRC (element); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: gst_element_post_message (element, gst_message_new_clock_lost (GST_OBJECT_CAST (element), GST_CLOCK_CAST (src->provided_clock))); break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); if (ret == GST_STATE_CHANGE_FAILURE) return ret; switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_PLAYING: gst_element_post_message (element, gst_message_new_clock_provide (GST_OBJECT_CAST (element), GST_CLOCK_CAST (src->provided_clock), TRUE)); break; default: break; } return ret; } #ifdef HAVE_LIBIEC61883 static GstDV1394Src * gst_dv1394src_from_raw1394handle (raw1394handle_t handle) { iec61883_dv_t dv = (iec61883_dv_t) raw1394_get_userdata (handle); iec61883_dv_fb_t dv_fb = (iec61883_dv_fb_t) iec61883_dv_get_callback_data (dv); return GST_DV1394SRC (iec61883_dv_fb_get_callback_data (dv_fb)); } #else /* HAVE_LIBIEC61883 */ static GstDV1394Src * gst_dv1394src_from_raw1394handle (raw1394handle_t handle) { return GST_DV1394SRC (raw1394_get_userdata (handle)); }
/* bus reset handler checks if device is still on the bus. if it is removed -> set device_present to 0 . bandwidth and channel are remotely freed on bus reset if device still present -> reallocate bw and channel -> channel is not guarranted to be the same after reallocation -> set new channel to camera if changed */ int dcam_busreset_handler( raw1394handle_t raw1394handle, unsigned int generation ) { dcam_handle_t dcamhandle = ( dcam_handle_t ) raw1394_get_userdata( raw1394handle ); int port; int channel; raw1394_update_generation( raw1394handle, generation ); // check if the device is still there or if it has changed if( _dcam_find_device( &dcamhandle->unicap_device, &port, &dcamhandle->node, &dcamhandle->directory ) != STATUS_SUCCESS ) { dcamhandle->device_present = 0; dcam_device_removed_event( dcamhandle ); return 0; } // what happens if a PC-Card is removed ? does this change the port??? if( port != dcamhandle->port ) { if( raw1394_set_port( raw1394handle, port ) < 0 ) { dcamhandle->device_present = 0; dcam_device_removed_event( dcamhandle ); return 0; } dcamhandle->port = port; } // reallocate bandwidth // ( reallocation should always succeed ) if( dcamhandle->allocate_bandwidth ) { if( !SUCCESS(_1394util_allocate_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ) ) ) { TRACE( "dcam.cpi: failed to reallocate bandwidth\n" ); dcam_capture_stop( dcamhandle ); return 0; } } // channel is freed on busreset // -> reallocate channel // check if newly allocated channel matches previous channel // -> conditionaly set new channel on the camera if( !SUCCESS(_1394util_allocate_channel(dcamhandle->raw1394handle, dcamhandle->channel_allocated ) ) ) { if( ( channel = _1394util_find_free_channel( dcamhandle->raw1394handle ) ) < 0 ) { TRACE( "dcam.cpi: failed to allocate channel\n"); _1394util_free_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ); dcam_capture_stop( dcamhandle ); return 0; } if( channel != dcamhandle->channel_allocated ) { quadlet_t quad = 0; if( dcam_isoch_table[dcamhandle->current_iso_index].min_speed <= S400 ) { quad = ( channel << 28 ) | ( S400 << 24 ); } else { quad = ( channel << 28 ) | ( dcam_isoch_table[dcamhandle->current_iso_index].min_speed << 24 ); } if( _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x60c, quad ) < 0 ) { _1394util_free_channel( dcamhandle->raw1394handle, channel ); _1394util_free_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ); return 0; } } } return 0; }
static GstHDV1394Src * gst_hdv1394src_from_raw1394handle (raw1394handle_t handle) { iec61883_mpeg2_t mpeg2 = (iec61883_mpeg2_t) raw1394_get_userdata (handle); return GST_HDV1394SRC (iec61883_mpeg2_get_callback_data (mpeg2)); }
/* handler for raw1394 isoch reception sequence: - get buffer from input queue - start on sy == 1 to fill buffer - fill buffer until dcamhandle->buffer_size is reached - put buffer into output queue */ enum raw1394_iso_disposition dcam_iso_handler( raw1394handle_t raw1394handle, unsigned char * data, unsigned int len, unsigned char channel, unsigned char tag, unsigned char sy, unsigned int cycle, unsigned int dropped ) { dcam_handle_t dcamhandle = raw1394_get_userdata( raw1394handle ); if( !len ) { return 0; } /* TRACE( "len: %d, sy: %d, cycle: %d, dropped: %d,current_offset: %d, buffer_size: %d\n", */ /* len, */ /* sy, */ /* cycle, */ /* dropped, */ /* dcamhandle->current_buffer_offset, */ /* dcamhandle->buffer_size); */ if( dcamhandle->wait_for_sy ) { if( !sy ) { return 0; } dcamhandle->current_buffer_offset = 0; dcamhandle->current_buffer = ucutil_get_front_queue( &dcamhandle->input_queue ); if( !dcamhandle->current_buffer ) { return 0; } dcamhandle->wait_for_sy = 0; /* gettimeofday( &dcamhandle->current_buffer->fill_start_time, NULL ); */ } if( (dcamhandle->current_buffer_offset + len) > dcamhandle->buffer_size ) { TRACE( "dcam.cpi: (isoch handler) got more data than allowed\n" ); return 0; } memcpy( dcamhandle->current_buffer->data + dcamhandle->current_buffer_offset, data, len ); dcamhandle->current_buffer_offset += len; if( dcamhandle->current_buffer_offset == dcamhandle->buffer_size ) { /* gettimeofday( &dcamhandle->current_buffer->fill_end_time, NULL ); */ ucutil_insert_back_queue( &dcamhandle->output_queue, dcamhandle->current_buffer ); /* new_frame_event( dcamhandle, dcamhandle->current_buffer ); */ dcamhandle->current_buffer = 0; dcamhandle->wait_for_sy = 1; } return 0; }