Skip to content

Commit fdbeb96

Browse files
committed
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>
1 parent 9c171cd commit fdbeb96

File tree

10 files changed

+160
-76
lines changed

10 files changed

+160
-76
lines changed

drivers/media/dvb-core/dmxdev.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,8 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
385385

386386
static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
387387
const u8 *buffer2, size_t buffer2_len,
388-
struct dmx_section_filter *filter)
388+
struct dmx_section_filter *filter,
389+
u32 *buffer_flags)
389390
{
390391
struct dmxdev_filter *dmxdevfilter = filter->priv;
391392
int ret;
@@ -404,10 +405,12 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
404405
dprintk("section callback %*ph\n", 6, buffer1);
405406
if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) {
406407
ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
407-
buffer1, buffer1_len);
408+
buffer1, buffer1_len,
409+
buffer_flags);
408410
if (ret == buffer1_len)
409411
ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
410-
buffer2, buffer2_len);
412+
buffer2, buffer2_len,
413+
buffer_flags);
411414
} else {
412415
ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,
413416
buffer1, buffer1_len);
@@ -427,7 +430,8 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
427430

428431
static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
429432
const u8 *buffer2, size_t buffer2_len,
430-
struct dmx_ts_feed *feed)
433+
struct dmx_ts_feed *feed,
434+
u32 *buffer_flags)
431435
{
432436
struct dmxdev_filter *dmxdevfilter = feed->priv;
433437
struct dvb_ringbuffer *buffer;
@@ -456,9 +460,11 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
456460
}
457461

458462
if (dvb_vb2_is_streaming(ctx)) {
459-
ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len);
463+
ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len,
464+
buffer_flags);
460465
if (ret == buffer1_len)
461-
ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len);
466+
ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len,
467+
buffer_flags);
462468
} else {
463469
if (buffer->error) {
464470
spin_unlock(&dmxdevfilter->dev->lock);
@@ -1218,7 +1224,7 @@ static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma)
12181224
int ret;
12191225

12201226
if (!dmxdev->may_do_mmap)
1221-
return -EOPNOTSUPP;
1227+
return -ENOTTY;
12221228

12231229
if (mutex_lock_interruptible(&dmxdev->mutex))
12241230
return -ERESTARTSYS;
@@ -1318,7 +1324,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
13181324
break;
13191325
#endif
13201326
default:
1321-
ret = -EINVAL;
1327+
ret = -ENOTTY;
13221328
break;
13231329
}
13241330
mutex_unlock(&dmxdev->mutex);
@@ -1367,7 +1373,7 @@ static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma)
13671373
int ret;
13681374

13691375
if (!dmxdev->may_do_mmap)
1370-
return -EOPNOTSUPP;
1376+
return -ENOTTY;
13711377

13721378
if (dmxdev->exit)
13731379
return -ENODEV;

drivers/media/dvb-core/dvb_demux.c

Lines changed: 73 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ MODULE_PARM_DESC(dvb_demux_feed_err_pkts,
5555
dprintk(x); \
5656
} while (0)
5757

58+
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
59+
# define dprintk_sect_loss(x...) dprintk(x)
60+
#else
61+
# define dprintk_sect_loss(x...)
62+
#endif
63+
64+
#define set_buf_flags(__feed, __flag) \
65+
do { \
66+
(__feed)->buffer_flags |= (__flag); \
67+
} while (0)
68+
5869
/******************************************************************************
5970
* static inlined helper functions
6071
******************************************************************************/
@@ -104,31 +115,30 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
104115
{
105116
int count = payload(buf);
106117
int p;
107-
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
108118
int ccok;
109119
u8 cc;
110-
#endif
111120

112121
if (count == 0)
113122
return -1;
114123

115124
p = 188 - count;
116125

117-
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
118126
cc = buf[3] & 0x0f;
119127
ccok = ((feed->cc + 1) & 0x0f) == cc;
120128
feed->cc = cc;
121-
if (!ccok)
122-
dprintk("missed packet: %d instead of %d!\n",
123-
cc, (feed->cc + 1) & 0x0f);
124-
#endif
129+
if (!ccok) {
130+
set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
131+
dprintk_sect_loss("missed packet: %d instead of %d!\n",
132+
cc, (feed->cc + 1) & 0x0f);
133+
}
125134

126135
if (buf[1] & 0x40) // PUSI ?
127136
feed->peslen = 0xfffa;
128137

129138
feed->peslen += count;
130139

131-
return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts);
140+
return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts,
141+
&feed->buffer_flags);
132142
}
133143

134144
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,
150160
return 0;
151161

152162
return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen,
153-
NULL, 0, &f->filter);
163+
NULL, 0, &f->filter, &feed->buffer_flags);
154164
}
155165

156166
static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
@@ -169,8 +179,10 @@ static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
169179
if (sec->check_crc) {
170180
section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0);
171181
if (section_syntax_indicator &&
172-
demux->check_crc32(feed, sec->secbuf, sec->seclen))
182+
demux->check_crc32(feed, sec->secbuf, sec->seclen)) {
183+
set_buf_flags(feed, DMX_BUFFER_FLAG_HAD_CRC32_DISCARD);
173184
return -1;
185+
}
174186
}
175187

176188
do {
@@ -187,7 +199,6 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
187199
{
188200
struct dmx_section_feed *sec = &feed->feed.sec;
189201

190-
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
191202
if (sec->secbufp < sec->tsfeedp) {
192203
int n = sec->tsfeedp - sec->secbufp;
193204

@@ -197,12 +208,13 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
197208
* but just first and last.
198209
*/
199210
if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) {
200-
dprintk("section ts padding loss: %d/%d\n",
201-
n, sec->tsfeedp);
202-
dprintk("pad data: %*ph\n", n, sec->secbuf);
211+
set_buf_flags(feed,
212+
DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
213+
dprintk_sect_loss("section ts padding loss: %d/%d\n",
214+
n, sec->tsfeedp);
215+
dprintk_sect_loss("pad data: %*ph\n", n, sec->secbuf);
203216
}
204217
}
205-
#endif
206218

207219
sec->tsfeedp = sec->secbufp = sec->seclen = 0;
208220
sec->secbuf = sec->secbuf_base;
@@ -237,11 +249,10 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
237249
return 0;
238250

239251
if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
240-
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
241-
dprintk("section buffer full loss: %d/%d\n",
242-
sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
243-
DMX_MAX_SECFEED_SIZE);
244-
#endif
252+
set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
253+
dprintk_sect_loss("section buffer full loss: %d/%d\n",
254+
sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
255+
DMX_MAX_SECFEED_SIZE);
245256
len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
246257
}
247258

@@ -269,12 +280,13 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
269280
sec->seclen = seclen;
270281
sec->crc_val = ~0;
271282
/* dump [secbuf .. secbuf+seclen) */
272-
if (feed->pusi_seen)
283+
if (feed->pusi_seen) {
273284
dvb_dmx_swfilter_section_feed(feed);
274-
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
275-
else
276-
dprintk("pusi not seen, discarding section data\n");
277-
#endif
285+
} else {
286+
set_buf_flags(feed,
287+
DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
288+
dprintk_sect_loss("pusi not seen, discarding section data\n");
289+
}
278290
sec->secbufp += seclen; /* secbufp and secbuf moving together is */
279291
sec->secbuf += seclen; /* redundant but saves pointer arithmetic */
280292
}
@@ -307,25 +319,30 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
307319
}
308320

309321
if (!ccok || dc_i) {
310-
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
311-
if (dc_i)
312-
dprintk("%d frame with disconnect indicator\n",
322+
if (dc_i) {
323+
set_buf_flags(feed,
324+
DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR);
325+
dprintk_sect_loss("%d frame with disconnect indicator\n",
313326
cc);
314-
else
315-
dprintk("discontinuity: %d instead of %d. %d bytes lost\n",
327+
} else {
328+
set_buf_flags(feed,
329+
DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
330+
dprintk_sect_loss("discontinuity: %d instead of %d. %d bytes lost\n",
316331
cc, (feed->cc + 1) & 0x0f, count + 4);
332+
}
317333
/*
318-
* those bytes under sume circumstances will again be reported
334+
* those bytes under some circumstances will again be reported
319335
* in the following dvb_dmx_swfilter_section_new
320336
*/
321-
#endif
337+
322338
/*
323339
* Discontinuity detected. Reset pusi_seen to
324340
* stop feeding of suspicious data until next PUSI=1 arrives
325341
*
326342
* FIXME: does it make sense if the MPEG-TS is the one
327343
* reporting discontinuity?
328344
*/
345+
329346
feed->pusi_seen = false;
330347
dvb_dmx_swfilter_section_new(feed);
331348
}
@@ -345,11 +362,11 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
345362
dvb_dmx_swfilter_section_new(feed);
346363
dvb_dmx_swfilter_section_copy_dump(feed, after,
347364
after_len);
365+
} else if (count > 0) {
366+
set_buf_flags(feed,
367+
DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
368+
dprintk_sect_loss("PUSI=1 but %d bytes lost\n", count);
348369
}
349-
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
350-
else if (count > 0)
351-
dprintk("PUSI=1 but %d bytes lost\n", count);
352-
#endif
353370
} else {
354371
/* PUSI=0 (is not set), no section boundary */
355372
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,
369386
if (feed->ts_type & TS_PAYLOAD_ONLY)
370387
dvb_dmx_swfilter_payload(feed, buf);
371388
else
372-
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts);
389+
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
390+
&feed->buffer_flags);
373391
}
374392
/* Used only on full-featured devices */
375393
if (feed->ts_type & TS_DECODER)
@@ -430,6 +448,11 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
430448
}
431449

432450
if (buf[1] & 0x80) {
451+
list_for_each_entry(feed, &demux->feed_list, list_head) {
452+
if ((feed->pid != pid) && (feed->pid != 0x2000))
453+
continue;
454+
set_buf_flags(feed, DMX_BUFFER_FLAG_TEI);
455+
}
433456
dprintk_tscheck("TEI detected. PID=0x%x data1=0x%x\n",
434457
pid, buf[1]);
435458
/* 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)
445468
(demux->cnt_storage[pid] + 1) & 0xf;
446469

447470
if ((buf[3] & 0xf) != demux->cnt_storage[pid]) {
471+
list_for_each_entry(feed, &demux->feed_list, list_head) {
472+
if ((feed->pid != pid) && (feed->pid != 0x2000))
473+
continue;
474+
set_buf_flags(feed,
475+
DMX_BUFFER_PKT_COUNTER_MISMATCH);
476+
}
477+
448478
dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n",
449479
pid, demux->cnt_storage[pid],
450480
buf[3] & 0xf);
@@ -466,7 +496,8 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
466496
if (feed->pid == pid)
467497
dvb_dmx_swfilter_packet_type(feed, buf);
468498
else if (feed->pid == 0x2000)
469-
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts);
499+
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
500+
&feed->buffer_flags);
470501
}
471502
}
472503

@@ -585,7 +616,8 @@ void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count)
585616

586617
spin_lock_irqsave(&demux->lock, flags);
587618

588-
demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts);
619+
demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts,
620+
&demux->feed->buffer_flags);
589621

590622
spin_unlock_irqrestore(&demux->lock, flags);
591623
}
@@ -785,6 +817,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
785817
feed->demux = demux;
786818
feed->pid = 0xffff;
787819
feed->peslen = 0xfffa;
820+
feed->buffer_flags = 0;
788821

789822
(*ts_feed) = &feed->feed.ts;
790823
(*ts_feed)->parent = dmx;
@@ -1042,6 +1075,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
10421075
dvbdmxfeed->cb.sec = callback;
10431076
dvbdmxfeed->demux = dvbdmx;
10441077
dvbdmxfeed->pid = 0xffff;
1078+
dvbdmxfeed->buffer_flags = 0;
10451079
dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
10461080
dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;
10471081
dvbdmxfeed->feed.sec.tsfeedp = 0;

drivers/media/dvb-core/dvb_net.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,8 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len)
883883

884884
static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
885885
const u8 *buffer2, size_t buffer2_len,
886-
struct dmx_ts_feed *feed)
886+
struct dmx_ts_feed *feed,
887+
u32 *buffer_flags)
887888
{
888889
struct net_device *dev = feed->priv;
889890

@@ -992,7 +993,7 @@ static void dvb_net_sec(struct net_device *dev,
992993

993994
static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
994995
const u8 *buffer2, size_t buffer2_len,
995-
struct dmx_section_filter *filter)
996+
struct dmx_section_filter *filter, u32 *buffer_flags)
996997
{
997998
struct net_device *dev = filter->priv;
998999

0 commit comments

Comments
 (0)