From dff8c6450b8e3bd4dbc19fcce52faa8c5950b662 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Aug 2008 08:44:12 +0200 Subject: renamed decode.c to decoder_thread.c It should be obvious in which thread or context a function is being executed at runtime. The code which was left in decode.c is for the decoder thread itself; give the file a better name. --- src/Makefile.am | 3 +- src/decode.c | 197 -------------------------------------------------- src/decode.h | 2 - src/decoder_thread.c | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/decoder_thread.h | 25 +++++++ src/main.c | 2 +- 6 files changed, 227 insertions(+), 201 deletions(-) delete mode 100644 src/decode.c create mode 100644 src/decoder_thread.c create mode 100644 src/decoder_thread.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 28a949b4e..ff4db3523 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,6 +41,7 @@ mpd_headers = \ crossfade.h \ dbUtils.h \ decode.h \ + decoder_thread.h \ decoder_api.h \ decoder_internal.h \ directory.h \ @@ -106,7 +107,7 @@ mpd_SOURCES = \ conf.c \ crossfade.c \ dbUtils.c \ - decode.c \ + decoder_thread.c \ decoder_control.c \ decoder_api.c \ directory.c \ diff --git a/src/decode.c b/src/decode.c deleted file mode 100644 index 3362077ac..000000000 --- a/src/decode.c +++ /dev/null @@ -1,197 +0,0 @@ -/* the Music Player Daemon (MPD) - * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) - * This project's homepage is: http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "decode.h" -#include "decoder_internal.h" -#include "player.h" - -#include "path.h" -#include "log.h" -#include "ls.h" - -static void decodeStart(void) -{ - struct decoder decoder; - int ret; - int close_instream = 1; - InputStream inStream; - struct decoder_plugin *plugin = NULL; - char path_max_fs[MPD_PATH_MAX]; - char path_max_utf8[MPD_PATH_MAX]; - - if (!get_song_url(path_max_utf8, dc.next_song)) { - dc.error = DECODE_ERROR_FILE; - goto stop_no_close; - } - if (!isRemoteUrl(path_max_utf8)) { - rmp2amp_r(path_max_fs, - utf8_to_fs_charset(path_max_fs, path_max_utf8)); - } else - pathcpy_trunc(path_max_fs, path_max_utf8); - - dc.current_song = dc.next_song; /* NEED LOCK */ - if (openInputStream(&inStream, path_max_fs) < 0) { - dc.error = DECODE_ERROR_FILE; - goto stop_no_close; - } - - decoder.seeking = 0; - - dc.state = DECODE_STATE_START; - dc.command = DECODE_COMMAND_NONE; - - /* wait for the input stream to become ready; its metadata - will be available then */ - - while (!inStream.ready) { - if (dc.command != DECODE_COMMAND_NONE) - goto stop; - - ret = bufferInputStream(&inStream); - if (ret < 0) - goto stop; - } - - /* for http streams, seekable is determined in bufferInputStream */ - dc.seekable = inStream.seekable; - - if (dc.command == DECODE_COMMAND_STOP) - goto stop; - - ret = DECODE_ERROR_UNKTYPE; - if (isRemoteUrl(path_max_utf8)) { - unsigned int next = 0; - - /* first we try mime types: */ - while (ret && (plugin = decoder_plugin_from_mime_type(inStream.mime, next++))) { - if (!plugin->stream_decode_func) - continue; - if (!(plugin->stream_types & INPUT_PLUGIN_STREAM_URL)) - continue; - if (plugin->try_decode_func - && !plugin->try_decode_func(&inStream)) - continue; - ret = plugin->stream_decode_func(&decoder, &inStream); - break; - } - - /* if that fails, try suffix matching the URL: */ - if (plugin == NULL) { - const char *s = getSuffix(path_max_utf8); - next = 0; - while (ret && (plugin = decoder_plugin_from_suffix(s, next++))) { - if (!plugin->stream_decode_func) - continue; - if (!(plugin->stream_types & - INPUT_PLUGIN_STREAM_URL)) - continue; - if (plugin->try_decode_func && - !plugin->try_decode_func(&inStream)) - continue; - decoder.plugin = plugin; - ret = plugin->stream_decode_func(&decoder, - &inStream); - break; - } - } - /* fallback to mp3: */ - /* this is needed for bastard streams that don't have a suffix - or set the mimeType */ - if (plugin == NULL) { - /* we already know our mp3Plugin supports streams, no - * need to check for stream{Types,DecodeFunc} */ - if ((plugin = decoder_plugin_from_name("mp3"))) { - decoder.plugin = plugin; - ret = plugin->stream_decode_func(&decoder, - &inStream); - } - } - } else { - unsigned int next = 0; - const char *s = getSuffix(path_max_utf8); - while (ret && (plugin = decoder_plugin_from_suffix(s, next++))) { - if (!plugin->stream_types & INPUT_PLUGIN_STREAM_FILE) - continue; - - if (plugin->try_decode_func && - !plugin->try_decode_func(&inStream)) - continue; - - if (plugin->file_decode_func) { - closeInputStream(&inStream); - close_instream = 0; - decoder.plugin = plugin; - ret = plugin->file_decode_func(&decoder, - path_max_fs); - break; - } else if (plugin->stream_decode_func) { - decoder.plugin = plugin; - ret = plugin->stream_decode_func(&decoder, - &inStream); - break; - } - } - } - - if (ret < 0 || ret == DECODE_ERROR_UNKTYPE) { - if (ret != DECODE_ERROR_UNKTYPE) - dc.error = DECODE_ERROR_FILE; - else - dc.error = DECODE_ERROR_UNKTYPE; - } - -stop: - if (close_instream) - closeInputStream(&inStream); -stop_no_close: - dc.state = DECODE_STATE_STOP; - dc.command = DECODE_COMMAND_NONE; -} - -static void * decoder_task(mpd_unused void *arg) -{ - notify_enter(&dc.notify); - - while (1) { - assert(dc.state == DECODE_STATE_STOP); - - if (dc.command == DECODE_COMMAND_START || - dc.command == DECODE_COMMAND_SEEK) { - decodeStart(); - } else if (dc.command == DECODE_COMMAND_STOP) { - dc.command = DECODE_COMMAND_NONE; - notify_signal(&pc.notify); - } else { - notify_wait(&dc.notify); - notify_signal(&pc.notify); - } - } - - return NULL; -} - -void decoderInit(void) -{ - pthread_attr_t attr; - pthread_t decoder_thread; - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - if (pthread_create(&decoder_thread, &attr, decoder_task, NULL)) - FATAL("Failed to spawn decoder task: %s\n", strerror(errno)); -} diff --git a/src/decode.h b/src/decode.h index a1ed04157..0b1fe389f 100644 --- a/src/decode.h +++ b/src/decode.h @@ -55,8 +55,6 @@ struct decoder_control { extern struct decoder_control dc; -void decoderInit(void); - static inline int decoder_is_idle(void) { return dc.state == DECODE_STATE_STOP && diff --git a/src/decoder_thread.c b/src/decoder_thread.c new file mode 100644 index 000000000..4104b585f --- /dev/null +++ b/src/decoder_thread.c @@ -0,0 +1,199 @@ +/* the Music Player Daemon (MPD) + * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) + * Copyright (C) 2008 Max Kellermann + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "decoder_thread.h" +#include "decode.h" +#include "decoder_internal.h" +#include "player.h" + +#include "path.h" +#include "log.h" +#include "ls.h" + +static void decodeStart(void) +{ + struct decoder decoder; + int ret; + int close_instream = 1; + InputStream inStream; + struct decoder_plugin *plugin = NULL; + char path_max_fs[MPD_PATH_MAX]; + char path_max_utf8[MPD_PATH_MAX]; + + if (!get_song_url(path_max_utf8, dc.next_song)) { + dc.error = DECODE_ERROR_FILE; + goto stop_no_close; + } + if (!isRemoteUrl(path_max_utf8)) { + rmp2amp_r(path_max_fs, + utf8_to_fs_charset(path_max_fs, path_max_utf8)); + } else + pathcpy_trunc(path_max_fs, path_max_utf8); + + dc.current_song = dc.next_song; /* NEED LOCK */ + if (openInputStream(&inStream, path_max_fs) < 0) { + dc.error = DECODE_ERROR_FILE; + goto stop_no_close; + } + + decoder.seeking = 0; + + dc.state = DECODE_STATE_START; + dc.command = DECODE_COMMAND_NONE; + + /* wait for the input stream to become ready; its metadata + will be available then */ + + while (!inStream.ready) { + if (dc.command != DECODE_COMMAND_NONE) + goto stop; + + ret = bufferInputStream(&inStream); + if (ret < 0) + goto stop; + } + + /* for http streams, seekable is determined in bufferInputStream */ + dc.seekable = inStream.seekable; + + if (dc.command == DECODE_COMMAND_STOP) + goto stop; + + ret = DECODE_ERROR_UNKTYPE; + if (isRemoteUrl(path_max_utf8)) { + unsigned int next = 0; + + /* first we try mime types: */ + while (ret && (plugin = decoder_plugin_from_mime_type(inStream.mime, next++))) { + if (!plugin->stream_decode_func) + continue; + if (!(plugin->stream_types & INPUT_PLUGIN_STREAM_URL)) + continue; + if (plugin->try_decode_func + && !plugin->try_decode_func(&inStream)) + continue; + ret = plugin->stream_decode_func(&decoder, &inStream); + break; + } + + /* if that fails, try suffix matching the URL: */ + if (plugin == NULL) { + const char *s = getSuffix(path_max_utf8); + next = 0; + while (ret && (plugin = decoder_plugin_from_suffix(s, next++))) { + if (!plugin->stream_decode_func) + continue; + if (!(plugin->stream_types & + INPUT_PLUGIN_STREAM_URL)) + continue; + if (plugin->try_decode_func && + !plugin->try_decode_func(&inStream)) + continue; + decoder.plugin = plugin; + ret = plugin->stream_decode_func(&decoder, + &inStream); + break; + } + } + /* fallback to mp3: */ + /* this is needed for bastard streams that don't have a suffix + or set the mimeType */ + if (plugin == NULL) { + /* we already know our mp3Plugin supports streams, no + * need to check for stream{Types,DecodeFunc} */ + if ((plugin = decoder_plugin_from_name("mp3"))) { + decoder.plugin = plugin; + ret = plugin->stream_decode_func(&decoder, + &inStream); + } + } + } else { + unsigned int next = 0; + const char *s = getSuffix(path_max_utf8); + while (ret && (plugin = decoder_plugin_from_suffix(s, next++))) { + if (!plugin->stream_types & INPUT_PLUGIN_STREAM_FILE) + continue; + + if (plugin->try_decode_func && + !plugin->try_decode_func(&inStream)) + continue; + + if (plugin->file_decode_func) { + closeInputStream(&inStream); + close_instream = 0; + decoder.plugin = plugin; + ret = plugin->file_decode_func(&decoder, + path_max_fs); + break; + } else if (plugin->stream_decode_func) { + decoder.plugin = plugin; + ret = plugin->stream_decode_func(&decoder, + &inStream); + break; + } + } + } + + if (ret < 0 || ret == DECODE_ERROR_UNKTYPE) { + if (ret != DECODE_ERROR_UNKTYPE) + dc.error = DECODE_ERROR_FILE; + else + dc.error = DECODE_ERROR_UNKTYPE; + } + +stop: + if (close_instream) + closeInputStream(&inStream); +stop_no_close: + dc.state = DECODE_STATE_STOP; + dc.command = DECODE_COMMAND_NONE; +} + +static void * decoder_task(mpd_unused void *arg) +{ + notify_enter(&dc.notify); + + while (1) { + assert(dc.state == DECODE_STATE_STOP); + + if (dc.command == DECODE_COMMAND_START || + dc.command == DECODE_COMMAND_SEEK) { + decodeStart(); + } else if (dc.command == DECODE_COMMAND_STOP) { + dc.command = DECODE_COMMAND_NONE; + notify_signal(&pc.notify); + } else { + notify_wait(&dc.notify); + notify_signal(&pc.notify); + } + } + + return NULL; +} + +void decoderInit(void) +{ + pthread_attr_t attr; + pthread_t decoder_thread; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (pthread_create(&decoder_thread, &attr, decoder_task, NULL)) + FATAL("Failed to spawn decoder task: %s\n", strerror(errno)); +} diff --git a/src/decoder_thread.h b/src/decoder_thread.h new file mode 100644 index 000000000..439641e8a --- /dev/null +++ b/src/decoder_thread.h @@ -0,0 +1,25 @@ +/* the Music Player Daemon (MPD) + * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) + * Copyright (C) 2008 Max Kellermann + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DECODER_THREAD_H +#define DECODER_THREAD_H + +void decoderInit(void); + +#endif diff --git a/src/main.c b/src/main.c index 5a98b7e27..cfb38458d 100644 --- a/src/main.c +++ b/src/main.c @@ -25,7 +25,7 @@ #include "conf.h" #include "path.h" #include "playerData.h" -#include "decode.h" +#include "decoder_thread.h" #include "player.h" #include "stats.h" #include "sig_handlers.h" -- cgit v1.2.3