1
0
Fork 0
mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-01-23 08:35:19 -05:00

media: dvb: update buffer mmaped flags and frame counter

Now that we have support for a buffer counter and for
error flags, update them at DMX_DQBUF.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
Mauro Carvalho Chehab 2018-02-09 07:30:46 -05:00
parent 9c171cdf22
commit fdbeb96258
10 changed files with 160 additions and 76 deletions

View file

@ -385,7 +385,8 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len, const u8 *buffer2, size_t buffer2_len,
struct dmx_section_filter *filter) struct dmx_section_filter *filter,
u32 *buffer_flags)
{ {
struct dmxdev_filter *dmxdevfilter = filter->priv; struct dmxdev_filter *dmxdevfilter = filter->priv;
int ret; int ret;
@ -404,10 +405,12 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
dprintk("section callback %*ph\n", 6, buffer1); dprintk("section callback %*ph\n", 6, buffer1);
if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) { if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) {
ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx, ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
buffer1, buffer1_len); buffer1, buffer1_len,
buffer_flags);
if (ret == buffer1_len) if (ret == buffer1_len)
ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx, ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
buffer2, buffer2_len); buffer2, buffer2_len,
buffer_flags);
} else { } else {
ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,
buffer1, buffer1_len); buffer1, buffer1_len);
@ -427,7 +430,8 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len, const u8 *buffer2, size_t buffer2_len,
struct dmx_ts_feed *feed) struct dmx_ts_feed *feed,
u32 *buffer_flags)
{ {
struct dmxdev_filter *dmxdevfilter = feed->priv; struct dmxdev_filter *dmxdevfilter = feed->priv;
struct dvb_ringbuffer *buffer; struct dvb_ringbuffer *buffer;
@ -456,9 +460,11 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
} }
if (dvb_vb2_is_streaming(ctx)) { if (dvb_vb2_is_streaming(ctx)) {
ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len); ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len,
buffer_flags);
if (ret == buffer1_len) if (ret == buffer1_len)
ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len); ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len,
buffer_flags);
} else { } else {
if (buffer->error) { if (buffer->error) {
spin_unlock(&dmxdevfilter->dev->lock); spin_unlock(&dmxdevfilter->dev->lock);
@ -1218,7 +1224,7 @@ static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma)
int ret; int ret;
if (!dmxdev->may_do_mmap) if (!dmxdev->may_do_mmap)
return -EOPNOTSUPP; return -ENOTTY;
if (mutex_lock_interruptible(&dmxdev->mutex)) if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS; return -ERESTARTSYS;
@ -1318,7 +1324,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
break; break;
#endif #endif
default: default:
ret = -EINVAL; ret = -ENOTTY;
break; break;
} }
mutex_unlock(&dmxdev->mutex); mutex_unlock(&dmxdev->mutex);
@ -1367,7 +1373,7 @@ static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma)
int ret; int ret;
if (!dmxdev->may_do_mmap) if (!dmxdev->may_do_mmap)
return -EOPNOTSUPP; return -ENOTTY;
if (dmxdev->exit) if (dmxdev->exit)
return -ENODEV; return -ENODEV;

View file

@ -55,6 +55,17 @@ MODULE_PARM_DESC(dvb_demux_feed_err_pkts,
dprintk(x); \ dprintk(x); \
} while (0) } while (0)
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
# define dprintk_sect_loss(x...) dprintk(x)
#else
# define dprintk_sect_loss(x...)
#endif
#define set_buf_flags(__feed, __flag) \
do { \
(__feed)->buffer_flags |= (__flag); \
} while (0)
/****************************************************************************** /******************************************************************************
* static inlined helper functions * static inlined helper functions
******************************************************************************/ ******************************************************************************/
@ -104,31 +115,30 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
{ {
int count = payload(buf); int count = payload(buf);
int p; int p;
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
int ccok; int ccok;
u8 cc; u8 cc;
#endif
if (count == 0) if (count == 0)
return -1; return -1;
p = 188 - count; p = 188 - count;
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
cc = buf[3] & 0x0f; cc = buf[3] & 0x0f;
ccok = ((feed->cc + 1) & 0x0f) == cc; ccok = ((feed->cc + 1) & 0x0f) == cc;
feed->cc = cc; feed->cc = cc;
if (!ccok) if (!ccok) {
dprintk("missed packet: %d instead of %d!\n", set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
dprintk_sect_loss("missed packet: %d instead of %d!\n",
cc, (feed->cc + 1) & 0x0f); cc, (feed->cc + 1) & 0x0f);
#endif }
if (buf[1] & 0x40) // PUSI ? if (buf[1] & 0x40) // PUSI ?
feed->peslen = 0xfffa; feed->peslen = 0xfffa;
feed->peslen += count; feed->peslen += count;
return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts); return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts,
&feed->buffer_flags);
} }
static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed, static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
@ -150,7 +160,7 @@ static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
return 0; return 0;
return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen, return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen,
NULL, 0, &f->filter); NULL, 0, &f->filter, &feed->buffer_flags);
} }
static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed) static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
@ -169,9 +179,11 @@ static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
if (sec->check_crc) { if (sec->check_crc) {
section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0); section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0);
if (section_syntax_indicator && if (section_syntax_indicator &&
demux->check_crc32(feed, sec->secbuf, sec->seclen)) demux->check_crc32(feed, sec->secbuf, sec->seclen)) {
set_buf_flags(feed, DMX_BUFFER_FLAG_HAD_CRC32_DISCARD);
return -1; return -1;
} }
}
do { do {
if (dvb_dmx_swfilter_sectionfilter(feed, f) < 0) if (dvb_dmx_swfilter_sectionfilter(feed, f) < 0)
@ -187,7 +199,6 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
{ {
struct dmx_section_feed *sec = &feed->feed.sec; struct dmx_section_feed *sec = &feed->feed.sec;
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
if (sec->secbufp < sec->tsfeedp) { if (sec->secbufp < sec->tsfeedp) {
int n = sec->tsfeedp - sec->secbufp; int n = sec->tsfeedp - sec->secbufp;
@ -197,12 +208,13 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
* but just first and last. * but just first and last.
*/ */
if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) { if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) {
dprintk("section ts padding loss: %d/%d\n", set_buf_flags(feed,
DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
dprintk_sect_loss("section ts padding loss: %d/%d\n",
n, sec->tsfeedp); n, sec->tsfeedp);
dprintk("pad data: %*ph\n", n, sec->secbuf); dprintk_sect_loss("pad data: %*ph\n", n, sec->secbuf);
} }
} }
#endif
sec->tsfeedp = sec->secbufp = sec->seclen = 0; sec->tsfeedp = sec->secbufp = sec->seclen = 0;
sec->secbuf = sec->secbuf_base; sec->secbuf = sec->secbuf_base;
@ -237,11 +249,10 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
return 0; return 0;
if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) { if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
dprintk("section buffer full loss: %d/%d\n", dprintk_sect_loss("section buffer full loss: %d/%d\n",
sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
DMX_MAX_SECFEED_SIZE); DMX_MAX_SECFEED_SIZE);
#endif
len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp; len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
} }
@ -269,12 +280,13 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
sec->seclen = seclen; sec->seclen = seclen;
sec->crc_val = ~0; sec->crc_val = ~0;
/* dump [secbuf .. secbuf+seclen) */ /* dump [secbuf .. secbuf+seclen) */
if (feed->pusi_seen) if (feed->pusi_seen) {
dvb_dmx_swfilter_section_feed(feed); dvb_dmx_swfilter_section_feed(feed);
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG } else {
else set_buf_flags(feed,
dprintk("pusi not seen, discarding section data\n"); DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
#endif dprintk_sect_loss("pusi not seen, discarding section data\n");
}
sec->secbufp += seclen; /* secbufp and secbuf moving together is */ sec->secbufp += seclen; /* secbufp and secbuf moving together is */
sec->secbuf += seclen; /* redundant but saves pointer arithmetic */ sec->secbuf += seclen; /* redundant but saves pointer arithmetic */
} }
@ -307,18 +319,22 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
} }
if (!ccok || dc_i) { if (!ccok || dc_i) {
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG if (dc_i) {
if (dc_i) set_buf_flags(feed,
dprintk("%d frame with disconnect indicator\n", DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR);
dprintk_sect_loss("%d frame with disconnect indicator\n",
cc); cc);
else } else {
dprintk("discontinuity: %d instead of %d. %d bytes lost\n", set_buf_flags(feed,
DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
dprintk_sect_loss("discontinuity: %d instead of %d. %d bytes lost\n",
cc, (feed->cc + 1) & 0x0f, count + 4); cc, (feed->cc + 1) & 0x0f, count + 4);
}
/* /*
* those bytes under sume circumstances will again be reported * those bytes under some circumstances will again be reported
* in the following dvb_dmx_swfilter_section_new * in the following dvb_dmx_swfilter_section_new
*/ */
#endif
/* /*
* Discontinuity detected. Reset pusi_seen to * Discontinuity detected. Reset pusi_seen to
* stop feeding of suspicious data until next PUSI=1 arrives * stop feeding of suspicious data until next PUSI=1 arrives
@ -326,6 +342,7 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
* FIXME: does it make sense if the MPEG-TS is the one * FIXME: does it make sense if the MPEG-TS is the one
* reporting discontinuity? * reporting discontinuity?
*/ */
feed->pusi_seen = false; feed->pusi_seen = false;
dvb_dmx_swfilter_section_new(feed); dvb_dmx_swfilter_section_new(feed);
} }
@ -345,11 +362,11 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
dvb_dmx_swfilter_section_new(feed); dvb_dmx_swfilter_section_new(feed);
dvb_dmx_swfilter_section_copy_dump(feed, after, dvb_dmx_swfilter_section_copy_dump(feed, after,
after_len); after_len);
} else if (count > 0) {
set_buf_flags(feed,
DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
dprintk_sect_loss("PUSI=1 but %d bytes lost\n", count);
} }
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
else if (count > 0)
dprintk("PUSI=1 but %d bytes lost\n", count);
#endif
} else { } else {
/* PUSI=0 (is not set), no section boundary */ /* PUSI=0 (is not set), no section boundary */
dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count); dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count);
@ -369,7 +386,8 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
if (feed->ts_type & TS_PAYLOAD_ONLY) if (feed->ts_type & TS_PAYLOAD_ONLY)
dvb_dmx_swfilter_payload(feed, buf); dvb_dmx_swfilter_payload(feed, buf);
else else
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts); feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
&feed->buffer_flags);
} }
/* Used only on full-featured devices */ /* Used only on full-featured devices */
if (feed->ts_type & TS_DECODER) if (feed->ts_type & TS_DECODER)
@ -430,6 +448,11 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
} }
if (buf[1] & 0x80) { if (buf[1] & 0x80) {
list_for_each_entry(feed, &demux->feed_list, list_head) {
if ((feed->pid != pid) && (feed->pid != 0x2000))
continue;
set_buf_flags(feed, DMX_BUFFER_FLAG_TEI);
}
dprintk_tscheck("TEI detected. PID=0x%x data1=0x%x\n", dprintk_tscheck("TEI detected. PID=0x%x data1=0x%x\n",
pid, buf[1]); pid, buf[1]);
/* data in this packet can't be trusted - drop it unless /* data in this packet can't be trusted - drop it unless
@ -445,6 +468,13 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
(demux->cnt_storage[pid] + 1) & 0xf; (demux->cnt_storage[pid] + 1) & 0xf;
if ((buf[3] & 0xf) != demux->cnt_storage[pid]) { if ((buf[3] & 0xf) != demux->cnt_storage[pid]) {
list_for_each_entry(feed, &demux->feed_list, list_head) {
if ((feed->pid != pid) && (feed->pid != 0x2000))
continue;
set_buf_flags(feed,
DMX_BUFFER_PKT_COUNTER_MISMATCH);
}
dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n", dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n",
pid, demux->cnt_storage[pid], pid, demux->cnt_storage[pid],
buf[3] & 0xf); buf[3] & 0xf);
@ -466,7 +496,8 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
if (feed->pid == pid) if (feed->pid == pid)
dvb_dmx_swfilter_packet_type(feed, buf); dvb_dmx_swfilter_packet_type(feed, buf);
else if (feed->pid == 0x2000) else if (feed->pid == 0x2000)
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts); feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
&feed->buffer_flags);
} }
} }
@ -585,7 +616,8 @@ void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count)
spin_lock_irqsave(&demux->lock, flags); spin_lock_irqsave(&demux->lock, flags);
demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts); demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts,
&demux->feed->buffer_flags);
spin_unlock_irqrestore(&demux->lock, flags); spin_unlock_irqrestore(&demux->lock, flags);
} }
@ -785,6 +817,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
feed->demux = demux; feed->demux = demux;
feed->pid = 0xffff; feed->pid = 0xffff;
feed->peslen = 0xfffa; feed->peslen = 0xfffa;
feed->buffer_flags = 0;
(*ts_feed) = &feed->feed.ts; (*ts_feed) = &feed->feed.ts;
(*ts_feed)->parent = dmx; (*ts_feed)->parent = dmx;
@ -1042,6 +1075,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
dvbdmxfeed->cb.sec = callback; dvbdmxfeed->cb.sec = callback;
dvbdmxfeed->demux = dvbdmx; dvbdmxfeed->demux = dvbdmx;
dvbdmxfeed->pid = 0xffff; dvbdmxfeed->pid = 0xffff;
dvbdmxfeed->buffer_flags = 0;
dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base; dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0; dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;
dvbdmxfeed->feed.sec.tsfeedp = 0; dvbdmxfeed->feed.sec.tsfeedp = 0;

View file

@ -883,7 +883,8 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len)
static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len, static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len, const u8 *buffer2, size_t buffer2_len,
struct dmx_ts_feed *feed) struct dmx_ts_feed *feed,
u32 *buffer_flags)
{ {
struct net_device *dev = feed->priv; struct net_device *dev = feed->priv;
@ -992,7 +993,7 @@ static void dvb_net_sec(struct net_device *dev,
static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len, static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len, const u8 *buffer2, size_t buffer2_len,
struct dmx_section_filter *filter) struct dmx_section_filter *filter, u32 *buffer_flags)
{ {
struct net_device *dev = filter->priv; struct net_device *dev = filter->priv;

View file

@ -256,7 +256,8 @@ int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx)
} }
int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
const unsigned char *src, int len) const unsigned char *src, int len,
enum dmx_buffer_flags *buffer_flags)
{ {
unsigned long flags = 0; unsigned long flags = 0;
void *vbuf = NULL; void *vbuf = NULL;
@ -264,15 +265,17 @@ int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
unsigned char *psrc = (unsigned char *)src; unsigned char *psrc = (unsigned char *)src;
int ll = 0; int ll = 0;
dprintk(3, "[%s] %d bytes are rcvd\n", ctx->name, len); /*
if (!src) { * normal case: This func is called twice from demux driver
dprintk(3, "[%s]:NULL pointer src\n", ctx->name); * one with valid src pointer, second time with NULL pointer
/**normal case: This func is called twice from demux driver
* once with valid src pointer, second time with NULL pointer
*/ */
if (!src || !len)
return 0; return 0;
}
spin_lock_irqsave(&ctx->slock, flags); spin_lock_irqsave(&ctx->slock, flags);
if (buffer_flags && *buffer_flags) {
ctx->flags |= *buffer_flags;
*buffer_flags = 0;
}
while (todo) { while (todo) {
if (!ctx->buf) { if (!ctx->buf) {
if (list_empty(&ctx->dvb_q)) { if (list_empty(&ctx->dvb_q)) {
@ -395,6 +398,7 @@ int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
{ {
unsigned long flags;
int ret; int ret;
ret = vb2_core_dqbuf(&ctx->vb_q, &b->index, b, ctx->nonblocking); ret = vb2_core_dqbuf(&ctx->vb_q, &b->index, b, ctx->nonblocking);
@ -402,7 +406,16 @@ int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
dprintk(1, "[%s] errno=%d\n", ctx->name, ret); dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
return ret; return ret;
} }
dprintk(5, "[%s] index=%d\n", ctx->name, b->index);
spin_lock_irqsave(&ctx->slock, flags);
b->count = ctx->count++;
b->flags = ctx->flags;
ctx->flags = 0;
spin_unlock_irqrestore(&ctx->slock, flags);
dprintk(5, "[%s] index=%d, count=%d, flags=%d\n",
ctx->name, b->index, ctx->count, b->flags);
return 0; return 0;
} }

View file

@ -324,14 +324,15 @@ static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
} }
return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len, return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
buffer2, buffer2_len, buffer2, buffer2_len,
&dvbdmxfilter->filter); &dvbdmxfilter->filter, NULL);
case DMX_TYPE_TS: case DMX_TYPE_TS:
if (!(dvbdmxfilter->feed->ts_type & TS_PACKET)) if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
return 0; return 0;
if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY) if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len, return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
buffer2, buffer2_len, buffer2, buffer2_len,
&dvbdmxfilter->feed->feed.ts); &dvbdmxfilter->feed->feed.ts,
NULL);
else else
av7110_p2t_write(buffer1, buffer1_len, av7110_p2t_write(buffer1, buffer1_len,
dvbdmxfilter->feed->pid, dvbdmxfilter->feed->pid,

View file

@ -99,7 +99,7 @@ int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
buf[4] = buf[5] = 0; buf[4] = buf[5] = 0;
if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
return dvbdmxfeed->cb.ts(buf, len, NULL, 0, return dvbdmxfeed->cb.ts(buf, len, NULL, 0,
&dvbdmxfeed->feed.ts); &dvbdmxfeed->feed.ts, NULL);
else else
return dvb_filter_pes2ts(p2t, buf, len, 1); return dvb_filter_pes2ts(p2t, buf, len, 1);
} }
@ -109,7 +109,7 @@ static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv; struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv;
dvbdmxfeed->cb.ts(data, 188, NULL, 0, dvbdmxfeed->cb.ts(data, 188, NULL, 0,
&dvbdmxfeed->feed.ts); &dvbdmxfeed->feed.ts, NULL);
return 0; return 0;
} }
@ -814,7 +814,7 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
memcpy(obuf + l, buf + c, TS_SIZE - l); memcpy(obuf + l, buf + c, TS_SIZE - l);
c = length; c = length;
} }
feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts); feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, NULL);
pes_start = 0; pes_start = 0;
} }
} }

View file

@ -428,7 +428,7 @@ static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
struct ttusb_dec *dec = priv; struct ttusb_dec *dec = priv;
dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
&dec->audio_filter->feed->feed.ts); &dec->audio_filter->feed->feed.ts, NULL);
return 0; return 0;
} }
@ -438,7 +438,7 @@ static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
struct ttusb_dec *dec = priv; struct ttusb_dec *dec = priv;
dec->video_filter->feed->cb.ts(data, 188, NULL, 0, dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
&dec->video_filter->feed->feed.ts); &dec->video_filter->feed->feed.ts, NULL);
return 0; return 0;
} }
@ -490,7 +490,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
if (output_pva) { if (output_pva) {
dec->video_filter->feed->cb.ts(pva, length, NULL, 0, dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
&dec->video_filter->feed->feed.ts); &dec->video_filter->feed->feed.ts, NULL);
return; return;
} }
@ -551,7 +551,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
case 0x02: /* MainAudioStream */ case 0x02: /* MainAudioStream */
if (output_pva) { if (output_pva) {
dec->audio_filter->feed->cb.ts(pva, length, NULL, 0, dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
&dec->audio_filter->feed->feed.ts); &dec->audio_filter->feed->feed.ts, NULL);
return; return;
} }
@ -589,7 +589,7 @@ static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
if (filter) if (filter)
filter->feed->cb.sec(&packet[2], length - 2, NULL, 0, filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
&filter->filter); &filter->filter, NULL);
} }
static void ttusb_dec_process_packet(struct ttusb_dec *dec) static void ttusb_dec_process_packet(struct ttusb_dec *dec)

View file

@ -117,7 +117,7 @@ struct dmx_ts_feed {
* specified by @filter_value that will be used on the filter * specified by @filter_value that will be used on the filter
* match logic. * match logic.
* @filter_mode: Contains a 16 bytes (128 bits) filter mode. * @filter_mode: Contains a 16 bytes (128 bits) filter mode.
* @parent: Pointer to struct dmx_section_feed. * @parent: Back-pointer to struct dmx_section_feed.
* @priv: Pointer to private data of the API client. * @priv: Pointer to private data of the API client.
* *
* *
@ -130,8 +130,9 @@ struct dmx_section_filter {
u8 filter_value[DMX_MAX_FILTER_SIZE]; u8 filter_value[DMX_MAX_FILTER_SIZE];
u8 filter_mask[DMX_MAX_FILTER_SIZE]; u8 filter_mask[DMX_MAX_FILTER_SIZE];
u8 filter_mode[DMX_MAX_FILTER_SIZE]; u8 filter_mode[DMX_MAX_FILTER_SIZE];
struct dmx_section_feed *parent; /* Back-pointer */ struct dmx_section_feed *parent;
void *priv; /* Pointer to private data of the API client */
void *priv;
}; };
/** /**
@ -193,6 +194,10 @@ struct dmx_section_feed {
* @buffer2: Pointer to the tail of the filtered TS packets, or NULL. * @buffer2: Pointer to the tail of the filtered TS packets, or NULL.
* @buffer2_length: Length of the TS data in buffer2. * @buffer2_length: Length of the TS data in buffer2.
* @source: Indicates which TS feed is the source of the callback. * @source: Indicates which TS feed is the source of the callback.
* @buffer_flags: Address where buffer flags are stored. Those are
* used to report discontinuity users via DVB
* memory mapped API, as defined by
* &enum dmx_buffer_flags.
* *
* This function callback prototype, provided by the client of the demux API, * This function callback prototype, provided by the client of the demux API,
* is called from the demux code. The function is only called when filtering * is called from the demux code. The function is only called when filtering
@ -245,7 +250,8 @@ typedef int (*dmx_ts_cb)(const u8 *buffer1,
size_t buffer1_length, size_t buffer1_length,
const u8 *buffer2, const u8 *buffer2,
size_t buffer2_length, size_t buffer2_length,
struct dmx_ts_feed *source); struct dmx_ts_feed *source,
u32 *buffer_flags);
/** /**
* typedef dmx_section_cb - DVB demux TS filter callback function prototype * typedef dmx_section_cb - DVB demux TS filter callback function prototype
@ -261,6 +267,10 @@ typedef int (*dmx_ts_cb)(const u8 *buffer1,
* including headers and CRC. * including headers and CRC.
* @source: Indicates which section feed is the source of the * @source: Indicates which section feed is the source of the
* callback. * callback.
* @buffer_flags: Address where buffer flags are stored. Those are
* used to report discontinuity users via DVB
* memory mapped API, as defined by
* &enum dmx_buffer_flags.
* *
* This function callback prototype, provided by the client of the demux API, * This function callback prototype, provided by the client of the demux API,
* is called from the demux code. The function is only called when * is called from the demux code. The function is only called when
@ -286,7 +296,8 @@ typedef int (*dmx_section_cb)(const u8 *buffer1,
size_t buffer1_len, size_t buffer1_len,
const u8 *buffer2, const u8 *buffer2,
size_t buffer2_len, size_t buffer2_len,
struct dmx_section_filter *source); struct dmx_section_filter *source,
u32 *buffer_flags);
/* /*
* DVB Front-End * DVB Front-End

View file

@ -115,6 +115,8 @@ struct dvb_demux_filter {
* @pid: PID to be filtered. * @pid: PID to be filtered.
* @timeout: feed timeout. * @timeout: feed timeout.
* @filter: pointer to &struct dvb_demux_filter. * @filter: pointer to &struct dvb_demux_filter.
* @buffer_flags: Buffer flags used to report discontinuity users via DVB
* memory mapped API, as defined by &enum dmx_buffer_flags.
* @ts_type: type of TS, as defined by &enum ts_filter_type. * @ts_type: type of TS, as defined by &enum ts_filter_type.
* @pes_type: type of PES, as defined by &enum dmx_ts_pes. * @pes_type: type of PES, as defined by &enum dmx_ts_pes.
* @cc: MPEG-TS packet continuity counter * @cc: MPEG-TS packet continuity counter
@ -145,6 +147,8 @@ struct dvb_demux_feed {
ktime_t timeout; ktime_t timeout;
struct dvb_demux_filter *filter; struct dvb_demux_filter *filter;
u32 buffer_flags;
enum ts_filter_type ts_type; enum ts_filter_type ts_type;
enum dmx_ts_pes pes_type; enum dmx_ts_pes pes_type;

View file

@ -85,6 +85,12 @@ struct dvb_buffer {
* @nonblocking: * @nonblocking:
* If different than zero, device is operating on non-blocking * If different than zero, device is operating on non-blocking
* mode. * mode.
* @flags: buffer flags as defined by &enum dmx_buffer_flags.
* Filled only at &DMX_DQBUF. &DMX_QBUF should zero this field.
* @count: monotonic counter for filled buffers. Helps to identify
* data stream loses. Filled only at &DMX_DQBUF. &DMX_QBUF should
* zero this field.
*
* @name: name of the device type. Currently, it can either be * @name: name of the device type. Currently, it can either be
* "dvr" or "demux_filter". * "dvr" or "demux_filter".
*/ */
@ -100,6 +106,10 @@ struct dvb_vb2_ctx {
int buf_siz; int buf_siz;
int buf_cnt; int buf_cnt;
int nonblocking; int nonblocking;
enum dmx_buffer_flags flags;
u32 count;
char name[DVB_VB2_NAME_MAX + 1]; char name[DVB_VB2_NAME_MAX + 1];
}; };
@ -114,7 +124,7 @@ static inline int dvb_vb2_release(struct dvb_vb2_ctx *ctx)
return 0; return 0;
}; };
#define dvb_vb2_is_streaming(ctx) (0) #define dvb_vb2_is_streaming(ctx) (0)
#define dvb_vb2_fill_buffer(ctx, file, wait) (0) #define dvb_vb2_fill_buffer(ctx, file, wait, flags) (0)
static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx,
struct file *file, struct file *file,
@ -153,9 +163,13 @@ int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx);
* @ctx: control struct for VB2 handler * @ctx: control struct for VB2 handler
* @src: place where the data is stored * @src: place where the data is stored
* @len: number of bytes to be copied from @src * @len: number of bytes to be copied from @src
* @buffer_flags:
* pointer to buffer flags as defined by &enum dmx_buffer_flags.
* can be NULL.
*/ */
int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
const unsigned char *src, int len); const unsigned char *src, int len,
enum dmx_buffer_flags *buffer_flags);
/** /**
* dvb_vb2_poll - Wrapper to vb2_core_streamon() for Digital TV * dvb_vb2_poll - Wrapper to vb2_core_streamon() for Digital TV