diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.12-PR2570.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.12-PR2570.patch new file mode 100644 index 0000000000..a57c5a8b3d --- /dev/null +++ b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.12-PR2570.patch @@ -0,0 +1,89 @@ +From 0aaeb72ed3d76134f11b80a4d17e50b40d6459be Mon Sep 17 00:00:00 2001 +From: hmis +Date: Mon, 8 Apr 2013 21:35:35 +0300 +Subject: [PATCH] Read CD audio USB drive bug fixed + +libcdio seems to allow read no more than about 10 audio sectors at once when CD audio device is connected via USB. +This patch makes XBMC read small number of sectors if default one fails. It uses more CPU but allows to use USB CD devices. +Tested on GNU/Linux x86 and RPi. (On Rpi OMXPlayer does not play CD, but I can rip tracks). +--- + xbmc/filesystem/CDDAFile.cpp | 34 +++++++++++++++++++++++++++------- + xbmc/filesystem/CDDAFile.h | 1 + + 2 files changed, 28 insertions(+), 7 deletions(-) + +diff --git a/xbmc/filesystem/CDDAFile.cpp b/xbmc/filesystem/CDDAFile.cpp +index 5342629..f5eaf37 100644 +--- a/xbmc/filesystem/CDDAFile.cpp ++++ b/xbmc/filesystem/CDDAFile.cpp +@@ -40,6 +40,7 @@ + m_lsnCurrent = CDIO_INVALID_LSN; + m_lsnEnd = CDIO_INVALID_LSN; + m_cdio = CLibcdio::GetInstance(); ++ m_iSectorCount = 52; + } + + CFileCDDA::~CFileCDDA(void) +@@ -120,7 +121,8 @@ unsigned int CFileCDDA::Read(void* lpBuf, int64_t uiBufSize) + if (!m_pCdIo || !g_mediaManager.IsDiscInDrive()) + return 0; + +- int iSectorCount = (int)uiBufSize / CDIO_CD_FRAMESIZE_RAW; ++ // limit number of sectors that fits in buffer by m_iSectorCount ++ int iSectorCount = std::min((int)uiBufSize / CDIO_CD_FRAMESIZE_RAW, m_iSectorCount); + + if (iSectorCount <= 0) + return 0; +@@ -129,14 +131,32 @@ unsigned int CFileCDDA::Read(void* lpBuf, int64_t uiBufSize) + if (m_lsnCurrent + iSectorCount > m_lsnEnd) + iSectorCount = m_lsnEnd - m_lsnCurrent; + +- int iret = m_cdio->cdio_read_audio_sectors(m_pCdIo, lpBuf, m_lsnCurrent, iSectorCount); +- +- if ( iret != DRIVER_OP_SUCCESS) ++ // The loop tries to solve read error problem by lowering number of sectors to read (iSectorCount). ++ // When problem is solved the proper number of sectors is stored in m_iSectorCount ++ int big_iSectorCount = iSectorCount; ++ while (iSectorCount > 0) + { +- CLog::Log(LOGERROR, "file cdda: Reading %d sectors of audio data starting at lsn %d failed with error code %i", iSectorCount, m_lsnCurrent, iret); +- return 0; ++ int iret = m_cdio->cdio_read_audio_sectors(m_pCdIo, lpBuf, m_lsnCurrent, iSectorCount); ++ ++ if (iret == DRIVER_OP_SUCCESS) ++ { ++ // If lower iSectorCount solved the problem limit it's value ++ if (iSectorCount < big_iSectorCount) ++ { ++ m_iSectorCount = iSectorCount; ++ } ++ break; ++ } ++ ++ // iSectorCount is low so it cannot solve read problem ++ if (iSectorCount <= 10) ++ { ++ CLog::Log(LOGERROR, "file cdda: Reading %d sectors of audio data starting at lsn %d failed with error code %i", iSectorCount, m_lsnCurrent, iret); ++ return 0; ++ } ++ ++ iSectorCount = 10; + } +- + m_lsnCurrent += iSectorCount; + + return iSectorCount*CDIO_CD_FRAMESIZE_RAW; +diff --git a/xbmc/filesystem/CDDAFile.h b/xbmc/filesystem/CDDAFile.h +index f041e0b..72b8d5b 100644 +--- a/xbmc/filesystem/CDDAFile.h ++++ b/xbmc/filesystem/CDDAFile.h +@@ -53,6 +53,7 @@ class CFileCDDA : public IFile + lsn_t m_lsnStart; // Start of m_iTrack in logical sector number + lsn_t m_lsnCurrent; // Position inside the track in logical sector number + lsn_t m_lsnEnd; // End of m_iTrack in logical sector number ++ int m_iSectorCount; // max number of sectors to read at once + boost::shared_ptr m_cdio; + }; + } +-- +1.8.1.6 +