Merge release 0.15.8 from branch 'v0.15.x
Conflicts: Makefile.am NEWS configure.ac src/decoder/ffmpeg_decoder_plugin.c src/decoder_thread.c
This commit is contained in:
commit
a0a26d3341
6
NEWS
6
NEWS
@ -88,11 +88,15 @@ ver 0.16 (20??/??/??)
|
|||||||
* require GLib 2.12
|
* require GLib 2.12
|
||||||
|
|
||||||
|
|
||||||
ver 0.15.8 (2009/??/??)
|
ver 0.15.8 (2010/01/17)
|
||||||
* input:
|
* input:
|
||||||
- curl: allow rewinding with Icy-Metadata
|
- curl: allow rewinding with Icy-Metadata
|
||||||
* decoders:
|
* decoders:
|
||||||
- ffmpeg, flac, vorbis: added more flac/vorbis MIME types
|
- ffmpeg, flac, vorbis: added more flac/vorbis MIME types
|
||||||
|
- ffmpeg: enabled libavformat's file name extension detection
|
||||||
|
* dbUtils: return empty tag value only if no value was found
|
||||||
|
* decoder_thread: fix CUE track playback
|
||||||
|
* queue: don't repeat current song in consume mode
|
||||||
|
|
||||||
|
|
||||||
ver 0.15.7 (2009/12/27)
|
ver 0.15.7 (2009/12/27)
|
||||||
|
@ -256,6 +256,7 @@ visitTag(struct client *client, struct strset *set,
|
|||||||
struct song *song, enum tag_type tagType)
|
struct song *song, enum tag_type tagType)
|
||||||
{
|
{
|
||||||
struct tag *tag = song->tag;
|
struct tag *tag = song->tag;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
if (tagType == LOCATE_TAG_FILE_TYPE) {
|
if (tagType == LOCATE_TAG_FILE_TYPE) {
|
||||||
song_print_uri(client, song);
|
song_print_uri(client, song);
|
||||||
@ -268,10 +269,12 @@ visitTag(struct client *client, struct strset *set,
|
|||||||
for (unsigned i = 0; i < tag->num_items; i++) {
|
for (unsigned i = 0; i < tag->num_items; i++) {
|
||||||
if (tag->items[i]->type == tagType) {
|
if (tag->items[i]->type == tagType) {
|
||||||
strset_add(set, tag->items[i]->value);
|
strset_add(set, tag->items[i]->value);
|
||||||
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
strset_add(set, "");
|
if (!found)
|
||||||
|
strset_add(set, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct list_tags_data {
|
struct list_tags_data {
|
||||||
|
@ -56,7 +56,7 @@ struct ffmpeg_context {
|
|||||||
|
|
||||||
struct ffmpeg_stream {
|
struct ffmpeg_stream {
|
||||||
/** hack - see url_to_struct() */
|
/** hack - see url_to_struct() */
|
||||||
char url[8];
|
char url[64];
|
||||||
|
|
||||||
struct decoder *decoder;
|
struct decoder *decoder;
|
||||||
struct input_stream *input;
|
struct input_stream *input;
|
||||||
@ -141,8 +141,28 @@ ffmpeg_find_audio_stream(const AVFormatContext *format_context)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append the suffix of the original URI to the virtual stream URI.
|
||||||
|
* Without this, libavformat cannot detect some of the codecs
|
||||||
|
* (e.g. "shorten").
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
append_uri_suffix(struct ffmpeg_stream *stream, const char *uri)
|
||||||
|
{
|
||||||
|
assert(stream != NULL);
|
||||||
|
assert(uri != NULL);
|
||||||
|
|
||||||
|
char *base = g_path_get_basename(uri);
|
||||||
|
|
||||||
|
const char *suffix = strrchr(base, '.');
|
||||||
|
if (suffix != NULL && suffix[1] != 0)
|
||||||
|
g_strlcat(stream->url, suffix, sizeof(stream->url));
|
||||||
|
|
||||||
|
g_free(base);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ffmpeg_helper(struct input_stream *input,
|
ffmpeg_helper(const char *uri, struct input_stream *input,
|
||||||
bool (*callback)(struct ffmpeg_context *ctx),
|
bool (*callback)(struct ffmpeg_context *ctx),
|
||||||
struct ffmpeg_context *ctx)
|
struct ffmpeg_context *ctx)
|
||||||
{
|
{
|
||||||
@ -155,6 +175,9 @@ ffmpeg_helper(struct input_stream *input,
|
|||||||
};
|
};
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
|
if (uri != NULL)
|
||||||
|
append_uri_suffix(&stream, uri);
|
||||||
|
|
||||||
stream.input = input;
|
stream.input = input;
|
||||||
if (ctx && ctx->decoder) {
|
if (ctx && ctx->decoder) {
|
||||||
stream.decoder = ctx->decoder; //are we in decoding loop ?
|
stream.decoder = ctx->decoder; //are we in decoding loop ?
|
||||||
@ -362,7 +385,8 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
|
|||||||
ctx.input = input;
|
ctx.input = input;
|
||||||
ctx.decoder = decoder;
|
ctx.decoder = decoder;
|
||||||
|
|
||||||
ffmpeg_helper(input, ffmpeg_decode_internal, &ctx);
|
ffmpeg_helper(decoder_get_uri(decoder), input,
|
||||||
|
ffmpeg_decode_internal, &ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(31<<8)+0)
|
#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(31<<8)+0)
|
||||||
@ -435,7 +459,7 @@ ffmpeg_stream_tag(struct input_stream *is)
|
|||||||
ctx.decoder = NULL;
|
ctx.decoder = NULL;
|
||||||
ctx.tag = tag_new();
|
ctx.tag = tag_new();
|
||||||
|
|
||||||
ret = ffmpeg_helper(is, ffmpeg_tag_internal, &ctx);
|
ret = ffmpeg_helper(NULL, is, ffmpeg_tag_internal, &ctx);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
tag_free(ctx.tag);
|
tag_free(ctx.tag);
|
||||||
ctx.tag = NULL;
|
ctx.tag = NULL;
|
||||||
@ -469,6 +493,7 @@ static const char *const ffmpeg_suffixes[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const char *const ffmpeg_mime_types[] = {
|
static const char *const ffmpeg_mime_types[] = {
|
||||||
|
"application/m4a",
|
||||||
"application/mp4",
|
"application/mp4",
|
||||||
"application/octet-stream",
|
"application/octet-stream",
|
||||||
"application/ogg",
|
"application/ogg",
|
||||||
@ -481,9 +506,12 @@ static const char *const ffmpeg_mime_types[] = {
|
|||||||
"audio/16sv",
|
"audio/16sv",
|
||||||
"audio/aac",
|
"audio/aac",
|
||||||
"audio/ac3",
|
"audio/ac3",
|
||||||
|
"audio/aiff"
|
||||||
"audio/amr",
|
"audio/amr",
|
||||||
"audio/basic",
|
"audio/basic",
|
||||||
"audio/flac",
|
"audio/flac",
|
||||||
|
"audio/m4a",
|
||||||
|
"audio/mp4",
|
||||||
"audio/mpeg",
|
"audio/mpeg",
|
||||||
"audio/musepack",
|
"audio/musepack",
|
||||||
"audio/ogg",
|
"audio/ogg",
|
||||||
@ -502,6 +530,7 @@ static const char *const ffmpeg_mime_types[] = {
|
|||||||
"audio/x-flac",
|
"audio/x-flac",
|
||||||
"audio/x-gsm",
|
"audio/x-gsm",
|
||||||
"audio/x-mace",
|
"audio/x-mace",
|
||||||
|
"audio/x-matroska",
|
||||||
"audio/x-monkeys-audio",
|
"audio/x-monkeys-audio",
|
||||||
"audio/x-mpeg",
|
"audio/x-mpeg",
|
||||||
"audio/x-ms-wma",
|
"audio/x-ms-wma",
|
||||||
@ -514,6 +543,7 @@ static const char *const ffmpeg_mime_types[] = {
|
|||||||
"audio/x-pn-multirate-realaudio",
|
"audio/x-pn-multirate-realaudio",
|
||||||
"audio/x-speex",
|
"audio/x-speex",
|
||||||
"audio/x-tta"
|
"audio/x-tta"
|
||||||
|
"audio/x-voc",
|
||||||
"audio/x-wav",
|
"audio/x-wav",
|
||||||
"audio/x-wma",
|
"audio/x-wma",
|
||||||
"audio/x-wv",
|
"audio/x-wv",
|
||||||
|
@ -46,14 +46,14 @@ queue_next_order(const struct queue *queue, unsigned order)
|
|||||||
|
|
||||||
if (queue->single)
|
if (queue->single)
|
||||||
{
|
{
|
||||||
if (queue->repeat)
|
if (queue->repeat && !queue->consume)
|
||||||
return order;
|
return order;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (order + 1 < queue->length)
|
if (order + 1 < queue->length)
|
||||||
return order + 1;
|
return order + 1;
|
||||||
else if (queue->repeat)
|
else if (queue->repeat && (order > 0 || !queue->consume))
|
||||||
/* restart at first song */
|
/* restart at first song */
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user