コード例 #1
0
static void vpeirq (unsigned long data)
{
        struct budget *budget = (struct budget*) data;
        u8 *mem = (u8 *)(budget->grabbing);
        u32 olddma = budget->ttbp;
        u32 newdma = saa7146_read(budget->dev, PCI_VDP3);

        /* nearest lower position divisible by 188 */
        newdma -= newdma % 188;

        if (newdma >= TS_BUFLEN)
                return;

	budget->ttbp = newdma;
	
	if(budget->feeding == 0 || newdma == olddma)
		return;

        if (newdma > olddma) { /* no wraparound, dump olddma..newdma */
                        dvb_dmx_swfilter_packets(&budget->demux, 
        	                mem+olddma, (newdma-olddma) / 188);
        } else { /* wraparound, dump olddma..buflen and 0..newdma */
	                dvb_dmx_swfilter_packets(&budget->demux,
        	                mem+olddma, (TS_BUFLEN-olddma) / 188);
                        dvb_dmx_swfilter_packets(&budget->demux,
                                mem, newdma / 188);
        }
}
コード例 #2
0
ファイル: au0828-dvb.c プロジェクト: maraz/linux-2.6
/*-------------------------------------------------------------------*/
static void urb_completion(struct urb *purb)
{
	u8 *ptr;
	struct au0828_dev *dev = purb->context;
	int ptype = usb_pipetype(purb->pipe);

	dprintk(2, "%s()\n", __func__);

	if (!dev)
		return;

	if (dev->urb_streaming == 0)
		return;

	if (ptype != PIPE_BULK) {
		printk(KERN_ERR "%s() Unsupported URB type %d\n",
		       __func__, ptype);
		return;
	}

	ptr = (u8 *)purb->transfer_buffer;

	/* Feed the transport payload into the kernel demux */
	dvb_dmx_swfilter_packets(&dev->dvb.demux,
		purb->transfer_buffer, purb->actual_length / 188);

	/* Clean the buffer before we requeue */
	memset(purb->transfer_buffer, 0, URB_BUFSIZE);

	/* Requeue URB */
	usb_submit_urb(purb, GFP_ATOMIC);
}
コード例 #3
0
ファイル: budget-core.c プロジェクト: 03199618/linux
static void vpeirq(unsigned long data)
{
	struct budget *budget = (struct budget *) data;
	u8 *mem = (u8 *) (budget->grabbing);
	u32 olddma = budget->ttbp;
	u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
	u32 count;

	/* Ensure streamed PCI data is synced to CPU */
	pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);

	/* nearest lower position divisible by 188 */
	newdma -= newdma % 188;

	if (newdma >= budget->buffer_size)
		return;

	budget->ttbp = newdma;

	if (budget->feeding == 0 || newdma == olddma)
		return;

	if (newdma > olddma) {	/* no wraparound, dump olddma..newdma */
		count = newdma - olddma;
		dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188);
	} else {		/* wraparound, dump olddma..buflen and 0..newdma */
		count = budget->buffer_size - olddma;
		dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188);
		count += newdma;
		dvb_dmx_swfilter_packets(&budget->demux, mem, newdma / 188);
	}

	if (count > budget->buffer_warning_threshold)
		budget->buffer_warnings++;

	if (budget->buffer_warnings && time_after(jiffies, budget->buffer_warning_time)) {
		printk("%s %s: used %d times >80%% of buffer (%u bytes now)\n",
			budget->dev->name, __func__, budget->buffer_warnings, count);
		budget->buffer_warning_time = jiffies + BUFFER_WARNING_WAIT;
		budget->buffer_warnings = 0;
	}
}
コード例 #4
0
static void rawiso_activity_cb(struct hpsb_iso *iso)
{
	struct firedtv *f, *fdtv = NULL;
	unsigned int i, num, packet;
	unsigned char *buf;
	unsigned long flags;
	int count;

	spin_lock_irqsave(&node_list_lock, flags);
	list_for_each_entry(f, &node_list, list)
		if (f->backend_data == iso) {
			fdtv = f;
			break;
		}
	spin_unlock_irqrestore(&node_list_lock, flags);

	packet = iso->first_packet;
	num = hpsb_iso_n_ready(iso);

	if (!fdtv) {
		dev_err(fdtv->device, "received at unknown iso channel\n");
		goto out;
	}

	for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) {
		buf = dma_region_i(&iso->data_buf, unsigned char,
			iso->infos[packet].offset + CIP_HEADER_SIZE);
		count = (iso->infos[packet].len - CIP_HEADER_SIZE) /
			MPEG2_TS_SOURCE_PACKET_SIZE;

		/* ignore empty packet */
		if (iso->infos[packet].len <= CIP_HEADER_SIZE)
			continue;

		while (count--) {
			if (buf[MPEG2_TS_HEADER_SIZE] == 0x47)
				dvb_dmx_swfilter_packets(&fdtv->demux,
						&buf[MPEG2_TS_HEADER_SIZE], 1);
			else
				dev_err(fdtv->device,
					"skipping invalid packet\n");
			buf += MPEG2_TS_SOURCE_PACKET_SIZE;
		}
	}
out:
	hpsb_iso_recv_release_packets(iso, num);
}
コード例 #5
0
ファイル: dvb_demux.c プロジェクト: Audioniek/driver
void demultiplexDvbPackets(struct dvb_demux *demux, const u8 *buf, int count)
{
	int first = 0;
	int next = 0;
	int cnt = 0;
	u16 pid, firstPid;
	struct DeviceContext_s *Context = (struct DeviceContext_s *)demux->priv;
	/* Group the packets by the PIDs and feed them into the kernel demuxer.
	 If there is data for the decoder we will be informed via the callback.
	 After the demuxer finished its work on the packet block that block is
	 fed into the decoder if required.
	 This workaround eliminates the scheduling bug caused by waiting while
	 the demux spin is locked. */
	while (count > 0)
	{
		first = next;
		cnt = 0;
		firstPid = ts_pid(&buf[first]);
		while (count > 0)
		{
			count--;
			next += 188;
			cnt++;
			pid = ts_pid(&buf[next]);
			if ((pid != firstPid) || (cnt > 8))
				break;
		}
		if ((next - first) > 0)
		{
			mutex_lock_interruptible(&Context->injectMutex);
			/* reset the flag (to be set by the callback */
			Context->provideToDecoder = 0;
			dvb_dmx_swfilter_packets(demux, buf + first, cnt);
			if (Context->provideToDecoder)
			{
				/* the demuxer indicated that the packets are for the decoder */
				writeToDecoder(demux, Context->feedPesType, buf + first, next - first);
			}
			mutex_unlock(&Context->injectMutex);
		}
	}
}
コード例 #6
0
ファイル: au0828-dvb.c プロジェクト: AllenDou/linux
/*-------------------------------------------------------------------*/
static void urb_completion(struct urb *purb)
{
	struct au0828_dev *dev = purb->context;
	int ptype = usb_pipetype(purb->pipe);
	unsigned char *ptr;

	dprintk(2, "%s()\n", __func__);

	if (!dev)
		return;

	if (dev->urb_streaming == 0)
		return;

	if (ptype != PIPE_BULK) {
		printk(KERN_ERR "%s() Unsupported URB type %d\n",
		       __func__, ptype);
		return;
	}

	/* See if the stream is corrupted (to work around a hardware
	   bug where the stream gets misaligned */
	ptr = purb->transfer_buffer;
	if (purb->actual_length > 0 && ptr[0] != 0x47) {
		dprintk(1, "Need to restart streaming %02x len=%d!\n",
			ptr[0], purb->actual_length);
		schedule_work(&dev->restart_streaming);
		return;
	}

	/* Feed the transport payload into the kernel demux */
	dvb_dmx_swfilter_packets(&dev->dvb.demux,
		purb->transfer_buffer, purb->actual_length / 188);

	/* Clean the buffer before we requeue */
	memset(purb->transfer_buffer, 0, URB_BUFSIZE);

	/* Requeue URB */
	usb_submit_urb(purb, GFP_ATOMIC);
}
コード例 #7
0
ファイル: flexcop.c プロジェクト: forgivemyheart/linux
void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no)
{
	dvb_dmx_swfilter_packets(&fc->demux, buf, no);
}
コード例 #8
0
void demultiplexDvbPackets(struct dvb_demux* demux, const u8 *buf, int count)
{
      dvb_dmx_swfilter_packets(demux, buf, count);
}
コード例 #9
0
ファイル: vtunerc_ctrldev.c プロジェクト: BackupGGCode/satip
static ssize_t vtunerc_ctrldev_write(struct file *filp, const char *buff,
					size_t len, loff_t *off)
{
	struct vtunerc_ctx *ctx = filp->private_data;
	struct dvb_demux *demux = &ctx->demux;
	int tailsize = len % 188;

	if (ctx->closing)
		return -EINTR;

	if (len < 188) {
		printk(KERN_ERR "vtunerc%d: Data are shorter then TS packet size (188B)\n",
				ctx->idx);
		return -EINVAL;
	}

	len -= tailsize;

	// new buffer need to be allocated ?
	if ((ctx->kernel_buf == NULL) || (len > ctx->kernel_buf_size)) {
		// free old buffer
		if (ctx->kernel_buf) {
			kfree(ctx->kernel_buf);
			ctx->kernel_buf = NULL;
			ctx->kernel_buf_size = 0;
		}
		// allocate a bigger buffer
		ctx->kernel_buf = kmalloc(len, GFP_KERNEL);
		if (!ctx->kernel_buf) {
			printk(KERN_ERR "vtunerc%d: unable to allocate buffer of %Zu bytes\n", ctx->idx, len);
			return -ENOMEM;
		}
		ctx->kernel_buf_size = len;
		printk(KERN_INFO "vtunerc%d: allocated buffer of %Zu bytes\n", ctx->idx, len);
	}

	if (down_interruptible(&ctx->tswrite_sem)) {
		return -ERESTARTSYS;
	}

	if (copy_from_user(ctx->kernel_buf, buff, len)) {
		printk(KERN_ERR "vtunerc%d: userdata passing error\n",
				ctx->idx);
		up(&ctx->tswrite_sem);
		return -EINVAL;
	}

	if (ctx->config->tscheck) {
		int i;

		for (i = 0; i < len; i += 188)
			if (ctx->kernel_buf[i] != 0x47) { /* start of TS packet */
				printk(KERN_ERR "vtunerc%d: Data not start on packet boundary: index=%d data=%02x %02x %02x %02x %02x ...\n",
						ctx->idx, i / 188, ctx->kernel_buf[i], ctx->kernel_buf[i + 1],
						ctx->kernel_buf[i + 2], ctx->kernel_buf[i + 3], ctx->kernel_buf[i + 4]);
				up(&ctx->tswrite_sem);
				return -EINVAL;
			}
	}

	ctx->stat_wr_data += len;
	dvb_dmx_swfilter_packets(demux, ctx->kernel_buf, len / 188);

	up(&ctx->tswrite_sem);

#ifdef CONFIG_PROC_FS
	/* TODO:  analyze injected data for statistics */
#endif

	return len;
}
コード例 #10
0
void SysDVBFeedTSPackets(dvb_t dev, unsigned char *buf, unsigned int len)
{
	DVBDev *p = (DVBDev *)dev;

	dvb_dmx_swfilter_packets(&p->demux_sw, buf, len/188);
}