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

@ -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);