Exemple #1
0
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));
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
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));
}
Exemple #9
0
/*
  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;
}