mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
Fix up audio formats as well
This commit is contained in:
parent
b67c216a04
commit
a973007a49
12 changed files with 82 additions and 58 deletions
|
|
@ -453,16 +453,16 @@ gst_caps_from_format (SpaFormat *format)
|
|||
NULL);
|
||||
}
|
||||
} else if (format->media_type == SPA_MEDIA_TYPE_AUDIO) {
|
||||
SpaFormatAudio f;
|
||||
|
||||
spa_format_audio_parse (format, &f);
|
||||
|
||||
if (format->media_subtype == SPA_MEDIA_SUBTYPE_RAW) {
|
||||
SpaAudioRawFormat f;
|
||||
|
||||
spa_audio_raw_format_parse (format, &f);
|
||||
|
||||
res = gst_caps_new_simple ("audio/x-raw",
|
||||
"format", G_TYPE_STRING, gst_audio_format_to_string (f.info.format),
|
||||
"format", G_TYPE_STRING, gst_audio_format_to_string (f.info.raw.format),
|
||||
"layout", G_TYPE_STRING, "interleaved",
|
||||
"rate", G_TYPE_INT, f.info.rate,
|
||||
"channels", G_TYPE_INT, f.info.channels,
|
||||
"rate", G_TYPE_INT, f.info.raw.rate,
|
||||
"channels", G_TYPE_INT, f.info.raw.channels,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ extern "C" {
|
|||
#include <spa/format.h>
|
||||
#include <spa/audio/raw.h>
|
||||
|
||||
typedef struct _SpaAudioRawFormat SpaAudioRawFormat;
|
||||
typedef struct _SpaFormatAudio SpaFormatAudio;
|
||||
|
||||
typedef enum {
|
||||
SPA_PROP_ID_AUDIO_FORMAT = SPA_PROP_ID_MEDIA_CUSTOM_START,
|
||||
|
|
@ -43,14 +43,18 @@ SpaResult spa_prop_info_fill_audio (SpaPropInfo *info,
|
|||
SpaPropIdAudio id,
|
||||
size_t offset);
|
||||
|
||||
struct _SpaAudioRawFormat {
|
||||
struct _SpaFormatAudio {
|
||||
SpaFormat format;
|
||||
SpaAudioRawInfo info;
|
||||
union {
|
||||
SpaAudioInfoRaw raw;
|
||||
} info;
|
||||
};
|
||||
|
||||
SpaResult spa_audio_raw_format_init (SpaAudioRawFormat *format);
|
||||
SpaResult spa_audio_raw_format_parse (const SpaFormat *format,
|
||||
SpaAudioRawFormat *rawformat);
|
||||
SpaResult spa_format_audio_init (SpaMediaType type,
|
||||
SpaMediaSubType subtype,
|
||||
SpaFormatAudio *format);
|
||||
SpaResult spa_format_audio_parse (const SpaFormat *format,
|
||||
SpaFormatAudio *aformat);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _SpaAudioRawInfo SpaAudioRawInfo;
|
||||
typedef struct _SpaAudioInfoRaw SpaAudioInfoRaw;
|
||||
|
||||
#include <endian.h>
|
||||
|
||||
|
|
@ -121,7 +121,7 @@ typedef enum {
|
|||
} SpaAudioLayout;
|
||||
|
||||
/**
|
||||
* SpaAudioRawInfo:
|
||||
* SpaAudioInfoRaw:
|
||||
* @format: the format
|
||||
* @flags: extra flags
|
||||
* @layout: the sample layout
|
||||
|
|
@ -129,7 +129,7 @@ typedef enum {
|
|||
* @channels: the number of channels
|
||||
* @channel_mask: the channel mask
|
||||
*/
|
||||
struct _SpaAudioRawInfo {
|
||||
struct _SpaAudioInfoRaw {
|
||||
SpaAudioFormat format;
|
||||
SpaAudioFlags flags;
|
||||
SpaAudioLayout layout;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ typedef enum {
|
|||
SPA_MEDIA_SUBTYPE_VP9 = 13,
|
||||
SPA_MEDIA_SUBTYPE_JPEG = 14,
|
||||
SPA_MEDIA_SUBTYPE_BAYER = 15,
|
||||
SPA_MEDIA_SUBTYPE_MP3 = 16,
|
||||
SPA_MEDIA_SUBTYPE_AAC = 17,
|
||||
} SpaMediaSubType;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include <spa/audio/raw.h>
|
||||
#include <spa/audio/format.h>
|
||||
|
||||
static const SpaAudioRawInfo default_info = {
|
||||
static const SpaAudioInfoRaw default_raw_info = {
|
||||
SPA_AUDIO_FORMAT_S16,
|
||||
SPA_AUDIO_FLAG_NONE,
|
||||
SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
|
|
@ -174,9 +174,9 @@ static const SpaPropInfo format_prop_info[] =
|
|||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_AUDIO_RAW_INFO, 0,
|
||||
"info", "the SpaAudioRawInfo structure",
|
||||
"info", "the SpaAudioInfoRaw structure",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_POINTER, sizeof (SpaAudioRawInfo),
|
||||
SPA_PROP_TYPE_POINTER, sizeof (SpaAudioInfoRaw),
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL },
|
||||
};
|
||||
|
|
@ -202,17 +202,19 @@ spa_prop_info_fill_audio (SpaPropInfo *info,
|
|||
}
|
||||
|
||||
SpaResult
|
||||
spa_audio_raw_format_init (SpaAudioRawFormat *format)
|
||||
spa_format_audio_init (SpaMediaType type,
|
||||
SpaMediaSubType subtype,
|
||||
SpaFormatAudio *format)
|
||||
{
|
||||
static SpaPropInfo raw_format_prop_info[] =
|
||||
{
|
||||
{ SPA_PROP_ID_AUDIO_FORMAT, offsetof (SpaAudioRawFormat, info.format), },
|
||||
{ SPA_PROP_ID_AUDIO_FLAGS, offsetof (SpaAudioRawFormat, info.flags), },
|
||||
{ SPA_PROP_ID_AUDIO_LAYOUT, offsetof (SpaAudioRawFormat, info.layout), },
|
||||
{ SPA_PROP_ID_AUDIO_RATE, offsetof (SpaAudioRawFormat, info.rate), },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNELS, offsetof (SpaAudioRawFormat, info.channels), },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNEL_MASK, offsetof (SpaAudioRawFormat, info.channel_mask), },
|
||||
{ SPA_PROP_ID_AUDIO_RAW_INFO, offsetof (SpaAudioRawFormat, info), },
|
||||
{ SPA_PROP_ID_AUDIO_FORMAT, offsetof (SpaFormatAudio, info.raw.format), },
|
||||
{ SPA_PROP_ID_AUDIO_FLAGS, offsetof (SpaFormatAudio, info.raw.flags), },
|
||||
{ SPA_PROP_ID_AUDIO_LAYOUT, offsetof (SpaFormatAudio, info.raw.layout), },
|
||||
{ SPA_PROP_ID_AUDIO_RATE, offsetof (SpaFormatAudio, info.raw.rate), },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNELS, offsetof (SpaFormatAudio, info.raw.channels), },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNEL_MASK, offsetof (SpaFormatAudio, info.raw.channel_mask), },
|
||||
{ SPA_PROP_ID_AUDIO_RAW_INFO, offsetof (SpaFormatAudio, info), },
|
||||
};
|
||||
|
||||
if (raw_format_prop_info[0].name == NULL) {
|
||||
|
|
@ -224,46 +226,47 @@ spa_audio_raw_format_init (SpaAudioRawFormat *format)
|
|||
raw_format_prop_info[i].offset);
|
||||
}
|
||||
|
||||
format->format.media_type = SPA_MEDIA_TYPE_AUDIO;
|
||||
format->format.media_subtype = SPA_MEDIA_SUBTYPE_RAW;
|
||||
format->format.media_type = type;
|
||||
format->format.media_subtype = subtype;
|
||||
format->format.props.n_prop_info = SPA_N_ELEMENTS (raw_format_prop_info);
|
||||
format->format.props.prop_info = raw_format_prop_info;
|
||||
format->format.props.unset_mask = (1 << 0) | (1 << 2) | (1 << 3) | (1 << 4);
|
||||
format->info = default_info;
|
||||
format->info.raw = default_raw_info;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
SpaResult
|
||||
spa_audio_raw_format_parse (const SpaFormat *format,
|
||||
SpaAudioRawFormat *rawformat)
|
||||
spa_format_audio_parse (const SpaFormat *format,
|
||||
SpaFormatAudio *aformat)
|
||||
{
|
||||
SpaPropValue value;
|
||||
const SpaProps *props;
|
||||
SpaResult res;
|
||||
|
||||
if ((void *)format == (void *)rawformat)
|
||||
if ((void *)format == (void *)aformat)
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
if (format->media_type != SPA_MEDIA_TYPE_AUDIO ||
|
||||
format->media_subtype != SPA_MEDIA_SUBTYPE_RAW)
|
||||
if (format->media_type != SPA_MEDIA_TYPE_AUDIO)
|
||||
return SPA_RESULT_INVALID_MEDIA_TYPE;
|
||||
|
||||
spa_audio_raw_format_init (rawformat);
|
||||
spa_format_audio_init (format->media_type,
|
||||
format->media_subtype,
|
||||
aformat);
|
||||
|
||||
props = &format->props;
|
||||
if ((res = spa_props_get_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_RAW_INFO), &value)) < 0)
|
||||
goto fallback;
|
||||
|
||||
if (value.type != SPA_PROP_TYPE_POINTER || value.size != sizeof (SpaAudioRawInfo))
|
||||
if (value.type != SPA_PROP_TYPE_POINTER || value.size != sizeof (SpaAudioInfoRaw))
|
||||
goto fallback;
|
||||
|
||||
memcpy (&rawformat->info, value.value, sizeof (SpaAudioRawInfo));
|
||||
memcpy (&aformat->info, value.value, sizeof (SpaAudioInfoRaw));
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
fallback:
|
||||
res = spa_props_copy (props, &rawformat->format.props);
|
||||
res = spa_props_copy (props, &aformat->format.props);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,6 +194,8 @@ struct media_subtype_name {
|
|||
{ "vp9" },
|
||||
{ "jpeg" },
|
||||
{ "bayer" },
|
||||
{ "mp3" },
|
||||
{ "aac" },
|
||||
};
|
||||
|
||||
struct prop_type_name {
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ struct _SpaALSASink {
|
|||
void *user_data;
|
||||
|
||||
bool have_format;
|
||||
SpaAudioRawFormat query_format;
|
||||
SpaAudioRawFormat current_format;
|
||||
SpaFormatAudio query_format;
|
||||
SpaFormatAudio current_format;
|
||||
|
||||
SpaALSAState state;
|
||||
|
||||
|
|
@ -351,10 +351,14 @@ spa_alsa_sink_node_port_enum_formats (SpaNode *node,
|
|||
|
||||
switch (index) {
|
||||
case 0:
|
||||
spa_audio_raw_format_init (&this->query_format);
|
||||
spa_format_audio_init (SPA_MEDIA_TYPE_AUDIO,
|
||||
SPA_MEDIA_SUBTYPE_RAW,
|
||||
&this->query_format);
|
||||
break;
|
||||
case 1:
|
||||
spa_audio_raw_format_init (&this->query_format);
|
||||
spa_format_audio_init (SPA_MEDIA_TYPE_AUDIO,
|
||||
SPA_MEDIA_SUBTYPE_AAC,
|
||||
&this->query_format);
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
|
@ -387,7 +391,7 @@ spa_alsa_sink_node_port_set_format (SpaNode *node,
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
if ((res = spa_audio_raw_format_parse (format, &this->current_format)) < 0)
|
||||
if ((res = spa_format_audio_parse (format, &this->current_format)) < 0)
|
||||
return res;
|
||||
|
||||
if (alsa_set_format (this, &this->current_format, false) < 0)
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ spa_alsa_format_to_alsa (SpaAudioFormat format)
|
|||
}
|
||||
|
||||
static int
|
||||
alsa_set_format (SpaALSASink *this, SpaAudioRawFormat *fmt, bool try_only)
|
||||
alsa_set_format (SpaALSASink *this, SpaFormatAudio *fmt, bool try_only)
|
||||
{
|
||||
unsigned int rrate;
|
||||
snd_pcm_uframes_t size;
|
||||
|
|
@ -113,7 +113,7 @@ alsa_set_format (SpaALSASink *this, SpaAudioRawFormat *fmt, bool try_only)
|
|||
snd_pcm_hw_params_t *params;
|
||||
snd_pcm_format_t format;
|
||||
SpaALSAState *state = &this->state;
|
||||
SpaAudioRawInfo *info = &fmt->info;
|
||||
SpaAudioInfoRaw *info = &fmt->info.raw;
|
||||
snd_pcm_t *handle;
|
||||
unsigned int buffer_time;
|
||||
unsigned int period_time;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ struct _MixerBuffer {
|
|||
typedef struct {
|
||||
bool valid;
|
||||
bool have_format;
|
||||
SpaAudioRawFormat format[2];
|
||||
SpaFormatAudio format[2];
|
||||
SpaAudioMixerPortProps props[2];
|
||||
SpaPortInfo info;
|
||||
SpaPortStatus status;
|
||||
|
|
@ -338,7 +338,9 @@ spa_audiomixer_node_port_enum_formats (SpaNode *node,
|
|||
|
||||
switch (index) {
|
||||
case 0:
|
||||
spa_audio_raw_format_init (&port->format[0]);
|
||||
spa_format_audio_init (SPA_MEDIA_TYPE_AUDIO,
|
||||
SPA_MEDIA_SUBTYPE_RAW,
|
||||
&port->format[0]);
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
|
@ -374,7 +376,7 @@ spa_audiomixer_node_port_set_format (SpaNode *node,
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
if ((res = spa_audio_raw_format_parse (format, &port->format[1])) < 0)
|
||||
if ((res = spa_format_audio_parse (format, &port->format[1])) < 0)
|
||||
return res;
|
||||
|
||||
port->have_format = true;
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ struct _SpaAudioTestSrc {
|
|||
SpaPortStatus status;
|
||||
|
||||
bool have_format;
|
||||
SpaAudioRawFormat query_format;
|
||||
SpaAudioRawFormat current_format;
|
||||
SpaFormatAudio query_format;
|
||||
SpaFormatAudio current_format;
|
||||
};
|
||||
|
||||
static const uint32_t default_wave = 1.0;
|
||||
|
|
@ -298,7 +298,9 @@ spa_audiotestsrc_node_port_enum_formats (SpaNode *node,
|
|||
|
||||
switch (index) {
|
||||
case 0:
|
||||
spa_audio_raw_format_init (&this->query_format);
|
||||
spa_format_audio_init (SPA_MEDIA_TYPE_AUDIO,
|
||||
SPA_MEDIA_SUBTYPE_RAW,
|
||||
&this->query_format);
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
|
@ -331,7 +333,7 @@ spa_audiotestsrc_node_port_set_format (SpaNode *node,
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
if ((res = spa_audio_raw_format_parse (format, &this->current_format)) < 0)
|
||||
if ((res = spa_format_audio_parse (format, &this->current_format)) < 0)
|
||||
return res;
|
||||
|
||||
this->have_format = true;
|
||||
|
|
|
|||
|
|
@ -477,8 +477,11 @@ spa_v4l2_set_format (SpaV4l2Source *this, V4l2Format *f, bool try_only)
|
|||
f->fmt.media_subtype,
|
||||
f->format,
|
||||
0);
|
||||
if (info == NULL)
|
||||
if (info == NULL) {
|
||||
fprintf (stderr, "unknown media type %d %d %d\n", f->fmt.media_type,
|
||||
f->fmt.media_subtype, f->format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fmt.fmt.pix.pixelformat = info->fourcc;
|
||||
fmt.fmt.pix.field = V4L2_FIELD_ANY;
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ struct _SpaVolume {
|
|||
void *user_data;
|
||||
|
||||
bool have_format;
|
||||
SpaAudioRawFormat query_format;
|
||||
SpaAudioRawFormat current_format;
|
||||
SpaFormatAudio query_format;
|
||||
SpaFormatAudio current_format;
|
||||
|
||||
SpaVolumePort ports[2];
|
||||
};
|
||||
|
|
@ -285,7 +285,9 @@ spa_volume_node_port_enum_formats (SpaNode *node,
|
|||
|
||||
switch (index) {
|
||||
case 0:
|
||||
spa_audio_raw_format_init (&this->query_format);
|
||||
spa_format_audio_init (SPA_MEDIA_TYPE_AUDIO,
|
||||
SPA_MEDIA_SUBTYPE_RAW,
|
||||
&this->query_format);
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
|
@ -321,7 +323,7 @@ spa_volume_node_port_set_format (SpaNode *node,
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
if ((res = spa_audio_raw_format_parse (format, &this->current_format)) < 0)
|
||||
if ((res = spa_format_audio_parse (format, &this->current_format)) < 0)
|
||||
return res;
|
||||
|
||||
port->have_format = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue