diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2010-05-16 14:41:00 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2010-05-16 14:41:00 +0000 |
commit | b197c3b0d6bfcf3daae4a7b1cad415b1acea28f6 (patch) | |
tree | 1c7bce8c4bc39617ff819111d39a41370ca8f49b | |
parent | caa4f54e4235f99acd1c69673c85a4557b6183a9 (diff) | |
download | rockbox-b197c3b0d6bfcf3daae4a7b1cad415b1acea28f6.tar.gz rockbox-b197c3b0d6bfcf3daae4a7b1cad415b1acea28f6.zip |
MPEGPlayer: Add a second layer of caching to help speed up byte-wise scanning and seeking a bit.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26088 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/plugins/mpegplayer/disk_buf.c | 150 | ||||
-rw-r--r-- | apps/plugins/mpegplayer/disk_buf.h | 42 | ||||
-rw-r--r-- | apps/plugins/mpegplayer/mpeg_misc.c | 6 | ||||
-rw-r--r-- | apps/plugins/mpegplayer/mpeg_misc.h | 6 | ||||
-rw-r--r-- | apps/plugins/mpegplayer/mpeg_parser.c | 50 |
5 files changed, 178 insertions, 76 deletions
diff --git a/apps/plugins/mpegplayer/disk_buf.c b/apps/plugins/mpegplayer/disk_buf.c index 0720197f3a..39563b7041 100644 --- a/apps/plugins/mpegplayer/disk_buf.c +++ b/apps/plugins/mpegplayer/disk_buf.c | |||
@@ -49,6 +49,26 @@ static inline void disk_buf_on_clear_data_notify(struct stream_hdr *sh) | |||
49 | list_remove_item(&sh->nf); | 49 | list_remove_item(&sh->nf); |
50 | } | 50 | } |
51 | 51 | ||
52 | |||
53 | inline bool disk_buf_is_data_ready(struct stream_hdr *sh, | ||
54 | ssize_t margin) | ||
55 | { | ||
56 | /* Data window available? */ | ||
57 | off_t right = sh->win_right; | ||
58 | |||
59 | /* Margins past end-of-file can still return true */ | ||
60 | if (right > disk_buf.filesize - margin) | ||
61 | right = disk_buf.filesize - margin; | ||
62 | |||
63 | return sh->win_left >= disk_buf.win_left && | ||
64 | right + margin <= disk_buf.win_right; | ||
65 | } | ||
66 | |||
67 | void dbuf_l2_init(struct dbuf_l2_cache *l2_p) | ||
68 | { | ||
69 | l2_p->addr = OFF_T_MAX; /* Mark as invalid */ | ||
70 | } | ||
71 | |||
52 | static int disk_buf_on_data_notify(struct stream_hdr *sh) | 72 | static int disk_buf_on_data_notify(struct stream_hdr *sh) |
53 | { | 73 | { |
54 | DEBUGF("DISK_BUF_DATA_NOTIFY: 0x%02X ", STR_FROM_HEADER(sh)->id); | 74 | DEBUGF("DISK_BUF_DATA_NOTIFY: 0x%02X ", STR_FROM_HEADER(sh)->id); |
@@ -519,17 +539,16 @@ static void disk_buf_thread(void) | |||
519 | } | 539 | } |
520 | 540 | ||
521 | /* Caches some data from the current file */ | 541 | /* Caches some data from the current file */ |
522 | static int disk_buf_probe(off_t start, size_t length, | 542 | static ssize_t disk_buf_probe(off_t start, size_t length, void **p) |
523 | void **p, size_t *outlen) | ||
524 | { | 543 | { |
525 | off_t end; | 544 | off_t end; |
526 | uint32_t tag, tag_end; | 545 | uint32_t tag, tag_end; |
527 | int page; | 546 | int page; |
528 | 547 | ||
529 | /* Can't read past end of file */ | 548 | /* Can't read past end of file */ |
530 | if (length > (size_t)(disk_buf.filesize - disk_buf.offset)) | 549 | if (length > (size_t)(disk_buf.filesize - start)) |
531 | { | 550 | { |
532 | length = disk_buf.filesize - disk_buf.offset; | 551 | length = disk_buf.filesize - start; |
533 | } | 552 | } |
534 | 553 | ||
535 | /* Can't cache more than the whole buffer size */ | 554 | /* Can't cache more than the whole buffer size */ |
@@ -559,11 +578,6 @@ static int disk_buf_probe(off_t start, size_t length, | |||
559 | + (start & DISK_BUF_PAGE_MASK); | 578 | + (start & DISK_BUF_PAGE_MASK); |
560 | } | 579 | } |
561 | 580 | ||
562 | if (outlen != NULL) | ||
563 | { | ||
564 | *outlen = length; | ||
565 | } | ||
566 | |||
567 | /* Obtain initial load point. If all data was cached, no message is sent | 581 | /* Obtain initial load point. If all data was cached, no message is sent |
568 | * otherwise begin on the first page that is not cached. Since we have to | 582 | * otherwise begin on the first page that is not cached. Since we have to |
569 | * send the message anyway, the buffering thread will determine what else | 583 | * send the message anyway, the buffering thread will determine what else |
@@ -573,12 +587,17 @@ static int disk_buf_probe(off_t start, size_t length, | |||
573 | if (disk_buf.cache[page] != tag) | 587 | if (disk_buf.cache[page] != tag) |
574 | { | 588 | { |
575 | static struct dbuf_range rng IBSS_ATTR; | 589 | static struct dbuf_range rng IBSS_ATTR; |
590 | intptr_t result; | ||
591 | |||
576 | DEBUGF("disk_buf: cache miss\n"); | 592 | DEBUGF("disk_buf: cache miss\n"); |
577 | rng.tag_start = tag; | 593 | rng.tag_start = tag; |
578 | rng.tag_end = tag_end; | 594 | rng.tag_end = tag_end; |
579 | rng.pg_start = page; | 595 | rng.pg_start = page; |
580 | return rb->queue_send(disk_buf.q, DISK_BUF_CACHE_RANGE, | 596 | |
581 | (intptr_t)&rng); | 597 | result = rb->queue_send(disk_buf.q, DISK_BUF_CACHE_RANGE, |
598 | (intptr_t)&rng); | ||
599 | |||
600 | return result == DISK_BUF_NOTIFY_OK ? (ssize_t)length : -1; | ||
582 | } | 601 | } |
583 | 602 | ||
584 | if (++page >= disk_buf.pgcount) | 603 | if (++page >= disk_buf.pgcount) |
@@ -586,35 +605,96 @@ static int disk_buf_probe(off_t start, size_t length, | |||
586 | } | 605 | } |
587 | while (++tag <= tag_end); | 606 | while (++tag <= tag_end); |
588 | 607 | ||
589 | return DISK_BUF_NOTIFY_OK; | 608 | return length; |
590 | } | 609 | } |
591 | 610 | ||
592 | /* Attempt to get a pointer to size bytes on the buffer. Returns real amount of | 611 | /* Attempt to get a pointer to size bytes on the buffer. Returns real amount of |
593 | * data available as well as the size of non-wrapped data after *p. */ | 612 | * data available as well as the size of non-wrapped data after *p. */ |
594 | ssize_t _disk_buf_getbuffer(size_t size, void **pp, void **pwrap, size_t *sizewrap) | 613 | ssize_t disk_buf_getbuffer(size_t size, void **pp, void **pwrap, |
614 | size_t *sizewrap) | ||
595 | { | 615 | { |
596 | disk_buf_lock(); | 616 | disk_buf_lock(); |
597 | 617 | ||
598 | if (disk_buf_probe(disk_buf.offset, size, pp, &size) == DISK_BUF_NOTIFY_OK) | 618 | size = disk_buf_probe(disk_buf.offset, size, pp); |
619 | |||
620 | if (size != (size_t)-1 && pwrap && sizewrap) | ||
599 | { | 621 | { |
600 | if (pwrap && sizewrap) | 622 | uint8_t *p = (uint8_t *)*pp; |
601 | { | ||
602 | uint8_t *p = (uint8_t *)*pp; | ||
603 | 623 | ||
604 | if (p + size > disk_buf.end + DISK_GUARDBUF_SIZE) | 624 | if (p + size > disk_buf.end + DISK_GUARDBUF_SIZE) |
605 | { | 625 | { |
606 | /* Return pointer to wraparound and the size of same */ | 626 | /* Return pointer to wraparound and the size of same */ |
607 | size_t nowrap = (disk_buf.end + DISK_GUARDBUF_SIZE) - p; | 627 | size_t nowrap = (disk_buf.end + DISK_GUARDBUF_SIZE) - p; |
608 | *pwrap = disk_buf.start + DISK_GUARDBUF_SIZE; | 628 | *pwrap = disk_buf.start + DISK_GUARDBUF_SIZE; |
609 | *sizewrap = size - nowrap; | 629 | *sizewrap = size - nowrap; |
610 | } | 630 | } |
611 | else | 631 | else |
612 | { | 632 | { |
613 | *pwrap = NULL; | 633 | *pwrap = NULL; |
614 | *sizewrap = 0; | 634 | *sizewrap = 0; |
615 | } | ||
616 | } | 635 | } |
617 | } | 636 | } |
637 | |||
638 | disk_buf_unlock(); | ||
639 | |||
640 | return size; | ||
641 | } | ||
642 | |||
643 | ssize_t disk_buf_getbuffer_l2(struct dbuf_l2_cache *l2, | ||
644 | size_t size, void **pp) | ||
645 | { | ||
646 | off_t offs; | ||
647 | off_t l2_addr; | ||
648 | size_t l2_size; | ||
649 | void *l2_p; | ||
650 | |||
651 | if (l2 == NULL) | ||
652 | { | ||
653 | /* Shouldn't have to check this normally */ | ||
654 | DEBUGF("disk_buf_getbuffer_l2: l2 = NULL!\n"); | ||
655 | } | ||
656 | |||
657 | if (size > DISK_BUF_L2_CACHE_SIZE) | ||
658 | { | ||
659 | /* Asking for too much; just go through L1 */ | ||
660 | return disk_buf_getbuffer(size, pp, NULL, NULL); | ||
661 | } | ||
662 | |||
663 | offs = disk_buf.offset; /* Other calls keep this within bounds */ | ||
664 | l2_addr = l2->addr; | ||
665 | |||
666 | if (offs >= l2_addr && offs < l2_addr + DISK_BUF_L2_CACHE_SIZE) | ||
667 | { | ||
668 | /* Data is in the local buffer */ | ||
669 | offs &= DISK_BUF_L2_CACHE_MASK; | ||
670 | |||
671 | *pp = l2->data + offs; | ||
672 | if (offs + size > l2->size) | ||
673 | size = l2->size - offs; /* Keep size within file limits */ | ||
674 | |||
675 | return size; | ||
676 | } | ||
677 | |||
678 | /* Have to probe main buffer */ | ||
679 | l2_addr = offs & ~DISK_BUF_L2_CACHE_MASK; | ||
680 | l2_size = DISK_BUF_L2_CACHE_SIZE*2; /* 2nd half is a guard buffer */ | ||
681 | |||
682 | disk_buf_lock(); | ||
683 | |||
684 | l2_size = disk_buf_probe(l2_addr, l2_size, &l2_p); | ||
685 | |||
686 | if (l2_size != (size_t)-1) | ||
687 | { | ||
688 | rb->memcpy(l2->data, l2_p, l2_size); | ||
689 | |||
690 | l2->addr = l2_addr; | ||
691 | l2->size = l2_size; | ||
692 | offs -= l2_addr; | ||
693 | |||
694 | *pp = l2->data + offs; | ||
695 | if (offs + size > l2->size) | ||
696 | size = l2->size - offs; /* Keep size within file limits */ | ||
697 | } | ||
618 | else | 698 | else |
619 | { | 699 | { |
620 | size = -1; | 700 | size = -1; |
@@ -625,6 +705,7 @@ ssize_t _disk_buf_getbuffer(size_t size, void **pp, void **pwrap, size_t *sizewr | |||
625 | return size; | 705 | return size; |
626 | } | 706 | } |
627 | 707 | ||
708 | |||
628 | /* Read size bytes of data into a buffer - advances the buffer pointer | 709 | /* Read size bytes of data into a buffer - advances the buffer pointer |
629 | * and returns the real size read. */ | 710 | * and returns the real size read. */ |
630 | ssize_t disk_buf_read(void *buffer, size_t size) | 711 | ssize_t disk_buf_read(void *buffer, size_t size) |
@@ -633,8 +714,9 @@ ssize_t disk_buf_read(void *buffer, size_t size) | |||
633 | 714 | ||
634 | disk_buf_lock(); | 715 | disk_buf_lock(); |
635 | 716 | ||
636 | if (disk_buf_probe(disk_buf.offset, size, PUN_PTR(void **, &p), | 717 | size = disk_buf_probe(disk_buf.offset, size, (void **)&p); |
637 | &size) == DISK_BUF_NOTIFY_OK) | 718 | |
719 | if (size != (size_t)-1) | ||
638 | { | 720 | { |
639 | if (p + size > disk_buf.end + DISK_GUARDBUF_SIZE) | 721 | if (p + size > disk_buf.end + DISK_GUARDBUF_SIZE) |
640 | { | 722 | { |
@@ -652,10 +734,6 @@ ssize_t disk_buf_read(void *buffer, size_t size) | |||
652 | 734 | ||
653 | disk_buf.offset += size; | 735 | disk_buf.offset += size; |
654 | } | 736 | } |
655 | else | ||
656 | { | ||
657 | size = -1; | ||
658 | } | ||
659 | 737 | ||
660 | disk_buf_unlock(); | 738 | disk_buf_unlock(); |
661 | 739 | ||
@@ -713,7 +791,7 @@ ssize_t disk_buf_prepare_streaming(off_t pos, size_t len) | |||
713 | DEBUGF("prepare streaming:\n pos:%ld len:%zu\n", pos, len); | 791 | DEBUGF("prepare streaming:\n pos:%ld len:%zu\n", pos, len); |
714 | 792 | ||
715 | pos = disk_buf_lseek(pos, SEEK_SET); | 793 | pos = disk_buf_lseek(pos, SEEK_SET); |
716 | disk_buf_probe(pos, len, NULL, &len); | 794 | len = disk_buf_probe(pos, len, NULL); |
717 | 795 | ||
718 | DEBUGF(" probe done: pos:%ld len:%zu\n", pos, len); | 796 | DEBUGF(" probe done: pos:%ld len:%zu\n", pos, len); |
719 | 797 | ||
diff --git a/apps/plugins/mpegplayer/disk_buf.h b/apps/plugins/mpegplayer/disk_buf.h index e16939a92e..a5a10cfe69 100644 --- a/apps/plugins/mpegplayer/disk_buf.h +++ b/apps/plugins/mpegplayer/disk_buf.h | |||
@@ -23,6 +23,10 @@ | |||
23 | #ifndef DISK_BUF_H | 23 | #ifndef DISK_BUF_H |
24 | #define DISK_BUF_H | 24 | #define DISK_BUF_H |
25 | 25 | ||
26 | #ifndef OFF_T_MAX | ||
27 | #define OFF_T_MAX (~(off_t)1 << (sizeof (off_t)*8 - 1)) | ||
28 | #endif | ||
29 | |||
26 | #define DISK_BUF_PAGE_SHIFT 15 /* 32KB cache lines */ | 30 | #define DISK_BUF_PAGE_SHIFT 15 /* 32KB cache lines */ |
27 | #define DISK_BUF_PAGE_SIZE (1 << DISK_BUF_PAGE_SHIFT) | 31 | #define DISK_BUF_PAGE_SIZE (1 << DISK_BUF_PAGE_SHIFT) |
28 | #define DISK_BUF_PAGE_MASK (DISK_BUF_PAGE_SIZE-1) | 32 | #define DISK_BUF_PAGE_MASK (DISK_BUF_PAGE_SIZE-1) |
@@ -58,6 +62,19 @@ struct dbuf_range | |||
58 | int pg_start; | 62 | int pg_start; |
59 | }; | 63 | }; |
60 | 64 | ||
65 | #define DISK_BUF_L2_CACHE_SHIFT 6 | ||
66 | #define DISK_BUF_L2_CACHE_SIZE (1 << DISK_BUF_L2_CACHE_SHIFT) | ||
67 | #define DISK_BUF_L2_CACHE_MASK (DISK_BUF_L2_CACHE_SIZE-1) | ||
68 | |||
69 | struct dbuf_l2_cache | ||
70 | { | ||
71 | off_t addr; /* L2 file offset */ | ||
72 | size_t size; /* Real size */ | ||
73 | uint8_t data[DISK_BUF_L2_CACHE_SIZE*2]; /* Local data and guard */ | ||
74 | }; | ||
75 | |||
76 | void dbuf_l2_init(struct dbuf_l2_cache *l2_p); | ||
77 | |||
61 | /* This object is an extension of the stream manager and handles some | 78 | /* This object is an extension of the stream manager and handles some |
62 | * playback events as well as buffering */ | 79 | * playback events as well as buffering */ |
63 | struct disk_buf | 80 | struct disk_buf |
@@ -88,20 +105,8 @@ struct disk_buf | |||
88 | 105 | ||
89 | extern struct disk_buf disk_buf SHAREDBSS_ATTR; | 106 | extern struct disk_buf disk_buf SHAREDBSS_ATTR; |
90 | 107 | ||
91 | static inline bool disk_buf_is_data_ready(struct stream_hdr *sh, | 108 | struct stream_hdr; |
92 | ssize_t margin) | 109 | bool disk_buf_is_data_ready(struct stream_hdr *sh, ssize_t margin); |
93 | { | ||
94 | /* Data window available? */ | ||
95 | off_t right = sh->win_right; | ||
96 | |||
97 | /* Margins past end-of-file can still return true */ | ||
98 | if (right > disk_buf.filesize - margin) | ||
99 | right = disk_buf.filesize - margin; | ||
100 | |||
101 | return sh->win_left >= disk_buf.win_left && | ||
102 | right + margin <= disk_buf.win_right; | ||
103 | } | ||
104 | |||
105 | 110 | ||
106 | bool disk_buf_init(void); | 111 | bool disk_buf_init(void); |
107 | void disk_buf_exit(void); | 112 | void disk_buf_exit(void); |
@@ -111,11 +116,10 @@ static inline int disk_buf_status(void) | |||
111 | 116 | ||
112 | int disk_buf_open(const char *filename); | 117 | int disk_buf_open(const char *filename); |
113 | void disk_buf_close(void); | 118 | void disk_buf_close(void); |
114 | ssize_t _disk_buf_getbuffer(size_t size, void **pp, void **pwrap, | 119 | ssize_t disk_buf_getbuffer(size_t size, void **pp, void **pwrap, |
115 | size_t *sizewrap); | 120 | size_t *sizewrap); |
116 | #define disk_buf_getbuffer(size, pp, pwrap, sizewrap) \ | 121 | ssize_t disk_buf_getbuffer_l2(struct dbuf_l2_cache *l2, |
117 | _disk_buf_getbuffer((size), PUN_PTR(void **, (pp)), \ | 122 | size_t size, void **pp); |
118 | PUN_PTR(void **, (pwrap)), (sizewrap)) | ||
119 | ssize_t disk_buf_read(void *buffer, size_t size); | 123 | ssize_t disk_buf_read(void *buffer, size_t size); |
120 | ssize_t disk_buf_lseek(off_t offset, int whence); | 124 | ssize_t disk_buf_lseek(off_t offset, int whence); |
121 | 125 | ||
diff --git a/apps/plugins/mpegplayer/mpeg_misc.c b/apps/plugins/mpegplayer/mpeg_misc.c index fd564a49c3..8e6ccf650f 100644 --- a/apps/plugins/mpegplayer/mpeg_misc.c +++ b/apps/plugins/mpegplayer/mpeg_misc.c | |||
@@ -25,6 +25,12 @@ | |||
25 | 25 | ||
26 | /** Streams **/ | 26 | /** Streams **/ |
27 | 27 | ||
28 | /* Initializes the cursor */ | ||
29 | void stream_scan_init(struct stream_scan *sk) | ||
30 | { | ||
31 | dbuf_l2_init(&sk->l2); | ||
32 | } | ||
33 | |||
28 | /* Ensures direction is -1 or 1 and margin is properly initialized */ | 34 | /* Ensures direction is -1 or 1 and margin is properly initialized */ |
29 | void stream_scan_normalize(struct stream_scan *sk) | 35 | void stream_scan_normalize(struct stream_scan *sk) |
30 | { | 36 | { |
diff --git a/apps/plugins/mpegplayer/mpeg_misc.h b/apps/plugins/mpegplayer/mpeg_misc.h index 7bac7eb255..5f60193d52 100644 --- a/apps/plugins/mpegplayer/mpeg_misc.h +++ b/apps/plugins/mpegplayer/mpeg_misc.h | |||
@@ -28,6 +28,8 @@ | |||
28 | #define ALIGNED_ATTR(x) __attribute__((aligned(x))) | 28 | #define ALIGNED_ATTR(x) __attribute__((aligned(x))) |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #include "disk_buf.h" | ||
32 | |||
31 | /* Generic states for when things are too simple to care about naming them */ | 33 | /* Generic states for when things are too simple to care about naming them */ |
32 | enum state_enum | 34 | enum state_enum |
33 | { | 35 | { |
@@ -158,11 +160,15 @@ struct stream_scan | |||
158 | off_t dir; /* Direction - >= 0; forward, < 0 backward */ | 160 | off_t dir; /* Direction - >= 0; forward, < 0 backward */ |
159 | ssize_t margin; /* Used by function to track margin between position and data end */ | 161 | ssize_t margin; /* Used by function to track margin between position and data end */ |
160 | intptr_t data; /* */ | 162 | intptr_t data; /* */ |
163 | struct dbuf_l2_cache l2; | ||
161 | }; | 164 | }; |
162 | 165 | ||
163 | #define SSCAN_REVERSE (-1) | 166 | #define SSCAN_REVERSE (-1) |
164 | #define SSCAN_FORWARD 1 | 167 | #define SSCAN_FORWARD 1 |
165 | 168 | ||
169 | /* Initializes the cursor */ | ||
170 | void stream_scan_init(struct stream_scan *sk); | ||
171 | |||
166 | /* Ensures direction is -1 or 1 and margin is properly initialized */ | 172 | /* Ensures direction is -1 or 1 and margin is properly initialized */ |
167 | void stream_scan_normalize(struct stream_scan *sk); | 173 | void stream_scan_normalize(struct stream_scan *sk); |
168 | 174 | ||
diff --git a/apps/plugins/mpegplayer/mpeg_parser.c b/apps/plugins/mpegplayer/mpeg_parser.c index 714f38ac09..f21292abd5 100644 --- a/apps/plugins/mpegplayer/mpeg_parser.c +++ b/apps/plugins/mpegplayer/mpeg_parser.c | |||
@@ -99,7 +99,7 @@ uint8_t * mpeg_parser_scan_start_code(struct stream_scan *sk, uint32_t code) | |||
99 | { | 99 | { |
100 | uint8_t *p; | 100 | uint8_t *p; |
101 | off_t pos = disk_buf_lseek(sk->pos, SEEK_SET); | 101 | off_t pos = disk_buf_lseek(sk->pos, SEEK_SET); |
102 | ssize_t len = disk_buf_getbuffer(4, &p, NULL, NULL); | 102 | ssize_t len = disk_buf_getbuffer_l2(&sk->l2, 4, (void **)&p); |
103 | 103 | ||
104 | if (pos < 0 || len < 4) | 104 | if (pos < 0 || len < 4) |
105 | break; | 105 | break; |
@@ -131,7 +131,7 @@ unsigned mpeg_parser_scan_pes(struct stream_scan *sk) | |||
131 | { | 131 | { |
132 | uint8_t *p; | 132 | uint8_t *p; |
133 | off_t pos = disk_buf_lseek(sk->pos, SEEK_SET); | 133 | off_t pos = disk_buf_lseek(sk->pos, SEEK_SET); |
134 | ssize_t len = disk_buf_getbuffer(4, &p, NULL, NULL); | 134 | ssize_t len = disk_buf_getbuffer_l2(&sk->l2, 4, (void **)&p); |
135 | 135 | ||
136 | if (pos < 0 || len < 4) | 136 | if (pos < 0 || len < 4) |
137 | break; | 137 | break; |
@@ -192,7 +192,7 @@ uint32_t mpeg_parser_scan_pts(struct stream_scan *sk, unsigned id) | |||
192 | { | 192 | { |
193 | uint8_t *p; | 193 | uint8_t *p; |
194 | off_t pos = disk_buf_lseek(sk->pos, SEEK_SET); | 194 | off_t pos = disk_buf_lseek(sk->pos, SEEK_SET); |
195 | ssize_t len = disk_buf_getbuffer(35, &p, NULL, NULL); | 195 | ssize_t len = disk_buf_getbuffer_l2(&sk->l2, 30, (void **)&p); |
196 | 196 | ||
197 | if (pos < 0 || len < 4) | 197 | if (pos < 0 || len < 4) |
198 | break; | 198 | break; |
@@ -201,7 +201,7 @@ uint32_t mpeg_parser_scan_pts(struct stream_scan *sk, unsigned id) | |||
201 | { | 201 | { |
202 | uint8_t *h = p; | 202 | uint8_t *h = p; |
203 | 203 | ||
204 | if (sk->margin < 6) | 204 | if (sk->margin < 7) |
205 | { | 205 | { |
206 | /* Insufficient data */ | 206 | /* Insufficient data */ |
207 | } | 207 | } |
@@ -215,29 +215,33 @@ uint32_t mpeg_parser_scan_pts(struct stream_scan *sk, unsigned id) | |||
215 | } | 215 | } |
216 | else /* mpeg1 */ | 216 | else /* mpeg1 */ |
217 | { | 217 | { |
218 | ssize_t l = 7; | 218 | ssize_t l = 6; |
219 | ssize_t margin = sk->margin; | 219 | ssize_t margin = sk->margin; |
220 | 220 | ||
221 | /* Skip stuffing_byte */ | 221 | /* Skip stuffing_byte */ |
222 | while (h[l - 1] == 0xff && ++l <= 23) | 222 | while (margin > 7 && h[l] == 0xff && ++l <= 22) |
223 | --margin; | 223 | --margin; |
224 | 224 | ||
225 | if ((h[l - 1] & 0xc0) == 0x40) | 225 | if (margin >= 7) |
226 | { | 226 | { |
227 | /* Skip STD_buffer_scale and STD_buffer_size */ | 227 | if ((h[l] & 0xc0) == 0x40) |
228 | margin -= 2; | 228 | { |
229 | l += 2; | 229 | /* Skip STD_buffer_scale and STD_buffer_size */ |
230 | } | 230 | margin -= 2; |
231 | 231 | l += 2; | |
232 | if (margin >= 4) | 232 | } |
233 | { | ||
234 | /* header points to the mpeg1 pes header */ | ||
235 | h += l; | ||
236 | 233 | ||
237 | if ((h[-1] & 0xe0) == 0x20) | 234 | if (margin >= 5) |
238 | { | 235 | { |
239 | sk->data = (h + 4) - p; | 236 | /* Header points to the mpeg1 pes header */ |
240 | return read_pts(h, -1); | 237 | h += l; |
238 | |||
239 | if ((h[0] & 0xe0) == 0x20) | ||
240 | { | ||
241 | /* PTS or PTS_DTS indicated */ | ||
242 | sk->data = (h + 5) - p; | ||
243 | return read_pts(h, 0); | ||
244 | } | ||
241 | } | 245 | } |
242 | } | 246 | } |
243 | } | 247 | } |
@@ -357,6 +361,8 @@ static off_t mpeg_parser_seek_PTS(uint32_t time, unsigned id) | |||
357 | enum state_enum state = STATE0; | 361 | enum state_enum state = STATE0; |
358 | struct stream_scan sk; | 362 | struct stream_scan sk; |
359 | 363 | ||
364 | stream_scan_init(&sk); | ||
365 | |||
360 | /* Initial estimate taken from average bitrate - later interpolations are | 366 | /* Initial estimate taken from average bitrate - later interpolations are |
361 | * taken similarly based on the remaining file interval */ | 367 | * taken similarly based on the remaining file interval */ |
362 | pos_new = muldiv_uint32(time - time_left, pos_right - pos_left, | 368 | pos_new = muldiv_uint32(time - time_left, pos_right - pos_left, |
@@ -564,6 +570,8 @@ static bool prepare_image(uint32_t time) | |||
564 | int tries; | 570 | int tries; |
565 | int result; | 571 | int result; |
566 | 572 | ||
573 | stream_scan_init(&sk); | ||
574 | |||
567 | if (!str_send_msg(&video_str, STREAM_NEEDS_SYNC, time)) | 575 | if (!str_send_msg(&video_str, STREAM_NEEDS_SYNC, time)) |
568 | { | 576 | { |
569 | DEBUGF("Image was ready\n"); | 577 | DEBUGF("Image was ready\n"); |
@@ -734,7 +742,7 @@ static int parse_demux(struct stream *str, enum stream_parse_mode type) | |||
734 | str->hdr.pos = disk_buf_lseek(str->hdr.pos, SEEK_SET); | 742 | str->hdr.pos = disk_buf_lseek(str->hdr.pos, SEEK_SET); |
735 | 743 | ||
736 | if (str->hdr.pos < 0 || str->hdr.pos >= str->hdr.limit || | 744 | if (str->hdr.pos < 0 || str->hdr.pos >= str->hdr.limit || |
737 | disk_buf_getbuffer(MIN_BUFAHEAD, &p, NULL, NULL) <= 0) | 745 | disk_buf_getbuffer(MIN_BUFAHEAD, (void **)&p, NULL, NULL) <= 0) |
738 | { | 746 | { |
739 | str_end_of_stream(str); | 747 | str_end_of_stream(str); |
740 | return STREAM_DATA_END; | 748 | return STREAM_DATA_END; |
@@ -1009,7 +1017,7 @@ static int parse_elementary(struct stream *str, enum stream_parse_mode type) | |||
1009 | 1017 | ||
1010 | case STREAM_PM_RANDOM_ACCESS: | 1018 | case STREAM_PM_RANDOM_ACCESS: |
1011 | str->hdr.pos = disk_buf_lseek(str->hdr.pos, SEEK_SET); | 1019 | str->hdr.pos = disk_buf_lseek(str->hdr.pos, SEEK_SET); |
1012 | len = disk_buf_getbuffer(DISK_BUF_PAGE_SIZE, &p, NULL, NULL); | 1020 | len = disk_buf_getbuffer(DISK_BUF_PAGE_SIZE, (void **)&p, NULL, NULL); |
1013 | 1021 | ||
1014 | if (len <= 0 || str->hdr.pos < 0 || str->hdr.pos >= str->hdr.limit) | 1022 | if (len <= 0 || str->hdr.pos < 0 || str->hdr.pos >= str->hdr.limit) |
1015 | { | 1023 | { |