Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/VLC/modules/misc/preparser_serializer/json/   (VLC Media Plyer ©)  Datei vom 23.9.2026 mit Größe 38 kB image not shown  

Quelle  tojson.c   Sprache: C

 

// SPDX-License-Identifier: LGPL-2.1-or-later
/*****************************************************************************
 * tojson.c: write json from vlc struct
 *****************************************************************************
 * Copyright © 2025 Videolabs, VideoLAN and VLC authors
 *
 * Authors: Gabriel Lafond Thenaille <gabriel@videolabs.io>
 *****************************************************************************/


#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <vlc_common.h>
#include <vlc_charset.h>
#include <vlc_es.h>
#include <vlc_input_item.h>
#include <vlc_strings.h>
#include <vlc_preparser_ipc.h>
#include <vlc_vector.h>

#include <float.h>
#include <stdckdint.h>

#include "serializer.h"

/****************************************************************************
 * Stringify functions
 */


/* Write in the memstream `character` value in utf notation. */
static inline void json_stringify_utf8char(struct serdes_sys *sys,
                                           uint32_t character)
{
    assert(sys != NULL);

    /* If the character is in the Basic Multilingual Plane (U+0000 through
     * U+FFFF), then it may be represented as a six-character sequence:
     * \uxxxx */

    if (character < 0x10000)
    {
        if (serdes_buf_printf(sys, "\\u%04x", character) < 0) {
            return;
        }
    }
    /* To escape an extended character that is not in the Basic Multilingual
     * Plane, the character is represented as a 12-character sequence, encoding
     * the UTF-16 surrogate pair. */


    else if (0x10000 <= character && character <= 0x10FFFF) {
        unsigned int code;
        uint16_t units[2];

        code = (character - 0x10000);
        units[0] = 0xD800 | (code >> 10);
        units[1] = 0xDC00 | (code & 0x3FF);

        if (serdes_buf_printf(sys, "\\u%04x\\u%04x", units[0], units[1]) < 0) {
            return;
        }
    }
}

/* Write in the memstream a string. If is not encoded in utf8 write 'null'
 * instead.
 * `str` mustn't be null.*/

static inline void json_stringify_utf8string(struct serdes_sys *sys,
                                             const char *str)
{
    assert(sys != NULL);
    assert(str != NULL);

    if (!IsUTF8(str)) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }

    if (serdes_buf_putc(sys, '\"') < 0) {
        return;
    }

    unsigned char byte;
    while (*str != '\0') {
        switch (*str) {
            case '\b':
                if (serdes_buf_write(sys, "\\b", 2) < 0) {
                    return;
                }
                break;
            case '\f':
                if (serdes_buf_write(sys, "\\f", 2) < 0) {
                    return;
                }
                break;
            case '\n':
                if (serdes_buf_write(sys, "\\n", 2) < 0) {
                    return;
                }
                break;
            case '\r':
                if (serdes_buf_write(sys, "\\r", 2) < 0) {
                    return;
                }
                break;
            case '\t':
                if (serdes_buf_write(sys, "\\t", 2) < 0) {
                    return;
                }
                break;
            case '\\':
                if (serdes_buf_write(sys, "\\\\", 2) < 0) {
                    return;
                }
                break;
            case '\"':
                if (serdes_buf_write(sys, "\\\"", 2) < 0) {
                    return;
                }
                break;
            default:
                byte = *str;
                if (byte <= 0x1F || byte == 0x7F) {
                    if (serdes_buf_printf(sys, "\\u%04x", byte) < 0) {
                        return;
                    }
                }
                else if (byte < 0x80) {
                    if (serdes_buf_putc(sys, byte) < 0) {
                        return;
                    }
                }
                else {
                    uint32_t bytes;
                    ssize_t len = vlc_towc(str, &bytes);
                    assert(len > 0);
                    json_stringify_utf8char(sys, bytes);
                    str += len - 1;
                }
        }
        str++;
    }

    if (serdes_buf_putc(sys, '\"') < 0) {
        return;
    }
}

static inline void json_stringify_double(struct serdes_sys *sys,
                                         double number)
{
    assert(sys != NULL);

    if (serdes_buf_printf(sys, "%.*g", DBL_DECIMAL_DIG, number) < 0) {
        return;
    }
}

static inline void json_stringify_int64(struct serdes_sys *sys,
                                        int64_t number)
{
    assert(sys != NULL);

    if (number > (1LL << 53) - 1 || number < -((1LL << 53) - 1)) {
        if (serdes_buf_printf(sys, "\"%" PRId64 "\"", number) < 0) {
            return;
        }
    } else {
        if (serdes_buf_printf(sys, "%" PRId64, number) < 0) {
            return;
        }
    }
}

static inline void json_stringify_uint64(struct serdes_sys *sys,
                                        uint64_t number)
{
    assert(sys != NULL);

    if (number > (1LL << 53) - 1) {
        if (serdes_buf_printf(sys, "\"%" PRIu64 "\"", number) < 0) {
            return;
        }
    } else {
        if (serdes_buf_printf(sys, "%" PRIu64, number) < 0) {
            return;
        }
    }
}

#define json_stringify_number(sys, number) \
    _Generic(number,\
            int64_t: json_stringify_int64(sys, number),\
            uint64_t: json_stringify_uint64(sys, number),\
            default: json_stringify_double(sys, number))

static inline void json_stringify_string(struct serdes_sys *sys,
                                         const char *str)
{
    assert(sys != NULL);

    if (str != NULL) {
        json_stringify_utf8string(sys, str);
    } else {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
    }
}

static inline void json_stringify_boolean(struct serdes_sys *sys,
                                          bool boolean)
{
    assert(sys != NULL);

    if (serdes_buf_puts(sys, boolean ? "true" : "false") < 0) {
        return;
    }
}

/* The last argument is for using the function inside marco as the others. */
static inline void json_stringify_null(struct serdes_sys *sys, void *unused)
{
    assert(sys != NULL);

    VLC_UNUSED(unused);
    if (serdes_buf_puts(sys, "null") < 0) {
        return;
    }
}

static inline void json_stringify_fourcc(struct serdes_sys *sys,
                                         vlc_fourcc_t fourcc)
{
    char str[25];
    char *ptr = str;
    char f[5];
    vlc_fourcc_to_char(fourcc, f);
    for (size_t i = 0; i < 4; i++) {
        if (f[i] < 0x20 || f[i] >= 0x7f) {
            int ret = sprintf(ptr, "\\\\x%02" PRIx8, f[i]);
            ptr += ret;
        } else {
            *ptr++ = f[i];
        }
    }
    *ptr = '\0';
    if (serdes_buf_printf(sys, "\"%s\"", str) < 0) {
        return;
    }
}

/****************************************************************************
 * Macro declaration
 */


#define json_stringify_first(type, sys, name, var) \
    do { \
        if (serdes_buf_putc(sys, '{') < 0) { \
            return;\
        }\
     json_stringify_utf8string(sys, name); \
        if (serdes_buf_puts(sys, ": ") < 0) { \
            return;\
        }\
        json_stringify_##type(sys, var); \
        if (serdes_buf_puts(sys, ", ") < 0) { \
            return;\
        }\
    } while (0)

#define json_stringify(type, sys, name, var) \
    do { \
        json_stringify_utf8string(sys, name); \
        if (serdes_buf_puts(sys, ": ") < 0) { \
            return;\
        }\
        json_stringify_##type(sys, var); \
        if (serdes_buf_puts(sys, ", ") < 0) { \
            return;\
        }\
    } while (0)

#define json_stringify_last(type, sys, name, var) \
    do { \
        json_stringify_utf8string(sys, name); \
        if (serdes_buf_puts(sys, ": ") < 0) { \
            return;\
        }\
        json_stringify_##type(sys, var); \
        if (serdes_buf_putc(sys, '}') < 0) { \
            return;\
        }\
    } while (0)

#define json_stringify_array(func, size, sys, name, array) \
    do { \
        if ((name) != NULL) {\
            json_stringify_utf8string(sys, name); \
            if (serdes_buf_puts(sys, ": ") < 0) { \
                return;\
            }\
        }\
        if (serdes_buf_putc(sys, '[') < 0) { \
            return;\
        }\
        if ((size) > 0) { \
            (func)(sys, &(array)[0], NULL); \
            for (size_t _i = 1; _i < (size); _i++) { \
                if (serdes_buf_puts(sys, ", ") < 0) {\
                    return;\
                }\
                (func)(sys, &(array)[_i], NULL); \
            }\
        } \
        if (serdes_buf_putc(sys, ']') < 0) { \
            return;\
        }\
    } while (0)

#define json_stringify_array_value(type, size, sys, name, array) \
    do { \
        if ((name) != NULL) {\
            json_stringify_utf8string(sys, name); \
            if (serdes_buf_puts(sys, ": ") < 0) { \
                return;\
            }\
        }\
        if (serdes_buf_putc(sys, '[') < 0) { \
            return;\
        }\
        if ((size) > 0) { \
            json_stringify_##type(sys, (array)[0]); \
            for (size_t _i = 1; _i < (size); _i++) { \
                if (serdes_buf_puts(sys, ", ") < 0) {\
                    return;\
                }\
                json_stringify_##type(sys, (array)[_i]); \
            }\
        } \
        if (serdes_buf_putc(sys, ']') < 0) { \
            return;\
        }\
    } while (0)

/****************************************************************************
 * tojson functions
 */


static void toJSON_extra_languages(struct serdes_sys *sys,
                                   const extra_languages_t *el,
                                   const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (el == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    json_stringify_first(string, sys, "psz_language", el->psz_language);
    json_stringify_last(string, sys, "psz_description", el->psz_description);
}

static void toJSON_audio_format(struct serdes_sys *sys,
                                const audio_format_t *a, const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (a == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    json_stringify_first(number, sys, "i_format", a->i_format);
    json_stringify(number, sys, "i_rate", a->i_rate);
    json_stringify(number, sys, "i_physical_channels", a->i_physical_channels);
    json_stringify(number, sys, "i_chan_mode", a->i_chan_mode);
    json_stringify(number, sys, "channel_type", a->channel_type);
    json_stringify(number, sys, "i_bytes_per_frame", a->i_bytes_per_frame);
    json_stringify(number, sys, "i_frame_length", a->i_frame_length);
    json_stringify(number, sys, "i_bitspersample", a->i_bitspersample);
    json_stringify(number, sys, "i_blockalign", a->i_blockalign);
    json_stringify_last(number, sys, "i_channels", a->i_channels);
}

static void toJSON_audio_replay_gain(struct serdes_sys *sys,
                                     const audio_replay_gain_t *ag,
                                     const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (ag == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    if (serdes_buf_putc(sys, '{') < 0) {
        return;
    }
    json_stringify_array_value(boolean, AUDIO_REPLAY_GAIN_MAX, sys, "pb_peak",
                               ag->pb_peak);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify_array_value(number, AUDIO_REPLAY_GAIN_MAX, sys, "pf_peak",
                               ag->pf_peak);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify_array_value(boolean, AUDIO_REPLAY_GAIN_MAX, sys, "pb_gain",
                               ag->pb_gain);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify_array_value(number, AUDIO_REPLAY_GAIN_MAX, sys, "pf_gain",
                               ag->pf_gain);
    if (serdes_buf_putc(sys, '}') < 0) {
        return;
    }
}

static void toJSON_video_palette(struct serdes_sys *sys,
                                 const video_palette_t *palette,
                                 const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (palette == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }

    json_stringify_first(number, sys, "i_entries", palette->i_entries);
    json_stringify_utf8string(sys, "palette");
    if (serdes_buf_puts(sys, ": [") < 0) {
        return;
    }
    int i = 0;
    if (i < VIDEO_PALETTE_COLORS_MAX) {
        json_stringify_array_value(number, 4, sys, NULL, palette->palette[i]);
        for (i = 1; i < VIDEO_PALETTE_COLORS_MAX; i++) {
            if (serdes_buf_puts(sys, ", ") < 0) {
                return;
            }
            json_stringify_array_value(number, 4, sys, NULL,
                                       palette->palette[i]);
        }
    }
    if (serdes_buf_puts(sys, "]}") < 0) {
        return;
    }
}

static void toJSON_video_format(struct serdes_sys *sys,
                                const video_format_t *video,
                                const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (video == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    json_stringify_first(fourcc, sys, "i_chroma", video->i_chroma);
    json_stringify(number, sys, "i_width", video->i_width);
    json_stringify(number, sys, "i_height", video->i_height);
    json_stringify(number, sys, "i_x_offset", video->i_x_offset);
    json_stringify(number, sys, "i_y_offset", video->i_y_offset);
    json_stringify(number, sys, "i_visible_width", video->i_visible_width);
    json_stringify(number, sys, "i_visible_height", video->i_visible_height);
    json_stringify(number, sys, "i_sar_num", video->i_sar_num);
    json_stringify(number, sys, "i_sar_den", video->i_sar_den);
    json_stringify(number, sys, "i_frame_rate", video->i_frame_rate);
    json_stringify(number, sys, "i_frame_rate_base", video->i_frame_rate_base);
    toJSON_video_palette(sys, video->p_palette, "p_palette");
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify(number, sys, "orientation", video->orientation);
    json_stringify(number, sys, "primaries", video->primaries);
    json_stringify(number, sys, "transfer", video->transfer);
    json_stringify(number, sys, "space", video->space);
    json_stringify(number, sys, "color_range", video->color_range);
    json_stringify(number, sys, "chroma_location", video->chroma_location);
    json_stringify(number, sys, "multiview_mode", video->multiview_mode);
    json_stringify(boolean, sys, "b_multiview_right_eye_first",
                   video->b_multiview_right_eye_first);
    json_stringify(number, sys, "projection_mode", video->projection_mode);

    /* vlc_viewpoint_t pose */
    json_stringify_utf8string(sys, "pose");
    if (serdes_buf_puts(sys, ": ") < 0) {
        return;
    }
    json_stringify_first(number, sys, "yaw", video->pose.yaw);
    json_stringify(number, sys, "pitch", video->pose.pitch);
    json_stringify(number, sys, "roll", video->pose.roll);
    json_stringify_last(number, sys, "fov", video->pose.fov);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }

    /* video->mastering */
    json_stringify_utf8string(sys, "mastering");
    if (serdes_buf_puts(sys, ": {") < 0) {
        return;
    }
    /* size: G,B,R / x,y */
    json_stringify_array_value(number, 3 * 2, sys, "primaries",
                               video->mastering.primaries);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    /* size: x,y */
    json_stringify_array_value(number, 2, sys, "white_point",
                               video->mastering.white_point);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify(number, sys, "max_luminance",
                   video->mastering.max_luminance);
    json_stringify_last(number, sys, "min_luminance",
                        video->mastering.min_luminance);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }

    /* video->lighting */
    json_stringify_utf8string(sys, "lighting");
    if (serdes_buf_puts(sys, ": ") < 0) {
        return;
    }
    json_stringify_first(number, sys, "MaxCLL", video->lighting.MaxCLL);
    json_stringify_last(number, sys, "MaxFALL", video->lighting.MaxFALL);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }

    /* video->dovi */
    json_stringify_utf8string(sys, "dovi");
    if (serdes_buf_puts(sys, ": ") < 0) {
        return;
    }
    json_stringify_first(number, sys, "version_major",
                         video->dovi.version_major);
    json_stringify(number, sys, "version_minor", video->dovi.version_minor);
    json_stringify(number, sys, "profile", video->dovi.profile);
    json_stringify(number, sys, "level", video->dovi.level);
    json_stringify(number, sys, "rpu_present", video->dovi.rpu_present);
    json_stringify(number, sys, "el_present", video->dovi.el_present);
    json_stringify_last(number, sys, "bl_present", video->dovi.bl_present);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }

    json_stringify_last(number, sys, "i_cubemap_padding",
                        video->i_cubemap_padding);
}

static void toJSON_subs_format(struct serdes_sys *sys,
                               const subs_format_t *subs, const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (subs == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    json_stringify_first(string, sys, "psz_encoding", subs->psz_encoding);
    json_stringify(number, sys, "i_x_origin", subs->i_x_origin);
    json_stringify(number, sys, "i_y_origin", subs->i_y_origin);

    /* subs->spu */
    json_stringify_utf8string(sys, "spu");
    if (serdes_buf_puts(sys, ": ") < 0) {
        return;
    }
    json_stringify_first(number, sys, "i_original_frame_width",
                         subs->spu.i_original_frame_width);
    json_stringify(number, sys, "i_original_frame_height",
                   subs->spu.i_original_frame_height);
    json_stringify_array_value(number, VIDEO_PALETTE_CLUT_COUNT, sys,
                               "palette", subs->spu.palette);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify_last(boolean, sys, "b_palette", subs->spu.b_palette);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }

    /* subs->dvb */
    json_stringify_utf8string(sys, "dvb");
    if (serdes_buf_puts(sys, ": {") < 0) {
        return;
    }
    json_stringify_last(number, sys, "i_id", subs->dvb.i_id);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }

    /* subs->teletext */
    json_stringify_utf8string(sys, "teletext");
    if (serdes_buf_puts(sys, ": ") < 0) {
        return;
    }
    json_stringify_first(number, sys, "i_magazine", subs->teletext.i_magazine);
    json_stringify_last(number, sys, "i_page", subs->teletext.i_page);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }

    /* subs->cc */
    json_stringify_utf8string(sys, "cc");
    if (serdes_buf_puts(sys, ": ") < 0) {
        return;
    }
    json_stringify_first(number, sys, "i_channel", subs->cc.i_channel);
    json_stringify_last(number, sys, "i_reorder_depth",
                        subs->cc.i_reorder_depth);

    if (serdes_buf_puts(sys, "}") < 0) {
        return;
    }
}

static void toJSON_es_format(struct serdes_sys *sys, const es_format_t *es,
                             const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (es == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    json_stringify_first(number, sys, "i_cat", es->i_cat);
    json_stringify(fourcc, sys, "i_codec", es->i_codec);
    json_stringify(fourcc, sys, "i_original_fourcc", es->i_original_fourcc);
    json_stringify(number, sys, "i_id", es->i_id);
    json_stringify(number, sys, "i_group", es->i_group);
    json_stringify(number, sys, "i_priority", es->i_priority);
    json_stringify(string, sys, "psz_language", es->psz_language);
    json_stringify(string, sys, "psz_description", es->psz_description);
    json_stringify(number, sys, "i_extra_languages", es->i_extra_languages);
    json_stringify_array(toJSON_extra_languages, es->i_extra_languages, sys,
                         "p_extra_languages", es->p_extra_languages);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }

    switch (es->i_cat) {
        case AUDIO_ES:
            toJSON_audio_format(sys, &es->audio, "audio");
            if (serdes_buf_puts(sys, ", ") < 0) {
                return;
            }
            toJSON_audio_replay_gain(sys, &es->audio_replay_gain,
                                     "audio_replay_gain");
            break;
        case VIDEO_ES:
            toJSON_video_format(sys, &es->video, "video");
            break;
        case SPU_ES:
            toJSON_subs_format(sys, &es->subs, "subs");
            break;
        default:
            break;
    }
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }

    json_stringify(number, sys, "i_bitrate", es->i_bitrate);
    json_stringify(number, sys, "i_profile", es->i_profile);
    json_stringify(number, sys, "i_level", es->i_level);
    json_stringify_last(boolean, sys, "b_packetized", es->b_packetized);
    //json_stringify_last(number, sys, "i_extra", es->i_extra);
    /* p_extra not sent */
}

static void toJSON_meta(struct serdes_sys *sys, const vlc_meta_t *meta,
                        const char *name)
{
#define stringify_meta(sys, meta, type) \
    do { \
        json_stringify_utf8string(sys, #type); \
        if (serdes_buf_puts(sys, ": ") < 0) {\
            return;\
        } \
        vlc_meta_priority_t p_##type = VLC_META_PRIORITY_BASIC; \
        const char *v_##type = vlc_meta_GetWithPriority(meta, vlc_meta_##type,\
                                                        &p_##type); \
        assert(p_##type >= VLC_META_PRIORITY_BASIC \
                && p_##type <= VLC_META_PRIORITY_INBAND); \
        json_stringify_first(string, sys, "value", v_##type); \
        json_stringify_last(number, sys, "priority", p_##type); \
        if (serdes_buf_puts(sys, ", ") < 0) {\
            return;\
        } \
    } while (0)

    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (meta == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    if (serdes_buf_putc(sys, '{') < 0) {
        return;
    }
    stringify_meta(sys, meta, Title);
    stringify_meta(sys, meta, Artist);
    stringify_meta(sys, meta, AlbumArtist);
    stringify_meta(sys, meta, Genre);
    stringify_meta(sys, meta, Copyright);
    stringify_meta(sys, meta, Album);
    stringify_meta(sys, meta, TrackNumber);
    stringify_meta(sys, meta, Description);
    stringify_meta(sys, meta, Rating);
    stringify_meta(sys, meta, Date);
    stringify_meta(sys, meta, Setting);
    stringify_meta(sys, meta, URL);
    stringify_meta(sys, meta, Language);
    stringify_meta(sys, meta, NowPlaying);
    stringify_meta(sys, meta, ESNowPlaying);
    stringify_meta(sys, meta, Publisher);
    stringify_meta(sys, meta, EncodedBy);
    stringify_meta(sys, meta, ArtworkURL);
    stringify_meta(sys, meta, TrackID);
    stringify_meta(sys, meta, TrackTotal);
    stringify_meta(sys, meta, Director);
    stringify_meta(sys, meta, Season);
    stringify_meta(sys, meta, Episode);
    stringify_meta(sys, meta, ShowName);
    stringify_meta(sys, meta, Actors);
    stringify_meta(sys, meta, DiscNumber);
    stringify_meta(sys, meta, DiscTotal);
    stringify_meta(sys, meta, Compilation);

#undef stringify_meta

    json_stringify_utf8string(sys, "extra_tags");
    if (serdes_buf_puts(sys, ": ") < 0) {
        return;
    }
    if (serdes_buf_putc(sys, '[') < 0) {
        return;
    }
    char **keys = vlc_meta_CopyExtraNames(meta);
    if (keys != NULL) {
        for (size_t i = 0; i < vlc_meta_GetExtraCount(meta); i++) {
            if (i != 0) {
                if (serdes_buf_puts(sys, ", ") < 0) {
                    return;
                }
            }
            vlc_meta_priority_t priority = VLC_META_PRIORITY_BASIC;
            const char *value = vlc_meta_GetExtraWithPriority(meta, keys[i],
                                                              &priority);
            assert(priority >= VLC_META_PRIORITY_BASIC
                    && priority <= VLC_META_PRIORITY_INBAND);
            json_stringify_first(string, sys, "key", keys[i]);
            json_stringify(string, sys, "value", value);
            json_stringify_last(number, sys, "priority", priority);
            free(keys[i]);
        }
        free(keys);
    }
    if (serdes_buf_puts(sys, "], ") < 0) {
        return;
    }
    json_stringify_last(number, sys, "i_status", vlc_meta_GetStatus(meta));
}

static void toJSON_input_item_es(struct serdes_sys *sys,
                                 const struct input_item_es *item_es,
                                 const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (item_es == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    if (serdes_buf_putc(sys, '{') < 0) {
        return;
    }
    toJSON_es_format(sys, &item_es->es, "es");
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify(string, sys, "id", item_es->id);
    json_stringify_last(boolean, sys, "id_stable", item_es->id_stable);
}

static void toJSON_input_item_slave(struct serdes_sys *sys,
                                    struct input_item_slave * const * slave,
                                    const char *name)
{
    assert(sys != NULL);
    assert(slave != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (*slave == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    json_stringify_first(number, sys, "i_type", (*slave)->i_type);
    json_stringify(number, sys, "i_priority", (*slave)->i_priority);
    json_stringify(boolean, sys, "b_forced", (*slave)->b_forced);
    json_stringify_last(string, sys, "psz_uri", (*slave)->psz_uri);
}

static inline void toJSON_input_item(struct serdes_sys *sys,
                                     const input_item_t *item,
                                     const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (item == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    json_stringify_first(string, sys, "psz_name", item->psz_name);
    json_stringify(string, sys, "psz_uri", item->psz_uri);
    json_stringify(number, sys, "i_duration", item->i_duration);
    json_stringify_array(toJSON_input_item_es, item->es_vec.size, sys,
                         "es_vec", item->es_vec.data);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    toJSON_meta(sys, item->p_meta, "p_meta");
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify(number, sys, "i_slaves", item->i_slaves);
    json_stringify_array(toJSON_input_item_slave, (size_t)item->i_slaves, sys,
                         "pp_slaves", item->pp_slaves);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify(number, sys, "i_type", item->i_type);
    json_stringify_last(boolean, sys, "b_net", item->b_net);
}

static inline void toJSON_input_item_node(struct serdes_sys *sys,
                                          input_item_node_t * const *n,
                                          const char *name)
{
    assert(sys != NULL);
    assert(n != NULL);
    const input_item_node_t *node = *n;

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (node == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    if (serdes_buf_putc(sys, '{') < 0) {
        return;
    }
    toJSON_input_item(sys, node->p_item, "p_item");
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify(number, sys, "i_children", node->i_children);
    json_stringify_array(toJSON_input_item_node, (size_t)node->i_children, sys,
                         "pp_children", node->pp_children);
    if (serdes_buf_putc(sys, '}') < 0) {
        return;
    }
}

static void toJSON_input_attachment(struct serdes_sys *sys,
                                    input_attachment_t * const *a,
                                    const char *name)
{
    assert(sys != NULL);
    assert(a != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (*a == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    json_stringify_first(string, sys, "psz_name", (*a)->psz_name);
    json_stringify(string, sys, "psz_mime", (*a)->psz_mime);
    json_stringify(string, sys, "psz_description", (*a)->psz_description);
    json_stringify(number, sys, "i_data", (*a)->i_data);
    if (sys->bin_data) {
        json_stringify_last(null, sys, "p_data", NULL);
        vlc_vector_push_all(&sys->attach_data , (*a)->p_data, (*a)->i_data);
    } else {
        char *b64 = vlc_b64_encode_binary((*a)->p_data, (*a)->i_data);
        json_stringify_last(string, sys, "p_data", b64);
        free(b64);
    }
}

static void toJSON_plane(struct serdes_sys *sys, const plane_t *plane,
                         const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (plane == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    if (sys->bin_data) {
        json_stringify_first(null, sys, "p_pixels", NULL);
        vlc_vector_push_all(&sys->attach_data, plane->p_pixels,
                            plane->i_pitch * plane->i_lines);
    } else {
        char *b64 = vlc_b64_encode_binary(plane->p_pixels,
                                          plane->i_pitch * plane->i_lines);
        json_stringify_first(string, sys, "p_pixels", b64);
        free(b64);
    }
    json_stringify(number, sys, "i_lines", plane->i_lines);
    json_stringify(number, sys, "i_pitch", plane->i_pitch);
    json_stringify(number, sys, "i_pixel_pitch", plane->i_pixel_pitch);
    json_stringify(number, sys, "i_visible_lines", plane->i_visible_lines);
    json_stringify_last(number, sys, "i_visible_pitch", plane->i_visible_pitch);
}

static void toJSON_picture(struct serdes_sys *sys, const picture_t *pic,
                           const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (pic == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    if (serdes_buf_putc(sys, '{') < 0) {
        return;
    }
    toJSON_video_format(sys, &pic->format, "format");
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify_array(toJSON_plane, (size_t)pic->i_planes, sys, "p", pic->p);
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify(number, sys, "i_planes", pic->i_planes);
    json_stringify(number, sys, "date", pic->date);
    json_stringify(boolean, sys, "b_force", pic->b_force);
    json_stringify(boolean, sys, "b_still", pic->b_still);
    json_stringify(boolean, sys, "b_progressive", pic->b_progressive);
    json_stringify(boolean, sys, "b_top_field_first", pic->b_top_field_first);
    json_stringify(boolean, sys, "b_multiview_left_eye",
                   pic->b_multiview_left_eye);
    json_stringify_last(number, sys, "i_nb_fields", pic->i_nb_fields);
}

static void
toJSON_vlc_thumbnailer_output(struct serdes_sys *sys,
                              const struct vlc_thumbnailer_output *output,
                              const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (output == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }
    json_stringify_first(number, sys, "format", output->format);
    json_stringify(number, sys, "width", output->width);
    json_stringify(number, sys, "height", output->height);
    json_stringify(boolean, sys, "crop", output->crop);
    json_stringify(string, sys, "file_path", output->file_path);
    json_stringify_last(number, sys, "creat_mode", output->creat_mode);
}

static void
toJSON_vlc_preparser_msg_req(struct serdes_sys *sys,
                             const struct vlc_preparser_msg_req *req,
                             const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (req == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }

    json_stringify_first(number, sys, "type", req->type);

    assert(req->type == VLC_PREPARSER_MSG_REQ_TYPE_PARSE ||
            req->type == VLC_PREPARSER_MSG_REQ_TYPE_THUMBNAIL ||
            req->type == VLC_PREPARSER_MSG_REQ_TYPE_THUMBNAIL_TO_FILES);

    if (req->type == VLC_PREPARSER_MSG_REQ_TYPE_PARSE) {
        json_stringify(number, sys, "options", req->options);
    } else {
        if (req->type == VLC_PREPARSER_MSG_REQ_TYPE_THUMBNAIL_TO_FILES) {
            json_stringify_array(toJSON_vlc_thumbnailer_output,
                                 req->outputs.size, sys, "outputs",
                                 req->outputs.data);
            if (serdes_buf_puts(sys, ", ") < 0) {
                return;
            }
        }
        json_stringify(number, sys, "seek.type", req->arg.seek.type);
        if (req->arg.seek.type == VLC_THUMBNAILER_SEEK_TIME) {
            json_stringify(number, sys, "seek.time", req->arg.seek.time);
        } else if (req->arg.seek.type == VLC_THUMBNAILER_SEEK_POS) {
            json_stringify(number, sys, "seek.pos", req->arg.seek.pos);
        } else if (req->arg.seek.type != VLC_THUMBNAILER_SEEK_NONE) {
            vlc_assert_unreachable();
        }
        json_stringify(number, sys, "seek.speed", req->arg.seek.speed);
        json_stringify(boolean, sys, "hw_dec", req->arg.hw_dec);
    }

    json_stringify_last(string, sys, "uri", req->uri);
}

/*
 * TODO: use more json_stringify_array if possible and add to toJSON_* functions
 * name and possible null.
 */

static void
toJSON_vlc_preparser_msg_res(struct serdes_sys *sys,
                             const struct vlc_preparser_msg_res *res,
                             const char *name)
{
    assert(sys != NULL);

    if (name != NULL) {
        json_stringify_utf8string(sys, name);
        if (serdes_buf_puts(sys, ": ") < 0) {
            return;
        }
    }
    if (res == NULL) {
        if (serdes_buf_puts(sys, "null") < 0) {
            return;
        }
        return;
    }

    json_stringify_first(number, sys, "type", res->type);
    switch (res->type) {
        case VLC_PREPARSER_MSG_REQ_TYPE_PARSE:
            json_stringify_array(toJSON_input_attachment, res->attachments.size,
                    sys, "attachments", res->attachments.data);
            if (serdes_buf_puts(sys, ", ") < 0) {
                return;
            }
            toJSON_input_item_node(sys, &res->subtree, "subtree");
            break;
        case VLC_PREPARSER_MSG_REQ_TYPE_THUMBNAIL:
            toJSON_picture(sys, res->pic, "pic");
            break;
        case VLC_PREPARSER_MSG_REQ_TYPE_THUMBNAIL_TO_FILES:
            json_stringify_array_value(boolean, res->result.size, sys, "result",
                    res->result.data);
            break;
        default:
            vlc_assert_unreachable();
    }
    if (serdes_buf_puts(sys, ", ") < 0) {
        return;
    }
    json_stringify(number, sys, "status", res->status);
    toJSON_input_item(sys, res->item, "item");
    if (serdes_buf_puts(sys, "}") < 0) {
        return;
    }
}

void
toJSON_vlc_preparser_msg(struct serdes_sys *sys,
                         const struct vlc_preparser_msg *msg)
{
    assert(sys != NULL);
    assert(msg != NULL);

    json_stringify_first(number, sys, "type", msg->type);
    json_stringify(number, sys, "req_type", msg->req_type);

    if (msg->type == VLC_PREPARSER_MSG_TYPE_REQ) {
        toJSON_vlc_preparser_msg_req(sys, &msg->req, "req");
    } else if (msg->type == VLC_PREPARSER_MSG_TYPE_RES) {
        toJSON_vlc_preparser_msg_res(sys, &msg->res, "res");
    } else {
        vlc_assert_unreachable();
    }
    if (serdes_buf_puts(sys, "}") < 0) {
        return;
    }
}

#undef json_stringify_first
#undef json_stringify
#undef json_stringify_last
#undef json_stringify_array
#undef json_stringify_array_value

Messung
CHZG
83979993

¤ Dauer der Verarbeitung: 0.8 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.