format: make media types and properties dynamic

Use URI properties to dynamically register the media types/subtypes and
property names. Add some helpers to set up the mappings.
This commit is contained in:
Wim Taymans 2017-03-21 11:28:23 +01:00
parent ee470fc6c6
commit 3f5a3e215b
25 changed files with 769 additions and 685 deletions

View file

@ -23,6 +23,7 @@
#include <string.h> #include <string.h>
#include <spa/id-map.h> #include <spa/id-map.h>
#include <spa/lib/mapper.h>
#include <pinos/client/map.h> #include <pinos/client/map.h>
@ -44,7 +45,7 @@ id_map_get_id (SpaIDMap *map, const char *uri)
if (strcmp (pinos_map_lookup_unchecked (&this->uris, i), uri) == 0) if (strcmp (pinos_map_lookup_unchecked (&this->uris, i), uri) == 0)
return i; return i;
} }
i = pinos_map_insert_new (&this->uris, (char *)uri); i = pinos_map_insert_new (&this->uris, strdup (uri));
} }
return i; return i;
} }
@ -82,5 +83,6 @@ static IDMap default_id_map = {
SpaIDMap * SpaIDMap *
pinos_id_map_get_default (void) pinos_id_map_get_default (void)
{ {
spa_id_map_set_default (&default_id_map.map);
return &default_id_map.map; return &default_id_map.map;
} }

View file

@ -23,6 +23,7 @@
#include <gst/video/video.h> #include <gst/video/video.h>
#include <gst/audio/audio.h> #include <gst/audio/audio.h>
#include <spa/lib/mapper.h>
#include <spa/include/spa/video/format.h> #include <spa/include/spa/video/format.h>
#include <spa/include/spa/audio/format.h> #include <spa/include/spa/audio/format.h>
#include <spa/include/spa/format.h> #include <spa/include/spa/format.h>
@ -32,15 +33,33 @@
typedef struct { typedef struct {
const char *name; const char *name;
uint32_t media_type; uint32_t *media_type;
uint32_t media_subtype; uint32_t *media_subtype;
} MediaType; } MediaType;
static const MediaType media_types[] = { static SpaMediaTypes media_types = { 0, };
{ "video/x-raw", SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, static SpaMediaSubtypes media_subtypes = { 0, };
{ "audio/x-raw", SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW }, static SpaMediaSubtypesVideo media_subtypes_video = { 0, };
{ "image/jpeg", SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_MJPG }, static SpaMediaSubtypesAudio media_subtypes_audio = { 0, };
{ "video/x-h264", SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_H264 }, 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, } { NULL, }
}; };
@ -55,9 +74,9 @@ static const MediaType *
find_media_types (const char *name) find_media_types (const char *name)
{ {
int i; int i;
for (i = 0; media_types[i].name; i++) { for (i = 0; media_type_map[i].name; i++) {
if (!strcmp (media_types[i].name, name)) if (!strcmp (media_type_map[i].name, name))
return &media_types[i]; return &media_type_map[i];
} }
return NULL; return NULL;
} }
@ -229,7 +248,7 @@ handle_video_fields (ConvertData *d)
for (i = 0; (v = get_nth_string (value, i)); i++) { for (i = 0; (v = get_nth_string (value, i)); i++) {
if (i == 0) if (i == 0)
spa_pod_builder_push_prop (&d->b, &f, 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); get_range_type (value) | SPA_POD_PROP_FLAG_READWRITE);
spa_pod_builder_int (&d->b, gst_video_format_from_string (v)); 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++) { for (i = 0; get_nth_rectangle (value, value2, i, &v); i++) {
if (i == 0) if (i == 0)
spa_pod_builder_push_prop (&d->b, &f, 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); get_range_type2 (value, value2) | SPA_POD_PROP_FLAG_READWRITE);
spa_pod_builder_rectangle (&d->b, v.width, v.height); 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++) { for (i = 0; get_nth_fraction (value, i, &v); i++) {
if (i == 0) if (i == 0)
spa_pod_builder_push_prop (&d->b, &f, 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); get_range_type (value) | SPA_POD_PROP_FLAG_READWRITE);
spa_pod_builder_fraction (&d->b, v.num, v.denom); 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++) { for (i = 0; (v = get_nth_string (value, i)); i++) {
if (i == 0) if (i == 0)
spa_pod_builder_push_prop (&d->b, &f, 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); get_range_type (value) | SPA_POD_PROP_FLAG_READWRITE);
spa_pod_builder_int (&d->b, gst_audio_format_from_string (v)); spa_pod_builder_int (&d->b, gst_audio_format_from_string (v));
@ -311,7 +330,7 @@ handle_audio_fields (ConvertData *d)
if (i == 0) if (i == 0)
spa_pod_builder_push_prop (&d->b, &f, 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); get_range_type (value) | SPA_POD_PROP_FLAG_READWRITE);
spa_pod_builder_int (&d->b, layout); 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++) { for (i = 0; get_nth_int (value, i, &v); i++) {
if (i == 0) if (i == 0)
spa_pod_builder_push_prop (&d->b, &f, 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); get_range_type (value) | SPA_POD_PROP_FLAG_READWRITE);
spa_pod_builder_int (&d->b, v); 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++) { for (i = 0; get_nth_int (value, i, &v); i++) {
if (i == 0) if (i == 0)
spa_pod_builder_push_prop (&d->b, &f, 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); get_range_type (value) | SPA_POD_PROP_FLAG_READWRITE);
spa_pod_builder_int (&d->b, v); spa_pod_builder_int (&d->b, v);
@ -383,12 +402,12 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
d.b.write = write_pod; d.b.write = write_pod;
spa_pod_builder_push_format (&d.b, &f, spa_pod_builder_push_format (&d.b, &f,
d.type->media_type, *d.type->media_type,
d.type->media_subtype); *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); 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); handle_audio_fields (&d);
spa_pod_builder_pop (&d.b, &f); 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_IS_CAPS (caps), NULL);
g_return_val_if_fail (gst_caps_is_fixed (caps), NULL); g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
ensure_types();
f = gst_caps_get_features (caps, index); f = gst_caps_get_features (caps, index);
s = gst_caps_get_structure (caps, index); s = gst_caps_get_structure (caps, index);
@ -433,6 +454,8 @@ gst_caps_to_format_all (GstCaps *caps)
{ {
GPtrArray *res; GPtrArray *res;
ensure_types();
res = g_ptr_array_new_full (gst_caps_get_size (caps), (GDestroyNotify)g_free); res = g_ptr_array_new_full (gst_caps_get_size (caps), (GDestroyNotify)g_free);
gst_caps_foreach (caps, (GstCapsForeachFunc) foreach_func, res); gst_caps_foreach (caps, (GstCapsForeachFunc) foreach_func, res);
@ -445,16 +468,18 @@ gst_caps_from_format (const SpaFormat *format)
GstCaps *res = NULL; GstCaps *res = NULL;
uint32_t media_type, media_subtype; uint32_t media_type, media_subtype;
ensure_types();
media_type = format->body.media_type.value; media_type = format->body.media_type.value;
media_subtype = format->body.media_subtype.value; media_subtype = format->body.media_subtype.value;
if (media_type == SPA_MEDIA_TYPE_VIDEO) { if (media_type == media_types.video) {
SpaVideoInfo f; SpaVideoInfo f;
if (spa_format_video_parse (format, &f) < 0) if (spa_format_video_parse (format, &f) < 0)
return NULL; return NULL;
if (media_subtype == SPA_MEDIA_SUBTYPE_RAW) { if (media_subtype == media_subtypes.raw) {
res = gst_caps_new_simple ("video/x-raw", res = gst_caps_new_simple ("video/x-raw",
"format", G_TYPE_STRING, gst_video_format_to_string (f.info.raw.format), "format", G_TYPE_STRING, gst_video_format_to_string (f.info.raw.format),
"width", G_TYPE_INT, f.info.raw.size.width, "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, "framerate", GST_TYPE_FRACTION, f.info.raw.framerate.num, f.info.raw.framerate.denom,
NULL); NULL);
} }
else if (media_subtype == SPA_MEDIA_SUBTYPE_MJPG) { else if (media_subtype == media_subtypes_video.mjpg) {
res = gst_caps_new_simple ("image/jpeg", res = gst_caps_new_simple ("image/jpeg",
"width", G_TYPE_INT, f.info.mjpg.size.width, "width", G_TYPE_INT, f.info.mjpg.size.width,
"height", G_TYPE_INT, f.info.mjpg.size.height, "height", G_TYPE_INT, f.info.mjpg.size.height,
"framerate", GST_TYPE_FRACTION, f.info.mjpg.framerate.num, f.info.mjpg.framerate.denom, "framerate", GST_TYPE_FRACTION, f.info.mjpg.framerate.num, f.info.mjpg.framerate.denom,
NULL); 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", res = gst_caps_new_simple ("video/x-h264",
"width", G_TYPE_INT, f.info.h264.size.width, "width", G_TYPE_INT, f.info.h264.size.width,
"height", G_TYPE_INT, f.info.h264.size.height, "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", "alignment", G_TYPE_STRING, "au",
NULL); NULL);
} }
} else if (media_type == SPA_MEDIA_TYPE_AUDIO) { } else if (media_type == media_types.audio) {
SpaAudioInfo f; SpaAudioInfo f;
if (spa_format_audio_parse (format, &f) < 0) if (spa_format_audio_parse (format, &f) < 0)
return NULL; return NULL;
if (media_subtype == SPA_MEDIA_SUBTYPE_RAW) { if (media_subtype == media_subtypes.raw) {
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.raw.format), "format", G_TYPE_STRING, gst_audio_format_to_string (f.info.raw.format),
"layout", G_TYPE_STRING, "interleaved", "layout", G_TYPE_STRING, "interleaved",

View file

@ -29,19 +29,41 @@ extern "C" {
typedef struct _SpaAudioInfo SpaAudioInfo; typedef struct _SpaAudioInfo SpaAudioInfo;
typedef enum { #define SPA_PROP_AUDIO_URI "http://spaplug.in/ns/prop-audio"
SPA_PROP_ID_AUDIO_INFO = SPA_PROP_ID_MEDIA_CUSTOM_START, #define SPA_PROP_AUDIO_PREFIX SPA_PROP_AUDIO_URI "#"
SPA_PROP_ID_AUDIO_FORMAT,
SPA_PROP_ID_AUDIO_FLAGS, #define SPA_PROP_AUDIO__format SPA_PROP_AUDIO_PREFIX "format"
SPA_PROP_ID_AUDIO_LAYOUT, #define SPA_PROP_AUDIO__flags SPA_PROP_AUDIO_PREFIX "flags"
SPA_PROP_ID_AUDIO_RATE, #define SPA_PROP_AUDIO__layout SPA_PROP_AUDIO_PREFIX "layout"
SPA_PROP_ID_AUDIO_CHANNELS, #define SPA_PROP_AUDIO__rate SPA_PROP_AUDIO_PREFIX "rate"
SPA_PROP_ID_AUDIO_CHANNEL_MASK, #define SPA_PROP_AUDIO__channels SPA_PROP_AUDIO_PREFIX "channels"
} SpaPropIdAudio; #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 { struct _SpaAudioInfo {
SpaMediaType media_type; uint32_t media_type;
SpaMediaSubType media_subtype; uint32_t media_subtype;
union { union {
SpaAudioInfoRaw raw; SpaAudioInfoRaw raw;
} info; } info;

View file

@ -37,16 +37,16 @@ spa_pod_builder_push_format (SpaPODBuilder *builder,
{ {
const SpaFormat p = { { sizeof (SpaFormatBody), SPA_POD_TYPE_OBJECT }, const SpaFormat p = { { sizeof (SpaFormatBody), SPA_POD_TYPE_OBJECT },
{ { 0, 0 }, { { 0, 0 },
{ { sizeof (uint32_t), SPA_POD_TYPE_INT }, media_type }, { { sizeof (uint32_t), SPA_POD_TYPE_URI }, media_type },
{ { sizeof (uint32_t), SPA_POD_TYPE_INT }, media_subtype } } }; { { sizeof (uint32_t), SPA_POD_TYPE_URI }, media_subtype } } };
return spa_pod_builder_push (builder, frame, &p.pod, return spa_pod_builder_push (builder, frame, &p.pod,
spa_pod_builder_raw (builder, &p, sizeof(p))); spa_pod_builder_raw (builder, &p, sizeof(p)));
} }
#define spa_pod_builder_format(b,f,media_type,media_subtype,...) \ #define spa_pod_builder_format(b,f,media_type,media_subtype,...) \
spa_pod_builder_object(b, f, 0, 0, \ spa_pod_builder_object(b, f, 0, 0, \
SPA_POD_TYPE_INT,media_type, \ SPA_POD_TYPE_URI,media_type, \
SPA_POD_TYPE_INT,media_subtype, \ SPA_POD_TYPE_URI,media_subtype, \
__VA_ARGS__) __VA_ARGS__)
SpaResult SpaResult

View file

@ -33,66 +33,152 @@ typedef struct _SpaFormat SpaFormat;
#include <spa/defs.h> #include <spa/defs.h>
#include <spa/pod-utils.h> #include <spa/pod-utils.h>
#include <spa/id-map.h>
typedef enum { #define SPA_MEDIA_TYPE_URI "http://spaplug.in/ns/media-type"
SPA_MEDIA_TYPE_INVALID = 0, #define SPA_MEDIA_TYPE_PREFIX SPA_MEDIA_TYPE_URI "#"
SPA_MEDIA_TYPE_AUDIO = 1,
SPA_MEDIA_TYPE_VIDEO = 2,
SPA_MEDIA_TYPE_IMAGE = 3,
} SpaMediaType;
typedef enum { #define SPA_MEDIA_TYPE__audio SPA_MEDIA_TYPE_PREFIX "audio"
SPA_MEDIA_SUBTYPE_INVALID = 0, #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 typedef struct {
SPA_MEDIA_SUBTYPE_RAW = SPA_MEDIA_SUBTYPE_ANY_FIRST, uint32_t audio;
#define SPA_MEDIA_SUBTYPE_ANY_LAST SPA_MEDIA_SUBTYPE_RAW uint32_t video;
uint32_t image;
} SpaMediaTypes;
/* VIDEO */ static inline void
#define SPA_MEDIA_SUBTYPE_VIDEO_FIRST 20 spa_media_types_fill (SpaMediaTypes *types, SpaIDMap *map)
SPA_MEDIA_SUBTYPE_H264 = SPA_MEDIA_SUBTYPE_VIDEO_FIRST, {
SPA_MEDIA_SUBTYPE_MJPG, if (types->audio == 0) {
SPA_MEDIA_SUBTYPE_DV, types->audio = spa_id_map_get_id (map, SPA_MEDIA_TYPE__audio);
SPA_MEDIA_SUBTYPE_MPEGTS, types->video = spa_id_map_get_id (map, SPA_MEDIA_TYPE__video);
SPA_MEDIA_SUBTYPE_H263, types->image = spa_id_map_get_id (map, SPA_MEDIA_TYPE__image);
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
/* AUDIO */ #define SPA_MEDIA_SUBTYPE_URI "http://spaplug.in/ns/media-subtype"
#define SPA_MEDIA_SUBTYPE_AUDIO_FIRST 200 #define SPA_MEDIA_SUBTYPE_PREFIX SPA_MEDIA_TYPE_URI "#"
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
} SpaMediaSubType; #define SPA_MEDIA_SUBTYPE__raw SPA_MEDIA_TYPE_PREFIX "raw"
typedef enum { typedef struct {
SPA_PROP_ID_INVALID = 0, uint32_t raw;
SPA_PROP_ID_MEDIA_CUSTOM_START = 200, } SpaMediaSubtypes;
} SpaFormatProps;
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 { typedef struct {
SpaPODObjectBody obj_body; SpaPODObjectBody obj_body;
SpaPODInt media_type SPA_ALIGNED (8); SpaPODURI media_type SPA_ALIGNED (8);
SpaPODInt media_subtype SPA_ALIGNED (8); SpaPODURI media_subtype SPA_ALIGNED (8);
/* contents follow, series of SpaPODProp */ /* contents follow, series of SpaPODProp */
} SpaFormatBody; } SpaFormatBody;
@ -110,8 +196,8 @@ struct _SpaFormat {
#define SPA_FORMAT_INIT(size,type,media_type,media_subtype,...) \ #define SPA_FORMAT_INIT(size,type,media_type,media_subtype,...) \
{ { size, SPA_POD_TYPE_OBJECT }, \ { { size, SPA_POD_TYPE_OBJECT }, \
{ { 0, type }, \ { { 0, type }, \
SPA_POD_INT_INIT (media_type), \ SPA_POD_URI_INIT (media_type), \
SPA_POD_INT_INIT (media_subtype) } } SPA_POD_URI_INIT (media_subtype) } }
#define SPA_FORMAT_BODY_FOREACH(body, size, iter) \ #define SPA_FORMAT_BODY_FOREACH(body, size, iter) \
for ((iter) = SPA_MEMBER ((body), sizeof (SpaFormatBody), SpaPODProp); \ for ((iter) = SPA_MEMBER ((body), sizeof (SpaFormatBody), SpaPODProp); \

View file

@ -341,30 +341,18 @@ spa_pod_builder_addv (SpaPODBuilder *builder,
uint32_t body_size; uint32_t body_size;
static const uint64_t zeroes = 0; static const uint64_t zeroes = 0;
while (type != 0) { while (type != SPA_POD_TYPE_INVALID) {
SpaPODFrame *f = NULL; SpaPODFrame *f = NULL;
const void *data[3]; const void *data[3];
uint32_t size[3], ref, i, n_sizes = 0; uint32_t size[3], ref, i, n_sizes = 0;
switch (type) { switch (type) {
case SPA_POD_TYPE_INVALID: case SPA_POD_TYPE_NONE:
break; break;
case SPA_POD_TYPE_BOOL: 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: 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: 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.pod.size = body_size = sizeof (uint32_t);
head.int_pod.value = va_arg (args, int); head.int_pod.value = va_arg (args, int);
head_size = sizeof (SpaPOD); head_size = sizeof (SpaPOD);

View file

@ -36,6 +36,7 @@ extern "C" {
*/ */
typedef enum { typedef enum {
SPA_POD_TYPE_INVALID = 0, SPA_POD_TYPE_INVALID = 0,
SPA_POD_TYPE_NONE = 1,
SPA_POD_TYPE_BOOL, SPA_POD_TYPE_BOOL,
SPA_POD_TYPE_URI, SPA_POD_TYPE_URI,
SPA_POD_TYPE_INT, SPA_POD_TYPE_INT,

View file

@ -30,34 +30,80 @@ extern "C" {
typedef struct _SpaVideoInfo SpaVideoInfo; typedef struct _SpaVideoInfo SpaVideoInfo;
typedef enum { #define SPA_PROP_VIDEO_URI "http://spaplug.in/ns/prop-video"
SPA_PROP_ID_VIDEO_INFO = SPA_PROP_ID_MEDIA_CUSTOM_START, #define SPA_PROP_VIDEO_PREFIX SPA_PROP_VIDEO_URI "#"
SPA_PROP_ID_VIDEO_FORMAT,
SPA_PROP_ID_VIDEO_SIZE, #define SPA_PROP_VIDEO__format SPA_PROP_VIDEO_PREFIX "format"
SPA_PROP_ID_VIDEO_FRAMERATE, #define SPA_PROP_VIDEO__size SPA_PROP_VIDEO_PREFIX "size"
SPA_PROP_ID_VIDEO_MAX_FRAMERATE, #define SPA_PROP_VIDEO__framerate SPA_PROP_VIDEO_PREFIX "framerate"
SPA_PROP_ID_VIDEO_VIEWS, #define SPA_PROP_VIDEO__maxFramerate SPA_PROP_VIDEO_PREFIX "max-framerate"
SPA_PROP_ID_VIDEO_INTERLACE_MODE, #define SPA_PROP_VIDEO__views SPA_PROP_VIDEO_PREFIX "views"
SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO, #define SPA_PROP_VIDEO__interlaceMode SPA_PROP_VIDEO_PREFIX "interlace-mode"
SPA_PROP_ID_VIDEO_MULTIVIEW_MODE, #define SPA_PROP_VIDEO__pixelAspectRatio SPA_PROP_VIDEO_PREFIX "pixel-aspect-ratio"
SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS, #define SPA_PROP_VIDEO__multiviewMode SPA_PROP_VIDEO_PREFIX "multiview-mode"
SPA_PROP_ID_VIDEO_CHROMA_SITE, #define SPA_PROP_VIDEO__multiviewFlags SPA_PROP_VIDEO_PREFIX "multiview-flags"
SPA_PROP_ID_VIDEO_COLOR_RANGE, #define SPA_PROP_VIDEO__chromaSite SPA_PROP_VIDEO_PREFIX "chroma-site"
SPA_PROP_ID_VIDEO_COLOR_MATRIX, #define SPA_PROP_VIDEO__colorRange SPA_PROP_VIDEO_PREFIX "color-range"
SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION, #define SPA_PROP_VIDEO__colorMatrix SPA_PROP_VIDEO_PREFIX "color-matrix"
SPA_PROP_ID_VIDEO_COLOR_PRIMARIES, #define SPA_PROP_VIDEO__transferFunction SPA_PROP_VIDEO_PREFIX "transfer-function"
SPA_PROP_ID_VIDEO_PROFILE, #define SPA_PROP_VIDEO__colorPrimaries SPA_PROP_VIDEO_PREFIX "color-primaries"
SPA_PROP_ID_VIDEO_LEVEL, #define SPA_PROP_VIDEO__profile SPA_PROP_VIDEO_PREFIX "profile"
SPA_PROP_ID_VIDEO_STREAM_FORMAT, #define SPA_PROP_VIDEO__level SPA_PROP_VIDEO_PREFIX "level"
SPA_PROP_ID_VIDEO_ALIGNMENT, #define SPA_PROP_VIDEO__streamFormat SPA_PROP_VIDEO_PREFIX "stream-format"
} SpaPropIdVideo; #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, SpaResult spa_format_video_parse (const SpaFormat *format,
SpaVideoInfo *info); SpaVideoInfo *info);
struct _SpaVideoInfo { struct _SpaVideoInfo {
SpaMediaType media_type; uint32_t media_type;
SpaMediaSubType media_subtype; uint32_t media_subtype;
union { union {
SpaVideoInfoRaw raw; SpaVideoInfoRaw raw;
SpaVideoInfoH264 h264; SpaVideoInfoH264 h264;

View file

@ -22,78 +22,42 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <lib/mapper.h>
#include <spa/audio/raw.h> #include <spa/audio/raw.h>
#include <spa/audio/format.h> #include <spa/audio/format.h>
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 SpaResult
spa_format_audio_parse (const SpaFormat *format, spa_format_audio_parse (const SpaFormat *format,
SpaAudioInfo *info) SpaAudioInfo *info)
{ {
SpaPODProp *prop; static SpaMediaTypes media_types = { 0, };
const ParseInfo *pinfo, *find; 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; return SPA_RESULT_INVALID_MEDIA_TYPE;
info->media_type = format->body.media_type.value; info->media_type = format->body.media_type.value;
info->media_subtype = format->body.media_subtype.value; info->media_subtype = format->body.media_subtype.value;
switch (info->media_subtype) { if (info->media_subtype == media_subtypes.raw) {
case SPA_MEDIA_SUBTYPE_RAW: spa_format_query (format,
pinfo = raw_parse_info; prop_audio.format, SPA_POD_TYPE_INT, &info->info.raw.format,
break; prop_audio.flags, SPA_POD_TYPE_INT, &info->info.raw.flags,
case SPA_MEDIA_SUBTYPE_MP3: prop_audio.layout, SPA_POD_TYPE_INT, &info->info.raw.layout,
case SPA_MEDIA_SUBTYPE_AAC: prop_audio.rate, SPA_POD_TYPE_INT, &info->info.raw.rate,
case SPA_MEDIA_SUBTYPE_VORBIS: prop_audio.channels, SPA_POD_TYPE_INT, &info->info.raw.channels,
case SPA_MEDIA_SUBTYPE_WMA: prop_audio.channel_mask, SPA_POD_TYPE_INT, &info->info.raw.channel_mask,
case SPA_MEDIA_SUBTYPE_RA: 0);
case SPA_MEDIA_SUBTYPE_SBC: }
case SPA_MEDIA_SUBTYPE_ADPCM: else
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; 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; return SPA_RESULT_OK;
} }

View file

@ -19,6 +19,7 @@
#include <stdio.h> #include <stdio.h>
#include <lib/mapper.h>
#include "debug.h" #include "debug.h"
static const struct meta_type_name { static const struct meta_type_name {
@ -180,92 +181,12 @@ spa_debug_props (const SpaProps *props, bool print_ranges)
return SPA_RESULT_OK; 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 { struct pod_type_name {
const char *name; const char *name;
const char *CCName; const char *CCName;
} pod_type_names[] = { } pod_type_names[] = {
{ "invalid", "*Invalid*" }, { "invalid", "*Invalid*" },
{ "ignored", "ignored" },
{ "bool", "Bool" }, { "bool", "Bool" },
{ "uri", "URI" }, { "uri", "URI" },
{ "int", "Int" }, { "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); printf ("%-*sBool %d\n", prefix, "", *(int32_t *) body);
break; break;
case SPA_POD_TYPE_URI: 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; break;
case SPA_POD_TYPE_INT: case SPA_POD_TYPE_INT:
printf ("%-*sInt %d\n", prefix, "", *(int32_t *) body); 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; void *alt;
int i; 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) if (b->flags & SPA_POD_PROP_FLAG_UNSET)
printf ("%-*sUnset (Default):\n", prefix + 2, ""); printf ("%-*sUnset (Default):\n", prefix + 2, "");
else else
@ -441,10 +364,9 @@ print_format_value (uint32_t size, uint32_t type, void *body)
SpaResult SpaResult
spa_debug_format (const SpaFormat *format) spa_debug_format (const SpaFormat *format)
{ {
int i, first, last, idx; int i;
const char *media_type; const char *media_type;
const char *media_subtype; const char *media_subtype;
const char **prop_names;
SpaPODProp *prop; SpaPODProp *prop;
uint32_t mtype, mstype; uint32_t mtype, mstype;
@ -454,35 +376,22 @@ spa_debug_format (const SpaFormat *format)
mtype = format->body.media_type.value; mtype = format->body.media_type.value;
mstype = format->body.media_subtype.value; mstype = format->body.media_subtype.value;
if (mtype > 0 && mtype < SPA_N_ELEMENTS (media_type_names)) { media_type = spa_id_map_get_uri (spa_id_map_get_default (), mtype);
media_type = media_type_names[mtype].name; media_subtype = spa_id_map_get_uri (spa_id_map_get_default (), mstype);
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;
}
if (mstype >= SPA_MEDIA_SUBTYPE_ANY_FIRST && fprintf (stderr, "%-6s %s/%s\n", "", strstr (media_type, "#")+1, strstr (media_subtype, "#")+1);
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);
SPA_FORMAT_FOREACH (format, prop) { SPA_FORMAT_FOREACH (format, prop) {
const char *key;
if ((prop->body.flags & SPA_POD_PROP_FLAG_UNSET) && if ((prop->body.flags & SPA_POD_PROP_FLAG_UNSET) &&
(prop->body.flags & SPA_POD_PROP_FLAG_OPTIONAL)) (prop->body.flags & SPA_POD_PROP_FLAG_OPTIONAL))
continue; 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)) { 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)); print_format_value (prop->body.value.size, prop->body.value.type, SPA_POD_BODY (&prop->body.value));
} else { } else {

View file

@ -45,6 +45,7 @@ id_map_get_id (SpaIDMap *map, const char *uri)
if (strcmp (this->uris[i], uri) == 0) if (strcmp (this->uris[i], uri) == 0)
return i; return i;
} }
printf ("spa adding %d %s\n", i, uri);
this->uris[i] = (char *)uri; this->uris[i] = (char *)uri;
this->n_uris++; this->n_uris++;
} }
@ -56,6 +57,8 @@ id_map_get_uri (SpaIDMap *map, uint32_t id)
{ {
IDMap *this = SPA_CONTAINER_OF (map, IDMap, map); IDMap *this = SPA_CONTAINER_OF (map, IDMap, map);
printf ("spa get %d\n", id);
if (id < this->n_uris) if (id < this->n_uris)
return this->uris[id]; return this->uris[id];
return 0; return 0;
@ -71,8 +74,16 @@ static IDMap default_id_map = {
0 0
}; };
static SpaIDMap *default_map = &default_id_map.map;
SpaIDMap * SpaIDMap *
spa_id_map_get_default (void) 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;
} }

View file

@ -26,6 +26,7 @@ extern "C" {
#include <spa/id-map.h> #include <spa/id-map.h>
void spa_id_map_set_default (SpaIDMap *map);
SpaIDMap * spa_id_map_get_default (void); SpaIDMap * spa_id_map_get_default (void);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -26,107 +26,60 @@
#include <spa/video/format.h> #include <spa/video/format.h>
#include <spa/format-builder.h> #include <spa/format-builder.h>
#include <lib/props.h> #include <lib/props.h>
#include <lib/mapper.h>
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;
}
SpaResult SpaResult
spa_format_video_parse (const SpaFormat *format, spa_format_video_parse (const SpaFormat *format,
SpaVideoInfo *info) SpaVideoInfo *info)
{ {
SpaPODProp *prop; static SpaMediaTypes media_types = { 0, };
const ParseInfo *pinfo, *find; 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; return SPA_RESULT_INVALID_MEDIA_TYPE;
info->media_type = format->body.media_type.value; info->media_type = format->body.media_type.value;
info->media_subtype = format->body.media_subtype.value; info->media_subtype = format->body.media_subtype.value;
switch (info->media_subtype) { if (info->media_subtype == media_subtypes.raw)
case SPA_MEDIA_SUBTYPE_RAW: spa_format_query (format,
pinfo = raw_parse_info; prop_video.format, SPA_POD_TYPE_INT, &info->info.raw.format,
break; prop_video.size, SPA_POD_TYPE_RECTANGLE, &info->info.raw.size,
case SPA_MEDIA_SUBTYPE_H264: prop_video.framerate, SPA_POD_TYPE_FRACTION, &info->info.raw.framerate,
pinfo = h264_parse_info; prop_video.max_framerate, SPA_POD_TYPE_FRACTION, &info->info.raw.max_framerate,
break; prop_video.views, SPA_POD_TYPE_INT, &info->info.raw.views,
case SPA_MEDIA_SUBTYPE_MJPG: prop_video.interlace_mode, SPA_POD_TYPE_INT, &info->info.raw.interlace_mode,
pinfo = mjpg_parse_info; prop_video.pixel_aspect_ratio, SPA_POD_TYPE_FRACTION, &info->info.raw.pixel_aspect_ratio,
break; prop_video.multiview_mode, SPA_POD_TYPE_INT, &info->info.raw.multiview_mode,
case SPA_MEDIA_SUBTYPE_DV: prop_video.multiview_flags, SPA_POD_TYPE_INT, &info->info.raw.multiview_flags,
case SPA_MEDIA_SUBTYPE_MPEGTS: prop_video.chroma_site, SPA_POD_TYPE_INT, &info->info.raw.chroma_site,
case SPA_MEDIA_SUBTYPE_H263: prop_video.color_range, SPA_POD_TYPE_INT, &info->info.raw.color_range,
case SPA_MEDIA_SUBTYPE_MPEG1: prop_video.color_matrix, SPA_POD_TYPE_INT, &info->info.raw.color_matrix,
case SPA_MEDIA_SUBTYPE_MPEG2: prop_video.transfer_function, SPA_POD_TYPE_INT, &info->info.raw.transfer_function,
case SPA_MEDIA_SUBTYPE_MPEG4: prop_video.color_primaries, SPA_POD_TYPE_INT, &info->info.raw.color_primaries,
case SPA_MEDIA_SUBTYPE_XVID: 0);
case SPA_MEDIA_SUBTYPE_VC1: else if (info->media_subtype == media_subtypes_video.h264)
case SPA_MEDIA_SUBTYPE_VP8: spa_format_query (format,
case SPA_MEDIA_SUBTYPE_VP9: prop_video.size, SPA_POD_TYPE_RECTANGLE, &info->info.h264.size,
case SPA_MEDIA_SUBTYPE_JPEG: prop_video.framerate, SPA_POD_TYPE_FRACTION, &info->info.h264.framerate,
case SPA_MEDIA_SUBTYPE_BAYER: 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; 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; return SPA_RESULT_OK;
} }

View file

@ -325,17 +325,17 @@ next:
switch (index++) { switch (index++) {
case 0: case 0:
spa_pod_builder_format (&b, &f[0], spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16, 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_S16,
SPA_AUDIO_FORMAT_S32), 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], this->uri.prop_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.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
break; break;
case 1: case 1:
spa_pod_builder_format (&b, &f[0], spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_AAC, this->uri.media_types.audio, this->uri.media_subtypes_audio.aac,
0); SPA_POD_TYPE_NONE);
break; break;
default: default:
return SPA_RESULT_ENUM_END; return SPA_RESULT_ENUM_END;
@ -795,6 +795,10 @@ alsa_sink_init (const SpaHandleFactory *factory,
return SPA_RESULT_ERROR; return SPA_RESULT_ERROR;
} }
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI); 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->node = alsasink_node;
this->stream = SND_PCM_STREAM_PLAYBACK; this->stream = SND_PCM_STREAM_PLAYBACK;

View file

@ -359,17 +359,17 @@ next:
switch (index++) { switch (index++) {
case 0: case 0:
spa_pod_builder_format (&b, &f[0], spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16, 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_S16,
SPA_AUDIO_FORMAT_S32), 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], this->uri.prop_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.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
break; break;
case 1: case 1:
spa_pod_builder_format (&b, &f[0], spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_AAC, this->uri.media_types.audio, this->uri.media_subtypes_audio.aac,
0); SPA_POD_TYPE_NONE);
default: default:
return SPA_RESULT_ENUM_END; 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.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_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->node = alsasource_node;
this->clock = alsasource_clock; this->clock = alsasource_clock;
this->stream = SND_PCM_STREAM_CAPTURE; this->stream = SND_PCM_STREAM_CAPTURE;

View file

@ -62,6 +62,10 @@ struct _SpaALSABuffer {
typedef struct { typedef struct {
uint32_t node; uint32_t node;
uint32_t clock; uint32_t clock;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaMediaSubtypesAudio media_subtypes_audio;
SpaPropAudio prop_audio;
} URI; } URI;
struct _SpaALSAState { struct _SpaALSAState {

View file

@ -39,6 +39,9 @@
typedef struct { typedef struct {
uint32_t node; uint32_t node;
uint32_t clock; uint32_t clock;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaPropAudio prop_audio;
} URI; } URI;
typedef struct _SpaAudioTestSrc SpaAudioTestSrc; typedef struct _SpaAudioTestSrc SpaAudioTestSrc;
@ -467,12 +470,12 @@ next:
switch (index++) { switch (index++) {
case 0: case 0:
spa_pod_builder_format (&b, &f[0], spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16, 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_S16,
SPA_AUDIO_FORMAT_S32), 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], this->uri.prop_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.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
break; break;
default: default:
return SPA_RESULT_ENUM_END; 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_init (&b, this->format_buffer, sizeof (this->format_buffer));
spa_pod_builder_format (&b, &f[0], spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, this->current_format.info.raw.format), PROP (&f[1], this->uri.prop_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], this->uri.prop_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)); 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); *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.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_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->node = audiotestsrc_node;
this->clock = audiotestsrc_clock; this->clock = audiotestsrc_clock;

View file

@ -57,6 +57,8 @@ typedef struct {
typedef struct { typedef struct {
uint32_t node; uint32_t node;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
} URI; } URI;
struct _SpaFFMpegEnc { struct _SpaFFMpegEnc {
@ -264,8 +266,8 @@ spa_ffmpeg_enc_node_port_set_format (SpaNode *node,
return SPA_RESULT_OK; return SPA_RESULT_OK;
} }
if (format->body.media_type.value != SPA_MEDIA_TYPE_VIDEO || if (format->body.media_type.value != this->uri.media_types.video ||
format->body.media_subtype.value != SPA_MEDIA_SUBTYPE_RAW) format->body.media_subtype.value != this->uri.media_subtypes.raw)
return SPA_RESULT_INVALID_MEDIA_TYPE; return SPA_RESULT_INVALID_MEDIA_TYPE;
if ((res = spa_format_video_parse (format, &query_format) < 0)) if ((res = spa_format_video_parse (format, &query_format) < 0))
@ -542,6 +544,8 @@ spa_ffmpeg_enc_init (SpaHandle *handle,
return SPA_RESULT_ERROR; return SPA_RESULT_ERROR;
} }
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI); 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; this->node = ffmpeg_enc_node;

View file

@ -65,6 +65,10 @@ struct _V4l2Buffer {
typedef struct { typedef struct {
uint32_t node; uint32_t node;
uint32_t clock; uint32_t clock;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaMediaSubtypesVideo media_subtypes_video;
SpaPropVideo prop_video;
} URI; } URI;
typedef struct { typedef struct {
@ -112,9 +116,9 @@ struct _SpaV4l2Source {
SpaNode node; SpaNode node;
SpaClock clock; SpaClock clock;
URI uri;
SpaIDMap *map; SpaIDMap *map;
SpaLog *log; SpaLog *log;
URI uri;
uint32_t seq; 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_type,
state->current_format.media_subtype); state->current_format.media_subtype);
switch (state->current_format.media_subtype) { if (state->current_format.media_subtype == this->uri.media_subtypes.raw) {
case SPA_MEDIA_SUBTYPE_RAW:
spa_pod_builder_add (&b, 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], this->uri.prop_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], this->uri.prop_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), PROP (&f[1], this->uri.prop_video.framerate, -SPA_POD_TYPE_FRACTION, &state->current_format.info.raw.framerate),
0); 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;
} }
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]); spa_pod_builder_pop (&b, &f[0]);
*format = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); *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.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_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->node = v4l2source_node;
this->clock = v4l2source_clock; this->clock = v4l2source_clock;

View file

@ -165,117 +165,137 @@ spa_v4l2_close (SpaV4l2Source *this)
typedef struct { typedef struct {
uint32_t fourcc; uint32_t fourcc;
SpaVideoFormat format; SpaVideoFormat format;
SpaMediaType media_type; off_t media_type_offset;
SpaMediaSubType media_subtype; off_t media_subtype_offset;
} FormatInfo; } 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[] = static const FormatInfo format_info[] =
{ {
/* RGB formats */ /* RGB formats */
{ V4L2_PIX_FMT_RGB332, SPA_VIDEO_FORMAT_UNKNOWN, 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, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_ARGB555, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_XRGB555, SPA_VIDEO_FORMAT_RGB15, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_XRGB555, SPA_VIDEO_FORMAT_RGB15, VIDEO, RAW },
{ V4L2_PIX_FMT_ARGB555X, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_ARGB555X, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_XRGB555X, SPA_VIDEO_FORMAT_BGR15, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_XRGB555X, SPA_VIDEO_FORMAT_BGR15, VIDEO, RAW },
{ V4L2_PIX_FMT_RGB565, SPA_VIDEO_FORMAT_RGB16, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_RGB565, SPA_VIDEO_FORMAT_RGB16, VIDEO, RAW },
{ V4L2_PIX_FMT_RGB565X, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_RGB565X, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_BGR666, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_BGR666, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_BGR24, SPA_VIDEO_FORMAT_BGR, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_BGR24, SPA_VIDEO_FORMAT_BGR, VIDEO, RAW },
{ V4L2_PIX_FMT_RGB24, SPA_VIDEO_FORMAT_RGB, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_RGB24, SPA_VIDEO_FORMAT_RGB, VIDEO, RAW },
{ V4L2_PIX_FMT_ABGR32, SPA_VIDEO_FORMAT_BGRA, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_ABGR32, SPA_VIDEO_FORMAT_BGRA, VIDEO, RAW },
{ V4L2_PIX_FMT_XBGR32, SPA_VIDEO_FORMAT_BGRx, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_XBGR32, SPA_VIDEO_FORMAT_BGRx, VIDEO, RAW },
{ V4L2_PIX_FMT_ARGB32, SPA_VIDEO_FORMAT_ARGB, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_ARGB32, SPA_VIDEO_FORMAT_ARGB, VIDEO, RAW },
{ V4L2_PIX_FMT_XRGB32, SPA_VIDEO_FORMAT_xRGB, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_XRGB32, SPA_VIDEO_FORMAT_xRGB, VIDEO, RAW },
/* Deprecated Packed RGB Image Formats (alpha ambiguity) */ /* 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_RGB444, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_RGB555, SPA_VIDEO_FORMAT_RGB15, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_RGB555, SPA_VIDEO_FORMAT_RGB15, VIDEO, RAW },
{ V4L2_PIX_FMT_RGB555X, SPA_VIDEO_FORMAT_BGR15, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_RGB555X, SPA_VIDEO_FORMAT_BGR15, VIDEO, RAW },
{ V4L2_PIX_FMT_BGR32, SPA_VIDEO_FORMAT_BGRx, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_BGR32, SPA_VIDEO_FORMAT_BGRx, VIDEO, RAW },
{ V4L2_PIX_FMT_RGB32, SPA_VIDEO_FORMAT_xRGB, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_RGB32, SPA_VIDEO_FORMAT_xRGB, VIDEO, RAW },
/* Grey formats */ /* Grey formats */
{ V4L2_PIX_FMT_GREY, SPA_VIDEO_FORMAT_GRAY8, 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, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_Y4, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_Y6, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_Y6, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_Y10, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_Y10, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_Y12, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_Y12, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_Y16, SPA_VIDEO_FORMAT_GRAY16_LE, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_Y16, SPA_VIDEO_FORMAT_GRAY16_LE, VIDEO, RAW },
{ V4L2_PIX_FMT_Y16_BE, SPA_VIDEO_FORMAT_GRAY16_BE, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_Y16_BE, SPA_VIDEO_FORMAT_GRAY16_BE, VIDEO, RAW },
{ V4L2_PIX_FMT_Y10BPACK, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_Y10BPACK, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
/* Palette formats */ /* 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 */ /* 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 */ /* Luminance+Chrominance formats */
{ V4L2_PIX_FMT_YVU410, SPA_VIDEO_FORMAT_YVU9, 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, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YVU420, SPA_VIDEO_FORMAT_YV12, VIDEO, RAW },
{ V4L2_PIX_FMT_YVU420M, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YVU420M, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_YUYV, SPA_VIDEO_FORMAT_YUY2, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YUYV, SPA_VIDEO_FORMAT_YUY2, VIDEO, RAW },
{ V4L2_PIX_FMT_YYUV, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YYUV, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_YVYU, SPA_VIDEO_FORMAT_YVYU, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YVYU, SPA_VIDEO_FORMAT_YVYU, VIDEO, RAW },
{ V4L2_PIX_FMT_UYVY, SPA_VIDEO_FORMAT_UYVY, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_UYVY, SPA_VIDEO_FORMAT_UYVY, VIDEO, RAW },
{ V4L2_PIX_FMT_VYUY, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_VYUY, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_YUV422P, SPA_VIDEO_FORMAT_Y42B, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YUV422P, SPA_VIDEO_FORMAT_Y42B, VIDEO, RAW },
{ V4L2_PIX_FMT_YUV411P, SPA_VIDEO_FORMAT_Y41B, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YUV411P, SPA_VIDEO_FORMAT_Y41B, VIDEO, RAW },
{ V4L2_PIX_FMT_Y41P, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_Y41P, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_YUV444, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YUV444, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_YUV555, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YUV555, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_YUV565, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YUV565, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_YUV32, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YUV32, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_YUV410, SPA_VIDEO_FORMAT_YUV9, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YUV410, SPA_VIDEO_FORMAT_YUV9, VIDEO, RAW },
{ V4L2_PIX_FMT_YUV420, SPA_VIDEO_FORMAT_I420, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YUV420, SPA_VIDEO_FORMAT_I420, VIDEO, RAW },
{ V4L2_PIX_FMT_YUV420M, SPA_VIDEO_FORMAT_I420, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_YUV420M, SPA_VIDEO_FORMAT_I420, VIDEO, RAW },
{ V4L2_PIX_FMT_HI240, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_HI240, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_HM12, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_HM12, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_M420, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_M420, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
/* two planes -- one Y, one Cr + Cb interleaved */ /* 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_NV12, SPA_VIDEO_FORMAT_NV12, VIDEO, RAW },
{ V4L2_PIX_FMT_NV12M, SPA_VIDEO_FORMAT_NV12, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_NV12M, SPA_VIDEO_FORMAT_NV12, VIDEO, RAW },
{ V4L2_PIX_FMT_NV12MT, SPA_VIDEO_FORMAT_NV12_64Z32, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_NV12MT, SPA_VIDEO_FORMAT_NV12_64Z32, VIDEO, RAW },
{ V4L2_PIX_FMT_NV12MT_16X16, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_NV12MT_16X16, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_NV21, SPA_VIDEO_FORMAT_NV21, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_NV21, SPA_VIDEO_FORMAT_NV21, VIDEO, RAW },
{ V4L2_PIX_FMT_NV21M, SPA_VIDEO_FORMAT_NV21, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_NV21M, SPA_VIDEO_FORMAT_NV21, VIDEO, RAW },
{ V4L2_PIX_FMT_NV16, SPA_VIDEO_FORMAT_NV16, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_NV16, SPA_VIDEO_FORMAT_NV16, VIDEO, RAW },
{ V4L2_PIX_FMT_NV16M, SPA_VIDEO_FORMAT_NV16, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_NV16M, SPA_VIDEO_FORMAT_NV16, VIDEO, RAW },
{ V4L2_PIX_FMT_NV61, SPA_VIDEO_FORMAT_NV61, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_NV61, SPA_VIDEO_FORMAT_NV61, VIDEO, RAW },
{ V4L2_PIX_FMT_NV61M, SPA_VIDEO_FORMAT_NV61, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_NV61M, SPA_VIDEO_FORMAT_NV61, VIDEO, RAW },
{ V4L2_PIX_FMT_NV24, SPA_VIDEO_FORMAT_NV24, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_NV24, SPA_VIDEO_FORMAT_NV24, VIDEO, RAW },
{ V4L2_PIX_FMT_NV42, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_NV42, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ /* 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_SBGGR8, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, BAYER },
{ V4L2_PIX_FMT_SGBRG8, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_BAYER }, { V4L2_PIX_FMT_SGBRG8, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, BAYER },
{ V4L2_PIX_FMT_SGRBG8, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_BAYER }, { V4L2_PIX_FMT_SGRBG8, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, BAYER },
{ V4L2_PIX_FMT_SRGGB8, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_BAYER }, { V4L2_PIX_FMT_SRGGB8, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, BAYER },
/* compressed formats */ /* compressed formats */
{ V4L2_PIX_FMT_MJPEG, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_MJPG }, { V4L2_PIX_FMT_MJPEG, SPA_VIDEO_FORMAT_ENCODED, VIDEO, MJPG },
{ V4L2_PIX_FMT_JPEG, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_IMAGE, SPA_MEDIA_SUBTYPE_JPEG }, { V4L2_PIX_FMT_JPEG, SPA_VIDEO_FORMAT_ENCODED, IMAGE, JPEG },
{ V4L2_PIX_FMT_PJPG, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_PJPG, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_DV, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_DV }, { V4L2_PIX_FMT_DV, SPA_VIDEO_FORMAT_ENCODED, VIDEO, DV },
{ V4L2_PIX_FMT_MPEG, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_MPEGTS }, { V4L2_PIX_FMT_MPEG, SPA_VIDEO_FORMAT_ENCODED, VIDEO, MPEGTS },
{ V4L2_PIX_FMT_H264, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_H264 }, { V4L2_PIX_FMT_H264, SPA_VIDEO_FORMAT_ENCODED, VIDEO, H264 },
{ V4L2_PIX_FMT_H264_NO_SC, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_H264 }, { V4L2_PIX_FMT_H264_NO_SC, SPA_VIDEO_FORMAT_ENCODED, VIDEO, H264 },
{ V4L2_PIX_FMT_H264_MVC, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_H264 }, { V4L2_PIX_FMT_H264_MVC, SPA_VIDEO_FORMAT_ENCODED, VIDEO, H264 },
{ V4L2_PIX_FMT_H263, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_H263 }, { V4L2_PIX_FMT_H263, SPA_VIDEO_FORMAT_ENCODED, VIDEO, H263 },
{ V4L2_PIX_FMT_MPEG1, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_MPEG1 }, { V4L2_PIX_FMT_MPEG1, SPA_VIDEO_FORMAT_ENCODED, VIDEO, MPEG1 },
{ V4L2_PIX_FMT_MPEG2, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_MPEG2 }, { V4L2_PIX_FMT_MPEG2, SPA_VIDEO_FORMAT_ENCODED, VIDEO, MPEG2 },
{ V4L2_PIX_FMT_MPEG4, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_MPEG4 }, { V4L2_PIX_FMT_MPEG4, SPA_VIDEO_FORMAT_ENCODED, VIDEO, MPEG4 },
{ V4L2_PIX_FMT_XVID, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_XVID }, { V4L2_PIX_FMT_XVID, SPA_VIDEO_FORMAT_ENCODED, VIDEO, XVID },
{ V4L2_PIX_FMT_VC1_ANNEX_G, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_VC1 }, { V4L2_PIX_FMT_VC1_ANNEX_G, SPA_VIDEO_FORMAT_ENCODED, VIDEO, VC1 },
{ V4L2_PIX_FMT_VC1_ANNEX_L, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_VC1 }, { V4L2_PIX_FMT_VC1_ANNEX_L, SPA_VIDEO_FORMAT_ENCODED, VIDEO, VC1 },
{ V4L2_PIX_FMT_VP8, SPA_VIDEO_FORMAT_ENCODED, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_VP8 }, { V4L2_PIX_FMT_VP8, SPA_VIDEO_FORMAT_ENCODED, VIDEO, VP8 },
/* Vendor-specific formats */ /* Vendor-specific formats */
{ V4L2_PIX_FMT_WNVA, 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, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_SN9C10X, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_PWC1, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_PWC1, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
{ V4L2_PIX_FMT_PWC2, SPA_VIDEO_FORMAT_UNKNOWN, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW }, { V4L2_PIX_FMT_PWC2, SPA_VIDEO_FORMAT_UNKNOWN, VIDEO, RAW },
}; };
static const FormatInfo * static const FormatInfo *
@ -305,35 +325,42 @@ video_format_to_format_info (SpaVideoFormat format)
#endif #endif
static const FormatInfo * static const FormatInfo *
find_format_info_by_media_type (SpaMediaType type, find_format_info_by_media_type (URI *uri,
SpaMediaSubType subtype, uint32_t type,
uint32_t subtype,
SpaVideoFormat format, SpaVideoFormat format,
int startidx) int startidx)
{ {
int i; int i;
for (i = startidx; i < SPA_N_ELEMENTS (format_info); i++) { for (i = startidx; i < SPA_N_ELEMENTS (format_info); i++) {
if ((format_info[i].media_type == type) && uint32_t media_type, media_subtype, media_format;
(format_info[i].media_subtype == subtype) &&
(format == SPA_VIDEO_FORMAT_UNKNOWN || format_info[i].format == 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 &format_info[i];
} }
return NULL; return NULL;
} }
static SpaVideoFormat 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; SpaVideoFormat video_format = SPA_VIDEO_FORMAT_UNKNOWN;
if ((filter->body.media_type.value == SPA_MEDIA_TYPE_VIDEO || if ((filter->body.media_type.value == uri->media_types.video ||
filter->body.media_type.value == SPA_MEDIA_TYPE_IMAGE)) { filter->body.media_type.value == uri->media_types.image)) {
if (filter->body.media_subtype.value == SPA_MEDIA_SUBTYPE_RAW) { if (filter->body.media_subtype.value == uri->media_subtypes.raw) {
SpaPODProp *p; SpaPODProp *p;
uint32_t n_values; uint32_t n_values;
const uint32_t *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; return SPA_VIDEO_FORMAT_UNKNOWN;
if (p->body.value.type != SPA_POD_TYPE_INT) if (p->body.value.type != SPA_POD_TYPE_INT)
@ -457,6 +484,7 @@ spa_v4l2_enum_format (SpaV4l2Source *this,
SpaPODFrame f[2]; SpaPODFrame f[2];
SpaPODProp *prop; SpaPODProp *prop;
SpaPODBuilder b = { state->format_buffer, sizeof (state->format_buffer), }; SpaPODBuilder b = { state->format_buffer, sizeof (state->format_buffer), };
uint32_t media_type, media_subtype;
if (spa_v4l2_open (this) < 0) if (spa_v4l2_open (this) < 0)
return SPA_RESULT_ERROR; return SPA_RESULT_ERROR;
@ -483,11 +511,12 @@ next_fmtdesc:
if (filter) { if (filter) {
SpaVideoFormat video_format; 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) if (video_format == SPA_VIDEO_FORMAT_UNKNOWN)
return SPA_RESULT_ENUM_END; 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, filter->body.media_subtype.value,
video_format, video_format,
0); 0);
@ -516,7 +545,7 @@ next_frmsize:
SpaPODProp *p; SpaPODProp *p;
/* check if we have a fixed frame size */ /* 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; goto do_frmsize;
if (p->body.value.type != SPA_POD_TYPE_RECTANGLE) if (p->body.value.type != SPA_POD_TYPE_RECTANGLE)
@ -549,7 +578,7 @@ do_frmsize:
uint32_t i, n_values; uint32_t i, n_values;
/* check if we have a fixed frame size */ /* 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; goto have_size;
range = p->body.flags & SPA_POD_PROP_RANGE_MASK; range = p->body.flags & SPA_POD_PROP_RANGE_MASK;
@ -602,22 +631,25 @@ have_size:
} }
} }
spa_pod_builder_push_format (&b, &f[0], media_type = *SPA_MEMBER (&this->uri, info->media_type_offset, uint32_t);
info->media_type, media_subtype = *SPA_MEMBER (&this->uri, info->media_subtype_offset, uint32_t);
info->media_subtype);
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, 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); 0);
} }
spa_pod_builder_add (&b, spa_pod_builder_add (&b,
PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, SPA_POD_TYPE_RECTANGLE, state->frmsize.discrete.width, PROP (&f[1], this->uri.prop_video.size, SPA_POD_TYPE_RECTANGLE, state->frmsize.discrete.width,
state->frmsize.discrete.height), state->frmsize.discrete.height),
0); 0);
spa_pod_builder_push_prop (&b, &f[1], 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_RANGE_NONE |
SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_UNSET |
SPA_POD_PROP_FLAG_READWRITE); SPA_POD_PROP_FLAG_READWRITE);
@ -645,7 +677,7 @@ have_size:
uint32_t i, n_values; uint32_t i, n_values;
const SpaFraction step = { 1, 1 }, *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; goto have_framerate;
if (p->body.value.type != SPA_POD_TYPE_FRACTION) 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; fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
switch (format->media_subtype) { if (format->media_subtype == this->uri.media_subtypes.raw) {
case SPA_MEDIA_SUBTYPE_RAW:
video_format = format->info.raw.format; video_format = format->info.raw.format;
size = &format->info.raw.size; size = &format->info.raw.size;
framerate = &format->info.raw.framerate; framerate = &format->info.raw.framerate;
break; }
case SPA_MEDIA_SUBTYPE_MJPG: else if (format->media_subtype == this->uri.media_subtypes_video.mjpg ||
case SPA_MEDIA_SUBTYPE_JPEG: format->media_subtype == this->uri.media_subtypes_video.jpeg) {
video_format = SPA_VIDEO_FORMAT_ENCODED; video_format = SPA_VIDEO_FORMAT_ENCODED;
size = &format->info.mjpg.size; size = &format->info.mjpg.size;
framerate = &format->info.mjpg.framerate; framerate = &format->info.mjpg.framerate;
break; }
case SPA_MEDIA_SUBTYPE_H264: else if (format->media_subtype == this->uri.media_subtypes_video.h264) {
video_format = SPA_VIDEO_FORMAT_ENCODED; video_format = SPA_VIDEO_FORMAT_ENCODED;
size = &format->info.h264.size; size = &format->info.h264.size;
framerate = &format->info.h264.framerate; framerate = &format->info.h264.framerate;
break; }
case SPA_MEDIA_SUBTYPE_DV: else {
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; video_format = SPA_VIDEO_FORMAT_ENCODED;
break;
} }
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, format->media_subtype,
video_format, video_format,
0); 0);

View file

@ -144,8 +144,8 @@ drawing_data_init (DrawingData *dd,
SpaVideoInfo *format = &this->current_format; SpaVideoInfo *format = &this->current_format;
SpaRectangle *size = &format->info.raw.size; SpaRectangle *size = &format->info.raw.size;
if ((format->media_type != SPA_MEDIA_TYPE_VIDEO) || if ((format->media_type != this->uri.media_types.video) ||
(format->media_subtype != SPA_MEDIA_SUBTYPE_RAW)) (format->media_subtype != this->uri.media_subtypes.raw))
return SPA_RESULT_NOT_IMPLEMENTED; return SPA_RESULT_NOT_IMPLEMENTED;
switch (format->info.raw.format) { switch (format->info.raw.format) {

View file

@ -39,6 +39,9 @@
typedef struct { typedef struct {
uint32_t node; uint32_t node;
uint32_t clock; uint32_t clock;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaPropVideo prop_video;
} URI; } URI;
typedef struct _SpaVideoTestSrc SpaVideoTestSrc; typedef struct _SpaVideoTestSrc SpaVideoTestSrc;
@ -450,16 +453,16 @@ next:
switch (index++) { switch (index++) {
case 0: case 0:
spa_pod_builder_format (&b, &f[0], spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, this->uri.media_types.video, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, 3, 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_RGB, SPA_VIDEO_FORMAT_RGB,
SPA_VIDEO_FORMAT_UYVY), 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, 320, 240,
1, 1, 1, 1,
INT32_MAX, INT32_MAX), 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, 25, 1,
0, 1, 0, 1,
INT32_MAX, 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_init (&b, this->format_buffer, sizeof (this->format_buffer));
spa_pod_builder_format (&b, &f[0], spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, this->uri.media_types.video, this->uri.media_subtypes.raw,
PROP (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, this->current_format.info.raw.format), PROP (&f[1], this->uri.prop_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], this->uri.prop_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)); 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); *format = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat);
return SPA_RESULT_OK; 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.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_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->node = videotestsrc_node;
this->clock = videotestsrc_clock; this->clock = videotestsrc_clock;

View file

@ -63,6 +63,9 @@ typedef struct {
typedef struct { typedef struct {
uint32_t node; uint32_t node;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaPropAudio prop_audio;
} URI; } URI;
struct _SpaVolume { struct _SpaVolume {
@ -307,13 +310,14 @@ next:
switch (index++) { switch (index++) {
case 0: case 0:
spa_pod_builder_format (&b, &f[0], SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, spa_pod_builder_format (&b, &f[0],
PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, 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_S16, SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S32), 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], this->uri.prop_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.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
break; break;
default: default:
@ -837,6 +841,9 @@ volume_init (const SpaHandleFactory *factory,
return SPA_RESULT_ERROR; return SPA_RESULT_ERROR;
} }
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI); 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; this->node = volume_node;
reset_volume_props (&this->props); reset_volume_props (&this->props);

View file

@ -71,6 +71,8 @@ typedef struct {
typedef struct { typedef struct {
uint32_t node; uint32_t node;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
} URI; } URI;
struct _SpaXvSink { struct _SpaXvSink {
@ -324,8 +326,8 @@ spa_xv_sink_node_port_set_format (SpaNode *node,
return SPA_RESULT_OK; return SPA_RESULT_OK;
} }
if (format->body.media_type.value == SPA_MEDIA_TYPE_VIDEO) { if (format->body.media_type.value == this->uri.media_types.video) {
if (format->body.media_subtype.value == SPA_MEDIA_SUBTYPE_RAW) { if (format->body.media_subtype.value == this->uri.media_subtypes.raw) {
if ((res = spa_format_video_parse (format, &info) < 0)) if ((res = spa_format_video_parse (format, &info) < 0))
return res; return res;
} else } else
@ -569,6 +571,8 @@ xv_sink_init (const SpaHandleFactory *factory,
return SPA_RESULT_ERROR; return SPA_RESULT_ERROR;
} }
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI); 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; this->node = xvsink_node;
reset_xv_sink_props (&this->props); reset_xv_sink_props (&this->props);

View file

@ -40,19 +40,19 @@
*/ */
spa_build (SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, 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_VIDEO_FORMAT_I420
SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_UNSET |
SPA_PROP_RANGE_ENUM, 2, SPA_PROP_RANGE_ENUM, 2,
SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_I420,
SPA_VIDEO_FORMAT_YUY2, SPA_VIDEO_FORMAT_YUY2,
SPA_PROP_ID_VIDEO_SIZE , SPA_PROP_TYPE_RECTANGLE, prop_video.size , SPA_PROP_TYPE_RECTANGLE,
320, 240, 320, 240,
SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_UNSET |
SPA_PROP_RANGE_MIN_MAX, SPA_PROP_RANGE_MIN_MAX,
1, 1, 1, 1,
INT32_MAX, INT32_MAX, 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_POD_PROP_FLAG_UNSET |
SPA_PROP_RANGE_MIN_MAX, SPA_PROP_RANGE_MIN_MAX,
0, 1, 0, 1,
@ -60,7 +60,14 @@ spa_build (SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW,
0); 0);
#endif #endif
static const struct _test_format { static SpaMediaTypes media_types;
static SpaMediaSubtypes media_subtypes;
static SpaPropVideo prop_video;
static void
do_static_struct (void)
{
struct _test_format {
SpaFormat fmt; SpaFormat fmt;
struct { struct {
@ -88,19 +95,19 @@ static const struct _test_format {
} test_format = { } test_format = {
{ { sizeof (test_format.props) + sizeof (SpaFormatBody), SPA_POD_TYPE_OBJECT }, { { sizeof (test_format.props) + sizeof (SpaFormatBody), SPA_POD_TYPE_OBJECT },
{ { 0, 0 }, { { 0, 0 },
{ { sizeof (uint32_t), SPA_POD_TYPE_INT }, SPA_MEDIA_TYPE_VIDEO }, { { sizeof (uint32_t), SPA_POD_TYPE_URI }, media_types.video },
{ { sizeof (uint32_t), SPA_POD_TYPE_INT }, SPA_MEDIA_SUBTYPE_RAW } }, { { sizeof (uint32_t), SPA_POD_TYPE_URI }, media_subtypes.raw } },
}, { }, {
{ { sizeof (test_format.props.format_vals) + sizeof (SpaPODPropBody), { { sizeof (test_format.props.format_vals) + sizeof (SpaPODPropBody),
SPA_POD_TYPE_PROP } , SPA_POD_TYPE_PROP } ,
{ SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET, { prop_video.format, SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET,
{ sizeof (uint32_t), SPA_POD_TYPE_INT } }, }, { sizeof (uint32_t), SPA_POD_TYPE_INT } }, },
{ SPA_VIDEO_FORMAT_I420, { SPA_VIDEO_FORMAT_I420,
{ SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_YUY2 } }, 0, { SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_YUY2 } }, 0,
{ { sizeof (test_format.props.size_vals) + sizeof (SpaPODPropBody), { { sizeof (test_format.props.size_vals) + sizeof (SpaPODPropBody),
SPA_POD_TYPE_PROP } , SPA_POD_TYPE_PROP } ,
{ SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET, { prop_video.size, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET,
{ sizeof (SpaRectangle), SPA_POD_TYPE_RECTANGLE } }, }, { sizeof (SpaRectangle), SPA_POD_TYPE_RECTANGLE } }, },
{ { 320, 243 }, { { 320, 243 },
{ 1, 1 }, { 1, 1 },
@ -108,7 +115,7 @@ static const struct _test_format {
{ { sizeof (test_format.props.framerate_vals) + sizeof (SpaPODPropBody), { { sizeof (test_format.props.framerate_vals) + sizeof (SpaPODPropBody),
SPA_POD_TYPE_PROP } , SPA_POD_TYPE_PROP } ,
{ SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET, { prop_video.framerate, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET,
{ sizeof (SpaFraction), SPA_POD_TYPE_FRACTION } }, }, { sizeof (SpaFraction), SPA_POD_TYPE_FRACTION } }, },
{ { 25, 1 }, { { 25, 1 },
{ 0, 1 }, { 0, 1 },
@ -116,6 +123,23 @@ static const struct _test_format {
} }
}; };
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 int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
@ -124,13 +148,17 @@ main (int argc, char *argv[])
uint8_t buffer[1024]; uint8_t buffer[1024];
SpaFormat *fmt; 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)); spa_pod_builder_init (&b, buffer, sizeof (buffer));
fmt = SPA_MEMBER (buffer, spa_pod_builder_push_format (&b, &frame[0], fmt = SPA_MEMBER (buffer, spa_pod_builder_push_format (&b, &frame[0],
SPA_MEDIA_TYPE_VIDEO, media_types.video,
SPA_MEDIA_SUBTYPE_RAW), SpaFormat); media_subtypes.raw), SpaFormat);
spa_pod_builder_push_prop (&b, &frame[1], 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_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);
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 } }; SpaRectangle size_min_max[] = { { 1, 1 }, { INT32_MAX, INT32_MAX } };
spa_pod_builder_push_prop (&b, &frame[1], 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_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE);
spa_pod_builder_rectangle (&b, 320, 240); spa_pod_builder_rectangle (&b, 320, 240);
spa_pod_builder_raw (&b, size_min_max, sizeof(size_min_max)); 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 } }; SpaFraction rate_min_max[] = { { 0, 1 }, { INT32_MAX, 1 } };
spa_pod_builder_push_prop (&b, &frame[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_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE);
spa_pod_builder_fraction (&b, 25, 1); spa_pod_builder_fraction (&b, 25, 1);
spa_pod_builder_raw (&b, rate_min_max, sizeof(rate_min_max)); 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_init (&b, buffer, sizeof (buffer));
spa_pod_builder_format (&b, &frame[0], 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_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_PROP_RANGE_ENUM,
SPA_POD_TYPE_INT, 3, SPA_POD_TYPE_INT, 3,
SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_I420,
@ -170,7 +198,7 @@ main (int argc, char *argv[])
SPA_VIDEO_FORMAT_YUY2, SPA_VIDEO_FORMAT_YUY2,
-SPA_POD_TYPE_PROP, &frame[1], -SPA_POD_TYPE_PROP, &frame[1],
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_PROP_RANGE_MIN_MAX,
SPA_POD_TYPE_RECTANGLE, 3, SPA_POD_TYPE_RECTANGLE, 3,
320, 241, 320, 241,
@ -178,7 +206,7 @@ main (int argc, char *argv[])
INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX,
-SPA_POD_TYPE_PROP, &frame[1], -SPA_POD_TYPE_PROP, &frame[1],
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_PROP_RANGE_MIN_MAX,
SPA_POD_TYPE_FRACTION, 3, SPA_POD_TYPE_FRACTION, 3,
25, 1, 25, 1,
@ -194,10 +222,10 @@ main (int argc, char *argv[])
spa_pod_builder_add (&b, spa_pod_builder_add (&b,
SPA_POD_TYPE_OBJECT, &frame[0], 0, 0, SPA_POD_TYPE_OBJECT, &frame[0], 0, 0,
SPA_POD_TYPE_INT, SPA_MEDIA_TYPE_VIDEO, SPA_POD_TYPE_URI, media_types.video,
SPA_POD_TYPE_INT, SPA_MEDIA_SUBTYPE_RAW, SPA_POD_TYPE_URI, media_subtypes.raw,
SPA_POD_TYPE_PROP, &frame[1], 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_PROP_RANGE_ENUM,
SPA_POD_TYPE_INT, 3, SPA_POD_TYPE_INT, 3,
SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_I420,
@ -205,7 +233,7 @@ main (int argc, char *argv[])
SPA_VIDEO_FORMAT_YUY2, SPA_VIDEO_FORMAT_YUY2,
-SPA_POD_TYPE_PROP, &frame[1], -SPA_POD_TYPE_PROP, &frame[1],
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_PROP_RANGE_MIN_MAX,
SPA_POD_TYPE_RECTANGLE, 3, SPA_POD_TYPE_RECTANGLE, 3,
320, 242, 320, 242,
@ -213,7 +241,7 @@ main (int argc, char *argv[])
INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX,
-SPA_POD_TYPE_PROP, &frame[1], -SPA_POD_TYPE_PROP, &frame[1],
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_PROP_RANGE_MIN_MAX,
SPA_POD_TYPE_FRACTION, 3, SPA_POD_TYPE_FRACTION, 3,
25, 1, 25, 1,
@ -227,20 +255,7 @@ main (int argc, char *argv[])
spa_debug_pod (&fmt->pod); spa_debug_pod (&fmt->pod);
spa_debug_format (fmt); spa_debug_format (fmt);
spa_debug_pod (&test_format.fmt.pod); do_static_struct ();
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);
}
return 0; return 0;
} }