Update copyright notices.
[mpd-mk.git] / src / filter / autoconvert_filter_plugin.c
blob9e197a5f65e20b81f1684658b61308dc1174d28a
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 "filter/autoconvert_filter_plugin.h"
22 #include "filter/convert_filter_plugin.h"
23 #include "filter_plugin.h"
24 #include "filter_internal.h"
25 #include "filter_registry.h"
26 #include "conf.h"
27 #include "pcm_convert.h"
28 #include "audio_format.h"
29 #include "poison.h"
31 #include <assert.h>
32 #include <string.h>
34 struct autoconvert_filter {
35 struct filter base;
37 /**
38 * The audio format being fed to the underlying filter. This
39 * plugin actually doesn't need this variable, we have it here
40 * just so our open() method doesn't return a stack pointer.
42 struct audio_format in_audio_format;
44 /**
45 * The underlying filter.
47 struct filter *filter;
49 /**
50 * A convert_filter, just in case conversion is needed. NULL
51 * if unused.
53 struct filter *convert;
56 static void
57 autoconvert_filter_finish(struct filter *_filter)
59 struct autoconvert_filter *filter =
60 (struct autoconvert_filter *)_filter;
62 filter_free(filter->filter);
63 g_free(filter);
66 static const struct audio_format *
67 autoconvert_filter_open(struct filter *_filter,
68 struct audio_format *in_audio_format,
69 GError **error_r)
71 struct autoconvert_filter *filter =
72 (struct autoconvert_filter *)_filter;
73 const struct audio_format *out_audio_format;
75 assert(audio_format_valid(in_audio_format));
77 /* open the "real" filter */
79 filter->in_audio_format = *in_audio_format;
81 out_audio_format = filter_open(filter->filter,
82 &filter->in_audio_format, error_r);
83 if (out_audio_format == NULL)
84 return NULL;
86 /* need to convert? */
88 if (!audio_format_equals(&filter->in_audio_format, in_audio_format)) {
89 /* yes - create a convert_filter */
90 struct audio_format audio_format2 = *in_audio_format;
91 const struct audio_format *audio_format3;
93 filter->convert = filter_new(&convert_filter_plugin, NULL,
94 error_r);
95 if (filter->convert == NULL) {
96 filter_close(filter->filter);
97 return NULL;
100 audio_format3 = filter_open(filter->convert, &audio_format2,
101 error_r);
102 if (audio_format3 == NULL) {
103 filter_free(filter->convert);
104 filter_close(filter->filter);
105 return NULL;
108 assert(audio_format_equals(&audio_format2, in_audio_format));
110 convert_filter_set(filter->convert, &filter->in_audio_format);
111 } else
112 /* no */
113 filter->convert = NULL;
115 return out_audio_format;
118 static void
119 autoconvert_filter_close(struct filter *_filter)
121 struct autoconvert_filter *filter =
122 (struct autoconvert_filter *)_filter;
124 if (filter->convert != NULL) {
125 filter_close(filter->convert);
126 filter_free(filter->convert);
129 filter_close(filter->filter);
132 static const void *
133 autoconvert_filter_filter(struct filter *_filter, const void *src,
134 size_t src_size, size_t *dest_size_r,
135 GError **error_r)
137 struct autoconvert_filter *filter =
138 (struct autoconvert_filter *)_filter;
140 if (filter->convert != NULL) {
141 src = filter_filter(filter->convert, src, src_size, &src_size,
142 error_r);
143 if (src == NULL)
144 return NULL;
147 return filter_filter(filter->filter, src, src_size, dest_size_r,
148 error_r);
151 static const struct filter_plugin autoconvert_filter_plugin = {
152 .name = "convert",
153 .finish = autoconvert_filter_finish,
154 .open = autoconvert_filter_open,
155 .close = autoconvert_filter_close,
156 .filter = autoconvert_filter_filter,
159 struct filter *
160 autoconvert_filter_new(struct filter *_filter)
162 struct autoconvert_filter *filter =
163 g_new(struct autoconvert_filter, 1);
165 filter_init(&filter->base, &autoconvert_filter_plugin);
166 filter->filter = _filter;
168 return &filter->base;