Index: mythmusic/mythmusic/metaioid3v2.cpp
===================================================================
--- mythmusic/mythmusic/metaioid3v2.cpp	(revision 13054)
+++ mythmusic/mythmusic/metaioid3v2.cpp	(working copy)
@@ -12,7 +12,6 @@
 
 #include "metaio_libid3hack.h"
 
-
 #include <mythtv/mythcontext.h>
 
 //==========================================================================
@@ -241,6 +240,8 @@
             free(p_utf8);
         }
 
+         //length = getComment(tag, "TLEN").toInt();
+
         id3_file_close(p_input);
     }
 
@@ -250,7 +251,8 @@
         readFromFilename(filename, artist, album, title, genre, tracknum);
     }
 
-    length = getTrackLength(filename);
+    if (length <= 0)
+        length = getTrackLength(filename);
 
     // If we don't have title and artist or don't have the length return NULL
     if ((title.isEmpty() && artist.isEmpty()) || length<=0)
@@ -262,7 +264,7 @@
 
     Metadata *retdata = new Metadata(filename, artist, compilation_artist, album,
                                      title, genre, year, tracknum, length);
-                                     
+
     retdata->setCompilation(compilation);
 
     return retdata;
@@ -280,6 +282,7 @@
 {
     struct mad_stream stream;
     struct mad_header header;
+    struct mad_frame frame;
     mad_timer_t timer;
 
     unsigned char buffer[8192];
@@ -287,7 +290,8 @@
 
     mad_stream_init(&stream);
     mad_header_init(&header);
-   
+    mad_frame_init(&frame);
+
     timer = mad_timer_zero;
 
     FILE *input = fopen(filename.local8Bit(), "r");
@@ -340,6 +344,34 @@
             }
             else
             {
+
+                if (amount_checked == 0)
+                {
+                    frame.header = header;
+                    if (mad_frame_decode(&frame, &stream) == -1)
+                    {
+                            if (!MAD_RECOVERABLE(stream.error))
+                            {
+                                    VERBOSE(VB_IMPORTANT, "Unrecoverable libmad stream error.");
+                                    break;
+                            }
+                    }
+
+                    xing xing;
+                    xing.frames = 0;
+                    xing.bytes = 0;
+
+                    if (findXingHeader(&xing, stream.anc_ptr, stream.anc_bitlen))
+                    {
+                        unsigned long frames = xing.frames;
+                        mad_timer_t duration = header.duration;
+                        mad_timer_multiply(&duration, frames);
+                        alt_length = mad_timer_count(duration, MAD_UNITS_MILLISECONDS);
+                        loop_de_doo = false;
+                        break;
+                    }
+                }
+
                 if(amount_checked == 0)
                 {
                     old_bitrate = header.bitrate;
@@ -357,9 +389,9 @@
                 amount_checked++;
                 mad_timer_add(&timer, header.duration);
             }
-            
+
         }
-        
+
         if (stream.error != MAD_ERROR_BUFLEN)
             break;
 
@@ -369,6 +401,7 @@
 
     mad_header_finish(&header);
     mad_stream_finish(&stream);
+    mad_frame_finish(&frame);
 
     fclose(input);
 
@@ -378,7 +411,60 @@
     return alt_length;
 }
 
+bool MetaIOID3v2::findXingHeader(xing *xing, struct mad_bitptr ptr, unsigned int bitlen)
+{
+    if (bitlen < 64 || mad_bit_read(&ptr, 32) != XING_MAGIC)
+        goto fail;
 
+    xing->flags = mad_bit_read(&ptr, 32);
+    bitlen -= 64;
+
+    if (xing->flags & XING_FRAMES) {
+        if (bitlen < 32)
+            goto fail;
+
+        xing->frames = mad_bit_read(&ptr, 32);
+        bitlen -= 32;
+    }
+
+    if (xing->flags & XING_BYTES) {
+        if (bitlen < 32)
+            goto fail;
+
+        xing->bytes = mad_bit_read(&ptr, 32);
+        bitlen -= 32;
+    }
+
+    if (xing->flags & XING_TOC) {
+        int i;
+
+        if (bitlen < 800)
+            goto fail;
+
+        for (i = 0; i < 100; ++i)
+            xing->toc[i] = mad_bit_read(&ptr, 8);
+
+        bitlen -= 800;
+    }
+
+    if (xing->flags & XING_SCALE) {
+        if (bitlen < 32)
+            goto fail;
+
+        xing->scale = mad_bit_read(&ptr, 32);
+        bitlen -= 32;
+    }
+
+    return true;
+
+ fail:
+    xing->flags = 0;
+    xing->frames = 0;
+    xing->bytes = 0;
+    xing->scale = 0;
+    return false;
+}
+
 inline QString MetaIOID3v2::getRawID3String(union id3_field *pField)
 {
     QString tmp = "";
Index: mythmusic/mythmusic/metaioid3v2.h
===================================================================
--- mythmusic/mythmusic/metaioid3v2.h	(revision 13054)
+++ mythmusic/mythmusic/metaioid3v2.h	(working copy)
@@ -12,25 +12,44 @@
 #define MYTH_ID3_FRAME_COMMENT "TXXX"
 #define MYTH_ID3_FRAME_MUSICBRAINZ_ALBUMARTISTDESC "MusicBrainz Album Artist Id"
 
+#define XING_MAGIC     (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
+
+typedef struct {
+    int flags;
+    unsigned long frames;
+    unsigned long bytes;
+    unsigned char toc[100];
+    long scale;
+} xing;
+
 class MetaIOID3v2 : public MetaIO
 {
 public:
     MetaIOID3v2(void);
     virtual ~MetaIOID3v2(void);
-    
+
     bool write(Metadata* mdata, bool exclusive = false);
     Metadata* read(QString filename);
-    
+
 private:
+    enum {
+        XING_FRAMES = 0x0001,
+        XING_BYTES  = 0x0002,
+        XING_TOC    = 0x0004,
+        XING_SCALE  = 0x0008
+    };
+
     int getTrackLength(QString filename);
 
     QString getRawID3String(union id3_field *pField);
     void removeComment(id3_tag *pTag, const char* pLabel, const QString desc = "");
     QString getComment(id3_tag *pTag, const char* pLabel,
                        const QString desc = "");
-    
+
     bool setComment(id3_tag *pTag, const char* pLabel, const QString value,
                     const QString desc = "");
+
+    bool findXingHeader(xing *xing, struct mad_bitptr ptr, unsigned int bitlen);
 };
 
 #endif
