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;
|
||||
}
|
||||
|
||||
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 *
|
||||
gst_caps_from_format (const SpaFormat *format)
|
||||
{
|
||||
GstCaps *res = NULL;
|
||||
uint32_t media_type, media_subtype;
|
||||
SpaPODProp *prop;
|
||||
|
||||
ensure_types();
|
||||
|
||||
|
|
@ -596,62 +752,43 @@ gst_caps_from_format (const SpaFormat *format)
|
|||
media_subtype = SPA_FORMAT_MEDIA_SUBTYPE (format);
|
||||
|
||||
if (media_type == type.media_type.video) {
|
||||
SpaVideoInfo f = { media_type, media_subtype, };
|
||||
|
||||
if (media_subtype == type.media_subtype.raw) {
|
||||
const char * str;
|
||||
|
||||
if (!spa_format_video_raw_parse (format, &f.info.raw, &type.format_video))
|
||||
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);
|
||||
res = gst_caps_new_empty_simple ("video/x-raw");
|
||||
if ((prop = spa_format_find_prop (format, type.format_video.format))) {
|
||||
handle_id_prop (prop, "format", res);
|
||||
}
|
||||
}
|
||||
else if (media_subtype == type.media_subtype_video.mjpg) {
|
||||
if (!spa_format_video_mjpg_parse (format, &f.info.mjpg, &type.format_video))
|
||||
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);
|
||||
res = gst_caps_new_empty_simple ("image/jpeg");
|
||||
}
|
||||
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",
|
||||
"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",
|
||||
"alignment", G_TYPE_STRING, "au",
|
||||
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) {
|
||||
SpaAudioInfo f = { media_type, media_subtype, };
|
||||
|
||||
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",
|
||||
"format", G_TYPE_STRING, rindex (str, ':') + 1,
|
||||
"layout", G_TYPE_STRING, "interleaved",
|
||||
"rate", G_TYPE_INT, f.info.raw.rate,
|
||||
"channels", G_TYPE_INT, f.info.raw.channels,
|
||||
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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue