configure.ac: Move the encoders before the audio outputs.
[mpd-mk.git] / src / pipe.c
blob7e4b0d081fb9d8ac57c7c7d49b91dd19e22e0770
1 /*
2 * Copyright (C) 2003-2010 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "config.h"
21 #include "pipe.h"
22 #include "buffer.h"
23 #include "chunk.h"
25 #include <glib.h>
27 #include <assert.h>
29 struct music_pipe {
30 /** the first chunk */
31 struct music_chunk *head;
33 /** a pointer to the tail of the chunk */
34 struct music_chunk **tail_r;
36 /** the current number of chunks */
37 unsigned size;
39 /** a mutex which protects #head and #tail_r */
40 GMutex *mutex;
42 #ifndef NDEBUG
43 struct audio_format audio_format;
44 #endif
47 struct music_pipe *
48 music_pipe_new(void)
50 struct music_pipe *mp = g_new(struct music_pipe, 1);
52 mp->head = NULL;
53 mp->tail_r = &mp->head;
54 mp->size = 0;
55 mp->mutex = g_mutex_new();
57 #ifndef NDEBUG
58 audio_format_clear(&mp->audio_format);
59 #endif
61 return mp;
64 void
65 music_pipe_free(struct music_pipe *mp)
67 assert(mp->head == NULL);
68 assert(mp->tail_r == &mp->head);
70 g_mutex_free(mp->mutex);
71 g_free(mp);
74 #ifndef NDEBUG
76 bool
77 music_pipe_check_format(const struct music_pipe *pipe,
78 const struct audio_format *audio_format)
80 assert(pipe != NULL);
81 assert(audio_format != NULL);
83 return !audio_format_defined(&pipe->audio_format) ||
84 audio_format_equals(&pipe->audio_format, audio_format);
87 bool
88 music_pipe_contains(const struct music_pipe *mp,
89 const struct music_chunk *chunk)
91 g_mutex_lock(mp->mutex);
93 for (const struct music_chunk *i = mp->head;
94 i != NULL; i = i->next) {
95 if (i == chunk) {
96 g_mutex_unlock(mp->mutex);
97 return true;
101 g_mutex_unlock(mp->mutex);
103 return false;
106 #endif
108 const struct music_chunk *
109 music_pipe_peek(const struct music_pipe *mp)
111 return mp->head;
114 struct music_chunk *
115 music_pipe_shift(struct music_pipe *mp)
117 struct music_chunk *chunk;
119 g_mutex_lock(mp->mutex);
121 chunk = mp->head;
122 if (chunk != NULL) {
123 assert(!music_chunk_is_empty(chunk));
125 mp->head = chunk->next;
126 --mp->size;
128 if (mp->head == NULL) {
129 assert(mp->size == 0);
130 assert(mp->tail_r == &chunk->next);
132 mp->tail_r = &mp->head;
133 } else {
134 assert(mp->size > 0);
135 assert(mp->tail_r != &chunk->next);
138 #ifndef NDEBUG
139 /* poison the "next" reference */
140 chunk->next = (void*)0x01010101;
142 if (mp->size == 0)
143 audio_format_clear(&mp->audio_format);
144 #endif
147 g_mutex_unlock(mp->mutex);
149 return chunk;
152 void
153 music_pipe_clear(struct music_pipe *mp, struct music_buffer *buffer)
155 struct music_chunk *chunk;
157 while ((chunk = music_pipe_shift(mp)) != NULL)
158 music_buffer_return(buffer, chunk);
161 void
162 music_pipe_push(struct music_pipe *mp, struct music_chunk *chunk)
164 assert(!music_chunk_is_empty(chunk));
165 assert(chunk->length == 0 || audio_format_valid(&chunk->audio_format));
167 g_mutex_lock(mp->mutex);
169 assert(mp->size > 0 || !audio_format_defined(&mp->audio_format));
170 assert(!audio_format_defined(&mp->audio_format) ||
171 music_chunk_check_format(chunk, &mp->audio_format));
173 #ifndef NDEBUG
174 if (!audio_format_defined(&mp->audio_format) && chunk->length > 0)
175 mp->audio_format = chunk->audio_format;
176 #endif
178 chunk->next = NULL;
179 *mp->tail_r = chunk;
180 mp->tail_r = &chunk->next;
182 ++mp->size;
184 g_mutex_unlock(mp->mutex);
187 unsigned
188 music_pipe_size(const struct music_pipe *mp)
190 return mp->size;