Merge branch 'type_serializer' into 'master'

Draft: type serialization module

See merge request videolan/vlc!2979
This commit is contained in:
Louis Régnier 2024-04-28 09:23:26 +00:00
commit d8f13a3e22
6 changed files with 865 additions and 0 deletions

58
include/vlc_serializer.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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()