Merge tag 'v0.21.24'
release v0.21.24
This commit is contained in:
@@ -38,15 +38,19 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
DecoderBridge::DecoderBridge(DecoderControl &_dc, bool _initial_seek_pending,
|
||||
bool _initial_seek_essential,
|
||||
std::unique_ptr<Tag> _tag) noexcept
|
||||
:dc(_dc),
|
||||
initial_seek_pending(_initial_seek_pending),
|
||||
initial_seek_essential(_initial_seek_essential),
|
||||
song_tag(std::move(_tag)) {}
|
||||
|
||||
|
||||
DecoderBridge::~DecoderBridge() noexcept
|
||||
{
|
||||
/* caller must flush the chunk */
|
||||
@@ -364,6 +368,10 @@ DecoderBridge::SeekError() noexcept
|
||||
/* d'oh, we can't seek to the sub-song start position,
|
||||
what now? - no idea, ignoring the problem for now. */
|
||||
initial_seek_running = false;
|
||||
|
||||
if (initial_seek_essential)
|
||||
error = std::make_exception_ptr(std::runtime_error("Decoder failed to seek"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -64,6 +64,11 @@ private:
|
||||
*/
|
||||
bool initial_seek_pending;
|
||||
|
||||
/**
|
||||
* Are initial seek failures fatal?
|
||||
*/
|
||||
const bool initial_seek_essential;
|
||||
|
||||
/**
|
||||
* Is the initial seek currently running? During this time,
|
||||
* the decoder command is SEEK. This flag is set by
|
||||
@@ -112,6 +117,7 @@ private:
|
||||
|
||||
public:
|
||||
DecoderBridge(DecoderControl &_dc, bool _initial_seek_pending,
|
||||
bool _initial_seek_essential,
|
||||
std::unique_ptr<Tag> _tag) noexcept;
|
||||
|
||||
~DecoderBridge() noexcept;
|
||||
|
@@ -80,6 +80,7 @@ void
|
||||
DecoderControl::Start(std::unique_lock<Mutex> &lock,
|
||||
std::unique_ptr<DetachedSong> _song,
|
||||
SongTime _start_time, SongTime _end_time,
|
||||
bool _initial_seek_essential,
|
||||
MusicBuffer &_buffer,
|
||||
std::shared_ptr<MusicPipe> _pipe) noexcept
|
||||
{
|
||||
@@ -89,6 +90,7 @@ DecoderControl::Start(std::unique_lock<Mutex> &lock,
|
||||
song = std::move(_song);
|
||||
start_time = _start_time;
|
||||
end_time = _end_time;
|
||||
initial_seek_essential = _initial_seek_essential;
|
||||
buffer = &_buffer;
|
||||
pipe = std::move(_pipe);
|
||||
|
||||
|
@@ -112,6 +112,12 @@ private:
|
||||
public:
|
||||
bool seek_error;
|
||||
bool seekable;
|
||||
|
||||
/**
|
||||
* @see #DecoderBridge::initial_seek_essential
|
||||
*/
|
||||
bool initial_seek_essential;
|
||||
|
||||
SongTime seek_time;
|
||||
|
||||
private:
|
||||
@@ -383,12 +389,15 @@ public:
|
||||
* owned and freed by the decoder
|
||||
* @param start_time see #DecoderControl
|
||||
* @param end_time see #DecoderControl
|
||||
* @param initial_seek_essential see
|
||||
* #DecoderBridge::initial_seek_essential
|
||||
* @param pipe the pipe which receives the decoded chunks (owned by
|
||||
* the caller)
|
||||
*/
|
||||
void Start(std::unique_lock<Mutex> &lock,
|
||||
std::unique_ptr<DetachedSong> song,
|
||||
SongTime start_time, SongTime end_time,
|
||||
bool initial_seek_essential,
|
||||
MusicBuffer &buffer,
|
||||
std::shared_ptr<MusicPipe> pipe) noexcept;
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "util/Compiler.h"
|
||||
|
||||
#include <forward_list>
|
||||
#include <forward_list> // IWYU pragma: export
|
||||
|
||||
struct ConfigBlock;
|
||||
class InputStream;
|
||||
|
@@ -422,6 +422,7 @@ decoder_run_song(DecoderControl &dc,
|
||||
dc.start_time = dc.seek_time;
|
||||
|
||||
DecoderBridge bridge(dc, dc.start_time.IsPositive(),
|
||||
dc.initial_seek_essential,
|
||||
/* pass the song tag only if it's
|
||||
authoritative, i.e. if it's a local
|
||||
file - tags on "stream" songs are just
|
||||
|
@@ -27,11 +27,11 @@
|
||||
#include "fs/Path.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
#include "fs/NarrowPath.hxx"
|
||||
#include "util/ScopeExit.hxx"
|
||||
#include "util/StringCompare.hxx"
|
||||
#include "util/StringFormat.hxx"
|
||||
#include "util/StringView.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <cassert>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SUBTUNE_PREFIX "tune_"
|
||||
|
||||
@@ -83,11 +82,10 @@ gcc_pure
|
||||
static unsigned
|
||||
ParseSubtuneName(const char *base) noexcept
|
||||
{
|
||||
if (memcmp(base, SUBTUNE_PREFIX, sizeof(SUBTUNE_PREFIX) - 1) != 0)
|
||||
base = StringAfterPrefix(base, SUBTUNE_PREFIX);
|
||||
if (base == nullptr)
|
||||
return 0;
|
||||
|
||||
base += sizeof(SUBTUNE_PREFIX) - 1;
|
||||
|
||||
char *endptr;
|
||||
auto track = strtoul(base, &endptr, 10);
|
||||
if (endptr == base || *endptr != '.')
|
||||
@@ -106,41 +104,46 @@ ParseContainerPath(Path path_fs)
|
||||
const Path base = path_fs.GetBase();
|
||||
unsigned track;
|
||||
if (base.IsNull() ||
|
||||
(track = ParseSubtuneName(base.c_str())) < 1)
|
||||
(track = ParseSubtuneName(NarrowPath(base))) < 1)
|
||||
return { AllocatedPath(path_fs), 0 };
|
||||
|
||||
return { path_fs.GetDirectoryName(), track - 1 };
|
||||
}
|
||||
|
||||
static AllocatedPath
|
||||
ReplaceSuffix(Path src,
|
||||
const PathTraitsFS::const_pointer new_suffix) noexcept
|
||||
{
|
||||
const auto *old_suffix = src.GetSuffix();
|
||||
if (old_suffix == nullptr)
|
||||
return nullptr;
|
||||
|
||||
PathTraitsFS::string s(src.c_str(), old_suffix);
|
||||
s += new_suffix;
|
||||
return AllocatedPath::FromFS(std::move(s));
|
||||
}
|
||||
|
||||
static Music_Emu*
|
||||
LoadGmeAndM3u(const GmeContainerPath& container) {
|
||||
|
||||
const char *path = container.path.c_str();
|
||||
const char *suffix = uri_get_suffix(path);
|
||||
|
||||
Music_Emu *emu;
|
||||
const char *gme_err =
|
||||
gme_open_file(path, &emu, GME_SAMPLE_RATE);
|
||||
gme_open_file(NarrowPath(container.path), &emu, GME_SAMPLE_RATE);
|
||||
if (gme_err != nullptr) {
|
||||
LogWarning(gme_domain, gme_err);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(suffix == nullptr) {
|
||||
return emu;
|
||||
}
|
||||
|
||||
std::string m3u_path(path,suffix);
|
||||
m3u_path += "m3u";
|
||||
|
||||
const auto m3u_path = ReplaceSuffix(container.path,
|
||||
PATH_LITERAL("m3u"));
|
||||
/*
|
||||
* Some GME formats lose metadata if you attempt to
|
||||
* load a non-existant M3U file, so check that one
|
||||
* exists before loading.
|
||||
*/
|
||||
if(FileExists(Path::FromFS(m3u_path.c_str()))) {
|
||||
gme_load_m3u(emu,m3u_path.c_str());
|
||||
}
|
||||
if (!m3u_path.IsNull() && FileExists(m3u_path))
|
||||
gme_load_m3u(emu, NarrowPath(m3u_path));
|
||||
|
||||
return emu;
|
||||
}
|
||||
|
||||
@@ -320,7 +323,7 @@ gme_container_scan(Path path_fs)
|
||||
if (num_songs < 2)
|
||||
return list;
|
||||
|
||||
const char *subtune_suffix = uri_get_suffix(path_fs.c_str());
|
||||
const auto *subtune_suffix = path_fs.GetSuffix();
|
||||
|
||||
TagBuilder tag_builder;
|
||||
|
||||
|
Reference in New Issue
Block a user