Rewrite chunk queueing.
[paraslash.git] / afs.h
diff --git a/afs.h b/afs.h
index f1dc9b94380cb05724d6cab4c1f558a4f77ccc96..1fb6a435fe3a5b0c3706b58138b978847df25385 100644 (file)
--- a/afs.h
+++ b/afs.h
 /*
- * Copyright (C) 2005-2006 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2005-2007 Andre Noll <maan@systemlinux.org>
  *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ * Licensed under the GPL v2. For licencing details see COPYING.
  */
 
-/** \file afs.h functions and structures for audio format handling (para_server) */
+/** \file afs.h data structures common to all audio file selectors */
 
-/** \cond */
-#ifdef HAVE_OGGVORBIS
-#define OV_AUDIO_FORMAT " ogg"
-#define OV_AUDIO_FORMAT_ARRAY , "ogg"
-#else
-#define OV_AUDIO_FORMAT ""
-#define OV_AUDIO_FORMAT_ARRAY
-#endif
+#include <sys/select.h>
 
-#define SUPPORTED_AUDIO_FORMATS "mp3" OV_AUDIO_FORMAT
-#define SUPPORTED_AUDIO_FORMATS_ARRAY "mp3" OV_AUDIO_FORMAT_ARRAY, NULL
 
-
-/* status flags */
-#define AFS_NOMORE 1
-#define AFS_NEXT 2
-#define AFS_REPOS 4
-#define AFS_PLAYING 8
-#define DBT_CHANGE 16
-/** \endcond */
+int find_audio_files(const char *dirname, int (*f)(const char *, const char *));
 
 /**
- * structure for audio format handling
+ * describes one supported audio file selector
+ *
+ * There is one such struct for each supported selector.  During the startup
+ * part of para_server the \a init() function of the activated selector gets
+ * called which fills in all other function pointers.
  *
- * There's exactly one such struct for each supported audio format. Initially,
- * only \a name and \a init are defined. During the startup process,
- * para_server calls the \a init function of each audio format handler which is
- * expected to fill in all the other function pointers.
  */
-struct audio_format {
+struct audio_file_selector {
 /**
- *
- *
- * name of the audio format
+ * name name of this selector
  */
 const char *name;
 /**
+ * the init routine of the selector
  *
+ * It should check its command line options and do all necessary initialization
+ * like connecting to a database server.
  *
- * pointer to the audio format handler's init function
+ * A negative return value indicates an initialization error and means that
+ * this selector should be ignored for now (it may later be activated again via
+ * the chs command).
  *
- * Must initialize all function pointers and is assumed to succeed.
+ * If \a init() returns success (non-negative return value), it must have
+ * initialized in all non-optional function pointers of the given selector
+ * struct. Moreover, \a cmd_list must point to a NULL-terminated array which
+ * holds the list of all commands that are supported by this selector.
  */
-void (*init)(void*);
+int (*init)(struct audio_file_selector *self);
 /**
- *
- *
- * period of time between sending data chunks
-*/
-struct timeval chunk_tv; /* length of one chunk of data */
+ * list of commands supported by this selector
+ */
+struct server_command *cmd_list;
 /**
+ * pointer to function returning list of at most \a num audio files to be
+ * streamed next
  *
- *
- * end of file timeout - do not load new audio file until this time
+ * \a get_audio_file_list() must return a pointer to a array of at most \a num
+ * char* pointers (terminated by a NULL pointer), or NULL on errors.  Both the
+ * array and its contents must be dynamically allocated and are freed by the
+ * caller.
  *
 */
-struct timeval eof_tv; /* timeout on eof */
+char **(*get_audio_file_list)(unsigned int num);
 /**
  *
+ * the update hook
  *
- * Pointer to the optional get-header function.
+ * The \a update_audio_file pointer is optional and need not be supplied. In this
+ * case it is not neccessary to init this pointer from within init(). If
+ * \a update_audio_file is non-NULL, the function it points to gets called
+ * whenever a new audio file was successfully loaded and is going to be
+ * streamed by any of paraslash's senders. The full path of the audio file is
+ * passed \a update_audio_file().
  *
- * This is called from a sender in case a new client connects in the middle of
- * the stream.  The audio format handler may set this to NULL to indicate that
- * this audio format does not need any special header treatment.  If non-NULL,
- * the function it points to must return a pointer to a buffer holding the
- * current audio file header, together with the header length.
-*/
-char *(*get_header_info)(int *header_len);
+ */
+void (*update_audio_file)(char *audio_file);
 /**
  *
+ * shutdown this selector and free all resources
  *
- * check if this audio format handler can handle the file
- *
- * This is a  pointer to a function returning whether a given file is valid for
- * this audio format. A negative return value indicates that this audio format
- * handler did not recognize the given file. On success, the function is
- * expected to return a positive value and to fill in \arg info_str, \arg
- * chunks and \arg seconds appropriately.
-*/
-int (*get_file_info)(FILE *audio_file, char *info_str,
-       long unsigned *chunks, int *seconds);
+ * This gets called whenever the audio file selector changes. The reason for
+ * this change might be that some user sent the chs command, that para_server
+ * receives the HUP signal, or that para_server shuts down. It is assumed to
+ * succeed.
+ */
+void (*shutdown)(void);
 /**
  *
+ * add file descriptors to fd_sets
  *
- * cleanup function of this audio format handler
+ * The pre_select function of the activated selector gets called just before
+ * para_server enters its main select loop. The selector may add its own file
+ * descriptors to the \a rfds or the \a wfds set.
  *
- * This close function should deallocate any resources
- * associated with the current audio file. In particular, it is responsible
- * for closing the file handle. It is assumed to succeed.
-*/
-void (*close_audio_file)(void);
-/**
+ * \return The highest-numbered file descriptor which was added to either of
+ * the two fd sets (or -1 if no file descriptors were added).
  *
- *
- * jump to another position in the current audio file
- *
- * This is called if a client issued the ff or jmp command with \a request
- * being the number of the next chunk that should be sent out. Must return a
- * positive value on success and a negative value on errors.
-*/
-int (*reposition_stream)(long unsigned request);
+ * \sa select(2)
+ */
+int (*pre_select)(fd_set *rfds, fd_set *wfds);
 /**
+ * handle the file descriptors which are ready for I/O
  *
- *
- * function responsible for reading one data chunk.
- *
- * \a read_chunk() must return a pointer to the next chunk of data that should
- * be sent out, or \p NULL on errors or if the end of the file was encountered.
- *
- * If it returns non-NULL, \a len must contain the length of the returned
- * buffer (which may be zero if nothing has to be sent for some reason).
- * Otherwise, \a len is used to distinguish between the eof and the error case:
- * It must be zero in the eof case, or negative if an error occcured.
-*/
-char * (*read_chunk)(long unsigned chunk_num, ssize_t *len);
+ * If the pre_select hook added one ore more file descriptors to the read or write
+ * set, this is the hook to check the result and do any I/O on those descriptors
+ * which are ready for reading/writing.
+ */
+void (*post_select)(fd_set *rfds, fd_set *wfds);
+/**
+ * each selector has its private data pointer */
+void *private_data;
 };
 
-void afs_init(void);
-void afs_send_chunk(void);
-struct timeval *afs_preselect(void);
-const char *audio_format_name(int);
-unsigned int afs_playing(void);
-unsigned int afs_next(void);
-unsigned int afs_repos(void);
-unsigned int afs_paused(void);
+int mysql_selector_init(struct audio_file_selector*);
+int playlist_selector_init(struct audio_file_selector*);
+int random_selector_init(struct audio_file_selector*);