From a222f27c4a17ed8f9809cda7861fe5f23d4cc0c1 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Sat, 29 Dec 2007 19:46:35 +0000 Subject: mpegplayer: Make playback engine fully seekable and frame-accurate and split into logical parts. Be sure to have all current features work. Actual UI for seeking will be added soon. Recommended GOP size is about 15-30 frames depending on target or seeking can be slow with really long GOPs (nature of MPEG video). More refined encoding recommendations for a particular player should be posted soon. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15977 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/mpegplayer/alloc.c | 173 +++++++++++++++++++++++++++++++--------- 1 file changed, 136 insertions(+), 37 deletions(-) (limited to 'apps/plugins/mpegplayer/alloc.c') diff --git a/apps/plugins/mpegplayer/alloc.c b/apps/plugins/mpegplayer/alloc.c index c79894447b..1ff75d4d64 100644 --- a/apps/plugins/mpegplayer/alloc.c +++ b/apps/plugins/mpegplayer/alloc.c @@ -22,10 +22,7 @@ */ #include "plugin.h" - -#include "mpeg2.h" - -extern struct plugin_api* rb; +#include "mpegplayer.h" /* Main allocator */ static off_t mem_ptr; @@ -33,9 +30,58 @@ static size_t bufsize; static unsigned char* mallocbuf; /* libmpeg2 allocator */ -static off_t mpeg2_mem_ptr; -static size_t mpeg2_bufsize; -static unsigned char *mpeg2_mallocbuf; +static off_t mpeg2_mem_ptr NOCACHEBSS_ATTR; +static size_t mpeg2_bufsize NOCACHEBSS_ATTR; +static unsigned char *mpeg2_mallocbuf NOCACHEBSS_ATTR; +static unsigned char *mpeg2_bufallocbuf NOCACHEBSS_ATTR; + +#if defined(DEBUG) || defined(SIMULATOR) +const char * mpeg_get_reason_str(int reason) +{ + const char *str; + + switch (reason) + { + case MPEG2_ALLOC_MPEG2DEC: + str = "MPEG2_ALLOC_MPEG2DEC"; + break; + case MPEG2_ALLOC_CHUNK: + str = "MPEG2_ALLOC_CHUNK"; + break; + case MPEG2_ALLOC_YUV: + str = "MPEG2_ALLOC_YUV"; + break; + case MPEG2_ALLOC_CONVERT_ID: + str = "MPEG2_ALLOC_CONVERT_ID"; + break; + case MPEG2_ALLOC_CONVERTED: + str = "MPEG2_ALLOC_CONVERTED"; + break; + case MPEG_ALLOC_MPEG2_BUFFER: + str = "MPEG_ALLOC_MPEG2_BUFFER"; + break; + case MPEG_ALLOC_AUDIOBUF: + str = "MPEG_ALLOC_AUDIOBUF"; + break; + case MPEG_ALLOC_PCMOUT: + str = "MPEG_ALLOC_PCMOUT"; + break; + case MPEG_ALLOC_DISKBUF: + str = "MPEG_ALLOC_DISKBUF"; + break; + case MPEG_ALLOC_CODEC_MALLOC: + str = "MPEG_ALLOC_CODEC_MALLOC"; + break; + case MPEG_ALLOC_CODEC_CALLOC: + str = "MPEG_ALLOC_CODEC_CALLOC"; + break; + default: + str = "Unknown"; + } + + return str; +} +#endif static void * mpeg_malloc_internal (unsigned char *mallocbuf, off_t *mem_ptr, @@ -45,12 +91,15 @@ static void * mpeg_malloc_internal (unsigned char *mallocbuf, { void *x; + DEBUGF("mpeg_alloc_internal: bs:%lu s:%u reason:%s (%d)\n", + bufsize, size, mpeg_get_reason_str(reason), reason); + if ((size_t) (*mem_ptr + size) > bufsize) { DEBUGF("OUT OF MEMORY\n"); return NULL; } - + x = &mallocbuf[*mem_ptr]; *mem_ptr += (size + 3) & ~3; /* Keep memory 32-bit aligned */ @@ -64,39 +113,46 @@ void *mpeg_malloc(size_t size, mpeg2_alloc_t reason) reason); } -size_t mpeg_alloc_init(unsigned char *buf, size_t mallocsize, - size_t libmpeg2size) +void *mpeg_malloc_all(size_t *size_out, mpeg2_alloc_t reason) +{ + /* Can steal all but MIN_MEMMARGIN */ + if (bufsize - mem_ptr < MIN_MEMMARGIN) + return NULL; + + *size_out = bufsize - mem_ptr - MIN_MEMMARGIN; + return mpeg_malloc(*size_out, reason); +} + +bool mpeg_alloc_init(unsigned char *buf, size_t mallocsize) { mem_ptr = 0; - bufsize = mallocsize; - /* Line-align buffer */ - mallocbuf = (char *)(((intptr_t)buf + 15) & ~15); - /* Adjust for real size */ - bufsize -= mallocbuf - buf; + /* Cache-align buffer or 4-byte align */ + mallocbuf = buf; + bufsize = align_buffer(PUN_PTR(void **, &mallocbuf), + mallocsize, CACHEALIGN_UP(4)); /* Separate allocator for video */ - libmpeg2size = (libmpeg2size + 15) & ~15; + mpeg2_mem_ptr = 0; + mpeg2_mallocbuf = mallocbuf; + mpeg2_bufallocbuf = mallocbuf; + mpeg2_bufsize = CACHEALIGN_UP(LIBMPEG2_ALLOC_SIZE); + if (mpeg_malloc_internal(mallocbuf, &mem_ptr, - bufsize, libmpeg2size, 0) == NULL) + bufsize, mpeg2_bufsize, + MPEG_ALLOC_MPEG2_BUFFER) == NULL) { - return 0; + return false; } - mpeg2_mallocbuf = mallocbuf; - mpeg2_mem_ptr = 0; - mpeg2_bufsize = libmpeg2size; - -#if NUM_CORES > 1 - flush_icache(); -#endif - - return bufsize - mpeg2_bufsize; + IF_COP(flush_icache()); + return true; } -/* gcc may want to use memcpy before rb is initialised, so here's a trivial +/* gcc may want to use memcpy before rb is initialised, so here's a trivial implementation */ -void *memcpy(void *dest, const void *src, size_t n) { +void *memcpy(void *dest, const void *src, size_t n) +{ size_t i; char* d=(char*)dest; char* s=(char*)src; @@ -107,22 +163,60 @@ void *memcpy(void *dest, const void *src, size_t n) { return dest; } +/* allocate non-dedicated buffer space which mpeg2_mem_reset will free */ void * mpeg2_malloc(unsigned size, mpeg2_alloc_t reason) { - return mpeg_malloc_internal(mpeg2_mallocbuf, &mpeg2_mem_ptr, - mpeg2_bufsize, size, reason); + void *ptr = mpeg_malloc_internal(mpeg2_mallocbuf, &mpeg2_mem_ptr, + mpeg2_bufsize, size, reason); + /* libmpeg2 expects zero-initialized allocations */ + if (ptr) + rb->memset(ptr, 0, size); + + return ptr; } -void mpeg2_free(void *ptr) +/* allocate dedicated buffer - memory behind buffer pointer becomes dedicated + so order is important */ +void * mpeg2_bufalloc(unsigned size, mpeg2_alloc_t reason) { - mpeg2_mem_ptr = (void *)ptr - (void *)mpeg2_mallocbuf; + void *buf = mpeg2_malloc(size, reason); + + if (buf == NULL) + return NULL; + + mpeg2_bufallocbuf = &mpeg2_mallocbuf[mpeg2_mem_ptr]; + return buf; +} + +/* return unused buffer portion and size */ +void * mpeg2_get_buf(size_t *size) +{ + if ((size_t)mpeg2_mem_ptr + 32 >= mpeg2_bufsize) + return NULL; + + *size = mpeg2_bufsize - mpeg2_mem_ptr; + return &mpeg2_mallocbuf[mpeg2_mem_ptr]; +} + +/* de-allocate all non-dedicated buffer space */ +void mpeg2_mem_reset(void) +{ + DEBUGF("mpeg2_mem_reset\n"); + mpeg2_mem_ptr = mpeg2_bufallocbuf - mpeg2_mallocbuf; } /* The following are expected by libmad */ void * codec_malloc(size_t size) { - return mpeg_malloc_internal(mallocbuf, &mem_ptr, - bufsize, size, -3); + void* ptr; + + ptr = mpeg_malloc_internal(mallocbuf, &mem_ptr, + bufsize, size, MPEG_ALLOC_CODEC_MALLOC); + + if (ptr) + rb->memset(ptr,0,size); + + return ptr; } void * codec_calloc(size_t nmemb, size_t size) @@ -130,17 +224,22 @@ void * codec_calloc(size_t nmemb, size_t size) void* ptr; ptr = mpeg_malloc_internal(mallocbuf, &mem_ptr, - bufsize, nmemb*size, -3); + bufsize, nmemb*size, + MPEG_ALLOC_CODEC_CALLOC); if (ptr) rb->memset(ptr,0,size); - + return ptr; } void codec_free(void* ptr) { + DEBUGF("codec_free - %p\n", ptr); +#if 0 mem_ptr = (void *)ptr - (void *)mallocbuf; +#endif + (void)ptr; } void *memmove(void *dest, const void *src, size_t n) -- cgit v1.2.3