예제 #1
0
파일: dmxdev.c 프로젝트: 274914765/C
static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src,
                      int non_blocking, char __user *buf,
                      size_t count, loff_t *ppos)
{
    size_t todo;
    ssize_t avail;
    ssize_t ret = 0;

    if (!src->data)
        return 0;

    if (src->error) {
        ret = src->error;
        dvb_ringbuffer_flush(src);
        return ret;
    }

    for (todo = count; todo > 0; todo -= ret) {
        if (non_blocking && dvb_ringbuffer_empty(src)) {
            ret = -EWOULDBLOCK;
            break;
        }

        ret = wait_event_interruptible(src->queue,
                           !dvb_ringbuffer_empty(src) ||
                           (src->error != 0));
        if (ret < 0)
            break;

        if (src->error) {
            ret = src->error;
            dvb_ringbuffer_flush(src);
            break;
        }

        avail = dvb_ringbuffer_avail(src);
        if (avail > todo)
            avail = todo;

        ret = dvb_ringbuffer_read(src, (u8 *)buf, avail, 1);
        if (ret < 0)
            break;

        buf += ret;
    }

    return (count - todo) ? (count - todo) : ret;
}
예제 #2
0
파일: dmxdev.c 프로젝트: 274914765/C
static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
{
    if (dmxdevfilter->state < DMXDEV_STATE_GO)
        return 0;

    switch (dmxdevfilter->type) {
    case DMXDEV_TYPE_SEC:
        if (!dmxdevfilter->feed.sec)
            break;
        dvb_dmxdev_feed_stop(dmxdevfilter);
        if (dmxdevfilter->filter.sec)
            dmxdevfilter->feed.sec->
                release_filter(dmxdevfilter->feed.sec,
                       dmxdevfilter->filter.sec);
        dvb_dmxdev_feed_restart(dmxdevfilter);
        dmxdevfilter->feed.sec = NULL;
        break;
    case DMXDEV_TYPE_PES:
        if (!dmxdevfilter->feed.ts)
            break;
        dvb_dmxdev_feed_stop(dmxdevfilter);
        dmxdevfilter->dev->demux->
            release_ts_feed(dmxdevfilter->dev->demux,
                    dmxdevfilter->feed.ts);
        dmxdevfilter->feed.ts = NULL;
        break;
    default:
        if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED)
            return 0;
        return -EINVAL;
    }

    dvb_ringbuffer_flush(&dmxdevfilter->buffer);
    return 0;
}
예제 #3
0
static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
				  const u8 *buffer2, size_t buffer2_len,
				  struct dmx_ts_feed *feed,
				  enum dmx_success success)
{
	struct dmxdev_filter *dmxdevfilter = feed->priv;
	struct dvb_ringbuffer *buffer;
	int ret;

	spin_lock(&dmxdevfilter->dev->lock);
	if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
		spin_unlock(&dmxdevfilter->dev->lock);
		return 0;
	}

	if (dmxdevfilter->params.pes.output == DMX_OUT_TAP)
		buffer = &dmxdevfilter->buffer;
	else
		buffer = &dmxdevfilter->dev->dvr_buffer;
	if (buffer->error) {
		spin_unlock(&dmxdevfilter->dev->lock);
		wake_up(&buffer->queue);
		return 0;
	}
	ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
	if (ret == buffer1_len)
		ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
	if (ret < 0) {
		dvb_ringbuffer_flush(buffer);
		buffer->error = ret;
	}
	spin_unlock(&dmxdevfilter->dev->lock);
	wake_up(&buffer->queue);
	return 0;
}
예제 #4
0
static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,
				      unsigned long size)
{
	struct dvb_ringbuffer *buf = &dmxdevfilter->buffer;
	void *mem;

	if (buf->size == size)
		return 0;
	if (dmxdevfilter->state >= DMXDEV_STATE_GO)
		return -EBUSY;
	spin_lock_irq(&dmxdevfilter->dev->lock);
	mem = buf->data;
	buf->data = NULL;
	buf->size = size;
	dvb_ringbuffer_flush(buf);
	spin_unlock_irq(&dmxdevfilter->dev->lock);
	vfree(mem);

	if (buf->size) {
		mem = vmalloc(dmxdevfilter->buffer.size);
		if (!mem)
			return -ENOMEM;
		spin_lock_irq(&dmxdevfilter->dev->lock);
		buf->data = mem;
		spin_unlock_irq(&dmxdevfilter->dev->lock);
	}
	return 0;
}
예제 #5
0
void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
{
	unsigned long flags;

	spin_lock_irqsave(&rbuf->lock, flags);
	dvb_ringbuffer_flush(rbuf);
	spin_unlock_irqrestore(&rbuf->lock, flags);

	wake_up(&rbuf->queue);
}
예제 #6
0
파일: ngene-av.c 프로젝트: mona66/sifbox
static int audio_open(struct inode *inode, struct file *file)
{
	struct dvb_device *dvbdev = file->private_data;
	struct ngene_channel *chan = dvbdev->priv;
	struct ngene *dev = chan->dev;
	struct ngene_channel *chan2 = &chan->dev->channel[2];
	int ret;

	ret = dvb_generic_open(inode, file);
	if (ret < 0)
		return ret;
	dvb_ringbuffer_flush(&dev->ain_rbuf);

	chan2->Capture1Length = MAX_AUDIO_BUFFER_SIZE;
	chan2->pBufferExchange = ain_exchange;
	ngene_command_stream_control(chan2->dev, chan2->number, 0x80,
				     SMODE_AUDIO_CAPTURE, 0);
	return ret;
}
예제 #7
0
파일: dmxdev.c 프로젝트: 274914765/C
static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
                       const u8 *buffer2, size_t buffer2_len,
                       struct dmx_section_filter *filter,
                       enum dmx_success success)
{
    struct dmxdev_filter *dmxdevfilter = filter->priv;
    int ret;

    if (dmxdevfilter->buffer.error) {
        wake_up(&dmxdevfilter->buffer.queue);
        return 0;
    }
    spin_lock(&dmxdevfilter->dev->lock);
    if (dmxdevfilter->state != DMXDEV_STATE_GO) {
        spin_unlock(&dmxdevfilter->dev->lock);
        return 0;
    }
    del_timer(&dmxdevfilter->timer);
    dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n",
        buffer1[0], buffer1[1],
        buffer1[2], buffer1[3], buffer1[4], buffer1[5]);
    ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1,
                      buffer1_len);
    if (ret == buffer1_len) {
        ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2,
                          buffer2_len);
    }
    if (ret < 0) {
        dvb_ringbuffer_flush(&dmxdevfilter->buffer);
        dmxdevfilter->buffer.error = ret;
    }
    if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
        dmxdevfilter->state = DMXDEV_STATE_DONE;
    spin_unlock(&dmxdevfilter->dev->lock);
    wake_up(&dmxdevfilter->buffer.queue);
    return 0;
}
예제 #8
0
파일: ngene-av.c 프로젝트: mona66/sifbox
static int video_open(struct inode *inode, struct file *file)
{
	struct dvb_device *dvbdev = file->private_data;
	struct ngene_channel *chan = dvbdev->priv;
	struct ngene *dev = chan->dev;
	struct ngene_channel *chan0 = &chan->dev->channel[0];
	int ret;

	ret = dvb_generic_open(inode, file);
	if (ret < 0)
		return ret;
	if ((file->f_flags & O_ACCMODE) != O_RDONLY)
		return ret;
	dvb_ringbuffer_flush(&dev->vin_rbuf);

	chan0->nBytesPerLine = 1920 * 2;
	chan0->nLines = 540;
	chan0->Capture1Length = 1920 * 2 * 540;
	chan0->pBufferExchange = vcap_exchange;
	chan0->itumode = 2;
	ngene_command_stream_control(chan0->dev, chan0->number,
				     0x80, SMODE_VIDEO_CAPTURE, 0);
	return ret;
}
예제 #9
0
void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
{
        unsigned long flags;
#ifdef LEXRA5280_VEC_PATCH
	unsigned long vflags;
#endif //#ifdef LEXRA5280_VEC_PATCH

	
#ifdef LEXRA5280_VEC_PATCH
        spin_lock_irqsave(&rbuf->lock, flags, vflags);//tdl for Lexra 5280 vector interrupts
#else
	spin_lock_irqsave(&rbuf->lock, flags);
#endif //#ifdef LEXRA5280_VEC_PATCH
        dvb_ringbuffer_flush(rbuf);

	
#ifdef LEXRA5280_VEC_PATCH
        spin_unlock_irqrestore(&rbuf->lock, flags, vflags);//tdl for Lexra 5280 vector interrupts
#else
	spin_unlock_irqrestore(&rbuf->lock, flags);
#endif //#ifdef LEXRA5280_VEC_PATCH

        wake_up(&rbuf->queue);
}
예제 #10
0
파일: dmxdev.c 프로젝트: 274914765/C
static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
{
    struct dmxdev *dmxdev = filter->dev;
    void *mem;
    int ret, i;

    if (filter->state < DMXDEV_STATE_SET)
        return -EINVAL;

    if (filter->state >= DMXDEV_STATE_GO)
        dvb_dmxdev_filter_stop(filter);

    if (!filter->buffer.data) {
        mem = vmalloc(filter->buffer.size);
        if (!mem)
            return -ENOMEM;
        spin_lock_irq(&filter->dev->lock);
        filter->buffer.data = mem;
        spin_unlock_irq(&filter->dev->lock);
    }

    dvb_ringbuffer_flush(&filter->buffer);

    switch (filter->type) {
    case DMXDEV_TYPE_SEC:
    {
        struct dmx_sct_filter_params *para = &filter->params.sec;
        struct dmx_section_filter **secfilter = &filter->filter.sec;
        struct dmx_section_feed **secfeed = &filter->feed.sec;

        *secfilter = NULL;
        *secfeed = NULL;


        /* find active filter/feed with same PID */
        for (i = 0; i < dmxdev->filternum; i++) {
            if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&
                dmxdev->filter[i].type == DMXDEV_TYPE_SEC &&
                dmxdev->filter[i].params.sec.pid == para->pid) {
                *secfeed = dmxdev->filter[i].feed.sec;
                break;
            }
        }

        /* if no feed found, try to allocate new one */
        if (!*secfeed) {
            ret = dmxdev->demux->allocate_section_feed(dmxdev->demux,
                                   secfeed,
                                   dvb_dmxdev_section_callback);
            if (ret < 0) {
                printk("DVB (%s): could not alloc feed\n",
                       __func__);
                return ret;
            }

            ret = (*secfeed)->set(*secfeed, para->pid, 32768,
                          (para->flags & DMX_CHECK_CRC) ? 1 : 0);
            if (ret < 0) {
                printk("DVB (%s): could not set feed\n",
                       __func__);
                dvb_dmxdev_feed_restart(filter);
                return ret;
            }
        } else {
            dvb_dmxdev_feed_stop(filter);
        }

        ret = (*secfeed)->allocate_filter(*secfeed, secfilter);
        if (ret < 0) {
            dvb_dmxdev_feed_restart(filter);
            filter->feed.sec->start_filtering(*secfeed);
            dprintk("could not get filter\n");
            return ret;
        }

        (*secfilter)->priv = filter;

        memcpy(&((*secfilter)->filter_value[3]),
               &(para->filter.filter[1]), DMX_FILTER_SIZE - 1);
        memcpy(&(*secfilter)->filter_mask[3],
               &para->filter.mask[1], DMX_FILTER_SIZE - 1);
        memcpy(&(*secfilter)->filter_mode[3],
               &para->filter.mode[1], DMX_FILTER_SIZE - 1);

        (*secfilter)->filter_value[0] = para->filter.filter[0];
        (*secfilter)->filter_mask[0] = para->filter.mask[0];
        (*secfilter)->filter_mode[0] = para->filter.mode[0];
        (*secfilter)->filter_mask[1] = 0;
        (*secfilter)->filter_mask[2] = 0;

        filter->todo = 0;

        ret = filter->feed.sec->start_filtering(filter->feed.sec);
        if (ret < 0)
            return ret;

        dvb_dmxdev_filter_timer(filter);
        break;
    }
    case DMXDEV_TYPE_PES:
    {
        struct timespec timeout = { 0 };
        struct dmx_pes_filter_params *para = &filter->params.pes;
        dmx_output_t otype;
        int ret;
        int ts_type;
        enum dmx_ts_pes ts_pes;
        struct dmx_ts_feed **tsfeed = &filter->feed.ts;

        filter->feed.ts = NULL;
        otype = para->output;

        ts_pes = (enum dmx_ts_pes)para->pes_type;

        if (ts_pes < DMX_PES_OTHER)
            ts_type = TS_DECODER;
        else
            ts_type = 0;

        if (otype == DMX_OUT_TS_TAP)
            ts_type |= TS_PACKET;
        else if (otype == DMX_OUT_TSDEMUX_TAP)
            ts_type |= TS_PACKET | TS_DEMUX;
        else if (otype == DMX_OUT_TAP)
            ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;

        ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux,
                              tsfeed,
                              dvb_dmxdev_ts_callback);
        if (ret < 0)
            return ret;

        (*tsfeed)->priv = filter;

        ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes,
                     32768, timeout);
        if (ret < 0) {
            dmxdev->demux->release_ts_feed(dmxdev->demux,
                               *tsfeed);
            return ret;
        }

        ret = filter->feed.ts->start_filtering(filter->feed.ts);
        if (ret < 0) {
            dmxdev->demux->release_ts_feed(dmxdev->demux,
                               *tsfeed);
            return ret;
        }

        break;
    }
    default:
        return -EINVAL;
    }

    dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
    return 0;
}