PlaybackBase2.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #pragma once
  2. #include "PlaybackBase.h"
  3. #include "foundation/error.h"
  4. #include "service/api_service.h"
  5. /* this one does most of the work for you.
  6. It assumes blocking I/O and, generally, a simple implementation
  7. You provide an implementation of PlaybackImpl */
  8. class PlaybackBase2;
  9. class PlaybackImpl
  10. {
  11. public:
  12. void Connect(PlaybackBase2 *playback, ifc_playback_parameters *playback_parameters);
  13. /* stuff you need to implement */
  14. /* destructor. be diligent about closing stuff, can't guarantee that Close() got called beforehand */
  15. virtual ~PlaybackImpl();
  16. virtual ns_error_t Open(nx_uri_t filename)=0;
  17. /* you need to handle the possibility that Close gets called more than one time */
  18. virtual void Close()=0;
  19. virtual bool IsSeekable()=0;
  20. /* implementation note: add a reference (Retain) before assigning the value */
  21. virtual ns_error_t GetMetadata(ifc_metadata **metadata)=0;
  22. /* if you set *exact=false, GetLength will get called after the next DecodeStep */
  23. virtual ns_error_t GetLength(double *length, bool *exact)=0;
  24. /* only return an error if you're in a state you can't recover from.
  25. if you can't seek, then just don't seek and return NErr_Success */
  26. virtual ns_error_t Seek(const Agave_Seek *seek, ns_error_t *seek_error, double *new_position)=0;
  27. /* return NErr_Success to continue
  28. NErr_EndOfFile to indicate a natural end of file
  29. otherwise return an error */
  30. virtual ns_error_t DecodeStep()=0;
  31. /* Save information and close the OS file handle.
  32. fill resume_information with whatever information you'll need to resume */
  33. virtual ns_error_t Interrupt(Agave_Seek *resume_information)=0;
  34. /* During resume, be sure to call player->SetMetadata again */
  35. virtual ns_error_t Resume(Agave_Seek *resume_information)=0;
  36. protected:
  37. PlaybackBase2 *playback;
  38. ifc_playback_parameters *playback_parameters;
  39. PlaybackImpl();
  40. };
  41. class PlaybackBase2 : public PlaybackBase
  42. {
  43. public:
  44. PlaybackBase2();
  45. ~PlaybackBase2();
  46. ns_error_t Initialize(api_service *service_manager, PlaybackImpl *implementation, nx_uri_t filename, ifc_player *player);
  47. /* this two should ONLY be called from within your DecodeStep function! */
  48. ns_error_t OpenOutput(const ifc_audioout::Parameters *parameters); // if this returns an error, return it from DecodeStep()
  49. ns_error_t Output(const void *audio_data, size_t audio_data_length, double begin_position_seconds); // if this returns an error, return it from DecodeStep()
  50. ns_error_t OutputNonInterleaved(const void *audio_data, size_t audio_data_length, double begin_position_seconds); // if this returns an error, return it from DecodeStep()
  51. private:
  52. static nx_thread_return_t NXTHREADCALL PlayerThreadFunction(nx_thread_parameter_t param);
  53. nx_thread_return_t NXTHREADCALL DecodeLoop();
  54. ns_error_t Init();
  55. ns_error_t WaitForClose();
  56. ns_error_t OutputWait();
  57. ns_error_t Internal_Interrupt();
  58. PlaybackImpl *implementation;
  59. api_filelock *filelocker;
  60. ifc_audioout *out;
  61. bool paused;
  62. double last_position;
  63. bool exact_length;
  64. ifc_audioout::Parameters parameters;
  65. const uint8_t **output_pointers;
  66. };