decoder_control.h 7.45 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright (C) 2003-2011 The Music Player Daemon Project
3
 * http://www.musicpd.org
Warren Dukes's avatar
Warren Dukes committed
4 5 6 7 8 9 10 11 12 13
 *
 * 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.
14 15 16 17
 *
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Warren Dukes's avatar
Warren Dukes committed
18 19
 */

20 21
#ifndef MPD_DECODER_CONTROL_H
#define MPD_DECODER_CONTROL_H
Warren Dukes's avatar
Warren Dukes committed
22

23
#include "decoder_command.h"
24
#include "audio_format.h"
25 26

#include <glib.h>
Warren Dukes's avatar
Warren Dukes committed
27

28 29
#include <assert.h>

30 31 32
enum decoder_state {
	DECODE_STATE_STOP = 0,
	DECODE_STATE_START,
33 34 35 36 37 38 39 40 41
	DECODE_STATE_DECODE,

	/**
	 * The last "START" command failed, because there was an I/O
	 * error or because no decoder was able to decode the file.
	 * This state will only come after START; once the state has
	 * turned to DECODE, by definition no such error can occur.
	 */
	DECODE_STATE_ERROR,
42
};
43

44
struct decoder_control {
45 46 47 48
	/** the handle of the decoder thread, or NULL if the decoder
	    thread isn't running */
	GThread *thread;

49 50 51 52 53 54 55 56 57 58 59 60
	/**
	 * This lock protects #state and #command.
	 */
	GMutex *mutex;

	/**
	 * Trigger this object after you have modified #command.  This
	 * is also used by the decoder thread to notify the caller
	 * when it has finished a command.
	 */
	GCond *cond;

61 62 63 64 65 66
	/**
	 * The trigger of this object's client.  It is signalled
	 * whenever an event occurs.
	 */
	GCond *client_cond;

67 68
	enum decoder_state state;
	enum decoder_command command;
69

70 71 72 73 74 75 76 77
	/**
	 * The error that occurred in the decoder thread.  This
	 * attribute is only valid if #state is #DECODE_STATE_ERROR.
	 * The object must be freed when this object transitions to
	 * any other state (usually #DECODE_STATE_START).
	 */
	GError *error;

78
	bool quit;
Max Kellermann's avatar
Max Kellermann committed
79
	bool seek_error;
80
	bool seekable;
81
	double seek_where;
82 83 84 85 86 87 88

	/** the format of the song file */
	struct audio_format in_audio_format;

	/** the format being sent to the music pipe */
	struct audio_format out_audio_format;

89 90 91 92
	/**
	 * The song currently being decoded.  This attribute is set by
	 * the player thread, when it sends the #DECODE_COMMAND_START
	 * command.
93 94 95
	 *
	 * This is a duplicate, and must be freed when this attribute
	 * is cleared.
96
	 */
97
	struct song *song;
98

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
	/**
	 * The initial seek position (in milliseconds), e.g. to the
	 * start of a sub-track described by a CUE file.
	 *
	 * This attribute is set by dc_start().
	 */
	unsigned start_ms;

	/**
	 * The decoder will stop when it reaches this position (in
	 * milliseconds).  0 means don't stop before the end of the
	 * file.
	 *
	 * This attribute is set by dc_start().
	 */
	unsigned end_ms;

116
	float total_time;
117 118 119 120

	/** the #music_chunk allocator */
	struct music_buffer *buffer;

121 122 123 124
	/**
	 * The destination pipe for decoded chunks.  The caller thread
	 * owns this object, and is responsible for freeing it.
	 */
125
	struct music_pipe *pipe;
126

127 128
	float replay_gain_db;
	float replay_gain_prev_db;
129 130 131
	char *mixramp_start;
	char *mixramp_end;
	char *mixramp_prev_end;
132 133
};

134 135
G_GNUC_MALLOC
struct decoder_control *
136
dc_new(GCond *client_cond);
137

138
void
139
dc_free(struct decoder_control *dc);
140

141 142 143 144
/**
 * Locks the #decoder_control object.
 */
static inline void
145
decoder_lock(struct decoder_control *dc)
146
{
147
	g_mutex_lock(dc->mutex);
148 149 150 151 152 153
}

/**
 * Unlocks the #decoder_control object.
 */
static inline void
154
decoder_unlock(struct decoder_control *dc)
155
{
156
	g_mutex_unlock(dc->mutex);
157 158 159 160 161 162 163 164
}

/**
 * Waits for a signal on the #decoder_control object.  This function
 * is only valid in the decoder thread.  The object must be locked
 * prior to calling this function.
 */
static inline void
165
decoder_wait(struct decoder_control *dc)
166
{
167
	g_cond_wait(dc->cond, dc->mutex);
168 169 170 171 172 173 174 175
}

/**
 * Signals the #decoder_control object.  This function is only valid
 * in the player thread.  The object should be locked prior to calling
 * this function.
 */
static inline void
176
decoder_signal(struct decoder_control *dc)
177
{
178
	g_cond_signal(dc->cond);
179 180
}

181 182
static inline bool
decoder_is_idle(const struct decoder_control *dc)
183
{
184 185
	return dc->state == DECODE_STATE_STOP ||
		dc->state == DECODE_STATE_ERROR;
186 187
}

188 189
static inline bool
decoder_is_starting(const struct decoder_control *dc)
190
{
191
	return dc->state == DECODE_STATE_START;
192 193
}

194 195
static inline bool
decoder_has_failed(const struct decoder_control *dc)
196
{
197
	assert(dc->command == DECODE_COMMAND_NONE);
198

199
	return dc->state == DECODE_STATE_ERROR;
200 201
}

202 203 204 205 206 207 208 209 210 211 212
/**
 * Checks whether an error has occurred, and if so, returns a newly
 * allocated copy of the #GError object.
 *
 * Caller must lock the object.
 */
static inline GError *
dc_get_error(const struct decoder_control *dc)
{
	assert(dc != NULL);
	assert(dc->command == DECODE_COMMAND_NONE);
213
	assert(dc->state != DECODE_STATE_ERROR || dc->error != NULL);
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245

	return dc->state == DECODE_STATE_ERROR
		? g_error_copy(dc->error)
		: NULL;
}

/**
 * Like dc_get_error(), but locks and unlocks the object.
 */
static inline GError *
dc_lock_get_error(struct decoder_control *dc)
{
	decoder_lock(dc);
	GError *error = dc_get_error(dc);
	decoder_unlock(dc);
	return error;
}

/**
 * Clear the error condition and free the #GError object (if any).
 *
 * Caller must lock the object.
 */
static inline void
dc_clear_error(struct decoder_control *dc)
{
	if (dc->state == DECODE_STATE_ERROR) {
		g_error_free(dc->error);
		dc->state = DECODE_STATE_STOP;
	}
}

246 247
static inline bool
decoder_lock_is_idle(struct decoder_control *dc)
248 249 250
{
	bool ret;

251 252 253
	decoder_lock(dc);
	ret = decoder_is_idle(dc);
	decoder_unlock(dc);
254 255 256 257

	return ret;
}

258 259
static inline bool
decoder_lock_is_starting(struct decoder_control *dc)
260 261 262
{
	bool ret;

263 264 265
	decoder_lock(dc);
	ret = decoder_is_starting(dc);
	decoder_unlock(dc);
266 267 268 269

	return ret;
}

270 271
static inline bool
decoder_lock_has_failed(struct decoder_control *dc)
272 273 274
{
	bool ret;

275 276 277
	decoder_lock(dc);
	ret = decoder_has_failed(dc);
	decoder_unlock(dc);
278 279 280 281

	return ret;
}

282 283 284 285 286 287 288 289 290 291 292
/**
 * Check if the specified song is currently being decoded.  If the
 * decoder is not running currently (or being started), then this
 * function returns false in any case.
 *
 * Caller must lock the object.
 */
gcc_pure
bool
decoder_is_current_song(const struct decoder_control *dc,
			const struct song *song);
293

294 295 296 297 298 299 300 301 302
gcc_pure
static inline bool
decoder_lock_is_current_song(struct decoder_control *dc,
			     const struct song *song)
{
	decoder_lock(dc);
	const bool result = decoder_is_current_song(dc, song);
	decoder_unlock(dc);
	return result;
303 304
}

305 306 307 308
/**
 * Start the decoder.
 *
 * @param the decoder
309 310
 * @param song the song to be decoded; the given instance will be
 * owned and freed by the decoder
311 312
 * @param start_ms see #decoder_control
 * @param end_ms see #decoder_control
313 314 315
 * @param pipe the pipe which receives the decoded chunks (owned by
 * the caller)
 */
316
void
317
dc_start(struct decoder_control *dc, struct song *song,
318
	 unsigned start_ms, unsigned end_ms,
319
	 struct music_buffer *buffer, struct music_pipe *pipe);
Max Kellermann's avatar
Max Kellermann committed
320

321
void
322
dc_stop(struct decoder_control *dc);
Max Kellermann's avatar
Max Kellermann committed
323

324
bool
325
dc_seek(struct decoder_control *dc, double where);
Max Kellermann's avatar
Max Kellermann committed
326

327
void
328
dc_quit(struct decoder_control *dc);
329

330 331 332 333 334 335 336 337 338
void
dc_mixramp_start(struct decoder_control *dc, char *mixramp_start);

void
dc_mixramp_end(struct decoder_control *dc, char *mixramp_end);

void
dc_mixramp_prev_end(struct decoder_control *dc, char *mixramp_prev_end);

Warren Dukes's avatar
Warren Dukes committed
339
#endif