Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
c6a7f6da
Commit
c6a7f6da
authored
Jun 10, 2020
by
Max Kellermann
Browse files
Options
Browse Files
Download
Plain Diff
Merge tag 'v0.21.24'
release v0.21.24
parents
96a273bf
24741c5d
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
88 additions
and
36 deletions
+88
-36
NEWS
NEWS
+6
-3
build.py
android/build.py
+1
-0
protocol.rst
doc/protocol.rst
+2
-1
libs.py
python/build/libs.py
+12
-0
Bridge.cxx
src/decoder/Bridge.cxx
+8
-0
Bridge.hxx
src/decoder/Bridge.hxx
+6
-0
Control.cxx
src/decoder/Control.cxx
+2
-0
Control.hxx
src/decoder/Control.hxx
+9
-0
DecoderPlugin.hxx
src/decoder/DecoderPlugin.hxx
+1
-1
Thread.cxx
src/decoder/Thread.cxx
+1
-0
GmeDecoderPlugin.cxx
src/decoder/plugins/GmeDecoderPlugin.cxx
+24
-21
Request.cxx
src/lib/curl/Request.cxx
+1
-1
AudioFormat.hxx
src/pcm/AudioFormat.hxx
+2
-2
Thread.cxx
src/player/Thread.cxx
+11
-6
StringFormat.hxx
src/util/StringFormat.hxx
+1
-1
build.py
win32/build.py
+1
-0
No files found.
NEWS
View file @
c6a7f6da
...
...
@@ -40,7 +40,7 @@ ver 0.22 (not yet released)
* switch to C++17
- GCC 7 or clang 4 (or newer) recommended
ver 0.21.24 (
not yet released
)
ver 0.21.24 (
2020/06/10
)
* protocol
- "tagtypes" requires no permissions
* database
...
...
@@ -49,11 +49,14 @@ ver 0.21.24 (not yet released)
- modplug: fix Windows build failure
- wildmidi: attempt to detect WildMidi using pkg-config
- wildmidi: fix Windows build failure
* player
- don't restart current song if seeking beyond end
* Android
- enable the decoder plugins ModPlug and WildMidi
- enable the decoder plugins
GME,
ModPlug and WildMidi
- fix build failure with Android NDK r21
* Windows
- enable the decoder plugins ModPlug and WildMidi
- fix stream playback
- enable the decoder plugins GME, ModPlug and WildMidi
- work around Meson bug breaking the Windows build with GCC 10
* fix unit test failure
...
...
android/build.py
View file @
c6a7f6da
...
...
@@ -170,6 +170,7 @@ thirdparty_libs = [
libid3tag
,
libmodplug
,
wildmidi
,
gme
,
ffmpeg
,
curl
,
libexpat
,
...
...
doc/protocol.rst
View file @
c6a7f6da
...
...
@@ -485,7 +485,8 @@ Querying :program:`MPD`'s status
- ``songs``: number of songs
- ``uptime``: daemon uptime in seconds
- ``db_playtime``: sum of all song times in the database in seconds
- ``db_update``: last db update in UNIX time
- ``db_update``: last db update in UNIX time (seconds since
1970-01-01 UTC)
- ``playtime``: time length of music played
Playback options
...
...
python/build/libs.py
View file @
c6a7f6da
...
...
@@ -135,6 +135,18 @@ wildmidi = CmakeProject(
version
=
'0.4.3'
,
)
gme
=
CmakeProject
(
'https://bitbucket.org/mpyne/game-music-emu/downloads/game-music-emu-0.6.3.tar.xz'
,
'aba34e53ef0ec6a34b58b84e28bf8cfbccee6585cebca25333604c35db3e051d'
,
'lib/libgme.a'
,
[
'-DBUILD_SHARED_LIBS=OFF'
,
'-DENABLE_UBSAN=OFF'
,
'-DZLIB_INCLUDE_DIR=OFF'
,
'-DSDL2_DIR=OFF'
,
],
)
ffmpeg
=
FfmpegProject
(
'http://ffmpeg.org/releases/ffmpeg-4.2.3.tar.xz'
,
'9df6c90aed1337634c1fb026fb01c154c29c82a64ea71291ff2da9aacb9aad31'
,
...
...
src/decoder/Bridge.cxx
View file @
c6a7f6da
...
...
@@ -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
;
}
...
...
src/decoder/Bridge.hxx
View file @
c6a7f6da
...
...
@@ -65,6 +65,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
* decoder_get_virtual_command(), when the virtual SEEK
...
...
@@ -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
;
...
...
src/decoder/Control.cxx
View file @
c6a7f6da
...
...
@@ -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
);
...
...
src/decoder/Control.hxx
View file @
c6a7f6da
...
...
@@ -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
;
...
...
src/decoder/DecoderPlugin.hxx
View file @
c6a7f6da
...
...
@@ -22,7 +22,7 @@
#include "util/Compiler.h"
#include <forward_list>
#include <forward_list>
// IWYU pragma: export
struct
ConfigBlock
;
class
InputStream
;
...
...
src/decoder/Thread.cxx
View file @
c6a7f6da
...
...
@@ -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
...
...
src/decoder/plugins/GmeDecoderPlugin.cxx
View file @
c6a7f6da
...
...
@@ -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
;
...
...
src/lib/curl/Request.cxx
View file @
c6a7f6da
...
...
@@ -57,7 +57,7 @@ CurlRequest::CurlRequest(CurlGlobal &_global,
easy
.
SetUserAgent
(
"Music Player Daemon "
VERSION
);
easy
.
SetHeaderFunction
(
_HeaderFunction
,
this
);
easy
.
SetWriteFunction
(
WriteFunction
,
this
);
#if
ndef ANDROID
#if
!defined(ANDROID) && !defined(_WIN32)
easy
.
SetOption
(
CURLOPT_NETRC
,
1L
);
#endif
easy
.
SetErrorBuffer
(
error_buffer
);
...
...
src/pcm/AudioFormat.hxx
View file @
c6a7f6da
...
...
@@ -20,8 +20,8 @@
#ifndef MPD_AUDIO_FORMAT_HXX
#define MPD_AUDIO_FORMAT_HXX
#include "pcm/SampleFormat.hxx"
#include "pcm/ChannelDefs.hxx"
#include "pcm/SampleFormat.hxx"
// IWYU pragma: export
#include "pcm/ChannelDefs.hxx"
// IWYU pragma: export
#include "util/Compiler.h"
#include <cstddef>
...
...
src/player/Thread.cxx
View file @
c6a7f6da
...
...
@@ -224,7 +224,8 @@ private:
* Caller must lock the mutex.
*/
void
StartDecoder
(
std
::
unique_lock
<
Mutex
>
&
lock
,
std
::
shared_ptr
<
MusicPipe
>
pipe
)
noexcept
;
std
::
shared_ptr
<
MusicPipe
>
pipe
,
bool
initial_seek_essential
)
noexcept
;
/**
* The decoder has acknowledged the "START" command (see
...
...
@@ -367,7 +368,8 @@ public:
void
Player
::
StartDecoder
(
std
::
unique_lock
<
Mutex
>
&
lock
,
std
::
shared_ptr
<
MusicPipe
>
_pipe
)
noexcept
std
::
shared_ptr
<
MusicPipe
>
_pipe
,
bool
initial_seek_essential
)
noexcept
{
assert
(
queued
||
pc
.
command
==
PlayerCommand
::
SEEK
);
assert
(
pc
.
next_song
!=
nullptr
);
...
...
@@ -379,6 +381,7 @@ Player::StartDecoder(std::unique_lock<Mutex> &lock,
dc
.
Start
(
lock
,
std
::
make_unique
<
DetachedSong
>
(
*
pc
.
next_song
),
start_time
,
pc
.
next_song
->
GetEndTime
(),
initial_seek_essential
,
buffer
,
std
::
move
(
_pipe
));
}
...
...
@@ -636,7 +639,7 @@ Player::SeekDecoder(std::unique_lock<Mutex> &lock) noexcept
pipe
->
Clear
();
/* re-start the decoder */
StartDecoder
(
lock
,
pipe
);
StartDecoder
(
lock
,
pipe
,
true
);
ActivateDecoder
();
pc
.
seeking
=
true
;
...
...
@@ -714,7 +717,8 @@ Player::ProcessCommand(std::unique_lock<Mutex> &lock) noexcept
pc
.
CommandFinished
();
if
(
dc
.
IsIdle
())
StartDecoder
(
lock
,
std
::
make_shared
<
MusicPipe
>
());
StartDecoder
(
lock
,
std
::
make_shared
<
MusicPipe
>
(),
false
);
break
;
...
...
@@ -985,7 +989,7 @@ Player::Run() noexcept
std
::
unique_lock
<
Mutex
>
lock
(
pc
.
mutex
);
StartDecoder
(
lock
,
pipe
);
StartDecoder
(
lock
,
pipe
,
true
);
ActivateDecoder
();
pc
.
state
=
PlayerState
::
PLAY
;
...
...
@@ -1025,7 +1029,8 @@ Player::Run() noexcept
assert
(
dc
.
pipe
==
nullptr
||
dc
.
pipe
==
pipe
);
StartDecoder
(
lock
,
std
::
make_shared
<
MusicPipe
>
());
StartDecoder
(
lock
,
std
::
make_shared
<
MusicPipe
>
(),
false
);
}
if
(
/* no cross-fading if MPD is going to pause at the
...
...
src/util/StringFormat.hxx
View file @
c6a7f6da
...
...
@@ -30,7 +30,7 @@
#ifndef STRING_FORMAT_HXX
#define STRING_FORMAT_HXX
#include "StringBuffer.hxx"
#include "StringBuffer.hxx"
// IWYU pragma: export
#include <stdio.h>
...
...
win32/build.py
View file @
c6a7f6da
...
...
@@ -98,6 +98,7 @@ thirdparty_libs = [
liblame
,
libmodplug
,
wildmidi
,
gme
,
ffmpeg
,
curl
,
libexpat
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment