mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
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:
parent
ee470fc6c6
commit
3f5a3e215b
25 changed files with 769 additions and 685 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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); \
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
123
spa/lib/debug.c
123
spa/lib/debug.c
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue