2
0

decode.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. * Squeezelite - lightweight headless squeezebox emulator
  3. *
  4. * (c) Adrian Smith 2012-2015, triode1@btinternet.com
  5. * Ralph Irving 2015-2017, ralph_irving@hotmail.com
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. */
  21. // decode thread
  22. #include "squeezelite.h"
  23. log_level loglevel;
  24. extern struct buffer *streambuf;
  25. extern struct buffer *outputbuf;
  26. extern struct streamstate stream;
  27. extern struct outputstate output;
  28. extern struct processstate process;
  29. struct decodestate decode;
  30. struct codec *codecs[MAX_CODECS];
  31. struct codec *codec;
  32. static bool running = true;
  33. #define LOCK_S mutex_lock(streambuf->mutex)
  34. #define UNLOCK_S mutex_unlock(streambuf->mutex)
  35. #define LOCK_O mutex_lock(outputbuf->mutex)
  36. #define UNLOCK_O mutex_unlock(outputbuf->mutex)
  37. #define LOCK_D mutex_lock(decode.mutex);
  38. #define UNLOCK_D mutex_unlock(decode.mutex);
  39. #if PROCESS
  40. #define IF_DIRECT(x) if (decode.direct) { x }
  41. #define IF_PROCESS(x) if (!decode.direct) { x }
  42. #define MAY_PROCESS(x) { x }
  43. #else
  44. #define IF_DIRECT(x) { x }
  45. #define IF_PROCESS(x)
  46. #define MAY_PROCESS(x)
  47. #endif
  48. static void *decode_thread() {
  49. while (running) {
  50. size_t bytes, space, min_space;
  51. bool toend;
  52. bool ran = false;
  53. LOCK_S;
  54. bytes = _buf_used(streambuf);
  55. toend = (stream.state <= DISCONNECT);
  56. UNLOCK_S;
  57. LOCK_O;
  58. space = _buf_space(outputbuf);
  59. UNLOCK_O;
  60. LOCK_D;
  61. if (decode.state == DECODE_RUNNING && codec) {
  62. LOG_SDEBUG("streambuf bytes: %u outputbuf space: %u", bytes, space);
  63. IF_DIRECT(
  64. min_space = codec->min_space;
  65. );
  66. IF_PROCESS(
  67. min_space = process.max_out_frames * BYTES_PER_FRAME;
  68. );
  69. if (space > min_space && (bytes > codec->min_read_bytes || toend)) {
  70. decode.state = codec->decode();
  71. IF_PROCESS(
  72. if (process.in_frames) {
  73. process_samples();
  74. }
  75. if (decode.state == DECODE_COMPLETE) {
  76. process_drain();
  77. }
  78. );
  79. if (decode.state != DECODE_RUNNING) {
  80. LOG_INFO("decode %s", decode.state == DECODE_COMPLETE ? "complete" : "error");
  81. LOCK_O;
  82. if (output.fade_mode) _checkfade(false);
  83. UNLOCK_O;
  84. wake_controller();
  85. }
  86. ran = true;
  87. }
  88. }
  89. UNLOCK_D;
  90. if (!ran) {
  91. usleep(100000);
  92. }
  93. }
  94. return 0;
  95. }
  96. static void sort_codecs(int pry, struct codec* ptr) {
  97. static int priority[MAX_CODECS];
  98. int i, tpry;
  99. struct codec* tptr;
  100. for (i = 0; i < MAX_CODECS; i++) {
  101. if (!codecs[i]) {
  102. codecs[i] = ptr;
  103. priority[i] = pry;
  104. return;
  105. }
  106. if (pry < priority[i]) {
  107. tptr = codecs[i];
  108. codecs[i] = ptr;
  109. ptr = tptr;
  110. tpry = priority[i];
  111. priority[i] = pry;
  112. pry = tpry;
  113. }
  114. }
  115. }
  116. static thread_type thread;
  117. void decode_init(log_level level, const char *include_codecs, const char *exclude_codecs) {
  118. int i;
  119. char* order_codecs = NULL;
  120. loglevel = level;
  121. LOG_INFO("init decode");
  122. // register codecs
  123. // dsf,dff,alc,wma,wmap,wmal,aac,spt,ogg,ogf,flc,aif,pcm,mp3
  124. i = 0;
  125. #if DSD
  126. if (!strstr(exclude_codecs, "dsd") && (!include_codecs || (order_codecs = strstr(include_codecs, "dsd"))))
  127. sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_dsd());
  128. #endif
  129. #if FFMPEG
  130. if (!strstr(exclude_codecs, "alac") && (!include_codecs || (order_codecs = strstr(include_codecs, "alac"))))
  131. sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_ff("alc"));
  132. if (!strstr(exclude_codecs, "wma") && (!include_codecs || (order_codecs = strstr(include_codecs, "wma"))))
  133. sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_ff("wma"));
  134. #else
  135. if (!strstr(exclude_codecs, "alac") && (!include_codecs || (order_codecs = strstr(include_codecs, "alac"))))
  136. sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_alac());
  137. #endif
  138. #ifndef NO_FAAD
  139. if (!strstr(exclude_codecs, "aac") && (!include_codecs || (order_codecs = strstr(include_codecs, "aac"))))
  140. sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_faad());
  141. #endif
  142. if (!strstr(exclude_codecs, "ogg") && (!include_codecs || (order_codecs = strstr(include_codecs, "ogg"))))
  143. sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_vorbis());
  144. if (!strstr(exclude_codecs, "flac") && (!include_codecs || (order_codecs = strstr(include_codecs, "flac"))))
  145. sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_flac());
  146. if (!strstr(exclude_codecs, "pcm") && (!include_codecs || (order_codecs = strstr(include_codecs, "pcm"))))
  147. sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_pcm());
  148. // try mad then mpg for mp3 unless command line option passed
  149. if (!(strstr(exclude_codecs, "mp3") || strstr(exclude_codecs, "mad")) &&
  150. (!include_codecs || (order_codecs = strstr(include_codecs, "mp3")) || (order_codecs = strstr(include_codecs, "mad"))))
  151. sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_mad());
  152. else if (!(strstr(exclude_codecs, "mp3") || strstr(exclude_codecs, "mpg")) &&
  153. (!include_codecs || (order_codecs = strstr(include_codecs, "mp3")) || (order_codecs = strstr(include_codecs, "mpg"))))
  154. sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_mpg());
  155. LOG_DEBUG("include codecs: %s exclude codecs: %s", include_codecs ? include_codecs : "", exclude_codecs);
  156. mutex_create(decode.mutex);
  157. #if LINUX || OSX || FREEBSD || POSIX
  158. pthread_attr_t attr;
  159. pthread_attr_init(&attr);
  160. #ifdef PTHREAD_STACK_MIN
  161. pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + DECODE_THREAD_STACK_SIZE);
  162. #endif
  163. pthread_create(&thread, &attr, decode_thread, NULL);
  164. pthread_attr_destroy(&attr);
  165. #endif
  166. #if WIN
  167. thread = CreateThread(NULL, DECODE_THREAD_STACK_SIZE, (LPTHREAD_START_ROUTINE)&decode_thread, NULL, 0, NULL);
  168. #endif
  169. decode.new_stream = true;
  170. decode.state = DECODE_STOPPED;
  171. MAY_PROCESS(
  172. decode.direct = true;
  173. decode.process = false;
  174. );
  175. }
  176. void decode_close(void) {
  177. LOG_INFO("close decode");
  178. LOCK_D;
  179. if (codec) {
  180. codec->close();
  181. codec = NULL;
  182. }
  183. running = false;
  184. UNLOCK_D;
  185. #if LINUX || OSX || FREEBSD
  186. pthread_join(thread, NULL);
  187. #endif
  188. mutex_destroy(decode.mutex);
  189. }
  190. void decode_flush(void) {
  191. LOG_INFO("decode flush");
  192. LOCK_D;
  193. decode.state = DECODE_STOPPED;
  194. IF_PROCESS(
  195. process_flush();
  196. );
  197. UNLOCK_D;
  198. }
  199. unsigned decode_newstream(unsigned sample_rate, unsigned supported_rates[]) {
  200. // called with O locked to get sample rate for potentially processed output stream
  201. // release O mutex during process_newstream as it can take some time
  202. MAY_PROCESS(
  203. if (decode.process) {
  204. UNLOCK_O;
  205. sample_rate = process_newstream(&decode.direct, sample_rate, supported_rates);
  206. LOCK_O;
  207. }
  208. );
  209. return sample_rate;
  210. }
  211. void codec_open(u8_t format, u8_t sample_size, u8_t sample_rate, u8_t channels, u8_t endianness) {
  212. int i;
  213. LOG_INFO("codec open: '%c'", format);
  214. LOCK_D;
  215. decode.new_stream = true;
  216. decode.state = DECODE_STOPPED;
  217. MAY_PROCESS(
  218. decode.direct = true; // potentially changed within codec when processing enabled
  219. );
  220. // find the required codec
  221. for (i = 0; i < MAX_CODECS; ++i) {
  222. if (codecs[i] && codecs[i]->id == format) {
  223. if (codec && codec != codecs[i]) {
  224. LOG_INFO("closing codec: '%c'", codec->id);
  225. codec->close();
  226. }
  227. codec = codecs[i];
  228. codec->open(sample_size, sample_rate, channels, endianness);
  229. decode.state = DECODE_READY;
  230. UNLOCK_D;
  231. return;
  232. }
  233. }
  234. UNLOCK_D;
  235. LOG_ERROR("codec not found");
  236. }