major afs cleanup
authorAndre <maan@p133.(none)>
Wed, 17 May 2006 19:22:59 +0000 (21:22 +0200)
committerAndre <maan@p133.(none)>
Wed, 17 May 2006 19:22:59 +0000 (21:22 +0200)
This patch  makes afs.c the only user of the audio format handler
arry afl[] in order to completely separate audio format handling from
audio file sending.

This is achieved by providing the new helper functions afs_get_header()
and afs_chunk_time(). audio file senders may call these functions
without knowledge of struct audio_format. This allows to get rid of
the "af" parameter for the pre_select and post_select functions of
struct sender.

Related to this cleanup is the removal of match_audio_file_name() from db.c
which also depended on afl[]. This function was essentially identical to
afs.c's guess_audio_format(), so make the latter public and use it from
within db.c.

afs.c
afs.h
audiod.c
db.c
dccp_send.c
http_send.c
ortp_send.c
send.h
server.c

diff --git a/afs.c b/afs.c
index 918c563..e3b0db5 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -58,7 +58,7 @@ static FILE *audio_file = NULL;
 /**
  * the list of supported  audio formats
  */
-struct audio_format_handler afl[] = {
+static struct audio_format_handler afl[] = {
 #if 1
        {
                .name = "mp3",
@@ -81,7 +81,7 @@ struct audio_format_handler afl[] = {
                .name = NULL,
        }
 };
-
+#define FOR_EACH_AUDIO_FORMAT(i) for (i = 0; afl[i].name; i++)
 
 /**
  * check if audio file sender is playing
@@ -174,25 +174,30 @@ static int get_file_info(int i)
                &mmd->chunks_total, &mmd->seconds_total);
 }
 
-/*
+/**
  * guess the audio format judging from filename
+ *
  * \param name the filename
  *
  * \return This function returns -1 if it has no idea what kind of audio
  * file this might be. Otherwise the (non-negative) number of the audio format
  * is returned.
  */
-static int guess_audio_format(const char *name)
+int guess_audio_format(const char *name)
 {
-
-       int i, len1 = strlen(name), len2;
-
-       for (i = 0; afl[i].name; i++) {
-               len2 = strlen(afl[i].name);
-               if (len1 < len2)
-                       continue;
-               if (!strncasecmp(name + (len1 - len2), afl[i].name, len2)) {
-                       PARA_DEBUG_LOG("might be %s\n", afl[i].name);
+       int i,j, len = strlen(name);
+
+       FOR_EACH_AUDIO_FORMAT(i) {
+               for (j = 0; afl[i].suffixes[j]; j++) {
+                       const char *p = afl[i].suffixes[j];
+                       int plen = strlen(p);
+                       if (len < plen + 1)
+                               continue;
+                       if (name[len - plen - 1] != '.')
+                               continue;
+                       if (strcasecmp(name + len - plen, p))
+                               continue;
+                       PARA_DEBUG_LOG("might be %s\n", audio_format_name(i));
                        return i;
                }
        }
@@ -203,7 +208,7 @@ static int get_audio_format(int omit)
 {
        int i;
 
-       for (i = 0; afl[i].name; i++) {
+       FOR_EACH_AUDIO_FORMAT(i) {
                if (i == omit || !afl[i].get_file_info)
                        continue;
                rewind(audio_file);
@@ -369,6 +374,39 @@ static void afs_eof(struct audio_format_handler *af)
        mmd->events++;
 }
 
+/**
+ * get the header and of the current audio file
+ *
+ * \param header_len the length of the header is stored here
+ *
+ * \return a pointer to a buffer containing the header, or NULL, if no audio
+ * file is selected or if the current audio format does not need special header
+ * treamtment.
+ *
+ */
+char *afs_get_header(int *header_len)
+{
+       *header_len = 0;
+       if (mmd->audio_format < 0)
+               return NULL;
+       if (!afl[mmd->audio_format].get_header_info)
+               return NULL;
+       return afl[mmd->audio_format].get_header_info(header_len);
+}
+
+/**
+ * get the chunk time of the current audio file
+ *
+ * \return a pointer to a struct containing the chunk time, or NULL,
+ * if currently no audio file is selected.
+ */
+struct timeval *afs_chunk_time(void)
+{
+       if (mmd->audio_format < 0)
+               return NULL;
+       return &afl[mmd->audio_format].chunk_tv;
+}
+
 /**
  * compute the timeout for para_server's main select-loop
  *
@@ -484,8 +522,7 @@ void afs_send_chunk(void)
                mmd->events++;
        }
        for (i = 0; senders[i].name; i++)
-               senders[i].send(af, mmd->current_chunk,
-                       mmd->chunks_sent, buf, ret);
+               senders[i].send(mmd->current_chunk, mmd->chunks_sent, buf, ret);
        mmd->new_afs_status_flags |= AFS_PLAYING;
        mmd->chunks_sent++;
        mmd->current_chunk++;
diff --git a/afs.h b/afs.h
index c34f881..3725ffa 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -130,8 +130,6 @@ struct audio_format_handler {
        char * (*read_chunk)(long unsigned chunk_num, ssize_t *len);
 };
 
-extern struct audio_format_handler afl[];
-#define FOR_EACH_AUDIO_FORMAT(i) for (i = 0; afl[i].name; i++)
 
 void afs_init(void);
 void afs_send_chunk(void);
@@ -141,4 +139,6 @@ unsigned int afs_playing(void);
 unsigned int afs_next(void);
 unsigned int afs_repos(void);
 unsigned int afs_paused(void);
-
+char *afs_get_header(int *header_len);
+struct timeval *afs_chunk_time(void);
+int guess_audio_format(const char *name);
index 8d1d8eb..e155161 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -935,6 +935,7 @@ static void close_decoder_if_idle(int slot_num)
                        return;
        }
        if (s->write_fd > 0) {
+               PARA_INFO_LOG("err: %d\n", s->fci->error);
                PARA_INFO_LOG("slot %d: closing write fd %d\n", slot_num,
                        s->write_fd);
                close(s->write_fd);
diff --git a/db.c b/db.c
index cb6f692..9db622b 100644 (file)
--- a/db.c
+++ b/db.c
 #include "error.h"
 #include "string.h"
 
-/*
- * return 1 if name matches any supported audio format
- */
-static int match_audio_file_name(char *name)
-{
-       int i,j, len = strlen(name);
-
-       FOR_EACH_AUDIO_FORMAT(i) {
-               for (j = 0; afl[i].suffixes[j]; j++) {
-                       const char *p = afl[i].suffixes[j];
-                       int plen = strlen(p);
-                       if (len < plen + 1)
-                               continue;
-                       if (name[len - plen - 1] != '.')
-                               continue;
-                       if (strcasecmp(name + len - plen, p))
-                               continue;
-                       return 1;
-               }
-       }
-       return 0;
-}
-
 /**
  * traverse the given directory recursively
  *
@@ -103,7 +80,7 @@ int find_audio_files(const char *dirname, int (*f)(const char *, const char *))
                if (!S_ISREG(m) && !S_ISDIR(m)) /* skip links, sockets, ... */
                        continue;
                if (S_ISREG(m)) { /* regular file */
-                       if (!match_audio_file_name(entry->d_name))
+                       if (guess_audio_format(entry->d_name) < 0)
                                continue;
                        if (f(dirname, entry->d_name) < 0)
                                goto out;
index 855780e..546056a 100644 (file)
@@ -50,8 +50,8 @@ struct dccp_client {
        int header_sent;
 };
 
-static void dccp_pre_select(__a_unused struct audio_format_handler *af,
-               int *max_fileno, fd_set *rfds, __a_unused fd_set *wfds)
+static void dccp_pre_select( int *max_fileno, fd_set *rfds,
+               __a_unused fd_set *wfds)
 {
        if (listen_fd < 0)
                return;
@@ -59,8 +59,7 @@ static void dccp_pre_select(__a_unused struct audio_format_handler *af,
        *max_fileno = PARA_MAX(*max_fileno, listen_fd);
 }
 
-static void dccp_post_select(__a_unused struct audio_format_handler *af,
-               fd_set *rfds, __a_unused fd_set *wfds)
+static void dccp_post_select(fd_set *rfds, __a_unused fd_set *wfds)
 {
        struct dccp_client *dc;
        int ret;
@@ -133,8 +132,7 @@ err_out:
        return -E_DCCP_WRITE;
 }
 
-static void dccp_send(__a_unused struct audio_format_handler *af,
-               long unsigned current_chunk,
+static void dccp_send(long unsigned current_chunk,
                __a_unused long unsigned chunks_sent, const char *buf, size_t len)
 {
        struct dccp_client *dc, *tmp;
@@ -152,8 +150,8 @@ static void dccp_send(__a_unused struct audio_format_handler *af,
                }
                if (!ret)
                        continue;
-               if (!dc->header_sent && af->get_header_info && current_chunk) {
-                       header_buf = af->get_header_info(&header_len);
+               if (!dc->header_sent && current_chunk) {
+                       header_buf = afs_get_header(&header_len);
                        if (!header_buf || header_len <= 0)
                                continue; /* header not yet available */
                        ret = dccp_write(dc->fd, header_buf, header_len);
index f9345ac..6aa82e4 100644 (file)
@@ -206,9 +206,8 @@ static int send_queued_packets(struct http_client *hc)
        return 1;
 }
 
-static void http_send(__a_unused struct audio_format_handler *af,
-               long unsigned current_chunk,
-               __a_unused long unsigned chunks_sent, const char *buf, size_t len)
+static void http_send( long unsigned current_chunk,
+       __a_unused long unsigned chunks_sent, const char *buf, size_t len)
 {
        struct http_client *hc, *tmp;
        int ret;
@@ -218,12 +217,10 @@ static void http_send(__a_unused struct audio_format_handler *af,
                                hc->status != HTTP_READY_TO_STREAM)
                        continue;
                if (hc->status == HTTP_READY_TO_STREAM) {
-                       if (af->get_header_info && current_chunk) {
+                       int hlen;
+                       char *buf = afs_get_header(&hlen);
+                       if (buf && hlen > 0 && current_chunk) {
                                /* need to send header */
-                               int hlen;
-                               char *buf = af->get_header_info(&hlen);
-                               if (!buf || hlen <= 0)
-                                       continue; /* header not yet available */
                                PARA_INFO_LOG("queueing header: %d\n", hlen);
                                if (queue_packet(hc, buf, hlen) < 0)
                                        continue;
@@ -267,8 +264,7 @@ static int host_in_access_perm_list(struct http_client *hc)
        return 0;
 }
 
-static void http_post_select(__a_unused struct audio_format_handler *af, fd_set *rfds,
-               fd_set *wfds)
+static void http_post_select(fd_set *rfds, fd_set *wfds)
 {
        int i = -1, match;
        struct http_client *hc, *tmp;
@@ -347,8 +343,7 @@ err_out:
        free(hc);
 }
 
-static void http_pre_select(struct audio_format_handler *af, int *max_fileno,
-       fd_set *rfds, fd_set *wfds)
+static void http_pre_select(int *max_fileno, fd_set *rfds, fd_set *wfds)
 {
        struct http_client *hc, *tmp;
 
@@ -373,7 +368,7 @@ static void http_pre_select(struct audio_format_handler *af, int *max_fileno,
                        hc->check_w = 1;
                        break;
                case HTTP_SENT_OK_MSG:
-                       if (!af || !afs_playing())
+                       if (!afs_playing())
                                break; /* wait until server starts playing */
                        para_fd_set(hc->fd, wfds, max_fileno);
                        hc->check_w = 1;
index 46b3ece..9d24422 100644 (file)
@@ -133,27 +133,36 @@ static void ortp_shutdown_targets(void)
        }
 }
 
-static int need_extra_header(struct audio_format_handler *af,
-               long unsigned chunks_sent)
+static int need_extra_header(long unsigned current_chunk)
 {
-       /* FIXME: No need to compute this on every run */
-       int mod = conf.ortp_header_interval_arg / (tv2ms(&af->chunk_tv) + 1);
-       if (mod && (chunks_sent % mod))
+       static struct timeval last_header;
+       struct timeval now, diff;
+
+       if (!current_chunk)
+               return 0;
+       gettimeofday(&now, NULL);
+       tv_diff(&now, &last_header, &diff);
+       if (tv2ms(&diff) < conf.ortp_header_interval_arg)
                return 0;
+       last_header = now;
        return 1;
 }
 
-static void ortp_send(struct audio_format_handler *af, long unsigned current_chunk,
-               long unsigned chunks_sent, const char *buf, size_t len)
+static void ortp_send(long unsigned current_chunk, long unsigned chunks_sent,
+               const char *buf, size_t len)
 {
        struct ortp_target *ot, *tmp;
        size_t sendbuf_len;
        int header_len = 0;
-       int packet_type = ORTP_DATA, stream_type = af && af->get_header_info; /* header stream? */
+       int packet_type = ORTP_DATA;
        char *sendbuf, *header_buf = NULL;
+       struct timeval *chunk_tv;
 
        if (self->status != SENDER_ON)
                return;
+       chunk_tv = afs_chunk_time();
+       if (!chunk_tv)
+               return;
        list_for_each_entry_safe(ot, tmp, &targets, node) {
                if (!ot->session) {
                        ortp_init_session(ot);
@@ -162,18 +171,16 @@ static void ortp_send(struct audio_format_handler *af, long unsigned current_chu
                }
                if (!ot->chunk_ts)
                        ot->chunk_ts = rtp_session_time_to_ts(ot->session,
-                               tv2ms(&af->chunk_tv));
+                               tv2ms(chunk_tv));
 //             PARA_DEBUG_LOG("len: %d, ts: %lu, ts: %d\n",
 //                     len, ot->chunk_ts * chunks_sent, ot->chunk_ts);
                ot->streaming = 1;
        }
        if (list_empty(&targets))
                return;
-       if (stream_type) {
-               header_buf = af->get_header_info(&header_len);
-               if (!need_extra_header(af, chunks_sent))
-                       header_len = 0;
-       }
+       header_buf = afs_get_header(&header_len);
+       if (!need_extra_header(current_chunk))
+               header_len = 0;
        sendbuf_len = ORTP_AUDIO_HEADER_LEN + header_len + len;
        sendbuf = para_malloc(sendbuf_len);
        if (!current_chunk)
@@ -181,8 +188,8 @@ static void ortp_send(struct audio_format_handler *af, long unsigned current_chu
        else if (header_len)
                packet_type = ORTP_HEADER;
        WRITE_PACKET_TYPE(sendbuf, packet_type);
-       WRITE_CHUNK_TIME(sendbuf, af->chunk_tv.tv_usec);
-       WRITE_STREAM_TYPE(sendbuf, stream_type);
+       WRITE_CHUNK_TIME(sendbuf, chunk_tv->tv_usec);
+       WRITE_STREAM_TYPE(sendbuf,  header_buf? 1 : 0);
        WRITE_HEADER_LEN(sendbuf, header_len);
        if (header_len)
                memcpy(sendbuf + ORTP_AUDIO_HEADER_LEN, header_buf,
@@ -290,8 +297,7 @@ success:
        }
 }
 
-static void ortp_pre_select(__a_unused struct audio_format_handler *af,
-       __a_unused  int *max_fileno, __a_unused fd_set *rfds,
+static void ortp_pre_select(__a_unused  int *max_fileno, __a_unused fd_set *rfds,
        __a_unused fd_set *wfds)
 {
        return;
diff --git a/send.h b/send.h
index f7198ed..bf1ca11 100644 (file)
--- a/send.h
+++ b/send.h
@@ -45,8 +45,8 @@ struct sender {
  * command. Of course, \a buf is a pointer to the chunk of data which
  * should be sent, and \a len is the length of this buffer.
 */
-       void (*send)(struct audio_format_handler *af, long unsigned current_chunk,
-               long unsigned chunks_sent, const char *buf, size_t len);
+       void (*send)(long unsigned current_chunk, long unsigned chunks_sent,
+               const char *buf, size_t len);
 /** add file descriptors to fd_sets
  *
  * The pre_select function of each supported sender is called just before
@@ -58,8 +58,7 @@ struct sender {
  *
  * \sa select(2)
 */
-       void (*pre_select)(struct audio_format_handler *af, int *max_fileno, fd_set *rfds,
-               fd_set *wfds);
+       void (*pre_select)(int *max_fileno, fd_set *rfds, fd_set *wfds);
 /**
  * handle the file descriptors which are ready for I/O
  *
@@ -67,7 +66,7 @@ struct sender {
  * 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)(struct audio_format_handler *af, fd_set *rfds, fd_set *wfds);
+       void (*post_select)(fd_set *rfds, fd_set *wfds);
 /**
  * terminate all connected clients
  *
index 5616273..2391e07 100644 (file)
--- a/server.c
+++ b/server.c
@@ -449,10 +449,7 @@ repeat:
                        continue;
                if (!senders[i].pre_select)
                        continue;
-               senders[i].pre_select(mmd->audio_format >= 0?
-                       &afl[mmd->audio_format] : NULL,
-                       &max_fileno,
-                       &rfds, &wfds);
+               senders[i].pre_select( &max_fileno, &rfds, &wfds);
        }
        if (selectors[mmd->selector_num].pre_select) {
                ret = selectors[mmd->selector_num].pre_select(&rfds, &wfds);
@@ -472,9 +469,7 @@ repeat:
                        continue;
                if (!senders[i].post_select)
                        continue;
-               senders[i].post_select(mmd->audio_format >= 0?
-                       &afl[mmd->audio_format] : NULL,
-                       &rfds, &wfds);
+               senders[i].post_select(&rfds, &wfds);
        }
        afs_send_chunk();
        status_refresh();