forked from len0rd/rockbox
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
This commit is contained in:
parent
caa4f54e42
commit
b197c3b0d6
5 changed files with 180 additions and 78 deletions
|
@ -49,6 +49,26 @@ static inline void disk_buf_on_clear_data_notify(struct stream_hdr *sh)
|
||||||
list_remove_item(&sh->nf);
|
list_remove_item(&sh->nf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool disk_buf_is_data_ready(struct stream_hdr *sh,
|
||||||
|
ssize_t margin)
|
||||||
|
{
|
||||||
|
/* Data window available? */
|
||||||
|
off_t right = sh->win_right;
|
||||||
|
|
||||||
|
/* Margins past end-of-file can still return true */
|
||||||
|
if (right > disk_buf.filesize - margin)
|
||||||
|
right = disk_buf.filesize - margin;
|
||||||
|
|
||||||
|
return sh->win_left >= disk_buf.win_left &&
|
||||||
|
right + margin <= disk_buf.win_right;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbuf_l2_init(struct dbuf_l2_cache *l2_p)
|
||||||
|
{
|
||||||
|
l2_p->addr = OFF_T_MAX; /* Mark as invalid */
|
||||||
|
}
|
||||||
|
|
||||||
static int disk_buf_on_data_notify(struct stream_hdr *sh)
|
static int disk_buf_on_data_notify(struct stream_hdr *sh)
|
||||||
{
|
{
|
||||||
DEBUGF("DISK_BUF_DATA_NOTIFY: 0x%02X ", STR_FROM_HEADER(sh)->id);
|
DEBUGF("DISK_BUF_DATA_NOTIFY: 0x%02X ", STR_FROM_HEADER(sh)->id);
|
||||||
|
@ -519,17 +539,16 @@ static void disk_buf_thread(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Caches some data from the current file */
|
/* Caches some data from the current file */
|
||||||
static int disk_buf_probe(off_t start, size_t length,
|
static ssize_t disk_buf_probe(off_t start, size_t length, void **p)
|
||||||
void **p, size_t *outlen)
|
|
||||||
{
|
{
|
||||||
off_t end;
|
off_t end;
|
||||||
uint32_t tag, tag_end;
|
uint32_t tag, tag_end;
|
||||||
int page;
|
int page;
|
||||||
|
|
||||||
/* Can't read past end of file */
|
/* Can't read past end of file */
|
||||||
if (length > (size_t)(disk_buf.filesize - disk_buf.offset))
|
if (length > (size_t)(disk_buf.filesize - start))
|
||||||
{
|
{
|
||||||
length = disk_buf.filesize - disk_buf.offset;
|
length = disk_buf.filesize - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can't cache more than the whole buffer size */
|
/* Can't cache more than the whole buffer size */
|
||||||
|
@ -559,11 +578,6 @@ static int disk_buf_probe(off_t start, size_t length,
|
||||||
+ (start & DISK_BUF_PAGE_MASK);
|
+ (start & DISK_BUF_PAGE_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outlen != NULL)
|
|
||||||
{
|
|
||||||
*outlen = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Obtain initial load point. If all data was cached, no message is sent
|
/* Obtain initial load point. If all data was cached, no message is sent
|
||||||
* otherwise begin on the first page that is not cached. Since we have to
|
* otherwise begin on the first page that is not cached. Since we have to
|
||||||
* send the message anyway, the buffering thread will determine what else
|
* 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,
|
||||||
if (disk_buf.cache[page] != tag)
|
if (disk_buf.cache[page] != tag)
|
||||||
{
|
{
|
||||||
static struct dbuf_range rng IBSS_ATTR;
|
static struct dbuf_range rng IBSS_ATTR;
|
||||||
|
intptr_t result;
|
||||||
|
|
||||||
DEBUGF("disk_buf: cache miss\n");
|
DEBUGF("disk_buf: cache miss\n");
|
||||||
rng.tag_start = tag;
|
rng.tag_start = tag;
|
||||||
rng.tag_end = tag_end;
|
rng.tag_end = tag_end;
|
||||||
rng.pg_start = page;
|
rng.pg_start = page;
|
||||||
return rb->queue_send(disk_buf.q, DISK_BUF_CACHE_RANGE,
|
|
||||||
(intptr_t)&rng);
|
result = rb->queue_send(disk_buf.q, DISK_BUF_CACHE_RANGE,
|
||||||
|
(intptr_t)&rng);
|
||||||
|
|
||||||
|
return result == DISK_BUF_NOTIFY_OK ? (ssize_t)length : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++page >= disk_buf.pgcount)
|
if (++page >= disk_buf.pgcount)
|
||||||
|
@ -586,34 +605,95 @@ static int disk_buf_probe(off_t start, size_t length,
|
||||||
}
|
}
|
||||||
while (++tag <= tag_end);
|
while (++tag <= tag_end);
|
||||||
|
|
||||||
return DISK_BUF_NOTIFY_OK;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to get a pointer to size bytes on the buffer. Returns real amount of
|
/* Attempt to get a pointer to size bytes on the buffer. Returns real amount of
|
||||||
* data available as well as the size of non-wrapped data after *p. */
|
* data available as well as the size of non-wrapped data after *p. */
|
||||||
ssize_t _disk_buf_getbuffer(size_t size, void **pp, void **pwrap, size_t *sizewrap)
|
ssize_t disk_buf_getbuffer(size_t size, void **pp, void **pwrap,
|
||||||
|
size_t *sizewrap)
|
||||||
{
|
{
|
||||||
disk_buf_lock();
|
disk_buf_lock();
|
||||||
|
|
||||||
if (disk_buf_probe(disk_buf.offset, size, pp, &size) == DISK_BUF_NOTIFY_OK)
|
size = disk_buf_probe(disk_buf.offset, size, pp);
|
||||||
{
|
|
||||||
if (pwrap && sizewrap)
|
|
||||||
{
|
|
||||||
uint8_t *p = (uint8_t *)*pp;
|
|
||||||
|
|
||||||
if (p + size > disk_buf.end + DISK_GUARDBUF_SIZE)
|
if (size != (size_t)-1 && pwrap && sizewrap)
|
||||||
{
|
{
|
||||||
/* Return pointer to wraparound and the size of same */
|
uint8_t *p = (uint8_t *)*pp;
|
||||||
size_t nowrap = (disk_buf.end + DISK_GUARDBUF_SIZE) - p;
|
|
||||||
*pwrap = disk_buf.start + DISK_GUARDBUF_SIZE;
|
if (p + size > disk_buf.end + DISK_GUARDBUF_SIZE)
|
||||||
*sizewrap = size - nowrap;
|
{
|
||||||
}
|
/* Return pointer to wraparound and the size of same */
|
||||||
else
|
size_t nowrap = (disk_buf.end + DISK_GUARDBUF_SIZE) - p;
|
||||||
{
|
*pwrap = disk_buf.start + DISK_GUARDBUF_SIZE;
|
||||||
*pwrap = NULL;
|
*sizewrap = size - nowrap;
|
||||||
*sizewrap = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pwrap = NULL;
|
||||||
|
*sizewrap = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
disk_buf_unlock();
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t disk_buf_getbuffer_l2(struct dbuf_l2_cache *l2,
|
||||||
|
size_t size, void **pp)
|
||||||
|
{
|
||||||
|
off_t offs;
|
||||||
|
off_t l2_addr;
|
||||||
|
size_t l2_size;
|
||||||
|
void *l2_p;
|
||||||
|
|
||||||
|
if (l2 == NULL)
|
||||||
|
{
|
||||||
|
/* Shouldn't have to check this normally */
|
||||||
|
DEBUGF("disk_buf_getbuffer_l2: l2 = NULL!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size > DISK_BUF_L2_CACHE_SIZE)
|
||||||
|
{
|
||||||
|
/* Asking for too much; just go through L1 */
|
||||||
|
return disk_buf_getbuffer(size, pp, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
offs = disk_buf.offset; /* Other calls keep this within bounds */
|
||||||
|
l2_addr = l2->addr;
|
||||||
|
|
||||||
|
if (offs >= l2_addr && offs < l2_addr + DISK_BUF_L2_CACHE_SIZE)
|
||||||
|
{
|
||||||
|
/* Data is in the local buffer */
|
||||||
|
offs &= DISK_BUF_L2_CACHE_MASK;
|
||||||
|
|
||||||
|
*pp = l2->data + offs;
|
||||||
|
if (offs + size > l2->size)
|
||||||
|
size = l2->size - offs; /* Keep size within file limits */
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Have to probe main buffer */
|
||||||
|
l2_addr = offs & ~DISK_BUF_L2_CACHE_MASK;
|
||||||
|
l2_size = DISK_BUF_L2_CACHE_SIZE*2; /* 2nd half is a guard buffer */
|
||||||
|
|
||||||
|
disk_buf_lock();
|
||||||
|
|
||||||
|
l2_size = disk_buf_probe(l2_addr, l2_size, &l2_p);
|
||||||
|
|
||||||
|
if (l2_size != (size_t)-1)
|
||||||
|
{
|
||||||
|
rb->memcpy(l2->data, l2_p, l2_size);
|
||||||
|
|
||||||
|
l2->addr = l2_addr;
|
||||||
|
l2->size = l2_size;
|
||||||
|
offs -= l2_addr;
|
||||||
|
|
||||||
|
*pp = l2->data + offs;
|
||||||
|
if (offs + size > l2->size)
|
||||||
|
size = l2->size - offs; /* Keep size within file limits */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -625,6 +705,7 @@ ssize_t _disk_buf_getbuffer(size_t size, void **pp, void **pwrap, size_t *sizewr
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Read size bytes of data into a buffer - advances the buffer pointer
|
/* Read size bytes of data into a buffer - advances the buffer pointer
|
||||||
* and returns the real size read. */
|
* and returns the real size read. */
|
||||||
ssize_t disk_buf_read(void *buffer, size_t size)
|
ssize_t disk_buf_read(void *buffer, size_t size)
|
||||||
|
@ -633,8 +714,9 @@ ssize_t disk_buf_read(void *buffer, size_t size)
|
||||||
|
|
||||||
disk_buf_lock();
|
disk_buf_lock();
|
||||||
|
|
||||||
if (disk_buf_probe(disk_buf.offset, size, PUN_PTR(void **, &p),
|
size = disk_buf_probe(disk_buf.offset, size, (void **)&p);
|
||||||
&size) == DISK_BUF_NOTIFY_OK)
|
|
||||||
|
if (size != (size_t)-1)
|
||||||
{
|
{
|
||||||
if (p + size > disk_buf.end + DISK_GUARDBUF_SIZE)
|
if (p + size > disk_buf.end + DISK_GUARDBUF_SIZE)
|
||||||
{
|
{
|
||||||
|
@ -652,10 +734,6 @@ ssize_t disk_buf_read(void *buffer, size_t size)
|
||||||
|
|
||||||
disk_buf.offset += size;
|
disk_buf.offset += size;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
size = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
disk_buf_unlock();
|
disk_buf_unlock();
|
||||||
|
|
||||||
|
@ -713,7 +791,7 @@ ssize_t disk_buf_prepare_streaming(off_t pos, size_t len)
|
||||||
DEBUGF("prepare streaming:\n pos:%ld len:%zu\n", pos, len);
|
DEBUGF("prepare streaming:\n pos:%ld len:%zu\n", pos, len);
|
||||||
|
|
||||||
pos = disk_buf_lseek(pos, SEEK_SET);
|
pos = disk_buf_lseek(pos, SEEK_SET);
|
||||||
disk_buf_probe(pos, len, NULL, &len);
|
len = disk_buf_probe(pos, len, NULL);
|
||||||
|
|
||||||
DEBUGF(" probe done: pos:%ld len:%zu\n", pos, len);
|
DEBUGF(" probe done: pos:%ld len:%zu\n", pos, len);
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
#ifndef DISK_BUF_H
|
#ifndef DISK_BUF_H
|
||||||
#define DISK_BUF_H
|
#define DISK_BUF_H
|
||||||
|
|
||||||
|
#ifndef OFF_T_MAX
|
||||||
|
#define OFF_T_MAX (~(off_t)1 << (sizeof (off_t)*8 - 1))
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DISK_BUF_PAGE_SHIFT 15 /* 32KB cache lines */
|
#define DISK_BUF_PAGE_SHIFT 15 /* 32KB cache lines */
|
||||||
#define DISK_BUF_PAGE_SIZE (1 << DISK_BUF_PAGE_SHIFT)
|
#define DISK_BUF_PAGE_SIZE (1 << DISK_BUF_PAGE_SHIFT)
|
||||||
#define DISK_BUF_PAGE_MASK (DISK_BUF_PAGE_SIZE-1)
|
#define DISK_BUF_PAGE_MASK (DISK_BUF_PAGE_SIZE-1)
|
||||||
|
@ -58,6 +62,19 @@ struct dbuf_range
|
||||||
int pg_start;
|
int pg_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DISK_BUF_L2_CACHE_SHIFT 6
|
||||||
|
#define DISK_BUF_L2_CACHE_SIZE (1 << DISK_BUF_L2_CACHE_SHIFT)
|
||||||
|
#define DISK_BUF_L2_CACHE_MASK (DISK_BUF_L2_CACHE_SIZE-1)
|
||||||
|
|
||||||
|
struct dbuf_l2_cache
|
||||||
|
{
|
||||||
|
off_t addr; /* L2 file offset */
|
||||||
|
size_t size; /* Real size */
|
||||||
|
uint8_t data[DISK_BUF_L2_CACHE_SIZE*2]; /* Local data and guard */
|
||||||
|
};
|
||||||
|
|
||||||
|
void dbuf_l2_init(struct dbuf_l2_cache *l2_p);
|
||||||
|
|
||||||
/* This object is an extension of the stream manager and handles some
|
/* This object is an extension of the stream manager and handles some
|
||||||
* playback events as well as buffering */
|
* playback events as well as buffering */
|
||||||
struct disk_buf
|
struct disk_buf
|
||||||
|
@ -88,20 +105,8 @@ struct disk_buf
|
||||||
|
|
||||||
extern struct disk_buf disk_buf SHAREDBSS_ATTR;
|
extern struct disk_buf disk_buf SHAREDBSS_ATTR;
|
||||||
|
|
||||||
static inline bool disk_buf_is_data_ready(struct stream_hdr *sh,
|
struct stream_hdr;
|
||||||
ssize_t margin)
|
bool disk_buf_is_data_ready(struct stream_hdr *sh, ssize_t margin);
|
||||||
{
|
|
||||||
/* Data window available? */
|
|
||||||
off_t right = sh->win_right;
|
|
||||||
|
|
||||||
/* Margins past end-of-file can still return true */
|
|
||||||
if (right > disk_buf.filesize - margin)
|
|
||||||
right = disk_buf.filesize - margin;
|
|
||||||
|
|
||||||
return sh->win_left >= disk_buf.win_left &&
|
|
||||||
right + margin <= disk_buf.win_right;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool disk_buf_init(void);
|
bool disk_buf_init(void);
|
||||||
void disk_buf_exit(void);
|
void disk_buf_exit(void);
|
||||||
|
@ -111,11 +116,10 @@ static inline int disk_buf_status(void)
|
||||||
|
|
||||||
int disk_buf_open(const char *filename);
|
int disk_buf_open(const char *filename);
|
||||||
void disk_buf_close(void);
|
void disk_buf_close(void);
|
||||||
ssize_t _disk_buf_getbuffer(size_t size, void **pp, void **pwrap,
|
ssize_t disk_buf_getbuffer(size_t size, void **pp, void **pwrap,
|
||||||
size_t *sizewrap);
|
size_t *sizewrap);
|
||||||
#define disk_buf_getbuffer(size, pp, pwrap, sizewrap) \
|
ssize_t disk_buf_getbuffer_l2(struct dbuf_l2_cache *l2,
|
||||||
_disk_buf_getbuffer((size), PUN_PTR(void **, (pp)), \
|
size_t size, void **pp);
|
||||||
PUN_PTR(void **, (pwrap)), (sizewrap))
|
|
||||||
ssize_t disk_buf_read(void *buffer, size_t size);
|
ssize_t disk_buf_read(void *buffer, size_t size);
|
||||||
ssize_t disk_buf_lseek(off_t offset, int whence);
|
ssize_t disk_buf_lseek(off_t offset, int whence);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,12 @@
|
||||||
|
|
||||||
/** Streams **/
|
/** Streams **/
|
||||||
|
|
||||||
|
/* Initializes the cursor */
|
||||||
|
void stream_scan_init(struct stream_scan *sk)
|
||||||
|
{
|
||||||
|
dbuf_l2_init(&sk->l2);
|
||||||
|
}
|
||||||
|
|
||||||
/* Ensures direction is -1 or 1 and margin is properly initialized */
|
/* Ensures direction is -1 or 1 and margin is properly initialized */
|
||||||
void stream_scan_normalize(struct stream_scan *sk)
|
void stream_scan_normalize(struct stream_scan *sk)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#define ALIGNED_ATTR(x) __attribute__((aligned(x)))
|
#define ALIGNED_ATTR(x) __attribute__((aligned(x)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "disk_buf.h"
|
||||||
|
|
||||||
/* Generic states for when things are too simple to care about naming them */
|
/* Generic states for when things are too simple to care about naming them */
|
||||||
enum state_enum
|
enum state_enum
|
||||||
{
|
{
|
||||||
|
@ -158,11 +160,15 @@ struct stream_scan
|
||||||
off_t dir; /* Direction - >= 0; forward, < 0 backward */
|
off_t dir; /* Direction - >= 0; forward, < 0 backward */
|
||||||
ssize_t margin; /* Used by function to track margin between position and data end */
|
ssize_t margin; /* Used by function to track margin between position and data end */
|
||||||
intptr_t data; /* */
|
intptr_t data; /* */
|
||||||
|
struct dbuf_l2_cache l2;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SSCAN_REVERSE (-1)
|
#define SSCAN_REVERSE (-1)
|
||||||
#define SSCAN_FORWARD 1
|
#define SSCAN_FORWARD 1
|
||||||
|
|
||||||
|
/* Initializes the cursor */
|
||||||
|
void stream_scan_init(struct stream_scan *sk);
|
||||||
|
|
||||||
/* Ensures direction is -1 or 1 and margin is properly initialized */
|
/* Ensures direction is -1 or 1 and margin is properly initialized */
|
||||||
void stream_scan_normalize(struct stream_scan *sk);
|
void stream_scan_normalize(struct stream_scan *sk);
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ uint8_t * mpeg_parser_scan_start_code(struct stream_scan *sk, uint32_t code)
|
||||||
{
|
{
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
off_t pos = disk_buf_lseek(sk->pos, SEEK_SET);
|
off_t pos = disk_buf_lseek(sk->pos, SEEK_SET);
|
||||||
ssize_t len = disk_buf_getbuffer(4, &p, NULL, NULL);
|
ssize_t len = disk_buf_getbuffer_l2(&sk->l2, 4, (void **)&p);
|
||||||
|
|
||||||
if (pos < 0 || len < 4)
|
if (pos < 0 || len < 4)
|
||||||
break;
|
break;
|
||||||
|
@ -131,7 +131,7 @@ unsigned mpeg_parser_scan_pes(struct stream_scan *sk)
|
||||||
{
|
{
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
off_t pos = disk_buf_lseek(sk->pos, SEEK_SET);
|
off_t pos = disk_buf_lseek(sk->pos, SEEK_SET);
|
||||||
ssize_t len = disk_buf_getbuffer(4, &p, NULL, NULL);
|
ssize_t len = disk_buf_getbuffer_l2(&sk->l2, 4, (void **)&p);
|
||||||
|
|
||||||
if (pos < 0 || len < 4)
|
if (pos < 0 || len < 4)
|
||||||
break;
|
break;
|
||||||
|
@ -192,7 +192,7 @@ uint32_t mpeg_parser_scan_pts(struct stream_scan *sk, unsigned id)
|
||||||
{
|
{
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
off_t pos = disk_buf_lseek(sk->pos, SEEK_SET);
|
off_t pos = disk_buf_lseek(sk->pos, SEEK_SET);
|
||||||
ssize_t len = disk_buf_getbuffer(35, &p, NULL, NULL);
|
ssize_t len = disk_buf_getbuffer_l2(&sk->l2, 30, (void **)&p);
|
||||||
|
|
||||||
if (pos < 0 || len < 4)
|
if (pos < 0 || len < 4)
|
||||||
break;
|
break;
|
||||||
|
@ -201,7 +201,7 @@ uint32_t mpeg_parser_scan_pts(struct stream_scan *sk, unsigned id)
|
||||||
{
|
{
|
||||||
uint8_t *h = p;
|
uint8_t *h = p;
|
||||||
|
|
||||||
if (sk->margin < 6)
|
if (sk->margin < 7)
|
||||||
{
|
{
|
||||||
/* Insufficient data */
|
/* Insufficient data */
|
||||||
}
|
}
|
||||||
|
@ -215,29 +215,33 @@ uint32_t mpeg_parser_scan_pts(struct stream_scan *sk, unsigned id)
|
||||||
}
|
}
|
||||||
else /* mpeg1 */
|
else /* mpeg1 */
|
||||||
{
|
{
|
||||||
ssize_t l = 7;
|
ssize_t l = 6;
|
||||||
ssize_t margin = sk->margin;
|
ssize_t margin = sk->margin;
|
||||||
|
|
||||||
/* Skip stuffing_byte */
|
/* Skip stuffing_byte */
|
||||||
while (h[l - 1] == 0xff && ++l <= 23)
|
while (margin > 7 && h[l] == 0xff && ++l <= 22)
|
||||||
--margin;
|
--margin;
|
||||||
|
|
||||||
if ((h[l - 1] & 0xc0) == 0x40)
|
if (margin >= 7)
|
||||||
{
|
{
|
||||||
/* Skip STD_buffer_scale and STD_buffer_size */
|
if ((h[l] & 0xc0) == 0x40)
|
||||||
margin -= 2;
|
|
||||||
l += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (margin >= 4)
|
|
||||||
{
|
|
||||||
/* header points to the mpeg1 pes header */
|
|
||||||
h += l;
|
|
||||||
|
|
||||||
if ((h[-1] & 0xe0) == 0x20)
|
|
||||||
{
|
{
|
||||||
sk->data = (h + 4) - p;
|
/* Skip STD_buffer_scale and STD_buffer_size */
|
||||||
return read_pts(h, -1);
|
margin -= 2;
|
||||||
|
l += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (margin >= 5)
|
||||||
|
{
|
||||||
|
/* Header points to the mpeg1 pes header */
|
||||||
|
h += l;
|
||||||
|
|
||||||
|
if ((h[0] & 0xe0) == 0x20)
|
||||||
|
{
|
||||||
|
/* PTS or PTS_DTS indicated */
|
||||||
|
sk->data = (h + 5) - p;
|
||||||
|
return read_pts(h, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,6 +361,8 @@ static off_t mpeg_parser_seek_PTS(uint32_t time, unsigned id)
|
||||||
enum state_enum state = STATE0;
|
enum state_enum state = STATE0;
|
||||||
struct stream_scan sk;
|
struct stream_scan sk;
|
||||||
|
|
||||||
|
stream_scan_init(&sk);
|
||||||
|
|
||||||
/* Initial estimate taken from average bitrate - later interpolations are
|
/* Initial estimate taken from average bitrate - later interpolations are
|
||||||
* taken similarly based on the remaining file interval */
|
* taken similarly based on the remaining file interval */
|
||||||
pos_new = muldiv_uint32(time - time_left, pos_right - pos_left,
|
pos_new = muldiv_uint32(time - time_left, pos_right - pos_left,
|
||||||
|
@ -564,6 +570,8 @@ static bool prepare_image(uint32_t time)
|
||||||
int tries;
|
int tries;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
stream_scan_init(&sk);
|
||||||
|
|
||||||
if (!str_send_msg(&video_str, STREAM_NEEDS_SYNC, time))
|
if (!str_send_msg(&video_str, STREAM_NEEDS_SYNC, time))
|
||||||
{
|
{
|
||||||
DEBUGF("Image was ready\n");
|
DEBUGF("Image was ready\n");
|
||||||
|
@ -734,7 +742,7 @@ static int parse_demux(struct stream *str, enum stream_parse_mode type)
|
||||||
str->hdr.pos = disk_buf_lseek(str->hdr.pos, SEEK_SET);
|
str->hdr.pos = disk_buf_lseek(str->hdr.pos, SEEK_SET);
|
||||||
|
|
||||||
if (str->hdr.pos < 0 || str->hdr.pos >= str->hdr.limit ||
|
if (str->hdr.pos < 0 || str->hdr.pos >= str->hdr.limit ||
|
||||||
disk_buf_getbuffer(MIN_BUFAHEAD, &p, NULL, NULL) <= 0)
|
disk_buf_getbuffer(MIN_BUFAHEAD, (void **)&p, NULL, NULL) <= 0)
|
||||||
{
|
{
|
||||||
str_end_of_stream(str);
|
str_end_of_stream(str);
|
||||||
return STREAM_DATA_END;
|
return STREAM_DATA_END;
|
||||||
|
@ -1009,7 +1017,7 @@ static int parse_elementary(struct stream *str, enum stream_parse_mode type)
|
||||||
|
|
||||||
case STREAM_PM_RANDOM_ACCESS:
|
case STREAM_PM_RANDOM_ACCESS:
|
||||||
str->hdr.pos = disk_buf_lseek(str->hdr.pos, SEEK_SET);
|
str->hdr.pos = disk_buf_lseek(str->hdr.pos, SEEK_SET);
|
||||||
len = disk_buf_getbuffer(DISK_BUF_PAGE_SIZE, &p, NULL, NULL);
|
len = disk_buf_getbuffer(DISK_BUF_PAGE_SIZE, (void **)&p, NULL, NULL);
|
||||||
|
|
||||||
if (len <= 0 || str->hdr.pos < 0 || str->hdr.pos >= str->hdr.limit)
|
if (len <= 0 || str->hdr.pos < 0 || str->hdr.pos >= str->hdr.limit)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue