mirror of https://code.videolan.org/videolan/vlc
Merge branch 'type_serializer' into 'master'
Draft: type serialization module See merge request videolan/vlc!2979
This commit is contained in:
commit
d8f13a3e22
|
@ -0,0 +1,58 @@
|
|||
/*****************************************************************************
|
||||
* vlc_serializer.h
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2022 VLC authors and VideoLAN
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef VLC_SERIALIZER_H
|
||||
# define VLC_SERIALIZER_H
|
||||
|
||||
struct vlc_memstream;
|
||||
|
||||
/**
|
||||
* Structure received by serializer/deserializer modules.
|
||||
*
|
||||
* The caller has to fill the structure following:
|
||||
* - serialization:
|
||||
* 1. type to serialize.
|
||||
* 2. valid vlc_memstream, which will be filled with type content as raw bytes
|
||||
* by the serializer.
|
||||
*
|
||||
* - deserialization:
|
||||
* 1. type which will initialized from the content of the raw type buffer by
|
||||
* the deserializer.
|
||||
* 2. buffer of the type serialized.
|
||||
* 3. buffer size
|
||||
*/
|
||||
typedef struct type_serializer_t
|
||||
{
|
||||
struct vlc_object_t obj;
|
||||
|
||||
void *type;
|
||||
|
||||
int ( * pf_serialize )( struct type_serializer_t * );
|
||||
int ( * pf_deserialize )( struct type_serializer_t * );
|
||||
|
||||
/* serialization */
|
||||
struct vlc_memstream *serialized_type;
|
||||
|
||||
/* deserialization */
|
||||
char *serialized;
|
||||
unsigned int buffer_size;
|
||||
} type_serializer_t;
|
||||
|
||||
#endif
|
|
@ -138,3 +138,13 @@ libmedialibrary_plugin_la_LIBADD = $(MEDIALIBRARY_LIBS)
|
|||
libmedialibrary_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(miscdir)'
|
||||
EXTRA_LTLIBRARIES += libmedialibrary_plugin.la
|
||||
misc_LTLIBRARIES += $(LTLIBmedialibrary)
|
||||
|
||||
libserializers_plugin_la_SOURCES = \
|
||||
misc/serializers/serialize.c \
|
||||
misc/serializers/es_format.c \
|
||||
misc/serializers/input_item.c \
|
||||
misc/serializers/input_attachment.c
|
||||
|
||||
libserializers_plugin_la_CFLAGS = $(AM_CFLAGS)
|
||||
libserializers_plugin_la_LIBADD = $(AM_LIBADD)
|
||||
misc_LTLIBRARIES += libserializers_plugin.la
|
||||
|
|
|
@ -0,0 +1,285 @@
|
|||
/*****************************************************************************
|
||||
* es_format.c: serializer and deserializer for es_format_t
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2022 VLC authors and VideoLAN
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <vlc_common.h>
|
||||
#include <vlc_serializer.h>
|
||||
#include <vlc_memstream.h>
|
||||
#include <vlc_es.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* Local prototypes
|
||||
*****************************************************************************/
|
||||
int serialize_es_format(type_serializer_t *serializer);
|
||||
int deserialize_es_format(type_serializer_t *serializer);
|
||||
|
||||
int serialize_es_format(type_serializer_t *serializer)
|
||||
{
|
||||
es_format_t *es = (es_format_t *)serializer->type;
|
||||
struct vlc_memstream *serialized_format = serializer->serialized_type;
|
||||
|
||||
vlc_memstream_write(serialized_format, &es->i_cat, sizeof(es->i_cat));
|
||||
vlc_memstream_write(serialized_format, &es->i_codec, sizeof(es->i_codec));
|
||||
vlc_memstream_write(serialized_format, &es->i_original_fourcc, sizeof(es->i_original_fourcc));
|
||||
vlc_memstream_write(serialized_format, &es->i_id, sizeof(es->i_id));
|
||||
vlc_memstream_write(serialized_format, &es->i_group, sizeof(es->i_group));
|
||||
vlc_memstream_write(serialized_format, &es->i_priority, sizeof(es->i_priority));
|
||||
|
||||
{
|
||||
unsigned int language_length = 0;
|
||||
if (!es->psz_language) {
|
||||
vlc_memstream_write(serialized_format, &language_length, sizeof(language_length));
|
||||
} else {
|
||||
language_length = strlen(es->psz_language) + 1;
|
||||
|
||||
vlc_memstream_write(serialized_format, &language_length, sizeof(language_length));
|
||||
vlc_memstream_write(serialized_format, &es->psz_language, language_length);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
unsigned int description_length = 0;
|
||||
if (!es->psz_description) {
|
||||
vlc_memstream_write(serialized_format, &description_length, sizeof(description_length));
|
||||
} else {
|
||||
description_length = strlen(es->psz_language) + 1;
|
||||
|
||||
vlc_memstream_write(serialized_format, &description_length, sizeof(description_length));
|
||||
vlc_memstream_write(serialized_format, &es->psz_description, description_length);
|
||||
}
|
||||
}
|
||||
|
||||
vlc_memstream_write(serialized_format, &es->i_extra_languages, sizeof(es->i_extra_languages));
|
||||
for (unsigned j = 0; j < es->i_extra_languages; ++j) {
|
||||
const size_t language_len = strlen(es->p_extra_languages[j].psz_language) + 1;
|
||||
vlc_memstream_write(serialized_format, &language_len, sizeof(language_len));
|
||||
|
||||
char *const language = es->p_extra_languages[j].psz_language;
|
||||
vlc_memstream_write(serialized_format, language, language_len);
|
||||
|
||||
const size_t desc_len = strlen(es->p_extra_languages[j].psz_description) + 1;
|
||||
vlc_memstream_write(serialized_format, &desc_len, sizeof(desc_len));
|
||||
|
||||
char *const description = es->p_extra_languages[j].psz_description;
|
||||
vlc_memstream_write(serialized_format, description, desc_len);
|
||||
}
|
||||
|
||||
switch (es->i_cat) {
|
||||
case UNKNOWN_ES:
|
||||
break;
|
||||
case VIDEO_ES:
|
||||
vlc_memstream_write(serialized_format, &es->video, sizeof(es->video));
|
||||
break;
|
||||
|
||||
case AUDIO_ES:
|
||||
vlc_memstream_write(serialized_format, &es->audio, sizeof(es->audio));
|
||||
vlc_memstream_write(serialized_format, &es->audio_replay_gain, sizeof(es->audio_replay_gain));
|
||||
break;
|
||||
|
||||
case SPU_ES:
|
||||
case DATA_ES:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
vlc_memstream_write(serialized_format, &es->i_bitrate, sizeof(es->i_bitrate));
|
||||
vlc_memstream_write(serialized_format, &es->i_profile, sizeof(es->i_profile));
|
||||
vlc_memstream_write(serialized_format, &es->i_level, sizeof(es->i_level));
|
||||
vlc_memstream_write(serialized_format, &es->b_packetized, sizeof(es->b_packetized));
|
||||
vlc_memstream_write(serialized_format, &es->i_extra, sizeof(es->i_extra));
|
||||
if (es->i_extra)
|
||||
vlc_memstream_write(serialized_format, es->p_extra, es->i_extra);
|
||||
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
#define BOUNDARY_CHECK(offset) \
|
||||
do { \
|
||||
if (cur_pos + offset >= (serialized_format + size)) \
|
||||
goto error; \
|
||||
} while (0);
|
||||
|
||||
int deserialize_es_format(type_serializer_t *serializer)
|
||||
{
|
||||
const char *serialized_format = serializer->serialized;
|
||||
const char *cur_pos = serialized_format;
|
||||
es_format_t *es = (es_format_t *)serializer->type;
|
||||
const unsigned int size = serializer->buffer_size;
|
||||
|
||||
BOUNDARY_CHECK(sizeof(enum es_format_category_e));
|
||||
memcpy(&es->i_cat, cur_pos, sizeof(es->i_cat));
|
||||
cur_pos += sizeof(es->i_cat);
|
||||
|
||||
BOUNDARY_CHECK(sizeof(vlc_fourcc_t));
|
||||
memcpy(&es->i_codec, cur_pos, sizeof(es->i_codec));
|
||||
cur_pos += sizeof(es->i_codec);
|
||||
|
||||
BOUNDARY_CHECK(sizeof(vlc_fourcc_t));
|
||||
memcpy(&es->i_original_fourcc, cur_pos, sizeof(es->i_original_fourcc));
|
||||
cur_pos += sizeof(es->i_original_fourcc);
|
||||
|
||||
BOUNDARY_CHECK(sizeof(int));
|
||||
memcpy(&es->i_id, cur_pos, sizeof(es->i_id));
|
||||
cur_pos += sizeof(es->i_id);
|
||||
|
||||
BOUNDARY_CHECK(sizeof(int));
|
||||
memcpy(&es->i_group, cur_pos, sizeof(es->i_group));
|
||||
cur_pos += sizeof(es->i_group);
|
||||
|
||||
BOUNDARY_CHECK(sizeof(int));
|
||||
memcpy(&es->i_priority, cur_pos, sizeof(es->i_priority));
|
||||
cur_pos += sizeof(es->i_priority);
|
||||
|
||||
{
|
||||
BOUNDARY_CHECK(sizeof(unsigned int));
|
||||
unsigned int language_length;
|
||||
memcpy(&language_length, cur_pos, sizeof(language_length));
|
||||
cur_pos += sizeof(language_length);
|
||||
|
||||
char *psz_language = NULL;
|
||||
BOUNDARY_CHECK(language_length);
|
||||
if (language_length) {
|
||||
psz_language = strndup(cur_pos, language_length);
|
||||
if (unlikely(!psz_language))
|
||||
goto error;
|
||||
}
|
||||
|
||||
es->psz_language = psz_language;
|
||||
cur_pos += language_length;
|
||||
}
|
||||
|
||||
{
|
||||
BOUNDARY_CHECK(sizeof(unsigned int));
|
||||
unsigned int description_length;
|
||||
memcpy(&description_length, cur_pos, sizeof(description_length));
|
||||
cur_pos += sizeof(description_length);
|
||||
char *psz_description = NULL;
|
||||
|
||||
BOUNDARY_CHECK(description_length);
|
||||
if (description_length) {
|
||||
psz_description = strndup(cur_pos, description_length);
|
||||
if (unlikely(!psz_description))
|
||||
goto error;
|
||||
}
|
||||
|
||||
es->psz_description = psz_description;
|
||||
cur_pos += description_length;
|
||||
}
|
||||
|
||||
BOUNDARY_CHECK(sizeof(unsigned int));
|
||||
memcpy(&es->i_extra_languages, cur_pos, sizeof(es->i_extra_languages));
|
||||
cur_pos += sizeof(es->i_extra_languages);
|
||||
|
||||
es->p_extra_languages = 0;
|
||||
if (es->i_extra_languages) {
|
||||
es->p_extra_languages = vlc_alloc(es->i_extra_languages, sizeof(*es->p_extra_languages));
|
||||
if (unlikely(!es->p_extra_languages))
|
||||
goto error;
|
||||
|
||||
for (unsigned i = 0; i < es->i_extra_languages; ++i) {
|
||||
BOUNDARY_CHECK(sizeof(size_t));
|
||||
size_t language_len;
|
||||
memcpy(&language_len, cur_pos, sizeof(language_len));
|
||||
cur_pos += sizeof(size_t);
|
||||
|
||||
BOUNDARY_CHECK(sizeof(language_len));
|
||||
es->p_extra_languages[i].psz_language = strndup(cur_pos, language_len);
|
||||
if (unlikely(!es->p_extra_languages[i].psz_language))
|
||||
goto error;
|
||||
cur_pos += language_len;
|
||||
|
||||
BOUNDARY_CHECK(sizeof(size_t));
|
||||
size_t desc_len;
|
||||
memcpy(&desc_len, cur_pos, sizeof(desc_len));
|
||||
cur_pos += sizeof(size_t);
|
||||
|
||||
BOUNDARY_CHECK(sizeof(desc_len));
|
||||
es->p_extra_languages[i].psz_description = strndup(cur_pos, desc_len);
|
||||
if (unlikely(!es->p_extra_languages[i].psz_description))
|
||||
goto error;
|
||||
|
||||
cur_pos += desc_len;
|
||||
}
|
||||
}
|
||||
|
||||
switch (es->i_cat) {
|
||||
case VIDEO_ES:
|
||||
BOUNDARY_CHECK(sizeof(video_format_t));
|
||||
memcpy(&es->video, cur_pos, sizeof(es->video));
|
||||
cur_pos += sizeof(es->video);
|
||||
break;
|
||||
|
||||
case AUDIO_ES:
|
||||
BOUNDARY_CHECK(sizeof(audio_format_t));
|
||||
memcpy(&es->audio, cur_pos, sizeof(es->audio));
|
||||
cur_pos += sizeof(es->audio);
|
||||
|
||||
BOUNDARY_CHECK(sizeof(audio_replay_gain_t));
|
||||
memcpy(&es->audio_replay_gain, cur_pos, sizeof(es->audio_replay_gain));
|
||||
cur_pos += sizeof(es->audio_replay_gain);
|
||||
break;
|
||||
|
||||
case SPU_ES:
|
||||
case DATA_ES:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
BOUNDARY_CHECK(sizeof(unsigned int));
|
||||
memcpy(&es->i_bitrate, cur_pos, sizeof(es->i_bitrate));
|
||||
cur_pos += sizeof(es->i_bitrate);
|
||||
|
||||
BOUNDARY_CHECK(sizeof(int));
|
||||
memcpy(&es->i_profile, cur_pos, sizeof(es->i_profile));
|
||||
cur_pos += sizeof(es->i_profile);
|
||||
|
||||
BOUNDARY_CHECK(sizeof(int));
|
||||
memcpy(&es->i_level, cur_pos, sizeof(es->i_level));
|
||||
cur_pos += sizeof(es->i_level);
|
||||
|
||||
BOUNDARY_CHECK(sizeof(bool));
|
||||
memcpy(&es->b_packetized, cur_pos, sizeof(es->b_packetized));
|
||||
cur_pos += sizeof(es->b_packetized);
|
||||
|
||||
BOUNDARY_CHECK(sizeof(int));
|
||||
memcpy(&es->i_extra, cur_pos, sizeof(es->i_extra));
|
||||
cur_pos += sizeof(es->i_extra);
|
||||
|
||||
es->p_extra = NULL;
|
||||
if (es->i_extra) {
|
||||
BOUNDARY_CHECK(sizeof(es->i_extra));
|
||||
es->p_extra = malloc(es->i_extra);
|
||||
if (unlikely(!es->p_extra))
|
||||
goto error;
|
||||
|
||||
memcpy(es->p_extra, cur_pos, es->i_extra);
|
||||
}
|
||||
|
||||
return VLC_SUCCESS;
|
||||
|
||||
error:
|
||||
es_format_Clean(es);
|
||||
return VLC_ENOMEM;
|
||||
}
|
||||
|
||||
#undef BOUNDARY_CHECK
|
|
@ -0,0 +1,107 @@
|
|||
/*****************************************************************************
|
||||
* input_attachment.c: serializer and deserializer for input_attachment_t
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2022 VLC authors and VideoLAN
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <vlc_common.h>
|
||||
#include <vlc_modules.h>
|
||||
#include <vlc/libvlc.h>
|
||||
#include <vlc_serializer.h>
|
||||
#include <vlc_memstream.h>
|
||||
#include <vlc_input.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* Local prototypes
|
||||
*****************************************************************************/
|
||||
int serialize_attachment ( type_serializer_t * );
|
||||
int deserialize_attachment ( type_serializer_t * );
|
||||
|
||||
int serialize_attachment(type_serializer_t *serializer)
|
||||
{
|
||||
input_attachment_t *attach = (input_attachment_t *)serializer->type;
|
||||
struct vlc_memstream *serialize_attachment = serializer->serialized_type;
|
||||
|
||||
{
|
||||
unsigned int name_length = strlen(attach->psz_name) + 1;
|
||||
vlc_memstream_write(serialize_attachment, &name_length, sizeof(name_length));
|
||||
vlc_memstream_write(serialize_attachment, attach->psz_name, name_length);
|
||||
}
|
||||
|
||||
{
|
||||
unsigned int mime_length = strlen(attach->psz_mime) + 1;
|
||||
vlc_memstream_write(serialize_attachment, &mime_length, sizeof(mime_length));
|
||||
vlc_memstream_write(serialize_attachment, attach->psz_mime, mime_length);
|
||||
}
|
||||
|
||||
{
|
||||
unsigned int description_length = strlen(attach->psz_description) + 1;
|
||||
vlc_memstream_write(serialize_attachment, &description_length, sizeof(description_length));
|
||||
vlc_memstream_write(serialize_attachment, attach->psz_description, description_length);
|
||||
}
|
||||
|
||||
vlc_memstream_write(serialize_attachment, &attach->i_data, sizeof(attach->i_data));
|
||||
vlc_memstream_write(serialize_attachment, attach->p_data, attach->i_data);
|
||||
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
int deserialize_attachment(type_serializer_t *serializer)
|
||||
{
|
||||
const char *serialized_attachment = serializer->serialized;
|
||||
const char *cur_pos = serialized_attachment;
|
||||
|
||||
input_attachment_t *attach = (input_attachment_t *)serializer->type;
|
||||
{
|
||||
unsigned int name_length = *(unsigned int *)cur_pos;
|
||||
cur_pos += sizeof(name_length);
|
||||
attach->psz_name = strndup(cur_pos, name_length);
|
||||
cur_pos += name_length;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned int mime_length = *(unsigned int *)cur_pos;
|
||||
cur_pos += sizeof(mime_length);
|
||||
attach->psz_mime = strndup(cur_pos, mime_length);
|
||||
cur_pos += mime_length;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned int description_length = *(unsigned int *)cur_pos;
|
||||
cur_pos += sizeof(description_length);
|
||||
attach->psz_mime = strndup(cur_pos, description_length);
|
||||
cur_pos += description_length;
|
||||
}
|
||||
|
||||
attach->i_data = *(int *)cur_pos;
|
||||
cur_pos += sizeof(attach->i_data);
|
||||
|
||||
attach->p_data = malloc(attach->i_data);
|
||||
if (unlikely(!attach->p_data)) {
|
||||
goto error;
|
||||
}
|
||||
memcpy(attach->p_data, cur_pos, attach->i_data);
|
||||
|
||||
return VLC_SUCCESS;
|
||||
|
||||
error:
|
||||
return VLC_ENOMEM;
|
||||
}
|
|
@ -0,0 +1,315 @@
|
|||
/*****************************************************************************
|
||||
* input_item.c: serializer and deserializer for input_item_t
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2022 VLC authors and VideoLAN
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <vlc_common.h>
|
||||
#include <vlc_modules.h>
|
||||
#include <vlc_memstream.h>
|
||||
#include <vlc_serializer.h>
|
||||
#include <vlc_input_item.h>
|
||||
#include <vlc_meta.h>
|
||||
#include <vlc_es.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* Local prototypes
|
||||
*****************************************************************************/
|
||||
int serialize_input_item(type_serializer_t *serializer);
|
||||
int deserialize_input_item(type_serializer_t *serializer);
|
||||
|
||||
int serialize_input_item(type_serializer_t *serializer)
|
||||
{
|
||||
input_item_t *item = (input_item_t *)serializer->type;
|
||||
struct vlc_memstream *serialized_item = serializer->serialized_type;
|
||||
|
||||
/* psz_uri */
|
||||
if (item->psz_uri)
|
||||
{
|
||||
const size_t uri_len = strlen(item->psz_uri) + 1;
|
||||
vlc_memstream_write(serialized_item, &uri_len, sizeof(uri_len));
|
||||
vlc_memstream_write(serialized_item, item->psz_uri, uri_len);
|
||||
} else {
|
||||
const size_t uri_len = 0;
|
||||
vlc_memstream_write(serialized_item, &uri_len, sizeof(uri_len));
|
||||
}
|
||||
|
||||
/* psz_name */
|
||||
if (item->psz_name)
|
||||
{
|
||||
const size_t name_len = strlen(item->psz_name) + 1;
|
||||
vlc_memstream_write(serialized_item, &name_len, sizeof(name_len));
|
||||
vlc_memstream_write(serialized_item, item->psz_name, name_len);
|
||||
} else {
|
||||
const size_t name_len = 0;
|
||||
vlc_memstream_write(serialized_item, &name_len, sizeof(name_len));
|
||||
}
|
||||
|
||||
/* i_options */
|
||||
{
|
||||
vlc_memstream_write(serialized_item, &item->i_options, sizeof(item->i_options));
|
||||
for (int i = 0; i < item->i_options; ++i) {
|
||||
size_t opt_len = strlen(item->ppsz_options[i]) + 1;
|
||||
vlc_memstream_write(serialized_item, &opt_len, sizeof(opt_len));
|
||||
vlc_memstream_write(serialized_item, item->ppsz_options[i], opt_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* i_duration */
|
||||
{
|
||||
vlc_tick_t duration = input_item_GetDuration(item);
|
||||
vlc_memstream_write(serialized_item, &duration, sizeof(duration));
|
||||
}
|
||||
|
||||
/* es_format_t */
|
||||
vlc_memstream_write(serialized_item, &item->i_es, sizeof(item->i_es));
|
||||
|
||||
if (item->i_es) {
|
||||
/* load es_format_t serializer */
|
||||
type_serializer_t *serialize_es = NULL;
|
||||
serialize_es = vlc_object_create( serializer, sizeof(*serialize_es) );
|
||||
if (unlikely(!serialize_es)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
module_t *module = module_need(serialize_es, "serialize type", "serialize-es", true);
|
||||
if (!module) {
|
||||
msg_Err(serialize_es, "Could not find serialize-es module");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* serialize es_format_t */
|
||||
for (int i = 0; i < item->i_es; ++i) {
|
||||
if (vlc_memstream_flush(serialized_item))
|
||||
goto error;
|
||||
|
||||
unsigned int *format_size = (unsigned int *)(serialized_item->ptr + serialized_item->length);
|
||||
unsigned int old_stream_length = serialized_item->length;
|
||||
vlc_memstream_write(serialized_item, "format size", sizeof(unsigned int));
|
||||
serialize_es->serialized_type = serialized_item;
|
||||
serialize_es->type = item->es[i];
|
||||
if (serialize_es->pf_serialize(serialize_es)) {
|
||||
msg_Err(serialize_es, "Could not serialize es_format");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (vlc_memstream_flush(serialized_item)) {
|
||||
msg_Err(serialize_es, "Cannot flush memstream");
|
||||
goto error;
|
||||
}
|
||||
|
||||
*format_size = serialized_item->length - old_stream_length - sizeof(unsigned int);
|
||||
}
|
||||
|
||||
module_unneed(serialize_es, module);
|
||||
}
|
||||
|
||||
/* p_meta */
|
||||
for (vlc_meta_type_t i = vlc_meta_Title; i <= vlc_meta_DiscTotal; ++i) {
|
||||
char *psz_meta = input_item_GetMeta(item, i);
|
||||
if (psz_meta == NULL) {
|
||||
vlc_memstream_write(serialized_item, "\0\0\0\0", 4);
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned int len = (unsigned int)strlen(psz_meta) + 1;
|
||||
vlc_memstream_write(serialized_item, &len, sizeof(len));
|
||||
|
||||
vlc_memstream_write(serialized_item, psz_meta, len);
|
||||
free(psz_meta);
|
||||
}
|
||||
{
|
||||
int i_status = vlc_meta_GetStatus(item->p_meta);
|
||||
vlc_memstream_write(serialized_item, &i_status, sizeof(i_status));
|
||||
}
|
||||
|
||||
/* b_error_when_reading */
|
||||
vlc_memstream_write(serialized_item, &item->b_error_when_reading, sizeof(item->b_error_when_reading));
|
||||
|
||||
/* b_preparse_depth */
|
||||
vlc_memstream_write(serialized_item, &item->i_preparse_depth, sizeof(item->i_preparse_depth));
|
||||
|
||||
return VLC_SUCCESS;
|
||||
|
||||
error:
|
||||
return VLC_ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
#define BOUNDARY_CHECK(offset) \
|
||||
do { \
|
||||
if (cur_pos + offset >= (serialized_item + size)) \
|
||||
goto error; \
|
||||
} while (0);
|
||||
|
||||
int deserialize_input_item(type_serializer_t *serializer)
|
||||
{
|
||||
char *serialized_item = serializer->serialized;
|
||||
char *cur_pos = serialized_item;
|
||||
input_item_t *item = (input_item_t *)serializer->type;
|
||||
const unsigned int size = serializer->buffer_size;
|
||||
|
||||
/* get psz_uri*/
|
||||
{
|
||||
BOUNDARY_CHECK(sizeof(size_t));
|
||||
item->psz_uri = NULL;
|
||||
size_t len;
|
||||
memcpy(&len, cur_pos, sizeof(len));
|
||||
cur_pos += sizeof(len);
|
||||
if (len) {
|
||||
input_item_SetURI(item, cur_pos);
|
||||
BOUNDARY_CHECK(len);
|
||||
cur_pos += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* get psz_name*/
|
||||
{
|
||||
BOUNDARY_CHECK(sizeof(size_t));
|
||||
item->psz_name = NULL;
|
||||
size_t len;
|
||||
memcpy(&len, cur_pos, sizeof(len));
|
||||
cur_pos += sizeof(len);
|
||||
if (len) {
|
||||
input_item_SetName(item, cur_pos);
|
||||
BOUNDARY_CHECK(len);
|
||||
cur_pos += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* get ppsz_options */
|
||||
{
|
||||
BOUNDARY_CHECK(sizeof(int));
|
||||
item->i_options = *(int *)cur_pos;
|
||||
cur_pos += sizeof(item->i_options);
|
||||
|
||||
for (int i = 0; i < item->i_options; ++i) {
|
||||
BOUNDARY_CHECK(sizeof(size_t));
|
||||
size_t opt_len;
|
||||
memcpy(&opt_len, cur_pos, sizeof(size_t));
|
||||
cur_pos += sizeof(opt_len);
|
||||
|
||||
input_item_AddOption(item, cur_pos, 0);
|
||||
BOUNDARY_CHECK(opt_len);
|
||||
cur_pos += opt_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* get i_duration */
|
||||
{
|
||||
BOUNDARY_CHECK(sizeof(vlc_tick_t));
|
||||
vlc_tick_t duration = *(vlc_tick_t *)cur_pos;
|
||||
input_item_SetDuration(item, duration);
|
||||
cur_pos += sizeof(duration);
|
||||
}
|
||||
|
||||
/* get es_format_t */
|
||||
BOUNDARY_CHECK(sizeof(int));
|
||||
memcpy(&item->i_es, cur_pos, sizeof(item->i_es));
|
||||
cur_pos += sizeof(item->i_es);
|
||||
|
||||
if (item->i_es) {
|
||||
type_serializer_t *deserialize_es = NULL;
|
||||
deserialize_es = vlc_object_create( serializer, sizeof(*deserialize_es) );
|
||||
if (unlikely(!deserialize_es)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
module_t *module = module_need(deserialize_es, "serialize type", "serialize-es", true);
|
||||
if (!module) {
|
||||
msg_Err(deserialize_es, "Could not find serialize-es module for deserialization");
|
||||
goto error;
|
||||
}
|
||||
|
||||
item->es = vlc_alloc(item->i_es, sizeof(es_format_t *));
|
||||
if (unlikely(!item->es))
|
||||
goto error;
|
||||
|
||||
for (int i = 0; i < item->i_es; ++i) {
|
||||
BOUNDARY_CHECK(sizeof(unsigned int));
|
||||
unsigned int buffer_size;
|
||||
memcpy(&buffer_size, cur_pos, sizeof(buffer_size));
|
||||
cur_pos += sizeof(unsigned int);
|
||||
item->es[i] = malloc(sizeof(es_format_t));
|
||||
if (unlikely(!item->es[i]))
|
||||
goto error;
|
||||
|
||||
BOUNDARY_CHECK(buffer_size);
|
||||
deserialize_es->buffer_size = buffer_size;
|
||||
deserialize_es->type = item->es[i];
|
||||
deserialize_es->serialized = cur_pos;
|
||||
if (deserialize_es->pf_deserialize(deserialize_es))
|
||||
goto error;
|
||||
|
||||
cur_pos += buffer_size;
|
||||
}
|
||||
|
||||
module_unneed(deserialize_es, module);
|
||||
}
|
||||
|
||||
/* get meta */
|
||||
for (vlc_meta_type_t i = vlc_meta_Title; i <= vlc_meta_DiscTotal; ++i) {
|
||||
BOUNDARY_CHECK(sizeof(unsigned int));
|
||||
unsigned int meta_len;
|
||||
memcpy(&meta_len, cur_pos, sizeof(meta_len));
|
||||
cur_pos += sizeof(meta_len);
|
||||
if (!meta_len)
|
||||
continue;
|
||||
|
||||
BOUNDARY_CHECK(meta_len);
|
||||
input_item_SetMeta(item, i, cur_pos);
|
||||
cur_pos += meta_len;
|
||||
}
|
||||
|
||||
BOUNDARY_CHECK(sizeof(int));
|
||||
vlc_meta_SetStatus(item->p_meta, *(int *)cur_pos);
|
||||
cur_pos += sizeof(int);
|
||||
|
||||
/* get b_error_when_reading */
|
||||
{
|
||||
BOUNDARY_CHECK(sizeof(bool));
|
||||
bool reading_error;
|
||||
memcpy(&reading_error, cur_pos, sizeof(reading_error));
|
||||
item->b_error_when_reading = reading_error;
|
||||
cur_pos += sizeof(reading_error);
|
||||
}
|
||||
|
||||
/* get b_preparse_depth */
|
||||
{
|
||||
BOUNDARY_CHECK(sizeof(int));
|
||||
int i_preparse_depth;
|
||||
memcpy(&i_preparse_depth, cur_pos, sizeof(item->i_preparse_depth));
|
||||
item->i_preparse_depth = i_preparse_depth;
|
||||
cur_pos += sizeof(i_preparse_depth);
|
||||
}
|
||||
|
||||
return VLC_SUCCESS;
|
||||
|
||||
error:
|
||||
for (int i = 0; i < item->i_es; ++i) {
|
||||
es_format_t *const format = item->es[i];
|
||||
es_format_Clean(format);
|
||||
}
|
||||
free(item->es);
|
||||
return VLC_ENOMEM;
|
||||
}
|
||||
|
||||
#undef BOUNDARY_CHECK
|
|
@ -0,0 +1,90 @@
|
|||
/*****************************************************************************
|
||||
* serialize.c
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2022 VLC authors and VideoLAN
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <vlc_common.h>
|
||||
#include <vlc_plugin.h>
|
||||
#include <vlc_serializer.h>
|
||||
|
||||
/***************************************************************************
|
||||
* Serializable types
|
||||
***************************************************************************/
|
||||
int serialize_es_format ( type_serializer_t * );
|
||||
int deserialize_es_format ( type_serializer_t * );
|
||||
int serialize_input_item ( type_serializer_t * );
|
||||
int deserialize_input_item( type_serializer_t * );
|
||||
int serialize_attachment ( type_serializer_t * );
|
||||
int deserialize_attachment( type_serializer_t * );
|
||||
|
||||
static int SetInputItemSerializer( vlc_object_t *p_this )
|
||||
{
|
||||
type_serializer_t *serialize = (type_serializer_t *)p_this;
|
||||
|
||||
serialize->pf_serialize = serialize_input_item;
|
||||
serialize->pf_deserialize = deserialize_input_item;
|
||||
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
static int SetEsFormatSerializer( vlc_object_t *p_this )
|
||||
{
|
||||
type_serializer_t *serialize = (type_serializer_t *)p_this;
|
||||
|
||||
serialize->pf_serialize = serialize_es_format;
|
||||
serialize->pf_deserialize = deserialize_es_format;
|
||||
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
static int SetAttachmentSerializer( vlc_object_t *p_this )
|
||||
{
|
||||
type_serializer_t *serialize = (type_serializer_t *)p_this;
|
||||
|
||||
serialize->pf_serialize = serialize_attachment;
|
||||
serialize->pf_deserialize = deserialize_attachment;
|
||||
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
vlc_module_begin()
|
||||
set_subcategory( SUBCAT_ADVANCED_MISC )
|
||||
|
||||
add_submodule()
|
||||
set_description( N_("es_format_t serializer") )
|
||||
add_shortcut( "serialize-es" )
|
||||
set_capability( "serialize type", 0 )
|
||||
set_callback( SetEsFormatSerializer )
|
||||
|
||||
add_submodule()
|
||||
set_description( N_("input_item_t serializer") )
|
||||
add_shortcut( "serialize-item" )
|
||||
set_capability( "serialize type", 0 )
|
||||
set_callback( SetInputItemSerializer )
|
||||
|
||||
add_submodule()
|
||||
set_description( N_("input_attachment_t serializer") )
|
||||
add_shortcut( "serialize-attachment" )
|
||||
set_capability( "serialize type", 0 )
|
||||
set_callback( SetAttachmentSerializer )
|
||||
|
||||
vlc_module_end()
|
Loading…
Reference in New Issue