From 56d635ac26e700723bab764eea680cd0ac98a69e Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Sun, 7 May 2006 22:08:52 +0000 Subject: [PATCH] Changes for demuxer. New mutex code --- player.cc | 378 ++++++++++++++++++++++++++++++++---------------------- player.h | 31 ++++- 2 files changed, 253 insertions(+), 156 deletions(-) diff --git a/player.cc b/player.cc index 0449c13..0ee83c5 100644 --- a/player.cc +++ b/player.cc @@ -20,6 +20,8 @@ #include "player.h" +// ----------------------------------- Called from outside, one offs or info funcs + Player::Player(MessageQueue* messageQueue, bool tIsRecording, bool tIsRadio) : vfeed(this), afeed(this) { @@ -27,7 +29,7 @@ Player::Player(MessageQueue* messageQueue, bool tIsRecording, bool tIsRadio) audio = Audio::getInstance(); video = Video::getInstance(); logger = Log::getInstance(); - initted = 0; + initted = false; paused = false; playing = false; ffwd = false; @@ -63,16 +65,16 @@ Player::Player(MessageQueue* messageQueue, bool tIsRecording, bool tIsRadio) Player::~Player() { if (initted) shutdown(); - if (demuxer != NULL) delete demuxer; } int Player::init() { if (initted) return 0; - demuxer = new DemuxerVDR; + pthread_mutex_init(&mutex, NULL); - if (demuxer == NULL) return 0; + demuxer = new DemuxerVDR(); + if (!demuxer) return 0; if (!demuxer->init(this)) { @@ -92,14 +94,14 @@ int Player::init() video->blank(); audio->stop(); - initted = 1; + initted = true; return 1; } int Player::shutdown() { if (!initted) return 0; - initted = 0; + initted = false; // copy of stop if (playing) @@ -110,40 +112,129 @@ int Player::shutdown() video->blank(); audio->stop(); vfeed.stop(); + afeed.stop(); video->reset(); demuxer->reset(); feedPosition = 0; } + delete demuxer; + demuxer = NULL; + return 1; } +void Player::setPosition(ULLONG position) +{ + feedPosition = position; +} + +void Player::setLength(ULLONG length) +{ + lastRescan = time(NULL); + streamLength = length; + logger->log("Player", Log::DEBUG, "Player has received length of %llu", streamLength); +} + +ULLONG Player::getEndTS() // used internally (jump to percent) +{ + long long rendTS = endTS - startTS; + if (rendTS < 0) rendTS += 8589934592ULL; + return (ULLONG)rendTS; +} + +ULLONG Player::getPositionTS() // used internall (skip fw/bw) +{ + if (startup) return 0ULL; + long long currentTS = video->getCurrentTimestamp() - startTS; + if (currentTS < 0) currentTS += 8589934592ULL; + return (ULLONG)currentTS; +} + +// ----------------------------------- Externally called events + int Player::play() +{ + lock(); + return playInt(); +// unLock(); - let thread unlock this +} + +void Player::stop() +{ + lock(); + stopInt(); + unLock(); +} + +void Player::togglePause() +{ + lock(); + togglePauseInt(); + unLock(); +} + +void Player::toggleFastForward() +{ + lock(); + toggleFastForwardInt(); + unLock(); +} + +void Player::toggleFastBackward() +{ + lock(); + toggleFastBackwardInt(); + unLock(); +} + +void Player::jumpToPercent(int percent) +{ + threadLock(); + jumpToPercentInt(percent); +// unLock(); - let thread unlock this +} + +void Player::skipForward(int seconds) +{ + lock(); + skipForwardInt(seconds); +// unLock(); - let thread unlock this +} + +void Player::skipBackward(int seconds) +{ + lock(); + skipBackwardInt(seconds); +// unLock(); - let thread unlock this +} + +// ----------------------------------- Implementations called events + + +int Player::playInt() { if (!initted) return 0; // If we are just paused, unpause! if (paused) { - togglePause(); + togglePauseInt(); return 1; } - // If we are still seeking in from the last jump, ignore - if (videoStartup) return 1; - // If we are fast forwarding, set to normal if (ffwd) { - toggleFastForward(); + toggleFastForwardInt(); return 1; } // If we are fast backwarding, set to normal if (fbwd) { - toggleFastBackward(); + toggleFastBackwardInt(); return 1; } @@ -176,20 +267,15 @@ int Player::play() preBuffering = true; } -// ------------------------------------------------------------------------------------------------ - playing = true; return 1; } -void Player::stop() +void Player::stopInt() { if (!initted) return; if (!playing) return; - // If we are still seeking in from the last jump, ignore - if (videoStartup) return; - if (ffwd || fbwd) { ffwd = false; @@ -216,13 +302,13 @@ void Player::stop() feedPosition = 0; } -void Player::togglePause() +void Player::togglePauseInt() { if (!initted) return; if (!playing) return; - if (ffwd) toggleFastForward(); - if (fbwd) toggleFastBackward(); + if (ffwd) toggleFastForwardInt(); + if (fbwd) toggleFastBackwardInt(); if (paused) { @@ -238,83 +324,13 @@ void Player::togglePause() } } -void Player::setPosition(ULLONG position) -{ - feedPosition = position; -} - -void Player::setLength(ULLONG length) -{ - lastRescan = time(NULL); - streamLength = length; - logger->log("Player", Log::DEBUG, "Player has received length of %llu", streamLength); -} - -void Player::restartAt(ULLONG timecode) -{ - // If we are still seeking in from the last jump, ignore - if (videoStartup) return; - - if (paused) togglePause(); - if (ffwd) toggleFastForward(); - - ULONG wantedFrameNumber = video->timecodeToFrameNumber(timecode); - ULLONG newPosition = VDR::getInstance()->positionFromFrameNumber(wantedFrameNumber); - if (!VDR::getInstance()->isConnected()) { doConnectionLost(); return; } - logger->log("Player", Log::DEBUG, "wantedframe %i feedpos %llu goto %llu", wantedFrameNumber, feedPosition, newPosition); - - vfeed.stop(); - afeed.stop(); - threadStop(); - video->stop(); - video->reset(); - audio->reset(); - demuxer->flush(); - if (!isRadio) demuxer->seek(); - feedPosition = newPosition; - videoStartup = true; - afeed.start(); - vfeed.start(); - threadStart(); - audio->play(); - video->sync(); - audio->sync(); - audio->systemMuteOff(); - audio->doMuting(); - fbwd = false; -} - -void Player::skipForward(int seconds) -{ - logger->log("Player", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds); - restartAt(getPositionTS() + (seconds * 90000)); -} - -void Player::skipBackward(int seconds) -{ - logger->log("Player", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds); - long long newTimeCode = getPositionTS() - (seconds * 90000); - if (newTimeCode < 0) newTimeCode = 0; - restartAt(newTimeCode); -} - -void Player::jumpToPercent(int percent) -{ - logger->log("Player", Log::DEBUG, "JUMP TO %i%%", percent); - ULLONG newTimeCode = (ULLONG)(getEndTS() * ((float)percent / 100)); - restartAt(newTimeCode); -} - -void Player::toggleFastForward() +void Player::toggleFastForwardInt() { if (!initted) return; if (!playing) return; - // If we are still seeking in from the last jump, ignore - if (videoStartup) return; - - if (paused) togglePause(); - if (fbwd) toggleFastBackward(); + if (paused) togglePauseInt(); + if (fbwd) toggleFastBackwardInt(); if (ffwd) { @@ -350,16 +366,13 @@ void Player::toggleFastForward() } } -void Player::toggleFastBackward() +void Player::toggleFastBackwardInt() { if (!initted) return; if (!playing) return; - // If we are still seeking in from the last jump, ignore - if (videoStartup) return; - - if (paused) togglePause(); - if (ffwd) toggleFastForward(); + if (paused) togglePauseInt(); + if (ffwd) toggleFastForwardInt(); if (fbwd) { @@ -388,21 +401,122 @@ void Player::toggleFastBackward() } } -ULLONG Player::getPositionTS() +void Player::skipForwardInt(int seconds) { - if (startup) return 0ULL; - long long currentTS = video->getCurrentTimestamp() - startTS; - if (currentTS < 0) currentTS += 8589934592ULL; - return (ULLONG)currentTS; + logger->log("Player", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds); + restartAt(getPositionTS() + (seconds * 90000)); } -ULLONG Player::getEndTS() +void Player::skipBackwardInt(int seconds) { - long long rendTS = endTS - startTS; - if (rendTS < 0) rendTS += 8589934592ULL; - return (ULLONG)rendTS; + logger->log("Player", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds); + long long newTimeCode = getPositionTS() - (seconds * 90000); + if (newTimeCode < 0) newTimeCode = 0; + restartAt(newTimeCode); } +void Player::jumpToPercentInt(int percent) +{ + logger->log("Player", Log::DEBUG, "JUMP TO %i%%", percent); + ULLONG newTimeCode = (ULLONG)(getEndTS() * ((float)percent / 100)); + restartAt(newTimeCode); +} + + +// ----------------------------------- Internal functions + +void Player::lock() +{ +#ifndef WIN32 + pthread_mutex_lock(&mutex); +#else + // FIXME Marten +#endif +} + +void Player::unLock() +{ +#ifndef WIN32 + pthread_mutex_unlock(&mutex); +#else + // FIXME Marten +#endif +} + +void Player::restartAt(ULLONG timecode) +{ + if (paused) togglePauseInt(); + if (ffwd) toggleFastForwardInt(); + + ULONG wantedFrameNumber = video->timecodeToFrameNumber(timecode); + ULLONG newPosition = VDR::getInstance()->positionFromFrameNumber(wantedFrameNumber); + if (!VDR::getInstance()->isConnected()) { doConnectionLost(); return; } + logger->log("Player", Log::DEBUG, "wantedframe %i feedpos %llu goto %llu", wantedFrameNumber, feedPosition, newPosition); + + vfeed.stop(); + afeed.stop(); + threadStop(); + video->stop(); + video->reset(); + audio->reset(); + demuxer->flush(); + if (!isRadio) demuxer->seek(); + feedPosition = newPosition; + videoStartup = true; + afeed.start(); + vfeed.start(); + threadStart(); + audio->play(); + video->sync(); + audio->sync(); + audio->systemMuteOff(); + audio->doMuting(); + fbwd = false; +} + +void Player::setStartTS(UINT dataInBuffer) +{ + if (isRecording && feedPosition) // (feedPosition != 0) + { + // FIXME find out how much data need to get to find a TS + // Need to get the actual start of the recording + + UINT thisRead; + UCHAR* tempBuffer = VDR::getInstance()->getBlock(0, 100000, &thisRead); + if (!tempBuffer && !VDR::getInstance()->isConnected()) { doConnectionLost(); return; } + if (!tempBuffer) return; + if (thisRead) demuxer->findVideoPTS(tempBuffer, thisRead, &startTS); + free(tempBuffer); + } + else + { + demuxer->findVideoPTS(threadBuffer, dataInBuffer, &startTS); + } +} + +void Player::setEndTS() +{ + logger->log("Player", Log::DEBUG, "Setting end TS"); + + UINT thisRead; + UCHAR* tempBuffer = VDR::getInstance()->getBlock((streamLength - 100000), 100000, &thisRead); + if (!tempBuffer && !VDR::getInstance()->isConnected()) { doConnectionLost(); return; } + if (!tempBuffer) return; + if (thisRead) demuxer->findVideoPTS(tempBuffer, thisRead, &endTS); + free(tempBuffer); + logger->log("Player", Log::DEBUG, "Set end TS"); +} + +void Player::doConnectionLost() +{ + Message* m = new Message(); + m->message = Message::CONNECTION_LOST; + m->to = this; + commandMessageQueue->postMessage(m); +} + +// ----------------------------------- Callback + void Player::call(void* caller) { if (caller == demuxer) @@ -441,20 +555,14 @@ void Player::call(void* caller) video->play(); video->sync(); vfeed.release(); + unLock(); } threadSignalNoLock(); } } -void Player::doConnectionLost() -{ - Message* m = new Message(); - m->message = Message::CONNECTION_LOST; - m->to = this; - commandMessageQueue->postMessage(m); -} -// Feed thread +// ----------------------------------- Feed thread void Player::threadMethod() { @@ -549,6 +657,7 @@ void Player::threadMethod() video->pause(); afeed.start(); vfeed.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 } } @@ -582,7 +691,7 @@ void Player::threadMethod() if (!thisWrite) { // logger->log("Player", Log::DEBUG, "DEMUXER FULL!!!"); - // demuxer is full and can't take any more + // demuxer is full and can't take anymore threadLock(); threadWaitForSignal(); threadUnlock(); @@ -619,38 +728,7 @@ void Player::threadPostStopCleanup() } } -void Player::setStartTS(UINT dataInBuffer) -{ - if (isRecording && feedPosition) // (feedPosition != 0) - { - // FIXME find out how much data need to get to find a TS - // Need to get the actual start of the recording - - UINT thisRead; - UCHAR* tempBuffer = VDR::getInstance()->getBlock(0, 100000, &thisRead); - if (!tempBuffer && !VDR::getInstance()->isConnected()) { doConnectionLost(); return; } - if (!tempBuffer) return; - if (thisRead) demuxer->findVideoPTS(tempBuffer, thisRead, &startTS); - free(tempBuffer); - } - else - { - demuxer->findVideoPTS(threadBuffer, dataInBuffer, &startTS); - } -} - -void Player::setEndTS() -{ - logger->log("Player", Log::DEBUG, "Setting end TS"); - - UINT thisRead; - UCHAR* tempBuffer = VDR::getInstance()->getBlock((streamLength - 100000), 100000, &thisRead); - if (!tempBuffer && !VDR::getInstance()->isConnected()) { doConnectionLost(); return; } - if (!tempBuffer) return; - if (thisRead) demuxer->findVideoPTS(tempBuffer, thisRead, &endTS); - free(tempBuffer); - logger->log("Player", Log::DEBUG, "Set end TS"); -} +// ----------------------------------- Dev #ifdef DEV void Player::test1() diff --git a/player.h b/player.h index 6b632b0..228f6d2 100644 --- a/player.h +++ b/player.h @@ -48,6 +48,8 @@ class Player : public Thread_TYPE, public Callback int init(); int shutdown(); + void setPosition(ULLONG position); + void setLength(ULLONG length); int play(); void stop(); @@ -57,31 +59,39 @@ class Player : public Thread_TYPE, public Callback void jumpToPercent(int percent); void skipForward(int seconds); void skipBackward(int seconds); - void call(void*); // for callback interface - void setPosition(ULLONG position); - void setLength(ULLONG length); - ULLONG getPositionTS(); - ULLONG getEndTS(); bool isPaused() { return paused; } bool isFfwd() { return ffwd; } bool isFbwd() { return fbwd; } + ULLONG getPositionTS(); + ULLONG getEndTS(); + + void call(void*); // for callback interface #ifdef DEV void test1(); void test2(); #endif + protected: void threadMethod(); void threadPostStopCleanup(); private: + int playInt(); + void stopInt(); + void togglePauseInt(); + void toggleFastForwardInt(); + void toggleFastBackwardInt(); + void jumpToPercentInt(int percent); + void skipForwardInt(int seconds); + void skipBackwardInt(int seconds); + void setStartTS(UINT dataInBuffer); void setEndTS(); void doConnectionLost(); void restartAt(ULLONG timeCode); - int initted; MessageQueue* commandMessageQueue; Log* logger; Audio* audio; @@ -90,12 +100,21 @@ class Player : public Thread_TYPE, public Callback VFeed vfeed; AFeed afeed; + bool initted; bool startup; bool videoStartup; bool isRecording; bool isRadio; bool preBuffering; +#ifndef WIN32 + pthread_mutex_t mutex; +#else + // FIXME Marten +#endif + void lock(); + void unLock(); + ULLONG startTS; ULLONG endTS; ULLONG streamLength; -- 2.39.2