Index: xbmc/Util.cpp =================================================================== --- xbmc/Util.cpp (revision 23215) +++ xbmc/Util.cpp (working copy) @@ -1089,22 +1089,28 @@ { CStdString strResult; + printf("orig: %s\n", strURLData.c_str()); /* wonder what a good value is here is, depends on how often it occurs */ strResult.reserve( strURLData.length() * 2 ); for (int i = 0; i < (int)strURLData.size(); ++i) { int kar = (unsigned char)strURLData[i]; - //if (kar == ' ') strResult += '+'; - if (isalnum(kar)) strResult += kar; + if (isalnum(kar) || kar == '.' || kar == '_' || kar == '-') + { + printf("keeping %c\n", kar); + strResult += kar; + } else { + printf("replacing %c\n", kar); CStdString strTmp; strTmp.Format("%%%02.2x", kar); strResult += strTmp; } } strURLData = strResult; + printf("new: %s\n", strURLData.c_str()); } bool CUtil::GetDirectoryName(const CStdString& strFileName, CStdString& strDescription) Index: xbmc/MusicInfoTagLoaderAAC.cpp =================================================================== --- xbmc/MusicInfoTagLoaderAAC.cpp (revision 23215) +++ xbmc/MusicInfoTagLoaderAAC.cpp (working copy) @@ -16,12 +16,20 @@ * along with XBMC; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html + * + * ReadADIFHeaderDuration and ReadADTSHeaderDuration adapted from + * libfaad's aadinfo.c. + * FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding + * Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com + * Copyright (C) 2009 T. Nelson, XBMC Media Center, xbmc.org * */ #include "MusicInfoTagLoaderAAC.h" -#include "cores/paplayer/AACcodec.h" +#include "File.h" +const static int aac_sample_rates[] = {96000,88200,64000,48000,44100,32000, + 24000,22050,16000,12000,11025,8000}; using namespace MUSIC_INFO; @@ -33,10 +41,100 @@ int CMusicInfoTagLoaderAAC::ReadDuration(const CStdString& strFileName) { - AACCodec codec; - if (codec.Init(strFileName, 4096)) + int duration = 0; + XFILE::CFile file; + if (file.Open(strFileName)) { - return (int)((codec.m_TotalTime + 500) / 1000); + int tagOffset = ReadID3Length(file); + + do + { + if ((duration = ReadALACDuration(file, tagOffset))) + break; + if ((duration = ReadMP4Duration(file, tagOffset))) + break; + duration = ReadAACDuration(file, tagOffset); + } while(0); + file.Close(); } + + return (int)((duration + 500) / 1000); +} + +int CMusicInfoTagLoaderAAC::ReadID3Length(XFILE::CFile& file) +{ + char buf[10] = {}; + int tagLength = 0; + while (file.Read(buf, 10) == 10) + { + if (!memcmp(buf, "ID3", 3)) + break; + tagLength += ((buf[6] << 21) | (buf[7] << 14) | (buf[8] << 7) | buf[9]) + 10; + file.Seek(tagLength); + } + return 0; } + +// TODO: Snag license from aacinfo +int CMusicInfoTagLoaderAAC::ReadAACDuration(XFILE::CFile& file, int offset) +{ + char buf[4] = {}; + + file.Seek(offset); + if (file.Read(buf, 4) == 4) + { + if (!memcmp(buf, "ADIF", 4)) + return ReadADIFHeaderDuration(file, offset); + else + return ReadADTSHeaderDuration(file, offset); + } + + return 0; +} + +int CMusicInfoTagLoaderAAC::ReadADTSHeaderDuration(XFILE::CFile& file, int offset) +{ + uint8_t buf[10] = {}; + uint64_t totalLength = 0; + uint32_t frames = 0; + float framesPerSec = 0.f; + + file.Seek(offset); + + while (file.Read(buf, 10) == 10) + { + if ((buf[0] == 0xFF) && ((buf[1] & 0xF6) == 0xF0)) + { + if (!frames) + { + int sr_idx = (buf[2] & 0x3C) >> 2; + framesPerSec = aac_sample_rates[sr_idx] / 1024.f; + } + frames++; + totalLength += ((((uint32_t)buf[3] & 0x03) << 11) | (((uint32_t)buf[4]) << 3) | buf[5] >> 5); + file.Seek(totalLength + offset); + } + else + return 0; + } + return (int)((float)frames/framesPerSec*1000.0); +} + +int CMusicInfoTagLoaderAAC::ReadADIFHeaderDuration(XFILE::CFile& file, int offset) +{ + + return 0; +} + +int CMusicInfoTagLoaderAAC::ReadALACDuration(XFILE::CFile& file, int offset) +{ + + return 0; +} + +int CMusicInfoTagLoaderAAC::ReadMP4Duration(XFILE::CFile& file, int offset) +{ + + return 0; +} Index: xbmc/lib/libsquish/Makefile =================================================================== --- xbmc/lib/libsquish/Makefile (revision 23215) +++ xbmc/lib/libsquish/Makefile (working copy) @@ -1,6 +1,6 @@ SRCS=alpha.cpp clusterfit.cpp colourblock.cpp colourfit.cpp colourset.cpp maths.cpp rangefit.cpp singlecolourfit.cpp squish.cpp -CXXFLAGS+=-O3 +CXXFLAGS+=-O3 -I. LIB=libsquish.a include ../../../Makefile.include Index: xbmc/MusicInfoTagLoaderAAC.h =================================================================== --- xbmc/MusicInfoTagLoaderAAC.h (revision 23215) +++ xbmc/MusicInfoTagLoaderAAC.h (working copy) @@ -22,6 +22,11 @@ #include "MusicInfoTagLoaderMP3.h" +namespace XFILE +{ + class CFile; +} + namespace MUSIC_INFO { @@ -32,5 +37,11 @@ virtual ~CMusicInfoTagLoaderAAC(); private: virtual int ReadDuration(const CStdString& strFileName); + int ReadID3Length(XFILE::CFile& file); + int ReadAACDuration(XFILE::CFile& file, int offset); + int ReadADTSHeaderDuration(XFILE::CFile& file, int offset); + int ReadADIFHeaderDuration(XFILE::CFile& file, int offset); + int ReadALACDuration(XFILE::CFile& file, int offset); + int ReadMP4Duration(XFILE::CFile& file, int offset); }; } Index: tools/XBMCTexXBT/XBTFWriter.cpp =================================================================== --- tools/XBMCTexXBT/XBTFWriter.cpp (revision 23215) +++ tools/XBMCTexXBT/XBTFWriter.cpp (working copy) @@ -8,6 +8,11 @@ #define WRITE_U32(i, file) { unsigned long _n = i; _n = Endian_SwapLE32(i); fwrite(&_n, 4, 1, file); } #define WRITE_U64(i, file) { unsigned long long _n = i; _n = Endian_SwapLE64(i); fwrite(&_n, 8, 1, file); } +// I didn't want to pull in platformdefs.h for this. Maybe that's a better solution though? +#ifdef _LINUX +#define PRIu64 "lld" +#endif + CXBTFWriter::CXBTFWriter(CXBTF& xbtf, const std::string outputFile) : m_xbtf(xbtf) { m_outputFile = outputFile; @@ -121,11 +126,10 @@ } // Sanity check - fpos_t pos; - fgetpos(m_file, &pos); - if ((unsigned int) pos != m_xbtf.GetHeaderSize()) + int64_t pos = ftell(m_file); + if (pos != m_xbtf.GetHeaderSize()) { - printf("Expected header size (%llu) != actual size (%llu)\n", m_xbtf.GetHeaderSize(), pos); + printf("Expected header size (%" PRId64 ") != actual size (%" PRId64 ")\n", m_xbtf.GetHeaderSize(), pos); return false; } Index: guilib/XBTFReader.cpp =================================================================== --- guilib/XBTFReader.cpp (revision 23215) +++ guilib/XBTFReader.cpp (working copy) @@ -118,11 +118,10 @@ } // Sanity check - fpos_t pos; - fgetpos(m_file, &pos); - if ((unsigned int) pos != m_xbtf.GetHeaderSize()) + int64_t pos = ftell(m_file); + if (pos != m_xbtf.GetHeaderSize()) { - printf("Expected header size (%llu) != actual size (%llu)\n", m_xbtf.GetHeaderSize(), pos); + printf("Expected header size (%"PRId64") != actual size (%"PRId64")\n", m_xbtf.GetHeaderSize(), pos); return false; } Index: guilib/Makefile =================================================================== --- guilib/Makefile (revision 23215) +++ guilib/Makefile (working copy) @@ -1,4 +1,4 @@ -INCLUDES=-I. -I../ -Icommon -I../xbmc -I../xbmc/cores -I../xbmc/linux -I../xbmc/utils -I/usr/include/freetype2 -I/usr/include/SDL -I../xbmc/lib/squish +INCLUDES=-I. -I../ -Icommon -I../xbmc -I../xbmc/cores -I../xbmc/linux -I../xbmc/utils -I/usr/include/freetype2 -I/usr/include/SDL -I../xbmc/lib/libsquish SRCS=AnimatedGif.cpp \ AudioContext.cpp \ Index: guilib/XBTF.cpp =================================================================== --- guilib/XBTF.cpp (revision 23215) +++ guilib/XBTF.cpp (working copy) @@ -18,7 +18,7 @@ * http://www.gnu.org/copyleft/gpl.html * */ -#include +#include #include "XBTF.h" CXBTFFrame::CXBTFFrame()