CAudioStream.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #pragma once
  2. #include <string>
  3. extern "C"
  4. {
  5. #include <libavutil/fifo.h>
  6. #include <libavcodec/avcodec.h>
  7. #include <libavformat/avformat.h>
  8. #include <libswscale/swscale.h>
  9. #include <libswresample/swresample.h>
  10. #include <libavutil/opt.h>
  11. }
  12. #include <SDL.h>
  13. #include <SDL_thread.h>
  14. #include "WallpaperEngine/Audio/CAudioContext.h"
  15. namespace WallpaperEngine::Audio
  16. {
  17. class CAudioContext;
  18. /**
  19. * Represents a playable audio stream for the audio driver
  20. */
  21. class CAudioStream
  22. {
  23. public:
  24. CAudioStream (CAudioContext& context, const std::string& filename);
  25. CAudioStream (CAudioContext& context, const void* buffer, int length);
  26. CAudioStream (CAudioContext& audioContext, AVCodecContext* context);
  27. ~CAudioStream ();
  28. void queuePacket (AVPacket* pkt);
  29. /**
  30. * Gets the next packet in the queue
  31. *
  32. * WARNING: BLOCKS UNTIL SOME DATA IS READ FROM IT
  33. *
  34. * @return
  35. */
  36. void dequeuePacket (AVPacket* output);
  37. /**
  38. * @return The audio context in use for this audio stream
  39. */
  40. [[nodiscard]] CAudioContext& getAudioContext () const;
  41. /**
  42. * @return to the codec context, which provides information on the audio stream's format
  43. */
  44. AVCodecContext* getContext ();
  45. /**
  46. * @returns the format context, which controls how data is read off the audio stream
  47. */
  48. AVFormatContext* getFormatContext ();
  49. /**
  50. * @return The audio stream index of the given file
  51. */
  52. int getAudioStream ();
  53. /**
  54. * @return If the audio stream can be played or not
  55. */
  56. bool isInitialized ();
  57. /**
  58. * @param newRepeat true = repeat, false = no repeat
  59. */
  60. void setRepeat (bool newRepeat = true);
  61. /**
  62. * @return If the stream is to be repeated at the end or not
  63. */
  64. bool isRepeat ();
  65. /**
  66. * Stops decoding and playbak of the stream
  67. */
  68. void stop ();
  69. /**
  70. * @return The file data buffer
  71. */
  72. const void* getBuffer ();
  73. /**
  74. * @return The length of the file data buffer
  75. */
  76. int getLength ();
  77. /**
  78. * @return The read position of the data buffer
  79. */
  80. int getPosition ();
  81. /**
  82. * Updates the read position of the data buffer
  83. *
  84. * @param current
  85. */
  86. void setPosition (int current);
  87. /**
  88. * @return The SDL_cond used to signal waiting for data
  89. */
  90. SDL_cond* getWaitCondition ();
  91. /**
  92. * @return The data queue size
  93. */
  94. int getQueueSize ();
  95. /**
  96. * @return The amount of packets ready to be converted and played
  97. */
  98. int getQueuePacketCount ();
  99. /**
  100. * @return The duration (in seconds) of the queued data to be played
  101. */
  102. int64_t getQueueDuration ();
  103. /**
  104. * @return Time unit used for packet playback
  105. */
  106. AVRational getTimeBase ();
  107. /**
  108. * @return If the data queue is empty or not
  109. */
  110. bool isQueueEmpty ();
  111. /**
  112. * @return The SDL_mutex used for thread synchronization
  113. */
  114. SDL_mutex* getMutex ();
  115. /**
  116. * Reads a frame from the audio stream, resamples it to the driver's settings
  117. * and returns the data ready to be played
  118. *
  119. * @param audioBuffer
  120. * @param bufferSize
  121. *
  122. * @return The amount of bytes available or < 0 for error
  123. */
  124. int decodeFrame (uint8_t* audioBuffer, int bufferSize);
  125. private:
  126. /**
  127. * Initializes ffmpeg to read the given file
  128. *
  129. * @param filename
  130. */
  131. void loadCustomContent (const char* filename = nullptr);
  132. /**
  133. * Converts the audio frame from the original format to one supported by the audio driver
  134. *
  135. * @param decoded_audio_frame
  136. * @param out_buf
  137. * @return
  138. */
  139. int resampleAudio (AVFrame* decoded_audio_frame, uint8_t* out_buf);
  140. /**
  141. * Queues a packet into the play queue
  142. *
  143. * @param pkt
  144. * @return
  145. */
  146. bool doQueue (AVPacket* pkt);
  147. /**
  148. * Initializes queues and ffmpeg resampling
  149. */
  150. void initialize ();
  151. #if FF_API_OLD_CHANNEL_LAYOUT
  152. /** Chanel layout needed for old FFMPEG versions */
  153. AVChannelLayout m_out_channel_layout;
  154. #endif
  155. /** The SwrContext that handles resampling */
  156. SwrContext* m_swrctx;
  157. /** The audio context this stream will be played under */
  158. CAudioContext& m_audioContext;
  159. /** If this stream was properly initialized or not */
  160. bool m_initialized;
  161. /** Repeat enabled? */
  162. bool m_repeat;
  163. /** The codec context that contains the original audio format information */
  164. AVCodecContext* m_context = nullptr;
  165. /** The format context that controls how data is read off the file */
  166. AVFormatContext* m_formatContext = nullptr;
  167. /** The stream index for the audio being played */
  168. int m_audioStream = -1;
  169. /** File data pointer */
  170. const void* m_buffer;
  171. /** The length of the file data pointer */
  172. int m_length;
  173. /** The read position on the file data pointer */
  174. int m_position = 0;
  175. struct MyAVPacketList
  176. {
  177. AVPacket* packet;
  178. };
  179. /**
  180. * Packet queue information
  181. */
  182. struct PacketQueue
  183. {
  184. #if FF_API_FIFO_OLD_API
  185. AVFifo* packetList;
  186. #else
  187. AVFifoBuffer* packetList;
  188. #endif
  189. int nb_packets;
  190. int size;
  191. int64_t duration;
  192. SDL_mutex* mutex;
  193. SDL_cond* wait;
  194. SDL_cond* cond;
  195. }* m_queue;
  196. };
  197. }