/*
- Copyright 2004-2005 Chris Tallon
+ Copyright 2004-2008 Chris Tallon
This file is part of VOMP.
// ----------------------------------- Called from outside, one offs or info funcs
-Player::Player(MessageQueue* tmessageQueue, void* tmessageReceiver, bool tIsRecording)
+Player::Player(MessageQueue* tmessageQueue, void* tmessageReceiver)
: vfeed(this), afeed(this)
{
messageQueue = tmessageQueue;
ifactor = 4;
videoStartup = false;
- preBuffering = false;
- isRecording = tIsRecording;
-
threadBuffer = NULL;
blockSize = 100000;
startupBlockSize = 250000;
- preBufferSize = 500000;
video->turnVideoOn();
}
mutex=CreateMutex(NULL,FALSE,NULL);
#endif
- if (isRecording)
- demuxer = new DemuxerVDR();
- else
- demuxer = new DemuxerTS();
+ demuxer = new DemuxerVDR();
if (!demuxer) return 0;
if (!demuxer->init(this, audio, video, 2097152, 524288))
int Player::getCurrentAudioChannel()
{
- if (isRecording)
return demuxer->getselAudioChannel();
- else
- return ((DemuxerTS*)demuxer)->getAID();
}
void Player::setAudioChannel(int newChannel, int type)
{
- if (isRecording)
demuxer->setAudioChannel(newChannel);
- else
- ((DemuxerTS*)demuxer)->setAID(newChannel,type);
}
// ----------------------------------- Externally called events
-void Player::play(ULONG Vpid, ULONG Apid)
-{
- // TS mode
- DemuxerTS* dts = (DemuxerTS*)demuxer;
- dts->setVID(Vpid);
- dts->setAID(Apid,0);
- play();
-}
-
void Player::play()
{
if (!initted) return;
audio->systemMuteOff();
video->reset();
demuxer->reset();
- if (isRecording)
- {
- // FIXME use restartAtFrame here?
- if (currentFrameNumber > lengthFrames) currentFrameNumber = 0;
- demuxer->setFrameNum(currentFrameNumber);
- }
+ // FIXME use restartAtFrame here?
+ if (currentFrameNumber > lengthFrames) currentFrameNumber = 0;
+ demuxer->setFrameNum(currentFrameNumber);
demuxer->seek();
-
videoStartup = true;
state = S_PLAY;
threadStart();
-
- if (isRecording)
- {
- logger->log("Player", Log::DEBUG, "Immediate play");
- afeed.start();
- vfeed.start();
- video->sync();
- audio->sync();
- audio->play();
- video->pause();
- }
- else // do prebuffering
- {
- logger->log("Player", Log::DEBUG, "Prebuffering...");
- preBuffering = true;
- }
+ logger->log("Player", Log::DEBUG, "Immediate play");
+ afeed.start();
+ vfeed.start();
+ video->sync();
+ audio->sync();
+ audio->play();
+ video->pause();
return;
}
case S_PAUSE_P: // to S_PAUSE_P
// is farm out to threadFeed Live/Play/Scan
// All the guff is to support scan hitting one end
- if (isRecording)
- {
- if ((state == S_FFWD) || (state == S_FBWD))
- {
- threadFeedScan();
- // if this returns then scan hit one end
- if (state == S_FFWD) // scan hit the end. stop
- {
- threadCheckExit();
- Message* m = new Message(); // Must be done after this thread finishes, and must break into master mutex
- m->to = messageReceiver;
- m->from = this;
- m->message = Message::PLAYER_EVENT;
- m->parameter = STOP_PLAYBACK;
- logger->log("Player", Log::DEBUG, "Posting message to %p...", messageQueue);
- messageQueue->postMessage(m);
- logger->log("Player", Log::DEBUG, "Message posted...");
- return;
- }
- // if execution gets to here, threadFeedScan hit the start, go to play mode
- state = S_PLAY;
- audio->reset();
- audio->setStreamType(Audio::MPEG2_PES);
- demuxer->flush();
- demuxer->seek();
- demuxer->setFrameNum(currentFrameNumber);
- videoStartup = true;
- afeed.start();
- vfeed.start();
- audio->play();
- audio->sync();
- audio->systemMuteOff();
- audio->doMuting();
- }
-
- if (state == S_PLAY) threadFeedPlay();
- }
- else
- {
- threadFeedLive();
- }
-}
-
-void Player::threadFeedLive()
-{
- UINT thisRead;
- UINT writeLength;
- UINT thisWrite;
- UINT preBufferTotal = 0;
-
- UINT askFor;
- while(1)
+ if ((state == S_FFWD) || (state == S_FBWD))
{
- thisRead = 0;
- writeLength = 0;
- thisWrite = 0;
-
- threadCheckExit();
-
- if (startup)
- askFor = startupBlockSize; // find audio streams sized block
- else
- askFor = blockSize; // normal
-
- threadBuffer = vdr->getBlock(0, askFor, &thisRead);
-
- if (!vdr->isConnected())
- {
- doConnectionLost();
- return;
- }
-
- if (!threadBuffer) break;
-
- if (startup)
- {
- int a_stream = demuxer->scan(threadBuffer, thisRead);
- demuxer->setAudioStream(a_stream);
- logger->log("Player", Log::DEBUG, "Startup Audio stream chosen %x", a_stream);
- startup = false;
- }
-
- if (preBuffering)
- {
- preBufferTotal += thisRead;
- if (preBufferTotal >= preBufferSize)
- {
- logger->log("Player", Log::DEBUG, "Got >500K, prebuffering complete");
-
- preBuffering = false;
- preBufferTotal = 0;
-
-
-// FIXME check the win32 code on the mvp
-#ifndef WIN32
- audio->sync();
- audio->play();
- video->sync();
- video->pause();
- afeed.start();
- vfeed.start();
-#else
- afeed.start();
- vfeed.start();
- audio->sync();
- audio->play();
- video->sync();
- video->pause();
-#endif
-
-// unLock(); // thread will be locked by play until here
- // FIXME - see if this can segfault because it is starting threads out of the master mutex
- }
- }
-
- threadCheckExit();
-
- while(writeLength < thisRead)
+ threadFeedScan();
+ // if this returns then scan hit one end
+ if (state == S_FFWD) // scan hit the end. stop
{
- thisWrite = demuxer->put(threadBuffer + writeLength, thisRead - writeLength);
- writeLength += thisWrite;
-
-// logger->log("Player", Log::DEBUG, "Player put %u to demuxer", thisWrite);
-
- if (!thisWrite)
- {
-// logger->log("Player", Log::DEBUG, "Demuxer full");
- // demuxer is full and can't take anymore
- threadLock();
- threadWaitForSignal();
- threadUnlock();
- }
-
threadCheckExit();
+ Message* m = new Message(); // Must be done after this thread finishes, and must break into master mutex
+ m->to = messageReceiver;
+ m->from = this;
+ m->message = Message::PLAYER_EVENT;
+ m->parameter = STOP_PLAYBACK;
+ logger->log("Player", Log::DEBUG, "Posting message to %p...", messageQueue);
+ messageQueue->postMessage(m);
+ logger->log("Player", Log::DEBUG, "Message posted...");
+ return;
}
-
- free(threadBuffer);
- threadBuffer = NULL;
-
- }
-
- logger->log("Player", Log::DEBUG, "Live play failed to start or interrupted");
-
- if (videoStartup) // oh woe. there never was a stream, I was conned!
- {
- videoStartup = false;
- unLock();
- MILLISLEEP(500); // I think this will solve a race
+ // if execution gets to here, threadFeedScan hit the start, go to play mode
+ state = S_PLAY;
+ audio->reset();
+ audio->setStreamType(Audio::MPEG2_PES);
+ demuxer->flush();
+ demuxer->seek();
+ demuxer->setFrameNum(currentFrameNumber);
+ videoStartup = true;
+ afeed.start();
+ vfeed.start();
+ audio->play();
+ audio->sync();
+ audio->systemMuteOff();
+ audio->doMuting();
}
- threadCheckExit();
-
- Message* m = new Message(); // Must be done after this thread finishes, and must break into master mutex
- m->to = messageReceiver;
- m->from = this;
- m->message = Message::PLAYER_EVENT;
- m->parameter = Player::STREAM_END;
- logger->log("Player", Log::DEBUG, "Posting message to %p...", messageQueue);
- messageQueue->postMessage(m);
- logger->log("Player", Log::DEBUG, "Message posted...");
+ if (state == S_PLAY) threadFeedPlay();
}
void Player::threadFeedPlay()
void Player::test1()
{
logger->log("Player", Log::DEBUG, "PLAYER TEST 1");
-// video->play();
-// video->setAspectRatio(Video::ASPECT4X3);
- jumpToFrameP(37507);
}
void Player::test2()
{
logger->log("Player", Log::DEBUG, "PLAYER TEST 2");
- video->setAspectRatio(Video::ASPECT16X9);
}
#endif
// ----------------------------------- Called from outside, one offs or info funcs
-PlayerRadio::PlayerRadio(MessageQueue* tmessageQueue, void* tmessageReceiver, bool tIsRecording)
+PlayerRadio::PlayerRadio(MessageQueue* tmessageQueue, void* tmessageReceiver)
: afeed(this)
{
messageQueue = tmessageQueue;
startPTS = 0;
lengthSeconds = 0;
- isRecording = tIsRecording;
-
threadBuffer = NULL;
blockSize = 10000;
startupBlockSize = 20000;
- preBufferSize = 40000;
Video::getInstance()->turnVideoOff();
}
mutex=CreateMutex(NULL,FALSE,NULL);
#endif
- if (isRecording)
- demuxer = new DemuxerVDR();
- else
- demuxer = new DemuxerTS();
+ demuxer = new DemuxerVDR();
if (!demuxer) return 0;
if (!demuxer->init(this, audio, NULL, 0, 40000))
UINT thisRead = 0;
int success;
- if (isRecording)
+ UCHAR* buffer = vdr->getBlock(0, 10000, &thisRead);
+ if (!buffer)
{
- UCHAR* buffer = vdr->getBlock(0, 10000, &thisRead);
- if (!buffer)
- {
- logger->log("PlayerRadio", Log::ERR, "Failed to get start block");
- shutdown();
- if (!vdr->isConnected()) doConnectionLost();
- return 0;
- }
-
- success = demuxer->findPTS(buffer, thisRead, &startPTS);
- if (!success)
- {
- logger->log("PlayerRadio", Log::ERR, "Failed to get start PTS");
- free(buffer);
- shutdown();
- return 0;
- }
+ logger->log("PlayerRadio", Log::ERR, "Failed to get start block");
+ shutdown();
+ if (!vdr->isConnected()) doConnectionLost();
+ return 0;
+ }
+ success = demuxer->findPTS(buffer, thisRead, &startPTS);
+ if (!success)
+ {
+ logger->log("PlayerRadio", Log::ERR, "Failed to get start PTS");
free(buffer);
+ shutdown();
+ return 0;
+ }
- if (!setLengthSeconds())
- {
- logger->log("PlayerRadio", Log::ERR, "Failed to setLengthSeconds");
- shutdown();
- return 0;
- }
+ free(buffer);
+
+ if (!setLengthSeconds())
+ {
+ logger->log("PlayerRadio", Log::ERR, "Failed to setLengthSeconds");
+ shutdown();
+ return 0;
}
initted = true;
// ----------------------------------- Externally called events
-void PlayerRadio::play(ULONG Apid)
-{
- // TS mode
- DemuxerTS* dts = (DemuxerTS*)demuxer;
- dts->setAID(Apid,0/*Radio is always mpeg?*/);
- play();
-}
-
void PlayerRadio::play()
{
if (!initted) return;
audio->setStreamType(Audio::MPEG2_PES);
audio->systemMuteOff();
demuxer->reset();
- if (isRecording)
- {
- // FIXME use restartAtPacket here?
- if (currentPacketNumber > lengthPackets) currentPacketNumber = 0;
- demuxer->setPacketNum(currentPacketNumber);
- }
+ // FIXME use restartAtPacket here?
+ if (currentPacketNumber > lengthPackets) currentPacketNumber = 0;
+ demuxer->setPacketNum(currentPacketNumber);
state = S_PLAY;
threadStart();
+ logger->log("PlayerRadio", Log::DEBUG, "Immediate play");
+ afeed.start();
+ audio->play();
- if (isRecording)
- {
- logger->log("PlayerRadio", Log::DEBUG, "Immediate play");
- afeed.start();
- audio->play();
- }
- else // do prebuffering
- {
- logger->log("PlayerRadio", Log::DEBUG, "Prebuffering...");
- preBuffering = true;
- }
return;
}
case S_PAUSE_P: // to S_PAUSE_P
void PlayerRadio::threadMethod()
{
- if (isRecording)
- {
- if (state == S_PLAY) threadFeedPlay();
- }
- else
- {
- threadFeedLive();
- }
-}
-
-void PlayerRadio::threadFeedLive()
-{
- UINT thisRead;
- UINT writeLength;
- UINT thisWrite;
- UINT preBufferTotal = 0;
-
- UINT askFor;
- while(1)
- {
- thisRead = 0;
- writeLength = 0;
- thisWrite = 0;
-
- threadCheckExit();
-
- if (startup)
- askFor = startupBlockSize; // find audio streams sized block
- else
- askFor = blockSize; // normal
-
- threadBuffer = vdr->getBlock(0, askFor, &thisRead);
-
- if (!vdr->isConnected())
- {
- doConnectionLost();
- return;
- }
-
- if (!threadBuffer) break;
-
- if (startup)
- {
- int a_stream = demuxer->scan(threadBuffer, thisRead);
- demuxer->setAudioStream(a_stream);
- logger->log("PlayerRadio", Log::DEBUG, "Startup Audio stream chosen %x", a_stream);
- startup = false;
- }
-
- if (preBuffering)
- {
- preBufferTotal += thisRead;
- if (preBufferTotal >= preBufferSize)
- {
- logger->log("PlayerRadio", Log::DEBUG, "Got >500K, prebuffering complete");
-
- preBuffering = false;
- preBufferTotal = 0;
-
- audio->play();
- afeed.start();
-// unLock(); // thread will be locked by play until here
- // FIXME - see if this can segfault because it is starting threads out of the master mutex
- }
- }
-
- threadCheckExit();
-
- while(writeLength < thisRead)
- {
- thisWrite = demuxer->put(threadBuffer + writeLength, thisRead - writeLength);
- writeLength += thisWrite;
-
- if (!thisWrite)
- {
- // demuxer is full and can't take anymore
- threadLock();
- threadWaitForSignal();
- threadUnlock();
- }
-
- threadCheckExit();
- }
-
- free(threadBuffer);
- threadBuffer = NULL;
-
- }
-
- logger->log("PlayerRadio", Log::DEBUG, "Live play failed to start or interrupted");
-
- threadCheckExit();
-
- Message* m = new Message(); // Must be done after this thread finishes, and must break into master mutex
- m->to = messageReceiver;
- m->from = this;
- m->message = Message::PLAYER_EVENT;
- m->parameter = PlayerRadio::STREAM_END;
- logger->log("PlayerRadio", Log::DEBUG, "Posting message to %p...", messageQueue);
- messageQueue->postMessage(m);
- logger->log("PlayerRadio", Log::DEBUG, "Message posted...");
+ if (state == S_PLAY) threadFeedPlay();
}
void PlayerRadio::threadFeedPlay()
threadBuffer = NULL;
}
}
+