MediaThread.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include "main.h"
  2. #include "MediaThread.h"
  3. #include "config.h"
  4. MediaThread::MediaThread() : wait(INFINITE), thread(0)
  5. {
  6. killEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  7. stopped = CreateEvent(NULL, TRUE, TRUE, NULL);
  8. bufferFreed = CreateEvent(NULL, TRUE, TRUE, NULL);
  9. }
  10. MediaThread::~MediaThread()
  11. {
  12. Kill();
  13. if (thread)
  14. CloseHandle(thread);
  15. }
  16. VOID CALLBACK MediaThread_StartAPC(ULONG_PTR param)
  17. {
  18. reinterpret_cast<MediaThread *>(param)->StartAPC();
  19. }
  20. void MediaThread::StartAPC()
  21. {
  22. wait=config_video_jitter;
  23. }
  24. void MediaThread::StopAPC()
  25. {
  26. BufferList::iterator itr;
  27. for (itr = buffers.begin();itr != buffers.end();itr++)
  28. {
  29. (*itr)->buffer->Release();
  30. delete (*itr);
  31. }
  32. buffers.clear();
  33. SetEvent(stopped);
  34. SetEvent(bufferFreed);
  35. wait=INFINITE;
  36. }
  37. static VOID CALLBACK MediaThread_StopAPC(ULONG_PTR param)
  38. {
  39. reinterpret_cast<MediaThread *>(param)->StopAPC();
  40. }
  41. void MediaThread::Stop()
  42. {
  43. ResetEvent(stopped);
  44. QueueUserAPC(MediaThread_StopAPC, thread, reinterpret_cast<ULONG_PTR>(this));
  45. WaitForSingleObject(stopped, INFINITE);
  46. }
  47. void MediaThread::WaitForStop()
  48. {
  49. WaitForSingleObject(stopped, INFINITE);
  50. }
  51. void MediaThread::SignalStop()
  52. {
  53. ResetEvent(stopped);
  54. QueueUserAPC(MediaThread_StopAPC, thread, reinterpret_cast<ULONG_PTR>(this));
  55. }
  56. void MediaThread::Kill()
  57. {
  58. SetEvent(killEvent);
  59. WaitForSingleObject(stopped, INFINITE);
  60. }
  61. void MediaThread::OrderedInsert(MediaBuffer *buffer)
  62. {
  63. BufferList::iterator itr;
  64. for (itr = buffers.begin();itr != buffers.end(); itr++)
  65. {
  66. if ((*itr)->timestamp > buffer->timestamp)
  67. {
  68. buffers.insert(itr, buffer);
  69. break;
  70. }
  71. }
  72. if (itr == buffers.end())
  73. buffers.push_back(buffer);
  74. }
  75. VOID CALLBACK MediaThread_AddAPC(ULONG_PTR param)
  76. {
  77. MediaBufferAPC *apc = reinterpret_cast<MediaBufferAPC *>(param);
  78. apc->thread->AddAPC(apc->buffer);
  79. delete apc;
  80. }
  81. bool MediaThread::AddBuffer(INSSBuffer *buff, QWORD ts, unsigned long flags, bool drmProtected)
  82. {
  83. if (WaitForSingleObject(bufferFreed, 0) == WAIT_TIMEOUT)
  84. return false;
  85. buff->AddRef();
  86. MediaBuffer *buffer = new MediaBuffer(buff, ts, flags, drmProtected);
  87. MediaBufferAPC *apc = new MediaBufferAPC;
  88. apc->buffer = buffer;
  89. apc->thread = this;
  90. QueueUserAPC(MediaThread_AddAPC, thread, reinterpret_cast<ULONG_PTR>(apc));
  91. Sleep(config_video_jitter); // sleep for a bit to keep the thread from going nuts
  92. return true; // added
  93. }