mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-26 07:00:13 -05:00
gstformat: flesh out caps conversion
This commit is contained in:
parent
e90166678c
commit
37ae4e80c3
1 changed files with 178 additions and 41 deletions
|
|
@ -584,11 +584,167 @@ gst_caps_to_format_all (GstCaps *caps)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_id_prop (SpaPODProp *prop, const char *key, GstCaps *res)
|
||||||
|
{
|
||||||
|
const char * str;
|
||||||
|
uint32_t *id = SPA_POD_CONTENTS (SpaPODProp, prop);
|
||||||
|
uint32_t i, n_items = SPA_POD_PROP_N_VALUES (prop);
|
||||||
|
|
||||||
|
switch (prop->body.flags & SPA_POD_PROP_RANGE_MASK) {
|
||||||
|
case SPA_POD_PROP_RANGE_NONE:
|
||||||
|
if (!(str = spa_type_map_get_type (type.map, id[0])))
|
||||||
|
return;
|
||||||
|
gst_caps_set_simple (res, key, G_TYPE_STRING, rindex (str, ':') + 1, NULL);
|
||||||
|
break;
|
||||||
|
case SPA_POD_PROP_RANGE_ENUM:
|
||||||
|
{
|
||||||
|
GValue list = { 0 }, v = { 0 };
|
||||||
|
|
||||||
|
g_value_init (&list, GST_TYPE_LIST);
|
||||||
|
for (i = 1; i < n_items; i++) {
|
||||||
|
if (!(str = spa_type_map_get_type (type.map, id[i])))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
g_value_init (&v, G_TYPE_STRING);
|
||||||
|
g_value_set_string (&v, rindex (str, ':') + 1);
|
||||||
|
gst_value_list_append_and_take_value (&list, &v);
|
||||||
|
}
|
||||||
|
gst_caps_set_value (res, key, &list);
|
||||||
|
g_value_unset (&list);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_int_prop (SpaPODProp *prop, const char *key, GstCaps *res)
|
||||||
|
{
|
||||||
|
uint32_t *val = SPA_POD_CONTENTS (SpaPODProp, prop);
|
||||||
|
uint32_t i, n_items = SPA_POD_PROP_N_VALUES (prop);
|
||||||
|
|
||||||
|
switch (prop->body.flags & SPA_POD_PROP_RANGE_MASK) {
|
||||||
|
case SPA_POD_PROP_RANGE_NONE:
|
||||||
|
gst_caps_set_simple (res, key, G_TYPE_INT, val[0], NULL);
|
||||||
|
break;
|
||||||
|
case SPA_POD_PROP_RANGE_MIN_MAX:
|
||||||
|
case SPA_POD_PROP_RANGE_STEP:
|
||||||
|
{
|
||||||
|
if (n_items < 3)
|
||||||
|
return;
|
||||||
|
gst_caps_set_simple (res, key, GST_TYPE_INT_RANGE, val[1], val[2], NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPA_POD_PROP_RANGE_ENUM:
|
||||||
|
{
|
||||||
|
GValue list = { 0 }, v = { 0 };
|
||||||
|
|
||||||
|
g_value_init (&list, GST_TYPE_LIST);
|
||||||
|
for (i = 1; i < n_items; i++) {
|
||||||
|
g_value_init (&v, G_TYPE_INT);
|
||||||
|
g_value_set_int (&v, val[i]);
|
||||||
|
gst_value_list_append_and_take_value (&list, &v);
|
||||||
|
}
|
||||||
|
gst_caps_set_value (res, key, &list);
|
||||||
|
g_value_unset (&list);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_rect_prop (SpaPODProp *prop, const char *width, const char *height, GstCaps *res)
|
||||||
|
{
|
||||||
|
SpaRectangle *rect = SPA_POD_CONTENTS (SpaPODProp, prop);
|
||||||
|
uint32_t i, n_items = SPA_POD_PROP_N_VALUES (prop);
|
||||||
|
|
||||||
|
switch (prop->body.flags & SPA_POD_PROP_RANGE_MASK) {
|
||||||
|
case SPA_POD_PROP_RANGE_NONE:
|
||||||
|
gst_caps_set_simple (res, width, G_TYPE_INT, rect[0].width,
|
||||||
|
height, G_TYPE_INT, rect[0].height, NULL);
|
||||||
|
break;
|
||||||
|
case SPA_POD_PROP_RANGE_MIN_MAX:
|
||||||
|
case SPA_POD_PROP_RANGE_STEP:
|
||||||
|
{
|
||||||
|
if (n_items < 3)
|
||||||
|
return;
|
||||||
|
gst_caps_set_simple (res, width, GST_TYPE_INT_RANGE, rect[1].width, rect[2].width,
|
||||||
|
height, GST_TYPE_INT_RANGE, rect[1].height, rect[2].height, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPA_POD_PROP_RANGE_ENUM:
|
||||||
|
{
|
||||||
|
GValue l1 = { 0 }, l2 = { 0 }, v1 = { 0 }, v2 = { 0 };
|
||||||
|
|
||||||
|
g_value_init (&l1, GST_TYPE_LIST);
|
||||||
|
g_value_init (&l2, GST_TYPE_LIST);
|
||||||
|
for (i = 1; i < n_items; i++) {
|
||||||
|
g_value_init (&v1, G_TYPE_INT);
|
||||||
|
g_value_set_int (&v1, rect[i].width);
|
||||||
|
gst_value_list_append_and_take_value (&l1, &v1);
|
||||||
|
|
||||||
|
g_value_init (&v2, G_TYPE_INT);
|
||||||
|
g_value_set_int (&v2, rect[i].height);
|
||||||
|
gst_value_list_append_and_take_value (&l2, &v2);
|
||||||
|
}
|
||||||
|
gst_caps_set_value (res, width, &l1);
|
||||||
|
gst_caps_set_value (res, height, &l2);
|
||||||
|
g_value_unset (&l1);
|
||||||
|
g_value_unset (&l2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_fraction_prop (SpaPODProp *prop, const char *key, GstCaps *res)
|
||||||
|
{
|
||||||
|
SpaFraction *fract = SPA_POD_CONTENTS (SpaPODProp, prop);
|
||||||
|
uint32_t i, n_items = SPA_POD_PROP_N_VALUES (prop);
|
||||||
|
|
||||||
|
switch (prop->body.flags & SPA_POD_PROP_RANGE_MASK) {
|
||||||
|
case SPA_POD_PROP_RANGE_NONE:
|
||||||
|
gst_caps_set_simple (res, key, GST_TYPE_FRACTION, fract[0].num, fract[0].denom, NULL);
|
||||||
|
break;
|
||||||
|
case SPA_POD_PROP_RANGE_MIN_MAX:
|
||||||
|
case SPA_POD_PROP_RANGE_STEP:
|
||||||
|
{
|
||||||
|
if (n_items < 3)
|
||||||
|
return;
|
||||||
|
gst_caps_set_simple (res, key, GST_TYPE_FRACTION_RANGE, fract[1].num, fract[1].denom,
|
||||||
|
fract[2].num, fract[2].denom, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPA_POD_PROP_RANGE_ENUM:
|
||||||
|
{
|
||||||
|
GValue l1 = { 0 }, v1 = { 0 };
|
||||||
|
|
||||||
|
g_value_init (&l1, GST_TYPE_LIST);
|
||||||
|
for (i = 1; i < n_items; i++) {
|
||||||
|
g_value_init (&v1, GST_TYPE_FRACTION);
|
||||||
|
gst_value_set_fraction (&v1, fract[i].num, fract[i].denom);
|
||||||
|
gst_value_list_append_and_take_value (&l1, &v1);
|
||||||
|
}
|
||||||
|
gst_caps_set_value (res, key, &l1);
|
||||||
|
g_value_unset (&l1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
GstCaps *
|
GstCaps *
|
||||||
gst_caps_from_format (const SpaFormat *format)
|
gst_caps_from_format (const SpaFormat *format)
|
||||||
{
|
{
|
||||||
GstCaps *res = NULL;
|
GstCaps *res = NULL;
|
||||||
uint32_t media_type, media_subtype;
|
uint32_t media_type, media_subtype;
|
||||||
|
SpaPODProp *prop;
|
||||||
|
|
||||||
ensure_types();
|
ensure_types();
|
||||||
|
|
||||||
|
|
@ -596,62 +752,43 @@ gst_caps_from_format (const SpaFormat *format)
|
||||||
media_subtype = SPA_FORMAT_MEDIA_SUBTYPE (format);
|
media_subtype = SPA_FORMAT_MEDIA_SUBTYPE (format);
|
||||||
|
|
||||||
if (media_type == type.media_type.video) {
|
if (media_type == type.media_type.video) {
|
||||||
SpaVideoInfo f = { media_type, media_subtype, };
|
|
||||||
|
|
||||||
if (media_subtype == type.media_subtype.raw) {
|
if (media_subtype == type.media_subtype.raw) {
|
||||||
const char * str;
|
res = gst_caps_new_empty_simple ("video/x-raw");
|
||||||
|
if ((prop = spa_format_find_prop (format, type.format_video.format))) {
|
||||||
if (!spa_format_video_raw_parse (format, &f.info.raw, &type.format_video))
|
handle_id_prop (prop, "format", res);
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
str = spa_type_map_get_type (type.map, f.info.raw.format);
|
|
||||||
|
|
||||||
res = gst_caps_new_simple ("video/x-raw",
|
|
||||||
"format", G_TYPE_STRING, rindex (str, ':') + 1,
|
|
||||||
"width", G_TYPE_INT, f.info.raw.size.width,
|
|
||||||
"height", G_TYPE_INT, f.info.raw.size.height,
|
|
||||||
"framerate", GST_TYPE_FRACTION, f.info.raw.framerate.num, f.info.raw.framerate.denom,
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
else if (media_subtype == type.media_subtype_video.mjpg) {
|
else if (media_subtype == type.media_subtype_video.mjpg) {
|
||||||
if (!spa_format_video_mjpg_parse (format, &f.info.mjpg, &type.format_video))
|
res = gst_caps_new_empty_simple ("image/jpeg");
|
||||||
return NULL;
|
|
||||||
|
|
||||||
res = gst_caps_new_simple ("image/jpeg",
|
|
||||||
"width", G_TYPE_INT, f.info.mjpg.size.width,
|
|
||||||
"height", G_TYPE_INT, f.info.mjpg.size.height,
|
|
||||||
"framerate", GST_TYPE_FRACTION, f.info.mjpg.framerate.num, f.info.mjpg.framerate.denom,
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
else if (media_subtype == type.media_subtype_video.h264) {
|
else if (media_subtype == type.media_subtype_video.h264) {
|
||||||
if (!spa_format_video_h264_parse (format, &f.info.h264, &type.format_video))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
res = gst_caps_new_simple ("video/x-h264",
|
res = gst_caps_new_simple ("video/x-h264",
|
||||||
"width", G_TYPE_INT, f.info.h264.size.width,
|
|
||||||
"height", G_TYPE_INT, f.info.h264.size.height,
|
|
||||||
"framerate", GST_TYPE_FRACTION, f.info.h264.framerate.num, f.info.h264.framerate.denom,
|
|
||||||
"stream-format", G_TYPE_STRING, "byte-stream",
|
"stream-format", G_TYPE_STRING, "byte-stream",
|
||||||
"alignment", G_TYPE_STRING, "au",
|
"alignment", G_TYPE_STRING, "au",
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
if ((prop = spa_format_find_prop (format, type.format_video.size))) {
|
||||||
|
handle_rect_prop (prop, "width", "height", res);
|
||||||
|
}
|
||||||
|
if ((prop = spa_format_find_prop (format, type.format_video.framerate))) {
|
||||||
|
handle_fraction_prop (prop, "framerate", res);
|
||||||
|
}
|
||||||
} else if (media_type == type.media_type.audio) {
|
} else if (media_type == type.media_type.audio) {
|
||||||
SpaAudioInfo f = { media_type, media_subtype, };
|
|
||||||
|
|
||||||
if (media_subtype == type.media_subtype.raw) {
|
if (media_subtype == type.media_subtype.raw) {
|
||||||
const char * str;
|
|
||||||
|
|
||||||
if (!spa_format_audio_raw_parse (format, &f.info.raw, &type.format_audio))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
str = spa_type_map_get_type (type.map, f.info.raw.format);
|
|
||||||
|
|
||||||
res = gst_caps_new_simple ("audio/x-raw",
|
res = gst_caps_new_simple ("audio/x-raw",
|
||||||
"format", G_TYPE_STRING, rindex (str, ':') + 1,
|
|
||||||
"layout", G_TYPE_STRING, "interleaved",
|
"layout", G_TYPE_STRING, "interleaved",
|
||||||
"rate", G_TYPE_INT, f.info.raw.rate,
|
|
||||||
"channels", G_TYPE_INT, f.info.raw.channels,
|
|
||||||
NULL);
|
NULL);
|
||||||
|
if ((prop = spa_format_find_prop (format, type.format_audio.format))) {
|
||||||
|
handle_id_prop (prop, "format", res);
|
||||||
|
}
|
||||||
|
if ((prop = spa_format_find_prop (format, type.format_audio.rate))) {
|
||||||
|
handle_int_prop (prop, "rate", res);
|
||||||
|
}
|
||||||
|
if ((prop = spa_format_find_prop (format, type.format_audio.channels))) {
|
||||||
|
handle_int_prop (prop, "channels", res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (media_subtype == type.media_subtype_audio.aac) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue