1 /*
2 * Copyright 2003-2021 The Music Player Daemon Project
3 * http://www.musicpd.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "config.h"
21 #include "Control.hxx"
22 #include "Bridge.hxx"
23 #include "DecoderPlugin.hxx"
24 #include "song/DetachedSong.hxx"
25 #include "MusicPipe.hxx"
26 #include "fs/Traits.hxx"
27 #include "fs/AllocatedPath.hxx"
28 #include "DecoderAPI.hxx"
29 #include "input/InputStream.hxx"
30 #include "input/Registry.hxx"
31 #include "DecoderList.hxx"
32 #include "system/Error.hxx"
33 #include "util/MimeType.hxx"
34 #include "util/UriExtract.hxx"
35 #include "util/UriUtil.hxx"
36 #include "util/RuntimeError.hxx"
37 #include "util/Domain.hxx"
38 #include "util/ScopeExit.hxx"
39 #include "thread/Name.hxx"
40 #include "tag/ApeReplayGain.hxx"
41 #include "Log.hxx"
42
43 #include <stdexcept>
44 #include <functional>
45 #include <memory>
46
47 static constexpr Domain decoder_thread_domain("decoder_thread");
48
49 /**
50 * Decode a URI with the given decoder plugin.
51 *
52 * Caller holds DecoderControl::mutex.
53 */
54 static bool
DecoderUriDecode(const DecoderPlugin & plugin,DecoderBridge & bridge,const char * uri)55 DecoderUriDecode(const DecoderPlugin &plugin,
56 DecoderBridge &bridge, const char *uri)
57 {
58 assert(plugin.uri_decode != nullptr);
59 assert(bridge.stream_tag == nullptr);
60 assert(bridge.decoder_tag == nullptr);
61 assert(uri != nullptr);
62 assert(bridge.dc.state == DecoderState::START);
63
64 FmtDebug(decoder_thread_domain, "probing plugin {}", plugin.name);
65
66 if (bridge.dc.command == DecoderCommand::STOP)
67 throw StopDecoder();
68
69 {
70 const ScopeUnlock unlock(bridge.dc.mutex);
71
72 FormatThreadName("decoder:%s", plugin.name);
73
74 plugin.UriDecode(bridge, uri);
75
76 SetThreadName("decoder");
77 }
78
79 assert(bridge.dc.state == DecoderState::START ||
80 bridge.dc.state == DecoderState::DECODE);
81
82 return bridge.dc.state != DecoderState::START;
83 }
84
85 /**
86 * Decode a stream with the given decoder plugin.
87 *
88 * Caller holds DecoderControl::mutex.
89 */
90 static bool
decoder_stream_decode(const DecoderPlugin & plugin,DecoderBridge & bridge,InputStream & input_stream,std::unique_lock<Mutex> & lock)91 decoder_stream_decode(const DecoderPlugin &plugin,
92 DecoderBridge &bridge,
93 InputStream &input_stream,
94 std::unique_lock<Mutex> &lock)
95 {
96 assert(plugin.stream_decode != nullptr);
97 assert(bridge.stream_tag == nullptr);
98 assert(bridge.decoder_tag == nullptr);
99 assert(input_stream.IsReady());
100 assert(bridge.dc.state == DecoderState::START);
101
102 FmtDebug(decoder_thread_domain, "probing plugin {}", plugin.name);
103
104 if (bridge.dc.command == DecoderCommand::STOP)
105 throw StopDecoder();
106
107 /* rewind the stream, so each plugin gets a fresh start */
108 try {
109 input_stream.Rewind(lock);
110 } catch (...) {
111 }
112
113 {
114 const ScopeUnlock unlock(bridge.dc.mutex);
115
116 FormatThreadName("decoder:%s", plugin.name);
117
118 plugin.StreamDecode(bridge, input_stream);
119
120 SetThreadName("decoder");
121 }
122
123 assert(bridge.dc.state == DecoderState::START ||
124 bridge.dc.state == DecoderState::DECODE);
125
126 return bridge.dc.state != DecoderState::START;
127 }
128
129 /**
130 * Decode a file with the given decoder plugin.
131 *
132 * Caller holds DecoderControl::mutex.
133 */
134 static bool
decoder_file_decode(const DecoderPlugin & plugin,DecoderBridge & bridge,Path path)135 decoder_file_decode(const DecoderPlugin &plugin,
136 DecoderBridge &bridge, Path path)
137 {
138 assert(plugin.file_decode != nullptr);
139 assert(bridge.stream_tag == nullptr);
140 assert(bridge.decoder_tag == nullptr);
141 assert(!path.IsNull());
142 assert(path.IsAbsolute());
143 assert(bridge.dc.state == DecoderState::START);
144
145 FmtDebug(decoder_thread_domain, "probing plugin {}", plugin.name);
146
147 if (bridge.dc.command == DecoderCommand::STOP)
148 throw StopDecoder();
149
150 {
151 const ScopeUnlock unlock(bridge.dc.mutex);
152
153 FormatThreadName("decoder:%s", plugin.name);
154
155 plugin.FileDecode(bridge, path);
156
157 SetThreadName("decoder");
158 }
159
160 assert(bridge.dc.state == DecoderState::START ||
161 bridge.dc.state == DecoderState::DECODE);
162
163 return bridge.dc.state != DecoderState::START;
164 }
165
166 gcc_pure
167 static bool
decoder_check_plugin_mime(const DecoderPlugin & plugin,const InputStream & is)168 decoder_check_plugin_mime(const DecoderPlugin &plugin,
169 const InputStream &is) noexcept
170 {
171 assert(plugin.stream_decode != nullptr);
172
173 const char *mime_type = is.GetMimeType();
174 return mime_type != nullptr &&
175 plugin.SupportsMimeType(GetMimeTypeBase(mime_type));
176 }
177
178 gcc_pure
179 static bool
decoder_check_plugin_suffix(const DecoderPlugin & plugin,std::string_view suffix)180 decoder_check_plugin_suffix(const DecoderPlugin &plugin,
181 std::string_view suffix) noexcept
182 {
183 assert(plugin.stream_decode != nullptr);
184
185 return !suffix.empty() && plugin.SupportsSuffix(suffix);
186 }
187
188 gcc_pure
189 static bool
decoder_check_plugin(const DecoderPlugin & plugin,const InputStream & is,std::string_view suffix)190 decoder_check_plugin(const DecoderPlugin &plugin, const InputStream &is,
191 std::string_view suffix) noexcept
192 {
193 return plugin.stream_decode != nullptr &&
194 (decoder_check_plugin_mime(plugin, is) ||
195 decoder_check_plugin_suffix(plugin, suffix));
196 }
197
198 static bool
decoder_run_stream_plugin(DecoderBridge & bridge,InputStream & is,std::unique_lock<Mutex> & lock,std::string_view suffix,const DecoderPlugin & plugin,bool & tried_r)199 decoder_run_stream_plugin(DecoderBridge &bridge, InputStream &is,
200 std::unique_lock<Mutex> &lock,
201 std::string_view suffix,
202 const DecoderPlugin &plugin,
203 bool &tried_r)
204 {
205 if (!decoder_check_plugin(plugin, is, suffix))
206 return false;
207
208 bridge.Reset();
209
210 tried_r = true;
211 return decoder_stream_decode(plugin, bridge, is, lock);
212 }
213
214 static bool
decoder_run_stream_locked(DecoderBridge & bridge,InputStream & is,std::unique_lock<Mutex> & lock,const char * uri,bool & tried_r)215 decoder_run_stream_locked(DecoderBridge &bridge, InputStream &is,
216 std::unique_lock<Mutex> &lock,
217 const char *uri, bool &tried_r)
218 {
219 const auto suffix = uri_get_suffix(uri);
220
221 const auto f = [&,suffix](const auto &plugin)
222 { return decoder_run_stream_plugin(bridge, is, lock, suffix, plugin, tried_r); };
223
224 return decoder_plugins_try(f);
225 }
226
227 /**
228 * Try decoding a stream, using the fallback plugin.
229 */
230 static bool
decoder_run_stream_fallback(DecoderBridge & bridge,InputStream & is,std::unique_lock<Mutex> & lock)231 decoder_run_stream_fallback(DecoderBridge &bridge, InputStream &is,
232 std::unique_lock<Mutex> &lock)
233 {
234 const struct DecoderPlugin *plugin;
235
236 #ifdef ENABLE_FFMPEG
237 plugin = decoder_plugin_from_name("ffmpeg");
238 #else
239 plugin = decoder_plugin_from_name("mad");
240 #endif
241 return plugin != nullptr && plugin->stream_decode != nullptr &&
242 decoder_stream_decode(*plugin, bridge, is, lock);
243 }
244
245 /**
246 * Attempt to load replay gain data, and pass it to
247 * DecoderClient::SubmitReplayGain().
248 */
249 static void
LoadReplayGain(DecoderClient & client,InputStream & is)250 LoadReplayGain(DecoderClient &client, InputStream &is)
251 {
252 ReplayGainInfo info;
253 if (replay_gain_ape_read(is, info))
254 client.SubmitReplayGain(&info);
255 }
256
257 /**
258 * Call LoadReplayGain() unless ReplayGain is disabled. This saves
259 * the I/O overhead when the user is not interested in the feature.
260 */
261 static void
MaybeLoadReplayGain(DecoderBridge & bridge,InputStream & is)262 MaybeLoadReplayGain(DecoderBridge &bridge, InputStream &is)
263 {
264 {
265 const std::scoped_lock<Mutex> protect(bridge.dc.mutex);
266 if (bridge.dc.replay_gain_mode == ReplayGainMode::OFF)
267 /* ReplayGain is disabled */
268 return;
269 }
270
271 LoadReplayGain(bridge, is);
272 }
273
274 /**
275 * Try decoding a URI.
276 *
277 * DecoderControl::mutex is not be locked by caller.
278 */
279 static bool
TryUriDecode(DecoderBridge & bridge,const char * uri)280 TryUriDecode(DecoderBridge &bridge, const char *uri)
281 {
282 return decoder_plugins_try([&bridge, uri](const DecoderPlugin &plugin){
283 if (!plugin.SupportsUri(uri))
284 return false;
285
286 std::unique_lock<Mutex> lock(bridge.dc.mutex);
287 bridge.Reset();
288 return DecoderUriDecode(plugin, bridge, uri);
289 });
290 }
291
292 /**
293 * Try decoding a stream.
294 *
295 * DecoderControl::mutex is not locked by caller.
296 */
297 static bool
decoder_run_stream(DecoderBridge & bridge,const char * uri)298 decoder_run_stream(DecoderBridge &bridge, const char *uri)
299 {
300 if (TryUriDecode(bridge, uri))
301 return true;
302
303 DecoderControl &dc = bridge.dc;
304
305 auto input_stream = bridge.OpenUri(uri);
306 assert(input_stream);
307
308 MaybeLoadReplayGain(bridge, *input_stream);
309
310 std::unique_lock<Mutex> lock(dc.mutex);
311
312 bool tried = false;
313 return dc.command == DecoderCommand::STOP ||
314 decoder_run_stream_locked(bridge, *input_stream, lock, uri,
315 tried) ||
316 /* fallback to mp3: this is needed for bastard streams
317 that don't have a suffix or set the mimeType */
318 (!tried &&
319 decoder_run_stream_fallback(bridge, *input_stream, lock));
320 }
321
322 /**
323 * Decode a file with the given decoder plugin.
324 *
325 * DecoderControl::mutex is not locked by caller.
326 */
327 static bool
TryDecoderFile(DecoderBridge & bridge,Path path_fs,std::string_view suffix,InputStream & input_stream,const DecoderPlugin & plugin)328 TryDecoderFile(DecoderBridge &bridge, Path path_fs, std::string_view suffix,
329 InputStream &input_stream,
330 const DecoderPlugin &plugin)
331 {
332 if (!plugin.SupportsSuffix(suffix))
333 return false;
334
335 bridge.Reset();
336
337 DecoderControl &dc = bridge.dc;
338
339 if (plugin.file_decode != nullptr) {
340 const std::scoped_lock<Mutex> protect(dc.mutex);
341 return decoder_file_decode(plugin, bridge, path_fs);
342 } else if (plugin.stream_decode != nullptr) {
343 std::unique_lock<Mutex> lock(dc.mutex);
344 return decoder_stream_decode(plugin, bridge, input_stream,
345 lock);
346 } else
347 return false;
348 }
349
350 /**
351 * Decode a container file with the given decoder plugin.
352 *
353 * DecoderControl::mutex is not locked by caller.
354 */
355 static bool
TryContainerDecoder(DecoderBridge & bridge,Path path_fs,std::string_view suffix,const DecoderPlugin & plugin)356 TryContainerDecoder(DecoderBridge &bridge, Path path_fs,
357 std::string_view suffix,
358 const DecoderPlugin &plugin)
359 {
360 if (plugin.container_scan == nullptr ||
361 plugin.file_decode == nullptr ||
362 !plugin.SupportsSuffix(suffix))
363 return false;
364
365 bridge.Reset();
366
367 DecoderControl &dc = bridge.dc;
368 const std::scoped_lock<Mutex> protect(dc.mutex);
369 return decoder_file_decode(plugin, bridge, path_fs);
370 }
371
372 /**
373 * Decode a container file.
374 *
375 * DecoderControl::mutex is not locked by caller.
376 */
377 static bool
TryContainerDecoder(DecoderBridge & bridge,Path path_fs,std::string_view suffix)378 TryContainerDecoder(DecoderBridge &bridge, Path path_fs,
379 std::string_view suffix)
380 {
381 return decoder_plugins_try([&bridge, path_fs,
382 suffix](const DecoderPlugin &plugin){
383 return TryContainerDecoder(bridge,
384 path_fs,
385 suffix,
386 plugin);
387 });
388 }
389
390 /**
391 * Try decoding a file.
392 *
393 * DecoderControl::mutex is not locked by caller.
394 */
395 static bool
decoder_run_file(DecoderBridge & bridge,const char * uri_utf8,Path path_fs)396 decoder_run_file(DecoderBridge &bridge, const char *uri_utf8, Path path_fs)
397 {
398 const char *_suffix = PathTraitsUTF8::GetFilenameSuffix(uri_utf8);
399 if (_suffix == nullptr)
400 return false;
401
402 const std::string_view suffix{_suffix};
403
404 InputStreamPtr input_stream;
405
406 try {
407 input_stream = bridge.OpenLocal(path_fs, uri_utf8);
408 } catch (const std::system_error &e) {
409 if (IsPathNotFound(e) &&
410 /* ENOTDIR means this may be a path inside a
411 "container" file */
412 TryContainerDecoder(bridge, path_fs, suffix))
413 return true;
414
415 throw;
416 }
417
418 assert(input_stream);
419
420 MaybeLoadReplayGain(bridge, *input_stream);
421
422 auto &is = *input_stream;
423 return decoder_plugins_try([&bridge, path_fs, suffix,
424 &is](const DecoderPlugin &plugin){
425 return TryDecoderFile(bridge,
426 path_fs,
427 suffix,
428 is,
429 plugin);
430 });
431 }
432
433 /**
434 * Decode a song.
435 *
436 * DecoderControl::mutex is not locked.
437 */
438 static bool
DecoderUnlockedRunUri(DecoderBridge & bridge,const char * real_uri,Path path_fs)439 DecoderUnlockedRunUri(DecoderBridge &bridge,
440 const char *real_uri, Path path_fs)
441 try {
442 return !path_fs.IsNull()
443 ? decoder_run_file(bridge, real_uri, path_fs)
444 : decoder_run_stream(bridge, real_uri);
445 } catch (StopDecoder) {
446 return true;
447 } catch (...) {
448 const char *error_uri = real_uri;
449 const std::string allocated = uri_remove_auth(error_uri);
450 if (!allocated.empty())
451 error_uri = allocated.c_str();
452
453 std::throw_with_nested(FormatRuntimeError("Failed to decode %s",
454 error_uri));
455 }
456
457 /**
458 * Try to guess whether tags attached to the given song are
459 * "volatile", e.g. if they have been received by a live stream, but
460 * are only kept as a cache to be displayed by the client; they shall
461 * not be sent to the output.
462 */
463 gcc_pure
464 static bool
SongHasVolatileTags(const DetachedSong & song)465 SongHasVolatileTags(const DetachedSong &song) noexcept
466 {
467 return !song.IsFile() && !HasRemoteTagScanner(song.GetRealURI());
468 }
469
470 /**
471 * Decode a song addressed by a #DetachedSong.
472 *
473 * Caller holds DecoderControl::mutex.
474 */
475 static void
decoder_run_song(DecoderControl & dc,const DetachedSong & song,const char * uri,Path path_fs)476 decoder_run_song(DecoderControl &dc,
477 const DetachedSong &song, const char *uri, Path path_fs)
478 {
479 if (dc.command == DecoderCommand::SEEK)
480 /* if the SEEK command arrived too late, start the
481 decoder at the seek position */
482 dc.start_time = dc.seek_time;
483
484 DecoderBridge bridge(dc, dc.start_time.IsPositive(),
485 dc.initial_seek_essential,
486 /* pass the song tag only if it's
487 authoritative, i.e. if it's a local
488 file - tags on "stream" songs are just
489 remembered from the last time we
490 played it*/
491 !SongHasVolatileTags(song) ? std::make_unique<Tag>(song.GetTag()) : nullptr);
492
493 dc.state = DecoderState::START;
494 dc.CommandFinishedLocked();
495
496 bool success;
497 {
498 const ScopeUnlock unlock(dc.mutex);
499
500 AtScopeExit(&bridge) {
501 /* flush the last chunk */
502 bridge.CheckFlushChunk();
503 };
504
505 success = DecoderUnlockedRunUri(bridge, uri, path_fs);
506
507 }
508
509 bridge.CheckRethrowError();
510
511 if (success)
512 dc.state = DecoderState::STOP;
513 else {
514 const char *error_uri = song.GetURI();
515 const std::string allocated = uri_remove_auth(error_uri);
516 if (!allocated.empty())
517 error_uri = allocated.c_str();
518
519 throw FormatRuntimeError("Failed to decode %s", error_uri);
520 }
521
522 dc.client_cond.notify_one();
523 }
524
525 /**
526 *
527 * Caller holds DecoderControl::mutex.
528 */
529 static void
decoder_run(DecoderControl & dc)530 decoder_run(DecoderControl &dc) noexcept
531 try {
532 dc.ClearError();
533
534 assert(dc.song != nullptr);
535 const DetachedSong &song = *dc.song;
536
537 const char *const uri_utf8 = song.GetRealURI();
538
539 Path path_fs = nullptr;
540 AllocatedPath path_buffer = nullptr;
541 if (PathTraitsUTF8::IsAbsolute(uri_utf8)) {
542 path_buffer = AllocatedPath::FromUTF8Throw(uri_utf8);
543 path_fs = path_buffer;
544 }
545
546 decoder_run_song(dc, song, uri_utf8, path_fs);
547 } catch (...) {
548 dc.state = DecoderState::ERROR;
549 dc.command = DecoderCommand::NONE;
550 dc.error = std::current_exception();
551 dc.client_cond.notify_one();
552 }
553
554 void
RunThread()555 DecoderControl::RunThread() noexcept
556 {
557 SetThreadName("decoder");
558
559 std::unique_lock<Mutex> lock(mutex);
560
561 do {
562 assert(state == DecoderState::STOP ||
563 state == DecoderState::ERROR);
564
565 switch (command) {
566 case DecoderCommand::START:
567 CycleMixRamp();
568 replay_gain_prev_db = replay_gain_db;
569 replay_gain_db = 0;
570
571 decoder_run(*this);
572
573 if (state == DecoderState::ERROR) {
574 try {
575 std::rethrow_exception(error);
576 } catch (...) {
577 LogError(std::current_exception());
578 }
579 }
580
581 break;
582
583 case DecoderCommand::SEEK:
584 /* this seek was too late, and the decoder had
585 already finished; start a new decoder */
586
587 /* we need to clear the pipe here; usually the
588 PlayerThread is responsible, but it is not
589 aware that the decoder has finished */
590 pipe->Clear();
591
592 decoder_run(*this);
593 break;
594
595 case DecoderCommand::STOP:
596 CommandFinishedLocked();
597 break;
598
599 case DecoderCommand::NONE:
600 Wait(lock);
601 break;
602 }
603 } while (command != DecoderCommand::NONE || !quit);
604 }
605