aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
authorMarko Ristola <marko.ristola@kolumbus.fi>2011-04-08 11:40:51 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-05-20 08:28:48 -0400
commit38e009aac9e02d2c30fd9a5e979ab31433e7d578 (patch)
treebaad2ab0209a7c70a927106d6640064fd580df50 /drivers/media/dvb
parent3f84a4e1c1b785ff5dd3952cb2d4b3008b68ae45 (diff)
[media] Speed up DVB TS stream delivery from DMA buffer into dvb-core's buffer
Avoid unnecessary DVB TS 188 sized packet copying from DMA buffer into stack. Backtrack one 188 sized packet just after some garbage bytes when possible. This obsoletes patch https://patchwork.kernel.org/patch/118147/ Signed-off-by: Marko Ristola <marko.ristola@kolumbus.fi> Acked-by: Andreas Oberritter <obi@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c117
1 files changed, 57 insertions, 60 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 4a88a3e4db2..faa3671b649 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -478,97 +478,94 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
478 478
479EXPORT_SYMBOL(dvb_dmx_swfilter_packets); 479EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
480 480
481void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) 481static inline int find_next_packet(const u8 *buf, int pos, size_t count,
482 const int pktsize)
482{ 483{
483 int p = 0, i, j; 484 int start = pos, lost;
484 485
485 spin_lock(&demux->lock); 486 while (pos < count) {
486 487 if (buf[pos] == 0x47 ||
487 if (demux->tsbufp) { 488 (pktsize == 204 && buf[pos] == 0xB8))
488 i = demux->tsbufp; 489 break;
489 j = 188 - i; 490 pos++;
490 if (count < j) {
491 memcpy(&demux->tsbuf[i], buf, count);
492 demux->tsbufp += count;
493 goto bailout;
494 }
495 memcpy(&demux->tsbuf[i], buf, j);
496 if (demux->tsbuf[0] == 0x47)
497 dvb_dmx_swfilter_packet(demux, demux->tsbuf);
498 demux->tsbufp = 0;
499 p += j;
500 } 491 }
501 492
502 while (p < count) { 493 lost = pos - start;
503 if (buf[p] == 0x47) { 494 if (lost) {
504 if (count - p >= 188) { 495 /* This garbage is part of a valid packet? */
505 dvb_dmx_swfilter_packet(demux, &buf[p]); 496 int backtrack = pos - pktsize;
506 p += 188; 497 if (backtrack >= 0 && (buf[backtrack] == 0x47 ||
507 } else { 498 (pktsize == 204 && buf[backtrack] == 0xB8)))
508 i = count - p; 499 return backtrack;
509 memcpy(demux->tsbuf, &buf[p], i);
510 demux->tsbufp = i;
511 goto bailout;
512 }
513 } else
514 p++;
515 } 500 }
516 501
517bailout: 502 return pos;
518 spin_unlock(&demux->lock);
519} 503}
520 504
521EXPORT_SYMBOL(dvb_dmx_swfilter); 505/* Filter all pktsize= 188 or 204 sized packets and skip garbage. */
522 506static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf,
523void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) 507 size_t count, const int pktsize)
524{ 508{
525 int p = 0, i, j; 509 int p = 0, i, j;
526 u8 tmppack[188]; 510 const u8 *q;
527 511
528 spin_lock(&demux->lock); 512 spin_lock(&demux->lock);
529 513
530 if (demux->tsbufp) { 514 if (demux->tsbufp) { /* tsbuf[0] is now 0x47. */
531 i = demux->tsbufp; 515 i = demux->tsbufp;
532 j = 204 - i; 516 j = pktsize - i;
533 if (count < j) { 517 if (count < j) {
534 memcpy(&demux->tsbuf[i], buf, count); 518 memcpy(&demux->tsbuf[i], buf, count);
535 demux->tsbufp += count; 519 demux->tsbufp += count;
536 goto bailout; 520 goto bailout;
537 } 521 }
538 memcpy(&demux->tsbuf[i], buf, j); 522 memcpy(&demux->tsbuf[i], buf, j);
539 if ((demux->tsbuf[0] == 0x47) || (demux->tsbuf[0] == 0xB8)) { 523 if (demux->tsbuf[0] == 0x47) /* double check */
540 memcpy(tmppack, demux->tsbuf, 188); 524 dvb_dmx_swfilter_packet(demux, demux->tsbuf);
541 if (tmppack[0] == 0xB8)
542 tmppack[0] = 0x47;
543 dvb_dmx_swfilter_packet(demux, tmppack);
544 }
545 demux->tsbufp = 0; 525 demux->tsbufp = 0;
546 p += j; 526 p += j;
547 } 527 }
548 528
549 while (p < count) { 529 while (1) {
550 if ((buf[p] == 0x47) || (buf[p] == 0xB8)) { 530 p = find_next_packet(buf, p, count, pktsize);
551 if (count - p >= 204) { 531 if (p >= count)
552 memcpy(tmppack, &buf[p], 188); 532 break;
553 if (tmppack[0] == 0xB8) 533 if (count - p < pktsize)
554 tmppack[0] = 0x47; 534 break;
555 dvb_dmx_swfilter_packet(demux, tmppack); 535
556 p += 204; 536 q = &buf[p];
557 } else { 537
558 i = count - p; 538 if (pktsize == 204 && (*q == 0xB8)) {
559 memcpy(demux->tsbuf, &buf[p], i); 539 memcpy(demux->tsbuf, q, 188);
560 demux->tsbufp = i; 540 demux->tsbuf[0] = 0x47;
561 goto bailout; 541 q = demux->tsbuf;
562 }
563 } else {
564 p++;
565 } 542 }
543 dvb_dmx_swfilter_packet(demux, q);
544 p += pktsize;
545 }
546
547 i = count - p;
548 if (i) {
549 memcpy(demux->tsbuf, &buf[p], i);
550 demux->tsbufp = i;
551 if (pktsize == 204 && demux->tsbuf[0] == 0xB8)
552 demux->tsbuf[0] = 0x47;
566 } 553 }
567 554
568bailout: 555bailout:
569 spin_unlock(&demux->lock); 556 spin_unlock(&demux->lock);
570} 557}
571 558
559void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
560{
561 _dvb_dmx_swfilter(demux, buf, count, 188);
562}
563EXPORT_SYMBOL(dvb_dmx_swfilter);
564
565void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
566{
567 _dvb_dmx_swfilter(demux, buf, count, 204);
568}
572EXPORT_SYMBOL(dvb_dmx_swfilter_204); 569EXPORT_SYMBOL(dvb_dmx_swfilter_204);
573 570
574static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux) 571static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux)