summaryrefslogtreecommitdiffstats
path: root/src/pulsecore/source.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pulsecore/source.c')
-rw-r--r--src/pulsecore/source.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 15a5b8d9..587291ad 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -32,6 +32,7 @@
#include <pulse/xmalloc.h>
#include <pulse/timeval.h>
#include <pulse/util.h>
+#include <pulse/internal.h>
#include <pulsecore/core-util.h>
#include <pulsecore/source-output.h>
@@ -130,6 +131,7 @@ static void reset_callbacks(pa_source *s) {
s->set_mute = NULL;
s->update_requested_latency = NULL;
s->set_port = NULL;
+ s->get_formats = NULL;
}
/* Called from main context */
@@ -754,6 +756,15 @@ pa_usec_t pa_source_get_latency_within_thread(pa_source *s) {
return usec;
}
+/* Called from main context */
+pa_bool_t pa_source_is_passthrough(pa_source *s) {
+
+ pa_source_assert_ref(s);
+
+ /* NB Currently only monitor sources support passthrough mode */
+ return (s->monitor_of && pa_sink_is_passthrough(s->monitor_of));
+}
+
/* Called from main thread */
void pa_source_set_volume(
pa_source *s,
@@ -1575,3 +1586,84 @@ int pa_source_set_port(pa_source *s, const char *name, pa_bool_t save) {
return 0;
}
+
+/* Called from the main thread */
+/* Gets the list of formats supported by the source. The members and idxset must
+ * be freed by the caller. */
+pa_idxset* pa_source_get_formats(pa_source *s) {
+ pa_idxset *ret;
+
+ pa_assert(s);
+
+ if (s->get_formats) {
+ /* Source supports format query, all is good */
+ ret = s->get_formats(s);
+ } else {
+ /* Source doesn't support format query, so assume it does PCM */
+ pa_format_info *f = pa_format_info_new();
+ f->encoding = PA_ENCODING_PCM;
+
+ ret = pa_idxset_new(NULL, NULL);
+ pa_idxset_put(ret, f, NULL);
+ }
+
+ return ret;
+}
+
+/* Called from the main thread */
+/* Checks if the source can accept this format */
+pa_bool_t pa_source_check_format(pa_source *s, pa_format_info *f)
+{
+ pa_idxset *formats = NULL;
+ pa_bool_t ret = FALSE;
+
+ pa_assert(s);
+ pa_assert(f);
+
+ formats = pa_source_get_formats(s);
+
+ if (formats) {
+ pa_format_info *finfo_device;
+ uint32_t i;
+
+ PA_IDXSET_FOREACH(finfo_device, formats, i) {
+ if (pa_format_info_is_compatible(finfo_device, f)) {
+ ret = TRUE;
+ break;
+ }
+ }
+
+ pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+ }
+
+ return ret;
+}
+
+/* Called from the main thread */
+/* Calculates the intersection between formats supported by the source and
+ * in_formats, and returns these, in the order of the source's formats. */
+pa_idxset* pa_source_check_formats(pa_source *s, pa_idxset *in_formats) {
+ pa_idxset *out_formats = pa_idxset_new(NULL, NULL), *source_formats = NULL;
+ pa_format_info *f_source, *f_in;
+ uint32_t i, j;
+
+ pa_assert(s);
+
+ if (!in_formats || pa_idxset_isempty(in_formats))
+ goto done;
+
+ source_formats = pa_source_get_formats(s);
+
+ PA_IDXSET_FOREACH(f_source, source_formats, i) {
+ PA_IDXSET_FOREACH(f_in, in_formats, j) {
+ if (pa_format_info_is_compatible(f_source, f_in))
+ pa_idxset_put(out_formats, pa_format_info_copy(f_in), NULL);
+ }
+ }
+
+done:
+ if (source_formats)
+ pa_idxset_free(source_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+
+ return out_formats;
+}