#include "vdr.h"
#include "log.h"
+#include "command.h"
Channel::Channel()
{
}
VDR::getInstance()->getChannelPids(this); // FIXME sort out this system
-
+ if (!VDR::getInstance()->isConnected())
+ {
+ Command::getInstance()->connectionLost();
+ return;
+ }
+
Log::getInstance()->log("Channel", Log::DEBUG, "C.%lu loaded, VPid=%lu, numApids=%lu, numDpids=%lu, numSpids=%lu TPid=%lu",
number, vpid, numAPids, numDPids, numSPids, tpid);
for (ULONG i = 0; i < numAPids; i++)
boxstack->removeAll();
boxstack->update(wallpaper);
I18n::initialize();
+ if (!VDR::getInstance()->isConnected()) { connectionLost(); break; }
VWelcome* vw = new VWelcome();
vw->draw();
boxstack->add(vw);
void Command::doJustConnected(VConnect* vconnect)
{
I18n::initialize();
+ if (!VDR::getInstance()->isConnected()) { connectionLost(); return; }
+
Video* video = Video::getInstance();
Audio* audio = Audio::getInstance();
boxstack->remove(vconnect);
vdr->getNextIFrame(nextiframeNumber, 0, &filePos, &iframeNumber, &iframeLength);
buffer = vdr->getBlock(filePos, iframeLength, &amountReceived);
- videoLength = demuxer->stripAudio(buffer, amountReceived);
- video->displayIFrame(buffer, videoLength);
- video->displayIFrame(buffer, videoLength); // If you do it twice, it works :)
- free(buffer);
-
- currentFrameNumber = iframeNumber;
+ if (!vdr->isConnected())
+ {
+ if (buffer) free(buffer);
+ doConnectionLost();
+ }
+ else
+ {
+ videoLength = demuxer->stripAudio(buffer, amountReceived);
+ video->displayIFrame(buffer, videoLength);
+ video->displayIFrame(buffer, videoLength); // If you do it twice, it works :)
+ free(buffer);
+ currentFrameNumber = iframeNumber;
+ }
}
void Player::doConnectionLost()
// logger->log("Player", Log::DEBUG, "XXX Got frame");
threadBuffer = vdr->getBlock(filePos, iframeLength, &amountReceived);
+
+ if (!vdr->isConnected())
+ {
+ if (threadBuffer) free(threadBuffer);
+ doConnectionLost();
+ break;
+ }
+
#ifndef WIN32
gettimeofday(&clock1, NULL);
if (clock2.tv_sec != 0)
void PlayerLiveRadio::streamReceive(ULONG flag, void* data, ULONG len)
{
+ // Flag:
+ // 0 = normal stream packet
+ // 1 = stream end
+
+ if (flag == 1)
+ {
+ if (data) abort();
+
+ Message* m = new Message();
+ m->from = this;
+ m->to = messageReceiver;
+ m->message = Message::PLAYER_EVENT;
+ m->parameter = PlayerLiveRadio::STREAM_END;
+ messageQueue->postMessageFromOuterSpace(m);
+ }
+
if (streamChunks.size() < 11)
{
StreamChunk s;
{
StreamChunk s = streamChunks.front();
streamChunks.pop();
- logger->log("PlayerLiveRadio", Log::DEBUG, "About to call demuxer with %p %lu", s.data, s.len);
- int a = demuxer->put((UCHAR*)s.data, s.len);
- logger->log("PlayerLiveRadio", Log::DEBUG, "put %i to demuxer", a);
+ //logger->log("PlayerLiveRadio", Log::DEBUG, "About to call demuxer with %p %lu", s.data, s.len);
+ /*int a =*/ demuxer->put((UCHAR*)s.data, s.len);
+ //logger->log("PlayerLiveRadio", Log::DEBUG, "put %i to demuxer", a);
free(s.data);
}
}
}
+bool PlayerLiveRadio::checkError()
+{
+ if (!vdr->isConnected())
+ {
+ switchState(S_STOP);
+
+ Message* m = new Message();
+ m->from = this;
+ m->to = messageReceiver;
+ m->message = Message::PLAYER_EVENT;
+ m->parameter = PlayerLiveRadio::CONNECTION_LOST;
+ messageQueue->postMessageFromOuterSpace(m);
+
+ return true;
+ }
+ return false;
+}
+
void PlayerLiveRadio::optimizeInstructionQueue()
{
// Walk the list
i = instructions.front();
if (i.instruction == I_SETCHANNEL)
{
- logger->log("PlayerLiveRadio", Log::DEBUG, "Optimised out setch to %i", i.channelIndex);
instructions.pop(); // if this is the first of more than 1 command, currently it cannot possibly be relevant
}
else if (i.instruction == I_STOP)
switchState(S_PREBUFFERING);
- Channel* chan = (*chanList)[i.channelIndex];
- chan->loadPids();
-
- if (chan->numAPids > 0)
+ if (!checkError())
{
- demuxer->setAID(chan->apids[0].pid,0);
- logger->log("PlayerLiveRadio", Log::DEBUG, "Demuxer pids: %u %u", chan->vpid, chan->apids[0].pid);
+ Channel* chan = (*chanList)[i.channelIndex];
+ chan->loadPids();
+
+ if (chan->numAPids > 0)
+ {
+ demuxer->setAID(chan->apids[0].pid,0);
+ logger->log("PlayerLiveRadio", Log::DEBUG, "Demuxer pids: %u %u", chan->vpid, chan->apids[0].pid);
+ }
+ else
+ {
+ logger->log("PlayerLiveRadio", Log::WARN, "Demuxer no pids!");
+ }
+
+ int streamSuccess = vdr->streamChannel(chan->number, this);
+ if (!checkError() && !streamSuccess)
+ {
+ Message* m = new Message();
+ m->from = this;
+ m->to = messageReceiver;
+ m->message = Message::PLAYER_EVENT;
+ m->parameter = PlayerLiveRadio::STREAM_END;
+ messageQueue->postMessageFromOuterSpace(m);
+ }
}
- else
- {
- logger->log("PlayerLiveRadio", Log::WARN, "Demuxer no pids!");
- }
-
- vdr->streamChannel(chan->number, this);
}
else if (i.instruction == I_STOP)
{
logger->log("PlayerLiveRadio", Log::DEBUG, "Stopping");
switchState(S_STOP);
+ checkError();
stopNow = true;
break;
chunkToDemuxer();
if (state == S_PREBUFFERING)
- {
- if (++preBufferCount == preBufferAmount)
+ {
+ ++preBufferCount;
+ ULONG percentDone = (ULONG)(preBufferCount / (float)preBufferAmount * 100);
+ logger->log("PlayerLiveRadio", Log::DEBUG, "Prebuffering %lu%%", percentDone);
+
+ Message* m = new Message();
+ m->from = this;
+ m->to = messageReceiver;
+ m->message = Message::PLAYER_EVENT;
+ m->parameter = PlayerLiveRadio::PREBUFFERING;
+ m->tag = percentDone;
+ messageQueue->postMessageFromOuterSpace(m);
+
+ if (preBufferCount == preBufferAmount)
{
switchState(S_PLAY);
+ checkError();
}
}
}
const static UCHAR STREAM_END = 3;
const static UCHAR ASPECT43 = 4;
const static UCHAR ASPECT169 = 5;
-
+ const static UCHAR PREBUFFERING = 6;
+
protected:
void threadMethod();
void threadPostStopCleanup() {};
const static UCHAR S_PREBUFFERING = 2;
const static UCHAR S_PLAY = 3;
void switchState(UCHAR newState);
+ bool checkError();
bool stopNow;
int preBufferCount;
}
}
+bool PlayerLiveTV::checkError()
+{
+ if (!vdr->isConnected())
+ {
+ switchState(S_STOP);
+
+ Message* m = new Message();
+ m->from = this;
+ m->to = messageReceiver;
+ m->message = Message::PLAYER_EVENT;
+ m->parameter = PlayerLiveTV::CONNECTION_LOST;
+ messageQueue->postMessageFromOuterSpace(m);
+
+ return true;
+ }
+ return false;
+}
+
void PlayerLiveTV::optimizeInstructionQueue()
{
// Walk the list
switchState(S_PREBUFFERING);
videoStartup = false;
preBufferCount = 0;
+
+ checkError();
}
while(!instructions.empty())
logger->log("PlayerLiveTV", Log::DEBUG, "start new stream");
switchState(S_VIDEOSTARTUP);
-
- Channel* chan = (*chanList)[i.channelIndex];
- chan->loadPids();
- demuxer->setVID(chan->vpid);
- if (chan->numAPids > 0)
- {
- demuxer->setAID(chan->apids[0].pid,0);
- logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer pids: %u %u", chan->vpid, chan->apids[0].pid);
- }
- else
+
+ if (!checkError())
{
- logger->log("PlayerLiveTV", Log::WARN, "Demuxer video pid only: %u", chan->vpid);
- }
-
- int streamSuccess = vdr->streamChannel(chan->number, this);
- if (!streamSuccess)
- {
- Message* m = new Message();
- m->from = this;
- m->to = messageReceiver;
- m->message = Message::PLAYER_EVENT;
- m->parameter = PlayerLiveTV::STREAM_END;
- messageQueue->postMessageFromOuterSpace(m);
+ Channel* chan = (*chanList)[i.channelIndex];
+ chan->loadPids();
+ demuxer->setVID(chan->vpid);
+ if (chan->numAPids > 0)
+ {
+ demuxer->setAID(chan->apids[0].pid,0);
+ logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer pids: %u %u", chan->vpid, chan->apids[0].pid);
+ }
+ else
+ {
+ logger->log("PlayerLiveTV", Log::WARN, "Demuxer video pid only: %u", chan->vpid);
+ }
+
+ int streamSuccess = vdr->streamChannel(chan->number, this);
+ if (!checkError() && !streamSuccess)
+ {
+ Message* m = new Message();
+ m->from = this;
+ m->to = messageReceiver;
+ m->message = Message::PLAYER_EVENT;
+ m->parameter = PlayerLiveTV::STREAM_END;
+ messageQueue->postMessageFromOuterSpace(m);
+ }
}
}
else if (i.instruction == I_STOP)
{
logger->log("PlayerLiveTV", Log::DEBUG, "Stopping");
switchState(S_STOP);
+ checkError();
stopNow = true;
break;
if (preBufferCount == preBufferAmount)
{
switchState(S_PLAY);
+ checkError();
}
}
}
const static UCHAR S_PREBUFFERING = 3;
const static UCHAR S_PLAY = 4;
void switchState(UCHAR newState);
+ bool checkError();
bool videoStartup;
bool stopNow;
{
logger->log("PlayerRadio", Log::ERR, "Failed to get start block");
shutdown();
+ if (!vdr->isConnected()) doConnectionLost();
return 0;
}
if (!buffer)
{
logger->log("PlayerRadio", Log::ERR, "Failed to get end block");
+ if (!vdr->isConnected()) doConnectionLost();
return false;
}
#include "mark.h"
#include "log.h"
#include "demuxer.h"
+#include "command.h"
Recording* Recording::recInfoFor = NULL;
RecInfo* Recording::recInfo = NULL;
recInfoFor = this;
recInfo = vdr->getRecInfo(fileName);
Log::getInstance()->log("Recording", Log::DEBUG, "Recording has loaded recInfo %p", recInfo);
+
+ if (!VDR::getInstance()->isConnected()) Command::getInstance()->connectionLost();
}
void Recording::dropRecInfo()
void Recording::loadMarks()
{
markList = vdr->getMarks(fileName);
+ if (!VDR::getInstance()->isConnected()) Command::getInstance()->connectionLost();
}
bool Recording::isRadio()
free(buffer);
- // FIXME
vdr->stopStreaming();
+ if (!VDR::getInstance()->isConnected()) Command::getInstance()->connectionLost();
+
Log::getInstance()->log("Recording", Log::DEBUG, "Recording has messed about and worked out radio = %u", !hasVideo);
ULONG retval = VDR::getInstance()->deleteTimer(recTimer);
+ if (!VDR::getInstance()->isConnected()) { Command::getInstance()->connectionLost(); return; }
Log::getInstance()->log("VTimerList", Log::DEBUG, "Got return fron delete timer: %lu", retval);
if (retval != 10)
case PlayerLiveTV::CONNECTION_LOST: // connection lost detected
{
Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Received connection lost from player");
- // I can't handle this, send it to command
- Message* m2 = new Message();
- m2->to = Command::getInstance();
- m2->message = Message::CONNECTION_LOST;
- Command::getInstance()->postMessageNoLock(m2);
+ Command::getInstance()->connectionLost();
break;
}