]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
simplify vss_read_chunk()
authorAndre Noll <maan@systemlinux.org>
Sun, 4 Mar 2007 22:22:43 +0000 (23:22 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 4 Mar 2007 22:22:43 +0000 (23:22 +0100)
All its parameters are known globally within vss.c, so omit them.
Also, return an int instead of the pointer to the inbuffer which is
also known to the caller.

This patch also introduces para_fseek() in fd.c which is used by
mp3.c and vss.c and changes the mp3 audio format handler so that it
uses the new function and always check the return value.

error.h
fd.c
fd.h
mp3_afh.c
vss.c

diff --git a/error.h b/error.h
index 537aca5723e48a2ea32037fd342dca2f5068859c..45485e1df68e65a67a7d3d622ccb124ea311b706 100644 (file)
--- a/error.h
+++ b/error.h
@@ -264,8 +264,6 @@ extern const char **para_errlist[];
 
 
 #define MP3_AFH_ERRORS \
-       PARA_ERROR(FREAD, "fread error"), \
-       PARA_ERROR(FSEEK, "fseek error"), \
        PARA_ERROR(FRAME, "invalid mp3 frame"), \
        PARA_ERROR(FRAME_LENGTH, "invalid frame length"), \
        PARA_ERROR(MP3_NO_FILE, "invalid mp3 file pointer"), \
@@ -303,6 +301,7 @@ extern const char **para_errlist[];
 #define VSS_ERRORS \
        PARA_ERROR(AUDIO_FORMAT, "audio format not recognized"), \
        PARA_ERROR(FSTAT, "failed to fstat() audio file"), \
+       PARA_ERROR(EMPTY_CHUNK, "empty chunk"), \
 
 
 #define AFS_ERRORS \
@@ -401,6 +400,8 @@ extern const char **para_errlist[];
        PARA_ERROR(F_GETFL, "failed to get fd flags"), \
        PARA_ERROR(F_SETFL, "failed to set fd flags"), \
        PARA_ERROR(FGETS, "fgets error"), \
+       PARA_ERROR(FSEEK, "fseek error"), \
+       PARA_ERROR(FREAD, "fread error"), \
 
 
 #define WRITE_ERRORS \
diff --git a/fd.c b/fd.c
index d53a3b4521fdbec1e16aa3263ba07f699feac40c..df7921b4f393c4b4c2bcfc963c757c0a67aec661 100644 (file)
--- a/fd.c
+++ b/fd.c
@@ -141,7 +141,7 @@ __must_check int para_fread(void *dest, size_t nbytes, size_t nmemb, FILE *strea
        return -E_FREAD;
 }
 /**
-* paraslash's wrapper for fgets(3)  
+* paraslash's wrapper for fgets(3)
 * \param line pointer to the buffer to store the line
 * \param size the size of the buffer given by \a line
 * \param f the stream to read from
@@ -166,3 +166,9 @@ again:
        clearerr(f);
        goto again;
 }
+
+int para_fseek(FILE *stream, long offset, int whence)
+{
+       int ret = fseek(stream, offset, whence);
+       return ret < 0? -E_FSEEK : ret;
+}
diff --git a/fd.h b/fd.h
index 6cb3cbadd004d623d54ad913df3cae383908ed51..5ae3331f91145ae0ce30b36e476f49d6f4b3abc7 100644 (file)
--- a/fd.h
+++ b/fd.h
@@ -26,3 +26,4 @@ void para_fd_set(int fd, fd_set *fds, int *max_fileno);
 __must_check int para_fread(void *dest, size_t nbytes, size_t nmemb,
                FILE *stream);
 __must_check int para_fgets(char *line, int size, FILE *f);
+int para_fseek(FILE *stream, long offset, int whence);
index 691f1f093c302320b8877cf6588fdec246bb6c51..4eaad087f1405d3b7ee85d8ec4121c0cac15bf21 100644 (file)
--- a/mp3_afh.c
+++ b/mp3_afh.c
@@ -252,7 +252,7 @@ static int get_header(FILE *file, struct mp3header *header)
  */
 static int mp3_seek_next_header(void)
 {
-       int k, l = 0, c, first_len;
+       int k, l = 0, c, first_len, ret;
        struct mp3header h, h2;
        long valid_start = 0;
 
@@ -266,17 +266,22 @@ static int mp3_seek_next_header(void)
                first_len = get_header(infile, &h);
                if (first_len <= 0)
                        continue;
-               if (fseek(infile, first_len - FRAME_HEADER_SIZE, SEEK_CUR) < 0)
-                       return -E_FSEEK;
+               ret = para_fseek(infile, first_len - FRAME_HEADER_SIZE, SEEK_CUR);
+               if (ret < 0)
+                       return ret;
                for (k = 1; k < MIN_CONSEC_GOOD_FRAMES; k++) {
                        if ((l = get_header(infile, &h2)) <= 0)
                                break;
                        if (!compare_headers(&h, &h2))
                                break;
-                       fseek(infile, l - FRAME_HEADER_SIZE, SEEK_CUR);
+                       ret = para_fseek(infile, l - FRAME_HEADER_SIZE, SEEK_CUR);
+                       if (ret < 0)
+                               return ret;
                }
                if (k == MIN_CONSEC_GOOD_FRAMES) {
-                       fseek(infile, valid_start, SEEK_SET);
+                       ret = para_fseek(infile, valid_start, SEEK_SET);
+                       if (ret < 0)
+                               return ret;
                        memcpy(&(mp3.header), &h2, sizeof(struct mp3header));
                        return first_len;
                }
@@ -286,6 +291,7 @@ static int mp3_seek_next_header(void)
 static int mp3_get_id3(void)
 {
        char fbuf[4];
+       int ret;
 
        mp3.id3_isvalid = 0;
        mp3.id3.title[0] = '\0';
@@ -293,8 +299,9 @@ static int mp3_get_id3(void)
        mp3.id3.album[0] = '\0';
        mp3.id3.comment[0] = '\0';
        mp3.id3.year[0] = '\0';
-       if (fseek(infile, -128, SEEK_END))
-               return -E_FSEEK;
+       ret = para_fseek(infile, -128, SEEK_END);
+       if (ret < 0 )
+               return ret;
        if (para_fread(fbuf, 1, 3, infile) < 0)
                return -E_FREAD;
        fbuf[3] = '\0';
@@ -302,8 +309,9 @@ static int mp3_get_id3(void)
                PARA_INFO_LOG("%s", "no id3 tag\n");
                return 0;
        }
-       if (fseek(infile, -125, SEEK_END) < 0)
-               return -E_FSEEK;
+       ret = para_fseek(infile, -125, SEEK_END);
+       if (ret < 0)
+               return ret;
        if (para_fread(mp3.id3.title, 1, 30, infile) != 30)
                return -E_FREAD;
        mp3.id3.title[30] = '\0';
@@ -330,7 +338,7 @@ static int mp3_get_id3(void)
 
 static int find_valid_start(void)
 {
-       int frame_len;
+       int ret, frame_len;
 
        if (!infile)
                return -E_MP3_NO_FILE;
@@ -341,9 +349,11 @@ static int find_valid_start(void)
                frame_len = mp3_seek_next_header();
                if (frame_len <= 0)
                        return frame_len;
-       } else
-               if (fseek(infile, -FRAME_HEADER_SIZE, SEEK_CUR) < 0)
-                       return -E_FSEEK;
+       } else {
+               ret = para_fseek(infile, -FRAME_HEADER_SIZE, SEEK_CUR);
+               if (ret < 0)
+                       return ret;
+       }
        if (frame_len <= 1)
                return -E_FRAME_LENGTH;
        return frame_len;
@@ -370,8 +380,8 @@ static int mp3_read_info(void)
                int freq, br, fl;
                struct timeval tmp, cct; /* current chunk time */
                if (len > 0) {
-                       ret = -E_FSEEK;
-                       if (fseek(infile, len, SEEK_CUR) < 0)
+                       ret = para_fseek(infile, len, SEEK_CUR);
+                       if (ret < 0)
                                goto err_out;
                }
                len = find_valid_start();
@@ -417,8 +427,8 @@ static int mp3_read_info(void)
        ret = -E_MP3_INFO;
        if (!num_chunks || !freq_avg || !br_avg)
                goto err_out;
-       ret = -E_FSEEK;
-       if (fseek(infile, 0, SEEK_END) < 0)
+       ret= para_fseek(infile, 0, SEEK_END);
+       if (ret < 0)
                goto err_out;
        chunk_table[num_chunks] = ftell(infile);
        mp3.br_average = br_avg;
diff --git a/vss.c b/vss.c
index f1dbfb97fa45db3c79628887f0783301f218b4e9..9aeff44fd77e508d7c842a386a115ef5f72330cf 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -501,33 +501,38 @@ again:
        return ret;
 }
 
-static char *vss_read_chunk(long unsigned current_chunk, ssize_t *len)
+/**
+ * read a chunk of data from the current audio file
+ *
+ * \param current_chunk the chunk number to read
+ *
+ * \return The length of the chunk on success, zero on end of file, negative on
+ * errors.  Note: If the current chunk is of length zero, but the end of the
+ * file is not yet reached, this function returns -E_EMPTY_CHUNK.
+ * */
+ssize_t vss_read_chunk(void)
 {
-       int ret;
+       ssize_t len;
        size_t pos;
-
-       *len = 0;
-       if (current_chunk >= mmd->chunks_total)
-               return NULL;
-       *len = chunk_table[current_chunk + 1] - chunk_table[current_chunk];
-       if (!*len) /* nothing to send for this run */
-               return inbuf;
-       pos = chunk_table[current_chunk];
-       if (inbuf_size < *len) {
-               PARA_INFO_LOG("increasing inbuf for chunk #%lu/%lu to %zd bytes\n",
-                       current_chunk, mmd->chunks_total, *len);
-               inbuf = para_realloc(inbuf, *len);
-               inbuf_size = *len;
+       int ret;
+       long unsigned cc = mmd->current_chunk;
+
+       if (cc >= mmd->chunks_total) /* eof */
+               return 0;
+       len = chunk_table[cc + 1] - chunk_table[cc];
+       if (!len) /* nothing to send for this run */
+               return -E_EMPTY_CHUNK;
+       pos = chunk_table[cc];
+       if (inbuf_size < len) {
+               PARA_INFO_LOG("increasing inbuf for chunk #%lu/%lu to %zu bytes\n",
+                       cc, mmd->chunks_total, len);
+               inbuf = para_realloc(inbuf, len);
+               inbuf_size = len;
        }
-//     PARA_DEBUG_LOG("reading chunk #%lu@%zd (%zd bytes)\n", current_chunk,
-//             pos, *len);
-       ret = fseek(audio_file, pos, SEEK_SET);
+       ret = para_fseek(audio_file, pos, SEEK_SET);
        if (ret < 0)
-               return NULL;
-       ret = para_fread(inbuf, *len, 1, audio_file);
-       if (ret != *len)
-               return NULL;
-       return inbuf;
+               return ret;
+       return para_fread(inbuf, len, 1, audio_file);
 }
 
 /**
@@ -546,7 +551,6 @@ void vss_send_chunk(void)
 {
        int i;
        struct audio_format_handler *af;
-       char *buf;
        ssize_t ret;
        struct timeval now, due;
 
@@ -562,16 +566,23 @@ void vss_send_chunk(void)
        if (chk_barrier("data send", &now, &data_send_barrier,
                        &due, 1) < 0)
                return;
-       buf = vss_read_chunk(mmd->current_chunk, &ret);
+       ret= vss_read_chunk();
        mmd->new_vss_status_flags &= ~VSS_REPOS;
-       if (!buf) {
-               if (ret < 0)
+       if (!ret || (ret < 0 && ret != -E_EMPTY_CHUNK)) {
+               if (ret < 0) {
                        mmd->new_vss_status_flags = VSS_NEXT;
-               else
+                       PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+               } else
                        mmd->new_vss_status_flags |= VSS_NEXT;
                vss_eof(af);
                return;
        }
+       /*
+        * We call the send function also in case of empty chunks as they
+        * might have still some data queued which can be sent in this case.
+        */
+       if (ret < 0)
+               ret = 0;
        if (!mmd->chunks_sent) {
                struct timeval tmp;
                gettimeofday(&mmd->stream_start, NULL);
@@ -580,7 +591,7 @@ void vss_send_chunk(void)
                mmd->events++;
        }
        for (i = 0; senders[i].name; i++)
-               senders[i].send(mmd->current_chunk, mmd->chunks_sent, buf, ret);
+               senders[i].send(mmd->current_chunk, mmd->chunks_sent, inbuf, ret);
        mmd->new_vss_status_flags |= VSS_PLAYING;
        mmd->chunks_sent++;
        mmd->current_chunk++;