format: improve format parsing

This commit is contained in:
Wim Taymans 2017-03-24 18:11:11 +01:00
parent 94019fb1f5
commit 29cb7bf39a
30 changed files with 459 additions and 406 deletions

View file

@ -1,64 +0,0 @@
/* Simple Plugin API
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <lib/mapper.h>
#include <spa/audio/raw-utils.h>
#include <spa/audio/format-utils.h>
SpaResult
spa_format_audio_parse (const SpaFormat *format,
SpaAudioInfo *info)
{
static SpaTypeMediaType media_type = { 0, };
static SpaTypeMediaSubtype media_subtype = { 0, };
static SpaTypeMediaSubtypeAudio media_subtype_audio = { 0, };
static SpaTypeFormatAudio format_audio = { 0, };
SpaTypeMap *map = spa_type_map_get_default();
spa_type_media_type_map (map, &media_type);
spa_type_media_subtype_map (map, &media_subtype);
spa_type_media_subtype_audio_map (map, &media_subtype_audio);
spa_type_format_audio_map (map, &format_audio);
if (format->body.media_type.value != media_type.audio)
return SPA_RESULT_INVALID_MEDIA_TYPE;
info->media_type = format->body.media_type.value;
info->media_subtype = format->body.media_subtype.value;
if (info->media_subtype == media_subtype.raw) {
spa_format_query (format,
format_audio.format, SPA_POD_TYPE_ID, &info->info.raw.format,
format_audio.flags, SPA_POD_TYPE_INT, &info->info.raw.flags,
format_audio.layout, SPA_POD_TYPE_INT, &info->info.raw.layout,
format_audio.rate, SPA_POD_TYPE_INT, &info->info.raw.rate,
format_audio.channels, SPA_POD_TYPE_INT, &info->info.raw.channels,
format_audio.channel_mask, SPA_POD_TYPE_INT, &info->info.raw.channel_mask,
0);
}
else
return SPA_RESULT_NOT_IMPLEMENTED;
return SPA_RESULT_OK;
}

View file

@ -49,7 +49,7 @@ static const struct data_type_name {
#define DATA_TYPE_NAME(t) data_type_names[SPA_CLAMP(t,0,SPA_N_ELEMENTS(data_type_names)-1)].name
SpaResult
spa_debug_port_info (const SpaPortInfo *info)
spa_debug_port_info (const SpaPortInfo *info, const SpaTypeMap *map)
{
int i;
@ -63,7 +63,7 @@ spa_debug_port_info (const SpaPortInfo *info)
fprintf (stderr, " n_params: \t%d\n", info->n_params);
for (i = 0; i < info->n_params; i++) {
SpaAllocParam *param = info->params[i];
spa_debug_pod (&param->pod);
spa_debug_pod (&param->pod, map);
}
return SPA_RESULT_OK;
}
@ -176,9 +176,9 @@ spa_debug_dump_mem (const void *mem, size_t size)
}
SpaResult
spa_debug_props (const SpaProps *props, bool print_ranges)
spa_debug_props (const SpaProps *props, const SpaTypeMap *map)
{
spa_debug_pod (&props->pod);
spa_debug_pod (&props->pod, map);
return SPA_RESULT_OK;
}
@ -207,7 +207,7 @@ struct pod_type_name {
};
static void
print_pod_value (uint32_t size, uint32_t type, void *body, int prefix)
print_pod_value (const SpaTypeMap *map, uint32_t size, uint32_t type, void *body, int prefix)
{
switch (type) {
case SPA_POD_TYPE_BOOL:
@ -215,7 +215,7 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix)
break;
case SPA_POD_TYPE_ID:
printf ("%-*sId %d %s\n", prefix, "", *(int32_t *) body,
spa_type_map_get_type (spa_type_map_get_default(), *(int32_t*)body));
spa_type_map_get_type (map, *(int32_t*)body));
break;
case SPA_POD_TYPE_INT:
printf ("%-*sInt %d\n", prefix, "", *(int32_t *) body);
@ -236,7 +236,7 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix)
{
SpaPODPointerBody *b = body;
printf ("%-*sPointer %s %p\n", prefix, "",
spa_type_map_get_type (spa_type_map_get_default(), b->type), b->value);
spa_type_map_get_type (map, b->type), b->value);
break;
}
case SPA_POD_TYPE_RECTANGLE:
@ -261,7 +261,7 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix)
printf ("%-*sArray: child.size %d, child.type %d\n", prefix, "", b->child.size, b->child.type);
SPA_POD_ARRAY_BODY_FOREACH (b, size, p)
print_pod_value (b->child.size, b->child.type, p, prefix + 2);
print_pod_value (map, b->child.size, b->child.type, p, prefix + 2);
break;
}
case SPA_POD_TYPE_STRUCT:
@ -269,7 +269,7 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix)
SpaPOD *b = body, *p;
printf ("%-*sStruct: size %d\n", prefix, "", size);
SPA_POD_FOREACH (b, size, p)
print_pod_value (p->size, p->type, SPA_POD_BODY (p), prefix + 2);
print_pod_value (map, p->size, p->type, SPA_POD_BODY (p), prefix + 2);
break;
}
case SPA_POD_TYPE_OBJECT:
@ -278,9 +278,9 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix)
SpaPOD *p;
printf ("%-*sObject: size %d, id %d, type %s\n", prefix, "", size, b->id,
spa_type_map_get_type (spa_type_map_get_default(), b->type));
spa_type_map_get_type (map, b->type));
SPA_POD_OBJECT_BODY_FOREACH (b, size, p)
print_pod_value (p->size, p->type, SPA_POD_BODY (p), prefix + 2);
print_pod_value (map, p->size, p->type, SPA_POD_BODY (p), prefix + 2);
break;
}
case SPA_POD_TYPE_PROP:
@ -290,18 +290,18 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix)
int i;
printf ("%-*sProp: key %s, flags %d\n", prefix, "",
spa_type_map_get_type (spa_type_map_get_default(), b->key), b->flags);
spa_type_map_get_type (map, b->key), b->flags);
if (b->flags & SPA_POD_PROP_FLAG_UNSET)
printf ("%-*sUnset (Default):\n", prefix + 2, "");
else
printf ("%-*sValue: size %u\n", prefix + 2, "", b->value.size);
print_pod_value (b->value.size, b->value.type, SPA_POD_BODY (&b->value), prefix + 4);
print_pod_value (map, b->value.size, b->value.type, SPA_POD_BODY (&b->value), prefix + 4);
i = 0;
SPA_POD_PROP_ALTERNATIVE_FOREACH (b, size, alt) {
if (i == 0)
printf ("%-*sAlternatives:\n", prefix + 2, "");
print_pod_value (b->value.size, b->value.type, alt, prefix + 4);
print_pod_value (map, b->value.size, b->value.type, alt, prefix + 4);
i++;
}
break;
@ -321,14 +321,15 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix)
}
SpaResult
spa_debug_pod (const SpaPOD *pod)
spa_debug_pod (const SpaPOD *pod, const SpaTypeMap *map)
{
print_pod_value (pod->size, pod->type, SPA_POD_BODY (pod), 0);
map = map ? map : spa_type_map_get_default ();
print_pod_value (map, pod->size, pod->type, SPA_POD_BODY (pod), 0);
return SPA_RESULT_OK;
}
static void
print_format_value (uint32_t size, uint32_t type, void *body)
print_format_value (const SpaTypeMap *map, uint32_t size, uint32_t type, void *body)
{
switch (type) {
case SPA_POD_TYPE_BOOL:
@ -336,7 +337,7 @@ print_format_value (uint32_t size, uint32_t type, void *body)
break;
case SPA_POD_TYPE_ID:
{
const char *str = spa_type_map_get_type (spa_type_map_get_default(), *(int32_t*)body);
const char *str = spa_type_map_get_type (map, *(int32_t*)body);
if (str) {
const char *h = rindex (str, ':');
if (h)
@ -386,7 +387,7 @@ print_format_value (uint32_t size, uint32_t type, void *body)
}
SpaResult
spa_debug_format (const SpaFormat *format)
spa_debug_format (const SpaFormat *format, const SpaTypeMap *map)
{
int i;
const char *media_type;
@ -397,11 +398,13 @@ spa_debug_format (const SpaFormat *format)
if (format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
map = map ? map : spa_type_map_get_default ();
mtype = format->body.media_type.value;
mstype = format->body.media_subtype.value;
media_type = spa_type_map_get_type (spa_type_map_get_default (), mtype);
media_subtype = spa_type_map_get_type (spa_type_map_get_default (), mstype);
media_type = spa_type_map_get_type (map, mtype);
media_subtype = spa_type_map_get_type (map, mstype);
fprintf (stderr, "%-6s %s/%s\n", "", rindex (media_type, ':')+1, rindex (media_subtype, ':')+1);
@ -412,12 +415,14 @@ spa_debug_format (const SpaFormat *format)
(prop->body.flags & SPA_POD_PROP_FLAG_OPTIONAL))
continue;
key = spa_type_map_get_type (spa_type_map_get_default (), prop->body.key);
key = spa_type_map_get_type (map, prop->body.key);
fprintf (stderr, " %20s : (%s) ", rindex (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));
print_format_value (map, prop->body.value.size,
prop->body.value.type,
SPA_POD_BODY (&prop->body.value));
} else {
const char *ssep, *esep, *sep;
void *alt;
@ -444,7 +449,7 @@ spa_debug_format (const SpaFormat *format)
SPA_POD_PROP_ALTERNATIVE_FOREACH (&prop->body, prop->pod.size, alt) {
if (i > 0)
fprintf (stderr, "%s", sep);
print_format_value (prop->body.value.size, prop->body.value.type, alt);
print_format_value (map, prop->body.value.size, prop->body.value.type, alt);
i++;
}
fprintf (stderr, esep);

View file

@ -32,11 +32,11 @@ extern "C" {
#include <spa/format.h>
#include <spa/dict.h>
SpaResult spa_debug_port_info (const SpaPortInfo *info);
SpaResult spa_debug_port_info (const SpaPortInfo *info, const SpaTypeMap *map);
SpaResult spa_debug_buffer (const SpaBuffer *buffer);
SpaResult spa_debug_pod (const SpaPOD *pod);
SpaResult spa_debug_props (const SpaProps *props, bool print_ranges);
SpaResult spa_debug_format (const SpaFormat *format);
SpaResult spa_debug_props (const SpaProps *props, const SpaTypeMap *map);
SpaResult spa_debug_pod (const SpaPOD *pod, const SpaTypeMap *map);
SpaResult spa_debug_format (const SpaFormat *format, const SpaTypeMap *map);
SpaResult spa_debug_dump_mem (const void *data, size_t size);
SpaResult spa_debug_dict (const SpaDict *dict);

61
spa/lib/format.c Normal file
View file

@ -0,0 +1,61 @@
/* Simple Plugin API
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <spa/format-builder.h>
#include <spa/video/format-utils.h>
#include <lib/props.h>
#include <lib/mapper.h>
SpaResult
spa_format_filter (const SpaFormat *format,
const SpaFormat *filter,
SpaPODBuilder *result)
{
SpaPODFrame f;
SpaResult res;
if (format == NULL || result == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (filter == NULL) {
spa_pod_builder_raw_padded (result, format, SPA_POD_SIZE (format));
return SPA_RESULT_OK;
}
if (SPA_FORMAT_MEDIA_TYPE (filter) != SPA_FORMAT_MEDIA_TYPE (format) ||
SPA_FORMAT_MEDIA_SUBTYPE (filter) != SPA_FORMAT_MEDIA_SUBTYPE (format))
return SPA_RESULT_INVALID_MEDIA_TYPE;
spa_pod_builder_push_format (result, &f, filter->body.obj_body.type,
SPA_FORMAT_MEDIA_TYPE (filter),
SPA_FORMAT_MEDIA_SUBTYPE (filter));
res = spa_props_filter (result,
SPA_POD_CONTENTS (SpaFormat, format),
SPA_POD_CONTENTS_SIZE (SpaFormat, format),
SPA_POD_CONTENTS (SpaFormat, filter),
SPA_POD_CONTENTS_SIZE (SpaFormat, filter));
spa_pod_builder_pop (result, &f);
return res;
}

View file

@ -52,7 +52,7 @@ type_map_get_id (SpaTypeMap *map, const char *type)
}
static const char *
type_map_get_type (SpaTypeMap *map, uint32_t id)
type_map_get_type (const SpaTypeMap *map, uint32_t id)
{
TypeMap *this = SPA_CONTAINER_OF (map, TypeMap, map);
@ -63,7 +63,7 @@ type_map_get_type (SpaTypeMap *map, uint32_t id)
}
static size_t
type_map_get_size (SpaTypeMap *map)
type_map_get_size (const SpaTypeMap *map)
{
TypeMap *this = SPA_CONTAINER_OF (map, TypeMap, map);
return this->n_types;

View file

@ -1,8 +1,7 @@
spalib_sources = ['audio-raw.c',
'debug.c',
spalib_sources = ['debug.c',
'mapper.c',
'props.c',
'video-raw.c']
'format.c']
spalib = shared_library('spa-lib',
spalib_sources,

View file

@ -1,117 +0,0 @@
/* Simple Plugin API
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <spa/format-builder.h>
#include <spa/video/format-utils.h>
#include <lib/props.h>
#include <lib/mapper.h>
SpaResult
spa_format_video_parse (const SpaFormat *format,
SpaVideoInfo *info)
{
static SpaTypeMediaType media_type = { 0, };
static SpaTypeMediaSubtype media_subtype = { 0, };
static SpaTypeMediaSubtypeVideo media_subtype_video = { 0, };
static SpaTypeFormatVideo format_video = { 0, };
SpaTypeMap *map = spa_type_map_get_default ();
spa_type_media_type_map (map, &media_type);
spa_type_media_subtype_map (map, &media_subtype);
spa_type_media_subtype_video_map (map, &media_subtype_video);
spa_type_format_video_map (map, &format_video);
if (format->body.media_type.value != media_type.video)
return SPA_RESULT_INVALID_MEDIA_TYPE;
info->media_type = format->body.media_type.value;
info->media_subtype = format->body.media_subtype.value;
if (info->media_subtype == media_subtype.raw)
spa_format_query (format,
format_video.format, SPA_POD_TYPE_ID, &info->info.raw.format,
format_video.size, SPA_POD_TYPE_RECTANGLE, &info->info.raw.size,
format_video.framerate, SPA_POD_TYPE_FRACTION, &info->info.raw.framerate,
format_video.max_framerate, SPA_POD_TYPE_FRACTION, &info->info.raw.max_framerate,
format_video.views, SPA_POD_TYPE_INT, &info->info.raw.views,
format_video.interlace_mode, SPA_POD_TYPE_INT, &info->info.raw.interlace_mode,
format_video.pixel_aspect_ratio, SPA_POD_TYPE_FRACTION, &info->info.raw.pixel_aspect_ratio,
format_video.multiview_mode, SPA_POD_TYPE_INT, &info->info.raw.multiview_mode,
format_video.multiview_flags, SPA_POD_TYPE_INT, &info->info.raw.multiview_flags,
format_video.chroma_site, SPA_POD_TYPE_INT, &info->info.raw.chroma_site,
format_video.color_range, SPA_POD_TYPE_INT, &info->info.raw.color_range,
format_video.color_matrix, SPA_POD_TYPE_INT, &info->info.raw.color_matrix,
format_video.transfer_function, SPA_POD_TYPE_INT, &info->info.raw.transfer_function,
format_video.color_primaries, SPA_POD_TYPE_INT, &info->info.raw.color_primaries,
0);
else if (info->media_subtype == media_subtype_video.h264)
spa_format_query (format,
format_video.size, SPA_POD_TYPE_RECTANGLE, &info->info.h264.size,
format_video.framerate, SPA_POD_TYPE_FRACTION, &info->info.h264.framerate,
format_video.max_framerate, SPA_POD_TYPE_FRACTION, &info->info.h264.max_framerate,
0);
else if (info->media_subtype == media_subtype_video.mjpg)
spa_format_query (format,
format_video.size, SPA_POD_TYPE_RECTANGLE, &info->info.mjpg.size,
format_video.framerate, SPA_POD_TYPE_FRACTION, &info->info.mjpg.framerate,
format_video.max_framerate, SPA_POD_TYPE_FRACTION, &info->info.mjpg.max_framerate,
0);
else
return SPA_RESULT_NOT_IMPLEMENTED;
return SPA_RESULT_OK;
}
SpaResult
spa_format_filter (const SpaFormat *format,
const SpaFormat *filter,
SpaPODBuilder *result)
{
SpaPODFrame f;
SpaResult res;
if (format == NULL || result == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (filter == NULL) {
spa_pod_builder_raw_padded (result, format, SPA_POD_SIZE (format));
return SPA_RESULT_OK;
}
if (filter->body.media_type.value != format->body.media_type.value ||
filter->body.media_subtype.value != format->body.media_subtype.value)
return SPA_RESULT_INVALID_MEDIA_TYPE;
spa_pod_builder_push_format (result, &f, filter->body.obj_body.type,
filter->body.media_type.value,
filter->body.media_subtype.value);
res = spa_props_filter (result,
SPA_POD_CONTENTS (SpaFormat, format),
SPA_POD_CONTENTS_SIZE (SpaFormat, format),
SPA_POD_CONTENTS (SpaFormat, filter),
SPA_POD_CONTENTS_SIZE (SpaFormat, filter));
spa_pod_builder_pop (result, &f);
return res;
}