Don't initialize "vc" and "cs" with FLAC__metadata_object_new(); that
value is overwritten by FLAC__metadata_get_tags() and
FLAC__metadata_get_cuesheet().
The "off_t" type may change when you enable or disable large file
support on 32 bit platforms. This caused severe ABI problems within
MPD when we enabled LFS for the first time: two sources included
config.h and sys/types.h in different order, and had different off_t
sizes - leading to memory corruption because of ABI incompatibility.
This patch attempts to get rid of all public "off_t" uses: it removes
"off_t" from the input_stream ABI/API, and switches to GLib's 64 bit
"goffset" type. This may hurt 32 bit embedded platforms a tiny bit,
but that's not even measurable.
Usually, we read our "artist" tag from ffmpeg's "author" tag. In some
cases however (e.g. APE), this tag is named "artist". This patch
implements a fallback: if no "author" is found, MPD tries to use
"artist".
When the ID3 tag in an AAC file is larger than the current buffer, the
function decoder_buffer_consume() aborts. By using the new function
decoder_buffer_skip() instead, we can safely skip the ID3 tag.
using ov_test_callback with function CALLBACKS_STREAMONLY will cause
scanning to stop after the comment field. ov_open (and ov_test)
default to CALLBACKS_DEFAULT which scans the file structure causing a
huge slowdown. The speed improvement is huge: It scanned my files
around 10x faster This procedure has been recommended by monthy (main
vorbis developer) and was said to be safe for scanning files.
The function flac_cue_track() first calls FLAC__metadata_object_new(),
then overwrites this pointer with FLAC__metadata_get_cuesheet(). This
allocate two FLAC__StreamMetadata objects, but the first pointer is
lost, and never freed.
When libid3tag is disabled, the libmad decoder plugin is unable to
identify ID3 frames. If the file starts with an (unidentified) ID3
frame, it assumes that the file is not a valid MP3 song. This patch
solves this by adding minimal stubs for the ID3 functions.
Cuesheets are often saved as vorbis comment
flac files (CUESHEET=.. case doesn't matter).
We can parse this now and use the information to
tag the subtracks (from the embedded cuesheets).
Previous cast to float didn't have any effect because one value is uint
and the other is a floating type but the number itself is even..
This caused some tracks to end before they were really at an end.
On 2009/03/17 Max Kellermann<max@duempel.org> wrote:
> There doesn't seem to be an "official" standard. I'd say: search for
> TITLE[1] first (the most explicit form), then TITLE1, and finally fall
> back to TITLE. This makes sure MPD supports every possible standard,
> without breaking.
I've also added some additional checks to make sure entry is long
enough.
The cue sheet embedded in a flac file doen't contain any information
about track titles and similar. There are three possibilities: Use an
external cue sheet that includes these information, use a tag CUESHEET
with a cue sheet including these information or use tags. I think the
latter is the best option and is already used by other projects.
This updates the copyright header to all be the same, which is
pretty much an update of where to mail request for a copy of the GPL
and the years of the MPD project. This also puts all committers under
'The Music Player Project' umbrella. These entries should go
individually in the AUTHORS file, for consistancy.
So far only seekpoints are supported, so no proper tagging yet
except for track number and track length.
Tagging should be done by parsing the cue sheet which
is often embedded as vorbis comment in flac files.
Furthermore the pathname should be configurable like "%A - %t - %T",
where %A means Artist, %t track number and %T Title or so.
After the decoder command was obtained, don't wait until libflac
detects EOF (as a side effect), quit the decoder immediately. This
check was missing completely.
When the MPD core sends the decoder a command while
flac_process_single() is executed, this function fails. Abort the
decoder only if not seeking. This fixes a seeking bug.
If an input_stream is not seekable, libaudiofile fails to play at all:
Audio File Library: unrecognized audio file format [error 0]
Since we know in advance whether the input_stream is seekable, just
refuse to play on a non-seekable stream.
After much research[1][2][3] this should be the majority of currently
supported file extensions and mime-types for the currently supported
ffmpeg formats. This list maybe incomplete, but it's more complete
than anything else out there that I've been able to find. This list
needs to be updated every now and again as the ffmpeg sources support
more formats.
1. Sources
2. wiki.multimedia.cx
3. filext.com
Use faacDecInit2() instead of AudioSpecificConfig() to detect the AAC
track in the MP4 file. This has a great advantage: it initializes the
libfaad decoder, which the caller would normally do anyway - but now
we can go without the AudioSpecificConfig() call. When decoder==NULL
(called from mp4_tag_dup()), fall back to a mp4ff_get_track_type()==1
check, like other audio players do.
Moved the libfaad decoder initialization to mp4_faad_new(), and also
fill the audio_format struct there. This eliminates a little bit of
complexity in mp4_decode().
All callers of adts_find_frame() use faad_buffer_fill() before that.
Move that faad_buffer_fill() call into adts_find_frame() instead.
adts_find_frame() will get its own logic for on-demand filling.
There are a few problems left in this plugin:
- fluidsynth decodes in real time, while MPD prefers to buffer as
quickly as possible; as a workaround, this plugin uses a timer
object to synchronize with real-time playback
- I don't know yet how fluidsynth tells me when the song has ended
- the "soundfont" configuration setting is not yet documented, and it
will likely change soon (in favor of a per-decoder configuration
block)
The "current" variable is used for calculating the seek destination,
and was declared as "int". With very long song files, the 32 bit
integer can overflow. ffmpeg expects an int64_t, which is very
unlikely to overflow. Switch to int64_t.
If avcodec_decode_audio2() returns no output for an AVPacket,
libavcodec may buffer some data, and return a larger chunk of output
later. This patch disables a lot of bogus warnings.
Output the name of the codec as a debug message. During my tests,
ffmpeg never filled this struct member, but it may do so in the past,
and this debug message might become helpful.
Hi -
independently of libmikmod's other problems - there seems
to be a problem in mpd's wrapper: MikMod_Exit() is called
after the first file is decoded, which frees some ressources
within the mikmod library. An attempt to play a second file
leads to a crash. The appended patch fixes this for me.
(I don't know what the "dup" entry is good for - someone
who knows should review that too.)
best regards
Matthias
[mk: removed 3 more MikMod_Exit() invocations]
ffmpeg_tag_internal() does not look for a few tags that mpd
supports. Most noteably:
comment -> TAG_ITEM_COMMENT -> Description
genre -> TAG_ITEM_GENRE -> WM/Genre (not WM/GenreID)
year -> TAG_ITEM_DATE -> WM/Year
I *think* that this is the last of the tags that AVFormatContext() in
ffmpeg supports that mpd also uses.
On some platforms, g_free() must be used for memory allocated by
GLib. This patch intends to correct a lot of occurrences, but is
probably not complete.
The input_stream API sets size to -1 when the size of the resource is
not known. The modplug decoder checked for size==0, which would be an
empty file.
You are allowed to call decoder_read() with decoder==NULL. It is a
convenience function provided by the decoder API. Don't manually fall
back to input_stream_read().
Some plugins used the APE or ID3 tag loader as a fallback when their
own methods of loading tags did not work. Move this code out of all
decoder plugins, into song_file_update().
When libvorbis knows that a song is seekable, it seeks around like
crazy in the file before starting to decode it. This is very
expensive on remote HTTP resources, and delays MPD for 10 or 20
seconds.
This patch disables seeking on remote songs, because the advantages of
quickly playing a song seem to weigh more than the theoretical ability
of seeking for most MPD users. If users feel this feature is needed,
we will make a configuration option for that.
vorbis_parse_comment() should be a function which converts one comment
to a tag item. It should do everything required to do the conversion,
including looping over all possible tag types.
I tried to search for a certain composer in my collection, but only
non-mp4 files showed up. The source code reveals that this tag is not
read. This can be fixed by reading the 'Writer' tag field, in
mp4_plugin.c, in function mp4_load_tag.
I actually tried this, and after compiling with those lines added,
also mp4 (.m4a) files showed up when searching for a composer.
This patch adds RVA2 (relative volume adjustment) tag
support to mpd, as a fallback if no replaygain tags are
found. The code is almost directly from madplay (GPL).
RVA2 tags are generated for example by the "normalize" utility.
Updated by: Avuton Olrich <avuton@gmail.com>
The input_stream object should only be closed by the MPD core
(i.e. decoder_thread.c / decoder_run()). A decoder plugin which
attempts to close it will result in a segmentation fault.
neaacdec.h declares all arguments as "unsigned long", but internally
expects uint32_t pointers. This triggers gcc warnings on 64 bit
architectures. To avoid that, make configure.ac detect whether we're
using Debian's corrected headers or the original libfaad headers. In
any case, pass a pointer to an uint32_t, conditionally casted to
"unsigned long*".
The wavpack open function gives us an option called OPEN_STREAMING. This
provides more robust and error tolerant playback, but it automatically
disables seeking. (More exactly the wavpack lib will not return the
length information.) So, if the stream is already not seekable we can
use this option safely.
According to the documentation, mpc_decoder_decode() returns an
mpc_uint32_t. Since the special return value (mpc_uint32_t)-1
translates to a very large long integer, this may cause segmentation
faults if not interpreted properly.
Don't split the buffer conversion loop. When libmpcdec returns a
chunk, convert and send the whole chunk at a time. This moves several
checks out of the loop, and greatly improves performance.
Parse ID3 tags, even when they are in the middle of the stream. Very
few streams provide embedded ID3 tags. Most of them send only
Shoutcast "icy" tags, which limits the practical usefulness of this
patch.
When a command is received, decode_next_frame_header() and
decodeNextFrame() return DECODE_BREAK. This is already checked by
both callers, which means that we can eliminate lots of
decoder_get_command() checks.
The stream_decode() and file_decode() methods returned a boolean,
indicating whether they were able to decode the song. This is
redundant, since we already know that: if decoder_initialized() has
been called (and dc.state==DECODE), the plugin succeeded. Change both
methods to return void.
The function simplifies wavpack_replaygain(), because it already
contains the float parser, and it works with a fixed buffer instead of
doing expensive heap allocations.
The flac plugin wasn't initialized properly when an OGG file was being
decoded. For some reason, flac_process_metadata() was explicitly not
called for OGG files. Since that seems to fix the issue, make it
always call flac_process_metadata().
Since decoder_list.c does not include the libflac headers, it cannot
know whether to add the oggflac plugin to the decoder list. Solve
this by always enabling the oggflac sub-plugin, even with older
libflac versions. When the libflac API cannot support oggflac,
disable the plugin at runtime by returning "false" from its init()
method.
At this moment the wavpack lib doesn't use the return value of the
push_back function, which has an equivalent meaning of the return
value of ungetc(). This is a lucky situation, because so far it
simply returned with 1 as a hard coded value. From now on the
function will return EOF on error. (This function makes exactly one
byte pushable back.)
There are some functions in the wavpack-mpd input streams wrapper
which had too commonly used names (especially can_seek). I prefixed
these with "wavpack_input_".
libwavpack expects the read_bytes() stream method to fill the whole
buffer, and fails badly when we return a partial read (i.e. not enough
data available yet). This caused wavpack streams to break.
Re-implement the buffer filling loop.
Instead of manually waiting for the input stream to become ready (to
catch server errors), just read the first byte. Since the
wavpack_input has the capability to push back one byte, we can simply
re-feed it. Advantage is: decoder_read() handles everything for us,
i.e. waiting for the stream, polling for decoder commands and error
handling.
The API of mp4_load_tag() was strange: it always returned a tag
object, no matter if a tag was found in the file; the existence of a
tag was indicated with the tag_found integer reference. This flag is
superfluous, since we can simply check whether the tag is empty or
not.
Allocate the mp4ff_callback_t object on the stack. This is easier to
handle, since we don't have to free it. Incidentally, this fixes a
memory leak in mp4_load_tag().
The function decoder_read() already cares about the decoder command,
and loops until data is available. Reduced mpd_ffmpeg_read() to no
more than the decoder_read() call.
If an input stream provides tags (e.g. from an icecast server), send
them in the decoder_data() and decoder_tag() methods. Removed the
according code from the mp3 and oggvorbis plugins - decoders shouldn't
have to care about stream tags.
This patch also adds the missing decoder_tag() invocation to the mp3
plugin.
The "mod" decoder plugin was being initialized lazily, but was
deinitialized unconditionally. That led to segmentation faults.
Convert mod_initMikMod() to be the global module initialization
method. The MPD core should care about lazy initialization.
The try_decode() method may have read some data from the stream, which
is now lost. To make this data available to other methods, get it
back by rewinding the input stream after each try_decode() invocation.
The ogg and wavpack plugins did this manually and inconsistently; this
code can now be removed.
Ogg and ffmpeg detection was disabled when the stream was not
seekable, because the detection was too expensive. Since the curl
input stream can now rewind the stream cheaply, we can re-enable
detection on streams.
Since the aac and mod plugins have told MPD that they cannot seek, MPD
will never send a SEEK command to them. Removed the SEEK comand
checks from both plugins.
Don't pass the "seekable" flag with every decoder_data() invocation.
Since that flag won't change within the file, it is enough to pass it
to decoder_initialized() once per file.
"LOG_H" is a macro which is also used by ffmpeg/log.h. This is
ffmpeg's fault, because short macros should be reserved for
applications, but since it's always a good idea to choose prefixed
macro names, even for applications, we are going to do that in MPD.
Similar to libmad, libmpcdec provides samples with higher quality than
16 bit. Send 24 bit samples to MPD, which allows MPD to apply
dithering just in case the output devices are only 16 bit capable.
The conversion of integer samples was completely broken, which
presumably didn't annoy anybody because libmpcdec provides float
samples on most installations.
Its only caller in mp3_decode() just compared its value with
DECODE_BREAK. Convert that to bool, and return false if the loop
should be ended. Also eliminate some superfluous command checking
code, which was already done in the preceding while loop.
A decoder_flush() invocation was missing in the FLAC plugin, resulting
in casual assertion failures due to a wrong assumption about the last
chunk's audio format. It's much easier to remove that decoder_flush()
function and make the decoder thread call ob_flush().
Remember the seek_where argument and call decoder_command_finished()
immediately. This way, the player thread can continue working, and we
can receive more commands.
This also fixes several issues which resulted in broken frames,
leading to erroneos "elapsed" values: frames weren't parsed properly,
since the code was checking for command!=NONE.
size_t and long aren't 64 bit safe (i.e. files larger than 2 GB on a
32 bit OS). Use off_t instead, which is a 64 bit integer if compiled
with large file support.