mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
Make new USE_BUFFERS command
Make a new USE_BUFFERS command to atomically send a buffer array to the remote client. We can use this to then clean up an old array and go to the PAUSED state if possible. Work on formats. Make one structure that can hold all video formats. Work on pipeline suspend and resume. Add jpeg support to v4l2. Work on enum_formats with a filter in v4l2.
This commit is contained in:
parent
7e858ff694
commit
b67c216a04
24 changed files with 688 additions and 514 deletions
|
|
@ -135,55 +135,95 @@ static const SpaPropRangeInfo uint32_range[] = {
|
|||
{ "max", "Maximum value", 4, &max_uint32 },
|
||||
};
|
||||
|
||||
static const SpaPropInfo raw_format_prop_info[] =
|
||||
static const SpaPropInfo format_prop_info[] =
|
||||
{
|
||||
{ SPA_PROP_ID_AUDIO_FORMAT, "format", "The media format",
|
||||
{ SPA_PROP_ID_AUDIO_FORMAT, 0,
|
||||
"format", "The media format",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (format_format_range), format_format_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info.format) },
|
||||
{ SPA_PROP_ID_AUDIO_FLAGS, "flags", "Sample Flags",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_AUDIO_FLAGS, 0,
|
||||
"flags", "Sample Flags",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (flags_range), flags_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info.flags) },
|
||||
{ SPA_PROP_ID_AUDIO_LAYOUT, "layout", "Sample Layout",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_AUDIO_LAYOUT, 0,
|
||||
"layout", "Sample Layout",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (layouts_range), layouts_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info.layout) },
|
||||
{ SPA_PROP_ID_AUDIO_RATE, "rate", "Audio sample rate",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_AUDIO_RATE, 0,
|
||||
"rate", "Audio sample rate",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info.rate) },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNELS, "channels", "Audio channels",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNELS, 0,
|
||||
"channels", "Audio channels",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info.channels) },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNEL_MASK, "channel-mask", "Audio channel mask",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNEL_MASK, 0,
|
||||
"channel-mask", "Audio channel mask",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_BITMASK, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info.channel_mask) },
|
||||
{ SPA_PROP_ID_AUDIO_RAW_INFO, "info", "the SpaAudioRawInfo structure",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_AUDIO_RAW_INFO, 0,
|
||||
"info", "the SpaAudioRawInfo structure",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_POINTER, sizeof (SpaAudioRawInfo),
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info) },
|
||||
NULL },
|
||||
};
|
||||
|
||||
SpaResult
|
||||
spa_prop_info_fill_audio (SpaPropInfo *info,
|
||||
SpaPropIdAudio id,
|
||||
size_t offset)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (info == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
for (i = 0; i < SPA_N_ELEMENTS (format_prop_info); i++) {
|
||||
if (format_prop_info[i].id == id) {
|
||||
memcpy (info, &format_prop_info[i], sizeof (SpaPropInfo));
|
||||
info->offset = offset;
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
}
|
||||
return SPA_RESULT_INVALID_PROPERTY_INDEX;
|
||||
}
|
||||
|
||||
SpaResult
|
||||
spa_audio_raw_format_init (SpaAudioRawFormat *format)
|
||||
{
|
||||
static SpaPropInfo raw_format_prop_info[] =
|
||||
{
|
||||
{ SPA_PROP_ID_AUDIO_FORMAT, offsetof (SpaAudioRawFormat, info.format), },
|
||||
{ SPA_PROP_ID_AUDIO_FLAGS, offsetof (SpaAudioRawFormat, info.flags), },
|
||||
{ SPA_PROP_ID_AUDIO_LAYOUT, offsetof (SpaAudioRawFormat, info.layout), },
|
||||
{ SPA_PROP_ID_AUDIO_RATE, offsetof (SpaAudioRawFormat, info.rate), },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNELS, offsetof (SpaAudioRawFormat, info.channels), },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNEL_MASK, offsetof (SpaAudioRawFormat, info.channel_mask), },
|
||||
{ SPA_PROP_ID_AUDIO_RAW_INFO, offsetof (SpaAudioRawFormat, info), },
|
||||
};
|
||||
|
||||
if (raw_format_prop_info[0].name == NULL) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SPA_N_ELEMENTS (raw_format_prop_info); i++)
|
||||
spa_prop_info_fill_audio (&raw_format_prop_info[i],
|
||||
raw_format_prop_info[i].id,
|
||||
raw_format_prop_info[i].offset);
|
||||
}
|
||||
|
||||
format->format.media_type = SPA_MEDIA_TYPE_AUDIO;
|
||||
format->format.media_subtype = SPA_MEDIA_SUBTYPE_RAW;
|
||||
format->format.props.n_prop_info = SPA_N_ELEMENTS (raw_format_prop_info);
|
||||
|
|
@ -227,23 +267,3 @@ fallback:
|
|||
|
||||
return res;
|
||||
}
|
||||
|
||||
SpaResult
|
||||
spa_audio_raw_fill_prop_info (SpaPropInfo *info,
|
||||
SpaPropIdAudio id,
|
||||
size_t offset)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (info == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
for (i = 0; i < SPA_N_ELEMENTS (raw_format_prop_info); i++) {
|
||||
if (raw_format_prop_info[i].id == id) {
|
||||
memcpy (info, &raw_format_prop_info[i], sizeof (SpaPropInfo));
|
||||
info->offset = offset;
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
}
|
||||
return SPA_RESULT_INVALID_PROPERTY_INDEX;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -456,6 +456,27 @@ iter_parse_set_format (struct stack_iter *si, SpaControlCmdSetFormat *cmd)
|
|||
cmd->format = parse_format (mem, p, SPA_PTR_TO_INT (cmd->format));
|
||||
}
|
||||
|
||||
static void
|
||||
iter_parse_use_buffers (struct stack_iter *si, SpaControlCmdUseBuffers *cmd)
|
||||
{
|
||||
void *p;
|
||||
int i;
|
||||
|
||||
p = si->data;
|
||||
memcpy (cmd, p, sizeof (SpaControlCmdUseBuffers));
|
||||
if (cmd->buffers)
|
||||
cmd->buffers = SPA_MEMBER (p, SPA_PTR_TO_INT (cmd->buffers), SpaBuffer *);
|
||||
for (i = 0; i < cmd->n_buffers; i++) {
|
||||
SpaMemoryChunk *mc;
|
||||
SpaMemory *mem;
|
||||
|
||||
mc = SPA_MEMBER (p, SPA_PTR_TO_INT (cmd->buffers[i]), SpaMemoryChunk);
|
||||
mem = spa_memory_find (&mc->mem);
|
||||
|
||||
cmd->buffers[i] = SPA_MEMBER (spa_memory_ensure_ptr (mem), mc->offset, SpaBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
SpaResult
|
||||
spa_control_iter_parse_cmd (SpaControlIter *iter,
|
||||
void *command)
|
||||
|
|
@ -542,16 +563,8 @@ spa_control_iter_parse_cmd (SpaControlIter *iter,
|
|||
memcpy (command, si->data, sizeof (SpaControlCmdRemoveMem));
|
||||
break;
|
||||
|
||||
case SPA_CONTROL_CMD_ADD_BUFFER:
|
||||
if (si->size < sizeof (SpaControlCmdAddBuffer))
|
||||
return SPA_RESULT_ERROR;
|
||||
memcpy (command, si->data, sizeof (SpaControlCmdAddBuffer));
|
||||
break;
|
||||
|
||||
case SPA_CONTROL_CMD_REMOVE_BUFFER:
|
||||
if (si->size < sizeof (SpaControlCmdRemoveBuffer))
|
||||
return SPA_RESULT_ERROR;
|
||||
memcpy (command, si->data, sizeof (SpaControlCmdRemoveBuffer));
|
||||
case SPA_CONTROL_CMD_USE_BUFFERS:
|
||||
iter_parse_use_buffers (si, command);
|
||||
break;
|
||||
|
||||
case SPA_CONTROL_CMD_PROCESS_BUFFER:
|
||||
|
|
@ -1077,6 +1090,41 @@ builder_add_set_format (struct stack_builder *sb, SpaControlCmdSetFormat *sf)
|
|||
sf->format = SPA_INT_TO_PTR (SPA_PTRDIFF (p, sf));
|
||||
}
|
||||
|
||||
static void
|
||||
builder_add_use_buffers (struct stack_builder *sb, SpaControlCmdUseBuffers *ub)
|
||||
{
|
||||
size_t len;
|
||||
void *p;
|
||||
int i;
|
||||
SpaMemoryChunk **bmc;
|
||||
SpaControlCmdUseBuffers *d;
|
||||
|
||||
/* calculate length */
|
||||
/* port_id + format + mask */
|
||||
len = sizeof (SpaControlCmdUseBuffers);
|
||||
len += ub->n_buffers * sizeof (SpaBuffer *);
|
||||
len += ub->n_buffers * sizeof (SpaMemoryChunk);
|
||||
|
||||
p = builder_add_cmd (sb, SPA_CONTROL_CMD_USE_BUFFERS, len);
|
||||
memcpy (p, ub, sizeof (SpaControlCmdUseBuffers));
|
||||
d = p;
|
||||
|
||||
p = SPA_MEMBER (d, sizeof (SpaControlCmdUseBuffers), void);
|
||||
bmc = p;
|
||||
|
||||
if (d->n_buffers)
|
||||
d->buffers = SPA_INT_TO_PTR (SPA_PTRDIFF (bmc, d));
|
||||
else
|
||||
d->buffers = 0;
|
||||
|
||||
p = SPA_MEMBER (p, sizeof (SpaMemoryChunk*) * ub->n_buffers, void);
|
||||
for (i = 0; i < ub->n_buffers; i++) {
|
||||
memcpy (p, &ub->buffers[i]->mem, sizeof (SpaMemoryChunk));
|
||||
bmc[i] = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
|
||||
p = SPA_MEMBER (p, sizeof (SpaMemoryChunk), void);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* spa_control_builder_add_cmd:
|
||||
* @builder: a #SpaControlBuilder
|
||||
|
|
@ -1168,14 +1216,8 @@ spa_control_builder_add_cmd (SpaControlBuilder *builder,
|
|||
memcpy (p, command, sizeof (SpaControlCmdRemoveMem));
|
||||
break;
|
||||
|
||||
case SPA_CONTROL_CMD_ADD_BUFFER:
|
||||
p = builder_add_cmd (sb, cmd, sizeof (SpaControlCmdAddBuffer));
|
||||
memcpy (p, command, sizeof (SpaControlCmdAddBuffer));
|
||||
break;
|
||||
|
||||
case SPA_CONTROL_CMD_REMOVE_BUFFER:
|
||||
p = builder_add_cmd (sb, cmd, sizeof (SpaControlCmdRemoveBuffer));
|
||||
memcpy (p, command, sizeof (SpaControlCmdRemoveBuffer));
|
||||
case SPA_CONTROL_CMD_USE_BUFFERS:
|
||||
builder_add_use_buffers (sb, command);
|
||||
break;
|
||||
|
||||
case SPA_CONTROL_CMD_PROCESS_BUFFER:
|
||||
|
|
|
|||
|
|
@ -169,18 +169,31 @@ spa_debug_dump_mem (const void *mem, size_t size)
|
|||
struct media_type_name {
|
||||
const char *name;
|
||||
} media_type_names[] = {
|
||||
{ "unknown" },
|
||||
{ "invalid" },
|
||||
{ "audio" },
|
||||
{ "video" },
|
||||
{ "image" },
|
||||
};
|
||||
|
||||
struct media_subtype_name {
|
||||
const char *name;
|
||||
} media_subtype_names[] = {
|
||||
{ "unknown" },
|
||||
{ "invalid" },
|
||||
{ "raw" },
|
||||
{ "h264" },
|
||||
{ "mjpg" },
|
||||
{ "dv" },
|
||||
{ "mpegts" },
|
||||
{ "h263" },
|
||||
{ "mpeg1" },
|
||||
{ "mpeg2" },
|
||||
{ "mpeg4" },
|
||||
{ "xvid" },
|
||||
{ "vc1" },
|
||||
{ "vp8" },
|
||||
{ "vp9" },
|
||||
{ "jpeg" },
|
||||
{ "bayer" },
|
||||
};
|
||||
|
||||
struct prop_type_name {
|
||||
|
|
@ -330,7 +343,7 @@ spa_debug_props (const SpaProps *props, bool print_ranges)
|
|||
|
||||
res = spa_props_get_prop (props, i, &value);
|
||||
|
||||
fprintf (stderr, ". Current: ");
|
||||
fprintf (stderr, "Current: ");
|
||||
if (res == SPA_RESULT_OK)
|
||||
print_value (info, value.size, value.value);
|
||||
else if (res == SPA_RESULT_PROPERTY_UNSET)
|
||||
|
|
@ -386,14 +399,25 @@ spa_debug_format (const SpaFormat *format)
|
|||
{
|
||||
const SpaProps *props;
|
||||
int i;
|
||||
const char *media_type;
|
||||
const char *media_subtype;
|
||||
|
||||
if (format == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
props = &format->props;
|
||||
|
||||
fprintf (stderr, "%-6s %s/%s\n", "", media_type_names[format->media_type].name,
|
||||
media_subtype_names[format->media_subtype].name);
|
||||
if (format->media_type > 0 && format->media_type < SPA_N_ELEMENTS (media_type_names))
|
||||
media_type = media_type_names[format->media_type].name;
|
||||
else
|
||||
media_type = "unknown";
|
||||
|
||||
if (format->media_subtype > 0 && format->media_subtype < SPA_N_ELEMENTS (media_subtype_names))
|
||||
media_subtype = media_subtype_names[format->media_subtype].name;
|
||||
else
|
||||
media_subtype = "unknown";
|
||||
|
||||
fprintf (stderr, "%-6s %s/%s\n", "", media_type, media_subtype);
|
||||
|
||||
for (i = 0; i < props->n_prop_info; i++) {
|
||||
const SpaPropInfo *info = &props->prop_info[i];
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include <spa/video/raw.h>
|
||||
#include <spa/video/format.h>
|
||||
|
||||
static const SpaVideoRawInfo default_info = {
|
||||
static const SpaVideoInfoRaw default_raw_info = {
|
||||
SPA_VIDEO_FORMAT_UNKNOWN,
|
||||
{ 320, 240 },
|
||||
{ 0, 1 },
|
||||
|
|
@ -371,175 +371,193 @@ static const SpaPropRangeInfo framerate_range[] = {
|
|||
{ "max", "Maximum value", sizeof (SpaFraction), &max_framerate },
|
||||
};
|
||||
|
||||
static const SpaPropInfo raw_format_prop_info[] =
|
||||
static const SpaPropInfo format_prop_info[] =
|
||||
{
|
||||
{ SPA_PROP_ID_VIDEO_FORMAT, "format", "The media format",
|
||||
{ SPA_PROP_ID_VIDEO_FORMAT, 0,
|
||||
"format", "The media format",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (format_range), format_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.format) },
|
||||
{ SPA_PROP_ID_VIDEO_SIZE, "size", "Video size",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_SIZE, 0,
|
||||
"size", "Video size",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_RECTANGLE, sizeof (SpaRectangle),
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, size_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.size) },
|
||||
{ SPA_PROP_ID_VIDEO_FRAMERATE, "framerate", "Video framerate",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_FRAMERATE, 0,
|
||||
"framerate", "Video framerate",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.framerate) },
|
||||
{ SPA_PROP_ID_VIDEO_MAX_FRAMERATE, "max-framerate", "Video max framerate",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_MAX_FRAMERATE, 0,
|
||||
"max-framerate", "Video max framerate",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.max_framerate) },
|
||||
{ SPA_PROP_ID_VIDEO_VIEWS, "views", "Video number of views",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_VIEWS, 0,
|
||||
"views", "Video number of views",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.views) },
|
||||
{ SPA_PROP_ID_VIDEO_INTERLACE_MODE, "interlace-mode", "Interlace mode",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_INTERLACE_MODE, 0,
|
||||
"interlace-mode", "Interlace mode",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (interlace_mode_range), interlace_mode_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.interlace_mode) },
|
||||
{ SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO, "pixel-aspect-ratio", "Video pixel aspect ratio",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO, 0,
|
||||
"pixel-aspect-ratio", "Video pixel aspect ratio",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.pixel_aspect_ratio) },
|
||||
{ SPA_PROP_ID_VIDEO_MULTIVIEW_MODE, "multiview-mode", "Multiview mode",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_MULTIVIEW_MODE, 0,
|
||||
"multiview-mode", "Multiview mode",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (multiview_mode_range), multiview_mode_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.multiview_mode) },
|
||||
{ SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS, "multiview-flags", "Multiview flags",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS, 0,
|
||||
"multiview-flags", "Multiview flags",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (multiview_flags_range), multiview_flags_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.multiview_flags) },
|
||||
{ SPA_PROP_ID_VIDEO_CHROMA_SITE, "chroma-site", "Chroma site",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_CHROMA_SITE, 0,
|
||||
"chroma-site", "Chroma site",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (chroma_site_range), chroma_site_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.chroma_site) },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_RANGE, "color-range", "Color range",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_RANGE, 0,
|
||||
"color-range", "Color range",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_range_range), color_range_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.color_range) },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_MATRIX, "color-matrix", "Color matrix",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_MATRIX, 0,
|
||||
"color-matrix", "Color matrix",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_matrix_range), color_matrix_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.color_matrix) },
|
||||
{ SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION, "transfer-function", "Transfer function",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION, 0,
|
||||
"transfer-function", "Transfer function",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (transfer_function_range), transfer_function_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.transfer_function) },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_PRIMARIES, "color-primaries", "Color primaries",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_PRIMARIES, 0,
|
||||
"color-primaries", "Color primaries",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_primaries_range), color_primaries_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.color_primaries) },
|
||||
{ SPA_PROP_ID_VIDEO_RAW_INFO, "info", "the SpaVideoRawInfo structure",
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_RAW_INFO, 0,
|
||||
"info", "the SpaVideoRawInfo structure",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_POINTER, sizeof (SpaVideoRawInfo),
|
||||
SPA_PROP_TYPE_POINTER, sizeof (SpaVideoInfoRaw),
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info) },
|
||||
NULL },
|
||||
};
|
||||
|
||||
SpaResult
|
||||
spa_video_raw_format_init (SpaVideoRawFormat *format)
|
||||
spa_prop_info_fill_video (SpaPropInfo *info,
|
||||
SpaPropIdVideo id,
|
||||
size_t offset)
|
||||
{
|
||||
format->format.media_type = SPA_MEDIA_TYPE_VIDEO;
|
||||
format->format.media_subtype = SPA_MEDIA_SUBTYPE_RAW;
|
||||
format->format.props.n_prop_info = SPA_N_ELEMENTS (raw_format_prop_info);
|
||||
format->format.props.prop_info = raw_format_prop_info;
|
||||
format->format.props.unset_mask = (1 << 14)-1;
|
||||
format->info = default_info;
|
||||
int i;
|
||||
|
||||
if (info == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
i = id - SPA_PROP_ID_MEDIA_CUSTOM_START;
|
||||
|
||||
if (i < 0 || i >= SPA_N_ELEMENTS (format_prop_info))
|
||||
return SPA_RESULT_INVALID_PROPERTY_INDEX;
|
||||
|
||||
memcpy (info, &format_prop_info[i], sizeof (SpaPropInfo));
|
||||
info->offset = offset;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
SpaResult
|
||||
spa_video_raw_format_parse (const SpaFormat *format,
|
||||
SpaVideoRawFormat *rawformat)
|
||||
spa_format_video_init (SpaMediaType type,
|
||||
SpaMediaSubType subtype,
|
||||
SpaFormatVideo *format)
|
||||
{
|
||||
static SpaPropInfo raw_format_prop_info[] = {
|
||||
{ SPA_PROP_ID_VIDEO_FORMAT, offsetof (SpaFormatVideo, info.raw.format) },
|
||||
{ SPA_PROP_ID_VIDEO_SIZE, offsetof (SpaFormatVideo, info.raw.size) },
|
||||
{ SPA_PROP_ID_VIDEO_FRAMERATE, offsetof (SpaFormatVideo, info.raw.framerate) },
|
||||
{ SPA_PROP_ID_VIDEO_MAX_FRAMERATE, offsetof (SpaFormatVideo, info.raw.max_framerate) },
|
||||
{ SPA_PROP_ID_VIDEO_VIEWS, offsetof (SpaFormatVideo, info.raw.views) },
|
||||
{ SPA_PROP_ID_VIDEO_INTERLACE_MODE, offsetof (SpaFormatVideo, info.raw.interlace_mode) },
|
||||
{ SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO, offsetof (SpaFormatVideo, info.raw.pixel_aspect_ratio) },
|
||||
{ SPA_PROP_ID_VIDEO_MULTIVIEW_MODE, offsetof (SpaFormatVideo, info.raw.multiview_mode) },
|
||||
{ SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS, offsetof (SpaFormatVideo, info.raw.multiview_flags) },
|
||||
{ SPA_PROP_ID_VIDEO_CHROMA_SITE, offsetof (SpaFormatVideo, info.raw.chroma_site) },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_RANGE, offsetof (SpaFormatVideo, info.raw.color_range) },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_MATRIX, offsetof (SpaFormatVideo, info.raw.color_matrix) },
|
||||
{ SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION, offsetof (SpaFormatVideo, info.raw.transfer_function) },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_PRIMARIES, offsetof (SpaFormatVideo, info.raw.color_primaries) },
|
||||
{ SPA_PROP_ID_VIDEO_RAW_INFO, offsetof (SpaFormatVideo, info.raw ) },
|
||||
};
|
||||
|
||||
if (raw_format_prop_info[0].name == NULL) {
|
||||
int i;
|
||||
for (i = 0; i < SPA_N_ELEMENTS (raw_format_prop_info); i++)
|
||||
spa_prop_info_fill_video (&raw_format_prop_info[i],
|
||||
raw_format_prop_info[i].id,
|
||||
raw_format_prop_info[i].offset);
|
||||
}
|
||||
|
||||
format->format.media_type = type;
|
||||
format->format.media_subtype = subtype;
|
||||
format->format.props.n_prop_info = SPA_N_ELEMENTS (raw_format_prop_info);
|
||||
format->format.props.prop_info = raw_format_prop_info;
|
||||
format->format.props.unset_mask = (1 << 14)-1;
|
||||
format->info.raw = default_raw_info;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
SpaResult
|
||||
spa_format_video_parse (const SpaFormat *format,
|
||||
SpaFormatVideo *vformat)
|
||||
{
|
||||
SpaPropValue value;
|
||||
const SpaProps *props;
|
||||
SpaResult res;
|
||||
|
||||
if ((void *)format == (void *)rawformat)
|
||||
if ((void *)format == (void *)vformat)
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
if (format->media_type != SPA_MEDIA_TYPE_VIDEO ||
|
||||
format->media_subtype != SPA_MEDIA_SUBTYPE_RAW)
|
||||
if (format->media_type != SPA_MEDIA_TYPE_VIDEO)
|
||||
return SPA_RESULT_INVALID_MEDIA_TYPE;
|
||||
|
||||
spa_video_raw_format_init (rawformat);
|
||||
spa_format_video_init (format->media_type,
|
||||
format->media_subtype,
|
||||
vformat);
|
||||
|
||||
props = &format->props;
|
||||
if ((res = spa_props_get_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_RAW_INFO), &value)) < 0)
|
||||
goto fallback;
|
||||
|
||||
if (value.type != SPA_PROP_TYPE_POINTER || value.size != sizeof (SpaVideoRawInfo))
|
||||
if (value.type != SPA_PROP_TYPE_POINTER)
|
||||
goto fallback;
|
||||
|
||||
memcpy (&rawformat->info, value.value, sizeof (SpaVideoRawInfo));
|
||||
memcpy (&vformat->info, value.value, value.size);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
fallback:
|
||||
res = spa_props_copy (props, &rawformat->format.props);
|
||||
res = spa_props_copy (props, &vformat->format.props);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SpaResult
|
||||
spa_video_raw_fill_default_info (SpaVideoRawInfo *info)
|
||||
{
|
||||
if (info == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
memcpy (info, &default_info, sizeof (SpaVideoRawInfo));
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
SpaResult
|
||||
spa_video_raw_fill_prop_info (SpaPropInfo *info,
|
||||
SpaPropIdVideo id,
|
||||
size_t offset)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (info == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
for (i = 0; i < SPA_N_ELEMENTS (raw_format_prop_info); i++) {
|
||||
if (raw_format_prop_info[i].id == id) {
|
||||
memcpy (info, &raw_format_prop_info[i], sizeof (SpaPropInfo));
|
||||
info->offset = offset;
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
}
|
||||
return SPA_RESULT_INVALID_PROPERTY_INDEX;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue