PlaybackBase.h 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #pragma once
  2. #include "nx/nx.h"
  3. #include "nu/LockFreeItem.h"
  4. #include "player/ifc_playback.h"
  5. #include "player/ifc_player.h"
  6. #include "player/svc_output.h"
  7. #include "nu/ThreadLoop.h"
  8. #include "filelock/api_filelock.h"
  9. /* TODO: we can probably redo this without the mutex, possibly using semaphores */
  10. class PlaybackBase : public ifc_playback, public cb_filelock
  11. {
  12. public:
  13. using ifc_playback::Retain;
  14. using ifc_playback::Release;
  15. /* ifc_playback implementation */
  16. int WASABICALL Playback_Play(svc_output *output, ifc_playback_parameters *secondary_parameters);
  17. int WASABICALL Playback_SeekSeconds(double seconds);
  18. int WASABICALL Playback_Pause();
  19. int WASABICALL Playback_Unpause();
  20. int WASABICALL Playback_Stop();
  21. int WASABICALL Playback_Close();
  22. /* cb_filelock implementation */
  23. int WASABICALL FileLockCallback_Interrupt();
  24. protected:
  25. nx_thread_t playback_thread;
  26. svc_output *output_service;
  27. ifc_player *player;
  28. ifc_playback_parameters *secondary_parameters;
  29. nx_uri_t filename;
  30. enum
  31. {
  32. WAKE_KILL=(1<<0),
  33. WAKE_PLAY=(1<<1),
  34. WAKE_PAUSE=(1<<2),
  35. WAKE_STOP=(1<<3),
  36. WAKE_INTERRUPT=(1<<4),
  37. WAKE_UNPAUSE=(1<<5), // this is actually unused in wake_flags, just used as a return value from Wake/WakeReason
  38. WAKE_RESUME=(1<<6), // this is actually unused in wake_flags, just used as a return value from Wake/WakeReason
  39. WAKE_START_MASK = WAKE_PLAY|WAKE_STOP,
  40. WAKE_KILL_MASK = WAKE_KILL|WAKE_STOP,
  41. WAKE_ALL_MASK = WAKE_KILL|WAKE_PLAY|WAKE_PAUSE|WAKE_STOP|WAKE_INTERRUPT,
  42. };
  43. protected:
  44. PlaybackBase();
  45. ~PlaybackBase();
  46. /* === API for derived classes to use === */
  47. int Initialize(nx_uri_t filename, ifc_player *player);
  48. int Init();
  49. /* this checks if one of the flags in mask has toggled.
  50. if playback is stopped and WAKE_PLAY is in the mask, this will sleep until a flag changes
  51. if playback is paused and WAKE_PAUSE is in the mask, this will sleep until a flag changes
  52. if both WAKE_PLAY and WAKE_PAUSE are in the mask, this will sleep until either happens
  53. returns 0 if no flag changed */
  54. int Wake(int mask); /* Sleeps indefinitely until a flag changes */
  55. int Check(int mask); /* like Wake() but never actually goes to sleep for any reason */
  56. int Wait(unsigned int milliseconds, int mask); /* Sleeps for a limited amount of time for a flag to change */
  57. int Sleep(unsigned int milliseconds, int mask); /* unlike Wait, this one does *not* update last flags */
  58. int WakeReason(int mask) const;
  59. void OnInterrupted(); /* turn off the WAKE_INTERRUPT flag */
  60. void OnStopPlaying(); /* turn off the WAKE_PLAY flag */
  61. bool PendingSeek();
  62. Agave_Seek *GetSeek();
  63. void FreeSeek(Agave_Seek *seek);
  64. /* === End of API for derived classes to use === */
  65. private:
  66. void ToggleFlags(int wake_reason);
  67. int wake_flags; /* marked volatile so the compiler doesn't cache */
  68. int last_wake_flags;
  69. Agave_Seek *queued_seek;
  70. ThreadLoop thread_loop;
  71. static void APC_Play(void *_playback_base, void *param2, double real_value);
  72. static void APC_Seek(void *_playback_base, void *param2, double real_value);
  73. static void APC_Pause(void *_playback_base, void *param2, double real_value);
  74. static void APC_Unpause(void *_playback_base, void *param2, double real_value);
  75. static void APC_Stop(void *_playback_base, void *param2, double real_value);
  76. static void APC_Close(void *_playback_base, void *param2, double real_value);
  77. static void APC_Interrupt(void *_playback_base, void *param2, double real_value);
  78. };