123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- #include "SeekLayer.h"
- #include "Main.h"
- #include "output/AudioOut.h"
- #include "util.h"
- #include <assert.h>
- using namespace Nullsoft::Utility;
- struct OpenThreadData
- {
- IWMReaderCallback *callback;
- wchar_t *url;
- IWMReader *reader;
- void open()
- {
- reader->Open(url, callback, 0);
- }
- OpenThreadData(IWMReader *_reader, const wchar_t *_url, IWMReaderCallback *_callback)
- {
- reader = _reader;
- reader->AddRef();
- callback = _callback;
- callback->AddRef();
- url = _wcsdup(_url);
- }
- ~OpenThreadData()
- {
- free(url);
- reader->Release();
- callback->Release();
- }
- };
- DWORD WINAPI OpenThread(void *param)
- {
- OpenThreadData *data = (OpenThreadData *)param;
- data->open();
- delete data;
- return 0;
- }
- #define NEW_SEEK
- SeekLayer::SeekLayer(IWMReader *_reader, ClockLayer *_clock)
- : seekPos(0), reader(_reader), playState(PLAYSTATE_CLOSED), metadata(NULL), clock(_clock),
- needPause(false), paused(false), needStop(false),
- seekGuard(GUARDNAME("Seek Guard")),
- oldState_buffer(PLAYSTATE_NONE)
- {
- reader->AddRef();
- reader->QueryInterface(&reader2);
- }
- void SeekLayer::DoStop()
- {
- if (paused)
- reader->Resume();
- reader->Stop();
- First().Stopping();
- First().Kill();
- if (paused)
- {
- paused = false;
- out->Pause(0);
- }
- needStop = false;
- }
- void SeekLayer::SeekTo(long position)
- {
- AutoLock lock (seekGuard LOCKNAME("SeekTo"));
- if (paused)
- {
- reader->Resume();
- }
- First().Stopping();
- First().Kill();
- seekPos = position;
- clock->SetLastOutputTime(position);
- clock->SetStartTimeMilliseconds(position);
- out->Flush(position);
- QWORD qSeekPos = position;
- qSeekPos *= 10000;
- reader->Start(qSeekPos, 0, 1.0f, NULL);
- if (paused)
- {
- reader->Pause();
- }
- }
- void SeekLayer::Pause()
- {
- AutoLock lock (seekGuard LOCKNAME("Pause"));
- if (playState == PLAYSTATE_STARTED)
- {
- paused = true;
- reader->Pause();
- out->Pause(1);
- }
- else
- {
- needPause = true;
- }
- }
- int SeekLayer::Open(const wchar_t *filename, IWMReaderCallback *callback)
- {
- AutoLock lock (seekGuard LOCKNAME("Open"));
- assert(playState == PLAYSTATE_CLOSED);
- needStop = false;
- playState = PLAYSTATE_OPENING;
- DWORD dummyId;
- CreateThread(NULL, 0, OpenThread, new OpenThreadData(reader, filename, callback), 0, &dummyId);
- return 0;
- }
- void SeekLayer::Stop()
- {
- AutoLock lock (seekGuard LOCKNAME("Stop"));
- needStop = true;
- switch (playState)
- {
- case PLAYSTATE_BUFFERING:
- // needStop=false;
- reader2->StopBuffering();
- // reader->Stop();
- break;
- case PLAYSTATE_OPENING:
- // wait for it to open (or connect) and then we'll kill it there
- break;
- case PLAYSTATE_NONE:
- case PLAYSTATE_STOPPED:
- if (FAILED(reader->Close())) // reader->Close() is sometimes synchronous, and sometimes not valid here
- {
- playState = PLAYSTATE_CLOSED;
- return ;
- }
- break;
- case PLAYSTATE_OPENED:
- case PLAYSTATE_STARTED:
- reader->Stop();
- First().Stopping();
- First().Kill();
- break;
- case PLAYSTATE_CLOSED:
- needStop = false;
- break;
- /*
- case PLAYSTATE_BUFFERING:
- reader2->StopBuffering();
- reader->Stop();
- break;*/
- case PLAYSTATE_SEEK:
- break;
- }
- while (playState != PLAYSTATE_CLOSED)
- {
- lock.ManualUnlock();
- Sleep(55);
- lock.ManualLock(MANUALLOCKNAME("[Manual Lock]Stop"));
- }
- needStop = false;
- }
- void SeekLayer::Unpause()
- {
- AutoLock lock (seekGuard LOCKNAME("Unpause"));
- if (playState == PLAYSTATE_STARTED)
- {
- paused = false;
- out->Pause(0);
- reader->Resume();
- clock->Clock();
- }
- else
- {
- needPause = false;
- }
- }
- void SeekLayer::Opened()
- {
- {
- AutoLock lock (seekGuard LOCKNAME("SeekLayer::Opened"));
- if (needStop)
- {
- playState = PLAYSTATE_OPENED;
- lock.ManualUnlock();
- reader->Close();
- lock.ManualLock(MANUALLOCKNAME("[Manual Lock]SeekLayer::Opened"));
- return ;
- }
- playState = PLAYSTATE_OPENED;
- }
- WMHandler::Opened();
- }
- void SeekLayer::Stopped()
- {
- {
- AutoLock lock (seekGuard LOCKNAME("Stopped"));
- if (needStop)
- {
- playState = PLAYSTATE_STOPPED;
- lock.ManualUnlock();
- reader->Close();
- lock.ManualLock(MANUALLOCKNAME("Stopped"));
- }
- else
- {
- playState = PLAYSTATE_STOPPED;
- }
- WMHandler::Stopped();
- }
- }
- void SeekLayer::Started()
- {
- {
- AutoLock lock (seekGuard LOCKNAME("Started"));
- playState = PLAYSTATE_STARTED;
- if (needStop)
- {
- reader->Stop();
- First().Stopping();
- First().Kill();
- return ;
- }
- else if (needPause)
- {
- Pause();
- needPause = false;
- }
- }
- WMHandler::Started();
- }
- void SeekLayer::Closed()
- {
- playState = PLAYSTATE_CLOSED;
- paused = false;
- needPause = false;
- needStop = false;
- seekPos = 0;
- WMHandler::Closed();
- }
- void SeekLayer::BufferingStarted()
- {
- {
- AutoLock lock (seekGuard LOCKNAME("BufferingStarted"));
- if (playState == PLAYSTATE_OPENED)
- oldState_buffer = PLAYSTATE_NONE;
- else
- oldState_buffer = playState;
- if (playState != PLAYSTATE_STARTED)
- playState = PLAYSTATE_BUFFERING;
- if (needStop)
- reader2->StopBuffering();
- }
- WMHandler::BufferingStarted();
- }
- void SeekLayer::BufferingStopped()
- {
- {
- AutoLock lock (seekGuard LOCKNAME("BufferingStopped"));
- if (needStop)
- reader->Stop();
- playState = oldState_buffer;
- }
- WMHandler::BufferingStopped();
- }
- void SeekLayer::EndOfFile()
- {
- {
- AutoLock lock (seekGuard LOCKNAME("EndOfFile"));
- if (needStop)
- return ;
- }
- WMHandler::EndOfFile();
- }
- void SeekLayer::Connecting()
- {
- {
- AutoLock lock (seekGuard LOCKNAME("SeekLayer::Connecting"));
- if (needStop)
- {
- playState = PLAYSTATE_NONE;
- lock.ManualUnlock();
- reader->Close();
- lock.ManualLock(MANUALLOCKNAME("[Manual Lock]SeekLayer::Connecting"));
- return ;
- }
- playState = PLAYSTATE_NONE;
- }
- WMHandler::Connecting();
- }
- void SeekLayer::Locating()
- {
- {
- AutoLock lock (seekGuard LOCKNAME("SeekLayer::Locating"));
- if (needStop)
- {
- playState = PLAYSTATE_NONE;
- lock.ManualUnlock();
- reader->Close();
- lock.ManualLock(MANUALLOCKNAME("[Manual Lock]SeekLayer::Locating"));
- return ;
- }
- playState = PLAYSTATE_NONE;
- }
- WMHandler::Locating();
- }
- void SeekLayer::OpenCalled()
- {
- {
- AutoLock lock (seekGuard LOCKNAME("SeekLayer::OpenCalled"));
- if (needStop)
- {
- playState = PLAYSTATE_NONE;
- lock.ManualUnlock();
- reader->Close();
- lock.ManualLock(MANUALLOCKNAME("[Manual Lock]SeekLayer::OpenCalled"));
- return ;
- }
- playState = PLAYSTATE_NONE;
- }
- WMHandler::OpenCalled();
- }
- void SeekLayer::OpenFailed()
- {
- {
- AutoLock lock (seekGuard LOCKNAME("SeekLayer::OpenFailed"));
- if (playState == PLAYSTATE_OPENING)
- playState = PLAYSTATE_NONE;
- }
- WMHandler::OpenFailed();
- }
- void SeekLayer::Error()
- {
- {
- AutoLock lock (seekGuard LOCKNAME("SeekLayer::Error"));
- /*if (playState == PLAYSTATE_OPENING)
- playState = PLAYSTATE_CLOSED;
- else */if (playState != PLAYSTATE_CLOSED)
- playState = PLAYSTATE_NONE;
- }
- WMHandler::Error();
- }
|