void pa_transcode_init(pa_transcode *transcode, pa_encoding_t encoding, pa_transcode_flags_t flags, pa_format_info *transcode_format_info, pa_sample_spec *transcode_sink_spec) { pa_assert((flags & PA_TRANSCODE_DECODER) || (flags & PA_TRANSCODE_ENCODER)); transcode->flags = flags; transcode->encoding = encoding; switch(encoding) { #ifdef HAVE_OPUS case PA_ENCODING_OPUS: transcode->sample_size = OPUS_DEFAULT_SAMPLE_SIZE; if(flags & PA_TRANSCODE_DECODER) { if(pa_format_info_get_prop_int(transcode_format_info, "max_frame_size", (int *)&transcode->max_frame_size) != 0) transcode->max_frame_size = OPUS_DEFAULT_FRAME_SIZE; if(pa_format_info_get_prop_int(transcode_format_info, "frame_size", (int *)&transcode->frame_size) != 0) transcode->frame_size = OPUS_DEFAULT_FRAME_SIZE; if(pa_format_info_get_prop_int(transcode_format_info, "bitrate", (int *)&transcode->bitrate) != 0) transcode->bitrate = OPUS_DEFAULT_BITRATE; pa_format_info_get_rate(transcode_format_info, &transcode->rate); pa_format_info_get_channels(transcode_format_info, &transcode->channels); transcode->decoder = tc_opus_create_decoder(transcode->rate, transcode->channels); } else { if(transcode->bitrate == 0) transcode->bitrate = OPUS_DEFAULT_BITRATE; if(transcode->frame_size == 0) transcode->frame_size = OPUS_DEFAULT_FRAME_SIZE; transcode->channels = transcode_sink_spec->channels; transcode->rate = OPUS_DEFAULT_SAMPLE_RATE; transcode->encoder = tc_opus_create_encoder(transcode->rate, transcode->channels, transcode->bitrate); transcode_sink_spec->rate = transcode->rate; transcode_sink_spec->format = PA_SAMPLE_S16LE; } break; #endif default: transcode->decoder = NULL; transcode->encoder = NULL; } }
/* For PCM streams */ int pa_format_info_to_sample_spec(pa_format_info *f, pa_sample_spec *ss, pa_channel_map *map) { char *sf = NULL, *m = NULL; int rate, channels; int ret = -PA_ERR_INVALID; pa_assert(f); pa_assert(ss); if (!pa_format_info_is_pcm(f)) return pa_format_info_to_sample_spec_fake(f, ss); if (pa_format_info_get_prop_string(f, PA_PROP_FORMAT_SAMPLE_FORMAT, &sf)) goto out; if (pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate)) goto out; if (pa_format_info_get_prop_int(f, PA_PROP_FORMAT_CHANNELS, &channels)) goto out; if ((ss->format = pa_parse_sample_format(sf)) == PA_SAMPLE_INVALID) goto out; ss->rate = (uint32_t) rate; ss->channels = (uint8_t) channels; if (map) { pa_channel_map_init(map); if (pa_format_info_get_prop_string(f, PA_PROP_FORMAT_CHANNEL_MAP, &m) == 0) if (pa_channel_map_parse(map, m) == NULL) goto out; } ret = 0; out: if (sf) pa_xfree(sf); if (m) pa_xfree(m); return ret; }
/* For PCM streams */ pa_bool_t pa_format_info_to_sample_spec(pa_format_info *f, pa_sample_spec *ss, pa_channel_map *map) { char *sf = NULL, *m = NULL; int rate, channels; pa_bool_t ret = FALSE; pa_assert(f); pa_assert(ss); pa_return_val_if_fail(f->encoding == PA_ENCODING_PCM, FALSE); if (!pa_format_info_get_prop_string(f, PA_PROP_FORMAT_SAMPLE_FORMAT, &sf)) goto out; if (!pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate)) goto out; if (!pa_format_info_get_prop_int(f, PA_PROP_FORMAT_CHANNELS, &channels)) goto out; if ((ss->format = pa_parse_sample_format(sf)) == PA_SAMPLE_INVALID) goto out; ss->rate = (uint32_t) rate; ss->channels = (uint8_t) channels; if (map) { pa_channel_map_init(map); if (pa_format_info_get_prop_string(f, PA_PROP_FORMAT_CHANNEL_MAP, &m)) if (pa_channel_map_parse(map, m) == NULL) goto out; } ret = TRUE; out: if (sf) pa_xfree(sf); if (m) pa_xfree(m); return ret; }
/* For compressed streams */ pa_bool_t pa_format_info_to_sample_spec_fake(pa_format_info *f, pa_sample_spec *ss) { int rate; pa_assert(f); pa_assert(ss); pa_return_val_if_fail(f->encoding != PA_ENCODING_PCM, FALSE); ss->format = PA_SAMPLE_S16LE; ss->channels = 2; pa_return_val_if_fail(pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate), FALSE); ss->rate = (uint32_t) rate; if (f->encoding == PA_ENCODING_EAC3_IEC61937) ss->rate *= 4; return TRUE; }
/* For compressed streams */ static int pa_format_info_to_sample_spec_fake(pa_format_info *f, pa_sample_spec *ss) { int rate; pa_assert(f); pa_assert(ss); /* Note: When we add support for non-IEC61937 encapsulated compressed * formats, this function should return a non-zero values for these. */ ss->format = PA_SAMPLE_S16LE; ss->channels = 2; pa_return_val_if_fail(pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate) == 0, -PA_ERR_INVALID); ss->rate = (uint32_t) rate; if (f->encoding == PA_ENCODING_EAC3_IEC61937) ss->rate *= 4; return 0; }