Index: apps/mp3data.h
===================================================================
--- apps/mp3data.h  (revision 29537)
+++ apps/mp3data.h  (working copy)
@@ -57,17 +57,29 @@

 #define MAX_XING_HEADER_SIZE 576

-unsigned long find_next_frame(int fd, long *offset, long max_offset,
-                              unsigned long last_header);
-unsigned long mem_find_next_frame(int startpos, long *offset, long max_offset,
-                                  unsigned long last_header);
-int get_mp3file_info(int fd, struct mp3info *info);
-int count_mp3_frames(int fd, int startpos, int filesize,
+unsigned long find_next_frame(int fd, 
+                              long *offset, 
+                              long max_offset,
+                              unsigned long reference_header);
+unsigned long mem_find_next_frame(int startpos, 
+                                  long *offset, 
+                                  long max_offset, 
+                                  unsigned long reference_header);
+int get_mp3file_info(int fd, 
+                     struct mp3info *info);
+int count_mp3_frames(int fd, 
+                     int startpos, 
+                     int filesize,
                      void (*progressfunc)(int));
-int create_xing_header(int fd, long startpos, long filesize,
-                       unsigned char *buf, unsigned long num_frames,
-                       unsigned long rec_time, unsigned long header_template,
-                       void (*progressfunc)(int), bool generate_toc);
+int create_xing_header(int fd, 
+                       long startpos, 
+                       long filesize,
+                       unsigned char *buf, 
+                       unsigned long num_frames,
+                       unsigned long rec_time, 
+                       unsigned long header_template,
+                       void (*progressfunc)(int), 
+                       bool generate_toc);

 extern unsigned long bytes2int(unsigned long b0,
                                unsigned long b1,
Index: apps/plugin.h
===================================================================
--- apps/plugin.h  (revision 29537)
+++ apps/plugin.h  (working copy)
@@ -818,7 +818,7 @@
             unsigned long rec_time, unsigned long header_template,
             void (*progressfunc)(int), bool generate_toc);
     unsigned long (*find_next_frame)(int fd, long *offset,
-            long max_offset, unsigned long last_header);
+            long max_offset, unsigned long reference_header);

 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
     unsigned short (*peak_meter_scale_value)(unsigned short val,
Index: apps/mp3data.c
===================================================================
--- apps/mp3data.c  (revision 29583)
+++ apps/mp3data.c  (working copy)
@@ -39,6 +39,7 @@
 #include "mp3data.h"
 #include "file.h"
 #include "buffer.h"
+#include "metadata/metadata_common.h"

 // #define DEBUG_VERBOSE

@@ -201,39 +202,73 @@
     return true;
 }

+static bool headers_have_same_type(unsigned long header1, 
+                                   unsigned long header2)
+{
+    /* Compare MPEG version, layer and sampling frequency. If header1 is zero
+     * it is assumed the headers are of same type. */
+    unsigned int mask = 0xfffe0c00;
+    header1 &= mask;
+    header2 &= mask;
+    return header1 ? (header1 == header2) : true;
+}
+
 static unsigned long __find_next_frame(int fd, long *offset, long max_offset,
-                                       unsigned long last_header,
-                                       int(*getfunc)(int fd, unsigned char *c))
+                                       unsigned long reference_header,
+                                       int(*getfunc)(int fd, unsigned char *c),
+                                       bool single_header)
 {
     unsigned long header=0;
     unsigned char tmp;
-    int i;
+    long pos      = 0;

-    long pos = 0;
-
-    /* We remember the last header we found, to use as a template to see if
-       the header we find has the same frequency, layer etc */
-    last_header &= 0xffff0c00;
-    
-    /* Fill up header with first 24 bits */
-    for(i = 0; i < 3; i++) {
-        header <<= 8;
-        if(!getfunc(fd, &tmp))
-            return 0;
-        header |= tmp;
-        pos++;
-    }
-
+    /* We will search until we find two consecutive MPEG frame headers with 
+     * the same MPEG version, layer and sampling frequency. The first header
+     * of this pair is assumed to be the first valid MPEG frame header of the
+     * whole stream. */
     do {
+        /* Read 1 new byte. */
         header <<= 8;
-        if(!getfunc(fd, &tmp))
+        if (!getfunc(fd, &tmp))
             return 0;
         header |= tmp;
         pos++;
-        if(max_offset > 0 && pos > max_offset)
+        
+        /* Abort if max_offset is reached. Stop parsing. */
+        if (max_offset > 0 && pos > max_offset)
             return 0;
-    } while(!is_mp3frameheader(header) ||
-            (last_header?((header & 0xffff0c00) != last_header):false));
+        
+        if (is_mp3frameheader(header)) {
+            if (single_header) {
+                /* We only search for a single valid header that has the same
+                 * type as the reference_header. We are finished. */
+                if (headers_have_same_type(reference_header, header))
+                    break;
+            } else {
+                /* The current header is valid. Now gather the frame size,
+                 * seek to this byte position and check if there is another
+                 * valid MPEG frame header of the same type. */
+                struct mp3info info;
+                
+                /* Gather frame size from given header and seek to next
+                 * frame header. */
+                mp3headerinfo(&info, header);
+                lseek(fd, info.frame_size-4, SEEK_CUR);
+                
+                /* Read possible next frame header and seek back to last frame
+                 * headers byte position. */
+                reference_header = 0;
+                read_uint32be(fd, (uint32_t*)&reference_header);
+                lseek(fd, -info.frame_size, SEEK_CUR);
+                
+                /* The current header is valid and is of the same type as the 
+                 * previous one. We are finished. */
+                if (headers_have_same_type(header, reference_header))
+                    break;
+            }
+        }
+  
+    } while (true);

     *offset = pos - 4;

@@ -248,9 +283,13 @@
     return read(fd, c, 1);
 }

-unsigned long find_next_frame(int fd, long *offset, long max_offset, unsigned long last_header)
+unsigned long find_next_frame(int fd, 
+                              long *offset, 
+                              long max_offset,
+                              unsigned long reference_header)
 {
-    return __find_next_frame(fd, offset, max_offset, last_header, fileread);
+    return __find_next_frame(fd, offset, max_offset, reference_header, 
+                             fileread, true);
 }

 #ifndef __PCTOOL__
@@ -312,10 +351,9 @@
     fnf_read_index = 0;
 }

-static unsigned long buf_find_next_frame(int fd, long *offset, long max_offset,
-                                         unsigned long last_header)
+static unsigned long buf_find_next_frame(int fd, long *offset, long max_offset)
 {
-    return __find_next_frame(fd, offset, max_offset, last_header, buf_getbyte);
+    return __find_next_frame(fd, offset, max_offset, 0, buf_getbyte, true);
 }

 static int audiobuflen;
@@ -337,15 +375,18 @@
         return 1;
 }

-unsigned long mem_find_next_frame(int startpos, long *offset, long max_offset,
-                                  unsigned long last_header)
+unsigned long mem_find_next_frame(int startpos, 
+                                  long *offset, 
+                                  long max_offset,
+                                  unsigned long reference_header)
 {
     audiobuflen = audiobufend - audiobuf;
     mem_pos = startpos;
     mem_cnt = 0;
     mem_maxlen = max_offset;

-    return __find_next_frame(0, offset, max_offset, last_header, mem_getbyte);
+    return __find_next_frame(0, offset, max_offset, reference_header, 
+                             mem_getbyte, true);
 }
 #endif

@@ -446,17 +487,20 @@
 }

 /* Seek to next mpeg header and extract relevant information. */
-static int get_next_header_info(int fd, long *bytecount, struct mp3info *info)
+static int get_next_header_info(int fd, long *bytecount, struct mp3info *info,
+                                bool single_header)
 {
     long tmp;
-    unsigned long header = find_next_frame(fd, &tmp, 0x20000, 0);
+    unsigned long header = 0;
+    
+    header = __find_next_frame(fd, &tmp, 0x20000, 0, fileread, single_header);
     if(header == 0)
         return -1;

     if(!mp3headerinfo(info, header))
         return -2;

-    /* Next header is tmp bytes away. */
+    /* Next frame header is tmp bytes away. */
     *bytecount += tmp;

     return 0;
@@ -478,8 +522,8 @@
     info->enc_padding = -1;
 #endif

-    /* Get the very first MPEG frame. */
-    result = get_next_header_info(fd, &bytecount, info);
+    /* Get the very first single MPEG frame. */
+    result = get_next_header_info(fd, &bytecount, info, true);
     if(result)
         return result;

@@ -514,7 +558,7 @@
         bytecount += info->frame_size;

         /* Now get the next frame to read the real info about the mp3 stream */
-        result = get_next_header_info(fd, &bytecount, info);
+        result = get_next_header_info(fd, &bytecount, info, false);
         if(result)
             return result;

@@ -528,7 +572,7 @@
         bytecount += info->frame_size;

         /* Now get the next frame to read the real info about the mp3 stream */
-        result = get_next_header_info(fd, &bytecount, info);
+        result = get_next_header_info(fd, &bytecount, info, false);
         if(result)
             return result;

@@ -537,6 +581,13 @@
     else
     {
         VDEBUGF("-- No VBR header --\n");
+        
+        /* There was no VBR header found. So, we seek back to beginning and
+         * search for the first MPEG frame header of the mp3 stream. */
+        lseek(fd, -info->frame_size, SEEK_CUR);
+        result = get_next_header_info(fd, &bytecount, info, false);
+        if(result)
+            return result;
     }

     return bytecount;
@@ -574,7 +625,7 @@
     num_frames = 0;
     cnt = 0;

-    while((header = buf_find_next_frame(fd, &bytes, -1, header_template))) {
+    while((header = buf_find_next_frame(fd, &bytes, header_template))) {
         mp3headerinfo(&info, header);

         if(!header_template)
@@ -649,7 +700,7 @@
             /* Advance from the last seek point to this one */
             for(j = 0;j < pos - last_pos;j++)
             {
-                header = buf_find_next_frame(fd, &bytes, -1, header_template);
+                header = buf_find_next_frame(fd, &bytes, header_template);
                 filepos += bytes;
                 mp3headerinfo(&info, header);
                 buf_seek(fd, info.frame_size-4);