summaryrefslogtreecommitdiff
path: root/apps/plugins/mpegplayer/alloc.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-12-29 19:46:35 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-12-29 19:46:35 +0000
commita222f27c4a17ed8f9809cda7861fe5f23d4cc0c1 (patch)
treed393a23d83549f99772bb156e59ffb88725148b6 /apps/plugins/mpegplayer/alloc.c
parent1d0f6b90ff43776e55b4b9f062c9bea3f99aa768 (diff)
downloadrockbox-a222f27c4a17ed8f9809cda7861fe5f23d4cc0c1.tar.gz
rockbox-a222f27c4a17ed8f9809cda7861fe5f23d4cc0c1.zip
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
Diffstat (limited to 'apps/plugins/mpegplayer/alloc.c')
-rw-r--r--apps/plugins/mpegplayer/alloc.c173
1 files changed, 136 insertions, 37 deletions
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 @@
22 */ 22 */
23 23
24#include "plugin.h" 24#include "plugin.h"
25 25#include "mpegplayer.h"
26#include "mpeg2.h"
27
28extern struct plugin_api* rb;
29 26
30/* Main allocator */ 27/* Main allocator */
31static off_t mem_ptr; 28static off_t mem_ptr;
@@ -33,9 +30,58 @@ static size_t bufsize;
33static unsigned char* mallocbuf; 30static unsigned char* mallocbuf;
34 31
35/* libmpeg2 allocator */ 32/* libmpeg2 allocator */
36static off_t mpeg2_mem_ptr; 33static off_t mpeg2_mem_ptr NOCACHEBSS_ATTR;
37static size_t mpeg2_bufsize; 34static size_t mpeg2_bufsize NOCACHEBSS_ATTR;
38static unsigned char *mpeg2_mallocbuf; 35static unsigned char *mpeg2_mallocbuf NOCACHEBSS_ATTR;
36static unsigned char *mpeg2_bufallocbuf NOCACHEBSS_ATTR;
37
38#if defined(DEBUG) || defined(SIMULATOR)
39const char * mpeg_get_reason_str(int reason)
40{
41 const char *str;
42
43 switch (reason)
44 {
45 case MPEG2_ALLOC_MPEG2DEC:
46 str = "MPEG2_ALLOC_MPEG2DEC";
47 break;
48 case MPEG2_ALLOC_CHUNK:
49 str = "MPEG2_ALLOC_CHUNK";
50 break;
51 case MPEG2_ALLOC_YUV:
52 str = "MPEG2_ALLOC_YUV";
53 break;
54 case MPEG2_ALLOC_CONVERT_ID:
55 str = "MPEG2_ALLOC_CONVERT_ID";
56 break;
57 case MPEG2_ALLOC_CONVERTED:
58 str = "MPEG2_ALLOC_CONVERTED";
59 break;
60 case MPEG_ALLOC_MPEG2_BUFFER:
61 str = "MPEG_ALLOC_MPEG2_BUFFER";
62 break;
63 case MPEG_ALLOC_AUDIOBUF:
64 str = "MPEG_ALLOC_AUDIOBUF";
65 break;
66 case MPEG_ALLOC_PCMOUT:
67 str = "MPEG_ALLOC_PCMOUT";
68 break;
69 case MPEG_ALLOC_DISKBUF:
70 str = "MPEG_ALLOC_DISKBUF";
71 break;
72 case MPEG_ALLOC_CODEC_MALLOC:
73 str = "MPEG_ALLOC_CODEC_MALLOC";
74 break;
75 case MPEG_ALLOC_CODEC_CALLOC:
76 str = "MPEG_ALLOC_CODEC_CALLOC";
77 break;
78 default:
79 str = "Unknown";
80 }
81
82 return str;
83}
84#endif
39 85
40static void * mpeg_malloc_internal (unsigned char *mallocbuf, 86static void * mpeg_malloc_internal (unsigned char *mallocbuf,
41 off_t *mem_ptr, 87 off_t *mem_ptr,
@@ -45,12 +91,15 @@ static void * mpeg_malloc_internal (unsigned char *mallocbuf,
45{ 91{
46 void *x; 92 void *x;
47 93
94 DEBUGF("mpeg_alloc_internal: bs:%lu s:%u reason:%s (%d)\n",
95 bufsize, size, mpeg_get_reason_str(reason), reason);
96
48 if ((size_t) (*mem_ptr + size) > bufsize) 97 if ((size_t) (*mem_ptr + size) > bufsize)
49 { 98 {
50 DEBUGF("OUT OF MEMORY\n"); 99 DEBUGF("OUT OF MEMORY\n");
51 return NULL; 100 return NULL;
52 } 101 }
53 102
54 x = &mallocbuf[*mem_ptr]; 103 x = &mallocbuf[*mem_ptr];
55 *mem_ptr += (size + 3) & ~3; /* Keep memory 32-bit aligned */ 104 *mem_ptr += (size + 3) & ~3; /* Keep memory 32-bit aligned */
56 105
@@ -64,39 +113,46 @@ void *mpeg_malloc(size_t size, mpeg2_alloc_t reason)
64 reason); 113 reason);
65} 114}
66 115
67size_t mpeg_alloc_init(unsigned char *buf, size_t mallocsize, 116void *mpeg_malloc_all(size_t *size_out, mpeg2_alloc_t reason)
68 size_t libmpeg2size) 117{
118 /* Can steal all but MIN_MEMMARGIN */
119 if (bufsize - mem_ptr < MIN_MEMMARGIN)
120 return NULL;
121
122 *size_out = bufsize - mem_ptr - MIN_MEMMARGIN;
123 return mpeg_malloc(*size_out, reason);
124}
125
126bool mpeg_alloc_init(unsigned char *buf, size_t mallocsize)
69{ 127{
70 mem_ptr = 0; 128 mem_ptr = 0;
71 bufsize = mallocsize; 129 /* Cache-align buffer or 4-byte align */
72 /* Line-align buffer */ 130 mallocbuf = buf;
73 mallocbuf = (char *)(((intptr_t)buf + 15) & ~15); 131 bufsize = align_buffer(PUN_PTR(void **, &mallocbuf),
74 /* Adjust for real size */ 132 mallocsize, CACHEALIGN_UP(4));
75 bufsize -= mallocbuf - buf;
76 133
77 /* Separate allocator for video */ 134 /* Separate allocator for video */
78 libmpeg2size = (libmpeg2size + 15) & ~15; 135 mpeg2_mem_ptr = 0;
136 mpeg2_mallocbuf = mallocbuf;
137 mpeg2_bufallocbuf = mallocbuf;
138 mpeg2_bufsize = CACHEALIGN_UP(LIBMPEG2_ALLOC_SIZE);
139
79 if (mpeg_malloc_internal(mallocbuf, &mem_ptr, 140 if (mpeg_malloc_internal(mallocbuf, &mem_ptr,
80 bufsize, libmpeg2size, 0) == NULL) 141 bufsize, mpeg2_bufsize,
142 MPEG_ALLOC_MPEG2_BUFFER) == NULL)
81 { 143 {
82 return 0; 144 return false;
83 } 145 }
84 146
85 mpeg2_mallocbuf = mallocbuf; 147 IF_COP(flush_icache());
86 mpeg2_mem_ptr = 0; 148 return true;
87 mpeg2_bufsize = libmpeg2size;
88
89#if NUM_CORES > 1
90 flush_icache();
91#endif
92
93 return bufsize - mpeg2_bufsize;
94} 149}
95 150
96/* gcc may want to use memcpy before rb is initialised, so here's a trivial 151/* gcc may want to use memcpy before rb is initialised, so here's a trivial
97 implementation */ 152 implementation */
98 153
99void *memcpy(void *dest, const void *src, size_t n) { 154void *memcpy(void *dest, const void *src, size_t n)
155{
100 size_t i; 156 size_t i;
101 char* d=(char*)dest; 157 char* d=(char*)dest;
102 char* s=(char*)src; 158 char* s=(char*)src;
@@ -107,22 +163,60 @@ void *memcpy(void *dest, const void *src, size_t n) {
107 return dest; 163 return dest;
108} 164}
109 165
166/* allocate non-dedicated buffer space which mpeg2_mem_reset will free */
110void * mpeg2_malloc(unsigned size, mpeg2_alloc_t reason) 167void * mpeg2_malloc(unsigned size, mpeg2_alloc_t reason)
111{ 168{
112 return mpeg_malloc_internal(mpeg2_mallocbuf, &mpeg2_mem_ptr, 169 void *ptr = mpeg_malloc_internal(mpeg2_mallocbuf, &mpeg2_mem_ptr,
113 mpeg2_bufsize, size, reason); 170 mpeg2_bufsize, size, reason);
171 /* libmpeg2 expects zero-initialized allocations */
172 if (ptr)
173 rb->memset(ptr, 0, size);
174
175 return ptr;
114} 176}
115 177
116void mpeg2_free(void *ptr) 178/* allocate dedicated buffer - memory behind buffer pointer becomes dedicated
179 so order is important */
180void * mpeg2_bufalloc(unsigned size, mpeg2_alloc_t reason)
117{ 181{
118 mpeg2_mem_ptr = (void *)ptr - (void *)mpeg2_mallocbuf; 182 void *buf = mpeg2_malloc(size, reason);
183
184 if (buf == NULL)
185 return NULL;
186
187 mpeg2_bufallocbuf = &mpeg2_mallocbuf[mpeg2_mem_ptr];
188 return buf;
189}
190
191/* return unused buffer portion and size */
192void * mpeg2_get_buf(size_t *size)
193{
194 if ((size_t)mpeg2_mem_ptr + 32 >= mpeg2_bufsize)
195 return NULL;
196
197 *size = mpeg2_bufsize - mpeg2_mem_ptr;
198 return &mpeg2_mallocbuf[mpeg2_mem_ptr];
199}
200
201/* de-allocate all non-dedicated buffer space */
202void mpeg2_mem_reset(void)
203{
204 DEBUGF("mpeg2_mem_reset\n");
205 mpeg2_mem_ptr = mpeg2_bufallocbuf - mpeg2_mallocbuf;
119} 206}
120 207
121/* The following are expected by libmad */ 208/* The following are expected by libmad */
122void * codec_malloc(size_t size) 209void * codec_malloc(size_t size)
123{ 210{
124 return mpeg_malloc_internal(mallocbuf, &mem_ptr, 211 void* ptr;
125 bufsize, size, -3); 212
213 ptr = mpeg_malloc_internal(mallocbuf, &mem_ptr,
214 bufsize, size, MPEG_ALLOC_CODEC_MALLOC);
215
216 if (ptr)
217 rb->memset(ptr,0,size);
218
219 return ptr;
126} 220}
127 221
128void * codec_calloc(size_t nmemb, size_t size) 222void * codec_calloc(size_t nmemb, size_t size)
@@ -130,17 +224,22 @@ void * codec_calloc(size_t nmemb, size_t size)
130 void* ptr; 224 void* ptr;
131 225
132 ptr = mpeg_malloc_internal(mallocbuf, &mem_ptr, 226 ptr = mpeg_malloc_internal(mallocbuf, &mem_ptr,
133 bufsize, nmemb*size, -3); 227 bufsize, nmemb*size,
228 MPEG_ALLOC_CODEC_CALLOC);
134 229
135 if (ptr) 230 if (ptr)
136 rb->memset(ptr,0,size); 231 rb->memset(ptr,0,size);
137 232
138 return ptr; 233 return ptr;
139} 234}
140 235
141void codec_free(void* ptr) 236void codec_free(void* ptr)
142{ 237{
238 DEBUGF("codec_free - %p\n", ptr);
239#if 0
143 mem_ptr = (void *)ptr - (void *)mallocbuf; 240 mem_ptr = (void *)ptr - (void *)mallocbuf;
241#endif
242 (void)ptr;
144} 243}
145 244
146void *memmove(void *dest, const void *src, size_t n) 245void *memmove(void *dest, const void *src, size_t n)