Merge tag 'v0.23.6'

release v0.23.6
This commit is contained in:
Max Kellermann
2022-03-14 18:58:47 +01:00
11 changed files with 114 additions and 49 deletions

View File

@@ -21,12 +21,16 @@
#include "TagStream.hxx"
#include "TagFile.hxx"
#include "tag/Generic.hxx"
#include "song/LightSong.hxx"
#include "db/Interface.hxx"
#include "storage/StorageInterface.hxx"
#include "client/Client.hxx"
#include "protocol/Ack.hxx"
#include "fs/AllocatedPath.hxx"
#include "input/InputStream.hxx"
#include "util/Compiler.h"
#include "util/ScopeExit.hxx"
#include "util/StringCompare.hxx"
#include "util/UriExtract.hxx"
#include "LocateUri.hxx"
@@ -51,10 +55,67 @@ TagScanFile(const Path path_fs, TagHandler &handler)
ScanGenericTags(path_fs, handler);
}
#ifdef ENABLE_DATABASE
/**
* Collapse "../" prefixes in a URI relative to the specified base
* URI.
*/
static std::string
ResolveUri(std::string_view base, const char *relative)
{
while (true) {
const char *rest = StringAfterPrefix(relative, "../");
if (rest == nullptr)
break;
if (base == ".")
throw ProtocolError(ACK_ERROR_NO_EXIST, "Bad real URI");
base = PathTraitsUTF8::GetParent(base);
relative = rest;
}
return PathTraitsUTF8::Build(base, relative);
}
/**
* Look up the specified song in the database and return its
* (resolved) "real" URI.
*/
static std::string
GetRealSongUri(Client &client, std::string_view uri)
{
const auto &db = client.GetDatabaseOrThrow();
const auto *song = db.GetSong(uri);
if (song == nullptr)
throw ProtocolError(ACK_ERROR_NO_EXIST, "No such song");
AtScopeExit(&db, song) { db.ReturnSong(song); };
if (song->real_uri == nullptr)
return {};
return ResolveUri(PathTraitsUTF8::GetParent(uri), song->real_uri);
}
#endif
static void
TagScanDatabase(Client &client, const char *uri, TagHandler &handler)
{
#ifdef ENABLE_DATABASE
const auto real_uri = GetRealSongUri(client, uri);
if (!real_uri.empty()) {
uri = real_uri.c_str();
// TODO: support absolute paths?
if (uri_has_scheme(uri))
return TagScanStream(uri, handler);
}
const Storage *storage = client.GetStorage();
if (storage == nullptr) {
#else

View File

@@ -160,8 +160,7 @@ find_stream_art(std::string_view directory, Mutex &mutex)
static constexpr auto art_names = std::array {
"cover.png",
"cover.jpg",
"cover.tiff",
"cover.bmp",
"cover.webp",
};
for(const auto name : art_names) {

View File

@@ -21,6 +21,7 @@
#define __STDC_CONSTANT_MACROS
#include "FfmpegIo.hxx"
#include "libavutil/mem.h"
#include "../DecoderAPI.hxx"
#include "input/InputStream.hxx"
@@ -35,7 +36,11 @@ AvioStream::~AvioStream()
inline int
AvioStream::Read(void *dest, int size)
{
return decoder_read(client, input, dest, size);
const auto nbytes = decoder_read(client, input, dest, size);
if (nbytes == 0)
return AVERROR_EOF;
return nbytes;
}
inline int64_t

View File

@@ -1,14 +0,0 @@
Index: libnfs-libnfs-4.0.0/include/win32/win32_compat.h
===================================================================
--- libnfs-libnfs-4.0.0.orig/include/win32/win32_compat.h
+++ libnfs-libnfs-4.0.0/include/win32/win32_compat.h
@@ -133,7 +133,9 @@ struct pollfd {
/* Wrapper macros to call misc. functions win32 is missing */
#define poll(x, y, z) win32_poll(x, y, z)
+#ifndef __MINGW32__
#define snprintf sprintf_s
+#endif
#define inet_pton(x,y,z) win32_inet_pton(x,y,z)
#define open(x, y, z) _open(x, y, z)
#ifndef lseek

View File

@@ -1 +0,0 @@
no_sprintf_s

View File

@@ -1,4 +1,11 @@
libflac_dep = dependency('flac', version: '>= 1.2', required: get_option('flac'))
if is_windows
# Our Windows build generates a static libFLAC build
libflac_dep = declare_dependency(compile_args: '-DFLAC__NO_DLL',
dependencies: libflac_dep)
endif
libopus_dep = dependency('opus', required: get_option('opus'))
if get_option('tremor').enabled()

View File

@@ -336,6 +336,8 @@ PipeWireOutput::Enable()
throw MakeErrno("pw_thread_loop_new() failed");
pw_thread_loop_start(thread_loop);
stream = nullptr;
}
void

View File

@@ -471,6 +471,16 @@ try {
}
UINT32 write_in_frames = buffer_size_in_frames;
DWORD mode = 0;
AtScopeExit(&) {
render_client->ReleaseBuffer(write_in_frames, mode);
if (!started) {
Start(client);
started = true;
}
};
if (!is_exclusive) {
UINT32 data_in_frames =
GetCurrentPaddingFrames(client);
@@ -481,7 +491,6 @@ try {
}
BYTE *data;
DWORD mode = 0;
if (HRESULT result =
render_client->GetBuffer(write_in_frames, &data);
@@ -489,15 +498,6 @@ try {
throw MakeHResultError(result, "Failed to get buffer");
}
AtScopeExit(&) {
render_client->ReleaseBuffer(write_in_frames, mode);
if (!started) {
Start(client);
started = true;
}
};
const UINT32 write_size = write_in_frames * frame_size;
UINT32 new_data_size = 0;
new_data_size = spsc_buffer.pop(data, write_size);