ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen) { int consumed; int curpktlen; int curpktstatus; if (idx == -1) { idx = rbuf->pread; } else { curpktlen = rbuf->data[idx] << 8; curpktlen |= rbuf->data[(idx + 1) % rbuf->size]; idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size; } consumed = (idx - rbuf->pread) % rbuf->size; while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) { curpktlen = rbuf->data[idx] << 8; curpktlen |= rbuf->data[(idx + 1) % rbuf->size]; curpktstatus = rbuf->data[(idx + 2) % rbuf->size]; if (curpktstatus == PKT_READY) { *pktlen = curpktlen; return idx; } consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE; idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size; } // no packets available return -1; }
static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file, char __user *buf, size_t count, loff_t *ppos) { int avail; int non_blocking = file->f_flags & O_NONBLOCK; ssize_t len; if (!cibuf->data || !count) return 0; if (non_blocking && (dvb_ringbuffer_empty(cibuf))) return -EWOULDBLOCK; if (wait_event_interruptible(cibuf->queue, !dvb_ringbuffer_empty(cibuf))) return -ERESTARTSYS; avail = dvb_ringbuffer_avail(cibuf); if (avail < 4) return 0; len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8; len |= DVB_RINGBUFFER_PEEK(cibuf, 1); if (avail < len + 2 || count < len) return -EINVAL; DVB_RINGBUFFER_SKIP(cibuf, 2); return dvb_ringbuffer_read(cibuf, buf, len, 1); }
int mpq_streambuffer_data_read_dispose( struct mpq_streambuffer *sbuff, size_t len) { if (NULL == sbuff) return -EINVAL; if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) { if (unlikely(dvb_ringbuffer_avail(&sbuff->raw_data) < len)) return -EINVAL; DVB_RINGBUFFER_SKIP(&sbuff->raw_data, len); wake_up_all(&sbuff->raw_data.queue); } else { struct mpq_streambuffer_buffer_desc *desc; desc = (struct mpq_streambuffer_buffer_desc *) &sbuff->raw_data.data[sbuff->raw_data.pread]; if ((desc->read_ptr + len) > desc->size) desc->read_ptr = desc->size; else desc->read_ptr += len; } return 0; }
ssize_t video_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct dvb_device *dvbdev = file->private_data; struct ngene_channel *chan = dvbdev->priv; struct ngene *dev = chan->dev; int left, avail; left = count; while (left) { if (wait_event_interruptible( dev->vin_rbuf.queue, dvb_ringbuffer_avail(&dev->vin_rbuf) > 0) < 0) return -EAGAIN; avail = dvb_ringbuffer_avail(&dev->vin_rbuf); if (avail > left) avail = left; dvb_ringbuffer_read_user(&dev->vin_rbuf, buf, avail); left -= avail; buf += avail; } return count; }
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; }
ssize_t mpq_streambuffer_data_avail( struct mpq_streambuffer *sbuff) { struct mpq_streambuffer_buffer_desc *desc; if (NULL == sbuff) return -EINVAL; if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) return dvb_ringbuffer_avail(&sbuff->raw_data); desc = (struct mpq_streambuffer_buffer_desc *) &sbuff->raw_data.data[sbuff->raw_data.pread]; return desc->write_ptr - desc->read_ptr; }
ssize_t mpq_streambuffer_data_read_user( struct mpq_streambuffer *sbuff, u8 __user *buf, size_t len) { ssize_t actual_len = 0; if ((NULL == sbuff) || (NULL == buf)) return -EINVAL; if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) { /* * Secure buffers are not permitted to be mapped into kernel * memory, and so buffer base address may be NULL */ if (NULL == sbuff->raw_data.data) return -EPERM; actual_len = dvb_ringbuffer_avail(&sbuff->raw_data); if (actual_len < len) len = actual_len; if (len) dvb_ringbuffer_read_user(&sbuff->raw_data, buf, len); wake_up_all(&sbuff->raw_data.queue); } else { /* Linear buffer group */ struct mpq_streambuffer_buffer_desc *desc; desc = (struct mpq_streambuffer_buffer_desc *) &sbuff->raw_data.data[sbuff->raw_data.pread]; /* * Secure buffers are not permitted to be mapped into kernel * memory, and so buffer base address may be NULL */ if (NULL == desc->base) return -EPERM; actual_len = (desc->write_ptr - desc->read_ptr); if (actual_len < len) len = actual_len; if (copy_to_user(buf, desc->base + desc->read_ptr, len)) return -EFAULT; desc->read_ptr += len; } return len; }
void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx) { size_t pktlen; rbuf->data[(idx + 2) % rbuf->size] = PKT_DISPOSED; // clean up disposed packets while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) { if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) { pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8; pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1); DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE); } else { // first packet is not disposed, so we stop cleaning now break; } } }
/*============================================================================= Function : kfront_read Description : Input : Output : Return : =============================================================================*/ static ssize_t kfront_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { int avail; int non_blocking = file->f_flags & O_NONBLOCK; if (!ci_rbuffer.data || !count) return 0; if (non_blocking && (dvb_ringbuffer_empty(&ci_rbuffer))) return -EWOULDBLOCK; if (wait_event_interruptible(ci_rbuffer.queue, !dvb_ringbuffer_empty(&ci_rbuffer))) return -ERESTARTSYS; avail = dvb_ringbuffer_avail(&ci_rbuffer); if (avail < 1) return 0; return dvb_ringbuffer_read_user(&ci_rbuffer, buf, 1); }
void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) { struct ngene_channel *chan = priv; struct ngene *dev = chan->dev; u32 alen; alen = dvb_ringbuffer_avail(&dev->tsout_rbuf); alen -= alen % 188; if (alen < len) FillTSBuffer(buf + alen, len - alen, flags); else alen = len; dvb_ringbuffer_read(&dev->tsout_rbuf, buf, alen); if (flags & DF_SWAP32) swap_buffer((u32 *)buf, alen); wake_up_interruptible(&dev->tsout_rbuf.queue); return buf; }