Problem with transfer mode, xine plugin and ActualDevice
Commit Message
Hi,
Luca Olivetti wrote:
> Btw, this is the patch I'm using now (against original 0.7.6), and it
> seems to work, but I'm not sure it's due to simple luck or it is working
> by design (e.g. if I switch the order of cControl::Shutdown() and
> Skins.Message in the OnClientConnect handler it won't work).
As you wrote in a previous email: it's a threading issue.
Please try the attached patch against 0.7.6, which now uses VDR's main
thread to switch the primary device.
Bye.
Comments
En/na Reinhard Nissl ha escrit:
> Hi,
>
> Luca Olivetti wrote:
>
>> Btw, this is the patch I'm using now (against original 0.7.6), and it
>> seems to work, but I'm not sure it's due to simple luck or it is working
>> by design (e.g. if I switch the order of cControl::Shutdown() and
>> Skins.Message in the OnClientConnect handler it won't work).
>
> As you wrote in a previous email: it's a threading issue.
>
> Please try the attached patch against 0.7.6, which now uses VDR's main
> thread to switch the primary device.
It works, thanks.
Bye
@@ -156,7 +156,7 @@ void cPluginXine::Housekeeping(void)
cOsdObject *cPluginXine::MainMenuAction(void)
{
// Perform the action when selected from the main VDR menu.
- m_settings.TogglePrebufferMode();
+ PluginXine::cXineDevice::MainMenuTrampoline();
return NULL;
}
@@ -2580,8 +2588,14 @@ store_frame(jumboPESdata, todo, __LINE__
void cXineDevice::MakePrimaryDevice(bool On)
{
+ xfprintf(stderr, "-------------------------\n");
+ xfprintf(stderr, "MakePrimaryDevice: %d\n", On);
+ xfprintf(stderr, "=========================\n");
+
if (On)
new cXineOsdProvider(*this);
+ else
+ cOsdProvider::Shutdown();
originalPrimaryDevice = 0;
}
@@ -2619,6 +2633,51 @@ store_frame(jumboPESdata, todo, __LINE__
m_currentOsd->ReshowCurrentOsd(dontOptimize, frameWidth, frameHeight);
}
+ void cXineDevice::mainMenuTrampoline()
+ {
+ cMutexLock switchPrimaryDeviceLock(&m_switchPrimaryDeviceMutex);
+ if (m_switchPrimaryDeviceDeviceNo < 0)
+ return;
+
+ cControl::Shutdown();
+
+ if (m_switchPrimaryDeviceDeviceNo == (1 + DeviceNumber()))
+ {
+ char *msg = 0;
+ ::asprintf(&msg, tr("Switching primary DVB to %s..."), m_plugin->Name());
+
+ Skins.Message(mtInfo, msg);
+ ::free(msg);
+ }
+
+ SetPrimaryDevice(m_switchPrimaryDeviceDeviceNo);
+
+ if (m_switchPrimaryDeviceDeviceNo != (1 + DeviceNumber()))
+ {
+ char *msg = 0;
+ ::asprintf(&msg, tr("Switched primary DVB back from %s"), m_plugin->Name());
+
+ Skins.Message(mtInfo, msg);
+ ::free(msg);
+ }
+
+ m_switchPrimaryDeviceCond.Broadcast();
+ }
+
+ void cXineDevice::switchPrimaryDevice(const int deviceNo, const bool waitForExecution)
+ {
+ while (cRemote::HasKeys())
+ cCondWait::SleepMs(10);
+
+ cMutexLock switchPrimaryDeviceLock(&m_switchPrimaryDeviceMutex);
+ m_switchPrimaryDeviceDeviceNo = deviceNo;
+
+ cRemote::CallPlugin(m_plugin->Name());
+
+ if (waitForExecution)
+ m_switchPrimaryDeviceCond.Wait(m_switchPrimaryDeviceMutex);
+ }
+
void cXineDevice::OnClientConnect()
{
reshowCurrentOsd();
@@ -2630,7 +2689,8 @@ store_frame(jumboPESdata, todo, __LINE__
{
cDevice *primaryDevice = cDevice::PrimaryDevice();
if (this != primaryDevice)
- SetPrimaryDevice(1 + DeviceNumber());
+ switchPrimaryDevice(1 + DeviceNumber(), true);
+
originalPrimaryDevice = primaryDevice;
}
@@ -2647,7 +2707,7 @@ store_frame(jumboPESdata, todo, __LINE__
&& originalPrimaryDevice)
{
if (this != originalPrimaryDevice)
- SetPrimaryDevice(1 + originalPrimaryDevice->DeviceNumber());
+ switchPrimaryDevice(1 + originalPrimaryDevice->DeviceNumber(), false);
}
}
@@ -2697,6 +2757,8 @@ store_frame(jumboPESdata, todo, __LINE__
, m_currentOsd(0)
, m_spuDecoder(0)
, m_audioChannel(0)
+ , m_plugin(plugin)
+ , m_switchPrimaryDeviceDeviceNo(-1)
, m_xineLib(plugin, settings, m_osdMutex, remote)
{
m_xineLib.SetEventSink(this);
@@ -97,6 +97,13 @@ namespace PluginXine
virtual void OnClientDisconnect();
virtual void ReshowCurrentOSD(const int frameWidth, const int frameHeight);
+ cPlugin *const m_plugin;
+ int m_switchPrimaryDeviceDeviceNo;
+ cMutex m_switchPrimaryDeviceMutex;
+ cCondVar m_switchPrimaryDeviceCond;
+ void switchPrimaryDevice(const int deviceNo, const bool waitForExecution);
+ void mainMenuTrampoline();
+
public:
virtual int64_t GetSTC(void);
@@ -126,6 +133,11 @@ namespace PluginXine
static void Stop();
static cXineDevice *GetDevice();
+ static void MainMenuTrampoline()
+ {
+ GetDevice()->mainMenuTrampoline();
+ }
+
bool hasNoSignalStream() const
{
return m_xineLib.hasNoSignalStream();