Blame src/dv.c

Packit 0bbbb1
/*
Packit 0bbbb1
 * libiec61883 - Linux IEEE 1394 streaming media library.
Packit 0bbbb1
 * Copyright (C) 2004 Kristian Hogsberg, Dan Dennedy, and Dan Maas.
Packit 0bbbb1
 * This file written by Dan Dennedy.
Packit 0bbbb1
 *
Packit 0bbbb1
 * This library is free software; you can redistribute it and/or
Packit 0bbbb1
 * modify it under the terms of the GNU Lesser General Public
Packit 0bbbb1
 * License as published by the Free Software Foundation; either
Packit 0bbbb1
 * version 2.1 of the License, or (at your option) any later version.
Packit 0bbbb1
 *
Packit 0bbbb1
 * This library is distributed in the hope that it will be useful,
Packit 0bbbb1
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 0bbbb1
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 0bbbb1
 * Lesser General Public License for more details.
Packit 0bbbb1
 *
Packit 0bbbb1
 * You should have received a copy of the GNU Lesser General Public
Packit 0bbbb1
 * License along with this library; if not, write to the Free Software
Packit 0bbbb1
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit 0bbbb1
 */
Packit 0bbbb1
Packit 0bbbb1
#ifdef HAVE_CONFIG_H
Packit 0bbbb1
#include <config.h>
Packit 0bbbb1
#endif
Packit 0bbbb1
Packit 0bbbb1
#include "iec61883.h"
Packit 0bbbb1
#include "iec61883-private.h"
Packit 0bbbb1
Packit 0bbbb1
#include <stdio.h>
Packit 0bbbb1
#include <errno.h>
Packit 0bbbb1
#include <stdlib.h>
Packit 0bbbb1
#include <netinet/in.h>
Packit 0bbbb1
#include <string.h>
Packit 0bbbb1
#include <assert.h>
Packit 0bbbb1
Packit 0bbbb1
#define DIF_BLOCK_SIZE 480
Packit 0bbbb1
#define DV_CUSTOM_CIP 	/* packetizer and syt generation code from Dan Maas */
Packit 0bbbb1
Packit 0bbbb1
iec61883_dv_t
Packit 0bbbb1
iec61883_dv_xmit_init (raw1394handle_t handle, 
Packit 0bbbb1
		int is_pal,
Packit 0bbbb1
		iec61883_dv_xmit_t get_data,
Packit 0bbbb1
		void *callback_data)
Packit 0bbbb1
{
Packit 0bbbb1
	/* DV is composed of DIF blocks, each 480 bytes */
Packit 0bbbb1
	int dbs = DIF_BLOCK_SIZE / sizeof (quadlet_t);
Packit 0bbbb1
	int fdf = is_pal ? 0x80 : 0x00;
Packit 0bbbb1
	int syt_interval = is_pal ? 300 : 250;
Packit 0bbbb1
	int rate = syt_interval * (is_pal ? 25 : 30000.0/1001.0);
Packit 0bbbb1
	struct iec61883_dv *dv;
Packit 0bbbb1
Packit 0bbbb1
	assert (handle != NULL);
Packit 0bbbb1
	dv = malloc (sizeof (struct iec61883_dv));
Packit 0bbbb1
	if (!dv) {
Packit 0bbbb1
		errno = ENOMEM;
Packit 0bbbb1
		return NULL;
Packit 0bbbb1
	}
Packit 0bbbb1
	
Packit 0bbbb1
	dv->channel = -1;
Packit 0bbbb1
	dv->handle = handle;
Packit 0bbbb1
	dv->put_data = NULL;
Packit 0bbbb1
	dv->get_data = get_data;
Packit 0bbbb1
	dv->callback_data = callback_data;
Packit 0bbbb1
	dv->buffer_packets = 1000;
Packit 0bbbb1
	dv->prebuffer_packets = 1000;
Packit 0bbbb1
	dv->irq_interval = 250;
Packit 0bbbb1
	dv->synch = 0;
Packit 0bbbb1
	dv->speed = RAW1394_ISO_SPEED_100;
Packit 0bbbb1
Packit 0bbbb1
	iec61883_cip_init (&dv->cip, IEC61883_FMT_DV, fdf, rate, dbs, syt_interval);
Packit 0bbbb1
Packit 0bbbb1
	iec61883_cip_set_transmission_mode (&dv->cip, IEC61883_MODE_NON_BLOCKING);
Packit 0bbbb1
Packit 0bbbb1
	raw1394_set_userdata (handle, dv);
Packit 0bbbb1
	
Packit 0bbbb1
	return dv;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
iec61883_dv_t
Packit 0bbbb1
iec61883_dv_recv_init (raw1394handle_t handle, 
Packit 0bbbb1
		iec61883_dv_recv_t put_data,
Packit 0bbbb1
		void *callback_data)
Packit 0bbbb1
{
Packit 0bbbb1
	struct iec61883_dv *dv;
Packit 0bbbb1
Packit 0bbbb1
	assert (handle != NULL);
Packit 0bbbb1
	dv = malloc (sizeof (struct iec61883_dv));
Packit 0bbbb1
	if (!dv) {
Packit 0bbbb1
		errno = ENOMEM;
Packit 0bbbb1
		return NULL;
Packit 0bbbb1
	}
Packit 0bbbb1
	
Packit 0bbbb1
	dv->channel = -1;
Packit 0bbbb1
	dv->handle = handle;
Packit 0bbbb1
	dv->put_data = put_data;
Packit 0bbbb1
	dv->get_data = NULL;
Packit 0bbbb1
	dv->callback_data = callback_data;
Packit 0bbbb1
	dv->buffer_packets = 1000;
Packit 0bbbb1
	dv->irq_interval = 250;
Packit 0bbbb1
	dv->synch = 0;
Packit 0bbbb1
	dv->speed = RAW1394_ISO_SPEED_100;
Packit 0bbbb1
Packit 0bbbb1
	raw1394_set_userdata (handle, dv);
Packit 0bbbb1
	
Packit 0bbbb1
	return dv;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
static enum raw1394_iso_disposition
Packit 0bbbb1
dv_xmit_handler (raw1394handle_t handle,
Packit 0bbbb1
		unsigned char *data, 
Packit 0bbbb1
		unsigned int *len,
Packit 0bbbb1
		unsigned char *tag,
Packit 0bbbb1
		unsigned char *sy,
Packit 0bbbb1
		int cycle,
Packit 0bbbb1
		unsigned int dropped)
Packit 0bbbb1
{
Packit 0bbbb1
	struct iec61883_dv *dv = raw1394_get_userdata (handle);
Packit 0bbbb1
	struct iec61883_packet *packet;
Packit 0bbbb1
	int n_dif_blocks;
Packit 0bbbb1
	int result = RAW1394_ISO_OK;
Packit 0bbbb1
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	packet = (struct iec61883_packet *) data;
Packit 0bbbb1
	n_dif_blocks = iec61883_cip_fill_header (handle, &dv->cip, packet);
Packit 0bbbb1
Packit 0bbbb1
#ifdef DV_CUSTOM_CIP
Packit 0bbbb1
	static const int syt_offset = 3;
Packit 0bbbb1
Packit 0bbbb1
	static int packet_num = 0;
Packit 0bbbb1
	static int cip_accum = 0;
Packit 0bbbb1
	static int continuity_counter = 0;
Packit 0bbbb1
	
Packit 0bbbb1
	unsigned int ts;
Packit 0bbbb1
	int cip_n = 1; /* PAL defaults */
Packit 0bbbb1
	int cip_d = 16;
Packit 0bbbb1
	
Packit 0bbbb1
	if (dv->cip.syt_interval == 250) { /* NTSC */
Packit 0bbbb1
		cip_n = 68;
Packit 0bbbb1
		cip_d = 1068;
Packit 0bbbb1
	}
Packit 0bbbb1
	/* generate syt */
Packit 0bbbb1
	if (packet_num == 0) {
Packit 0bbbb1
		ts = cycle + syt_offset;
Packit 0bbbb1
		if (ts > 8000)
Packit 0bbbb1
			ts -= 8000;
Packit 0bbbb1
		ts = (ts & 0xF) << 12;
Packit 0bbbb1
	} else {
Packit 0bbbb1
		ts = 0xFFFF;
Packit 0bbbb1
	}
Packit 0bbbb1
	packet->syt = htons(ts);
Packit 0bbbb1
	packet->dbc = continuity_counter;
Packit 0bbbb1
	/* num/denom algorithm to determine empty packet rate */
Packit 0bbbb1
	if (cip_accum > (cip_d - cip_n)) {
Packit 0bbbb1
		n_dif_blocks = 0;
Packit 0bbbb1
		cip_accum -= (cip_d - cip_n);
Packit 0bbbb1
	} else {
Packit 0bbbb1
		n_dif_blocks = 1;
Packit 0bbbb1
		cip_accum += cip_n;
Packit 0bbbb1
		continuity_counter++;
Packit 0bbbb1
		if (++packet_num >= dv->cip.syt_interval) {
Packit 0bbbb1
			packet_num = 0;
Packit 0bbbb1
		}
Packit 0bbbb1
	}
Packit 0bbbb1
#endif
Packit 0bbbb1
	
Packit 0bbbb1
	dv->total_dropped += dropped;
Packit 0bbbb1
	
Packit 0bbbb1
	*len = n_dif_blocks * DIF_BLOCK_SIZE + 8;
Packit 0bbbb1
	*tag = IEC61883_TAG_WITH_CIP;
Packit 0bbbb1
	*sy = 0;
Packit 0bbbb1
		 
Packit 0bbbb1
	if (dv->get_data != NULL &&
Packit 0bbbb1
		dv->get_data (packet->data, n_dif_blocks, dropped, dv->callback_data) < 0)
Packit 0bbbb1
			result = RAW1394_ISO_ERROR;
Packit 0bbbb1
Packit 0bbbb1
	return result;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
int
Packit 0bbbb1
iec61883_dv_xmit_start (struct iec61883_dv *dv, int channel)
Packit 0bbbb1
{
Packit 0bbbb1
	int result = 0;
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	unsigned int max_packet_size = iec61883_cip_get_max_packet_size (&dv->cip);
Packit 0bbbb1
	
Packit 0bbbb1
	result = raw1394_iso_xmit_init (dv->handle,
Packit 0bbbb1
		dv_xmit_handler,
Packit 0bbbb1
		dv->buffer_packets,
Packit 0bbbb1
		max_packet_size,
Packit 0bbbb1
		channel,
Packit 0bbbb1
		dv->speed,
Packit 0bbbb1
		dv->irq_interval);
Packit 0bbbb1
Packit 0bbbb1
	if ( result == 0 )
Packit 0bbbb1
	{
Packit 0bbbb1
		dv->total_dropped = 0;
Packit 0bbbb1
		dv->channel = channel;
Packit 0bbbb1
		result = raw1394_iso_xmit_start (dv->handle, -1, dv->prebuffer_packets);
Packit 0bbbb1
	}
Packit 0bbbb1
	
Packit 0bbbb1
	return result;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
static enum raw1394_iso_disposition
Packit 0bbbb1
dv_recv_handler (raw1394handle_t handle, 
Packit 0bbbb1
		unsigned char *data,
Packit 0bbbb1
		unsigned int len, 
Packit 0bbbb1
		unsigned char channel,
Packit 0bbbb1
		unsigned char tag, 
Packit 0bbbb1
		unsigned char sy,
Packit 0bbbb1
		unsigned int cycle, 
Packit 0bbbb1
		unsigned int dropped)
Packit 0bbbb1
{
Packit 0bbbb1
	struct iec61883_dv *dv = raw1394_get_userdata (handle);
Packit 0bbbb1
	enum raw1394_iso_disposition result = RAW1394_ISO_OK;
Packit 0bbbb1
	
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	dv->total_dropped += dropped;
Packit 0bbbb1
	
Packit 0bbbb1
	if (dv->put_data != NULL && /* only if callback registered */
Packit 0bbbb1
		channel == dv->channel &&    /* only for selected channel */
Packit 0bbbb1
		len == DIF_BLOCK_SIZE + 8)   /* not empty packets */
Packit 0bbbb1
	{
Packit 0bbbb1
		if (dv->put_data (data + 8, DIF_BLOCK_SIZE, dropped, dv->callback_data) < 0)
Packit 0bbbb1
			result = RAW1394_ISO_ERROR;
Packit 0bbbb1
	}
Packit 0bbbb1
	if (result == RAW1394_ISO_OK && dropped)
Packit 0bbbb1
		result = RAW1394_ISO_DEFER;
Packit 0bbbb1
			
Packit 0bbbb1
	return result;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
int
Packit 0bbbb1
iec61883_dv_recv_start (struct iec61883_dv *dv, int channel)
Packit 0bbbb1
{
Packit 0bbbb1
	int result = 0;
Packit 0bbbb1
	
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	result = raw1394_iso_recv_init (dv->handle, 
Packit 0bbbb1
		dv_recv_handler,
Packit 0bbbb1
		dv->buffer_packets, 
Packit 0bbbb1
		DIF_BLOCK_SIZE + 8,
Packit 0bbbb1
		channel,
Packit 0bbbb1
		RAW1394_DMA_PACKET_PER_BUFFER,
Packit 0bbbb1
		dv->irq_interval);
Packit 0bbbb1
	
Packit 0bbbb1
	if (result == 0) {
Packit 0bbbb1
		dv->total_dropped = 0;
Packit 0bbbb1
		dv->channel = channel;
Packit 0bbbb1
		result = raw1394_iso_recv_start (dv->handle, -1, -1, 0);
Packit 0bbbb1
	}
Packit 0bbbb1
	return result;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
void
Packit 0bbbb1
iec61883_dv_recv_stop (iec61883_dv_t dv)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	if (dv->synch)
Packit 0bbbb1
		raw1394_iso_recv_flush (dv->handle);
Packit 0bbbb1
	raw1394_iso_shutdown (dv->handle);
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
void
Packit 0bbbb1
iec61883_dv_xmit_stop (iec61883_dv_t dv)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	if (dv->synch)
Packit 0bbbb1
		raw1394_iso_xmit_sync (dv->handle);
Packit 0bbbb1
	raw1394_iso_shutdown (dv->handle);
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
void
Packit 0bbbb1
iec61883_dv_close (iec61883_dv_t dv)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	if (dv->put_data)
Packit 0bbbb1
		iec61883_dv_recv_stop (dv);
Packit 0bbbb1
	if (dv->get_data)
Packit 0bbbb1
		iec61883_dv_xmit_stop (dv);
Packit 0bbbb1
	free (dv);
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
static int
Packit 0bbbb1
dv_fb_recv (unsigned char *data, int len, unsigned int dropped, void *callback_data)
Packit 0bbbb1
{
Packit 0bbbb1
	int result = 0;
Packit 0bbbb1
	if (len != 480) return result;
Packit 0bbbb1
	struct iec61883_dv_fb *fb = (struct iec61883_dv_fb *)callback_data;
Packit 0bbbb1
	int section_type = data[0] >> 5; /* section type is in bits 5 - 7 */
Packit 0bbbb1
	int dif_sequence = data[1] >> 4; /* dif sequence number is in bits 4 - 7 */
Packit 0bbbb1
	int dif_block = data[2];
Packit 0bbbb1
	
Packit 0bbbb1
	assert (fb != NULL);
Packit 0bbbb1
	/* test for start of frame */
Packit 0bbbb1
	if (section_type == 0 && dif_sequence == 0) {
Packit 0bbbb1
		/* if not waiting for the first frame */
Packit 0bbbb1
		if (fb->ff == 0) {
Packit 0bbbb1
			int total = ((fb->data[3] & 0x80) == 0 ? 250 : 300) * 480;
Packit 0bbbb1
			if (fb->len != total)
Packit 0bbbb1
				fb->total_incomplete++;
Packit 0bbbb1
			result = fb->put_data (fb->data, total, fb->len == total, 
Packit 0bbbb1
				fb->callback_data);
Packit 0bbbb1
			fb->len = 0;
Packit 0bbbb1
		} else {
Packit 0bbbb1
			/* no longer waiting for first frame */
Packit 0bbbb1
			fb->ff = 0;
Packit 0bbbb1
		}
Packit 0bbbb1
	} 
Packit 0bbbb1
	/* if not the first frame */
Packit 0bbbb1
	if (fb->ff == 0 && dif_sequence < 12) {
Packit 0bbbb1
		unsigned char *p = fb->data + dif_sequence * 150 * 80;
Packit 0bbbb1
		fb->len += len;
Packit 0bbbb1
		switch ( section_type ) {
Packit 0bbbb1
			case 0:    /* 1 Header block */
Packit 0bbbb1
				memcpy( p, data, len );
Packit 0bbbb1
				break;
Packit 0bbbb1
			case 1:    /* 2 Subcode blocks */
Packit 0bbbb1
				if (dif_block < 2)
Packit 0bbbb1
					memcpy( p + ( 1 + dif_block ) * 80, data, len );
Packit 0bbbb1
				break;
Packit 0bbbb1
			case 2:    /* 3 VAUX blocks */
Packit 0bbbb1
				if (dif_block < 3)
Packit 0bbbb1
					memcpy( p + ( 3 + dif_block ) * 80, data, len );
Packit 0bbbb1
				break;
Packit 0bbbb1
			case 3:    /* 9 Audio blocks interleaved with video */
Packit 0bbbb1
				if (dif_block < 9)
Packit 0bbbb1
					memcpy( p + ( 6 + dif_block * 16 ) * 80, data, len );
Packit 0bbbb1
				break;
Packit 0bbbb1
			case 4:    /* 135 Video blocks interleaved with audio */
Packit 0bbbb1
				if (dif_block < 135)
Packit 0bbbb1
					memcpy( p + ( 7 + ( dif_block / 15 ) + dif_block ) * 80, data, len );
Packit 0bbbb1
				break;
Packit 0bbbb1
			default:
Packit 0bbbb1
				break;
Packit 0bbbb1
		}
Packit 0bbbb1
	}
Packit 0bbbb1
		
Packit 0bbbb1
	return result;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
iec61883_dv_fb_t
Packit 0bbbb1
iec61883_dv_fb_init (raw1394handle_t handle, 
Packit 0bbbb1
		iec61883_dv_fb_recv_t put_data,
Packit 0bbbb1
		void *callback_data)
Packit 0bbbb1
{
Packit 0bbbb1
	struct iec61883_dv_fb *fb;
Packit 0bbbb1
	
Packit 0bbbb1
	fb = malloc (sizeof( struct iec61883_dv_fb));
Packit 0bbbb1
	if (!fb) {
Packit 0bbbb1
		errno = ENOMEM;
Packit 0bbbb1
		return NULL;
Packit 0bbbb1
	}
Packit 0bbbb1
	
Packit 0bbbb1
	memset (fb->data, 0, sizeof (fb->data));
Packit 0bbbb1
	fb->len = 0; /* tracks the bytes collected to determine if frame complete */
Packit 0bbbb1
	fb->ff = 1;  /* indicates waiting for the start of frame */
Packit 0bbbb1
	fb->put_data = put_data;
Packit 0bbbb1
	fb->callback_data = callback_data;
Packit 0bbbb1
	fb->dv = iec61883_dv_recv_init (handle, dv_fb_recv, (void *)fb );
Packit 0bbbb1
	if (!fb->dv) {
Packit 0bbbb1
		free (fb);
Packit 0bbbb1
		return NULL;
Packit 0bbbb1
	}
Packit 0bbbb1
	
Packit 0bbbb1
	return fb;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
iec61883_dv_t
Packit 0bbbb1
iec61883_dv_fb_get_dv(iec61883_dv_fb_t fb)
Packit 0bbbb1
{
Packit 0bbbb1
	return (fb != NULL ) ? fb->dv : NULL;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
int
Packit 0bbbb1
iec61883_dv_fb_start (iec61883_dv_fb_t fb, int channel)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (fb != NULL);
Packit 0bbbb1
	return iec61883_dv_recv_start (fb->dv, channel);
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
void
Packit 0bbbb1
iec61883_dv_fb_stop (iec61883_dv_fb_t fb)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (fb != NULL);
Packit 0bbbb1
	iec61883_dv_recv_stop (fb->dv);
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
void
Packit 0bbbb1
iec61883_dv_fb_close (iec61883_dv_fb_t fb)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (fb != NULL);
Packit 0bbbb1
	iec61883_dv_close (fb->dv);
Packit 0bbbb1
	free (fb);
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
unsigned int
Packit 0bbbb1
iec61883_dv_get_buffers (iec61883_dv_t dv)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	return dv->buffer_packets;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
void
Packit 0bbbb1
iec61883_dv_set_buffers (iec61883_dv_t dv, unsigned int packets)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	dv->buffer_packets = packets;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
unsigned int
Packit 0bbbb1
iec61883_dv_get_prebuffers (iec61883_dv_t dv)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	return dv->prebuffer_packets;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
void
Packit 0bbbb1
iec61883_dv_set_prebuffers (iec61883_dv_t dv, unsigned int packets)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	dv->prebuffer_packets = packets;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
unsigned int
Packit 0bbbb1
iec61883_dv_get_irq_interval (iec61883_dv_t dv)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	return dv->irq_interval;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
void
Packit 0bbbb1
iec61883_dv_set_irq_interval (iec61883_dv_t dv, unsigned int packets)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	dv->irq_interval = packets;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
int
Packit 0bbbb1
iec61883_dv_get_synch (iec61883_dv_t dv)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	return dv->synch;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
void
Packit 0bbbb1
iec61883_dv_set_synch (iec61883_dv_t dv, int synch)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	dv->synch = synch;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
int
Packit 0bbbb1
iec61883_dv_get_speed (iec61883_dv_t dv)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	return dv->speed;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
void
Packit 0bbbb1
iec61883_dv_set_speed (iec61883_dv_t dv, int speed)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	dv->speed = speed;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
unsigned int
Packit 0bbbb1
iec61883_dv_get_dropped (iec61883_dv_t dv)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	return dv->total_dropped;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
void *
Packit 0bbbb1
iec61883_dv_get_callback_data (iec61883_dv_t dv)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (dv != NULL);
Packit 0bbbb1
	return dv->callback_data;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
unsigned int
Packit 0bbbb1
iec61883_dv_fb_get_incomplete (iec61883_dv_fb_t fb)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (fb != NULL);
Packit 0bbbb1
	return fb->total_incomplete;
Packit 0bbbb1
}
Packit 0bbbb1
Packit 0bbbb1
void *
Packit 0bbbb1
iec61883_dv_fb_get_callback_data (iec61883_dv_fb_t fb)
Packit 0bbbb1
{
Packit 0bbbb1
	assert (fb != NULL);
Packit 0bbbb1
	return fb->callback_data;
Packit 0bbbb1
}