Increase MAXTHREADS
[Rockbox.git] / apps / buffering.c
blobd2e3bfd7b1ef255759b89872e88cad45b595b72e
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2007 Nicolas Pennequin
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "config.h"
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <ctype.h>
25 #include "buffering.h"
27 #include "ata.h"
28 #include "system.h"
29 #include "thread.h"
30 #include "file.h"
31 #include "panic.h"
32 #include "memory.h"
33 #include "lcd.h"
34 #include "font.h"
35 #include "button.h"
36 #include "kernel.h"
37 #include "tree.h"
38 #include "debug.h"
39 #include "sprintf.h"
40 #include "settings.h"
41 #include "codecs.h"
42 #include "audio.h"
43 #include "logf.h"
44 #include "mp3_playback.h"
45 #include "usb.h"
46 #include "status.h"
47 #include "screens.h"
48 #include "playlist.h"
49 #include "playback.h"
50 #include "pcmbuf.h"
51 #include "buffer.h"
52 #include "ata_idle_notify.h"
54 #ifdef SIMULATOR
55 #define ata_disk_is_active() 1
56 #endif
58 #if MEM > 1
59 #define GUARD_BUFSIZE (32*1024)
60 #else
61 #define GUARD_BUFSIZE (8*1024)
62 #endif
65 /* macros to enable logf for queues
66 logging on SYS_TIMEOUT can be disabled */
67 #ifdef SIMULATOR
68 /* Define this for logf output of all queuing except SYS_TIMEOUT */
69 #define BUFFERING_LOGQUEUES
70 /* Define this to logf SYS_TIMEOUT messages */
71 /* #define BUFFERING_LOGQUEUES_SYS_TIMEOUT */
72 #endif
74 #ifdef BUFFERING_LOGQUEUES
75 #define LOGFQUEUE logf
76 #else
77 #define LOGFQUEUE(...)
78 #endif
80 #ifdef BUFFERING_LOGQUEUES_SYS_TIMEOUT
81 #define LOGFQUEUE_SYS_TIMEOUT logf
82 #else
83 #define LOGFQUEUE_SYS_TIMEOUT(...)
84 #endif
87 /* amount of data to read in one read() call */
88 #define AUDIO_DEFAULT_FILECHUNK (1024*32)
90 /* Ring buffer helper macros */
91 /* Buffer pointer (p) plus value (v), wrapped if necessary */
92 #define RINGBUF_ADD(p,v) ((p+v)<buffer_len ? p+v : p+v-buffer_len)
93 /* Buffer pointer (p) minus value (v), wrapped if necessary */
94 #define RINGBUF_SUB(p,v) ((p>=v) ? p-v : p+buffer_len-v)
95 /* How far value (v) plus buffer pointer (p1) will cross buffer pointer (p2) */
96 #define RINGBUF_ADD_CROSS(p1,v,p2) \
97 ((p1<p2) ? (int)(p1+v)-(int)p2 : (int)(p1+v-p2)-(int)buffer_len)
98 /* Bytes available in the buffer */
99 #define BUF_USED RINGBUF_SUB(buf_widx, buf_ridx)
101 struct memory_handle {
102 int id; /* A unique ID for the handle */
103 enum data_type type;
104 char path[MAX_PATH];
105 int fd;
106 size_t data; /* Start index of the handle's data buffer */
107 size_t ridx; /* Current read pointer, relative to the main buffer */
108 size_t widx; /* Current write pointer */
109 size_t filesize; /* File total length */
110 size_t filerem; /* Remaining bytes of file NOT in buffer */
111 size_t available; /* Available bytes to read from buffer */
112 size_t offset; /* Offset at which we started reading the file */
113 struct memory_handle *next;
115 /* at all times, we have: filesize == offset + available + filerem */
118 static char *buffer;
119 static char *guard_buffer;
121 static size_t buffer_len;
123 static size_t buf_widx; /* current writing position */
124 static size_t buf_ridx; /* current reading position */
125 /* buf_*idx are values relative to the buffer, not real pointers. */
127 static size_t conf_filechunk = 0;
128 static size_t conf_watermark = 0; /* Level to trigger filebuf fill */
129 #if MEM > 8
130 static size_t high_watermark = 0; /* High watermark for rebuffer */
131 #endif
134 /* current memory handle in the linked list. NULL when the list is empty. */
135 static struct memory_handle *cur_handle;
136 /* first memory handle in the linked list. NULL when the list is empty. */
137 static struct memory_handle *first_handle;
139 static int num_handles; /* number of handles in the list */
141 static struct mutex llist_mutex;
143 /* Handle cache (makes find_handle faster).
144 These need to be global so that move_handle can invalidate them. */
145 static int cached_handle_id = -1;
146 static struct memory_handle *cached_handle = NULL;
149 /* Messages available to communicate with the buffering thread */
150 enum {
151 Q_BUFFER_HANDLE = 1, /* Request buffering of a handle */
152 Q_RESET_HANDLE, /* (internal) Request resetting of a handle to its
153 offset (the offset has to be set beforehand) */
154 Q_CLOSE_HANDLE,
155 Q_BUFFERING_FILL_BUFFER_IF_ACTIVE_ATA,
158 /* Buffering thread */
159 void buffering_thread(void);
160 static long buffering_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)];
161 static const char buffering_thread_name[] = "buffering";
162 struct thread_entry *buffering_thread_p;
163 struct event_queue buffering_queue;
164 struct queue_sender_list buffering_queue_sender_list;
168 LINKED LIST MANAGEMENT
169 ======================
171 add_handle : Add a handle to the list
172 rm_handle : Remove a handle from the list
173 find_handle : Get a handle pointer from an ID
174 move_handle : Move a handle in the buffer (with or without its data)
176 These functions only handle the linked list structure. They don't touch the
177 contents of the struct memory_handle headers. They also change the buf_*idx
178 pointers when necessary and manage the handle IDs.
180 The first and current (== last) handle are kept track of.
181 A new handle is added at buf_widx and becomes the current one.
182 buf_widx always points to the current writing position for the current handle
183 buf_ridx always points to the location of the first handle.
184 buf_ridx == buf_widx means the buffer is empty.
188 /* Add a new handle to the linked list and return it. It will have become the
189 new current handle. The handle will reserve "data_size" bytes or if that's
190 not possible, decrease "data_size" to allow adding the handle. */
191 static struct memory_handle *add_handle(size_t *data_size)
193 mutex_lock(&llist_mutex);
195 /* this will give each handle a unique id */
196 static int cur_handle_id = 1;
198 /* make sure buf_widx is 32-bit aligned so that the handle struct is,
199 but before that we check we can actually align. */
200 if (RINGBUF_ADD_CROSS(buf_widx, 3, buf_ridx) >= 0) {
201 mutex_unlock(&llist_mutex);
202 return NULL;
204 buf_widx = (RINGBUF_ADD(buf_widx, 3)) & ~3;
206 size_t len = (data_size ? *data_size : 0)
207 + sizeof(struct memory_handle);
209 /* check that we actually can add the handle and its data */
210 int overlap = RINGBUF_ADD_CROSS(buf_widx, len, buf_ridx);
211 if (overlap >= 0) {
212 *data_size -= overlap;
213 len -= overlap;
215 if (len < sizeof(struct memory_handle)) {
216 /* There isn't even enough space to write the struct */
217 mutex_unlock(&llist_mutex);
218 return NULL;
221 struct memory_handle *new_handle =
222 (struct memory_handle *)(&buffer[buf_widx]);
224 /* only advance the buffer write index of the size of the struct */
225 buf_widx = RINGBUF_ADD(buf_widx, sizeof(struct memory_handle));
227 if (!first_handle) {
228 /* the new handle is the first one */
229 first_handle = new_handle;
232 if (cur_handle) {
233 cur_handle->next = new_handle;
236 cur_handle = new_handle;
237 cur_handle->id = cur_handle_id++;
238 cur_handle->next = NULL;
239 num_handles++;
241 mutex_unlock(&llist_mutex);
242 return cur_handle;
245 /* Delete a given memory handle from the linked list
246 and return true for success. Nothing is actually erased from memory. */
247 static bool rm_handle(struct memory_handle *h)
249 mutex_lock(&llist_mutex);
251 if (h == first_handle) {
252 first_handle = h->next;
253 if (h == cur_handle) {
254 /* h was the first and last handle: the buffer is now empty */
255 cur_handle = NULL;
256 buf_ridx = buf_widx;
257 } else {
258 /* update buf_ridx to point to the new first handle */
259 buf_ridx = (void *)first_handle - (void *)buffer;
261 } else {
262 struct memory_handle *m = first_handle;
263 while (m && m->next != h) {
264 m = m->next;
266 if (h && m && m->next == h) {
267 m->next = h->next;
268 if (h == cur_handle) {
269 cur_handle = m;
270 buf_widx = cur_handle->widx;
272 } else {
273 mutex_unlock(&llist_mutex);
274 return false;
278 /* Invalidate the cache to prevent it from keeping the old location of h */
279 if (h == cached_handle)
280 cached_handle = NULL;
282 num_handles--;
284 mutex_unlock(&llist_mutex);
285 return true;
288 /* Return a pointer to the memory handle of given ID.
289 NULL if the handle wasn't found */
290 static struct memory_handle *find_handle(int handle_id)
292 mutex_lock(&llist_mutex);
294 /* simple caching because most of the time the requested handle
295 will either be the same as the last, or the one after the last */
296 if (cached_handle)
298 if (cached_handle_id == handle_id &&
299 cached_handle_id == cached_handle->id) {
300 mutex_unlock(&llist_mutex);
301 return cached_handle;
302 } else if (cached_handle->next &&
303 (cached_handle->next->id == handle_id)) {
304 cached_handle = cached_handle->next;
305 cached_handle_id = handle_id;
306 mutex_unlock(&llist_mutex);
307 return cached_handle;
311 struct memory_handle *m = first_handle;
312 while (m && m->id != handle_id) {
313 m = m->next;
315 cached_handle_id = handle_id;
316 cached_handle = m;
317 struct memory_handle *ret = (m && m->id == handle_id) ? m : NULL;
319 mutex_unlock(&llist_mutex);
320 return ret;
323 /* Move a memory handle and data_size of its data of delta.
324 Return a pointer to the new location of the handle.
325 delta is the value of which to move the struct data.
326 data_size is the amount of data to move along with the struct. */
327 static struct memory_handle *move_handle(struct memory_handle *h,
328 size_t *delta, size_t data_size)
330 mutex_lock(&llist_mutex);
332 if (*delta < 4) {
333 /* aligning backwards would yield a negative result,
334 and moving the handle of such a small amount is a waste
335 of time anyway. */
336 mutex_unlock(&llist_mutex);
337 return NULL;
339 /* make sure delta is 32-bit aligned so that the handle struct is. */
340 *delta = (*delta - 3) & ~3;
342 size_t newpos = RINGBUF_ADD((void *)h - (void *)buffer, *delta);
344 struct memory_handle *dest = (struct memory_handle *)(&buffer[newpos]);
346 /* Invalidate the cache to prevent it from keeping the old location of h */
347 if (h == cached_handle)
348 cached_handle = NULL;
350 /* the cur_handle pointer might need updating */
351 if (h == cur_handle) {
352 cur_handle = dest;
355 if (h == first_handle) {
356 first_handle = dest;
357 buf_ridx = newpos;
358 } else {
359 struct memory_handle *m = first_handle;
360 while (m && m->next != h) {
361 m = m->next;
363 if (h && m && m->next == h) {
364 m->next = dest;
365 } else {
366 mutex_unlock(&llist_mutex);
367 return NULL;
371 memmove(dest, h, sizeof(struct memory_handle) + data_size);
373 mutex_unlock(&llist_mutex);
374 return dest;
379 BUFFER SPACE MANAGEMENT
380 =======================
382 yield_codec : Used by buffer_handle to know if it should interrupt buffering
383 buffer_handle : Buffer data for a handle
384 reset_handle : Reset writing position and data buffer of a handle to its
385 current offset
386 rebuffer_handle : Seek to a nonbuffered part of a handle by rebuffering the data
387 shrink_handle : Free buffer space by moving a handle
388 fill_buffer : Call buffer_handle for all handles that have data to buffer
389 can_add_handle : Indicate whether it's safe to add a handle
390 data_rem : Total amount of data needing to be buffered
391 wasted_space : Total amount of space available for freeing
392 buffered_data : Total amount of data currently in the buffer
394 These functions are used by the buffering thread to manage buffer space.
397 static bool filebuf_is_lowdata(void)
399 return BUF_USED < AUDIO_FILEBUF_CRITICAL;
402 /* Yield to the codec thread for as long as possible if it is in need of data.
403 Return true if the caller should break to let the buffering thread process
404 new queue events */
405 static bool yield_codec(void)
407 yield();
409 if (!queue_empty(&buffering_queue))
410 return true;
412 while (pcmbuf_is_lowdata() && !filebuf_is_lowdata())
414 sleep(2);
416 if (!queue_empty(&buffering_queue))
417 return true;
420 return false;
423 /* Buffer data for the given handle. Return the amount of data buffered
424 or -1 if the handle wasn't found */
425 static ssize_t buffer_handle(int handle_id)
427 DEBUGF("buffer_handle(%d)\n", handle_id);
428 struct memory_handle *h = find_handle(handle_id);
429 if (!h)
430 return -1;
432 if (h->filerem == 0) {
433 /* nothing left to buffer */
434 return 0;
437 if (h->fd < 0) /* file closed, reopen */
439 if (*h->path)
440 h->fd = open(h->path, O_RDONLY);
441 else
442 return -1;
444 if (h->fd < 0)
445 return -1;
447 if (h->offset)
448 lseek(h->fd, h->offset, SEEK_SET);
451 buffering = true;
452 trigger_cpu_boost();
454 ssize_t ret = 0;
455 while (h->filerem > 0)
457 /* max amount to copy */
458 size_t copy_n = MIN( MIN(h->filerem, conf_filechunk),
459 buffer_len - h->widx);
461 /* stop copying if it would overwrite the reading position
462 or the next handle */
463 if (RINGBUF_ADD_CROSS(h->widx, copy_n, buf_ridx) >= 0 || (h->next &&
464 RINGBUF_ADD_CROSS(h->widx, copy_n, (unsigned)
465 ((void *)h->next - (void *)buffer)) > 0))
466 break;
468 /* rc is the actual amount read */
469 int rc = read(h->fd, &buffer[h->widx], copy_n);
471 if (rc < 0)
473 if (h->type == TYPE_CODEC) {
474 DEBUGF("Partial codec\n");
475 break;
478 DEBUGF("File ended %ld bytes early\n", (long)h->filerem);
479 h->filesize -= h->filerem;
480 h->filerem = 0;
481 break;
484 /* Advance buffer */
485 h->widx = RINGBUF_ADD(h->widx, rc);
486 if (h == cur_handle)
487 buf_widx = h->widx;
488 h->available += rc;
489 ret += rc;
490 h->filerem -= rc;
492 /* DEBUGF("buffer_handle(%d): buffered %ld bytes. done: %ld. remaining: %ld.\n",
493 h->id, rc, h->available, h->filerem); */
495 /* Stop buffering if new queue events have arrived */
496 if (yield_codec())
497 break;
500 if (h->filerem == 0) {
501 /* finished buffering the file */
502 close(h->fd);
503 h->fd = -1;
506 DEBUGF("buffer_handle(%d): buffered %ld bytes (%ld of %ld available, "
507 "rem: %ld, off: %ld)\n",
508 handle_id, (long)ret, (long)h->available, (long)h->filesize,
509 (long)h->filerem, (long)h->offset);
511 buffering = false;
512 return ret;
515 void request_buffer_handle(int handle_id)
517 LOGFQUEUE("buffering >| buffering Q_BUFFER_HANDLE");
518 queue_send(&buffering_queue, Q_BUFFER_HANDLE, handle_id);
521 /* Reset writing position and data buffer of a handle to its current offset.
522 Use this after having set the new offset to use.
523 Returns 0 for success or -1 if the handle wasn't found. */
524 static void reset_handle(int handle_id)
526 DEBUGF("reset_handle(%d)\n", handle_id);
528 struct memory_handle *h = find_handle(handle_id);
529 if (!h)
530 return;
532 h->widx = h->data;
533 if (h == cur_handle)
534 buf_widx = h->widx;
535 h->available = 0;
536 h->filerem = h->filesize - h->offset;
538 if (h->fd >= 0) {
539 lseek(h->fd, h->offset, SEEK_SET);
543 /* Seek to a nonbuffered part of a handle by rebuffering the data. */
544 static void rebuffer_handle(int handle_id, size_t newpos)
546 struct memory_handle *h = find_handle(handle_id);
547 if (!h)
548 return;
550 DEBUGF("rebuffer_handle: resetting the handle to offset %ld\n", (long)newpos);
551 h->offset = newpos;
553 LOGFQUEUE("? >| buffering Q_RESET_HANDLE");
554 queue_send(&buffering_queue, Q_RESET_HANDLE, handle_id);
556 LOGFQUEUE("? >| buffering Q_BUFFER_HANDLE");
557 queue_send(&buffering_queue, Q_BUFFER_HANDLE, handle_id);
559 h->ridx = h->data;
562 static int close_handle(int handle_id)
564 struct memory_handle *h = find_handle(handle_id);
565 if (!h)
566 return -1;
568 if (h->fd >= 0) {
569 close(h->fd);
570 h->fd = -1;
573 rm_handle(h);
574 return 0;
577 /* Free buffer space by moving the handle struct right before the useful
578 part of its data buffer or by moving all the data. */
579 static void shrink_handle(int handle_id)
581 struct memory_handle *h = find_handle(handle_id);
582 if (!h)
583 return;
585 size_t delta;
586 /* The value of delta might change for alignment reasons */
588 if (h->next && (h->type == TYPE_ID3 || h->type == TYPE_CUESHEET ||
589 h->type == TYPE_IMAGE) && h->filerem == 0 )
591 /* metadata handle: we can move all of it */
592 delta = RINGBUF_SUB( (unsigned)((void *)h->next - (void *)buffer),
593 h->data) - h->available;
594 h = move_handle(h, &delta, h->available);
595 if (!h) return;
596 h->data = RINGBUF_ADD(h->data, delta);
597 h->ridx = RINGBUF_ADD(h->ridx, delta);
598 h->widx = RINGBUF_ADD(h->widx, delta);
600 /* when moving a struct mp3entry we need to readjust its pointers. */
601 if (h->type == TYPE_ID3 && h->filesize == sizeof(struct mp3entry)) {
602 adjust_mp3entry((struct mp3entry *)&buffer[h->data],
603 (void *)&buffer[h->data],
604 (void *)&buffer[RINGBUF_SUB(h->data, delta)]);
607 DEBUGF("shrink_handle(%d): metadata, moved by %ld bytes\n",
608 handle_id, (long)delta);
610 else
612 /* only move the handle struct */
613 delta = RINGBUF_SUB(h->ridx, h->data);
614 h = move_handle(h, &delta, 0);
615 if (!h) return;
616 h->data = RINGBUF_ADD(h->data, delta);
617 h->available -= delta;
618 h->offset += delta;
619 DEBUGF("shrink_handle(%d): audio, %ld bytes freed\n",
620 handle_id, (long)delta);
624 /* Fill the buffer by buffering as much data as possible for handles that still
625 have data left to buffer */
626 static void fill_buffer(void)
628 DEBUGF("fill_buffer()\n");
629 struct memory_handle *m = first_handle;
630 while (queue_empty(&buffering_queue) && m) {
631 if (m->filerem > 0) {
632 buffer_handle(m->id);
634 m = m->next;
637 #ifndef SIMULATOR
638 if (queue_empty(&buffering_queue)) {
639 /* only spin the disk down if the filling wasn't interrupted by an
640 event arriving in the queue. */
641 ata_sleep();
643 #endif
646 /* Check whether it's safe to add a new handle and reserve space to let the
647 current one finish buffering its data. Used by bufopen and bufalloc as
648 a preliminary check before even trying to physically add the handle.
649 Returns true if it's ok to add a new handle, false if not.
651 static bool can_add_handle(void)
653 if (cur_handle && cur_handle->filerem > 0) {
654 /* the current handle hasn't finished buffering. We can only add
655 a new one if there is already enough free space to finish
656 the buffering. */
657 if (cur_handle->filerem < (buffer_len - BUF_USED)) {
658 /* Before adding the new handle we reserve some space for the
659 current one to finish buffering its data. */
660 buf_widx = RINGBUF_ADD(buf_widx, cur_handle->filerem);
661 } else {
662 return false;
666 return true;
669 /* Return the total amount of data left to be buffered for all the handles */
670 static size_t data_rem(void)
672 size_t ret = 0;
674 struct memory_handle *m = first_handle;
675 while (m) {
676 ret += m->filerem;
677 m = m->next;
680 return ret;
683 /* Return the amount of data we have but don't need anymore. This data can be
684 safely erased to reclaim buffer space. */
685 static size_t wasted_space(void)
687 size_t ret = 0;
689 struct memory_handle *m = first_handle;
690 while (m) {
691 ret += RINGBUF_SUB(m->ridx, m->data);
692 m = m->next;
695 return ret;
698 static size_t buffered_data(void)
700 size_t ret = 0;
701 struct memory_handle *m = first_handle;
702 while (m) {
703 ret += m->available;
704 m = m->next;
706 return ret;
709 size_t useful_data(int start_handle_id)
711 /* use a static var to remember which handle to start with when the caller
712 doesn't have access to the playback data. */
713 static int start_id = 0;
714 if (start_handle_id > 0)
715 start_id = start_handle_id;
717 size_t ret = 0;
718 struct memory_handle *m = first_handle;
719 while (m) {
720 if (m->id >= start_id)
721 ret += m->available - RINGBUF_SUB(m->ridx, m->data);
722 m = m->next;
724 return ret;
729 BUFFERING API FUNCTIONS
730 =======================
732 bufopen : Request the opening of a new handle for a file
733 bufalloc : Open a new handle for data other than a file.
734 bufclose : Close an open handle
735 bufseek : Set the read pointer in a handle
736 bufadvance : Move the read pointer in a handle
737 bufread : Copy data from a handle into a given buffer
738 bufgetdata : Give a pointer to the handle's data
739 bufused : Return the amount of buffer space used
741 These functions are exported, to allow interaction with the buffer.
742 They take care of the content of the structs, and rely on the linked list
743 management functions for all the actual handle management work.
747 /* Reserve space in the buffer for a file.
748 filename: name of the file to open
749 offset: offset at which to start buffering the file, useful when the first
750 (offset-1) bytes of the file aren't needed.
751 return value: <0 if the file cannot be opened, or one file already
752 queued to be opened, otherwise the handle for the file in the buffer
754 int bufopen(char *file, size_t offset, enum data_type type)
756 if (!can_add_handle())
757 return -2;
759 int fd = open(file, O_RDONLY);
760 if (fd < 0)
761 return -1;
763 size_t size = filesize(fd) - offset;
765 if (type != TYPE_AUDIO &&
766 size + sizeof(struct memory_handle) > buffer_len - buf_widx)
768 /* for types other than audio, the data can't wrap, so we force it */
769 buf_widx = 0;
772 DEBUGF("bufopen: %s (offset: %ld) (%ld bytes needed)...\n",
773 file, (long)offset, (long)size);
775 struct memory_handle *h = add_handle(&size);
776 if (!h)
778 DEBUGF("bufopen: failed to add handle\n");
779 close(fd);
780 return -2;
783 strncpy(h->path, file, MAX_PATH);
784 h->fd = -1;
785 h->filesize = filesize(fd);
786 h->filerem = h->filesize - offset;
787 h->offset = offset;
788 h->ridx = buf_widx;
789 h->widx = buf_widx;
790 h->data = buf_widx;
791 h->available = 0;
792 h->type = type;
794 close(fd);
796 DEBUGF("bufopen: allocated %ld bytes. ID: %d\n", (long)size, h->id);
798 if (type == TYPE_CODEC || type == TYPE_CUESHEET || type == TYPE_IMAGE) {
799 /* Immediately buffer those */
800 LOGFQUEUE("? >| buffering Q_BUFFER_HANDLE");
801 queue_send(&buffering_queue, Q_BUFFER_HANDLE, h->id);
804 DEBUGF("bufopen: opened handle %d\n", h->id);
805 return h->id;
808 /* Open a new handle from data that needs to be copied from memory.
809 src is the source buffer from which to copy data. It can be NULL to simply
810 reserve buffer space.
811 size is the requested size. The call will only be successful if the
812 requested amount of data can entirely fit in the buffer without wrapping.
813 Return value is the handle id for success or <0 for failure.
815 int bufalloc(void *src, size_t size, enum data_type type)
817 if (!can_add_handle())
818 return -2;
820 if (size + sizeof(struct memory_handle) > buffer_len - buf_widx) {
821 /* The data would need to wrap. */
822 DEBUGF("bufalloc: data wrap\n");
823 return -2;
826 size_t allocsize = size;
827 struct memory_handle *h = add_handle(&allocsize);
829 if (!h || allocsize != size)
830 return -2;
832 if (src) {
833 if (type == TYPE_ID3 && size == sizeof(struct mp3entry)) {
834 DEBUGF("bufalloc: allocating metadata\n");
835 /* specially take care of struct mp3entry */
836 copy_mp3entry((struct mp3entry *)&buffer[buf_widx],
837 (struct mp3entry *)src);
838 } else {
839 memcpy(&buffer[buf_widx], src, size);
843 h->fd = -1;
844 *h->path = 0;
845 h->filesize = size;
846 h->filerem = 0;
847 h->offset = 0;
848 h->ridx = buf_widx;
849 h->widx = buf_widx;
850 h->data = buf_widx;
851 h->available = size;
852 h->type = type;
854 buf_widx = RINGBUF_ADD(buf_widx, size);
856 DEBUGF("bufalloc: opened handle %d\n", h->id);
857 return h->id;
860 /* Close the handle. Return 0 for success and < 0 for failure */
861 int bufclose(int handle_id)
863 DEBUGF("bufclose(%d)\n", handle_id);
865 LOGFQUEUE("buffering >| Q_CLOSE_HANDLE");
866 return queue_send(&buffering_queue, Q_CLOSE_HANDLE, handle_id);
869 /* Set reading index in handle (relatively to the start of the file).
870 Access before the available data will trigger a rebuffer.
871 Return 0 for success and < 0 for failure:
872 -1 if the handle wasn't found
873 -2 if the new requested position was beyond the end of the file
875 int bufseek(int handle_id, size_t newpos)
877 struct memory_handle *h = find_handle(handle_id);
878 if (!h)
879 return -1;
881 if (newpos > h->filesize) {
882 /* access beyond the end of the file */
883 return -3;
885 else if (newpos < h->offset || h->offset + h->available < newpos) {
886 /* access before or after buffered data. A rebuffer is needed. */
887 rebuffer_handle(handle_id, newpos);
889 else {
890 h->ridx = RINGBUF_ADD(h->data, newpos - h->offset);
892 return 0;
895 /* Advance the reading index in a handle (relatively to its current position).
896 Return 0 for success and < 0 for failure */
897 int bufadvance(int handle_id, off_t offset)
899 struct memory_handle *h = find_handle(handle_id);
900 if (!h)
901 return -1;
903 size_t newpos = h->offset + RINGBUF_SUB(h->ridx, h->data) + offset;
905 return bufseek(handle_id, newpos);
908 /* Copy data from the given handle to the dest buffer.
909 Return the number of bytes copied or < 0 for failure. */
910 ssize_t bufread(int handle_id, size_t size, void *dest)
912 struct memory_handle *h = find_handle(handle_id);
913 size_t buffered_data;
914 if (!h)
915 return -1;
917 if (size == 0 && h->filerem > 0 &&
918 h->available - RINGBUF_SUB(h->ridx, h->data) == 0)
919 /* Data isn't ready */
920 return -2;
922 if (h->available - RINGBUF_SUB(h->ridx, h->data) < size && h->filerem > 0)
923 /* Data isn't ready */
924 return -2;
926 if (h->available - RINGBUF_SUB(h->ridx, h->data) == 0 && h->filerem == 0)
927 /* File is finished reading */
928 return 0;
930 buffered_data = MIN(size, h->available - RINGBUF_SUB(h->ridx, h->data));
932 if (h->ridx + buffered_data > buffer_len)
934 /* the data wraps around the end of the buffer */
935 size_t read = buffer_len - h->ridx;
936 memcpy(dest, &buffer[h->ridx], read);
937 memcpy(dest+read, buffer, buffered_data - read);
939 else memcpy(dest, &buffer[h->ridx], buffered_data);
941 return buffered_data;
944 /* Update the "data" pointer to make the handle's data available to the caller.
945 Return the length of the available linear data or < 0 for failure.
946 size is the amount of linear data requested. it can be 0 to get as
947 much as possible.
948 The guard buffer may be used to provide the requested size */
949 ssize_t bufgetdata(int handle_id, size_t size, void **data)
951 struct memory_handle *h = find_handle(handle_id);
952 if (!h)
953 return -1;
955 if (size == 0 && h->filerem > 0 &&
956 h->available - RINGBUF_SUB(h->ridx, h->data) == 0)
957 /* Data isn't ready */
958 return -2;
960 if (h->available - RINGBUF_SUB(h->ridx, h->data) < size && h->filerem > 0)
961 /* Data isn't ready */
962 return -2;
964 if (h->available - RINGBUF_SUB(h->ridx, h->data) == 0 && h->filerem == 0)
965 /* File is finished reading */
966 return 0;
968 ssize_t ret;
970 if (h->ridx + size > buffer_len &&
971 h->available - RINGBUF_SUB(h->ridx, h->data) >= size)
973 /* the data wraps around the end of the buffer :
974 use the guard buffer to provide the requested amount of data. */
975 size_t copy_n = MIN(h->ridx + size - buffer_len, GUARD_BUFSIZE);
976 memcpy(guard_buffer, (unsigned char *)buffer, copy_n);
977 ret = buffer_len - h->ridx + copy_n;
978 DEBUGF("used the guard buffer to complete\n");
980 else
982 ret = MIN(h->available - RINGBUF_SUB(h->ridx, h->data),
983 buffer_len - h->ridx);
986 *data = &buffer[h->ridx];
988 /* DEBUGF("bufgetdata(%d): h->ridx=%ld, ret=%ld\n", handle_id,
989 (long)h->ridx, ret); */
990 return ret;
993 /* Return the amount of buffer space used */
994 size_t bufused(void)
996 return BUF_USED;
999 /* Initialise the buffering subsystem */
1000 bool buffering_init(char *filebuf, size_t filebuflen)
1002 if (!filebuf || !filebuflen)
1003 return false;
1005 buffering = false;
1007 buffer = filebuf;
1008 buffer_len = filebuflen;
1009 guard_buffer = buffer + buffer_len;
1011 buf_widx = 0;
1012 buf_ridx = 0;
1014 first_handle = NULL;
1015 num_handles = 0;
1017 mutex_init(&llist_mutex);
1019 conf_filechunk = AUDIO_DEFAULT_FILECHUNK;
1020 conf_watermark = AUDIO_DEFAULT_WATERMARK;
1022 /* Set the high watermark as 75% full...or 25% empty :) */
1023 #if MEM > 8
1024 high_watermark = 3*filebuflen / 4;
1025 #endif
1027 buffering_thread_p = create_thread( buffering_thread, buffering_stack,
1028 sizeof(buffering_stack), 0,
1029 buffering_thread_name IF_PRIO(, PRIORITY_BUFFERING)
1030 IF_COP(, CPU));
1032 queue_init(&buffering_queue, true);
1033 queue_enable_queue_send(&buffering_queue, &buffering_queue_sender_list);
1035 return true;
1038 #if MEM > 8
1039 /* we dont want this rebuffering on targets with little ram
1040 because the disk may never spin down */
1041 static bool ata_fillbuffer_callback(void)
1043 queue_post(&buffering_queue, Q_BUFFERING_FILL_BUFFER_IF_ACTIVE_ATA, 0);
1044 return true;
1046 #endif
1048 void buffering_thread(void)
1050 struct queue_event ev;
1052 while (true)
1054 queue_wait_w_tmo(&buffering_queue, &ev, HZ/2);
1056 #if MEM > 8
1057 if ((ev.id == SYS_TIMEOUT) && (buffered_data() < high_watermark))
1058 register_ata_idle_func(ata_fillbuffer_callback);
1059 #endif
1061 switch (ev.id)
1063 case Q_BUFFER_HANDLE:
1064 LOGFQUEUE("buffering < Q_BUFFER_HANDLE");
1065 queue_reply(&buffering_queue, 1);
1066 buffer_handle((int)ev.data);
1067 break;
1069 case Q_RESET_HANDLE:
1070 LOGFQUEUE("buffering < Q_RESET_HANDLE");
1071 queue_reply(&buffering_queue, 1);
1072 reset_handle((int)ev.data);
1073 break;
1075 case Q_CLOSE_HANDLE:
1076 LOGFQUEUE("buffering < Q_CLOSE_HANDLE");
1077 queue_reply(&buffering_queue, close_handle((int)ev.data));
1078 break;
1080 #if MEM > 8
1081 case Q_BUFFERING_FILL_BUFFER_IF_ACTIVE_ATA:
1082 /* only fill if the disk is still spining */
1083 #ifndef SIMULATOR
1084 if (!ata_disk_is_active())
1085 break;
1086 #endif
1087 if (num_handles > 0 && data_rem() > 0)
1088 fill_buffer();
1089 break;
1090 #endif /* MEM > 8 */
1092 #ifndef SIMULATOR
1093 case SYS_USB_CONNECTED:
1094 LOGFQUEUE("buffering < SYS_USB_CONNECTED");
1095 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1096 usb_wait_for_disconnect(&buffering_queue);
1097 break;
1098 #endif
1100 case SYS_TIMEOUT:
1101 LOGFQUEUE_SYS_TIMEOUT("buffering < SYS_TIMEOUT");
1102 break;
1105 if (ev.id == SYS_TIMEOUT && queue_empty(&buffering_queue))
1107 if (data_rem() > 0 && wasted_space() > buffered_data()/2)
1109 DEBUGF("there is %ld bytes of wasted space\n",
1110 (long)wasted_space());
1112 /* free buffer from outdated audio data */
1113 struct memory_handle *m = first_handle;
1114 while (m) {
1115 if (m->type == TYPE_AUDIO)
1116 shrink_handle(m->id);
1117 m = m->next;
1120 /* free buffer by moving metadata */
1121 m = first_handle;
1122 while (m) {
1123 if (m->type != TYPE_AUDIO)
1124 shrink_handle(m->id);
1125 m = m->next;
1130 if (data_rem() > 0 && buffered_data() < conf_watermark)
1132 DEBUGF("%ld bytes left to buffer and the buffer is low\n",
1133 (long)data_rem());
1135 fill_buffer();
1141 /* Get a buffer offset from a pointer */
1142 ssize_t get_offset(int handle_id, void *ptr)
1144 struct memory_handle *h = find_handle(handle_id);
1145 if (!h)
1146 return -1;
1148 return (size_t)ptr - (size_t)&buffer[h->ridx];
1151 void buffering_get_debugdata(struct buffering_debug *dbgdata)
1153 dbgdata->num_handles = num_handles;
1154 dbgdata->data_rem = data_rem();
1155 dbgdata->wasted_space = wasted_space();
1156 dbgdata->buffered_data = buffered_data();
1157 dbgdata->useful_data = useful_data(0);
1158 dbgdata->buffering = buffering;