forked from len0rd/rockbox
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
This commit is contained in:
parent
1d0f6b90ff
commit
a222f27c4a
34 changed files with 7850 additions and 2764 deletions
|
@ -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)
|
||||
{
|
||||
mem_ptr = 0;
|
||||
bufsize = mallocsize;
|
||||
/* Line-align buffer */
|
||||
mallocbuf = (char *)(((intptr_t)buf + 15) & ~15);
|
||||
/* Adjust for real size */
|
||||
bufsize -= mallocbuf - buf;
|
||||
/* Can steal all but MIN_MEMMARGIN */
|
||||
if (bufsize - mem_ptr < MIN_MEMMARGIN)
|
||||
return NULL;
|
||||
|
||||
/* Separate allocator for video */
|
||||
libmpeg2size = (libmpeg2size + 15) & ~15;
|
||||
if (mpeg_malloc_internal(mallocbuf, &mem_ptr,
|
||||
bufsize, libmpeg2size, 0) == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
mpeg2_mallocbuf = mallocbuf;
|
||||
mpeg2_mem_ptr = 0;
|
||||
mpeg2_bufsize = libmpeg2size;
|
||||
|
||||
#if NUM_CORES > 1
|
||||
flush_icache();
|
||||
#endif
|
||||
|
||||
return bufsize - mpeg2_bufsize;
|
||||
*size_out = bufsize - mem_ptr - MIN_MEMMARGIN;
|
||||
return mpeg_malloc(*size_out, reason);
|
||||
}
|
||||
|
||||
/* gcc may want to use memcpy before rb is initialised, so here's a trivial
|
||||
bool mpeg_alloc_init(unsigned char *buf, size_t mallocsize)
|
||||
{
|
||||
mem_ptr = 0;
|
||||
/* Cache-align buffer or 4-byte align */
|
||||
mallocbuf = buf;
|
||||
bufsize = align_buffer(PUN_PTR(void **, &mallocbuf),
|
||||
mallocsize, CACHEALIGN_UP(4));
|
||||
|
||||
/* Separate allocator for video */
|
||||
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, mpeg2_bufsize,
|
||||
MPEG_ALLOC_MPEG2_BUFFER) == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
IF_COP(flush_icache());
|
||||
return true;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue