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.
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"
27 #include "pcm_convert.h"
28 #include "audio_format.h"
34 struct autoconvert_filter
{
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
;
45 * The underlying filter.
47 struct filter
*filter
;
50 * A convert_filter, just in case conversion is needed. NULL
53 struct filter
*convert
;
57 autoconvert_filter_finish(struct filter
*_filter
)
59 struct autoconvert_filter
*filter
=
60 (struct autoconvert_filter
*)_filter
;
62 filter_free(filter
->filter
);
66 static const struct audio_format
*
67 autoconvert_filter_open(struct filter
*_filter
,
68 struct audio_format
*in_audio_format
,
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
)
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
,
95 if (filter
->convert
== NULL
) {
96 filter_close(filter
->filter
);
100 audio_format3
= filter_open(filter
->convert
, &audio_format2
,
102 if (audio_format3
== NULL
) {
103 filter_free(filter
->convert
);
104 filter_close(filter
->filter
);
108 assert(audio_format_equals(&audio_format2
, in_audio_format
));
110 convert_filter_set(filter
->convert
, &filter
->in_audio_format
);
113 filter
->convert
= NULL
;
115 return out_audio_format
;
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
);
133 autoconvert_filter_filter(struct filter
*_filter
, const void *src
,
134 size_t src_size
, size_t *dest_size_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
,
147 return filter_filter(filter
->filter
, src
, src_size
, dest_size_r
,
151 static const struct filter_plugin autoconvert_filter_plugin
= {
153 .finish
= autoconvert_filter_finish
,
154 .open
= autoconvert_filter_open
,
155 .close
= autoconvert_filter_close
,
156 .filter
= autoconvert_filter_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
;