summaryrefslogtreecommitdiff
path: root/firmware/buffer.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2011-08-14 15:13:00 +0000
committerThomas Martitz <kugel@rockbox.org>2011-08-14 15:13:00 +0000
commitd1322b71595336740eb5e18e5deed056ddb71c7a (patch)
tree812db6a9c2e9d78405ec0ed38465fd88dc5be748 /firmware/buffer.c
parent9b9bd73dfb212d4192fccc5fc5e269fc6499139c (diff)
downloadrockbox-d1322b71595336740eb5e18e5deed056ddb71c7a.tar.gz
rockbox-d1322b71595336740eb5e18e5deed056ddb71c7a.zip
GSoC/Buflib: Replace all direct accesses to audiobuf with buffer API functions.
Namely, introduce buffer_get_buffer() and buffer_release_buffer(). buffer_get_buffer() aquires all available and grabs a lock, attempting to call buffer_alloc() or buffer_get_buffer() while this lock is locked will cause a panicf() (doesn't actually happen, but is for debugging purpose). buffer_release_buffer() unlocks that lock and can additionally increment the audiobuf buffer to make an allocation. Pass 0 to only unlock if buffer was used temporarily only. buffer_available() is a replacement function to query audiobuflen, i.e. what's left in the buffer. Buffer init is moved up in the init chain and handles ipodvideo64mb internally. Further changes happened to mp3data.c and talk.c as to not call the above API functions, but get the buffer from callers. The caller is the audio system which has the buffer lock while mp3data.c and talk mess with the buffer. mpeg.c now implements some buffer related functions of playback.h, especially audio_get_buffer(), allowing to reduce #ifdef hell a tiny bit. audiobuf and audiobufend are local to buffer.c now. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30308 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/buffer.c')
-rw-r--r--firmware/buffer.c75
1 files changed, 72 insertions, 3 deletions
diff --git a/firmware/buffer.c b/firmware/buffer.c
index c317cec924..2168087bd9 100644
--- a/firmware/buffer.c
+++ b/firmware/buffer.c
@@ -19,19 +19,33 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include <stdio.h> 21#include <stdio.h>
22#include <stdint.h>
23#include "system.h"
22#include "buffer.h" 24#include "buffer.h"
23#include "panic.h" 25#include "panic.h"
24#include "logf.h" 26#include "logf.h"
25 27
26#if (CONFIG_PLATFORM & PLATFORM_HOSTED) 28#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
27unsigned char audiobuffer[(MEMORYSIZE*1024-256)*1024];
28unsigned char *audiobufend = audiobuffer + sizeof(audiobuffer);
29#else 29#else
30#endif
31
32/* defined in linker script */
33#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
34#if defined(IPOD_VIDEO)
35extern unsigned char *audiobufend_lds[];
36unsigned char *audiobufend;
37#else /* !IPOD_VIDEO */
38extern unsigned char audiobufend[];
39#endif
30/* defined in linker script */ 40/* defined in linker script */
31extern unsigned char audiobuffer[]; 41extern unsigned char audiobuffer[];
42#else /* PLATFORM_HOSTED */
43unsigned char audiobuffer[(MEMORYSIZE*1024-256)*1024];
44unsigned char *audiobufend = audiobuffer + sizeof(audiobuffer);
45extern unsigned char *audiobufend;
32#endif 46#endif
33 47
34unsigned char *audiobuf; 48static unsigned char *audiobuf;
35 49
36#ifdef BUFFER_ALLOC_DEBUG 50#ifdef BUFFER_ALLOC_DEBUG
37static unsigned char *audiobuf_orig_start; 51static unsigned char *audiobuf_orig_start;
@@ -54,13 +68,68 @@ void buffer_init(void)
54{ 68{
55 /* 32-bit aligned */ 69 /* 32-bit aligned */
56 audiobuf = (void *)(((unsigned long)audiobuffer + 3) & ~3); 70 audiobuf = (void *)(((unsigned long)audiobuffer + 3) & ~3);
71
72#if defined(IPOD_VIDEO)
73 audiobufend=(unsigned char *)audiobufend_lds;
74 if(MEMORYSIZE==64 && probed_ramsize!=64)
75 {
76 audiobufend -= (32<<20);
77 }
78#endif
79
57#ifdef BUFFER_ALLOC_DEBUG 80#ifdef BUFFER_ALLOC_DEBUG
58 audiobuf_orig_start = audiobuf; 81 audiobuf_orig_start = audiobuf;
59#endif /* BUFFER_ALLOC_DEBUG */ 82#endif /* BUFFER_ALLOC_DEBUG */
60} 83}
61 84
85/* protect concurrent access */
86static volatile int lock;
87
88/*
89 * Give the entire buffer, return the size in size.
90 * The caller needs to make sure audiobuf is not otherwise used
91 *
92 * Note that this does not modify the buffer position (buffer_release_buffer()
93 * does), so call this if you want to aquire temporary memory
94 **/
95#define _ALIGN (sizeof(char*))
96void *buffer_get_buffer(size_t *size)
97{
98 if (lock)
99 panicf("concurrent audiobuf access");
100 lock = 1;
101 audiobuf = ALIGN_UP(audiobuf, sizeof(intptr_t));
102 *size = (audiobufend - audiobuf);
103 return audiobuf;
104}
105
106/*
107 * Release the buffer gotten with buffer_get_buffer
108 *
109 * size should have the amount of bytes (from the front) that caller keeps for
110 * its own, 0 if the entire buffer is to be released
111 *
112 * safe to be called with size=0 even if the buffer wasn't claimed before
113 **/
114void buffer_release_buffer(size_t size)
115{
116 audiobuf += size;
117 /* ensure alignment */
118 audiobuf = ALIGN_UP(audiobuf, sizeof(intptr_t));
119 lock = 0;
120}
121
122/*
123 * Query how much free space the buffer has */
124size_t buffer_available(void)
125{
126 return audiobufend - audiobuf;
127}
128
62void *buffer_alloc(size_t size) 129void *buffer_alloc(size_t size)
63{ 130{
131 if (lock) /* it's not save to call this here */
132 panicf("buffer_alloc(): exclusive buffer owner");
64 void *retval; 133 void *retval;
65#ifdef BUFFER_ALLOC_DEBUG 134#ifdef BUFFER_ALLOC_DEBUG
66 struct buffer_start_marker *start; 135 struct buffer_start_marker *start;