diff options
| author | Marko Ristola <marko.ristola@kolumbus.fi> | 2011-04-08 11:40:51 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-05-20 08:28:48 -0400 |
| commit | 38e009aac9e02d2c30fd9a5e979ab31433e7d578 (patch) | |
| tree | baad2ab0209a7c70a927106d6640064fd580df50 /drivers/media/dvb/dvb-core | |
| parent | 3f84a4e1c1b785ff5dd3952cb2d4b3008b68ae45 (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/dvb-core')
| -rw-r--r-- | drivers/media/dvb/dvb-core/dvb_demux.c | 117 |
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 | ||
| 479 | EXPORT_SYMBOL(dvb_dmx_swfilter_packets); | 479 | EXPORT_SYMBOL(dvb_dmx_swfilter_packets); |
| 480 | 480 | ||
| 481 | void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) | 481 | static 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 | ||
| 517 | bailout: | 502 | return pos; |
| 518 | spin_unlock(&demux->lock); | ||
| 519 | } | 503 | } |
| 520 | 504 | ||
| 521 | EXPORT_SYMBOL(dvb_dmx_swfilter); | 505 | /* Filter all pktsize= 188 or 204 sized packets and skip garbage. */ |
| 522 | 506 | static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, | |
| 523 | void 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 | ||
| 568 | bailout: | 555 | bailout: |
| 569 | spin_unlock(&demux->lock); | 556 | spin_unlock(&demux->lock); |
| 570 | } | 557 | } |
| 571 | 558 | ||
| 559 | void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) | ||
| 560 | { | ||
| 561 | _dvb_dmx_swfilter(demux, buf, count, 188); | ||
| 562 | } | ||
| 563 | EXPORT_SYMBOL(dvb_dmx_swfilter); | ||
| 564 | |||
| 565 | void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) | ||
| 566 | { | ||
| 567 | _dvb_dmx_swfilter(demux, buf, count, 204); | ||
| 568 | } | ||
| 572 | EXPORT_SYMBOL(dvb_dmx_swfilter_204); | 569 | EXPORT_SYMBOL(dvb_dmx_swfilter_204); |
| 573 | 570 | ||
| 574 | static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux) | 571 | static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux) |
