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

@ -29,19 +29,41 @@ extern "C" {
typedef struct _SpaAudioInfo SpaAudioInfo;
typedef enum {
SPA_PROP_ID_AUDIO_INFO = SPA_PROP_ID_MEDIA_CUSTOM_START,
SPA_PROP_ID_AUDIO_FORMAT,
SPA_PROP_ID_AUDIO_FLAGS,
SPA_PROP_ID_AUDIO_LAYOUT,
SPA_PROP_ID_AUDIO_RATE,
SPA_PROP_ID_AUDIO_CHANNELS,
SPA_PROP_ID_AUDIO_CHANNEL_MASK,
} SpaPropIdAudio;
#define SPA_PROP_AUDIO_URI "http://spaplug.in/ns/prop-audio"
#define SPA_PROP_AUDIO_PREFIX SPA_PROP_AUDIO_URI "#"
#define SPA_PROP_AUDIO__format SPA_PROP_AUDIO_PREFIX "format"
#define SPA_PROP_AUDIO__flags SPA_PROP_AUDIO_PREFIX "flags"
#define SPA_PROP_AUDIO__layout SPA_PROP_AUDIO_PREFIX "layout"
#define SPA_PROP_AUDIO__rate SPA_PROP_AUDIO_PREFIX "rate"
#define SPA_PROP_AUDIO__channels SPA_PROP_AUDIO_PREFIX "channels"
#define SPA_PROP_AUDIO__channelMask SPA_PROP_AUDIO_PREFIX "channel-mask"
typedef struct {
uint32_t format;
uint32_t flags;
uint32_t layout;
uint32_t rate;
uint32_t channels;
uint32_t channel_mask;
} SpaPropAudio;
static inline void
spa_prop_audio_map (SpaIDMap *map, SpaPropAudio *types)
{
if (types->format == 0) {
types->format = spa_id_map_get_id (map, SPA_PROP_AUDIO__format);
types->flags = spa_id_map_get_id (map, SPA_PROP_AUDIO__flags);
types->layout = spa_id_map_get_id (map, SPA_PROP_AUDIO__layout);
types->rate = spa_id_map_get_id (map, SPA_PROP_AUDIO__rate);
types->channels = spa_id_map_get_id (map, SPA_PROP_AUDIO__channels);
types->channel_mask = spa_id_map_get_id (map, SPA_PROP_AUDIO__channelMask);
}
}
struct _SpaAudioInfo {
SpaMediaType media_type;
SpaMediaSubType media_subtype;
uint32_t media_type;
uint32_t media_subtype;
union {
SpaAudioInfoRaw raw;
} info;

View file

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

View file

@ -33,66 +33,152 @@ typedef struct _SpaFormat SpaFormat;
#include <spa/defs.h>
#include <spa/pod-utils.h>
#include <spa/id-map.h>
typedef enum {
SPA_MEDIA_TYPE_INVALID = 0,
SPA_MEDIA_TYPE_AUDIO = 1,
SPA_MEDIA_TYPE_VIDEO = 2,
SPA_MEDIA_TYPE_IMAGE = 3,
} SpaMediaType;
#define SPA_MEDIA_TYPE_URI "http://spaplug.in/ns/media-type"
#define SPA_MEDIA_TYPE_PREFIX SPA_MEDIA_TYPE_URI "#"
typedef enum {
SPA_MEDIA_SUBTYPE_INVALID = 0,
#define SPA_MEDIA_TYPE__audio SPA_MEDIA_TYPE_PREFIX "audio"
#define SPA_MEDIA_TYPE__video SPA_MEDIA_TYPE_PREFIX "video"
#define SPA_MEDIA_TYPE__image SPA_MEDIA_TYPE_PREFIX "image"
#define SPA_MEDIA_SUBTYPE_ANY_FIRST 1
SPA_MEDIA_SUBTYPE_RAW = SPA_MEDIA_SUBTYPE_ANY_FIRST,
#define SPA_MEDIA_SUBTYPE_ANY_LAST SPA_MEDIA_SUBTYPE_RAW
typedef struct {
uint32_t audio;
uint32_t video;
uint32_t image;
} SpaMediaTypes;
/* VIDEO */
#define SPA_MEDIA_SUBTYPE_VIDEO_FIRST 20
SPA_MEDIA_SUBTYPE_H264 = SPA_MEDIA_SUBTYPE_VIDEO_FIRST,
SPA_MEDIA_SUBTYPE_MJPG,
SPA_MEDIA_SUBTYPE_DV,
SPA_MEDIA_SUBTYPE_MPEGTS,
SPA_MEDIA_SUBTYPE_H263,
SPA_MEDIA_SUBTYPE_MPEG1,
SPA_MEDIA_SUBTYPE_MPEG2,
SPA_MEDIA_SUBTYPE_MPEG4,
SPA_MEDIA_SUBTYPE_XVID,
SPA_MEDIA_SUBTYPE_VC1,
SPA_MEDIA_SUBTYPE_VP8,
SPA_MEDIA_SUBTYPE_VP9,
SPA_MEDIA_SUBTYPE_JPEG,
SPA_MEDIA_SUBTYPE_BAYER,
#define SPA_MEDIA_SUBTYPE_VIDEO_LAST SPA_MEDIA_SUBTYPE_BAYER
static inline void
spa_media_types_fill (SpaMediaTypes *types, SpaIDMap *map)
{
if (types->audio == 0) {
types->audio = spa_id_map_get_id (map, SPA_MEDIA_TYPE__audio);
types->video = spa_id_map_get_id (map, SPA_MEDIA_TYPE__video);
types->image = spa_id_map_get_id (map, SPA_MEDIA_TYPE__image);
}
}
/* AUDIO */
#define SPA_MEDIA_SUBTYPE_AUDIO_FIRST 200
SPA_MEDIA_SUBTYPE_MP3 = SPA_MEDIA_SUBTYPE_AUDIO_FIRST,
SPA_MEDIA_SUBTYPE_AAC,
SPA_MEDIA_SUBTYPE_VORBIS,
SPA_MEDIA_SUBTYPE_WMA,
SPA_MEDIA_SUBTYPE_RA,
SPA_MEDIA_SUBTYPE_SBC,
SPA_MEDIA_SUBTYPE_ADPCM,
SPA_MEDIA_SUBTYPE_G723,
SPA_MEDIA_SUBTYPE_G726,
SPA_MEDIA_SUBTYPE_G729,
SPA_MEDIA_SUBTYPE_AMR,
SPA_MEDIA_SUBTYPE_GSM,
#define SPA_MEDIA_SUBTYPE_AUDIO_LAST SPA_MEDIA_SUBTYPE_GSM
#define SPA_MEDIA_SUBTYPE_URI "http://spaplug.in/ns/media-subtype"
#define SPA_MEDIA_SUBTYPE_PREFIX SPA_MEDIA_TYPE_URI "#"
} SpaMediaSubType;
#define SPA_MEDIA_SUBTYPE__raw SPA_MEDIA_TYPE_PREFIX "raw"
typedef enum {
SPA_PROP_ID_INVALID = 0,
SPA_PROP_ID_MEDIA_CUSTOM_START = 200,
} SpaFormatProps;
typedef struct {
uint32_t raw;
} SpaMediaSubtypes;
static inline void
spa_media_subtypes_map (SpaIDMap *map, SpaMediaSubtypes *types)
{
if (types->raw == 0) {
types->raw = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__raw);
}
}
#define SPA_MEDIA_SUBTYPE__h264 SPA_MEDIA_SUBTYPE_PREFIX "h264"
#define SPA_MEDIA_SUBTYPE__mjpg SPA_MEDIA_SUBTYPE_PREFIX "mjpg"
#define SPA_MEDIA_SUBTYPE__dv SPA_MEDIA_SUBTYPE_PREFIX "dv"
#define SPA_MEDIA_SUBTYPE__mpegts SPA_MEDIA_SUBTYPE_PREFIX "mpegts"
#define SPA_MEDIA_SUBTYPE__h263 SPA_MEDIA_SUBTYPE_PREFIX "h263"
#define SPA_MEDIA_SUBTYPE__mpeg1 SPA_MEDIA_SUBTYPE_PREFIX "mpeg1"
#define SPA_MEDIA_SUBTYPE__mpeg2 SPA_MEDIA_SUBTYPE_PREFIX "mpeg2"
#define SPA_MEDIA_SUBTYPE__mpeg4 SPA_MEDIA_SUBTYPE_PREFIX "mpeg4"
#define SPA_MEDIA_SUBTYPE__xvid SPA_MEDIA_SUBTYPE_PREFIX "xvid"
#define SPA_MEDIA_SUBTYPE__vc1 SPA_MEDIA_SUBTYPE_PREFIX "vc1"
#define SPA_MEDIA_SUBTYPE__vp8 SPA_MEDIA_SUBTYPE_PREFIX "vp8"
#define SPA_MEDIA_SUBTYPE__vp9 SPA_MEDIA_SUBTYPE_PREFIX "vp9"
#define SPA_MEDIA_SUBTYPE__jpeg SPA_MEDIA_SUBTYPE_PREFIX "jpeg"
#define SPA_MEDIA_SUBTYPE__bayer SPA_MEDIA_SUBTYPE_PREFIX "bayer"
typedef struct {
uint32_t h264;
uint32_t mjpg;
uint32_t dv;
uint32_t mpegts;
uint32_t h263;
uint32_t mpeg1;
uint32_t mpeg2;
uint32_t mpeg4;
uint32_t xvid;
uint32_t vc1;
uint32_t vp8;
uint32_t vp9;
uint32_t jpeg;
uint32_t bayer;
} SpaMediaSubtypesVideo;
static inline void
spa_media_subtypes_video_map (SpaIDMap *map, SpaMediaSubtypesVideo *types)
{
if (types->h264 == 0) {
types->h264 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__h264);
types->mjpg = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__mjpg);
types->dv = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__dv);
types->mpegts = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__mpegts);
types->h263 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__h263);
types->mpeg1 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__mpeg1);
types->mpeg2 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__mpeg2);
types->mpeg4 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__mpeg4);
types->xvid = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__xvid);
types->vc1 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__vc1);
types->vp8 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__vp8);
types->vp9 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__vp9);
types->jpeg = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__jpeg);
types->bayer = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__bayer);
}
}
#define SPA_MEDIA_SUBTYPE__mp3 SPA_MEDIA_SUBTYPE_PREFIX "mp3"
#define SPA_MEDIA_SUBTYPE__aac SPA_MEDIA_SUBTYPE_PREFIX "aac"
#define SPA_MEDIA_SUBTYPE__vorbis SPA_MEDIA_SUBTYPE_PREFIX "vorbis"
#define SPA_MEDIA_SUBTYPE__wma SPA_MEDIA_SUBTYPE_PREFIX "wma"
#define SPA_MEDIA_SUBTYPE__ra SPA_MEDIA_SUBTYPE_PREFIX "ra"
#define SPA_MEDIA_SUBTYPE__sbc SPA_MEDIA_SUBTYPE_PREFIX "sbc"
#define SPA_MEDIA_SUBTYPE__adpcm SPA_MEDIA_SUBTYPE_PREFIX "adpcm"
#define SPA_MEDIA_SUBTYPE__g723 SPA_MEDIA_SUBTYPE_PREFIX "g723"
#define SPA_MEDIA_SUBTYPE__g726 SPA_MEDIA_SUBTYPE_PREFIX "g726"
#define SPA_MEDIA_SUBTYPE__g729 SPA_MEDIA_SUBTYPE_PREFIX "g729"
#define SPA_MEDIA_SUBTYPE__amr SPA_MEDIA_SUBTYPE_PREFIX "amr"
#define SPA_MEDIA_SUBTYPE__gsm SPA_MEDIA_SUBTYPE_PREFIX "gsm"
typedef struct {
uint32_t mp3;
uint32_t aac;
uint32_t vorbis;
uint32_t wma;
uint32_t ra;
uint32_t sbc;
uint32_t adpcm;
uint32_t g723;
uint32_t g726;
uint32_t g729;
uint32_t amr;
uint32_t gsm;
} SpaMediaSubtypesAudio;
static inline void
spa_media_subtypes_audio_map (SpaIDMap *map, SpaMediaSubtypesAudio *types)
{
if (types->mp3 == 0) {
types->mp3 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__mp3);
types->aac = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__aac);
types->vorbis = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__vorbis);
types->wma = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__wma);
types->ra = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__ra);
types->sbc = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__sbc);
types->adpcm = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__adpcm);
types->g723 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__g723);
types->g726 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__g726);
types->g729 = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__g729);
types->amr = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__amr);
types->gsm = spa_id_map_get_id (map, SPA_MEDIA_SUBTYPE__gsm);
}
}
typedef struct {
SpaPODObjectBody obj_body;
SpaPODInt media_type SPA_ALIGNED (8);
SpaPODInt media_subtype SPA_ALIGNED (8);
SpaPODURI media_type SPA_ALIGNED (8);
SpaPODURI media_subtype SPA_ALIGNED (8);
/* contents follow, series of SpaPODProp */
} SpaFormatBody;
@ -110,8 +196,8 @@ struct _SpaFormat {
#define SPA_FORMAT_INIT(size,type,media_type,media_subtype,...) \
{ { size, SPA_POD_TYPE_OBJECT }, \
{ { 0, type }, \
SPA_POD_INT_INIT (media_type), \
SPA_POD_INT_INIT (media_subtype) } }
SPA_POD_URI_INIT (media_type), \
SPA_POD_URI_INIT (media_subtype) } }
#define SPA_FORMAT_BODY_FOREACH(body, size, iter) \
for ((iter) = SPA_MEMBER ((body), sizeof (SpaFormatBody), SpaPODProp); \

View file

@ -341,30 +341,18 @@ spa_pod_builder_addv (SpaPODBuilder *builder,
uint32_t body_size;
static const uint64_t zeroes = 0;
while (type != 0) {
while (type != SPA_POD_TYPE_INVALID) {
SpaPODFrame *f = NULL;
const void *data[3];
uint32_t size[3], ref, i, n_sizes = 0;
switch (type) {
case SPA_POD_TYPE_INVALID:
case SPA_POD_TYPE_NONE:
break;
case SPA_POD_TYPE_BOOL:
head.bool_pod.pod.type = SPA_POD_TYPE_BOOL;
head.bool_pod.pod.size = body_size = sizeof (uint32_t);
head.bool_pod.value = va_arg (args, int);
head_size = sizeof (SpaPOD);
body = &head.bool_pod.value;
goto primitive;
case SPA_POD_TYPE_URI:
head.uri_pod.pod.type = SPA_POD_TYPE_URI;
head.uri_pod.pod.size = body_size = sizeof (uint32_t);
head.uri_pod.value = va_arg (args, int);
head_size = sizeof (SpaPOD);
body = &head.uri_pod.value;
goto primitive;
case SPA_POD_TYPE_INT:
head.int_pod.pod.type = SPA_POD_TYPE_INT;
head.int_pod.pod.type = type;
head.int_pod.pod.size = body_size = sizeof (uint32_t);
head.int_pod.value = va_arg (args, int);
head_size = sizeof (SpaPOD);

View file

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

View file

@ -30,34 +30,80 @@ extern "C" {
typedef struct _SpaVideoInfo SpaVideoInfo;
typedef enum {
SPA_PROP_ID_VIDEO_INFO = SPA_PROP_ID_MEDIA_CUSTOM_START,
SPA_PROP_ID_VIDEO_FORMAT,
SPA_PROP_ID_VIDEO_SIZE,
SPA_PROP_ID_VIDEO_FRAMERATE,
SPA_PROP_ID_VIDEO_MAX_FRAMERATE,
SPA_PROP_ID_VIDEO_VIEWS,
SPA_PROP_ID_VIDEO_INTERLACE_MODE,
SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO,
SPA_PROP_ID_VIDEO_MULTIVIEW_MODE,
SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS,
SPA_PROP_ID_VIDEO_CHROMA_SITE,
SPA_PROP_ID_VIDEO_COLOR_RANGE,
SPA_PROP_ID_VIDEO_COLOR_MATRIX,
SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION,
SPA_PROP_ID_VIDEO_COLOR_PRIMARIES,
SPA_PROP_ID_VIDEO_PROFILE,
SPA_PROP_ID_VIDEO_LEVEL,
SPA_PROP_ID_VIDEO_STREAM_FORMAT,
SPA_PROP_ID_VIDEO_ALIGNMENT,
} SpaPropIdVideo;
#define SPA_PROP_VIDEO_URI "http://spaplug.in/ns/prop-video"
#define SPA_PROP_VIDEO_PREFIX SPA_PROP_VIDEO_URI "#"
#define SPA_PROP_VIDEO__format SPA_PROP_VIDEO_PREFIX "format"
#define SPA_PROP_VIDEO__size SPA_PROP_VIDEO_PREFIX "size"
#define SPA_PROP_VIDEO__framerate SPA_PROP_VIDEO_PREFIX "framerate"
#define SPA_PROP_VIDEO__maxFramerate SPA_PROP_VIDEO_PREFIX "max-framerate"
#define SPA_PROP_VIDEO__views SPA_PROP_VIDEO_PREFIX "views"
#define SPA_PROP_VIDEO__interlaceMode SPA_PROP_VIDEO_PREFIX "interlace-mode"
#define SPA_PROP_VIDEO__pixelAspectRatio SPA_PROP_VIDEO_PREFIX "pixel-aspect-ratio"
#define SPA_PROP_VIDEO__multiviewMode SPA_PROP_VIDEO_PREFIX "multiview-mode"
#define SPA_PROP_VIDEO__multiviewFlags SPA_PROP_VIDEO_PREFIX "multiview-flags"
#define SPA_PROP_VIDEO__chromaSite SPA_PROP_VIDEO_PREFIX "chroma-site"
#define SPA_PROP_VIDEO__colorRange SPA_PROP_VIDEO_PREFIX "color-range"
#define SPA_PROP_VIDEO__colorMatrix SPA_PROP_VIDEO_PREFIX "color-matrix"
#define SPA_PROP_VIDEO__transferFunction SPA_PROP_VIDEO_PREFIX "transfer-function"
#define SPA_PROP_VIDEO__colorPrimaries SPA_PROP_VIDEO_PREFIX "color-primaries"
#define SPA_PROP_VIDEO__profile SPA_PROP_VIDEO_PREFIX "profile"
#define SPA_PROP_VIDEO__level SPA_PROP_VIDEO_PREFIX "level"
#define SPA_PROP_VIDEO__streamFormat SPA_PROP_VIDEO_PREFIX "stream-format"
#define SPA_PROP_VIDEO__alignment SPA_PROP_VIDEO_PREFIX "alignment"
typedef struct {
uint32_t format;
uint32_t size;
uint32_t framerate;
uint32_t max_framerate;
uint32_t views;
uint32_t interlace_mode;
uint32_t pixel_aspect_ratio;
uint32_t multiview_mode;
uint32_t multiview_flags;
uint32_t chroma_site;
uint32_t color_range;
uint32_t color_matrix;
uint32_t transfer_function;
uint32_t color_primaries;
uint32_t profile;
uint32_t level;
uint32_t stream_format;
uint32_t alignment;
} SpaPropVideo;
static inline void
spa_prop_video_map (SpaIDMap *map, SpaPropVideo *types)
{
if (types->format == 0) {
types->format = spa_id_map_get_id (map, SPA_PROP_VIDEO__format);
types->size = spa_id_map_get_id (map, SPA_PROP_VIDEO__size);
types->framerate = spa_id_map_get_id (map, SPA_PROP_VIDEO__framerate);
types->max_framerate = spa_id_map_get_id (map, SPA_PROP_VIDEO__maxFramerate);
types->views = spa_id_map_get_id (map, SPA_PROP_VIDEO__views);
types->interlace_mode = spa_id_map_get_id (map, SPA_PROP_VIDEO__interlaceMode);
types->pixel_aspect_ratio = spa_id_map_get_id (map, SPA_PROP_VIDEO__pixelAspectRatio);
types->multiview_mode = spa_id_map_get_id (map, SPA_PROP_VIDEO__multiviewMode);
types->multiview_flags = spa_id_map_get_id (map, SPA_PROP_VIDEO__multiviewFlags);
types->chroma_site = spa_id_map_get_id (map, SPA_PROP_VIDEO__chromaSite);
types->color_range = spa_id_map_get_id (map, SPA_PROP_VIDEO__colorRange);
types->color_matrix = spa_id_map_get_id (map, SPA_PROP_VIDEO__colorMatrix);
types->transfer_function = spa_id_map_get_id (map, SPA_PROP_VIDEO__transferFunction);
types->color_primaries = spa_id_map_get_id (map, SPA_PROP_VIDEO__colorPrimaries);
types->profile = spa_id_map_get_id (map, SPA_PROP_VIDEO__profile);
types->level = spa_id_map_get_id (map, SPA_PROP_VIDEO__level);
types->stream_format = spa_id_map_get_id (map, SPA_PROP_VIDEO__streamFormat);
types->alignment = spa_id_map_get_id (map, SPA_PROP_VIDEO__alignment);
}
}
SpaResult spa_format_video_parse (const SpaFormat *format,
SpaVideoInfo *info);
struct _SpaVideoInfo {
SpaMediaType media_type;
SpaMediaSubType media_subtype;
uint32_t media_type;
uint32_t media_subtype;
union {
SpaVideoInfoRaw raw;
SpaVideoInfoH264 h264;

View file

@ -22,78 +22,42 @@
#include <stdio.h>
#include <string.h>
#include <lib/mapper.h>
#include <spa/audio/raw.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
spa_format_audio_parse (const SpaFormat *format,
SpaAudioInfo *info)
{
SpaPODProp *prop;
const ParseInfo *pinfo, *find;
static SpaMediaTypes media_types = { 0, };
static SpaMediaSubtypes media_subtypes = { 0, };
static SpaMediaSubtypesAudio media_subtypes_audio = { 0, };
static SpaPropAudio prop_audio = { 0, };
if (format->body.media_type.value != SPA_MEDIA_TYPE_AUDIO)
spa_media_types_fill (&media_types, spa_id_map_get_default());
spa_media_subtypes_map (spa_id_map_get_default(), &media_subtypes);
spa_media_subtypes_audio_map (spa_id_map_get_default (), &media_subtypes_audio);
spa_prop_audio_map (spa_id_map_get_default (), &prop_audio);
if (format->body.media_type.value != media_types.audio)
return SPA_RESULT_INVALID_MEDIA_TYPE;
info->media_type = format->body.media_type.value;
info->media_subtype = format->body.media_subtype.value;
switch (info->media_subtype) {
case SPA_MEDIA_SUBTYPE_RAW:
pinfo = raw_parse_info;
break;
case SPA_MEDIA_SUBTYPE_MP3:
case SPA_MEDIA_SUBTYPE_AAC:
case SPA_MEDIA_SUBTYPE_VORBIS:
case SPA_MEDIA_SUBTYPE_WMA:
case SPA_MEDIA_SUBTYPE_RA:
case SPA_MEDIA_SUBTYPE_SBC:
case SPA_MEDIA_SUBTYPE_ADPCM:
case SPA_MEDIA_SUBTYPE_G723:
case SPA_MEDIA_SUBTYPE_G726:
case SPA_MEDIA_SUBTYPE_G729:
case SPA_MEDIA_SUBTYPE_AMR:
case SPA_MEDIA_SUBTYPE_GSM:
return SPA_RESULT_NOT_IMPLEMENTED;
default:
return SPA_RESULT_INVALID_ARGUMENTS;
if (info->media_subtype == media_subtypes.raw) {
spa_format_query (format,
prop_audio.format, SPA_POD_TYPE_INT, &info->info.raw.format,
prop_audio.flags, SPA_POD_TYPE_INT, &info->info.raw.flags,
prop_audio.layout, SPA_POD_TYPE_INT, &info->info.raw.layout,
prop_audio.rate, SPA_POD_TYPE_INT, &info->info.raw.rate,
prop_audio.channels, SPA_POD_TYPE_INT, &info->info.raw.channels,
prop_audio.channel_mask, SPA_POD_TYPE_INT, &info->info.raw.channel_mask,
0);
}
else
return SPA_RESULT_NOT_IMPLEMENTED;
SPA_FORMAT_FOREACH (format, prop) {
if ((find = parse_info_find (pinfo, prop->body.key, prop->body.value.type))) {
memcpy (SPA_MEMBER (info, find->offset, void),
SPA_POD_BODY (&prop->body.value),
SPA_POD_BODY_SIZE (&prop->body.value));
}
}
return SPA_RESULT_OK;
}

View file

@ -19,6 +19,7 @@
#include <stdio.h>
#include <lib/mapper.h>
#include "debug.h"
static const struct meta_type_name {
@ -180,92 +181,12 @@ spa_debug_props (const SpaProps *props, bool print_ranges)
return SPA_RESULT_OK;
}
static const char* media_audio_prop_names[] = {
"info",
"format",
"flags",
"layout",
"rate",
"channels",
"channel-mask",
};
static const char* media_video_prop_names[] = {
"info",
"format",
"size",
"framerate",
"max-framerate",
"views",
"interlace-mode",
"pixel-aspect-ratio",
"multiview-mode",
"multiview-flags",
"chroma-site",
"color-range",
"color-matrix",
"transfer-function",
"color-primaries",
"profile",
"stream-format",
"alignment",
};
static const struct media_type_name {
const char *name;
unsigned int first;
unsigned int last;
unsigned int idx;
const char **prop_names;
} media_type_names[] = {
{ "invalid", 0, 0, 0 },
{ "audio", SPA_MEDIA_SUBTYPE_AUDIO_FIRST, SPA_MEDIA_SUBTYPE_AUDIO_LAST, 16, media_audio_prop_names },
{ "video", SPA_MEDIA_SUBTYPE_VIDEO_FIRST, SPA_MEDIA_SUBTYPE_VIDEO_LAST, 2, media_video_prop_names },
{ "image", 0, 0 },
};
static const struct media_subtype_name {
const char *name;
} media_subtype_names[] = {
{ "invalid" },
{ "raw" },
{ "h264" },
{ "mjpg" },
{ "dv" },
{ "mpegts" },
{ "h263" },
{ "mpeg1" },
{ "mpeg2" },
{ "mpeg4" },
{ "xvid" },
{ "vc1" },
{ "vp8" },
{ "vp9" },
{ "jpeg" },
{ "bayer" },
{ "mp3" },
{ "aac" },
{ "vorbis" },
{ "wma" },
{ "ra" },
{ "sbc" },
{ "adpcm" },
{ "g723" },
{ "g726" },
{ "g729" },
{ "amr" },
{ "gsm" },
};
struct pod_type_name {
const char *name;
const char *CCName;
} pod_type_names[] = {
{ "invalid", "*Invalid*" },
{ "ignored", "ignored" },
{ "bool", "Bool" },
{ "uri", "URI" },
{ "int", "Int" },
@ -291,7 +212,8 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix)
printf ("%-*sBool %d\n", prefix, "", *(int32_t *) body);
break;
case SPA_POD_TYPE_URI:
printf ("%-*sURI %d\n", prefix, "", *(int32_t *) body);
printf ("%-*sURI %d %s\n", prefix, "", *(int32_t *) body,
spa_id_map_get_uri (spa_id_map_get_default(), *(int32_t*)body));
break;
case SPA_POD_TYPE_INT:
printf ("%-*sInt %d\n", prefix, "", *(int32_t *) body);
@ -357,7 +279,8 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix)
void *alt;
int i;
printf ("%-*sProp: key %d, flags %d\n", prefix, "", b->key, b->flags);
printf ("%-*sProp: key %s, flags %d\n", prefix, "",
spa_id_map_get_uri (spa_id_map_get_default(), b->key), b->flags);
if (b->flags & SPA_POD_PROP_FLAG_UNSET)
printf ("%-*sUnset (Default):\n", prefix + 2, "");
else
@ -441,10 +364,9 @@ print_format_value (uint32_t size, uint32_t type, void *body)
SpaResult
spa_debug_format (const SpaFormat *format)
{
int i, first, last, idx;
int i;
const char *media_type;
const char *media_subtype;
const char **prop_names;
SpaPODProp *prop;
uint32_t mtype, mstype;
@ -454,35 +376,22 @@ spa_debug_format (const SpaFormat *format)
mtype = format->body.media_type.value;
mstype = format->body.media_subtype.value;
if (mtype > 0 && mtype < SPA_N_ELEMENTS (media_type_names)) {
media_type = media_type_names[mtype].name;
first = media_type_names[mtype].first;
last = media_type_names[mtype].last;
idx = media_type_names[mtype].idx;
prop_names = media_type_names[mtype].prop_names;
}
else {
media_type = "unknown";
idx = first = last = -1;
prop_names = NULL;
}
media_type = spa_id_map_get_uri (spa_id_map_get_default (), mtype);
media_subtype = spa_id_map_get_uri (spa_id_map_get_default (), mstype);
if (mstype >= SPA_MEDIA_SUBTYPE_ANY_FIRST &&
mstype <= SPA_MEDIA_SUBTYPE_ANY_LAST) {
media_subtype = media_subtype_names[mstype].name;
} else if (mstype >= first && mstype <= last)
media_subtype = media_subtype_names[mstype - first + idx].name;
else
media_subtype = "unknown";
fprintf (stderr, "%-6s %s/%s\n", "", media_type, media_subtype);
fprintf (stderr, "%-6s %s/%s\n", "", strstr (media_type, "#")+1, strstr (media_subtype, "#")+1);
SPA_FORMAT_FOREACH (format, prop) {
const char *key;
if ((prop->body.flags & SPA_POD_PROP_FLAG_UNSET) &&
(prop->body.flags & SPA_POD_PROP_FLAG_OPTIONAL))
continue;
fprintf (stderr, " %20s : (%s) ", prop_names[prop->body.key - SPA_PROP_ID_MEDIA_CUSTOM_START], pod_type_names[prop->body.value.type].name);
key = spa_id_map_get_uri (spa_id_map_get_default (), prop->body.key);
fprintf (stderr, " %20s : (%s) ", strstr (key, "#")+1, pod_type_names[prop->body.value.type].name);
if (!(prop->body.flags & SPA_POD_PROP_FLAG_UNSET)) {
print_format_value (prop->body.value.size, prop->body.value.type, SPA_POD_BODY (&prop->body.value));
} else {

View file

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

View file

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

View file

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

View file

@ -325,17 +325,17 @@ next:
switch (index++) {
case 0:
spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW,
PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16,
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S32),
PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
break;
case 1:
spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_AAC,
0);
this->uri.media_types.audio, this->uri.media_subtypes_audio.aac,
SPA_POD_TYPE_NONE);
break;
default:
return SPA_RESULT_ENUM_END;
@ -795,6 +795,10 @@ alsa_sink_init (const SpaHandleFactory *factory,
return SPA_RESULT_ERROR;
}
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_media_subtypes_audio_map (this->map, &this->uri.media_subtypes_audio);
spa_prop_audio_map (this->map, &this->uri.prop_audio);
this->node = alsasink_node;
this->stream = SND_PCM_STREAM_PLAYBACK;

View file

@ -109,7 +109,7 @@ spa_alsa_source_node_get_props (SpaNode *node,
static SpaResult
spa_alsa_source_node_set_props (SpaNode *node,
const SpaProps *props)
const SpaProps *props)
{
SpaALSASource *this;
@ -359,17 +359,17 @@ next:
switch (index++) {
case 0:
spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW,
PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S32),
PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S32),
PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
break;
case 1:
spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_AAC,
0);
this->uri.media_types.audio, this->uri.media_subtypes_audio.aac,
SPA_POD_TYPE_NONE);
default:
return SPA_RESULT_ENUM_END;
}
@ -861,6 +861,11 @@ alsa_source_init (const SpaHandleFactory *factory,
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_media_subtypes_audio_map (this->map, &this->uri.media_subtypes_audio);
spa_prop_audio_map (this->map, &this->uri.prop_audio);
this->node = alsasource_node;
this->clock = alsasource_clock;
this->stream = SND_PCM_STREAM_CAPTURE;

View file

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

View file

@ -39,6 +39,9 @@
typedef struct {
uint32_t node;
uint32_t clock;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaPropAudio prop_audio;
} URI;
typedef struct _SpaAudioTestSrc SpaAudioTestSrc;
@ -467,12 +470,12 @@ next:
switch (index++) {
case 0:
spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW,
PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16,
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S32),
PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
break;
default:
return SPA_RESULT_ENUM_END;
@ -585,10 +588,10 @@ spa_audiotestsrc_node_port_get_format (SpaNode *node,
spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer));
spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW,
PROP (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, this->current_format.info.raw.format),
PROP (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, this->current_format.info.raw.rate),
PROP (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, this->current_format.info.raw.channels));
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_INT, this->current_format.info.raw.format),
PROP (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, this->current_format.info.raw.rate),
PROP (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, this->current_format.info.raw.channels));
*format = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat);
@ -952,6 +955,9 @@ audiotestsrc_init (const SpaHandleFactory *factory,
}
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_prop_audio_map (this->map, &this->uri.prop_audio);
this->node = audiotestsrc_node;
this->clock = audiotestsrc_clock;

View file

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

View file

@ -65,6 +65,10 @@ struct _V4l2Buffer {
typedef struct {
uint32_t node;
uint32_t clock;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaMediaSubtypesVideo media_subtypes_video;
SpaPropVideo prop_video;
} URI;
typedef struct {
@ -112,9 +116,9 @@ struct _SpaV4l2Source {
SpaNode node;
SpaClock clock;
URI uri;
SpaIDMap *map;
SpaLog *log;
URI uri;
uint32_t seq;
@ -573,38 +577,28 @@ spa_v4l2_source_node_port_get_format (SpaNode *node,
state->current_format.media_type,
state->current_format.media_subtype);
switch (state->current_format.media_subtype) {
case SPA_MEDIA_SUBTYPE_RAW:
spa_pod_builder_add (&b,
PROP (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, state->current_format.info.raw.format),
PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.raw.size),
PROP (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, -SPA_POD_TYPE_FRACTION, &state->current_format.info.raw.framerate),
0);
break;
case SPA_MEDIA_SUBTYPE_MJPG:
case SPA_MEDIA_SUBTYPE_JPEG:
spa_pod_builder_add (&b,
PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.mjpg.size),
PROP (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, -SPA_POD_TYPE_FRACTION, &state->current_format.info.mjpg.framerate),
0);
break;
case SPA_MEDIA_SUBTYPE_H264:
spa_pod_builder_add (&b,
PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.h264.size),
PROP (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, -SPA_POD_TYPE_FRACTION, &state->current_format.info.h264.framerate),
0);
break;
case SPA_MEDIA_SUBTYPE_DV:
case SPA_MEDIA_SUBTYPE_MPEGTS:
case SPA_MEDIA_SUBTYPE_MPEG1:
case SPA_MEDIA_SUBTYPE_MPEG2:
case SPA_MEDIA_SUBTYPE_MPEG4:
case SPA_MEDIA_SUBTYPE_XVID:
case SPA_MEDIA_SUBTYPE_VC1:
case SPA_MEDIA_SUBTYPE_VP8:
default:
return SPA_RESULT_NO_FORMAT;
if (state->current_format.media_subtype == this->uri.media_subtypes.raw) {
spa_pod_builder_add (&b,
PROP (&f[1], this->uri.prop_video.format, SPA_POD_TYPE_INT, state->current_format.info.raw.format),
PROP (&f[1], this->uri.prop_video.size, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.raw.size),
PROP (&f[1], this->uri.prop_video.framerate, -SPA_POD_TYPE_FRACTION, &state->current_format.info.raw.framerate),
0);
}
else if (state->current_format.media_subtype == this->uri.media_subtypes_video.mjpg ||
state->current_format.media_subtype == this->uri.media_subtypes_video.jpeg) {
spa_pod_builder_add (&b,
PROP (&f[1], this->uri.prop_video.size, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.mjpg.size),
PROP (&f[1], this->uri.prop_video.framerate, -SPA_POD_TYPE_FRACTION, &state->current_format.info.mjpg.framerate),
0);
}
else if (state->current_format.media_subtype == this->uri.media_subtypes_video.h264) {
spa_pod_builder_add (&b,
PROP (&f[1], this->uri.prop_video.size, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.h264.size),
PROP (&f[1], this->uri.prop_video.framerate, -SPA_POD_TYPE_FRACTION, &state->current_format.info.h264.framerate),
0);
} else
return SPA_RESULT_NO_FORMAT;
spa_pod_builder_pop (&b, &f[0]);
*format = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat);
@ -974,6 +968,10 @@ v4l2_source_init (const SpaHandleFactory *factory,
}
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_media_subtypes_video_map (this->map, &this->uri.media_subtypes_video);
spa_prop_video_map (this->map, &this->uri.prop_video);
this->node = v4l2source_node;
this->clock = v4l2source_clock;

View file

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

View file

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

View file

@ -39,6 +39,9 @@
typedef struct {
uint32_t node;
uint32_t clock;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaPropVideo prop_video;
} URI;
typedef struct _SpaVideoTestSrc SpaVideoTestSrc;
@ -450,16 +453,16 @@ next:
switch (index++) {
case 0:
spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW,
PROP_U_EN (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, 3,
this->uri.media_types.video, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_video.format, SPA_POD_TYPE_INT, 3,
SPA_VIDEO_FORMAT_RGB,
SPA_VIDEO_FORMAT_RGB,
SPA_VIDEO_FORMAT_UYVY),
PROP_U_MM (&f[1], SPA_PROP_ID_VIDEO_SIZE, SPA_POD_TYPE_RECTANGLE,
PROP_U_MM (&f[1], this->uri.prop_video.size, SPA_POD_TYPE_RECTANGLE,
320, 240,
1, 1,
INT32_MAX, INT32_MAX),
PROP_U_MM (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_TYPE_FRACTION,
PROP_U_MM (&f[1], this->uri.prop_video.framerate, SPA_POD_TYPE_FRACTION,
25, 1,
0, 1,
INT32_MAX, 1));
@ -590,10 +593,10 @@ spa_videotestsrc_node_port_get_format (SpaNode *node,
spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer));
spa_pod_builder_format (&b, &f[0],
SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW,
PROP (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, this->current_format.info.raw.format),
PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, -SPA_POD_TYPE_RECTANGLE, &this->current_format.info.raw.size),
PROP (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, -SPA_POD_TYPE_FRACTION, &this->current_format.info.raw.framerate));
this->uri.media_types.video, this->uri.media_subtypes.raw,
PROP (&f[1], this->uri.prop_video.format, SPA_POD_TYPE_INT, this->current_format.info.raw.format),
PROP (&f[1], this->uri.prop_video.size, -SPA_POD_TYPE_RECTANGLE, &this->current_format.info.raw.size),
PROP (&f[1], this->uri.prop_video.framerate, -SPA_POD_TYPE_FRACTION, &this->current_format.info.raw.framerate));
*format = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat);
return SPA_RESULT_OK;
@ -956,6 +959,9 @@ videotestsrc_init (const SpaHandleFactory *factory,
}
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_prop_video_map (this->map, &this->uri.prop_video);
this->node = videotestsrc_node;
this->clock = videotestsrc_clock;

View file

@ -63,6 +63,9 @@ typedef struct {
typedef struct {
uint32_t node;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaPropAudio prop_audio;
} URI;
struct _SpaVolume {
@ -307,13 +310,14 @@ next:
switch (index++) {
case 0:
spa_pod_builder_format (&b, &f[0], SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW,
PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3,
SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S32),
PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
spa_pod_builder_format (&b, &f[0],
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_INT, 3,
SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S32),
PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
break;
default:
@ -837,6 +841,9 @@ volume_init (const SpaHandleFactory *factory,
return SPA_RESULT_ERROR;
}
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_prop_audio_map (this->map, &this->uri.prop_audio);
this->node = volume_node;
reset_volume_props (&this->props);

View file

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

View file

@ -40,19 +40,19 @@
*/
spa_build (SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW,
SPA_PROP_ID_VIDEO_FORMAT, SPA_PROP_TYPE_INT,
prop_video.format, SPA_PROP_TYPE_INT,
SPA_VIDEO_FORMAT_I420
SPA_POD_PROP_FLAG_UNSET |
SPA_PROP_RANGE_ENUM, 2,
SPA_VIDEO_FORMAT_I420,
SPA_VIDEO_FORMAT_YUY2,
SPA_PROP_ID_VIDEO_SIZE , SPA_PROP_TYPE_RECTANGLE,
prop_video.size , SPA_PROP_TYPE_RECTANGLE,
320, 240,
SPA_POD_PROP_FLAG_UNSET |
SPA_PROP_RANGE_MIN_MAX,
1, 1,
INT32_MAX, INT32_MAX,
SPA_PROP_ID_VIDEO_FRAMERATE, SPA_PROP_TYPE_FRACTION, 25, 1,
prop_video.framerate, SPA_PROP_TYPE_FRACTION, 25, 1,
SPA_POD_PROP_FLAG_UNSET |
SPA_PROP_RANGE_MIN_MAX,
0, 1,
@ -60,61 +60,85 @@ spa_build (SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW,
0);
#endif
static const struct _test_format {
SpaFormat fmt;
static SpaMediaTypes media_types;
static SpaMediaSubtypes media_subtypes;
static SpaPropVideo prop_video;
static void
do_static_struct (void)
{
struct _test_format {
SpaFormat fmt;
struct {
SpaPODProp prop_format;
struct {
uint32_t def_format;
uint32_t enum_format[2];
} format_vals;
uint32_t pad;
SpaPODProp prop_format;
struct {
uint32_t def_format;
uint32_t enum_format[2];
} format_vals;
uint32_t pad;
SpaPODProp prop_size;
struct {
SpaRectangle def_size;
SpaRectangle min_size;
SpaRectangle max_size;
} size_vals;
SpaPODProp prop_size;
struct {
SpaRectangle def_size;
SpaRectangle min_size;
SpaRectangle max_size;
} size_vals;
SpaPODProp prop_framerate;
struct {
SpaFraction def_framerate;
SpaFraction min_framerate;
SpaFraction max_framerate;
} framerate_vals;
} props;
} test_format = {
{ { sizeof (test_format.props) + sizeof (SpaFormatBody), SPA_POD_TYPE_OBJECT },
{ { 0, 0 },
{ { sizeof (uint32_t), SPA_POD_TYPE_INT }, SPA_MEDIA_TYPE_VIDEO },
{ { sizeof (uint32_t), SPA_POD_TYPE_INT }, SPA_MEDIA_SUBTYPE_RAW } },
}, {
{ { sizeof (test_format.props.format_vals) + sizeof (SpaPODPropBody),
SPA_POD_TYPE_PROP } ,
{ SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET,
{ sizeof (uint32_t), SPA_POD_TYPE_INT } }, },
{ SPA_VIDEO_FORMAT_I420,
{ SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_YUY2 } }, 0,
SpaPODProp prop_framerate;
struct {
SpaFraction def_framerate;
SpaFraction min_framerate;
SpaFraction max_framerate;
} framerate_vals;
} props;
} test_format = {
{ { sizeof (test_format.props) + sizeof (SpaFormatBody), SPA_POD_TYPE_OBJECT },
{ { 0, 0 },
{ { sizeof (uint32_t), SPA_POD_TYPE_URI }, media_types.video },
{ { sizeof (uint32_t), SPA_POD_TYPE_URI }, media_subtypes.raw } },
}, {
{ { sizeof (test_format.props.format_vals) + sizeof (SpaPODPropBody),
SPA_POD_TYPE_PROP } ,
{ prop_video.format, SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET,
{ sizeof (uint32_t), SPA_POD_TYPE_INT } }, },
{ SPA_VIDEO_FORMAT_I420,
{ SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_YUY2 } }, 0,
{ { sizeof (test_format.props.size_vals) + sizeof (SpaPODPropBody),
SPA_POD_TYPE_PROP } ,
{ SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET,
{ sizeof (SpaRectangle), SPA_POD_TYPE_RECTANGLE } }, },
{ { 320, 243 },
{ 1, 1 },
{ INT32_MAX, INT32_MAX } },
{ { sizeof (test_format.props.size_vals) + sizeof (SpaPODPropBody),
SPA_POD_TYPE_PROP } ,
{ prop_video.size, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET,
{ sizeof (SpaRectangle), SPA_POD_TYPE_RECTANGLE } }, },
{ { 320, 243 },
{ 1, 1 },
{ INT32_MAX, INT32_MAX } },
{ { sizeof (test_format.props.framerate_vals) + sizeof (SpaPODPropBody),
SPA_POD_TYPE_PROP } ,
{ SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET,
{ sizeof (SpaFraction), SPA_POD_TYPE_FRACTION } }, },
{ { 25, 1 },
{ 0, 1 },
{ INT32_MAX, 1 } },
{ { sizeof (test_format.props.framerate_vals) + sizeof (SpaPODPropBody),
SPA_POD_TYPE_PROP } ,
{ prop_video.framerate, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET,
{ sizeof (SpaFraction), SPA_POD_TYPE_FRACTION } }, },
{ { 25, 1 },
{ 0, 1 },
{ INT32_MAX, 1 } },
}
};
spa_debug_pod (&test_format.fmt.pod);
spa_debug_format (&test_format.fmt);
{
uint32_t format = 0, match;
SpaFraction frac = { 0, 0 };
match = spa_pod_contents_query (&test_format.fmt.pod, sizeof (SpaFormat),
prop_video.format, SPA_POD_TYPE_INT, &format,
prop_video.framerate, SPA_POD_TYPE_FRACTION, &frac,
0);
printf ("%d %d %d %d\n", match, format, frac.num, frac.denom);
}
};
}
int
main (int argc, char *argv[])
@ -124,13 +148,17 @@ main (int argc, char *argv[])
uint8_t buffer[1024];
SpaFormat *fmt;
spa_media_types_fill (&media_types, spa_id_map_get_default());
spa_media_subtypes_map (spa_id_map_get_default(), &media_subtypes);
spa_prop_video_map (spa_id_map_get_default(), &prop_video);
spa_pod_builder_init (&b, buffer, sizeof (buffer));
fmt = SPA_MEMBER (buffer, spa_pod_builder_push_format (&b, &frame[0],
SPA_MEDIA_TYPE_VIDEO,
SPA_MEDIA_SUBTYPE_RAW), SpaFormat);
media_types.video,
media_subtypes.raw), SpaFormat);
spa_pod_builder_push_prop (&b, &frame[1],
SPA_PROP_ID_VIDEO_FORMAT,
prop_video.format,
SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE);
spa_pod_builder_int (&b, SPA_VIDEO_FORMAT_I420);
spa_pod_builder_int (&b, SPA_VIDEO_FORMAT_I420);
@ -139,7 +167,7 @@ main (int argc, char *argv[])
SpaRectangle size_min_max[] = { { 1, 1 }, { INT32_MAX, INT32_MAX } };
spa_pod_builder_push_prop (&b, &frame[1],
SPA_PROP_ID_VIDEO_SIZE,
prop_video.size,
SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE);
spa_pod_builder_rectangle (&b, 320, 240);
spa_pod_builder_raw (&b, size_min_max, sizeof(size_min_max));
@ -147,7 +175,7 @@ main (int argc, char *argv[])
SpaFraction rate_min_max[] = { { 0, 1 }, { INT32_MAX, 1 } };
spa_pod_builder_push_prop (&b, &frame[1],
SPA_PROP_ID_VIDEO_FRAMERATE,
prop_video.framerate,
SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE);
spa_pod_builder_fraction (&b, 25, 1);
spa_pod_builder_raw (&b, rate_min_max, sizeof(rate_min_max));
@ -160,9 +188,9 @@ main (int argc, char *argv[])
spa_pod_builder_init (&b, buffer, sizeof (buffer));
spa_pod_builder_format (&b, &frame[0],
SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW,
media_types.video, media_subtypes.raw,
SPA_POD_TYPE_PROP, &frame[1],
SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_FLAG_UNSET |
prop_video.format, SPA_POD_PROP_FLAG_UNSET |
SPA_POD_PROP_RANGE_ENUM,
SPA_POD_TYPE_INT, 3,
SPA_VIDEO_FORMAT_I420,
@ -170,7 +198,7 @@ main (int argc, char *argv[])
SPA_VIDEO_FORMAT_YUY2,
-SPA_POD_TYPE_PROP, &frame[1],
SPA_POD_TYPE_PROP, &frame[1],
SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_FLAG_UNSET |
prop_video.size, SPA_POD_PROP_FLAG_UNSET |
SPA_POD_PROP_RANGE_MIN_MAX,
SPA_POD_TYPE_RECTANGLE, 3,
320, 241,
@ -178,7 +206,7 @@ main (int argc, char *argv[])
INT32_MAX, INT32_MAX,
-SPA_POD_TYPE_PROP, &frame[1],
SPA_POD_TYPE_PROP, &frame[1],
SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_FLAG_UNSET |
prop_video.framerate, SPA_POD_PROP_FLAG_UNSET |
SPA_POD_PROP_RANGE_MIN_MAX,
SPA_POD_TYPE_FRACTION, 3,
25, 1,
@ -194,10 +222,10 @@ main (int argc, char *argv[])
spa_pod_builder_add (&b,
SPA_POD_TYPE_OBJECT, &frame[0], 0, 0,
SPA_POD_TYPE_INT, SPA_MEDIA_TYPE_VIDEO,
SPA_POD_TYPE_INT, SPA_MEDIA_SUBTYPE_RAW,
SPA_POD_TYPE_URI, media_types.video,
SPA_POD_TYPE_URI, media_subtypes.raw,
SPA_POD_TYPE_PROP, &frame[1],
SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_FLAG_UNSET |
prop_video.format, SPA_POD_PROP_FLAG_UNSET |
SPA_POD_PROP_RANGE_ENUM,
SPA_POD_TYPE_INT, 3,
SPA_VIDEO_FORMAT_I420,
@ -205,7 +233,7 @@ main (int argc, char *argv[])
SPA_VIDEO_FORMAT_YUY2,
-SPA_POD_TYPE_PROP, &frame[1],
SPA_POD_TYPE_PROP, &frame[1],
SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_FLAG_UNSET |
prop_video.size, SPA_POD_PROP_FLAG_UNSET |
SPA_POD_PROP_RANGE_MIN_MAX,
SPA_POD_TYPE_RECTANGLE, 3,
320, 242,
@ -213,7 +241,7 @@ main (int argc, char *argv[])
INT32_MAX, INT32_MAX,
-SPA_POD_TYPE_PROP, &frame[1],
SPA_POD_TYPE_PROP, &frame[1],
SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_FLAG_UNSET |
prop_video.framerate, SPA_POD_PROP_FLAG_UNSET |
SPA_POD_PROP_RANGE_MIN_MAX,
SPA_POD_TYPE_FRACTION, 3,
25, 1,
@ -227,20 +255,7 @@ main (int argc, char *argv[])
spa_debug_pod (&fmt->pod);
spa_debug_format (fmt);
spa_debug_pod (&test_format.fmt.pod);
spa_debug_format (&test_format.fmt);
{
uint32_t format = 0, match;
SpaFraction frac = { 0, 0 };
match = spa_pod_contents_query (&test_format.fmt.pod, sizeof (SpaFormat),
SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, &format,
SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_TYPE_FRACTION, &frac,
0);
printf ("%d %d %d %d\n", match, format, frac.num, frac.denom);
}
do_static_struct ();
return 0;
}