diff --git a/pinos/client/mapper.c b/pinos/client/mapper.c index 511f5fb2d..96de7e89f 100644 --- a/pinos/client/mapper.c +++ b/pinos/client/mapper.c @@ -23,6 +23,7 @@ #include #include +#include #include @@ -44,7 +45,7 @@ id_map_get_id (SpaIDMap *map, const char *uri) if (strcmp (pinos_map_lookup_unchecked (&this->uris, i), uri) == 0) return i; } - i = pinos_map_insert_new (&this->uris, (char *)uri); + i = pinos_map_insert_new (&this->uris, strdup (uri)); } return i; } @@ -82,5 +83,6 @@ static IDMap default_id_map = { SpaIDMap * pinos_id_map_get_default (void) { + spa_id_map_set_default (&default_id_map.map); return &default_id_map.map; } diff --git a/pinos/gst/gstpinosformat.c b/pinos/gst/gstpinosformat.c index 5428ce66f..aa15b7dd1 100644 --- a/pinos/gst/gstpinosformat.c +++ b/pinos/gst/gstpinosformat.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -32,15 +33,33 @@ typedef struct { const char *name; - uint32_t media_type; - uint32_t media_subtype; + uint32_t *media_type; + uint32_t *media_subtype; } MediaType; -static const MediaType media_types[] = { - { "video/x-raw", SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { "audio/x-raw", SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW }, - { "image/jpeg", SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_MJPG }, - { "video/x-h264", SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_H264 }, +static SpaMediaTypes media_types = { 0, }; +static SpaMediaSubtypes media_subtypes = { 0, }; +static SpaMediaSubtypesVideo media_subtypes_video = { 0, }; +static SpaMediaSubtypesAudio media_subtypes_audio = { 0, }; +static SpaPropVideo prop_video = { 0, }; +static SpaPropAudio prop_audio = { 0, }; + +static void +ensure_types (void) +{ + spa_media_types_fill (&media_types, spa_id_map_get_default ()); + spa_media_subtypes_map (spa_id_map_get_default (), &media_subtypes); + spa_media_subtypes_video_map (spa_id_map_get_default (), &media_subtypes_video); + spa_media_subtypes_audio_map (spa_id_map_get_default (), &media_subtypes_audio); + spa_prop_video_map (spa_id_map_get_default (), &prop_video); + spa_prop_audio_map (spa_id_map_get_default (), &prop_audio); +} + +static const MediaType media_type_map[] = { + { "video/x-raw", &media_types.video, &media_subtypes.raw }, + { "audio/x-raw", &media_types.audio, &media_subtypes.raw }, + { "image/jpeg", &media_types.video, &media_subtypes_video.mjpg }, + { "video/x-h264", &media_types.video, &media_subtypes_video.h264 }, { NULL, } }; @@ -55,9 +74,9 @@ static const MediaType * find_media_types (const char *name) { int i; - for (i = 0; media_types[i].name; i++) { - if (!strcmp (media_types[i].name, name)) - return &media_types[i]; + for (i = 0; media_type_map[i].name; i++) { + if (!strcmp (media_type_map[i].name, name)) + return &media_type_map[i]; } return NULL; } @@ -229,7 +248,7 @@ handle_video_fields (ConvertData *d) for (i = 0; (v = get_nth_string (value, i)); i++) { if (i == 0) spa_pod_builder_push_prop (&d->b, &f, - SPA_PROP_ID_VIDEO_FORMAT, + prop_video.format, get_range_type (value) | SPA_POD_PROP_FLAG_READWRITE); spa_pod_builder_int (&d->b, gst_video_format_from_string (v)); @@ -245,7 +264,7 @@ handle_video_fields (ConvertData *d) for (i = 0; get_nth_rectangle (value, value2, i, &v); i++) { if (i == 0) spa_pod_builder_push_prop (&d->b, &f, - SPA_PROP_ID_VIDEO_SIZE, + prop_video.size, get_range_type2 (value, value2) | SPA_POD_PROP_FLAG_READWRITE); spa_pod_builder_rectangle (&d->b, v.width, v.height); @@ -261,7 +280,7 @@ handle_video_fields (ConvertData *d) for (i = 0; get_nth_fraction (value, i, &v); i++) { if (i == 0) spa_pod_builder_push_prop (&d->b, &f, - SPA_PROP_ID_VIDEO_FRAMERATE, + prop_video.framerate, get_range_type (value) | SPA_POD_PROP_FLAG_READWRITE); spa_pod_builder_fraction (&d->b, v.num, v.denom); @@ -286,7 +305,7 @@ handle_audio_fields (ConvertData *d) for (i = 0; (v = get_nth_string (value, i)); i++) { if (i == 0) spa_pod_builder_push_prop (&d->b, &f, - SPA_PROP_ID_AUDIO_FORMAT, + prop_audio.format, get_range_type (value) | SPA_POD_PROP_FLAG_READWRITE); spa_pod_builder_int (&d->b, gst_audio_format_from_string (v)); @@ -311,7 +330,7 @@ handle_audio_fields (ConvertData *d) if (i == 0) spa_pod_builder_push_prop (&d->b, &f, - SPA_PROP_ID_AUDIO_LAYOUT, + prop_audio.layout, get_range_type (value) | SPA_POD_PROP_FLAG_READWRITE); spa_pod_builder_int (&d->b, layout); @@ -326,7 +345,7 @@ handle_audio_fields (ConvertData *d) for (i = 0; get_nth_int (value, i, &v); i++) { if (i == 0) spa_pod_builder_push_prop (&d->b, &f, - SPA_PROP_ID_AUDIO_RATE, + prop_audio.rate, get_range_type (value) | SPA_POD_PROP_FLAG_READWRITE); spa_pod_builder_int (&d->b, v); @@ -341,7 +360,7 @@ handle_audio_fields (ConvertData *d) for (i = 0; get_nth_int (value, i, &v); i++) { if (i == 0) spa_pod_builder_push_prop (&d->b, &f, - SPA_PROP_ID_AUDIO_CHANNELS, + prop_audio.channels, get_range_type (value) | SPA_POD_PROP_FLAG_READWRITE); spa_pod_builder_int (&d->b, v); @@ -383,12 +402,12 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs) d.b.write = write_pod; spa_pod_builder_push_format (&d.b, &f, - d.type->media_type, - d.type->media_subtype); + *d.type->media_type, + *d.type->media_subtype); - if (d.type->media_type == SPA_MEDIA_TYPE_VIDEO) + if (*d.type->media_type == media_types.video) handle_video_fields (&d); - else if (d.type->media_type == SPA_MEDIA_TYPE_AUDIO) + else if (*d.type->media_type == media_types.audio) handle_audio_fields (&d); spa_pod_builder_pop (&d.b, &f); @@ -406,6 +425,8 @@ gst_caps_to_format (GstCaps *caps, guint index) g_return_val_if_fail (GST_IS_CAPS (caps), NULL); g_return_val_if_fail (gst_caps_is_fixed (caps), NULL); + ensure_types(); + f = gst_caps_get_features (caps, index); s = gst_caps_get_structure (caps, index); @@ -433,6 +454,8 @@ gst_caps_to_format_all (GstCaps *caps) { GPtrArray *res; + ensure_types(); + res = g_ptr_array_new_full (gst_caps_get_size (caps), (GDestroyNotify)g_free); gst_caps_foreach (caps, (GstCapsForeachFunc) foreach_func, res); @@ -445,16 +468,18 @@ gst_caps_from_format (const SpaFormat *format) GstCaps *res = NULL; uint32_t media_type, media_subtype; + ensure_types(); + media_type = format->body.media_type.value; media_subtype = format->body.media_subtype.value; - if (media_type == SPA_MEDIA_TYPE_VIDEO) { + if (media_type == media_types.video) { SpaVideoInfo f; if (spa_format_video_parse (format, &f) < 0) return NULL; - if (media_subtype == SPA_MEDIA_SUBTYPE_RAW) { + if (media_subtype == media_subtypes.raw) { res = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, gst_video_format_to_string (f.info.raw.format), "width", G_TYPE_INT, f.info.raw.size.width, @@ -462,14 +487,14 @@ gst_caps_from_format (const SpaFormat *format) "framerate", GST_TYPE_FRACTION, f.info.raw.framerate.num, f.info.raw.framerate.denom, NULL); } - else if (media_subtype == SPA_MEDIA_SUBTYPE_MJPG) { + else if (media_subtype == media_subtypes_video.mjpg) { res = gst_caps_new_simple ("image/jpeg", "width", G_TYPE_INT, f.info.mjpg.size.width, "height", G_TYPE_INT, f.info.mjpg.size.height, "framerate", GST_TYPE_FRACTION, f.info.mjpg.framerate.num, f.info.mjpg.framerate.denom, NULL); } - else if (media_subtype == SPA_MEDIA_SUBTYPE_H264) { + else if (media_subtype == media_subtypes_video.h264) { res = gst_caps_new_simple ("video/x-h264", "width", G_TYPE_INT, f.info.h264.size.width, "height", G_TYPE_INT, f.info.h264.size.height, @@ -478,13 +503,13 @@ gst_caps_from_format (const SpaFormat *format) "alignment", G_TYPE_STRING, "au", NULL); } - } else if (media_type == SPA_MEDIA_TYPE_AUDIO) { + } else if (media_type == media_types.audio) { SpaAudioInfo f; if (spa_format_audio_parse (format, &f) < 0) return NULL; - if (media_subtype == SPA_MEDIA_SUBTYPE_RAW) { + if (media_subtype == media_subtypes.raw) { res = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, gst_audio_format_to_string (f.info.raw.format), "layout", G_TYPE_STRING, "interleaved", diff --git a/spa/include/spa/audio/format.h b/spa/include/spa/audio/format.h index 8b1d68fa2..f5249ff49 100644 --- a/spa/include/spa/audio/format.h +++ b/spa/include/spa/audio/format.h @@ -29,19 +29,41 @@ extern "C" { typedef struct _SpaAudioInfo SpaAudioInfo; -typedef enum { - SPA_PROP_ID_AUDIO_INFO = SPA_PROP_ID_MEDIA_CUSTOM_START, - SPA_PROP_ID_AUDIO_FORMAT, - SPA_PROP_ID_AUDIO_FLAGS, - SPA_PROP_ID_AUDIO_LAYOUT, - SPA_PROP_ID_AUDIO_RATE, - SPA_PROP_ID_AUDIO_CHANNELS, - SPA_PROP_ID_AUDIO_CHANNEL_MASK, -} SpaPropIdAudio; +#define SPA_PROP_AUDIO_URI "http://spaplug.in/ns/prop-audio" +#define SPA_PROP_AUDIO_PREFIX SPA_PROP_AUDIO_URI "#" + +#define SPA_PROP_AUDIO__format SPA_PROP_AUDIO_PREFIX "format" +#define SPA_PROP_AUDIO__flags SPA_PROP_AUDIO_PREFIX "flags" +#define SPA_PROP_AUDIO__layout SPA_PROP_AUDIO_PREFIX "layout" +#define SPA_PROP_AUDIO__rate SPA_PROP_AUDIO_PREFIX "rate" +#define SPA_PROP_AUDIO__channels SPA_PROP_AUDIO_PREFIX "channels" +#define SPA_PROP_AUDIO__channelMask SPA_PROP_AUDIO_PREFIX "channel-mask" + +typedef struct { + uint32_t format; + uint32_t flags; + uint32_t layout; + uint32_t rate; + uint32_t channels; + uint32_t channel_mask; +} SpaPropAudio; + +static inline void +spa_prop_audio_map (SpaIDMap *map, SpaPropAudio *types) +{ + if (types->format == 0) { + types->format = spa_id_map_get_id (map, SPA_PROP_AUDIO__format); + types->flags = spa_id_map_get_id (map, SPA_PROP_AUDIO__flags); + types->layout = spa_id_map_get_id (map, SPA_PROP_AUDIO__layout); + types->rate = spa_id_map_get_id (map, SPA_PROP_AUDIO__rate); + types->channels = spa_id_map_get_id (map, SPA_PROP_AUDIO__channels); + types->channel_mask = spa_id_map_get_id (map, SPA_PROP_AUDIO__channelMask); + } +} struct _SpaAudioInfo { - SpaMediaType media_type; - SpaMediaSubType media_subtype; + uint32_t media_type; + uint32_t media_subtype; union { SpaAudioInfoRaw raw; } info; diff --git a/spa/include/spa/format-builder.h b/spa/include/spa/format-builder.h index 781563b4d..baa443ffc 100644 --- a/spa/include/spa/format-builder.h +++ b/spa/include/spa/format-builder.h @@ -37,16 +37,16 @@ spa_pod_builder_push_format (SpaPODBuilder *builder, { const SpaFormat p = { { sizeof (SpaFormatBody), SPA_POD_TYPE_OBJECT }, { { 0, 0 }, - { { sizeof (uint32_t), SPA_POD_TYPE_INT }, media_type }, - { { sizeof (uint32_t), SPA_POD_TYPE_INT }, media_subtype } } }; + { { sizeof (uint32_t), SPA_POD_TYPE_URI }, media_type }, + { { sizeof (uint32_t), SPA_POD_TYPE_URI }, media_subtype } } }; return spa_pod_builder_push (builder, frame, &p.pod, spa_pod_builder_raw (builder, &p, sizeof(p))); } #define spa_pod_builder_format(b,f,media_type,media_subtype,...) \ spa_pod_builder_object(b, f, 0, 0, \ - SPA_POD_TYPE_INT,media_type, \ - SPA_POD_TYPE_INT,media_subtype, \ + SPA_POD_TYPE_URI,media_type, \ + SPA_POD_TYPE_URI,media_subtype, \ __VA_ARGS__) SpaResult diff --git a/spa/include/spa/format.h b/spa/include/spa/format.h index 8c7b60312..0109b1757 100644 --- a/spa/include/spa/format.h +++ b/spa/include/spa/format.h @@ -33,66 +33,152 @@ typedef struct _SpaFormat SpaFormat; #include #include +#include -typedef enum { - SPA_MEDIA_TYPE_INVALID = 0, - SPA_MEDIA_TYPE_AUDIO = 1, - SPA_MEDIA_TYPE_VIDEO = 2, - SPA_MEDIA_TYPE_IMAGE = 3, -} SpaMediaType; +#define SPA_MEDIA_TYPE_URI "http://spaplug.in/ns/media-type" +#define SPA_MEDIA_TYPE_PREFIX SPA_MEDIA_TYPE_URI "#" -typedef enum { - SPA_MEDIA_SUBTYPE_INVALID = 0, +#define SPA_MEDIA_TYPE__audio SPA_MEDIA_TYPE_PREFIX "audio" +#define SPA_MEDIA_TYPE__video SPA_MEDIA_TYPE_PREFIX "video" +#define SPA_MEDIA_TYPE__image SPA_MEDIA_TYPE_PREFIX "image" -#define SPA_MEDIA_SUBTYPE_ANY_FIRST 1 - SPA_MEDIA_SUBTYPE_RAW = SPA_MEDIA_SUBTYPE_ANY_FIRST, -#define SPA_MEDIA_SUBTYPE_ANY_LAST SPA_MEDIA_SUBTYPE_RAW +typedef struct { + uint32_t audio; + uint32_t video; + uint32_t image; +} SpaMediaTypes; - /* VIDEO */ -#define SPA_MEDIA_SUBTYPE_VIDEO_FIRST 20 - SPA_MEDIA_SUBTYPE_H264 = SPA_MEDIA_SUBTYPE_VIDEO_FIRST, - SPA_MEDIA_SUBTYPE_MJPG, - SPA_MEDIA_SUBTYPE_DV, - SPA_MEDIA_SUBTYPE_MPEGTS, - SPA_MEDIA_SUBTYPE_H263, - SPA_MEDIA_SUBTYPE_MPEG1, - SPA_MEDIA_SUBTYPE_MPEG2, - SPA_MEDIA_SUBTYPE_MPEG4, - SPA_MEDIA_SUBTYPE_XVID, - SPA_MEDIA_SUBTYPE_VC1, - SPA_MEDIA_SUBTYPE_VP8, - SPA_MEDIA_SUBTYPE_VP9, - SPA_MEDIA_SUBTYPE_JPEG, - SPA_MEDIA_SUBTYPE_BAYER, -#define SPA_MEDIA_SUBTYPE_VIDEO_LAST SPA_MEDIA_SUBTYPE_BAYER +static inline void +spa_media_types_fill (SpaMediaTypes *types, SpaIDMap *map) +{ + if (types->audio == 0) { + types->audio = spa_id_map_get_id (map, SPA_MEDIA_TYPE__audio); + types->video = spa_id_map_get_id (map, SPA_MEDIA_TYPE__video); + types->image = spa_id_map_get_id (map, SPA_MEDIA_TYPE__image); + } +} - /* AUDIO */ -#define SPA_MEDIA_SUBTYPE_AUDIO_FIRST 200 - SPA_MEDIA_SUBTYPE_MP3 = SPA_MEDIA_SUBTYPE_AUDIO_FIRST, - SPA_MEDIA_SUBTYPE_AAC, - SPA_MEDIA_SUBTYPE_VORBIS, - SPA_MEDIA_SUBTYPE_WMA, - SPA_MEDIA_SUBTYPE_RA, - SPA_MEDIA_SUBTYPE_SBC, - SPA_MEDIA_SUBTYPE_ADPCM, - SPA_MEDIA_SUBTYPE_G723, - SPA_MEDIA_SUBTYPE_G726, - SPA_MEDIA_SUBTYPE_G729, - SPA_MEDIA_SUBTYPE_AMR, - SPA_MEDIA_SUBTYPE_GSM, -#define SPA_MEDIA_SUBTYPE_AUDIO_LAST SPA_MEDIA_SUBTYPE_GSM +#define SPA_MEDIA_SUBTYPE_URI "http://spaplug.in/ns/media-subtype" +#define SPA_MEDIA_SUBTYPE_PREFIX SPA_MEDIA_TYPE_URI "#" -} SpaMediaSubType; +#define SPA_MEDIA_SUBTYPE__raw SPA_MEDIA_TYPE_PREFIX "raw" -typedef enum { - SPA_PROP_ID_INVALID = 0, - SPA_PROP_ID_MEDIA_CUSTOM_START = 200, -} SpaFormatProps; +typedef struct { + uint32_t raw; +} SpaMediaSubtypes; + +static inline void +spa_media_subtypes_map (SpaIDMap *map, SpaMediaSubtypes *types) +{ + if (types->raw == 0) { + types->raw = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__raw); + } +} + +#define SPA_MEDIA_SUBTYPE__h264 SPA_MEDIA_SUBTYPE_PREFIX "h264" +#define SPA_MEDIA_SUBTYPE__mjpg SPA_MEDIA_SUBTYPE_PREFIX "mjpg" +#define SPA_MEDIA_SUBTYPE__dv SPA_MEDIA_SUBTYPE_PREFIX "dv" +#define SPA_MEDIA_SUBTYPE__mpegts SPA_MEDIA_SUBTYPE_PREFIX "mpegts" +#define SPA_MEDIA_SUBTYPE__h263 SPA_MEDIA_SUBTYPE_PREFIX "h263" +#define SPA_MEDIA_SUBTYPE__mpeg1 SPA_MEDIA_SUBTYPE_PREFIX "mpeg1" +#define SPA_MEDIA_SUBTYPE__mpeg2 SPA_MEDIA_SUBTYPE_PREFIX "mpeg2" +#define SPA_MEDIA_SUBTYPE__mpeg4 SPA_MEDIA_SUBTYPE_PREFIX "mpeg4" +#define SPA_MEDIA_SUBTYPE__xvid SPA_MEDIA_SUBTYPE_PREFIX "xvid" +#define SPA_MEDIA_SUBTYPE__vc1 SPA_MEDIA_SUBTYPE_PREFIX "vc1" +#define SPA_MEDIA_SUBTYPE__vp8 SPA_MEDIA_SUBTYPE_PREFIX "vp8" +#define SPA_MEDIA_SUBTYPE__vp9 SPA_MEDIA_SUBTYPE_PREFIX "vp9" +#define SPA_MEDIA_SUBTYPE__jpeg SPA_MEDIA_SUBTYPE_PREFIX "jpeg" +#define SPA_MEDIA_SUBTYPE__bayer SPA_MEDIA_SUBTYPE_PREFIX "bayer" + +typedef struct { + uint32_t h264; + uint32_t mjpg; + uint32_t dv; + uint32_t mpegts; + uint32_t h263; + uint32_t mpeg1; + uint32_t mpeg2; + uint32_t mpeg4; + uint32_t xvid; + uint32_t vc1; + uint32_t vp8; + uint32_t vp9; + uint32_t jpeg; + uint32_t bayer; +} SpaMediaSubtypesVideo; + +static inline void +spa_media_subtypes_video_map (SpaIDMap *map, SpaMediaSubtypesVideo *types) +{ + if (types->h264 == 0) { + types->h264 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__h264); + types->mjpg = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__mjpg); + types->dv = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__dv); + types->mpegts = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__mpegts); + types->h263 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__h263); + types->mpeg1 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__mpeg1); + types->mpeg2 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__mpeg2); + types->mpeg4 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__mpeg4); + types->xvid = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__xvid); + types->vc1 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__vc1); + types->vp8 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__vp8); + types->vp9 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__vp9); + types->jpeg = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__jpeg); + types->bayer = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__bayer); + } +} + +#define SPA_MEDIA_SUBTYPE__mp3 SPA_MEDIA_SUBTYPE_PREFIX "mp3" +#define SPA_MEDIA_SUBTYPE__aac SPA_MEDIA_SUBTYPE_PREFIX "aac" +#define SPA_MEDIA_SUBTYPE__vorbis SPA_MEDIA_SUBTYPE_PREFIX "vorbis" +#define SPA_MEDIA_SUBTYPE__wma SPA_MEDIA_SUBTYPE_PREFIX "wma" +#define SPA_MEDIA_SUBTYPE__ra SPA_MEDIA_SUBTYPE_PREFIX "ra" +#define SPA_MEDIA_SUBTYPE__sbc SPA_MEDIA_SUBTYPE_PREFIX "sbc" +#define SPA_MEDIA_SUBTYPE__adpcm SPA_MEDIA_SUBTYPE_PREFIX "adpcm" +#define SPA_MEDIA_SUBTYPE__g723 SPA_MEDIA_SUBTYPE_PREFIX "g723" +#define SPA_MEDIA_SUBTYPE__g726 SPA_MEDIA_SUBTYPE_PREFIX "g726" +#define SPA_MEDIA_SUBTYPE__g729 SPA_MEDIA_SUBTYPE_PREFIX "g729" +#define SPA_MEDIA_SUBTYPE__amr SPA_MEDIA_SUBTYPE_PREFIX "amr" +#define SPA_MEDIA_SUBTYPE__gsm SPA_MEDIA_SUBTYPE_PREFIX "gsm" + +typedef struct { + uint32_t mp3; + uint32_t aac; + uint32_t vorbis; + uint32_t wma; + uint32_t ra; + uint32_t sbc; + uint32_t adpcm; + uint32_t g723; + uint32_t g726; + uint32_t g729; + uint32_t amr; + uint32_t gsm; +} SpaMediaSubtypesAudio; + +static inline void +spa_media_subtypes_audio_map (SpaIDMap *map, SpaMediaSubtypesAudio *types) +{ + if (types->mp3 == 0) { + types->mp3 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__mp3); + types->aac = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__aac); + types->vorbis = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__vorbis); + types->wma = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__wma); + types->ra = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__ra); + types->sbc = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__sbc); + types->adpcm = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__adpcm); + types->g723 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__g723); + types->g726 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__g726); + types->g729 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__g729); + types->amr = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__amr); + types->gsm = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__gsm); + } +} typedef struct { SpaPODObjectBody obj_body; - SpaPODInt media_type SPA_ALIGNED (8); - SpaPODInt media_subtype SPA_ALIGNED (8); + SpaPODURI media_type SPA_ALIGNED (8); + SpaPODURI media_subtype SPA_ALIGNED (8); /* contents follow, series of SpaPODProp */ } SpaFormatBody; @@ -110,8 +196,8 @@ struct _SpaFormat { #define SPA_FORMAT_INIT(size,type,media_type,media_subtype,...) \ { { size, SPA_POD_TYPE_OBJECT }, \ { { 0, type }, \ - SPA_POD_INT_INIT (media_type), \ - SPA_POD_INT_INIT (media_subtype) } } + SPA_POD_URI_INIT (media_type), \ + SPA_POD_URI_INIT (media_subtype) } } #define SPA_FORMAT_BODY_FOREACH(body, size, iter) \ for ((iter) = SPA_MEMBER ((body), sizeof (SpaFormatBody), SpaPODProp); \ diff --git a/spa/include/spa/pod-builder.h b/spa/include/spa/pod-builder.h index 8a982e18c..9936688b3 100644 --- a/spa/include/spa/pod-builder.h +++ b/spa/include/spa/pod-builder.h @@ -341,30 +341,18 @@ spa_pod_builder_addv (SpaPODBuilder *builder, uint32_t body_size; static const uint64_t zeroes = 0; - while (type != 0) { + while (type != SPA_POD_TYPE_INVALID) { SpaPODFrame *f = NULL; const void *data[3]; uint32_t size[3], ref, i, n_sizes = 0; switch (type) { - case SPA_POD_TYPE_INVALID: + case SPA_POD_TYPE_NONE: break; case SPA_POD_TYPE_BOOL: - head.bool_pod.pod.type = SPA_POD_TYPE_BOOL; - head.bool_pod.pod.size = body_size = sizeof (uint32_t); - head.bool_pod.value = va_arg (args, int); - head_size = sizeof (SpaPOD); - body = &head.bool_pod.value; - goto primitive; case SPA_POD_TYPE_URI: - head.uri_pod.pod.type = SPA_POD_TYPE_URI; - head.uri_pod.pod.size = body_size = sizeof (uint32_t); - head.uri_pod.value = va_arg (args, int); - head_size = sizeof (SpaPOD); - body = &head.uri_pod.value; - goto primitive; case SPA_POD_TYPE_INT: - head.int_pod.pod.type = SPA_POD_TYPE_INT; + head.int_pod.pod.type = type; head.int_pod.pod.size = body_size = sizeof (uint32_t); head.int_pod.value = va_arg (args, int); head_size = sizeof (SpaPOD); diff --git a/spa/include/spa/pod.h b/spa/include/spa/pod.h index e3a00b6b2..710d95ca6 100644 --- a/spa/include/spa/pod.h +++ b/spa/include/spa/pod.h @@ -36,6 +36,7 @@ extern "C" { */ typedef enum { SPA_POD_TYPE_INVALID = 0, + SPA_POD_TYPE_NONE = 1, SPA_POD_TYPE_BOOL, SPA_POD_TYPE_URI, SPA_POD_TYPE_INT, diff --git a/spa/include/spa/video/format.h b/spa/include/spa/video/format.h index e6c0df0dd..4eae945ef 100644 --- a/spa/include/spa/video/format.h +++ b/spa/include/spa/video/format.h @@ -30,34 +30,80 @@ extern "C" { typedef struct _SpaVideoInfo SpaVideoInfo; -typedef enum { - SPA_PROP_ID_VIDEO_INFO = SPA_PROP_ID_MEDIA_CUSTOM_START, - SPA_PROP_ID_VIDEO_FORMAT, - SPA_PROP_ID_VIDEO_SIZE, - SPA_PROP_ID_VIDEO_FRAMERATE, - SPA_PROP_ID_VIDEO_MAX_FRAMERATE, - SPA_PROP_ID_VIDEO_VIEWS, - SPA_PROP_ID_VIDEO_INTERLACE_MODE, - SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO, - SPA_PROP_ID_VIDEO_MULTIVIEW_MODE, - SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS, - SPA_PROP_ID_VIDEO_CHROMA_SITE, - SPA_PROP_ID_VIDEO_COLOR_RANGE, - SPA_PROP_ID_VIDEO_COLOR_MATRIX, - SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION, - SPA_PROP_ID_VIDEO_COLOR_PRIMARIES, - SPA_PROP_ID_VIDEO_PROFILE, - SPA_PROP_ID_VIDEO_LEVEL, - SPA_PROP_ID_VIDEO_STREAM_FORMAT, - SPA_PROP_ID_VIDEO_ALIGNMENT, -} SpaPropIdVideo; +#define SPA_PROP_VIDEO_URI "http://spaplug.in/ns/prop-video" +#define SPA_PROP_VIDEO_PREFIX SPA_PROP_VIDEO_URI "#" + +#define SPA_PROP_VIDEO__format SPA_PROP_VIDEO_PREFIX "format" +#define SPA_PROP_VIDEO__size SPA_PROP_VIDEO_PREFIX "size" +#define SPA_PROP_VIDEO__framerate SPA_PROP_VIDEO_PREFIX "framerate" +#define SPA_PROP_VIDEO__maxFramerate SPA_PROP_VIDEO_PREFIX "max-framerate" +#define SPA_PROP_VIDEO__views SPA_PROP_VIDEO_PREFIX "views" +#define SPA_PROP_VIDEO__interlaceMode SPA_PROP_VIDEO_PREFIX "interlace-mode" +#define SPA_PROP_VIDEO__pixelAspectRatio SPA_PROP_VIDEO_PREFIX "pixel-aspect-ratio" +#define SPA_PROP_VIDEO__multiviewMode SPA_PROP_VIDEO_PREFIX "multiview-mode" +#define SPA_PROP_VIDEO__multiviewFlags SPA_PROP_VIDEO_PREFIX "multiview-flags" +#define SPA_PROP_VIDEO__chromaSite SPA_PROP_VIDEO_PREFIX "chroma-site" +#define SPA_PROP_VIDEO__colorRange SPA_PROP_VIDEO_PREFIX "color-range" +#define SPA_PROP_VIDEO__colorMatrix SPA_PROP_VIDEO_PREFIX "color-matrix" +#define SPA_PROP_VIDEO__transferFunction SPA_PROP_VIDEO_PREFIX "transfer-function" +#define SPA_PROP_VIDEO__colorPrimaries SPA_PROP_VIDEO_PREFIX "color-primaries" +#define SPA_PROP_VIDEO__profile SPA_PROP_VIDEO_PREFIX "profile" +#define SPA_PROP_VIDEO__level SPA_PROP_VIDEO_PREFIX "level" +#define SPA_PROP_VIDEO__streamFormat SPA_PROP_VIDEO_PREFIX "stream-format" +#define SPA_PROP_VIDEO__alignment SPA_PROP_VIDEO_PREFIX "alignment" + +typedef struct { + uint32_t format; + uint32_t size; + uint32_t framerate; + uint32_t max_framerate; + uint32_t views; + uint32_t interlace_mode; + uint32_t pixel_aspect_ratio; + uint32_t multiview_mode; + uint32_t multiview_flags; + uint32_t chroma_site; + uint32_t color_range; + uint32_t color_matrix; + uint32_t transfer_function; + uint32_t color_primaries; + uint32_t profile; + uint32_t level; + uint32_t stream_format; + uint32_t alignment; +} SpaPropVideo; + +static inline void +spa_prop_video_map (SpaIDMap *map, SpaPropVideo *types) +{ + if (types->format == 0) { + types->format = spa_id_map_get_id (map, SPA_PROP_VIDEO__format); + types->size = spa_id_map_get_id (map, SPA_PROP_VIDEO__size); + types->framerate = spa_id_map_get_id (map, SPA_PROP_VIDEO__framerate); + types->max_framerate = spa_id_map_get_id (map, SPA_PROP_VIDEO__maxFramerate); + types->views = spa_id_map_get_id (map, SPA_PROP_VIDEO__views); + types->interlace_mode = spa_id_map_get_id (map, SPA_PROP_VIDEO__interlaceMode); + types->pixel_aspect_ratio = spa_id_map_get_id (map, SPA_PROP_VIDEO__pixelAspectRatio); + types->multiview_mode = spa_id_map_get_id (map, SPA_PROP_VIDEO__multiviewMode); + types->multiview_flags = spa_id_map_get_id (map, SPA_PROP_VIDEO__multiviewFlags); + types->chroma_site = spa_id_map_get_id (map, SPA_PROP_VIDEO__chromaSite); + types->color_range = spa_id_map_get_id (map, SPA_PROP_VIDEO__colorRange); + types->color_matrix = spa_id_map_get_id (map, SPA_PROP_VIDEO__colorMatrix); + types->transfer_function = spa_id_map_get_id (map, SPA_PROP_VIDEO__transferFunction); + types->color_primaries = spa_id_map_get_id (map, SPA_PROP_VIDEO__colorPrimaries); + types->profile = spa_id_map_get_id (map, SPA_PROP_VIDEO__profile); + types->level = spa_id_map_get_id (map, SPA_PROP_VIDEO__level); + types->stream_format = spa_id_map_get_id (map, SPA_PROP_VIDEO__streamFormat); + types->alignment = spa_id_map_get_id (map, SPA_PROP_VIDEO__alignment); + } +} SpaResult spa_format_video_parse (const SpaFormat *format, SpaVideoInfo *info); struct _SpaVideoInfo { - SpaMediaType media_type; - SpaMediaSubType media_subtype; + uint32_t media_type; + uint32_t media_subtype; union { SpaVideoInfoRaw raw; SpaVideoInfoH264 h264; diff --git a/spa/lib/audio-raw.c b/spa/lib/audio-raw.c index db682532c..680fe3c54 100644 --- a/spa/lib/audio-raw.c +++ b/spa/lib/audio-raw.c @@ -22,78 +22,42 @@ #include #include +#include #include #include -typedef struct { - uint32_t key; - uint32_t type; - off_t offset; -} ParseInfo; - -static const ParseInfo raw_parse_info[] = { - { SPA_PROP_ID_AUDIO_INFO, SPA_POD_TYPE_BYTES, offsetof (SpaAudioInfo, info.raw) }, - { SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, offsetof (SpaAudioInfo, info.raw.format) }, - { SPA_PROP_ID_AUDIO_FLAGS, SPA_POD_TYPE_INT, offsetof (SpaAudioInfo, info.raw.flags) }, - { SPA_PROP_ID_AUDIO_LAYOUT, SPA_POD_TYPE_INT, offsetof (SpaAudioInfo, info.raw.layout) }, - { SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, offsetof (SpaAudioInfo, info.raw.rate) }, - { SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, offsetof (SpaAudioInfo, info.raw.channels) }, - { SPA_PROP_ID_AUDIO_CHANNEL_MASK, SPA_POD_TYPE_INT, offsetof (SpaAudioInfo, info.raw.channel_mask) }, - { 0, } -}; - -static const ParseInfo * -parse_info_find (const ParseInfo *info, uint32_t key, uint32_t type) -{ - while (info->key) { - if (info->key == key && info->type == type) - return info; - info++; - } - return NULL; -} - SpaResult spa_format_audio_parse (const SpaFormat *format, SpaAudioInfo *info) { - SpaPODProp *prop; - const ParseInfo *pinfo, *find; + static SpaMediaTypes media_types = { 0, }; + static SpaMediaSubtypes media_subtypes = { 0, }; + static SpaMediaSubtypesAudio media_subtypes_audio = { 0, }; + static SpaPropAudio prop_audio = { 0, }; - if (format->body.media_type.value != SPA_MEDIA_TYPE_AUDIO) + spa_media_types_fill (&media_types, spa_id_map_get_default()); + spa_media_subtypes_map (spa_id_map_get_default(), &media_subtypes); + spa_media_subtypes_audio_map (spa_id_map_get_default (), &media_subtypes_audio); + spa_prop_audio_map (spa_id_map_get_default (), &prop_audio); + + if (format->body.media_type.value != media_types.audio) return SPA_RESULT_INVALID_MEDIA_TYPE; info->media_type = format->body.media_type.value; info->media_subtype = format->body.media_subtype.value; - switch (info->media_subtype) { - case SPA_MEDIA_SUBTYPE_RAW: - pinfo = raw_parse_info; - break; - case SPA_MEDIA_SUBTYPE_MP3: - case SPA_MEDIA_SUBTYPE_AAC: - case SPA_MEDIA_SUBTYPE_VORBIS: - case SPA_MEDIA_SUBTYPE_WMA: - case SPA_MEDIA_SUBTYPE_RA: - case SPA_MEDIA_SUBTYPE_SBC: - case SPA_MEDIA_SUBTYPE_ADPCM: - case SPA_MEDIA_SUBTYPE_G723: - case SPA_MEDIA_SUBTYPE_G726: - case SPA_MEDIA_SUBTYPE_G729: - case SPA_MEDIA_SUBTYPE_AMR: - case SPA_MEDIA_SUBTYPE_GSM: - return SPA_RESULT_NOT_IMPLEMENTED; - - default: - return SPA_RESULT_INVALID_ARGUMENTS; + if (info->media_subtype == media_subtypes.raw) { + spa_format_query (format, + prop_audio.format, SPA_POD_TYPE_INT, &info->info.raw.format, + prop_audio.flags, SPA_POD_TYPE_INT, &info->info.raw.flags, + prop_audio.layout, SPA_POD_TYPE_INT, &info->info.raw.layout, + prop_audio.rate, SPA_POD_TYPE_INT, &info->info.raw.rate, + prop_audio.channels, SPA_POD_TYPE_INT, &info->info.raw.channels, + prop_audio.channel_mask, SPA_POD_TYPE_INT, &info->info.raw.channel_mask, + 0); } + else + return SPA_RESULT_NOT_IMPLEMENTED; - SPA_FORMAT_FOREACH (format, prop) { - if ((find = parse_info_find (pinfo, prop->body.key, prop->body.value.type))) { - memcpy (SPA_MEMBER (info, find->offset, void), - SPA_POD_BODY (&prop->body.value), - SPA_POD_BODY_SIZE (&prop->body.value)); - } - } return SPA_RESULT_OK; } diff --git a/spa/lib/debug.c b/spa/lib/debug.c index cb93839de..bfea91126 100644 --- a/spa/lib/debug.c +++ b/spa/lib/debug.c @@ -19,6 +19,7 @@ #include +#include #include "debug.h" static const struct meta_type_name { @@ -180,92 +181,12 @@ spa_debug_props (const SpaProps *props, bool print_ranges) return SPA_RESULT_OK; } -static const char* media_audio_prop_names[] = { - "info", - "format", - "flags", - "layout", - "rate", - "channels", - "channel-mask", -}; - -static const char* media_video_prop_names[] = { - "info", - "format", - "size", - "framerate", - "max-framerate", - "views", - "interlace-mode", - "pixel-aspect-ratio", - "multiview-mode", - "multiview-flags", - "chroma-site", - "color-range", - "color-matrix", - "transfer-function", - "color-primaries", - "profile", - "stream-format", - "alignment", -}; - -static const struct media_type_name { - const char *name; - unsigned int first; - unsigned int last; - unsigned int idx; - const char **prop_names; -} media_type_names[] = { - { "invalid", 0, 0, 0 }, - { "audio", SPA_MEDIA_SUBTYPE_AUDIO_FIRST, SPA_MEDIA_SUBTYPE_AUDIO_LAST, 16, media_audio_prop_names }, - { "video", SPA_MEDIA_SUBTYPE_VIDEO_FIRST, SPA_MEDIA_SUBTYPE_VIDEO_LAST, 2, media_video_prop_names }, - { "image", 0, 0 }, -}; - - -static const struct media_subtype_name { - const char *name; -} media_subtype_names[] = { - { "invalid" }, - - { "raw" }, - - { "h264" }, - { "mjpg" }, - { "dv" }, - { "mpegts" }, - { "h263" }, - { "mpeg1" }, - { "mpeg2" }, - { "mpeg4" }, - { "xvid" }, - { "vc1" }, - { "vp8" }, - { "vp9" }, - { "jpeg" }, - { "bayer" }, - - { "mp3" }, - { "aac" }, - { "vorbis" }, - { "wma" }, - { "ra" }, - { "sbc" }, - { "adpcm" }, - { "g723" }, - { "g726" }, - { "g729" }, - { "amr" }, - { "gsm" }, -}; - struct pod_type_name { const char *name; const char *CCName; } pod_type_names[] = { { "invalid", "*Invalid*" }, + { "ignored", "ignored" }, { "bool", "Bool" }, { "uri", "URI" }, { "int", "Int" }, @@ -291,7 +212,8 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix) printf ("%-*sBool %d\n", prefix, "", *(int32_t *) body); break; case SPA_POD_TYPE_URI: - printf ("%-*sURI %d\n", prefix, "", *(int32_t *) body); + printf ("%-*sURI %d %s\n", prefix, "", *(int32_t *) body, + spa_id_map_get_uri (spa_id_map_get_default(), *(int32_t*)body)); break; case SPA_POD_TYPE_INT: printf ("%-*sInt %d\n", prefix, "", *(int32_t *) body); @@ -357,7 +279,8 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix) void *alt; int i; - printf ("%-*sProp: key %d, flags %d\n", prefix, "", b->key, b->flags); + printf ("%-*sProp: key %s, flags %d\n", prefix, "", + spa_id_map_get_uri (spa_id_map_get_default(), b->key), b->flags); if (b->flags & SPA_POD_PROP_FLAG_UNSET) printf ("%-*sUnset (Default):\n", prefix + 2, ""); else @@ -441,10 +364,9 @@ print_format_value (uint32_t size, uint32_t type, void *body) SpaResult spa_debug_format (const SpaFormat *format) { - int i, first, last, idx; + int i; const char *media_type; const char *media_subtype; - const char **prop_names; SpaPODProp *prop; uint32_t mtype, mstype; @@ -454,35 +376,22 @@ spa_debug_format (const SpaFormat *format) mtype = format->body.media_type.value; mstype = format->body.media_subtype.value; - if (mtype > 0 && mtype < SPA_N_ELEMENTS (media_type_names)) { - media_type = media_type_names[mtype].name; - first = media_type_names[mtype].first; - last = media_type_names[mtype].last; - idx = media_type_names[mtype].idx; - prop_names = media_type_names[mtype].prop_names; - } - else { - media_type = "unknown"; - idx = first = last = -1; - prop_names = NULL; - } + media_type = spa_id_map_get_uri (spa_id_map_get_default (), mtype); + media_subtype = spa_id_map_get_uri (spa_id_map_get_default (), mstype); - if (mstype >= SPA_MEDIA_SUBTYPE_ANY_FIRST && - mstype <= SPA_MEDIA_SUBTYPE_ANY_LAST) { - media_subtype = media_subtype_names[mstype].name; - } else if (mstype >= first && mstype <= last) - media_subtype = media_subtype_names[mstype - first + idx].name; - else - media_subtype = "unknown"; - - fprintf (stderr, "%-6s %s/%s\n", "", media_type, media_subtype); + fprintf (stderr, "%-6s %s/%s\n", "", strstr (media_type, "#")+1, strstr (media_subtype, "#")+1); SPA_FORMAT_FOREACH (format, prop) { + const char *key; + if ((prop->body.flags & SPA_POD_PROP_FLAG_UNSET) && (prop->body.flags & SPA_POD_PROP_FLAG_OPTIONAL)) continue; - fprintf (stderr, " %20s : (%s) ", prop_names[prop->body.key - SPA_PROP_ID_MEDIA_CUSTOM_START], pod_type_names[prop->body.value.type].name); + key = spa_id_map_get_uri (spa_id_map_get_default (), prop->body.key); + + fprintf (stderr, " %20s : (%s) ", strstr (key, "#")+1, pod_type_names[prop->body.value.type].name); + if (!(prop->body.flags & SPA_POD_PROP_FLAG_UNSET)) { print_format_value (prop->body.value.size, prop->body.value.type, SPA_POD_BODY (&prop->body.value)); } else { diff --git a/spa/lib/mapper.c b/spa/lib/mapper.c index cac4f17e0..71c5ff1f5 100644 --- a/spa/lib/mapper.c +++ b/spa/lib/mapper.c @@ -45,6 +45,7 @@ id_map_get_id (SpaIDMap *map, const char *uri) if (strcmp (this->uris[i], uri) == 0) return i; } + printf ("spa adding %d %s\n", i, uri); this->uris[i] = (char *)uri; this->n_uris++; } @@ -56,6 +57,8 @@ id_map_get_uri (SpaIDMap *map, uint32_t id) { IDMap *this = SPA_CONTAINER_OF (map, IDMap, map); + printf ("spa get %d\n", id); + if (id < this->n_uris) return this->uris[id]; return 0; @@ -71,8 +74,16 @@ static IDMap default_id_map = { 0 }; +static SpaIDMap *default_map = &default_id_map.map; + SpaIDMap * spa_id_map_get_default (void) { - return &default_id_map.map; + return default_map; +} + +void +spa_id_map_set_default (SpaIDMap *map) +{ + default_map = map; } diff --git a/spa/lib/mapper.h b/spa/lib/mapper.h index f04d514af..b5b418c71 100644 --- a/spa/lib/mapper.h +++ b/spa/lib/mapper.h @@ -26,6 +26,7 @@ extern "C" { #include +void spa_id_map_set_default (SpaIDMap *map); SpaIDMap * spa_id_map_get_default (void); #ifdef __cplusplus diff --git a/spa/lib/video-raw.c b/spa/lib/video-raw.c index c885b06f8..5eff754ed 100644 --- a/spa/lib/video-raw.c +++ b/spa/lib/video-raw.c @@ -26,107 +26,60 @@ #include #include #include - -typedef struct { - uint32_t key; - uint32_t type; - off_t offset; -} ParseInfo; - -static const ParseInfo raw_parse_info[] = { - { SPA_PROP_ID_VIDEO_INFO, SPA_POD_TYPE_BYTES, offsetof (SpaVideoInfo, info.raw) }, - { SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, offsetof (SpaVideoInfo, info.raw.format) }, - { SPA_PROP_ID_VIDEO_SIZE, SPA_POD_TYPE_RECTANGLE, offsetof (SpaVideoInfo, info.raw.size) }, - { SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_TYPE_FRACTION, offsetof (SpaVideoInfo, info.raw.framerate) }, - { SPA_PROP_ID_VIDEO_MAX_FRAMERATE, SPA_POD_TYPE_FRACTION, offsetof (SpaVideoInfo, info.raw.max_framerate) }, - { SPA_PROP_ID_VIDEO_VIEWS, SPA_POD_TYPE_INT, offsetof (SpaVideoInfo, info.raw.views) }, - { SPA_PROP_ID_VIDEO_INTERLACE_MODE, SPA_POD_TYPE_INT, offsetof (SpaVideoInfo, info.raw.interlace_mode) }, - { SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO, SPA_POD_TYPE_FRACTION, offsetof (SpaVideoInfo, info.raw.pixel_aspect_ratio) }, - { SPA_PROP_ID_VIDEO_MULTIVIEW_MODE, SPA_POD_TYPE_INT, offsetof (SpaVideoInfo, info.raw.multiview_mode) }, - { SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS, SPA_POD_TYPE_INT, offsetof (SpaVideoInfo, info.raw.multiview_flags) }, - { SPA_PROP_ID_VIDEO_CHROMA_SITE, SPA_POD_TYPE_INT, offsetof (SpaVideoInfo, info.raw.chroma_site) }, - { SPA_PROP_ID_VIDEO_COLOR_RANGE, SPA_POD_TYPE_INT, offsetof (SpaVideoInfo, info.raw.color_range) }, - { SPA_PROP_ID_VIDEO_COLOR_MATRIX, SPA_POD_TYPE_INT, offsetof (SpaVideoInfo, info.raw.color_matrix) }, - { SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION, SPA_POD_TYPE_INT, offsetof (SpaVideoInfo, info.raw.transfer_function) }, - { SPA_PROP_ID_VIDEO_COLOR_PRIMARIES, SPA_POD_TYPE_INT, offsetof (SpaVideoInfo, info.raw.color_primaries) }, - { 0, } -}; - -static const ParseInfo h264_parse_info[] = { - { SPA_PROP_ID_VIDEO_INFO, SPA_POD_TYPE_BYTES, offsetof (SpaVideoInfo, info.h264) }, - { SPA_PROP_ID_VIDEO_SIZE, SPA_POD_TYPE_RECTANGLE, offsetof (SpaVideoInfo, info.h264.size) }, - { SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_TYPE_FRACTION, offsetof (SpaVideoInfo, info.h264.framerate) }, - { SPA_PROP_ID_VIDEO_MAX_FRAMERATE, SPA_POD_TYPE_FRACTION, offsetof (SpaVideoInfo, info.h264.max_framerate) }, - { 0, } -}; - -static const ParseInfo mjpg_parse_info[] = { - { SPA_PROP_ID_VIDEO_INFO, SPA_POD_TYPE_BYTES, offsetof (SpaVideoInfo, info.h264) }, - { SPA_PROP_ID_VIDEO_SIZE, SPA_POD_TYPE_RECTANGLE, offsetof (SpaVideoInfo, info.h264.size) }, - { SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_TYPE_FRACTION, offsetof (SpaVideoInfo, info.h264.framerate) }, - { SPA_PROP_ID_VIDEO_MAX_FRAMERATE, SPA_POD_TYPE_FRACTION, offsetof (SpaVideoInfo, info.h264.max_framerate) }, - { 0, } -}; - -static const ParseInfo * -parse_info_find (const ParseInfo *info, uint32_t key, uint32_t type) -{ - while (info->key) { - if (info->key == key && info->type == type) - return info; - info++; - } - return NULL; -} +#include SpaResult -spa_format_video_parse (const SpaFormat *format, - SpaVideoInfo *info) +spa_format_video_parse (const SpaFormat *format, + SpaVideoInfo *info) { - SpaPODProp *prop; - const ParseInfo *pinfo, *find; + static SpaMediaTypes media_types = { 0, }; + static SpaMediaSubtypes media_subtypes = { 0, }; + static SpaMediaSubtypesVideo media_subtypes_video = { 0, }; + static SpaPropVideo prop_video = { 0, }; - if (format->body.media_type.value != SPA_MEDIA_TYPE_VIDEO) + spa_media_types_fill (&media_types, spa_id_map_get_default ()); + spa_media_subtypes_map (spa_id_map_get_default (), &media_subtypes); + spa_media_subtypes_video_map (spa_id_map_get_default (), &media_subtypes_video); + spa_prop_video_map (spa_id_map_get_default (), &prop_video); + + if (format->body.media_type.value != media_types.video) return SPA_RESULT_INVALID_MEDIA_TYPE; info->media_type = format->body.media_type.value; info->media_subtype = format->body.media_subtype.value; - switch (info->media_subtype) { - case SPA_MEDIA_SUBTYPE_RAW: - pinfo = raw_parse_info; - break; - case SPA_MEDIA_SUBTYPE_H264: - pinfo = h264_parse_info; - break; - case SPA_MEDIA_SUBTYPE_MJPG: - pinfo = mjpg_parse_info; - break; - case SPA_MEDIA_SUBTYPE_DV: - case SPA_MEDIA_SUBTYPE_MPEGTS: - case SPA_MEDIA_SUBTYPE_H263: - case SPA_MEDIA_SUBTYPE_MPEG1: - case SPA_MEDIA_SUBTYPE_MPEG2: - case SPA_MEDIA_SUBTYPE_MPEG4: - case SPA_MEDIA_SUBTYPE_XVID: - case SPA_MEDIA_SUBTYPE_VC1: - case SPA_MEDIA_SUBTYPE_VP8: - case SPA_MEDIA_SUBTYPE_VP9: - case SPA_MEDIA_SUBTYPE_JPEG: - case SPA_MEDIA_SUBTYPE_BAYER: - return SPA_RESULT_NOT_IMPLEMENTED; + if (info->media_subtype == media_subtypes.raw) + spa_format_query (format, + prop_video.format, SPA_POD_TYPE_INT, &info->info.raw.format, + prop_video.size, SPA_POD_TYPE_RECTANGLE, &info->info.raw.size, + prop_video.framerate, SPA_POD_TYPE_FRACTION, &info->info.raw.framerate, + prop_video.max_framerate, SPA_POD_TYPE_FRACTION, &info->info.raw.max_framerate, + prop_video.views, SPA_POD_TYPE_INT, &info->info.raw.views, + prop_video.interlace_mode, SPA_POD_TYPE_INT, &info->info.raw.interlace_mode, + prop_video.pixel_aspect_ratio, SPA_POD_TYPE_FRACTION, &info->info.raw.pixel_aspect_ratio, + prop_video.multiview_mode, SPA_POD_TYPE_INT, &info->info.raw.multiview_mode, + prop_video.multiview_flags, SPA_POD_TYPE_INT, &info->info.raw.multiview_flags, + prop_video.chroma_site, SPA_POD_TYPE_INT, &info->info.raw.chroma_site, + prop_video.color_range, SPA_POD_TYPE_INT, &info->info.raw.color_range, + prop_video.color_matrix, SPA_POD_TYPE_INT, &info->info.raw.color_matrix, + prop_video.transfer_function, SPA_POD_TYPE_INT, &info->info.raw.transfer_function, + prop_video.color_primaries, SPA_POD_TYPE_INT, &info->info.raw.color_primaries, + 0); + else if (info->media_subtype == media_subtypes_video.h264) + spa_format_query (format, + prop_video.size, SPA_POD_TYPE_RECTANGLE, &info->info.h264.size, + prop_video.framerate, SPA_POD_TYPE_FRACTION, &info->info.h264.framerate, + prop_video.max_framerate, SPA_POD_TYPE_FRACTION, &info->info.h264.max_framerate, + 0); + else if (info->media_subtype == media_subtypes_video.mjpg) + spa_format_query (format, + prop_video.size, SPA_POD_TYPE_RECTANGLE, &info->info.mjpg.size, + prop_video.framerate, SPA_POD_TYPE_FRACTION, &info->info.mjpg.framerate, + prop_video.max_framerate, SPA_POD_TYPE_FRACTION, &info->info.mjpg.max_framerate, + 0); + else + return SPA_RESULT_NOT_IMPLEMENTED; - default: - return SPA_RESULT_INVALID_ARGUMENTS; - } - - SPA_FORMAT_FOREACH (format, prop) { - if ((find = parse_info_find (pinfo, prop->body.key, prop->body.value.type))) { - memcpy (SPA_MEMBER (info, find->offset, void), - SPA_POD_BODY (&prop->body.value), - SPA_POD_BODY_SIZE (&prop->body.value)); - } - } return SPA_RESULT_OK; } diff --git a/spa/plugins/alsa/alsa-sink.c b/spa/plugins/alsa/alsa-sink.c index b2acdad6e..deed7a1ba 100644 --- a/spa/plugins/alsa/alsa-sink.c +++ b/spa/plugins/alsa/alsa-sink.c @@ -325,17 +325,17 @@ next: switch (index++) { case 0: spa_pod_builder_format (&b, &f[0], - SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, - PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16, + this->uri.media_types.audio, this->uri.media_subtypes.raw, + PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_S32), - PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX), - PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, 2, 1, INT32_MAX)); + PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX), + PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX)); break; case 1: spa_pod_builder_format (&b, &f[0], - SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_AAC, - 0); + this->uri.media_types.audio, this->uri.media_subtypes_audio.aac, + SPA_POD_TYPE_NONE); break; default: return SPA_RESULT_ENUM_END; @@ -795,6 +795,10 @@ alsa_sink_init (const SpaHandleFactory *factory, return SPA_RESULT_ERROR; } this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI); + spa_media_types_fill (&this->uri.media_types, this->map); + spa_media_subtypes_map (this->map, &this->uri.media_subtypes); + spa_media_subtypes_audio_map (this->map, &this->uri.media_subtypes_audio); + spa_prop_audio_map (this->map, &this->uri.prop_audio); this->node = alsasink_node; this->stream = SND_PCM_STREAM_PLAYBACK; diff --git a/spa/plugins/alsa/alsa-source.c b/spa/plugins/alsa/alsa-source.c index 8f3f8d86a..f1c7ce101 100644 --- a/spa/plugins/alsa/alsa-source.c +++ b/spa/plugins/alsa/alsa-source.c @@ -109,7 +109,7 @@ spa_alsa_source_node_get_props (SpaNode *node, static SpaResult spa_alsa_source_node_set_props (SpaNode *node, - const SpaProps *props) + const SpaProps *props) { SpaALSASource *this; @@ -359,17 +359,17 @@ next: switch (index++) { case 0: spa_pod_builder_format (&b, &f[0], - SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, - PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S32), - PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX), - PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, 2, 1, INT32_MAX)); + this->uri.media_types.audio, this->uri.media_subtypes.raw, + PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S32), + PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX), + PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX)); break; case 1: spa_pod_builder_format (&b, &f[0], - SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_AAC, - 0); + this->uri.media_types.audio, this->uri.media_subtypes_audio.aac, + SPA_POD_TYPE_NONE); default: return SPA_RESULT_ENUM_END; } @@ -861,6 +861,11 @@ alsa_source_init (const SpaHandleFactory *factory, this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI); this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI); + spa_media_types_fill (&this->uri.media_types, this->map); + spa_media_subtypes_map (this->map, &this->uri.media_subtypes); + spa_media_subtypes_audio_map (this->map, &this->uri.media_subtypes_audio); + spa_prop_audio_map (this->map, &this->uri.prop_audio); + this->node = alsasource_node; this->clock = alsasource_clock; this->stream = SND_PCM_STREAM_CAPTURE; diff --git a/spa/plugins/alsa/alsa-utils.h b/spa/plugins/alsa/alsa-utils.h index af00294cf..6890ac5e8 100644 --- a/spa/plugins/alsa/alsa-utils.h +++ b/spa/plugins/alsa/alsa-utils.h @@ -62,6 +62,10 @@ struct _SpaALSABuffer { typedef struct { uint32_t node; uint32_t clock; + SpaMediaTypes media_types; + SpaMediaSubtypes media_subtypes; + SpaMediaSubtypesAudio media_subtypes_audio; + SpaPropAudio prop_audio; } URI; struct _SpaALSAState { diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c index 1589fdee0..c366728b7 100644 --- a/spa/plugins/audiotestsrc/audiotestsrc.c +++ b/spa/plugins/audiotestsrc/audiotestsrc.c @@ -39,6 +39,9 @@ typedef struct { uint32_t node; uint32_t clock; + SpaMediaTypes media_types; + SpaMediaSubtypes media_subtypes; + SpaPropAudio prop_audio; } URI; typedef struct _SpaAudioTestSrc SpaAudioTestSrc; @@ -467,12 +470,12 @@ next: switch (index++) { case 0: spa_pod_builder_format (&b, &f[0], - SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, - PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16, + this->uri.media_types.audio, this->uri.media_subtypes.raw, + PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_S32), - PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX), - PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, 2, 1, INT32_MAX)); + PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX), + PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX)); break; default: return SPA_RESULT_ENUM_END; @@ -585,10 +588,10 @@ spa_audiotestsrc_node_port_get_format (SpaNode *node, spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer)); spa_pod_builder_format (&b, &f[0], - SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, - PROP (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, this->current_format.info.raw.format), - PROP (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, this->current_format.info.raw.rate), - PROP (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, this->current_format.info.raw.channels)); + this->uri.media_types.audio, this->uri.media_subtypes.raw, + PROP (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_INT, this->current_format.info.raw.format), + PROP (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, this->current_format.info.raw.rate), + PROP (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, this->current_format.info.raw.channels)); *format = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); @@ -952,6 +955,9 @@ audiotestsrc_init (const SpaHandleFactory *factory, } this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI); this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI); + spa_media_types_fill (&this->uri.media_types, this->map); + spa_media_subtypes_map (this->map, &this->uri.media_subtypes); + spa_prop_audio_map (this->map, &this->uri.prop_audio); this->node = audiotestsrc_node; this->clock = audiotestsrc_clock; diff --git a/spa/plugins/ffmpeg/ffmpeg-enc.c b/spa/plugins/ffmpeg/ffmpeg-enc.c index af41292ce..ae898e938 100644 --- a/spa/plugins/ffmpeg/ffmpeg-enc.c +++ b/spa/plugins/ffmpeg/ffmpeg-enc.c @@ -57,6 +57,8 @@ typedef struct { typedef struct { uint32_t node; + SpaMediaTypes media_types; + SpaMediaSubtypes media_subtypes; } URI; struct _SpaFFMpegEnc { @@ -264,8 +266,8 @@ spa_ffmpeg_enc_node_port_set_format (SpaNode *node, return SPA_RESULT_OK; } - if (format->body.media_type.value != SPA_MEDIA_TYPE_VIDEO || - format->body.media_subtype.value != SPA_MEDIA_SUBTYPE_RAW) + if (format->body.media_type.value != this->uri.media_types.video || + format->body.media_subtype.value != this->uri.media_subtypes.raw) return SPA_RESULT_INVALID_MEDIA_TYPE; if ((res = spa_format_video_parse (format, &query_format) < 0)) @@ -542,6 +544,8 @@ spa_ffmpeg_enc_init (SpaHandle *handle, return SPA_RESULT_ERROR; } this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI); + spa_media_types_fill (&this->uri.media_types, this->map); + spa_media_subtypes_map (this->map, &this->uri.media_subtypes); this->node = ffmpeg_enc_node; diff --git a/spa/plugins/v4l2/v4l2-source.c b/spa/plugins/v4l2/v4l2-source.c index 35e0cb38f..e1b746530 100644 --- a/spa/plugins/v4l2/v4l2-source.c +++ b/spa/plugins/v4l2/v4l2-source.c @@ -65,6 +65,10 @@ struct _V4l2Buffer { typedef struct { uint32_t node; uint32_t clock; + SpaMediaTypes media_types; + SpaMediaSubtypes media_subtypes; + SpaMediaSubtypesVideo media_subtypes_video; + SpaPropVideo prop_video; } URI; typedef struct { @@ -112,9 +116,9 @@ struct _SpaV4l2Source { SpaNode node; SpaClock clock; - URI uri; SpaIDMap *map; SpaLog *log; + URI uri; uint32_t seq; @@ -573,38 +577,28 @@ spa_v4l2_source_node_port_get_format (SpaNode *node, state->current_format.media_type, state->current_format.media_subtype); - switch (state->current_format.media_subtype) { - case SPA_MEDIA_SUBTYPE_RAW: - spa_pod_builder_add (&b, - PROP (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, state->current_format.info.raw.format), - PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.raw.size), - PROP (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, -SPA_POD_TYPE_FRACTION, &state->current_format.info.raw.framerate), - 0); - break; - case SPA_MEDIA_SUBTYPE_MJPG: - case SPA_MEDIA_SUBTYPE_JPEG: - spa_pod_builder_add (&b, - PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.mjpg.size), - PROP (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, -SPA_POD_TYPE_FRACTION, &state->current_format.info.mjpg.framerate), - 0); - break; - case SPA_MEDIA_SUBTYPE_H264: - spa_pod_builder_add (&b, - PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.h264.size), - PROP (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, -SPA_POD_TYPE_FRACTION, &state->current_format.info.h264.framerate), - 0); - break; - case SPA_MEDIA_SUBTYPE_DV: - case SPA_MEDIA_SUBTYPE_MPEGTS: - case SPA_MEDIA_SUBTYPE_MPEG1: - case SPA_MEDIA_SUBTYPE_MPEG2: - case SPA_MEDIA_SUBTYPE_MPEG4: - case SPA_MEDIA_SUBTYPE_XVID: - case SPA_MEDIA_SUBTYPE_VC1: - case SPA_MEDIA_SUBTYPE_VP8: - default: - return SPA_RESULT_NO_FORMAT; + if (state->current_format.media_subtype == this->uri.media_subtypes.raw) { + spa_pod_builder_add (&b, + PROP (&f[1], this->uri.prop_video.format, SPA_POD_TYPE_INT, state->current_format.info.raw.format), + PROP (&f[1], this->uri.prop_video.size, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.raw.size), + PROP (&f[1], this->uri.prop_video.framerate, -SPA_POD_TYPE_FRACTION, &state->current_format.info.raw.framerate), + 0); } + else if (state->current_format.media_subtype == this->uri.media_subtypes_video.mjpg || + state->current_format.media_subtype == this->uri.media_subtypes_video.jpeg) { + spa_pod_builder_add (&b, + PROP (&f[1], this->uri.prop_video.size, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.mjpg.size), + PROP (&f[1], this->uri.prop_video.framerate, -SPA_POD_TYPE_FRACTION, &state->current_format.info.mjpg.framerate), + 0); + } + else if (state->current_format.media_subtype == this->uri.media_subtypes_video.h264) { + spa_pod_builder_add (&b, + PROP (&f[1], this->uri.prop_video.size, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.h264.size), + PROP (&f[1], this->uri.prop_video.framerate, -SPA_POD_TYPE_FRACTION, &state->current_format.info.h264.framerate), + 0); + } else + return SPA_RESULT_NO_FORMAT; + spa_pod_builder_pop (&b, &f[0]); *format = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); @@ -974,6 +968,10 @@ v4l2_source_init (const SpaHandleFactory *factory, } this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI); this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI); + spa_media_types_fill (&this->uri.media_types, this->map); + spa_media_subtypes_map (this->map, &this->uri.media_subtypes); + spa_media_subtypes_video_map (this->map, &this->uri.media_subtypes_video); + spa_prop_video_map (this->map, &this->uri.prop_video); this->node = v4l2source_node; this->clock = v4l2source_clock; diff --git a/spa/plugins/v4l2/v4l2-utils.c b/spa/plugins/v4l2/v4l2-utils.c index ef9ae3a2b..892b20126 100644 --- a/spa/plugins/v4l2/v4l2-utils.c +++ b/spa/plugins/v4l2/v4l2-utils.c @@ -165,117 +165,137 @@ spa_v4l2_close (SpaV4l2Source *this) typedef struct { uint32_t fourcc; SpaVideoFormat format; - SpaMediaType media_type; - SpaMediaSubType media_subtype; + off_t media_type_offset; + off_t media_subtype_offset; } FormatInfo; +#define VIDEO offsetof(URI, media_types.video) +#define IMAGE offsetof(URI, media_types.image) + +#define RAW offsetof(URI, media_subtypes.raw) + +#define BAYER offsetof(URI, media_subtypes_video.bayer) +#define MJPG offsetof(URI, media_subtypes_video.mjpg) +#define JPEG offsetof(URI, media_subtypes_video.jpeg) +#define DV offsetof(URI, media_subtypes_video.dv) +#define MPEGTS offsetof(URI, media_subtypes_video.mpegts) +#define H264 offsetof(URI, media_subtypes_video.h264) +#define H263 offsetof(URI, media_subtypes_video.h263) +#define MPEG1 offsetof(URI, media_subtypes_video.mpeg1) +#define MPEG2 offsetof(URI, media_subtypes_video.mpeg2) +#define MPEG4 offsetof(URI, media_subtypes_video.mpeg4) +#define XVID offsetof(URI, media_subtypes_video.xvid) +#define VC1 offsetof(URI, media_subtypes_video.vc1) +#define VP8 offsetof(URI, media_subtypes_video.vp8) + + static const FormatInfo format_info[] = { /* RGB formats */ - { V4L2_PIX_FMT_RGB332, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_ARGB555, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_XRGB555, SPA_VIDEO_FORMAT_RGB15, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_ARGB555X, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_XRGB555X, SPA_VIDEO_FORMAT_BGR15, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_RGB565, SPA_VIDEO_FORMAT_RGB16, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_RGB565X, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_BGR666, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_BGR24, SPA_VIDEO_FORMAT_BGR, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_RGB24, SPA_VIDEO_FORMAT_RGB, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_ABGR32, SPA_VIDEO_FORMAT_BGRA, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_XBGR32, SPA_VIDEO_FORMAT_BGRx, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_ARGB32, SPA_VIDEO_FORMAT_ARGB, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_XRGB32, SPA_VIDEO_FORMAT_xRGB, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, + { V4L2_PIX_FMT_RGB332, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_ARGB555, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_XRGB555, SPA_VIDEO_FORMAT_RGB15, VIDEO, RAW }, + { V4L2_PIX_FMT_ARGB555X, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_XRGB555X, SPA_VIDEO_FORMAT_BGR15, VIDEO, RAW }, + { V4L2_PIX_FMT_RGB565, SPA_VIDEO_FORMAT_RGB16, VIDEO, RAW }, + { V4L2_PIX_FMT_RGB565X, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_BGR666, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_BGR24, SPA_VIDEO_FORMAT_BGR, VIDEO, RAW }, + { V4L2_PIX_FMT_RGB24, SPA_VIDEO_FORMAT_RGB, VIDEO, RAW }, + { V4L2_PIX_FMT_ABGR32, SPA_VIDEO_FORMAT_BGRA, VIDEO, RAW }, + { V4L2_PIX_FMT_XBGR32, SPA_VIDEO_FORMAT_BGRx, VIDEO, RAW }, + { V4L2_PIX_FMT_ARGB32, SPA_VIDEO_FORMAT_ARGB, VIDEO, RAW }, + { V4L2_PIX_FMT_XRGB32, SPA_VIDEO_FORMAT_xRGB, VIDEO, RAW }, /* Deprecated Packed RGB Image Formats (alpha ambiguity) */ - { V4L2_PIX_FMT_RGB444, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_RGB555, SPA_VIDEO_FORMAT_RGB15, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_RGB555X, SPA_VIDEO_FORMAT_BGR15, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_BGR32, SPA_VIDEO_FORMAT_BGRx, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_RGB32, SPA_VIDEO_FORMAT_xRGB, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, + { V4L2_PIX_FMT_RGB444, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_RGB555, SPA_VIDEO_FORMAT_RGB15, VIDEO, RAW }, + { V4L2_PIX_FMT_RGB555X, SPA_VIDEO_FORMAT_BGR15, VIDEO, RAW }, + { V4L2_PIX_FMT_BGR32, SPA_VIDEO_FORMAT_BGRx, VIDEO, RAW }, + { V4L2_PIX_FMT_RGB32, SPA_VIDEO_FORMAT_xRGB, VIDEO, RAW }, /* Grey formats */ - { V4L2_PIX_FMT_GREY, SPA_VIDEO_FORMAT_GRAY8, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_Y4, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_Y6, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_Y10, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_Y12, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_Y16, SPA_VIDEO_FORMAT_GRAY16_LE, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_Y16_BE, SPA_VIDEO_FORMAT_GRAY16_BE, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_Y10BPACK, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, + { V4L2_PIX_FMT_GREY, SPA_VIDEO_FORMAT_GRAY8, VIDEO, RAW }, + { V4L2_PIX_FMT_Y4, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_Y6, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_Y10, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_Y12, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_Y16, SPA_VIDEO_FORMAT_GRAY16_LE, VIDEO, RAW }, + { V4L2_PIX_FMT_Y16_BE, SPA_VIDEO_FORMAT_GRAY16_BE, VIDEO, RAW }, + { V4L2_PIX_FMT_Y10BPACK, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, /* Palette formats */ - { V4L2_PIX_FMT_PAL8, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, + { V4L2_PIX_FMT_PAL8, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, /* Chrominance formats */ - { V4L2_PIX_FMT_UV8, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, + { V4L2_PIX_FMT_UV8, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, /* Luminance+Chrominance formats */ - { V4L2_PIX_FMT_YVU410, SPA_VIDEO_FORMAT_YVU9, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YVU420, SPA_VIDEO_FORMAT_YV12, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YVU420M, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YUYV, SPA_VIDEO_FORMAT_YUY2, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YYUV, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YVYU, SPA_VIDEO_FORMAT_YVYU, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_UYVY, SPA_VIDEO_FORMAT_UYVY, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_VYUY, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YUV422P, SPA_VIDEO_FORMAT_Y42B, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YUV411P, SPA_VIDEO_FORMAT_Y41B, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_Y41P, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YUV444, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YUV555, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YUV565, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YUV32, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YUV410, SPA_VIDEO_FORMAT_YUV9, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YUV420, SPA_VIDEO_FORMAT_I420, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_YUV420M, SPA_VIDEO_FORMAT_I420, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_HI240, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_HM12, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_M420, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, + { V4L2_PIX_FMT_YVU410, SPA_VIDEO_FORMAT_YVU9, VIDEO, RAW }, + { V4L2_PIX_FMT_YVU420, SPA_VIDEO_FORMAT_YV12, VIDEO, RAW }, + { V4L2_PIX_FMT_YVU420M, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_YUYV, SPA_VIDEO_FORMAT_YUY2, VIDEO, RAW }, + { V4L2_PIX_FMT_YYUV, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_YVYU, SPA_VIDEO_FORMAT_YVYU, VIDEO, RAW }, + { V4L2_PIX_FMT_UYVY, SPA_VIDEO_FORMAT_UYVY, VIDEO, RAW }, + { V4L2_PIX_FMT_VYUY, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_YUV422P, SPA_VIDEO_FORMAT_Y42B, VIDEO, RAW }, + { V4L2_PIX_FMT_YUV411P, SPA_VIDEO_FORMAT_Y41B, VIDEO, RAW }, + { V4L2_PIX_FMT_Y41P, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_YUV444, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_YUV555, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_YUV565, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_YUV32, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_YUV410, SPA_VIDEO_FORMAT_YUV9, VIDEO, RAW }, + { V4L2_PIX_FMT_YUV420, SPA_VIDEO_FORMAT_I420, VIDEO, RAW }, + { V4L2_PIX_FMT_YUV420M, SPA_VIDEO_FORMAT_I420, VIDEO, RAW }, + { V4L2_PIX_FMT_HI240, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_HM12, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_M420, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, /* two planes -- one Y, one Cr + Cb interleaved */ - { V4L2_PIX_FMT_NV12, SPA_VIDEO_FORMAT_NV12, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_NV12M, SPA_VIDEO_FORMAT_NV12, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_NV12MT, SPA_VIDEO_FORMAT_NV12_64Z32, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_NV12MT_16X16, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_NV21, SPA_VIDEO_FORMAT_NV21, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_NV21M, SPA_VIDEO_FORMAT_NV21, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_NV16, SPA_VIDEO_FORMAT_NV16, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_NV16M, SPA_VIDEO_FORMAT_NV16, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_NV61, SPA_VIDEO_FORMAT_NV61, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_NV61M, SPA_VIDEO_FORMAT_NV61, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_NV24, SPA_VIDEO_FORMAT_NV24, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_NV42, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, + { V4L2_PIX_FMT_NV12, SPA_VIDEO_FORMAT_NV12, VIDEO, RAW }, + { V4L2_PIX_FMT_NV12M, SPA_VIDEO_FORMAT_NV12, VIDEO, RAW }, + { V4L2_PIX_FMT_NV12MT, SPA_VIDEO_FORMAT_NV12_64Z32, VIDEO, RAW }, + { V4L2_PIX_FMT_NV12MT_16X16, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_NV21, SPA_VIDEO_FORMAT_NV21, VIDEO, RAW }, + { V4L2_PIX_FMT_NV21M, SPA_VIDEO_FORMAT_NV21, VIDEO, RAW }, + { V4L2_PIX_FMT_NV16, SPA_VIDEO_FORMAT_NV16, VIDEO, RAW }, + { V4L2_PIX_FMT_NV16M, SPA_VIDEO_FORMAT_NV16, VIDEO, RAW }, + { V4L2_PIX_FMT_NV61, SPA_VIDEO_FORMAT_NV61, VIDEO, RAW }, + { V4L2_PIX_FMT_NV61M, SPA_VIDEO_FORMAT_NV61, VIDEO, RAW }, + { V4L2_PIX_FMT_NV24, SPA_VIDEO_FORMAT_NV24, VIDEO, RAW }, + { V4L2_PIX_FMT_NV42, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ - { V4L2_PIX_FMT_SBGGR8, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_BAYER }, - { V4L2_PIX_FMT_SGBRG8, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_BAYER }, - { V4L2_PIX_FMT_SGRBG8, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_BAYER }, - { V4L2_PIX_FMT_SRGGB8, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_BAYER }, + { V4L2_PIX_FMT_SBGGR8, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, BAYER }, + { V4L2_PIX_FMT_SGBRG8, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, BAYER }, + { V4L2_PIX_FMT_SGRBG8, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, BAYER }, + { V4L2_PIX_FMT_SRGGB8, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, BAYER }, /* compressed formats */ - { V4L2_PIX_FMT_MJPEG, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_MJPG }, - { V4L2_PIX_FMT_JPEG, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_IMAGE, SPA_MEDIA_SUBTYPE_JPEG }, - { V4L2_PIX_FMT_PJPG, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_DV, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_DV }, - { V4L2_PIX_FMT_MPEG, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_MPEGTS }, - { V4L2_PIX_FMT_H264, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_H264 }, - { V4L2_PIX_FMT_H264_NO_SC, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_H264 }, - { V4L2_PIX_FMT_H264_MVC, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_H264 }, - { V4L2_PIX_FMT_H263, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_H263 }, - { V4L2_PIX_FMT_MPEG1, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_MPEG1 }, - { V4L2_PIX_FMT_MPEG2, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_MPEG2 }, - { V4L2_PIX_FMT_MPEG4, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_MPEG4 }, - { V4L2_PIX_FMT_XVID, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_XVID }, - { V4L2_PIX_FMT_VC1_ANNEX_G, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_VC1 }, - { V4L2_PIX_FMT_VC1_ANNEX_L, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_VC1 }, - { V4L2_PIX_FMT_VP8, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_VP8 }, + { V4L2_PIX_FMT_MJPEG, SPA_VIDEO_FORMAT_ENCODED, VIDEO, MJPG }, + { V4L2_PIX_FMT_JPEG, SPA_VIDEO_FORMAT_ENCODED, IMAGE, JPEG }, + { V4L2_PIX_FMT_PJPG, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_DV, SPA_VIDEO_FORMAT_ENCODED, VIDEO, DV }, + { V4L2_PIX_FMT_MPEG, SPA_VIDEO_FORMAT_ENCODED, VIDEO, MPEGTS }, + { V4L2_PIX_FMT_H264, SPA_VIDEO_FORMAT_ENCODED, VIDEO, H264 }, + { V4L2_PIX_FMT_H264_NO_SC, SPA_VIDEO_FORMAT_ENCODED, VIDEO, H264 }, + { V4L2_PIX_FMT_H264_MVC, SPA_VIDEO_FORMAT_ENCODED, VIDEO, H264 }, + { V4L2_PIX_FMT_H263, SPA_VIDEO_FORMAT_ENCODED, VIDEO, H263 }, + { V4L2_PIX_FMT_MPEG1, SPA_VIDEO_FORMAT_ENCODED, VIDEO, MPEG1 }, + { V4L2_PIX_FMT_MPEG2, SPA_VIDEO_FORMAT_ENCODED, VIDEO, MPEG2 }, + { V4L2_PIX_FMT_MPEG4, SPA_VIDEO_FORMAT_ENCODED, VIDEO, MPEG4 }, + { V4L2_PIX_FMT_XVID, SPA_VIDEO_FORMAT_ENCODED, VIDEO, XVID }, + { V4L2_PIX_FMT_VC1_ANNEX_G, SPA_VIDEO_FORMAT_ENCODED, VIDEO, VC1 }, + { V4L2_PIX_FMT_VC1_ANNEX_L, SPA_VIDEO_FORMAT_ENCODED, VIDEO, VC1 }, + { V4L2_PIX_FMT_VP8, SPA_VIDEO_FORMAT_ENCODED, VIDEO, VP8 }, /* Vendor-specific formats */ - { V4L2_PIX_FMT_WNVA, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_SN9C10X, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_PWC1, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, - { V4L2_PIX_FMT_PWC2, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, + { V4L2_PIX_FMT_WNVA, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_SN9C10X, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_PWC1, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, + { V4L2_PIX_FMT_PWC2, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW }, }; static const FormatInfo * @@ -305,35 +325,42 @@ video_format_to_format_info (SpaVideoFormat format) #endif static const FormatInfo * -find_format_info_by_media_type (SpaMediaType type, - SpaMediaSubType subtype, +find_format_info_by_media_type (URI *uri, + uint32_t type, + uint32_t subtype, SpaVideoFormat format, int startidx) { int i; for (i = startidx; i < SPA_N_ELEMENTS (format_info); i++) { - if ((format_info[i].media_type == type) && - (format_info[i].media_subtype == subtype) && - (format == SPA_VIDEO_FORMAT_UNKNOWN || format_info[i].format == format)) + uint32_t media_type, media_subtype, media_format; + + media_type = *SPA_MEMBER (uri, format_info[i].media_type_offset, uint32_t); + media_subtype = *SPA_MEMBER (uri, format_info[i].media_subtype_offset, uint32_t); + media_format = format_info[i].format; + + if ((media_type == type) && + (media_subtype == subtype) && + (format == SPA_VIDEO_FORMAT_UNKNOWN || media_format == format)) return &format_info[i]; } return NULL; } static SpaVideoFormat -enum_filter_format (const SpaFormat *filter, uint32_t index) +enum_filter_format (URI *uri, const SpaFormat *filter, uint32_t index) { SpaVideoFormat video_format = SPA_VIDEO_FORMAT_UNKNOWN; - if ((filter->body.media_type.value == SPA_MEDIA_TYPE_VIDEO || - filter->body.media_type.value == SPA_MEDIA_TYPE_IMAGE)) { - if (filter->body.media_subtype.value == SPA_MEDIA_SUBTYPE_RAW) { + if ((filter->body.media_type.value == uri->media_types.video || + filter->body.media_type.value == uri->media_types.image)) { + if (filter->body.media_subtype.value == uri->media_subtypes.raw) { SpaPODProp *p; uint32_t n_values; const uint32_t *values; - if (!(p = spa_format_find_prop (filter, SPA_PROP_ID_VIDEO_FORMAT))) + if (!(p = spa_format_find_prop (filter, uri->prop_video.format))) return SPA_VIDEO_FORMAT_UNKNOWN; if (p->body.value.type != SPA_POD_TYPE_INT) @@ -457,6 +484,7 @@ spa_v4l2_enum_format (SpaV4l2Source *this, SpaPODFrame f[2]; SpaPODProp *prop; SpaPODBuilder b = { state->format_buffer, sizeof (state->format_buffer), }; + uint32_t media_type, media_subtype; if (spa_v4l2_open (this) < 0) return SPA_RESULT_ERROR; @@ -483,11 +511,12 @@ next_fmtdesc: if (filter) { SpaVideoFormat video_format; - video_format = enum_filter_format (filter, state->fmtdesc.index); + video_format = enum_filter_format (&this->uri, filter, state->fmtdesc.index); if (video_format == SPA_VIDEO_FORMAT_UNKNOWN) return SPA_RESULT_ENUM_END; - info = find_format_info_by_media_type (filter->body.media_type.value, + info = find_format_info_by_media_type (&this->uri, + filter->body.media_type.value, filter->body.media_subtype.value, video_format, 0); @@ -516,7 +545,7 @@ next_frmsize: SpaPODProp *p; /* check if we have a fixed frame size */ - if (!(p = spa_format_find_prop (filter, SPA_PROP_ID_VIDEO_SIZE))) + if (!(p = spa_format_find_prop (filter, this->uri.prop_video.size))) goto do_frmsize; if (p->body.value.type != SPA_POD_TYPE_RECTANGLE) @@ -549,7 +578,7 @@ do_frmsize: uint32_t i, n_values; /* check if we have a fixed frame size */ - if (!(p = spa_format_find_prop (filter, SPA_PROP_ID_VIDEO_SIZE))) + if (!(p = spa_format_find_prop (filter, this->uri.prop_video.size))) goto have_size; range = p->body.flags & SPA_POD_PROP_RANGE_MASK; @@ -602,22 +631,25 @@ have_size: } } - spa_pod_builder_push_format (&b, &f[0], - info->media_type, - info->media_subtype); + media_type = *SPA_MEMBER (&this->uri, info->media_type_offset, uint32_t); + media_subtype = *SPA_MEMBER (&this->uri, info->media_subtype_offset, uint32_t); - if (info->media_subtype == SPA_MEDIA_SUBTYPE_RAW) { + spa_pod_builder_push_format (&b, &f[0], + media_type, + media_subtype); + + if (media_subtype == this->uri.media_subtypes.raw) { spa_pod_builder_add (&b, - PROP (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, info->format), + PROP (&f[1], this->uri.prop_video.format, SPA_POD_TYPE_INT, info->format), 0); } spa_pod_builder_add (&b, - PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, SPA_POD_TYPE_RECTANGLE, state->frmsize.discrete.width, - state->frmsize.discrete.height), + PROP (&f[1], this->uri.prop_video.size, SPA_POD_TYPE_RECTANGLE, state->frmsize.discrete.width, + state->frmsize.discrete.height), 0); spa_pod_builder_push_prop (&b, &f[1], - SPA_PROP_ID_VIDEO_FRAMERATE, + this->uri.prop_video.framerate, SPA_POD_PROP_RANGE_NONE | SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE); @@ -645,7 +677,7 @@ have_size: uint32_t i, n_values; const SpaFraction step = { 1, 1 }, *values; - if (!(p = spa_format_find_prop (filter, SPA_PROP_ID_VIDEO_FRAMERATE))) + if (!(p = spa_format_find_prop (filter, this->uri.prop_video.framerate))) goto have_framerate; if (p->body.value.type != SPA_POD_TYPE_FRACTION) @@ -744,37 +776,28 @@ spa_v4l2_set_format (SpaV4l2Source *this, SpaVideoInfo *format, bool try_only) fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - switch (format->media_subtype) { - case SPA_MEDIA_SUBTYPE_RAW: - video_format = format->info.raw.format; - size = &format->info.raw.size; - framerate = &format->info.raw.framerate; - break; - case SPA_MEDIA_SUBTYPE_MJPG: - case SPA_MEDIA_SUBTYPE_JPEG: - video_format = SPA_VIDEO_FORMAT_ENCODED; - size = &format->info.mjpg.size; - framerate = &format->info.mjpg.framerate; - break; - case SPA_MEDIA_SUBTYPE_H264: - video_format = SPA_VIDEO_FORMAT_ENCODED; - size = &format->info.h264.size; - framerate = &format->info.h264.framerate; - break; - case SPA_MEDIA_SUBTYPE_DV: - case SPA_MEDIA_SUBTYPE_MPEGTS: - case SPA_MEDIA_SUBTYPE_MPEG1: - case SPA_MEDIA_SUBTYPE_MPEG2: - case SPA_MEDIA_SUBTYPE_MPEG4: - case SPA_MEDIA_SUBTYPE_XVID: - case SPA_MEDIA_SUBTYPE_VC1: - case SPA_MEDIA_SUBTYPE_VP8: - default: - video_format = SPA_VIDEO_FORMAT_ENCODED; - break; + if (format->media_subtype == this->uri.media_subtypes.raw) { + video_format = format->info.raw.format; + size = &format->info.raw.size; + framerate = &format->info.raw.framerate; + } + else if (format->media_subtype == this->uri.media_subtypes_video.mjpg || + format->media_subtype == this->uri.media_subtypes_video.jpeg) { + video_format = SPA_VIDEO_FORMAT_ENCODED; + size = &format->info.mjpg.size; + framerate = &format->info.mjpg.framerate; + } + else if (format->media_subtype == this->uri.media_subtypes_video.h264) { + video_format = SPA_VIDEO_FORMAT_ENCODED; + size = &format->info.h264.size; + framerate = &format->info.h264.framerate; + } + else { + video_format = SPA_VIDEO_FORMAT_ENCODED; } - info = find_format_info_by_media_type (format->media_type, + info = find_format_info_by_media_type (&this->uri, + format->media_type, format->media_subtype, video_format, 0); diff --git a/spa/plugins/videotestsrc/draw.c b/spa/plugins/videotestsrc/draw.c index 317588ad6..b4df2407c 100644 --- a/spa/plugins/videotestsrc/draw.c +++ b/spa/plugins/videotestsrc/draw.c @@ -144,8 +144,8 @@ drawing_data_init (DrawingData *dd, SpaVideoInfo *format = &this->current_format; SpaRectangle *size = &format->info.raw.size; - if ((format->media_type != SPA_MEDIA_TYPE_VIDEO) || - (format->media_subtype != SPA_MEDIA_SUBTYPE_RAW)) + if ((format->media_type != this->uri.media_types.video) || + (format->media_subtype != this->uri.media_subtypes.raw)) return SPA_RESULT_NOT_IMPLEMENTED; switch (format->info.raw.format) { diff --git a/spa/plugins/videotestsrc/videotestsrc.c b/spa/plugins/videotestsrc/videotestsrc.c index ff9b3f1a8..01a74dde3 100644 --- a/spa/plugins/videotestsrc/videotestsrc.c +++ b/spa/plugins/videotestsrc/videotestsrc.c @@ -39,6 +39,9 @@ typedef struct { uint32_t node; uint32_t clock; + SpaMediaTypes media_types; + SpaMediaSubtypes media_subtypes; + SpaPropVideo prop_video; } URI; typedef struct _SpaVideoTestSrc SpaVideoTestSrc; @@ -450,16 +453,16 @@ next: switch (index++) { case 0: spa_pod_builder_format (&b, &f[0], - SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, - PROP_U_EN (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, 3, + this->uri.media_types.video, this->uri.media_subtypes.raw, + PROP_U_EN (&f[1], this->uri.prop_video.format, SPA_POD_TYPE_INT, 3, SPA_VIDEO_FORMAT_RGB, SPA_VIDEO_FORMAT_RGB, SPA_VIDEO_FORMAT_UYVY), - PROP_U_MM (&f[1], SPA_PROP_ID_VIDEO_SIZE, SPA_POD_TYPE_RECTANGLE, + PROP_U_MM (&f[1], this->uri.prop_video.size, SPA_POD_TYPE_RECTANGLE, 320, 240, 1, 1, INT32_MAX, INT32_MAX), - PROP_U_MM (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_TYPE_FRACTION, + PROP_U_MM (&f[1], this->uri.prop_video.framerate, SPA_POD_TYPE_FRACTION, 25, 1, 0, 1, INT32_MAX, 1)); @@ -590,10 +593,10 @@ spa_videotestsrc_node_port_get_format (SpaNode *node, spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer)); spa_pod_builder_format (&b, &f[0], - SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, - PROP (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, this->current_format.info.raw.format), - PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, -SPA_POD_TYPE_RECTANGLE, &this->current_format.info.raw.size), - PROP (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, -SPA_POD_TYPE_FRACTION, &this->current_format.info.raw.framerate)); + this->uri.media_types.video, this->uri.media_subtypes.raw, + PROP (&f[1], this->uri.prop_video.format, SPA_POD_TYPE_INT, this->current_format.info.raw.format), + PROP (&f[1], this->uri.prop_video.size, -SPA_POD_TYPE_RECTANGLE, &this->current_format.info.raw.size), + PROP (&f[1], this->uri.prop_video.framerate, -SPA_POD_TYPE_FRACTION, &this->current_format.info.raw.framerate)); *format = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); return SPA_RESULT_OK; @@ -956,6 +959,9 @@ videotestsrc_init (const SpaHandleFactory *factory, } this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI); this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI); + spa_media_types_fill (&this->uri.media_types, this->map); + spa_media_subtypes_map (this->map, &this->uri.media_subtypes); + spa_prop_video_map (this->map, &this->uri.prop_video); this->node = videotestsrc_node; this->clock = videotestsrc_clock; diff --git a/spa/plugins/volume/volume.c b/spa/plugins/volume/volume.c index 5682df868..0c588f76a 100644 --- a/spa/plugins/volume/volume.c +++ b/spa/plugins/volume/volume.c @@ -63,6 +63,9 @@ typedef struct { typedef struct { uint32_t node; + SpaMediaTypes media_types; + SpaMediaSubtypes media_subtypes; + SpaPropAudio prop_audio; } URI; struct _SpaVolume { @@ -307,13 +310,14 @@ next: switch (index++) { case 0: - spa_pod_builder_format (&b, &f[0], SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, - PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S32), - PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX), - PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, 2, 1, INT32_MAX)); + spa_pod_builder_format (&b, &f[0], + this->uri.media_types.audio, this->uri.media_subtypes.raw, + PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_INT, 3, + SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S32), + PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX), + PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX)); break; default: @@ -837,6 +841,9 @@ volume_init (const SpaHandleFactory *factory, return SPA_RESULT_ERROR; } this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI); + spa_media_types_fill (&this->uri.media_types, this->map); + spa_media_subtypes_map (this->map, &this->uri.media_subtypes); + spa_prop_audio_map (this->map, &this->uri.prop_audio); this->node = volume_node; reset_volume_props (&this->props); diff --git a/spa/plugins/xv/xv-sink.c b/spa/plugins/xv/xv-sink.c index 14200a1ec..d56acc1ba 100644 --- a/spa/plugins/xv/xv-sink.c +++ b/spa/plugins/xv/xv-sink.c @@ -71,6 +71,8 @@ typedef struct { typedef struct { uint32_t node; + SpaMediaTypes media_types; + SpaMediaSubtypes media_subtypes; } URI; struct _SpaXvSink { @@ -324,8 +326,8 @@ spa_xv_sink_node_port_set_format (SpaNode *node, return SPA_RESULT_OK; } - if (format->body.media_type.value == SPA_MEDIA_TYPE_VIDEO) { - if (format->body.media_subtype.value == SPA_MEDIA_SUBTYPE_RAW) { + if (format->body.media_type.value == this->uri.media_types.video) { + if (format->body.media_subtype.value == this->uri.media_subtypes.raw) { if ((res = spa_format_video_parse (format, &info) < 0)) return res; } else @@ -569,6 +571,8 @@ xv_sink_init (const SpaHandleFactory *factory, return SPA_RESULT_ERROR; } this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI); + spa_media_types_fill (&this->uri.media_types, this->map); + spa_media_subtypes_map (this->map, &this->uri.media_subtypes); this->node = xvsink_node; reset_xv_sink_props (&this->props); diff --git a/spa/tests/test-props.c b/spa/tests/test-props.c index 2bab75685..407c65b3c 100644 --- a/spa/tests/test-props.c +++ b/spa/tests/test-props.c @@ -40,19 +40,19 @@ */ spa_build (SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, - SPA_PROP_ID_VIDEO_FORMAT, SPA_PROP_TYPE_INT, + prop_video.format, SPA_PROP_TYPE_INT, SPA_VIDEO_FORMAT_I420 SPA_POD_PROP_FLAG_UNSET | SPA_PROP_RANGE_ENUM, 2, SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_YUY2, - SPA_PROP_ID_VIDEO_SIZE , SPA_PROP_TYPE_RECTANGLE, + prop_video.size , SPA_PROP_TYPE_RECTANGLE, 320, 240, SPA_POD_PROP_FLAG_UNSET | SPA_PROP_RANGE_MIN_MAX, 1, 1, INT32_MAX, INT32_MAX, - SPA_PROP_ID_VIDEO_FRAMERATE, SPA_PROP_TYPE_FRACTION, 25, 1, + prop_video.framerate, SPA_PROP_TYPE_FRACTION, 25, 1, SPA_POD_PROP_FLAG_UNSET | SPA_PROP_RANGE_MIN_MAX, 0, 1, @@ -60,61 +60,85 @@ spa_build (SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, 0); #endif -static const struct _test_format { - SpaFormat fmt; +static SpaMediaTypes media_types; +static SpaMediaSubtypes media_subtypes; +static SpaPropVideo prop_video; + +static void +do_static_struct (void) +{ + struct _test_format { + SpaFormat fmt; - struct { - SpaPODProp prop_format; struct { - uint32_t def_format; - uint32_t enum_format[2]; - } format_vals; - uint32_t pad; + SpaPODProp prop_format; + struct { + uint32_t def_format; + uint32_t enum_format[2]; + } format_vals; + uint32_t pad; - SpaPODProp prop_size; - struct { - SpaRectangle def_size; - SpaRectangle min_size; - SpaRectangle max_size; - } size_vals; + SpaPODProp prop_size; + struct { + SpaRectangle def_size; + SpaRectangle min_size; + SpaRectangle max_size; + } size_vals; - SpaPODProp prop_framerate; - struct { - SpaFraction def_framerate; - SpaFraction min_framerate; - SpaFraction max_framerate; - } framerate_vals; - } props; -} test_format = { - { { sizeof (test_format.props) + sizeof (SpaFormatBody), SPA_POD_TYPE_OBJECT }, - { { 0, 0 }, - { { sizeof (uint32_t), SPA_POD_TYPE_INT }, SPA_MEDIA_TYPE_VIDEO }, - { { sizeof (uint32_t), SPA_POD_TYPE_INT }, SPA_MEDIA_SUBTYPE_RAW } }, - }, { - { { sizeof (test_format.props.format_vals) + sizeof (SpaPODPropBody), - SPA_POD_TYPE_PROP } , - { SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET, - { sizeof (uint32_t), SPA_POD_TYPE_INT } }, }, - { SPA_VIDEO_FORMAT_I420, - { SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_YUY2 } }, 0, + SpaPODProp prop_framerate; + struct { + SpaFraction def_framerate; + SpaFraction min_framerate; + SpaFraction max_framerate; + } framerate_vals; + } props; + } test_format = { + { { sizeof (test_format.props) + sizeof (SpaFormatBody), SPA_POD_TYPE_OBJECT }, + { { 0, 0 }, + { { sizeof (uint32_t), SPA_POD_TYPE_URI }, media_types.video }, + { { sizeof (uint32_t), SPA_POD_TYPE_URI }, media_subtypes.raw } }, + }, { + { { sizeof (test_format.props.format_vals) + sizeof (SpaPODPropBody), + SPA_POD_TYPE_PROP } , + { prop_video.format, SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET, + { sizeof (uint32_t), SPA_POD_TYPE_INT } }, }, + { SPA_VIDEO_FORMAT_I420, + { SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_YUY2 } }, 0, - { { sizeof (test_format.props.size_vals) + sizeof (SpaPODPropBody), - SPA_POD_TYPE_PROP } , - { SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET, - { sizeof (SpaRectangle), SPA_POD_TYPE_RECTANGLE } }, }, - { { 320, 243 }, - { 1, 1 }, - { INT32_MAX, INT32_MAX } }, + { { sizeof (test_format.props.size_vals) + sizeof (SpaPODPropBody), + SPA_POD_TYPE_PROP } , + { prop_video.size, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET, + { sizeof (SpaRectangle), SPA_POD_TYPE_RECTANGLE } }, }, + { { 320, 243 }, + { 1, 1 }, + { INT32_MAX, INT32_MAX } }, - { { sizeof (test_format.props.framerate_vals) + sizeof (SpaPODPropBody), - SPA_POD_TYPE_PROP } , - { SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET, - { sizeof (SpaFraction), SPA_POD_TYPE_FRACTION } }, }, - { { 25, 1 }, - { 0, 1 }, - { INT32_MAX, 1 } }, + { { sizeof (test_format.props.framerate_vals) + sizeof (SpaPODPropBody), + SPA_POD_TYPE_PROP } , + { prop_video.framerate, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET, + { sizeof (SpaFraction), SPA_POD_TYPE_FRACTION } }, }, + { { 25, 1 }, + { 0, 1 }, + { INT32_MAX, 1 } }, + } + }; + + spa_debug_pod (&test_format.fmt.pod); + spa_debug_format (&test_format.fmt); + + { + uint32_t format = 0, match; + SpaFraction frac = { 0, 0 }; + + match = spa_pod_contents_query (&test_format.fmt.pod, sizeof (SpaFormat), + prop_video.format, SPA_POD_TYPE_INT, &format, + prop_video.framerate, SPA_POD_TYPE_FRACTION, &frac, + 0); + + printf ("%d %d %d %d\n", match, format, frac.num, frac.denom); } -}; + +} int main (int argc, char *argv[]) @@ -124,13 +148,17 @@ main (int argc, char *argv[]) uint8_t buffer[1024]; SpaFormat *fmt; + spa_media_types_fill (&media_types, spa_id_map_get_default()); + spa_media_subtypes_map (spa_id_map_get_default(), &media_subtypes); + spa_prop_video_map (spa_id_map_get_default(), &prop_video); + spa_pod_builder_init (&b, buffer, sizeof (buffer)); fmt = SPA_MEMBER (buffer, spa_pod_builder_push_format (&b, &frame[0], - SPA_MEDIA_TYPE_VIDEO, - SPA_MEDIA_SUBTYPE_RAW), SpaFormat); + media_types.video, + media_subtypes.raw), SpaFormat); spa_pod_builder_push_prop (&b, &frame[1], - SPA_PROP_ID_VIDEO_FORMAT, + prop_video.format, SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE); spa_pod_builder_int (&b, SPA_VIDEO_FORMAT_I420); spa_pod_builder_int (&b, SPA_VIDEO_FORMAT_I420); @@ -139,7 +167,7 @@ main (int argc, char *argv[]) SpaRectangle size_min_max[] = { { 1, 1 }, { INT32_MAX, INT32_MAX } }; spa_pod_builder_push_prop (&b, &frame[1], - SPA_PROP_ID_VIDEO_SIZE, + prop_video.size, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE); spa_pod_builder_rectangle (&b, 320, 240); spa_pod_builder_raw (&b, size_min_max, sizeof(size_min_max)); @@ -147,7 +175,7 @@ main (int argc, char *argv[]) SpaFraction rate_min_max[] = { { 0, 1 }, { INT32_MAX, 1 } }; spa_pod_builder_push_prop (&b, &frame[1], - SPA_PROP_ID_VIDEO_FRAMERATE, + prop_video.framerate, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE); spa_pod_builder_fraction (&b, 25, 1); spa_pod_builder_raw (&b, rate_min_max, sizeof(rate_min_max)); @@ -160,9 +188,9 @@ main (int argc, char *argv[]) spa_pod_builder_init (&b, buffer, sizeof (buffer)); spa_pod_builder_format (&b, &frame[0], - SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, + media_types.video, media_subtypes.raw, SPA_POD_TYPE_PROP, &frame[1], - SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_FLAG_UNSET | + prop_video.format, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_ENUM, SPA_POD_TYPE_INT, 3, SPA_VIDEO_FORMAT_I420, @@ -170,7 +198,7 @@ main (int argc, char *argv[]) SPA_VIDEO_FORMAT_YUY2, -SPA_POD_TYPE_PROP, &frame[1], SPA_POD_TYPE_PROP, &frame[1], - SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_FLAG_UNSET | + prop_video.size, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_MIN_MAX, SPA_POD_TYPE_RECTANGLE, 3, 320, 241, @@ -178,7 +206,7 @@ main (int argc, char *argv[]) INT32_MAX, INT32_MAX, -SPA_POD_TYPE_PROP, &frame[1], SPA_POD_TYPE_PROP, &frame[1], - SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_FLAG_UNSET | + prop_video.framerate, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_MIN_MAX, SPA_POD_TYPE_FRACTION, 3, 25, 1, @@ -194,10 +222,10 @@ main (int argc, char *argv[]) spa_pod_builder_add (&b, SPA_POD_TYPE_OBJECT, &frame[0], 0, 0, - SPA_POD_TYPE_INT, SPA_MEDIA_TYPE_VIDEO, - SPA_POD_TYPE_INT, SPA_MEDIA_SUBTYPE_RAW, + SPA_POD_TYPE_URI, media_types.video, + SPA_POD_TYPE_URI, media_subtypes.raw, SPA_POD_TYPE_PROP, &frame[1], - SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_FLAG_UNSET | + prop_video.format, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_ENUM, SPA_POD_TYPE_INT, 3, SPA_VIDEO_FORMAT_I420, @@ -205,7 +233,7 @@ main (int argc, char *argv[]) SPA_VIDEO_FORMAT_YUY2, -SPA_POD_TYPE_PROP, &frame[1], SPA_POD_TYPE_PROP, &frame[1], - SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_FLAG_UNSET | + prop_video.size, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_MIN_MAX, SPA_POD_TYPE_RECTANGLE, 3, 320, 242, @@ -213,7 +241,7 @@ main (int argc, char *argv[]) INT32_MAX, INT32_MAX, -SPA_POD_TYPE_PROP, &frame[1], SPA_POD_TYPE_PROP, &frame[1], - SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_FLAG_UNSET | + prop_video.framerate, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_MIN_MAX, SPA_POD_TYPE_FRACTION, 3, 25, 1, @@ -227,20 +255,7 @@ main (int argc, char *argv[]) spa_debug_pod (&fmt->pod); spa_debug_format (fmt); - spa_debug_pod (&test_format.fmt.pod); - spa_debug_format (&test_format.fmt); - - { - uint32_t format = 0, match; - SpaFraction frac = { 0, 0 }; - - match = spa_pod_contents_query (&test_format.fmt.pod, sizeof (SpaFormat), - SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, &format, - SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_TYPE_FRACTION, &frac, - 0); - - printf ("%d %d %d %d\n", match, format, frac.num, frac.denom); - } + do_static_struct (); return 0; }