Fix up audio formats as well

This commit is contained in:
Wim Taymans 2016-08-26 19:22:50 +02:00
parent b67c216a04
commit a973007a49
12 changed files with 82 additions and 58 deletions

View file

@ -453,16 +453,16 @@ gst_caps_from_format (SpaFormat *format)
NULL); NULL);
} }
} else if (format->media_type == SPA_MEDIA_TYPE_AUDIO) { } 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) { 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", 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", "layout", G_TYPE_STRING, "interleaved",
"rate", G_TYPE_INT, f.info.rate, "rate", G_TYPE_INT, f.info.raw.rate,
"channels", G_TYPE_INT, f.info.channels, "channels", G_TYPE_INT, f.info.raw.channels,
NULL); NULL);
} }
} }

View file

@ -27,7 +27,7 @@ extern "C" {
#include <spa/format.h> #include <spa/format.h>
#include <spa/audio/raw.h> #include <spa/audio/raw.h>
typedef struct _SpaAudioRawFormat SpaAudioRawFormat; typedef struct _SpaFormatAudio SpaFormatAudio;
typedef enum { typedef enum {
SPA_PROP_ID_AUDIO_FORMAT = SPA_PROP_ID_MEDIA_CUSTOM_START, 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, SpaPropIdAudio id,
size_t offset); size_t offset);
struct _SpaAudioRawFormat { struct _SpaFormatAudio {
SpaFormat format; SpaFormat format;
SpaAudioRawInfo info; union {
SpaAudioInfoRaw raw;
} info;
}; };
SpaResult spa_audio_raw_format_init (SpaAudioRawFormat *format); SpaResult spa_format_audio_init (SpaMediaType type,
SpaResult spa_audio_raw_format_parse (const SpaFormat *format, SpaMediaSubType subtype,
SpaAudioRawFormat *rawformat); SpaFormatAudio *format);
SpaResult spa_format_audio_parse (const SpaFormat *format,
SpaFormatAudio *aformat);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View file

@ -24,7 +24,7 @@
extern "C" { extern "C" {
#endif #endif
typedef struct _SpaAudioRawInfo SpaAudioRawInfo; typedef struct _SpaAudioInfoRaw SpaAudioInfoRaw;
#include <endian.h> #include <endian.h>
@ -121,7 +121,7 @@ typedef enum {
} SpaAudioLayout; } SpaAudioLayout;
/** /**
* SpaAudioRawInfo: * SpaAudioInfoRaw:
* @format: the format * @format: the format
* @flags: extra flags * @flags: extra flags
* @layout: the sample layout * @layout: the sample layout
@ -129,7 +129,7 @@ typedef enum {
* @channels: the number of channels * @channels: the number of channels
* @channel_mask: the channel mask * @channel_mask: the channel mask
*/ */
struct _SpaAudioRawInfo { struct _SpaAudioInfoRaw {
SpaAudioFormat format; SpaAudioFormat format;
SpaAudioFlags flags; SpaAudioFlags flags;
SpaAudioLayout layout; SpaAudioLayout layout;

View file

@ -54,6 +54,8 @@ typedef enum {
SPA_MEDIA_SUBTYPE_VP9 = 13, SPA_MEDIA_SUBTYPE_VP9 = 13,
SPA_MEDIA_SUBTYPE_JPEG = 14, SPA_MEDIA_SUBTYPE_JPEG = 14,
SPA_MEDIA_SUBTYPE_BAYER = 15, SPA_MEDIA_SUBTYPE_BAYER = 15,
SPA_MEDIA_SUBTYPE_MP3 = 16,
SPA_MEDIA_SUBTYPE_AAC = 17,
} SpaMediaSubType; } SpaMediaSubType;
/** /**

View file

@ -25,7 +25,7 @@
#include <spa/audio/raw.h> #include <spa/audio/raw.h>
#include <spa/audio/format.h> #include <spa/audio/format.h>
static const SpaAudioRawInfo default_info = { static const SpaAudioInfoRaw default_raw_info = {
SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FLAG_NONE, SPA_AUDIO_FLAG_NONE,
SPA_AUDIO_LAYOUT_INTERLEAVED, SPA_AUDIO_LAYOUT_INTERLEAVED,
@ -174,9 +174,9 @@ static const SpaPropInfo format_prop_info[] =
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL }, NULL },
{ SPA_PROP_ID_AUDIO_RAW_INFO, 0, { SPA_PROP_ID_AUDIO_RAW_INFO, 0,
"info", "the SpaAudioRawInfo structure", "info", "the SpaAudioInfoRaw structure",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_POINTER, sizeof (SpaAudioRawInfo), SPA_PROP_TYPE_POINTER, sizeof (SpaAudioInfoRaw),
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL }, NULL },
}; };
@ -202,17 +202,19 @@ spa_prop_info_fill_audio (SpaPropInfo *info,
} }
SpaResult SpaResult
spa_audio_raw_format_init (SpaAudioRawFormat *format) spa_format_audio_init (SpaMediaType type,
SpaMediaSubType subtype,
SpaFormatAudio *format)
{ {
static SpaPropInfo raw_format_prop_info[] = static SpaPropInfo raw_format_prop_info[] =
{ {
{ SPA_PROP_ID_AUDIO_FORMAT, offsetof (SpaAudioRawFormat, info.format), }, { SPA_PROP_ID_AUDIO_FORMAT, offsetof (SpaFormatAudio, info.raw.format), },
{ SPA_PROP_ID_AUDIO_FLAGS, offsetof (SpaAudioRawFormat, info.flags), }, { SPA_PROP_ID_AUDIO_FLAGS, offsetof (SpaFormatAudio, info.raw.flags), },
{ SPA_PROP_ID_AUDIO_LAYOUT, offsetof (SpaAudioRawFormat, info.layout), }, { SPA_PROP_ID_AUDIO_LAYOUT, offsetof (SpaFormatAudio, info.raw.layout), },
{ SPA_PROP_ID_AUDIO_RATE, offsetof (SpaAudioRawFormat, info.rate), }, { SPA_PROP_ID_AUDIO_RATE, offsetof (SpaFormatAudio, info.raw.rate), },
{ SPA_PROP_ID_AUDIO_CHANNELS, offsetof (SpaAudioRawFormat, info.channels), }, { SPA_PROP_ID_AUDIO_CHANNELS, offsetof (SpaFormatAudio, info.raw.channels), },
{ SPA_PROP_ID_AUDIO_CHANNEL_MASK, offsetof (SpaAudioRawFormat, info.channel_mask), }, { SPA_PROP_ID_AUDIO_CHANNEL_MASK, offsetof (SpaFormatAudio, info.raw.channel_mask), },
{ SPA_PROP_ID_AUDIO_RAW_INFO, offsetof (SpaAudioRawFormat, info), }, { SPA_PROP_ID_AUDIO_RAW_INFO, offsetof (SpaFormatAudio, info), },
}; };
if (raw_format_prop_info[0].name == NULL) { 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); raw_format_prop_info[i].offset);
} }
format->format.media_type = SPA_MEDIA_TYPE_AUDIO; format->format.media_type = type;
format->format.media_subtype = SPA_MEDIA_SUBTYPE_RAW; format->format.media_subtype = subtype;
format->format.props.n_prop_info = SPA_N_ELEMENTS (raw_format_prop_info); 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.prop_info = raw_format_prop_info;
format->format.props.unset_mask = (1 << 0) | (1 << 2) | (1 << 3) | (1 << 4); 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; return SPA_RESULT_OK;
} }
SpaResult SpaResult
spa_audio_raw_format_parse (const SpaFormat *format, spa_format_audio_parse (const SpaFormat *format,
SpaAudioRawFormat *rawformat) SpaFormatAudio *aformat)
{ {
SpaPropValue value; SpaPropValue value;
const SpaProps *props; const SpaProps *props;
SpaResult res; SpaResult res;
if ((void *)format == (void *)rawformat) if ((void *)format == (void *)aformat)
return SPA_RESULT_OK; return SPA_RESULT_OK;
if (format->media_type != SPA_MEDIA_TYPE_AUDIO || if (format->media_type != SPA_MEDIA_TYPE_AUDIO)
format->media_subtype != SPA_MEDIA_SUBTYPE_RAW)
return SPA_RESULT_INVALID_MEDIA_TYPE; 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; props = &format->props;
if ((res = spa_props_get_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_RAW_INFO), &value)) < 0) if ((res = spa_props_get_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_RAW_INFO), &value)) < 0)
goto fallback; 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; goto fallback;
memcpy (&rawformat->info, value.value, sizeof (SpaAudioRawInfo)); memcpy (&aformat->info, value.value, sizeof (SpaAudioInfoRaw));
return SPA_RESULT_OK; return SPA_RESULT_OK;
fallback: fallback:
res = spa_props_copy (props, &rawformat->format.props); res = spa_props_copy (props, &aformat->format.props);
return res; return res;
} }

View file

@ -194,6 +194,8 @@ struct media_subtype_name {
{ "vp9" }, { "vp9" },
{ "jpeg" }, { "jpeg" },
{ "bayer" }, { "bayer" },
{ "mp3" },
{ "aac" },
}; };
struct prop_type_name { struct prop_type_name {

View file

@ -83,8 +83,8 @@ struct _SpaALSASink {
void *user_data; void *user_data;
bool have_format; bool have_format;
SpaAudioRawFormat query_format; SpaFormatAudio query_format;
SpaAudioRawFormat current_format; SpaFormatAudio current_format;
SpaALSAState state; SpaALSAState state;
@ -351,10 +351,14 @@ spa_alsa_sink_node_port_enum_formats (SpaNode *node,
switch (index) { switch (index) {
case 0: 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; break;
case 1: 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; break;
default: default:
return SPA_RESULT_ENUM_END; return SPA_RESULT_ENUM_END;
@ -387,7 +391,7 @@ spa_alsa_sink_node_port_set_format (SpaNode *node,
return SPA_RESULT_OK; 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; return res;
if (alsa_set_format (this, &this->current_format, false) < 0) if (alsa_set_format (this, &this->current_format, false) < 0)

View file

@ -105,7 +105,7 @@ spa_alsa_format_to_alsa (SpaAudioFormat format)
} }
static int 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; unsigned int rrate;
snd_pcm_uframes_t size; 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_hw_params_t *params;
snd_pcm_format_t format; snd_pcm_format_t format;
SpaALSAState *state = &this->state; SpaALSAState *state = &this->state;
SpaAudioRawInfo *info = &fmt->info; SpaAudioInfoRaw *info = &fmt->info.raw;
snd_pcm_t *handle; snd_pcm_t *handle;
unsigned int buffer_time; unsigned int buffer_time;
unsigned int period_time; unsigned int period_time;

View file

@ -49,7 +49,7 @@ struct _MixerBuffer {
typedef struct { typedef struct {
bool valid; bool valid;
bool have_format; bool have_format;
SpaAudioRawFormat format[2]; SpaFormatAudio format[2];
SpaAudioMixerPortProps props[2]; SpaAudioMixerPortProps props[2];
SpaPortInfo info; SpaPortInfo info;
SpaPortStatus status; SpaPortStatus status;
@ -338,7 +338,9 @@ spa_audiomixer_node_port_enum_formats (SpaNode *node,
switch (index) { switch (index) {
case 0: 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; break;
default: default:
return SPA_RESULT_ENUM_END; return SPA_RESULT_ENUM_END;
@ -374,7 +376,7 @@ spa_audiomixer_node_port_set_format (SpaNode *node,
return SPA_RESULT_OK; 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; return res;
port->have_format = true; port->have_format = true;

View file

@ -45,8 +45,8 @@ struct _SpaAudioTestSrc {
SpaPortStatus status; SpaPortStatus status;
bool have_format; bool have_format;
SpaAudioRawFormat query_format; SpaFormatAudio query_format;
SpaAudioRawFormat current_format; SpaFormatAudio current_format;
}; };
static const uint32_t default_wave = 1.0; static const uint32_t default_wave = 1.0;
@ -298,7 +298,9 @@ spa_audiotestsrc_node_port_enum_formats (SpaNode *node,
switch (index) { switch (index) {
case 0: 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; break;
default: default:
return SPA_RESULT_ENUM_END; return SPA_RESULT_ENUM_END;
@ -331,7 +333,7 @@ spa_audiotestsrc_node_port_set_format (SpaNode *node,
return SPA_RESULT_OK; 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; return res;
this->have_format = true; this->have_format = true;

View file

@ -477,8 +477,11 @@ spa_v4l2_set_format (SpaV4l2Source *this, V4l2Format *f, bool try_only)
f->fmt.media_subtype, f->fmt.media_subtype,
f->format, f->format,
0); 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; return -1;
}
fmt.fmt.pix.pixelformat = info->fourcc; fmt.fmt.pix.pixelformat = info->fourcc;
fmt.fmt.pix.field = V4L2_FIELD_ANY; fmt.fmt.pix.field = V4L2_FIELD_ANY;

View file

@ -51,8 +51,8 @@ struct _SpaVolume {
void *user_data; void *user_data;
bool have_format; bool have_format;
SpaAudioRawFormat query_format; SpaFormatAudio query_format;
SpaAudioRawFormat current_format; SpaFormatAudio current_format;
SpaVolumePort ports[2]; SpaVolumePort ports[2];
}; };
@ -285,7 +285,9 @@ spa_volume_node_port_enum_formats (SpaNode *node,
switch (index) { switch (index) {
case 0: 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; break;
default: default:
return SPA_RESULT_ENUM_END; return SPA_RESULT_ENUM_END;
@ -321,7 +323,7 @@ spa_volume_node_port_set_format (SpaNode *node,
return SPA_RESULT_OK; 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; return res;
port->have_format = true; port->have_format = true;