SeekLayer.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. #include "SeekLayer.h"
  2. #include "Main.h"
  3. #include "output/AudioOut.h"
  4. #include "util.h"
  5. #include <assert.h>
  6. using namespace Nullsoft::Utility;
  7. struct OpenThreadData
  8. {
  9. IWMReaderCallback *callback;
  10. wchar_t *url;
  11. IWMReader *reader;
  12. void open()
  13. {
  14. reader->Open(url, callback, 0);
  15. }
  16. OpenThreadData(IWMReader *_reader, const wchar_t *_url, IWMReaderCallback *_callback)
  17. {
  18. reader = _reader;
  19. reader->AddRef();
  20. callback = _callback;
  21. callback->AddRef();
  22. url = _wcsdup(_url);
  23. }
  24. ~OpenThreadData()
  25. {
  26. free(url);
  27. reader->Release();
  28. callback->Release();
  29. }
  30. };
  31. DWORD WINAPI OpenThread(void *param)
  32. {
  33. OpenThreadData *data = (OpenThreadData *)param;
  34. data->open();
  35. delete data;
  36. return 0;
  37. }
  38. #define NEW_SEEK
  39. SeekLayer::SeekLayer(IWMReader *_reader, ClockLayer *_clock)
  40. : seekPos(0), reader(_reader), playState(PLAYSTATE_CLOSED), metadata(NULL), clock(_clock),
  41. needPause(false), paused(false), needStop(false),
  42. seekGuard(GUARDNAME("Seek Guard")),
  43. oldState_buffer(PLAYSTATE_NONE)
  44. {
  45. reader->AddRef();
  46. reader->QueryInterface(&reader2);
  47. }
  48. void SeekLayer::DoStop()
  49. {
  50. if (paused)
  51. reader->Resume();
  52. reader->Stop();
  53. First().Stopping();
  54. First().Kill();
  55. if (paused)
  56. {
  57. paused = false;
  58. out->Pause(0);
  59. }
  60. needStop = false;
  61. }
  62. void SeekLayer::SeekTo(long position)
  63. {
  64. AutoLock lock (seekGuard LOCKNAME("SeekTo"));
  65. if (paused)
  66. {
  67. reader->Resume();
  68. }
  69. First().Stopping();
  70. First().Kill();
  71. seekPos = position;
  72. clock->SetLastOutputTime(position);
  73. clock->SetStartTimeMilliseconds(position);
  74. out->Flush(position);
  75. QWORD qSeekPos = position;
  76. qSeekPos *= 10000;
  77. reader->Start(qSeekPos, 0, 1.0f, NULL);
  78. if (paused)
  79. {
  80. reader->Pause();
  81. }
  82. }
  83. void SeekLayer::Pause()
  84. {
  85. AutoLock lock (seekGuard LOCKNAME("Pause"));
  86. if (playState == PLAYSTATE_STARTED)
  87. {
  88. paused = true;
  89. reader->Pause();
  90. out->Pause(1);
  91. }
  92. else
  93. {
  94. needPause = true;
  95. }
  96. }
  97. int SeekLayer::Open(const wchar_t *filename, IWMReaderCallback *callback)
  98. {
  99. AutoLock lock (seekGuard LOCKNAME("Open"));
  100. assert(playState == PLAYSTATE_CLOSED);
  101. needStop = false;
  102. playState = PLAYSTATE_OPENING;
  103. DWORD dummyId;
  104. CreateThread(NULL, 0, OpenThread, new OpenThreadData(reader, filename, callback), 0, &dummyId);
  105. return 0;
  106. }
  107. void SeekLayer::Stop()
  108. {
  109. AutoLock lock (seekGuard LOCKNAME("Stop"));
  110. needStop = true;
  111. switch (playState)
  112. {
  113. case PLAYSTATE_BUFFERING:
  114. // needStop=false;
  115. reader2->StopBuffering();
  116. // reader->Stop();
  117. break;
  118. case PLAYSTATE_OPENING:
  119. // wait for it to open (or connect) and then we'll kill it there
  120. break;
  121. case PLAYSTATE_NONE:
  122. case PLAYSTATE_STOPPED:
  123. if (FAILED(reader->Close())) // reader->Close() is sometimes synchronous, and sometimes not valid here
  124. {
  125. playState = PLAYSTATE_CLOSED;
  126. return ;
  127. }
  128. break;
  129. case PLAYSTATE_OPENED:
  130. case PLAYSTATE_STARTED:
  131. reader->Stop();
  132. First().Stopping();
  133. First().Kill();
  134. break;
  135. case PLAYSTATE_CLOSED:
  136. needStop = false;
  137. break;
  138. /*
  139. case PLAYSTATE_BUFFERING:
  140. reader2->StopBuffering();
  141. reader->Stop();
  142. break;*/
  143. case PLAYSTATE_SEEK:
  144. break;
  145. }
  146. while (playState != PLAYSTATE_CLOSED)
  147. {
  148. lock.ManualUnlock();
  149. Sleep(55);
  150. lock.ManualLock(MANUALLOCKNAME("[Manual Lock]Stop"));
  151. }
  152. needStop = false;
  153. }
  154. void SeekLayer::Unpause()
  155. {
  156. AutoLock lock (seekGuard LOCKNAME("Unpause"));
  157. if (playState == PLAYSTATE_STARTED)
  158. {
  159. paused = false;
  160. out->Pause(0);
  161. reader->Resume();
  162. clock->Clock();
  163. }
  164. else
  165. {
  166. needPause = false;
  167. }
  168. }
  169. void SeekLayer::Opened()
  170. {
  171. {
  172. AutoLock lock (seekGuard LOCKNAME("SeekLayer::Opened"));
  173. if (needStop)
  174. {
  175. playState = PLAYSTATE_OPENED;
  176. lock.ManualUnlock();
  177. reader->Close();
  178. lock.ManualLock(MANUALLOCKNAME("[Manual Lock]SeekLayer::Opened"));
  179. return ;
  180. }
  181. playState = PLAYSTATE_OPENED;
  182. }
  183. WMHandler::Opened();
  184. }
  185. void SeekLayer::Stopped()
  186. {
  187. {
  188. AutoLock lock (seekGuard LOCKNAME("Stopped"));
  189. if (needStop)
  190. {
  191. playState = PLAYSTATE_STOPPED;
  192. lock.ManualUnlock();
  193. reader->Close();
  194. lock.ManualLock(MANUALLOCKNAME("Stopped"));
  195. }
  196. else
  197. {
  198. playState = PLAYSTATE_STOPPED;
  199. }
  200. WMHandler::Stopped();
  201. }
  202. }
  203. void SeekLayer::Started()
  204. {
  205. {
  206. AutoLock lock (seekGuard LOCKNAME("Started"));
  207. playState = PLAYSTATE_STARTED;
  208. if (needStop)
  209. {
  210. reader->Stop();
  211. First().Stopping();
  212. First().Kill();
  213. return ;
  214. }
  215. else if (needPause)
  216. {
  217. Pause();
  218. needPause = false;
  219. }
  220. }
  221. WMHandler::Started();
  222. }
  223. void SeekLayer::Closed()
  224. {
  225. playState = PLAYSTATE_CLOSED;
  226. paused = false;
  227. needPause = false;
  228. needStop = false;
  229. seekPos = 0;
  230. WMHandler::Closed();
  231. }
  232. void SeekLayer::BufferingStarted()
  233. {
  234. {
  235. AutoLock lock (seekGuard LOCKNAME("BufferingStarted"));
  236. if (playState == PLAYSTATE_OPENED)
  237. oldState_buffer = PLAYSTATE_NONE;
  238. else
  239. oldState_buffer = playState;
  240. if (playState != PLAYSTATE_STARTED)
  241. playState = PLAYSTATE_BUFFERING;
  242. if (needStop)
  243. reader2->StopBuffering();
  244. }
  245. WMHandler::BufferingStarted();
  246. }
  247. void SeekLayer::BufferingStopped()
  248. {
  249. {
  250. AutoLock lock (seekGuard LOCKNAME("BufferingStopped"));
  251. if (needStop)
  252. reader->Stop();
  253. playState = oldState_buffer;
  254. }
  255. WMHandler::BufferingStopped();
  256. }
  257. void SeekLayer::EndOfFile()
  258. {
  259. {
  260. AutoLock lock (seekGuard LOCKNAME("EndOfFile"));
  261. if (needStop)
  262. return ;
  263. }
  264. WMHandler::EndOfFile();
  265. }
  266. void SeekLayer::Connecting()
  267. {
  268. {
  269. AutoLock lock (seekGuard LOCKNAME("SeekLayer::Connecting"));
  270. if (needStop)
  271. {
  272. playState = PLAYSTATE_NONE;
  273. lock.ManualUnlock();
  274. reader->Close();
  275. lock.ManualLock(MANUALLOCKNAME("[Manual Lock]SeekLayer::Connecting"));
  276. return ;
  277. }
  278. playState = PLAYSTATE_NONE;
  279. }
  280. WMHandler::Connecting();
  281. }
  282. void SeekLayer::Locating()
  283. {
  284. {
  285. AutoLock lock (seekGuard LOCKNAME("SeekLayer::Locating"));
  286. if (needStop)
  287. {
  288. playState = PLAYSTATE_NONE;
  289. lock.ManualUnlock();
  290. reader->Close();
  291. lock.ManualLock(MANUALLOCKNAME("[Manual Lock]SeekLayer::Locating"));
  292. return ;
  293. }
  294. playState = PLAYSTATE_NONE;
  295. }
  296. WMHandler::Locating();
  297. }
  298. void SeekLayer::OpenCalled()
  299. {
  300. {
  301. AutoLock lock (seekGuard LOCKNAME("SeekLayer::OpenCalled"));
  302. if (needStop)
  303. {
  304. playState = PLAYSTATE_NONE;
  305. lock.ManualUnlock();
  306. reader->Close();
  307. lock.ManualLock(MANUALLOCKNAME("[Manual Lock]SeekLayer::OpenCalled"));
  308. return ;
  309. }
  310. playState = PLAYSTATE_NONE;
  311. }
  312. WMHandler::OpenCalled();
  313. }
  314. void SeekLayer::OpenFailed()
  315. {
  316. {
  317. AutoLock lock (seekGuard LOCKNAME("SeekLayer::OpenFailed"));
  318. if (playState == PLAYSTATE_OPENING)
  319. playState = PLAYSTATE_NONE;
  320. }
  321. WMHandler::OpenFailed();
  322. }
  323. void SeekLayer::Error()
  324. {
  325. {
  326. AutoLock lock (seekGuard LOCKNAME("SeekLayer::Error"));
  327. /*if (playState == PLAYSTATE_OPENING)
  328. playState = PLAYSTATE_CLOSED;
  329. else */if (playState != PLAYSTATE_CLOSED)
  330. playState = PLAYSTATE_NONE;
  331. }
  332. WMHandler::Error();
  333. }