Browse Source

pipewire: add pass-through support

pull/172/head
Ayush Dey 2 years ago
committed by Steve Lhomme
parent
commit
ff7ddd8bb6
  1. 99
      modules/audio_output/pipewire.c

99
modules/audio_output/pipewire.c

@ -446,6 +446,8 @@ static struct vlc_pw_stream *vlc_pw_stream_create(audio_output_t *aout,
.channels = fmt->i_channels,
};
enum spa_audio_iec958_codec encoding = SPA_AUDIO_IEC958_CODEC_PCM; /* PCM by default */
/* Map possible audio output formats */
switch (fmt->i_format) {
case VLC_CODEC_FL64:
@ -464,11 +466,29 @@ static struct vlc_pw_stream *vlc_pw_stream_create(audio_output_t *aout,
rawfmt.format = SPA_AUDIO_FORMAT_U8;
break;
case VLC_CODEC_A52:
fmt->i_format = VLC_CODEC_SPDIFL;
fmt->i_bytes_per_frame = 4;
fmt->i_frame_length = 1;
fmt->i_physical_channels = AOUT_CHANS_2_0;
fmt->i_channels = 2;
encoding = SPA_AUDIO_IEC958_CODEC_AC3;
break;
case VLC_CODEC_EAC3:
fmt->i_format = VLC_CODEC_SPDIFL;
fmt->i_bytes_per_frame = 4;
fmt->i_frame_length = 1;
fmt->i_physical_channels = AOUT_CHANS_2_0;
fmt->i_channels = 2;
encoding = SPA_AUDIO_IEC958_CODEC_EAC3;
break;
case VLC_CODEC_DTS:
/* TODO: pass-through */
errno = ENOTSUP;
return NULL;
fmt->i_format = VLC_CODEC_SPDIFL;
fmt->i_bytes_per_frame = 4;
fmt->i_frame_length = 1;
fmt->i_physical_channels = AOUT_CHANS_2_0;
fmt->i_channels = 2;
encoding = SPA_AUDIO_IEC958_CODEC_DTS;
break;
default:
vlc_pw_error(sys->context, "unknown format");
errno = ENOTSUP;
@ -476,37 +496,40 @@ static struct vlc_pw_stream *vlc_pw_stream_create(audio_output_t *aout,
}
/* Map audio channels */
size_t mapped = 0;
if (encoding == SPA_AUDIO_IEC958_CODEC_PCM)
{
size_t mapped = 0;
if (fmt->i_channels > SPA_AUDIO_MAX_CHANNELS) {
vlc_pw_error(sys->context, "too many channels");
errno = ENOTSUP;
return NULL;
}
if (fmt->i_channels > SPA_AUDIO_MAX_CHANNELS) {
vlc_pw_error(sys->context, "too many channels");
errno = ENOTSUP;
return NULL;
}
static const unsigned char map[] = {
SPA_AUDIO_CHANNEL_FC,
SPA_AUDIO_CHANNEL_FL,
SPA_AUDIO_CHANNEL_FR,
0 /* unassigned */,
SPA_AUDIO_CHANNEL_RC,
SPA_AUDIO_CHANNEL_RL,
SPA_AUDIO_CHANNEL_RR,
0 /* unassigned */,
SPA_AUDIO_CHANNEL_SL,
SPA_AUDIO_CHANNEL_SR,
0 /* unassigned */,
0 /* unassigned */,
SPA_AUDIO_CHANNEL_LFE,
};
static const unsigned char map[] = {
SPA_AUDIO_CHANNEL_FC,
SPA_AUDIO_CHANNEL_FL,
SPA_AUDIO_CHANNEL_FR,
0 /* unassigned */,
SPA_AUDIO_CHANNEL_RC,
SPA_AUDIO_CHANNEL_RL,
SPA_AUDIO_CHANNEL_RR,
0 /* unassigned */,
SPA_AUDIO_CHANNEL_SL,
SPA_AUDIO_CHANNEL_SR,
0 /* unassigned */,
0 /* unassigned */,
SPA_AUDIO_CHANNEL_LFE,
};
for (size_t i = 0; i < ARRAY_SIZE(map); i++)
if ((fmt->i_physical_channels >> i) & 1)
rawfmt.position[mapped++] = map[i];
for (size_t i = 0; i < ARRAY_SIZE(map); i++)
if ((fmt->i_physical_channels >> i) & 1)
rawfmt.position[mapped++] = map[i];
while (mapped < fmt->i_channels) {
rawfmt.position[mapped] = SPA_AUDIO_CHANNEL_START_Aux + mapped;
mapped++;
while (mapped < fmt->i_channels) {
rawfmt.position[mapped] = SPA_AUDIO_CHANNEL_START_Aux + mapped;
mapped++;
}
}
/* Assemble the stream format */
@ -514,8 +537,20 @@ static struct vlc_pw_stream *vlc_pw_stream_create(audio_output_t *aout,
unsigned char buf[1024];
struct spa_pod_builder builder = SPA_POD_BUILDER_INIT(buf, sizeof (buf));
params[0] = spa_format_audio_raw_build(&builder, SPA_PARAM_EnumFormat,
&rawfmt);
if (encoding == SPA_AUDIO_IEC958_CODEC_PCM)
{
params[0] = spa_format_audio_raw_build(&builder, SPA_PARAM_EnumFormat,
&rawfmt);
}
else /* pass-through */
{
struct spa_audio_info_iec958 iecfmt = {
.rate = fmt->i_rate,
.codec = encoding
};
params[0] = spa_format_audio_iec958_build(&builder, SPA_PARAM_EnumFormat,
&iecfmt);
}
/* Assemble stream properties */
struct pw_properties *props;

Loading…
Cancel
Save