xbmc: add PR2570

Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
Stephan Raue 2013-05-14 23:42:05 +02:00
parent 8caa619554
commit ec5abfc236

View File

@ -0,0 +1,89 @@
From 0aaeb72ed3d76134f11b80a4d17e50b40d6459be Mon Sep 17 00:00:00 2001
From: hmis <hubert.mis@gmail.com>
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<MEDIA_DETECT::CLibcdio> m_cdio;
};
}
--
1.8.1.6