From 05d8ce3bcd6e19843dabf822264c2be4582c71b2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 9 May 2011 07:57:46 +0200 Subject: [PATCH 1/7] decoder/ffmpeg: define fallback macro AV_VERSION_INT() For ffmpeg < 0.5. Copied from libavutil 0.5. --- src/decoder/ffmpeg_decoder_plugin.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index f9d4eb8a9..29f476ba7 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -81,6 +81,10 @@ mpd_ffmpeg_log_callback(G_GNUC_UNUSED void *ptr, int level, #endif /* !OLD_FFMPEG_INCLUDES */ +#ifndef AV_VERSION_INT +#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c) +#endif + struct mpd_ffmpeg_stream { struct decoder *decoder; struct input_stream *input; @@ -230,7 +234,7 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, static enum sample_format ffmpeg_sample_format(G_GNUC_UNUSED const AVCodecContext *codec_context) { -#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(41<<8)+0) +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(51, 41, 0) switch (codec_context->sample_fmt) { case SAMPLE_FMT_S16: return SAMPLE_FORMAT_S16; From 327d41c00f8346366f10765f2f5c8a55827ffdd3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 2 May 2011 20:53:15 +0200 Subject: [PATCH 2/7] decoder/ffmpeg: don't use deprecated CODEC_TYPE_AUDIO with new lavc fixes build with lavc 53. --- NEWS | 2 ++ src/decoder/ffmpeg_decoder_plugin.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/NEWS b/NEWS index d7ecb395d..a68f83bd5 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,7 @@ ver 0.16.3 (2011/??/??) * fix assertion failure in audio format mask parser +* decoder: + - ffmpeg: support lavc 53 ver 0.16.2 (2011/03/18) diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index 29f476ba7..76155eeef 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -160,7 +160,11 @@ ffmpeg_find_audio_stream(const AVFormatContext *format_context) { for (unsigned i = 0; i < format_context->nb_streams; ++i) if (format_context->streams[i]->codec->codec_type == +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 64, 0) + AVMEDIA_TYPE_AUDIO) +#else CODEC_TYPE_AUDIO) +#endif return i; return -1; From eaf414cbc8b624394b1269861b7e51a4907004c2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 12 Apr 2011 08:17:30 +0200 Subject: [PATCH 3/7] decoder/ffmpeg: make variables more local --- src/decoder/ffmpeg_decoder_plugin.c | 43 +++++++++++------------------ 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index 76155eeef..c4f4dfa0b 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -106,13 +106,11 @@ static int64_t mpd_ffmpeg_stream_seek(void *opaque, int64_t pos, int whence) { struct mpd_ffmpeg_stream *stream = opaque; - bool ret; if (whence == AVSEEK_SIZE) return stream->input->size; - ret = input_stream_seek(stream->input, pos, whence, NULL); - if (!ret) + if (!input_stream_seek(stream->input, pos, whence, NULL)) return -1; return stream->input->offset; @@ -191,30 +189,24 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, AVCodecContext *codec_context, const AVRational *time_base) { - enum decoder_command cmd = DECODE_COMMAND_NONE; - uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2 + 16]; - int16_t *aligned_buffer; - size_t buffer_size; - int len, audio_size; - uint8_t *packet_data; - int packet_size; - if (packet->pts != (int64_t)AV_NOPTS_VALUE) decoder_timestamp(decoder, av_rescale_q(packet->pts, *time_base, (AVRational){1, 1})); - packet_data = packet->data; - packet_size = packet->size; + const uint8_t *packet_data = packet->data; + int packet_size = packet->size; - buffer_size = sizeof(audio_buf); - aligned_buffer = align16(audio_buf, &buffer_size); + uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2 + 16]; + size_t buffer_size = sizeof(audio_buf); + int16_t *aligned_buffer = align16(audio_buf, &buffer_size); + enum decoder_command cmd = DECODE_COMMAND_NONE; while ((packet_size > 0) && (cmd == DECODE_COMMAND_NONE)) { - audio_size = buffer_size; - len = avcodec_decode_audio2(codec_context, - aligned_buffer, &audio_size, - packet_data, packet_size); + int audio_size = buffer_size; + int len = avcodec_decode_audio2(codec_context, + aligned_buffer, &audio_size, + packet_data, packet_size); if (len < 0) { /* if error, we skip the frame */ @@ -307,12 +299,8 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) return; } - AVFormatContext *format_context; - AVCodecContext *codec_context; - AVCodec *codec; - int audio_stream; - //ffmpeg works with ours "fileops" helper + AVFormatContext *format_context; if (av_open_input_stream(&format_context, stream->io, input->uri, input_format, NULL) != 0) { g_warning("Open failed\n"); @@ -327,7 +315,7 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) return; } - audio_stream = ffmpeg_find_audio_stream(format_context); + int audio_stream = ffmpeg_find_audio_stream(format_context); if (audio_stream == -1) { g_warning("No audio stream inside\n"); av_close_input_stream(format_context); @@ -335,11 +323,12 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) return; } - codec_context = format_context->streams[audio_stream]->codec; + AVCodecContext *codec_context = + format_context->streams[audio_stream]->codec; if (codec_context->codec_name[0] != 0) g_debug("codec '%s'", codec_context->codec_name); - codec = avcodec_find_decoder(codec_context->codec_id); + AVCodec *codec = avcodec_find_decoder(codec_context->codec_id); if (!codec) { g_warning("Unsupported audio codec\n"); From 246db3d5652bb7289b1a1ab255dfdb67e0fa260e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 12 Apr 2011 08:16:57 +0200 Subject: [PATCH 4/7] decoder/ffmpeg: use avcodec_decode_audio3() if available avcodec_decode_audio3() has been added in libavformat 52.25.0, and the predecessor avcodec_decode_audio2() has been deprecated. --- NEWS | 2 +- src/decoder/ffmpeg_decoder_plugin.c | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index a68f83bd5..05b9d86fa 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ ver 0.16.3 (2011/??/??) * fix assertion failure in audio format mask parser * decoder: - - ffmpeg: support lavc 53 + - ffmpeg: support libavcodec 0.7 ver 0.16.2 (2011/03/18) diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index c4f4dfa0b..6d794db49 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -194,19 +194,35 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, av_rescale_q(packet->pts, *time_base, (AVRational){1, 1})); +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0) + AVPacket packet2 = *packet; +#else const uint8_t *packet_data = packet->data; int packet_size = packet->size; +#endif uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2 + 16]; size_t buffer_size = sizeof(audio_buf); int16_t *aligned_buffer = align16(audio_buf, &buffer_size); enum decoder_command cmd = DECODE_COMMAND_NONE; - while ((packet_size > 0) && (cmd == DECODE_COMMAND_NONE)) { + while ( +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0) + packet2.size > 0 && +#else + packet_size > 0 && +#endif + cmd == DECODE_COMMAND_NONE) { int audio_size = buffer_size; +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0) + int len = avcodec_decode_audio3(codec_context, + aligned_buffer, &audio_size, + &packet2); +#else int len = avcodec_decode_audio2(codec_context, aligned_buffer, &audio_size, packet_data, packet_size); +#endif if (len < 0) { /* if error, we skip the frame */ @@ -214,8 +230,13 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, break; } +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0) + packet2.data += len; + packet2.size -= len; +#else packet_data += len; packet_size -= len; +#endif if (audio_size <= 0) continue; From 9402b23dd5f75388cb48fdf04ca62033dfc6709a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 9 May 2011 18:03:45 +0200 Subject: [PATCH 5/7] playlist_song: fix NULL pointer dereference --- NEWS | 1 + src/playlist_song.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 05b9d86fa..9dab437d0 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ ver 0.16.3 (2011/??/??) * fix assertion failure in audio format mask parser +* fix NULL pointer dereference in playlist parser * decoder: - ffmpeg: support libavcodec 0.7 diff --git a/src/playlist_song.c b/src/playlist_song.c index 1e8e98795..2ad63c913 100644 --- a/src/playlist_song.c +++ b/src/playlist_song.c @@ -129,7 +129,7 @@ playlist_check_translate_song(struct song *song, const char *base_uri) else uri = g_strdup(uri); - if (uri_has_scheme(base_uri)) { + if (uri_has_scheme(uri)) { dest = song_remote_new(uri); g_free(uri); } else { From 26735390fffaa467bf90041a5c380802602affb6 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 9 May 2011 18:00:41 +0200 Subject: [PATCH 6/7] playlist_song: fix playlist files in base music directory g_path_get_dirname() returns "." when there is no directory name in the given path. This patch adds a workaround for that. --- NEWS | 1 + src/playlist_song.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/NEWS b/NEWS index 9dab437d0..fed63b5b1 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ ver 0.16.3 (2011/??/??) * fix assertion failure in audio format mask parser * fix NULL pointer dereference in playlist parser +* fix playlist files in base music directory * decoder: - ffmpeg: support libavcodec 0.7 diff --git a/src/playlist_song.c b/src/playlist_song.c index 2ad63c913..1a543a0b8 100644 --- a/src/playlist_song.c +++ b/src/playlist_song.c @@ -105,6 +105,13 @@ playlist_check_translate_song(struct song *song, const char *base_uri) } } + if (base_uri != NULL && strcmp(base_uri, ".") == 0) + /* g_path_get_dirname() returns "." when there is no + directory name in the given path; clear that now, + because it would break the database lookup + functions */ + base_uri = NULL; + if (g_path_is_absolute(uri)) { /* XXX fs_charset vs utf8? */ char *prefix = base_uri != NULL From 4b4aa64261154bcb1e521b98629c0640d6b259f7 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 9 May 2011 21:37:43 +0200 Subject: [PATCH 7/7] directory: allow directories with just playlists Keep those when scanning for empty directories. The check in playlist_vector_is_empty() was missing. --- NEWS | 1 + src/directory.h | 3 ++- src/playlist_vector.h | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index fed63b5b1..f56e2e872 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ ver 0.16.3 (2011/??/??) * fix assertion failure in audio format mask parser * fix NULL pointer dereference in playlist parser * fix playlist files in base music directory +* database: allow directories with just playlists * decoder: - ffmpeg: support libavcodec 0.7 diff --git a/src/directory.h b/src/directory.h index 69e2b3638..151cf5423 100644 --- a/src/directory.h +++ b/src/directory.h @@ -62,7 +62,8 @@ directory_free(struct directory *directory); static inline bool directory_is_empty(const struct directory *directory) { - return directory->children.nr == 0 && directory->songs.nr == 0; + return directory->children.nr == 0 && directory->songs.nr == 0 && + playlist_vector_is_empty(&directory->playlists); } static inline const char * diff --git a/src/playlist_vector.h b/src/playlist_vector.h index 566de5f00..62861ae49 100644 --- a/src/playlist_vector.h +++ b/src/playlist_vector.h @@ -51,6 +51,12 @@ playlist_vector_init(struct playlist_vector *pv) void playlist_vector_deinit(struct playlist_vector *pv); +static inline bool +playlist_vector_is_empty(const struct playlist_vector *pv) +{ + return pv->head == NULL; +} + struct playlist_metadata * playlist_vector_find(struct playlist_vector *pv, const char *name);