[xiph-cvs] cvs commit: ices/src mp3.c

Brendan brendan at xiph.org
Sun Mar 16 16:45:10 PST 2003



brendan     03/03/16 19:45:10

  Modified:    src      mp3.c
  Log:
  Remove buffer alias in MP3 parsing function.
  Experimental MP3 cleaning code (trim junk and short frames from end), disabled
  by default. Define TRIM_FILE to test.

Revision  Changes    Path
1.29      +46 -11    ices/src/mp3.c

Index: mp3.c
===================================================================
RCS file: /cvs/ice/ices/src/mp3.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- mp3.c	16 Mar 2003 22:21:49 -0000	1.28
+++ mp3.c	17 Mar 2003 00:45:10 -0000	1.29
@@ -17,7 +17,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
- * $Id: mp3.c,v 1.28 2003/03/16 22:21:49 brendan Exp $
+ * $Id: mp3.c,v 1.29 2003/03/17 00:45:10 brendan Exp $
  */
 
 #include "definitions.h"
@@ -98,7 +98,6 @@
 static int ices_mp3_parse (input_stream_t* source)
 {
   ices_mp3_in_t* mp3_data = (ices_mp3_in_t*) source->data;
-  unsigned char *buffer;
   mp3_header_t mh;
   size_t len, framelen;
   int rc = 0;
@@ -116,7 +115,9 @@
     ices_id3v2_parse (source);
 
   /* adjust file size for short frames */
+#ifdef TRIM_FILE
   mp3_trim_file (source);
+#endif
 
   /* ensure we have at least 4 bytes in the read buffer */
   if (!mp3_data->buf || mp3_data->len - mp3_data->pos < 4)
@@ -127,12 +128,13 @@
   }
 
   /* seek past garbage if necessary */
-  buffer = mp3_data->buf;
   do {
     len = mp3_data->len - mp3_data->pos;
 
     /* copy remaining bytes to front, refill buffer without malloc/free */
     if (len < 4) {
+      char* buffer = mp3_data->buf;
+
       memcpy (buffer, buffer + mp3_data->pos, len);
       /* make read fetch from source instead of buffer */
       mp3_data->buf = NULL;
@@ -146,7 +148,7 @@
     /* we must be able to read at least 4 bytes of header */
     while (mp3_data->len - mp3_data->pos >= 4) {
       /* don't bother with free bit rate MP3s - they are so rare that a parse error is more likely */
-      if ((rc = mp3_parse_frame(buffer + mp3_data->pos, &mh))
+      if ((rc = mp3_parse_frame(mp3_data->buf + mp3_data->pos, &mh))
           && (framelen = mp3_frame_length (&mh))) {
         mp3_header_t next_header;
 
@@ -161,8 +163,6 @@
         /* check next frame if possible */
         if (mp3_fill_buffer (source, framelen + 4) <= 0)
           break;
-        /* note: take care with aliasing buffer/mp3_data->buf */
-        buffer = mp3_data->buf;
 
         /* if we can't find the second frame, we assume the first frame was junk */
         if ((rc = mp3_parse_frame(mp3_data->buf + mp3_data->pos + framelen, &next_header))) {
@@ -317,16 +317,51 @@
 
 /* trim short frame from end of file if necessary */
 static void mp3_trim_file (input_stream_t* self) {
-#if 0
   char buf[MP3_BUFFER_SIZE];
-  off_t cur;
-  int rc = 0;
+  mp3_header_t header;
+  off_t cur, start, end;
+  int framelen;
+  int rlen, len;
 
   if (! self->filesize)
     return;
+
   cur = lseek (self->fd, 0, SEEK_CUR);
-  while (!rc) {}
-#endif
+  end = self->filesize;
+  while (end > cur) {
+    start = end - sizeof(buf);
+    if (start < cur)
+      start = cur;
+
+    /* load buffer */
+    lseek (self->fd, start, SEEK_SET);
+    for (len = 0; start + len < end; len += rlen) {
+      if ((rlen = read (self->fd, buf + len, end - (start + len))) <= 0) {
+        ices_log_debug ("Error reading MP3 while trimming end");
+        lseek (self->fd, cur, SEEK_SET);
+        return;
+      }
+    }
+    end = start;
+
+    /* search buffer backwards looking for sync */
+    for (len -= 4; len >= 0; len--) {
+      if (mp3_parse_frame (buf + len, &header) && (framelen = mp3_frame_length (&header))) {
+        if (start + len + framelen < self->filesize) {
+          self->filesize = start + len + framelen;
+          ices_log_debug ("Trimmed file to %d bytes", self->filesize);
+        } else if (start + len + framelen > self->filesize) {
+          ices_log_debug ("Trimmed short frame (%d bytes missing) at offset %d",
+            (int)(start + len + framelen) - self->filesize, (int)start + len);
+          self->filesize = start + len;
+        }
+
+        lseek (self->fd, cur, SEEK_SET);
+        return;
+      }
+    }
+  }
+  lseek (self->fd, cur, SEEK_SET);
 }
 
 /* make sure source buffer has at least len bytes.

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list