aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/dvb/db.cpp4
-rw-r--r--lib/dvb/decoder.cpp25
-rw-r--r--lib/dvb/decoder.h3
-rw-r--r--lib/dvb/idvb.h12
-rw-r--r--lib/dvb/pmt.cpp21
-rw-r--r--lib/dvb/pmt.h1
-rw-r--r--lib/python/Components/ChoiceList.py2
-rw-r--r--lib/python/Screens/InfoBarGenerics.py17
-rw-r--r--lib/service/iservice.h15
-rw-r--r--lib/service/servicedvb.cpp55
-rw-r--r--lib/service/servicedvb.h8
-rw-r--r--lib/service/servicemp3.h1
12 files changed, 129 insertions, 35 deletions
diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp
index 64ef6ed7..9b2324a6 100644
--- a/lib/dvb/db.cpp
+++ b/lib/dvb/db.cpp
@@ -232,14 +232,14 @@ int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQ
return res;
}
-int eDVBService::getCachePID(cacheID id)
+int eDVBService::getCacheEntry(cacheID id)
{
if (id >= cacheMax)
return -1;
return m_cache[id];
}
-void eDVBService::setCachePID(cacheID id, int pid)
+void eDVBService::setCacheEntry(cacheID id, int pid)
{
if (id < cacheMax)
m_cache[id] = pid;
diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp
index 1bec997d..76d0f504 100644
--- a/lib/dvb/decoder.cpp
+++ b/lib/dvb/decoder.cpp
@@ -137,6 +137,22 @@ void eDVBAudio::unfreeze()
eDebug("video: AUDIO_CONTINUE: %m");
}
+void eDVBAudio::setChannel(int channel)
+{
+ int val = AUDIO_STEREO;
+ switch (channel)
+ {
+ case aMonoLeft: val = AUDIO_MONO_LEFT; break;
+ case aMonoRight: val = AUDIO_MONO_RIGHT; break;
+ default:
+ break;
+ }
+ if (::ioctl(m_fd, AUDIO_CHANNEL_SELECT, val) < 0)
+ eDebug("video: AUDIO_CHANNEL_SELECT: %m");
+ else
+ eDebug("AUDIO_CHANNEL_SELECT ok");
+}
+
int eDVBAudio::getPTS(pts_t &now)
{
return ::ioctl(m_fd, AUDIO_GET_PTS, &now);
@@ -552,6 +568,15 @@ RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
return 0;
}
+RESULT eTSMPEGDecoder::setAudioChannel(int channel)
+{
+ if (m_audio)
+ m_audio->setChannel(channel);
+ else
+ eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
+ return 0;
+}
+
RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
{
if (m_pcrpid != pcrpid)
diff --git a/lib/dvb/decoder.h b/lib/dvb/decoder.h
index 834499b0..f8719869 100644
--- a/lib/dvb/decoder.h
+++ b/lib/dvb/decoder.h
@@ -14,6 +14,8 @@ public:
enum { aMPEG, aAC3, aDTS, aAAC };
eDVBAudio(eDVBDemux *demux, int dev);
int startPid(int pid, int type);
+ enum { aMonoLeft, aStereo, aMonoRight };
+ void setChannel(int channel);
void stop();
#if HAVE_DVB_API_VERSION < 3
void start();
@@ -107,6 +109,7 @@ public:
virtual ~eTSMPEGDecoder();
RESULT setVideoPID(int vpid, int type);
RESULT setAudioPID(int apid, int type);
+ RESULT setAudioChannel(int channel);
RESULT setSyncPCR(int pcrpid);
RESULT setTextPID(int textpid);
RESULT setSyncMaster(int who);
diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h
index ecf8bb92..dff543ca 100644
--- a/lib/dvb/idvb.h
+++ b/lib/dvb/idvb.h
@@ -223,11 +223,11 @@ class eDVBService: public iStaticServiceInformation
public:
enum cacheID
{
- cVPID, cAPID, cTPID, cPCRPID, cAC3PID, cVTYPE, cacheMax
+ cVPID, cAPID, cTPID, cPCRPID, cAC3PID, cVTYPE, cACHANNEL, cacheMax
};
- int getCachePID(cacheID);
- void setCachePID(cacheID, int);
+ int getCacheEntry(cacheID);
+ void setCacheEntry(cacheID, int);
bool cacheEmpty();
@@ -577,10 +577,14 @@ public:
/** Set Displayed Video PID and type */
virtual RESULT setVideoPID(int vpid, int type)=0;
- enum { af_MPEG, af_AC3, af_DTS };
+ enum { af_MPEG, af_AC3, af_DTS, af_AAC };
/** Set Displayed Audio PID and type */
virtual RESULT setAudioPID(int apid, int type)=0;
+ enum { ac_left, ac_stereo, ac_right };
+ /** Set Displayed Audio Channel */
+ virtual RESULT setAudioChannel(int channel)=0;
+
/** Set Displayed Videotext PID */
virtual RESULT setTextPID(int vpid)=0;
diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp
index 11cda125..1032267d 100644
--- a/lib/dvb/pmt.cpp
+++ b/lib/dvb/pmt.cpp
@@ -216,6 +216,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
program.isCrypted = false;
program.pmtPid = -1;
program.textPid = -1;
+ program.audioChannel = m_service ? m_service->getCacheEntry(eDVBService::cACHANNEL) : -1;
if ( ((m_service && m_service->usePMT()) || !m_service) && !m_PMT.getCurrent(ptr))
{
@@ -225,10 +226,10 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
int cached_tpid = -1;
if ( m_service && !m_service->cacheEmpty() )
{
- cached_vpid = m_service->getCachePID(eDVBService::cVPID);
- cached_apid_mpeg = m_service->getCachePID(eDVBService::cAC3PID);
- cached_apid_ac3 = m_service->getCachePID(eDVBService::cAPID);
- cached_tpid = m_service->getCachePID(eDVBService::cTPID);
+ cached_vpid = m_service->getCacheEntry(eDVBService::cVPID);
+ cached_apid_mpeg = m_service->getCacheEntry(eDVBService::cAC3PID);
+ cached_apid_ac3 = m_service->getCacheEntry(eDVBService::cAPID);
+ cached_tpid = m_service->getCacheEntry(eDVBService::cTPID);
}
eDVBTableSpec table_spec;
ptr->getSpec(table_spec);
@@ -359,12 +360,12 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
return 0;
} else if ( m_service && !m_service->cacheEmpty() )
{
- int vpid = m_service->getCachePID(eDVBService::cVPID),
- apid_ac3 = m_service->getCachePID(eDVBService::cAC3PID),
- apid_mpeg = m_service->getCachePID(eDVBService::cAPID),
- pcrpid = m_service->getCachePID(eDVBService::cPCRPID),
- tpid = m_service->getCachePID(eDVBService::cTPID),
- vpidtype = m_service->getCachePID(eDVBService::cVTYPE),
+ int vpid = m_service->getCacheEntry(eDVBService::cVPID),
+ apid_ac3 = m_service->getCacheEntry(eDVBService::cAC3PID),
+ apid_mpeg = m_service->getCacheEntry(eDVBService::cAPID),
+ pcrpid = m_service->getCacheEntry(eDVBService::cPCRPID),
+ tpid = m_service->getCacheEntry(eDVBService::cTPID),
+ vpidtype = m_service->getCacheEntry(eDVBService::cVTYPE),
cnt=0;
if ( vpidtype == -1 )
vpidtype = videoStream::vtMPEG2;
diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h
index b6a3743f..f4e99a57 100644
--- a/lib/dvb/pmt.h
+++ b/lib/dvb/pmt.h
@@ -122,6 +122,7 @@ public:
int pmtPid;
int textPid;
bool isCrypted;
+ int audioChannel;
};
int getProgramInfo(struct program &program);
diff --git a/lib/python/Components/ChoiceList.py b/lib/python/Components/ChoiceList.py
index ca58ecd6..fe3e6008 100644
--- a/lib/python/Components/ChoiceList.py
+++ b/lib/python/Components/ChoiceList.py
@@ -18,7 +18,7 @@ RT_VALIGN_BOTTOM = 16
def ChoiceEntryComponent(key, text):
res = [ text ]
- res.append((eListboxPythonMultiContent.TYPE_TEXT, 32, 00, 800,25, 0, RT_HALIGN_LEFT, text[0]))
+ res.append((eListboxPythonMultiContent.TYPE_TEXT, 32, 00, 800, 25, 0, RT_HALIGN_LEFT, text[0]))
png = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "key_" + key + "-fs8.png"))
if png is not None:
diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py
index c3c6e21a..67212656 100644
--- a/lib/python/Screens/InfoBarGenerics.py
+++ b/lib/python/Screens/InfoBarGenerics.py
@@ -13,7 +13,7 @@ from Components.PluginComponent import plugins
from Components.ProgressBar import *
from Components.ServiceEventTracker import ServiceEventTracker
from Components.ServiceName import ServiceName
-from Components.config import config, configElement, ConfigSubsection, configSequence, configElementBoolean
+from Components.config import config, configElement, ConfigSubsection, configSequence, configElementBoolean, configSelection, configElement_nonSave, getConfigListEntry
from Components.config import configfile, configsequencearg
from Components.TimerList import TimerEntryComponent
from Components.TunerInfo import TunerInfo
@@ -1192,9 +1192,11 @@ class InfoBarAudioSelection:
def audioSelection(self):
service = self.session.nav.getCurrentService()
audio = service.audioTracks()
- self.audio = audio
+ self.audioTracks = audio
n = audio.getNumberOfTracks()
if n > 0:
+# self.audioChannel = service.audioChannel()
+# config.audio.audiochannel = configElement_nonSave("config.audio.audiochannel", configSelection, self.audioChannel.getCurrentChannel(), (("left", _("Left >")), ("stereo", _("< Stereo >")), ("right", _("< Right"))))
tlist = []
for x in range(n):
i = audio.getTrackInfo(x)
@@ -1214,6 +1216,9 @@ class InfoBarAudioSelection:
selectedAudio = tlist[0][1]
tlist.sort(lambda x,y : cmp(x[0], y[0]))
+
+# tlist.insert(0, getConfigListEntry(_("Audio Channel"), config.audio.audiochannel))
+
selection = 0
for x in tlist:
if x[1] != selectedAudio:
@@ -1222,11 +1227,15 @@ class InfoBarAudioSelection:
break
self.session.openWithCallback(self.audioSelected, ChoiceBox, title=_("Select audio track"), list = tlist, selection = selection)
+ else:
+ del self.audioTracks
def audioSelected(self, audio):
if audio is not None:
- self.audio.selectTrack(audio[1])
- del self.audio
+ self.audioTracks.selectTrack(audio[1])
+ del self.audioTracks
+# del self.audioChannel
+# del config.audio.audiochannel
class InfoBarSubserviceSelection:
def __init__(self):
diff --git a/lib/service/iservice.h b/lib/service/iservice.h
index c93c84a5..a24b8b21 100644
--- a/lib/service/iservice.h
+++ b/lib/service/iservice.h
@@ -374,6 +374,20 @@ public:
TEMPLATE_TYPEDEF(ePtr<iAudioTrackSelection>, iAudioTrackSelectionPtr);
+class iAudioChannelSelection: public iObject
+{
+#ifdef SWIG
+ iAudioChannelSelection();
+ ~iAudioChannelSelection();
+#endif
+public:
+ enum { LEFT, STEREO, RIGHT };
+ virtual int getCurrentChannel()=0;
+ virtual RESULT selectChannel(int i)=0;
+};
+
+TEMPLATE_TYPEDEF(ePtr<iAudioChannelSelection>, iAudioChannelSelectionPtr);
+
class iSubserviceList: public iObject
{
#ifdef SWIG
@@ -459,6 +473,7 @@ public:
virtual SWIG_VOID(RESULT) pause(ePtr<iPauseableService> &SWIG_OUTPUT)=0;
virtual SWIG_VOID(RESULT) info(ePtr<iServiceInformation> &SWIG_OUTPUT)=0;
virtual SWIG_VOID(RESULT) audioTracks(ePtr<iAudioTrackSelection> &SWIG_OUTPUT)=0;
+ virtual SWIG_VOID(RESULT) audioChannel(ePtr<iAudioChannelSelection> &SWIG_OUTPUT)=0;
virtual SWIG_VOID(RESULT) subServices(ePtr<iSubserviceList> &SWIG_OUTPUT)=0;
virtual SWIG_VOID(RESULT) frontendStatusInfo(ePtr<iFrontendStatusInformation> &SWIG_OUTPUT)=0;
virtual SWIG_VOID(RESULT) timeshift(ePtr<iTimeshiftService> &SWIG_OUTPUT)=0;
diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp
index e9aeb8a9..0ec488fe 100644
--- a/lib/service/servicedvb.cpp
+++ b/lib/service/servicedvb.cpp
@@ -997,6 +997,12 @@ RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
return 0;
}
+RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
+{
+ ptr = this;
+ return 0;
+}
+
RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
{
ptr = this;
@@ -1239,12 +1245,12 @@ int eDVBServicePlay::selectAudioStream(int i)
{
if (program.audioStreams[i].type == eDVBAudio::aMPEG)
{
- m_dvb_service->setCachePID(eDVBService::cAPID, program.audioStreams[i].pid);
- m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
+ m_dvb_service->setCacheEntry(eDVBService::cAPID, program.audioStreams[i].pid);
+ m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
} else
{
- m_dvb_service->setCachePID(eDVBService::cAPID, -1);
- m_dvb_service->setCachePID(eDVBService::cAC3PID, program.audioStreams[i].pid);
+ m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
+ m_dvb_service->setCacheEntry(eDVBService::cAC3PID, program.audioStreams[i].pid);
}
}
@@ -1253,6 +1259,24 @@ int eDVBServicePlay::selectAudioStream(int i)
return 0;
}
+int eDVBServicePlay::getCurrentChannel()
+{
+ int curChannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
+ return curChannel == -1 ? STEREO : curChannel;
+}
+
+RESULT eDVBServicePlay::selectChannel(int i)
+{
+ if (i < iAudioChannelSelection::LEFT || i > iAudioChannelSelection::RIGHT)
+ i = -1; // Stereo
+ if (m_dvb_service->getCacheEntry(eDVBService::cACHANNEL) != i)
+ {
+ m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
+ if (m_decoder)
+ m_decoder->setAudioChannel(i);
+ }
+}
+
int eDVBServicePlay::getFrontendInfo(int w)
{
if (m_is_pvr)
@@ -1560,7 +1584,7 @@ void eDVBServicePlay::switchToTimeshift()
void eDVBServicePlay::updateDecoder()
{
- int vpid = -1, vpidtype = -1, apid = -1, apidtype = -1, pcrpid = -1, tpid = -1;
+ int vpid = -1, vpidtype = -1, apid = -1, apidtype = -1, pcrpid = -1, tpid = -1, achannel = -1;
eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
bool defaultac3=false;
@@ -1619,6 +1643,7 @@ void eDVBServicePlay::updateDecoder()
pcrpid = program.pcrPid;
eDebug(", and the text pid is %04x", program.textPid);
tpid = program.textPid;
+ achannel = program.audioChannel;
}
if (!m_decoder)
@@ -1651,7 +1676,11 @@ void eDVBServicePlay::updateDecoder()
if (!m_is_primary)
m_decoder->setTrickmode(1);
+
m_decoder->start();
+
+ m_decoder->setAudioChannel(achannel);
+
// how we can do this better?
// update cache pid when the user changed the audio track or video track
// TODO handling of difference audio types.. default audio types..
@@ -1661,18 +1690,18 @@ void eDVBServicePlay::updateDecoder()
{
if (apidtype == eDVBAudio::aMPEG)
{
- m_dvb_service->setCachePID(eDVBService::cAPID, apid);
- m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
+ m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
+ m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
}
else
{
- m_dvb_service->setCachePID(eDVBService::cAPID, -1);
- m_dvb_service->setCachePID(eDVBService::cAC3PID, apid);
+ m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
+ m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
}
- m_dvb_service->setCachePID(eDVBService::cVPID, vpid);
- m_dvb_service->setCachePID(eDVBService::cVTYPE, vpidtype);
- m_dvb_service->setCachePID(eDVBService::cPCRPID, pcrpid);
- m_dvb_service->setCachePID(eDVBService::cTPID, tpid);
+ m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
+ m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype);
+ m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
+ m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
}
}
}
diff --git a/lib/service/servicedvb.h b/lib/service/servicedvb.h
index 01eb0497..79e8d540 100644
--- a/lib/service/servicedvb.h
+++ b/lib/service/servicedvb.h
@@ -58,7 +58,8 @@ private:
class eDVBServicePlay: public iPlayableService, public iPauseableService,
public iSeekableService, public Object, public iServiceInformation,
- public iAudioTrackSelection, public iFrontendStatusInformation,
+ public iAudioTrackSelection, public iAudioChannelSelection,
+ public iFrontendStatusInformation,
public iSubserviceList, public iTimeshiftService,
public iCueSheet
{
@@ -75,6 +76,7 @@ public:
RESULT seek(ePtr<iSeekableService> &ptr);
RESULT pause(ePtr<iPauseableService> &ptr);
RESULT info(ePtr<iServiceInformation> &ptr);
+ RESULT audioChannel(ePtr<iAudioChannelSelection> &ptr);
RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr);
RESULT frontendStatusInfo(ePtr<iFrontendStatusInformation> &ptr);
RESULT subServices(ePtr<iSubserviceList> &ptr);
@@ -107,6 +109,10 @@ public:
RESULT selectTrack(unsigned int i);
RESULT getTrackInfo(struct iAudioTrackInfo &, unsigned int n);
+ // iAudioChannelSelection
+ int getCurrentChannel();
+ RESULT selectChannel(int i);
+
// iFrontendStatusInformation
int getFrontendInfo(int w);
PyObject *getFrontendData(bool);
diff --git a/lib/service/servicemp3.h b/lib/service/servicemp3.h
index cb400cc6..c6a0df06 100644
--- a/lib/service/servicemp3.h
+++ b/lib/service/servicemp3.h
@@ -58,6 +58,7 @@ public:
RESULT seek(ePtr<iSeekableService> &ptr);
// not implemented (yet)
+ RESULT audioChannel(ePtr<iAudioChannelSelection> &ptr) { ptr = 0; return -1; }
RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr) { ptr = 0; return -1; }
RESULT frontendStatusInfo(ePtr<iFrontendStatusInformation> &ptr) { ptr = 0; return -1; }
RESULT subServices(ePtr<iSubserviceList> &ptr) { ptr = 0; return -1; }