@@ -55,6 +55,17 @@ MODULE_PARM_DESC(dvb_demux_feed_err_pkts,
55
55
dprintk(x); \
56
56
} while (0)
57
57
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
+
58
69
/******************************************************************************
59
70
* static inlined helper functions
60
71
******************************************************************************/
@@ -104,31 +115,30 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
104
115
{
105
116
int count = payload (buf );
106
117
int p ;
107
- #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
108
118
int ccok ;
109
119
u8 cc ;
110
- #endif
111
120
112
121
if (count == 0 )
113
122
return -1 ;
114
123
115
124
p = 188 - count ;
116
125
117
- #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
118
126
cc = buf [3 ] & 0x0f ;
119
127
ccok = ((feed -> cc + 1 ) & 0x0f ) == cc ;
120
128
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
+ }
125
134
126
135
if (buf [1 ] & 0x40 ) // PUSI ?
127
136
feed -> peslen = 0xfffa ;
128
137
129
138
feed -> peslen += count ;
130
139
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 );
132
142
}
133
143
134
144
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,
150
160
return 0 ;
151
161
152
162
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 );
154
164
}
155
165
156
166
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)
169
179
if (sec -> check_crc ) {
170
180
section_syntax_indicator = ((sec -> secbuf [1 ] & 0x80 ) != 0 );
171
181
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 );
173
184
return -1 ;
185
+ }
174
186
}
175
187
176
188
do {
@@ -187,7 +199,6 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
187
199
{
188
200
struct dmx_section_feed * sec = & feed -> feed .sec ;
189
201
190
- #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
191
202
if (sec -> secbufp < sec -> tsfeedp ) {
192
203
int n = sec -> tsfeedp - sec -> secbufp ;
193
204
@@ -197,12 +208,13 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
197
208
* but just first and last.
198
209
*/
199
210
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 );
203
216
}
204
217
}
205
- #endif
206
218
207
219
sec -> tsfeedp = sec -> secbufp = sec -> seclen = 0 ;
208
220
sec -> secbuf = sec -> secbuf_base ;
@@ -237,11 +249,10 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
237
249
return 0 ;
238
250
239
251
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 );
245
256
len = DMX_MAX_SECFEED_SIZE - sec -> tsfeedp ;
246
257
}
247
258
@@ -269,12 +280,13 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
269
280
sec -> seclen = seclen ;
270
281
sec -> crc_val = ~0 ;
271
282
/* dump [secbuf .. secbuf+seclen) */
272
- if (feed -> pusi_seen )
283
+ if (feed -> pusi_seen ) {
273
284
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
+ }
278
290
sec -> secbufp += seclen ; /* secbufp and secbuf moving together is */
279
291
sec -> secbuf += seclen ; /* redundant but saves pointer arithmetic */
280
292
}
@@ -307,25 +319,30 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
307
319
}
308
320
309
321
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" ,
313
326
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" ,
316
331
cc , (feed -> cc + 1 ) & 0x0f , count + 4 );
332
+ }
317
333
/*
318
- * those bytes under sume circumstances will again be reported
334
+ * those bytes under some circumstances will again be reported
319
335
* in the following dvb_dmx_swfilter_section_new
320
336
*/
321
- #endif
337
+
322
338
/*
323
339
* Discontinuity detected. Reset pusi_seen to
324
340
* stop feeding of suspicious data until next PUSI=1 arrives
325
341
*
326
342
* FIXME: does it make sense if the MPEG-TS is the one
327
343
* reporting discontinuity?
328
344
*/
345
+
329
346
feed -> pusi_seen = false;
330
347
dvb_dmx_swfilter_section_new (feed );
331
348
}
@@ -345,11 +362,11 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
345
362
dvb_dmx_swfilter_section_new (feed );
346
363
dvb_dmx_swfilter_section_copy_dump (feed , after ,
347
364
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 );
348
369
}
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
353
370
} else {
354
371
/* PUSI=0 (is not set), no section boundary */
355
372
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,
369
386
if (feed -> ts_type & TS_PAYLOAD_ONLY )
370
387
dvb_dmx_swfilter_payload (feed , buf );
371
388
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 );
373
391
}
374
392
/* Used only on full-featured devices */
375
393
if (feed -> ts_type & TS_DECODER )
@@ -430,6 +448,11 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
430
448
}
431
449
432
450
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
+ }
433
456
dprintk_tscheck ("TEI detected. PID=0x%x data1=0x%x\n" ,
434
457
pid , buf [1 ]);
435
458
/* 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)
445
468
(demux -> cnt_storage [pid ] + 1 ) & 0xf ;
446
469
447
470
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
+
448
478
dprintk_tscheck ("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n" ,
449
479
pid , demux -> cnt_storage [pid ],
450
480
buf [3 ] & 0xf );
@@ -466,7 +496,8 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
466
496
if (feed -> pid == pid )
467
497
dvb_dmx_swfilter_packet_type (feed , buf );
468
498
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 );
470
501
}
471
502
}
472
503
@@ -585,7 +616,8 @@ void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count)
585
616
586
617
spin_lock_irqsave (& demux -> lock , flags );
587
618
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 );
589
621
590
622
spin_unlock_irqrestore (& demux -> lock , flags );
591
623
}
@@ -785,6 +817,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
785
817
feed -> demux = demux ;
786
818
feed -> pid = 0xffff ;
787
819
feed -> peslen = 0xfffa ;
820
+ feed -> buffer_flags = 0 ;
788
821
789
822
(* ts_feed ) = & feed -> feed .ts ;
790
823
(* ts_feed )-> parent = dmx ;
@@ -1042,6 +1075,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
1042
1075
dvbdmxfeed -> cb .sec = callback ;
1043
1076
dvbdmxfeed -> demux = dvbdmx ;
1044
1077
dvbdmxfeed -> pid = 0xffff ;
1078
+ dvbdmxfeed -> buffer_flags = 0 ;
1045
1079
dvbdmxfeed -> feed .sec .secbuf = dvbdmxfeed -> feed .sec .secbuf_base ;
1046
1080
dvbdmxfeed -> feed .sec .secbufp = dvbdmxfeed -> feed .sec .seclen = 0 ;
1047
1081
dvbdmxfeed -> feed .sec .tsfeedp = 0 ;
0 commit comments