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

Quelle  rtp-rawvid.c   Sprache: C

 

/*****************************************************************************
 * rtp-rawvid.c: RTP raw video decoder
 *****************************************************************************
 * Copyright (C) 2022 Rémi Denis-Courmont
 *
 * 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 <assert.h>
#include <errno.h>
#include <stdbit.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_codec.h>

#define PLANES_3(bits) \
    uint##bits##_t *restrict p0 = planes[0]; \
    uint##bits##_t *restrict p1 = planes[1]; \
    uint##bits##_t *restrict p2 = planes[2]; \
    (void)0

#define PLANES_4(bits) \
    uint##bits##_t *restrict p0 = planes[0]; \
    uint##bits##_t *restrict p1 = planes[1]; \
    uint##bits##_t *restrict p2 = planes[2]; \
    uint##bits##_t *restrict p3 = planes[3]; \
    (void)0

/* Read one 8-bit sample from one octet */
#define READ_8(a) \
    uint_fast8_t a; \
\
    do { \
        a = *(in++); \
        len--; \
    } while (0)

/* Read four 10-bit samples from five octets. */
#define READ_10(a, b, c, d) \
    uint_fast16_t a, b, c, d; \
\
    do { \
        uint_fast8_t b0_ = in[0]; \
        uint_fast8_t b1_ = in[1]; \
        uint_fast8_t b2_ = in[2]; \
        uint_fast8_t b3_ = in[3]; \
        uint_fast8_t b4_ = in[4]; \
\
        a =  (b0_ << 2) | (b1_ >> 6); \
        b = ((b1_ << 4) | (b2_ >> 4)) & 0x3ff; \
        c = ((b2_ << 6) | (b3_ >> 2)) & 0x3ff; \
        d = ((b3_ << 8) | (b4_ >> 0)) & 0x3ff; \
        in += 5; \
        len -= 5; \
    } while (0)

/* Read two 12-bit samples from three octets. */
#define READ_12(a, b) \
    uint_fast16_t a, b; \
\
    do { \
        uint_fast8_t b0_ = in[0]; \
        uint_fast8_t b1_ = in[1]; \
        uint_fast8_t b2_ = in[2]; \
\
        a =  (b0_ << 4) | (b1_ >> 4); \
        b = ((b1_ << 4) | (b2_ >> 0)) & 0xfff; \
        in += 3; \
        len -= 3; \
    } while (0)


/* Read one 16-bit sample from two octets */
#define READ_16(a) \
    uint_fast16_t a; \
\
    do { \
        a = GetWBE(in); \
        in += 2; \
        len -= 2; \
    } while (0)

#define WRITE_RGB(n) \
    do { \
        *(p0++) = g##n; \
        *(p1++) = b##n; \
        *(p2++) = r##n; \
    } while (0)

#define WRITE_RGBA(n) \
    do { \
        *(p0++) = g##n; \
        *(p1++) = b##n; \
        *(p2++) = r##n; \
        *(p3++) = a##n; \
    } while (0)

#define WRITE_YUV444(n) \
    do { \
        *(p0++) = y##n; \
        *(p1++) = u##n; \
        *(p2++) = v##n; \
    } while (0)

#define WRITE_YUV422(n) \
    do { \
        *(p0++) = y0##n; \
        *(p0++) = y1##n; \
        *(p1++) = u##n; \
        *(p2++) = v##n; \
    } while (0)

#define WRITE_YUV420(n) \
    do { \
        *(p0++) = y00##n; \
        *(p0++) = y01##n; \
        *(p3++) = y10##n; \
        *(p3++) = y11##n; \
        *(p1++) = u##n; \
        *(p2++) = v##n; \
    } while (0)

#define WRITE_YUV411(n) \
    do { \
        *(p0++) = y0##n; \
        *(p0++) = y1##n; \
        *(p0++) = y2##n; \
        *(p0++) = y3##n; \
        *(p1++) = u##n; \
        *(p2++) = v##n; \
    } while (0)

static void decode_rgb_8(void *restrict *restrict planes,
                         const unsigned char *restrict in, size_t len)
{
    PLANES_3(8);

    while (len > 0) {
        READ_8(r0);
        READ_8(g0);
        READ_8(b0);
        WRITE_RGB(0);
    }
}

static void decode_rgb_10(void *restrict *restrict planes,
                          const unsigned char *restrict in, size_t len)
{
    PLANES_3(16);

    while (len > 0) {
        READ_10(r0, g0, b0, r1);
        READ_10(g1, b1, r2, g2);
        READ_10(b2, r3, b3, g3);
        WRITE_RGB(0);
        WRITE_RGB(1);
        WRITE_RGB(2);
        WRITE_RGB(3);
    }
}

static void decode_rgb_12(void *restrict *restrict planes,
                          const unsigned char *restrict in, size_t len)
{
    PLANES_3(16);

    while (len > 0) {
        READ_12(r0, g0);
        READ_12(b0, r1);
        READ_12(g1, b1);
        WRITE_RGB(0);
        WRITE_RGB(1);
    }
}

static void decode_rgb_16(void *restrict *restrict planes,
                          const unsigned char *restrict in, size_t len)
{
    PLANES_3(16);

    while (len > 0) {
        READ_16(r0);
        READ_16(g0);
        READ_16(b0);
        WRITE_RGB(0);
    }
}

static void decode_rgba_8(void *restrict *restrict planes,
                          const unsigned char *restrict in, size_t len)
{
    PLANES_4(8);

    while (len > 0) {
        READ_8(r0);
        READ_8(g0);
        READ_8(b0);
        READ_8(a0);
        WRITE_RGBA(0);
    }
}

static void decode_rgba_10(void *restrict *restrict planes,
                           const unsigned char *restrict in, size_t len)
{
    PLANES_4(16);

    while (len > 0) {
        READ_10(r0, g0, b0, a0);
        WRITE_RGBA(0);
    }
}

static void decode_rgba_12(void *restrict *restrict planes,
                           const unsigned char *restrict in, size_t len)
{
    PLANES_4(16);

    while (len > 0) {
        READ_12(r0, g0);
        READ_12(b0, a0);
        WRITE_RGBA(0);
    }
}

static void decode_rgba_16(void *restrict *restrict planes,
                           const unsigned char *restrict in, size_t len)
{
    PLANES_4(16);

    while (len > 0) {
        READ_16(r0);
        READ_16(g0);
        READ_16(b0);
        READ_16(a0);
        WRITE_RGBA(0);
    }
}

static void decode_bgr_8(void *restrict *restrict planes,
                         const unsigned char *restrict in, size_t len)
{
    PLANES_3(8);

    while (len > 0) {
        READ_8(b0);
        READ_8(g0);
        READ_8(r0);
        WRITE_RGB(0);
    }
}

static void decode_bgr_10(void *restrict *restrict planes,
                          const unsigned char *restrict in, size_t len)
{
    PLANES_3(16);

    while (len > 0) {
        READ_10(b0, g0, r0, b1);
        READ_10(g1, r1, b2, g2);
        READ_10(r2, b3, g3, r3);
        WRITE_RGB(0);
        WRITE_RGB(1);
        WRITE_RGB(2);
        WRITE_RGB(3);
    }
}

static void decode_bgr_12(void *restrict *restrict planes,
                          const unsigned char *restrict in, size_t len)
{
    PLANES_3(16);

    while (len > 0) {
        READ_12(b0, g0);
        READ_12(r0, b1);
        READ_12(g1, r1);
        WRITE_RGB(0);
        WRITE_RGB(1);
    }
}

static void decode_bgr_16(void *restrict *restrict planes,
                          const unsigned char *restrict in, size_t len)
{
    PLANES_3(16);

    while (len > 0) {
        READ_16(b0);
        READ_16(g0);
        READ_16(r0);
        WRITE_RGB(0);
    }
}

static void decode_bgra_8(void *restrict *restrict planes,
                          const unsigned char *restrict in, size_t len)
{
    PLANES_4(8);

    while (len > 0) {
        READ_8(b0);
        READ_8(g0);
        READ_8(r0);
        READ_8(a0);
        WRITE_RGBA(0);
    }
}

static void decode_bgra_10(void *restrict *restrict planes,
                           const unsigned char *restrict in, size_t len)
{
    PLANES_4(16);

    while (len > 0) {
        READ_10(b0, g0, r0, a0);
        WRITE_RGBA(0);
    }
}

static void decode_bgra_12(void *restrict *restrict planes,
                           const unsigned char *restrict in, size_t len)
{
    PLANES_4(16);

    while (len > 0) {
        READ_12(b0, g0);
        READ_12(r0, a0);
        WRITE_RGBA(0);
    }
}

static void decode_bgra_16(void *restrict *restrict planes,
                           const unsigned char *restrict in, size_t len)
{
    PLANES_4(16);

    while (len > 0) {
        READ_16(b0);
        READ_16(g0);
        READ_16(r0);
        READ_16(a0);
        WRITE_RGBA(0);
    }
}

static void decode_yuv444_8(void *restrict *restrict planes,
                            const unsigned char *restrict in, size_t len)
{
    PLANES_3(8);

    while (len > 0) {
        READ_8(u0);
        READ_8(y0);
        READ_8(v0);
        WRITE_YUV444(0);
    }
}

static void decode_yuv444_10(void *restrict *restrict planes,
                             const unsigned char *restrict in, size_t len)
{
    PLANES_3(16);

    while (len > 0) {
        READ_10(u0, y0, v0, u1);
        READ_10(y1, v1, u2, y2);
        READ_10(v2, u3, y3, v3);
        WRITE_YUV444(0);
        WRITE_YUV444(1);
        WRITE_YUV444(2);
        WRITE_YUV444(3);
    }
}

static void decode_yuv444_12(void *restrict *restrict planes,
                             const unsigned char *restrict in, size_t len)
{
    PLANES_3(16);

    while (len > 0) {
        READ_12(u0, y0);
        READ_12(v0, u1);
        READ_12(y1, v1);
        WRITE_YUV444(0);
        WRITE_YUV444(1);
    }
}

static void decode_yuv444_16(void *restrict *restrict planes,
                             const unsigned char *restrict in, size_t len)
{
    PLANES_3(16);

    while (len > 0) {
        READ_16(u0);
        READ_16(y0);
        READ_16(v0);
        WRITE_YUV444(0);
    }
}

static void decode_yuv422_8(void *restrict *restrict planes,
                            const unsigned char *restrict in, size_t len)
{
    PLANES_3(8);

    while (len > 0) {
        READ_8(u0);
        READ_8(y00);
        READ_8(v0);
        READ_8(y10);
        WRITE_YUV422(0);
    }
}

static void decode_yuv422_10(void *restrict *restrict planes,
                             const unsigned char *restrict in, size_t len)
{
    PLANES_3(16);

    while (len > 0) {
        READ_10(u0, y00, v0, y10);
        WRITE_YUV422(0);
    }
}

static void decode_yuv422_12(void *restrict *restrict planes,
                             const unsigned char *restrict in, size_t len)
{
    PLANES_3(16);

    while (len > 0) {
        READ_12(u0, y00);
        READ_12(v0, y10);
        WRITE_YUV422(0);
    }
}

static void decode_yuv422_16(void *restrict *restrict planes,
                             const unsigned char *restrict in, size_t len)
{
    PLANES_3(16);

    while (len > 0) {
        READ_16(u0);
        READ_16(y00);
        READ_16(v0);
        READ_16(y10);
        WRITE_YUV422(0);
    }
}

static void decode_yuv420_8(void *restrict *restrict planes,
                            const unsigned char *restrict in, size_t len)
{
    PLANES_4(8);

    while (len > 0) {
        READ_8(y000);
        READ_8(y010);
        READ_8(y100);
        READ_8(y110);
        READ_8(u0);
        READ_8(v0);
        WRITE_YUV420(0);
    }
}

static void decode_yuv420_10(void *restrict *restrict planes,
                             const unsigned char *restrict in, size_t len)
{
    PLANES_4(16);

    while (len > 0) {
        READ_10(y000, y010, y100, y110);
        READ_10(u0, v0, y001, y011);
        READ_10(y101, y111, u1, v1);
        WRITE_YUV420(0);
        WRITE_YUV420(1);
    }
}

static void decode_yuv420_12(void *restrict *restrict planes,
                             const unsigned char *restrict in, size_t len)
{
    PLANES_4(16);

    while (len > 0) {
        READ_12(y000, y010);
        READ_12(y100, y110);
        READ_12(u0, v0);
        WRITE_YUV420(0);
    }
}

static void decode_yuv420_16(void *restrict *restrict planes,
                             const unsigned char *restrict in, size_t len)
{
    PLANES_4(16);

    while (len > 0) {
        READ_16(y000);
        READ_16(y010);
        READ_16(y100);
        READ_16(y110);
        READ_16(u0);
        READ_16(v0);
        WRITE_YUV420(0);
    }
}

static void decode_yuv411_8(void *restrict *restrict planes,
                            const unsigned char *restrict in, size_t len)
{
    PLANES_3(8);

    while (len > 0) {
        READ_8(u0);
        READ_8(y00);
        READ_8(y10);
        READ_8(v0);
        READ_8(y20);
        READ_8(y30);
        WRITE_YUV411(0);
    }
}

typedef void (*vlc_rtp_video_raw_cb)(void *restrict * restrict,
                                     const unsigned char * restrict, size_t);

struct vlc_rtp_video_raw_dec {
    unsigned int pgroup;
    bool half_height_uv;
    vlc_rtp_video_raw_cb decode_line;
    picture_t *pic;
};

static int Decode(decoder_t *dec, vlc_frame_t *block)
{
    struct vlc_rtp_video_raw_dec *sys = dec->p_sys;
    picture_t *pic = sys->pic;
    bool continuation;

    if (block == NULL) {
        /* Draining */
        if (pic != NULL) /* Send incomplete picture */
            decoder_QueueVideo(dec, pic);
        sys->pic = NULL;
        return VLCDEC_SUCCESS;
    }

    if ((block->i_flags & VLC_FRAME_FLAG_DISCONTINUITY)
     && pic != NULL && pic->date != block->i_pts) {
        /* Ideally, the EOS is set on the last block for a picture.
         * This manual check is necessary to deal with packet loss. */

        decoder_QueueVideo(dec, pic);
        pic = sys->pic = NULL;
    }

    if (pic == NULL) {
        pic = decoder_NewPicture(dec);

        if (pic == NULL) {
            block_Release(block);
            return VLCDEC_SUCCESS;
        }

        pic->date = block->i_pts;
        pic->b_progressive = true; /* TODO: interlacing */
        sys->pic = pic;
    }

    const unsigned char *in = block->p_buffer;
    size_t inlen = block->i_buffer;
    const unsigned int width = dec->fmt_out.video.i_width;
    const unsigned int height = dec->fmt_out.video.i_height;

    do {
        if (unlikely(inlen < 6)) {
corrupt:    msg_Err(dec, "corrupt packet, %zu bytes remaining", inlen);
            break;
        }

        uint_fast16_t length = GetWBE(in);
        uint_fast16_t lineno = GetWBE(in + 2);
        uint_fast16_t offset = GetWBE(in + 4);

        lineno &= 0x7fff; /* TODO: interlacing */
        continuation = (offset & 0x8000) != 0;
        offset &= 0x7fff;

        in += 6;
        inlen -= 6;

        div_t d = div(length, sys->pgroup);

        if (inlen < length /* input buffer underflow */
         || d.rem != 0 /* length must be a multiple of pgroup size */
         || offset + d.quot >= width /* output scanline overflow */
         || lineno >= height /* output picture overflow */)
            goto corrupt;

        void *restrict planes[4];

        if (sys->half_height_uv) {
            /* For I420, treat the odd Y lines as the 4th plane */
            if (unlikely(lineno & 1))
                goto corrupt; /* line number must always be even */

            assert(pic->i_planes <= 3);
            planes[0] = pic->p[0].p_pixels + lineno * pic->p[0].i_pitch
                                           + offset * pic->p[0].i_pixel_pitch;
            planes[3] = ((unsigned char *)planes[0]) + pic->p[0].i_pitch;
            lineno /= 2;

            for (int i = 1; i < pic->i_planes; i++) {
                plane_t *p = &pic->p[i];

                planes[i] = p->p_pixels + lineno * p->i_pitch
                                        + offset * p->i_pixel_pitch;
            }
        } else {
            for (int i = 0; i < pic->i_planes; i++) {
                plane_t *p = &pic->p[i];

                planes[i] = p->p_pixels + lineno * p->i_pitch
                                        + offset * p->i_pixel_pitch;
            }
        }

        sys->decode_line(planes, in, length);
    } while (continuation);

    if (block->i_flags & VLC_FRAME_FLAG_END_OF_SEQUENCE) {
        decoder_QueueVideo(dec, pic);
        sys->pic = NULL;
    }

    block_Release(block);
    return VLCDEC_SUCCESS;
}

static void Close(vlc_object_t *obj)
{
    decoder_t *dec = (decoder_t *)obj;
    struct vlc_rtp_video_raw_dec *sys = dec->p_sys;

    if (sys->pic != NULL)
        picture_Release(sys->pic);
}

struct vlc_rtp_video_raw_format {
    vlc_fourcc_t fourcc;
    vlc_rtp_video_raw_cb line_cb;
};

/**
 * RTP video/raw sampling
 *
 * This defines the list of all supported (per component) bit depths.
 */

struct vlc_rtp_video_raw_sampling {
    struct vlc_rtp_video_raw_format depth8;
    struct vlc_rtp_video_raw_format depth10;
    struct vlc_rtp_video_raw_format depth12;
    struct vlc_rtp_video_raw_format depth16;
};

/**
 * RTP video/raw samplings
 *
 * This type defines the list of all support RTP video/raw samplings.
 * \note This is purposedly a structure rather than an array so that CPU
 * optimisations can readily cherry-pick which samplings to optimise.
 */

struct vlc_rtp_video_raw_samplings {
    struct vlc_rtp_video_raw_sampling rgb;
    struct vlc_rtp_video_raw_sampling rgba;
    struct vlc_rtp_video_raw_sampling bgr;
    struct vlc_rtp_video_raw_sampling bgra;
    struct vlc_rtp_video_raw_sampling yuv444;
    struct vlc_rtp_video_raw_sampling yuv422;
    struct vlc_rtp_video_raw_sampling yuv420;
    struct vlc_rtp_video_raw_sampling yuv411;
};

#ifdef WORDS_BIGENDIAN
#define NE(x) x##B
#else
#define NE(x) x##L
#endif

static const struct vlc_rtp_video_raw_samplings samplings = {
    .rgb = {
        {    VLC_CODEC_GBR_PLANAR,     decode_rgb_8,  },
        { NE(VLC_CODEC_GBR_PLANAR_10), decode_rgb_10, },
        { NE(VLC_CODEC_GBR_PLANAR_12), decode_rgb_12, },
        { NE(VLC_CODEC_GBR_PLANAR_16), decode_rgb_16, },
    },
    .rgba = {
        {    VLC_CODEC_GBR_PLANAR,     decode_rgba_8,  },
        { NE(VLC_CODEC_GBR_PLANAR_10), decode_rgba_10, },
        { NE(VLC_CODEC_GBR_PLANAR_12), decode_rgba_12, },
        { NE(VLC_CODEC_GBR_PLANAR_16), decode_rgba_16, },
    },
    .bgr = {
        {    VLC_CODEC_GBR_PLANAR,     decode_bgr_8,  },
        { NE(VLC_CODEC_GBR_PLANAR_10), decode_bgr_10, },
        { NE(VLC_CODEC_GBR_PLANAR_12), decode_bgr_12, },
        { NE(VLC_CODEC_GBR_PLANAR_16), decode_bgr_16, },
    },
    .bgra = {
        {    VLC_CODEC_GBR_PLANAR,     decode_bgra_8,  },
        { NE(VLC_CODEC_GBR_PLANAR_10), decode_bgra_10, },
        { NE(VLC_CODEC_GBR_PLANAR_12), decode_bgra_12, },
        { NE(VLC_CODEC_GBR_PLANAR_16), decode_bgra_16, },
    },
    .yuv444 = {
        {    VLC_CODEC_I444,           decode_yuv444_8,  },
        { NE(VLC_CODEC_I444_10),       decode_yuv444_10, },
        { NE(VLC_CODEC_I444_12),       decode_yuv444_12, },
        { NE(VLC_CODEC_I444_16),       decode_yuv444_16, },
    },
    .yuv422 = {
        {    VLC_CODEC_I422,           decode_yuv422_8,  },
        { NE(VLC_CODEC_I422_10),       decode_yuv422_10, },
        { NE(VLC_CODEC_I422_12),       decode_yuv422_12, },
        { NE(VLC_CODEC_I422_16),       decode_yuv422_16, },
    },
    .yuv420 = {
        {    VLC_CODEC_I420,           decode_yuv420_8,  },
        { NE(VLC_CODEC_I420_10),       decode_yuv420_10, },
        { NE(VLC_CODEC_I420_12),       decode_yuv420_12, },
        { NE(VLC_CODEC_I420_16),       decode_yuv420_16, },
    },
    .yuv411 = {
        {    VLC_CODEC_I411,           decode_yuv411_8,  },
        /* High-definition 4:1:1 not supported */
        {  0, NULL }, { 0, NULL }, { 0, NULL }
    },
};

static int Open(vlc_object_t *obj)
{
    decoder_t *dec = (decoder_t *)obj;
    const char *sname = dec->fmt_in->p_extra;

    if (dec->fmt_in->i_codec != VLC_CODEC_RTP_VIDEO_RAW)
        return VLC_ENOTSUP;
    if (dec->fmt_in->i_extra <= 0 || sname[dec->fmt_in->i_extra - 1] != '\0')
        return VLC_EINVAL;

    /* Sampling is supplied as extra data, bit depth as level */
    unsigned int depth = dec->fmt_in->i_level;
    const struct vlc_rtp_video_raw_sampling *sampling;
    unsigned int spmp; /* samples per macropixel */
    bool half_height_uv = false;

    if (strcmp(sname, "RGB") == 0) {
        sampling = &samplings.rgb;
        spmp = 3;
    } else if (strcmp(sname, "RGBA") == 0) {
        sampling = &samplings.rgba;
        spmp = 4;
    } else if (strcmp(sname, "BGR") == 0) {
        sampling = &samplings.bgr;
        spmp = 3;
    } else if (strcmp(sname, "BGRA") == 0) {
        sampling = &samplings.bgra;
        spmp = 4;
    } else if (strcmp(sname, "YCbCr-4:4:4") == 0) {
        sampling = &samplings.yuv444;
        spmp = 3;
    } else if (strcmp(sname, "YCbCr-4:2:2") == 0) {
        sampling = &samplings.yuv422;
        spmp = 4;
    } else if (strcmp(sname, "YCbCr-4:2:0") == 0) {
        sampling = &samplings.yuv420;
        spmp = 6;
        half_height_uv = true;
    } else if (strcmp(sname, "YCbCr-4:1:1") == 0) {
        sampling = &samplings.yuv411;
        spmp = 6;
    } else {
        msg_Err(obj, "unknown RTP video sampling %s", sname);
        return VLC_ENOTSUP;
    }

    const struct vlc_rtp_video_raw_format *format;

    switch (depth) {
        case 8:
            format = &sampling->depth8;
            break;
        case 10:
            format = &sampling->depth10;
            break;
        case 12:
            format = &sampling->depth12;
            break;
        case 16:
            format = &sampling->depth16;
            break;
        default:
            msg_Err(obj, "unsupported RTP video bit depth %u", depth);
            return VLC_ENOTSUP;
    }

    if (format->fourcc == 0) {
        msg_Err(obj, "unimplemented RTP video format %u-bit %s",
                depth, sname);
        return VLC_ENOTSUP;
    }

    struct vlc_rtp_video_raw_dec *sys = vlc_obj_malloc(obj, sizeof (*sys));
    if (unlikely(sys == NULL))
        return VLC_ENOMEM;

    es_format_Copy(&dec->fmt_out, dec->fmt_in);
    dec->fmt_out.i_codec = format->fourcc;
    dec->fmt_out.video.i_chroma = format->fourcc;

    int ret = decoder_UpdateVideoFormat(dec);
    if (ret != VLC_SUCCESS)
        return ret;

    unsigned int bpmp = depth * spmp;

    /* pixel group size equals LCM(depth * spmp, 8) bits */
    sys->pgroup = bpmp >> ((bpmp % 8) ? stdc_trailing_zeros(bpmp) : 3);
    sys->half_height_uv = half_height_uv;
    sys->decode_line = format->line_cb;
    sys->pic = NULL;
    dec->p_sys = sys;
    dec->pf_decode = Decode;
    return VLC_SUCCESS;
}

vlc_module_begin()
    set_description(N_("RTP raw video decoder"))
    set_capability("video decoder", 50)
    set_subcategory(SUBCAT_INPUT_VCODEC)
    set_callbacks(Open, Close)
vlc_module_end()

Messung
CHZG
849510093

¤ Dauer der Verarbeitung: 0.5 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.