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

Quelle  repack.c   Sprache: C

 

/*****************************************************************************
 * repack.c: Codec specific formatting for AnnexB multiplexers
 *****************************************************************************
 * Copyright (C) 2021 VideoLabs, 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_block.h>

#include "repack.h"
#include "../../packetizer/h266_nal.h"
#include "../../packetizer/hevc_nal.h"
#include "../../packetizer/h264_nal.h"
#include "../../packetizer/hxxx_nal.h"

#include <assert.h>

static void AnnexBInject(block_t **pp_pes,
                   const uint8_t *p_extra, size_t i_extra,
                   const uint8_t *p_au, size_t i_au)
{
    if(!i_extra && !i_au)
        return;

    *pp_pes = block_Realloc(*pp_pes,
                            i_extra + i_au,
                            (*pp_pes)->i_buffer);
    if(!*pp_pes)
        return;
    if(i_au)
        memcpy(&(*pp_pes)->p_buffer[0], p_au, i_au);
    if(i_extra)
        memcpy(&(*pp_pes)->p_buffer[i_au], p_extra, i_extra);
}

static void PES_RepackVVC(block_t **pp_pes,
                           const uint8_t *p_extra, size_t i_extra)
{
    uint8_t audata[] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0xA1, 0x28 };
    size_t i_au = sizeof(audata);
    size_t i_aucurrent = 0;
    uint8_t au_payload_byte = 0;

    hxxx_iterator_ctx_t ctx;
    hxxx_iterator_init(&ctx, (*pp_pes)->p_buffer, (*pp_pes)->i_buffer, 0);
    const uint8_t *p_nal; size_t i_nal;
    while(hxxx_annexb_iterate_next(&ctx, &p_nal, &i_nal))
    {
        if(i_nal < 2)
            return;
        uint8_t type = h266_getNALType(p_nal);
        switch(type)
        {
        case H266_NAL_IDR_W_RADL:
        case H266_NAL_IDR_N_LP:
        case H266_NAL_CRA:
        case H266_NAL_GDR:
        case H266_NAL_RSV_IRAP_11:
            if(!au_payload_byte)
                au_payload_byte = 0x80 | (0x00 << 5) | 0x08;
            goto out;
        case H266_NAL_AUD:
            i_au = 0;
            i_aucurrent = i_nal + (p_nal - (*pp_pes)->p_buffer);
            if(i_nal >= 3)
                au_payload_byte = p_nal[2];
            break;
        case H266_NAL_VPS:
        case H266_NAL_PPS:
        case H266_NAL_SPS:
            i_extra = 0;
            break;
        default:
            if(type < H266_NAL_OPI)
                goto out;
            break;
        }
    }

out:
    if(au_payload_byte)
        audata[6] = au_payload_byte;

    if(i_aucurrent && i_extra) /* strip existing AU for now */
    {
        (*pp_pes)->p_buffer += i_aucurrent;
        (*pp_pes)->i_buffer -= i_aucurrent;
        i_au = sizeof(audata);
    }

    AnnexBInject(pp_pes, p_extra, i_extra, audata, i_au);
}

static void PES_RepackHEVC(block_t **pp_pes,
                                    const uint8_t *p_extra, size_t i_extra)
{
    const uint8_t audata[] = { 0x00, 0x00, 0x00, 0x01, 0x46, 0x01 };
    size_t i_au = sizeof(audata);
    size_t i_aucurrent = 0;
    hxxx_iterator_ctx_t ctx;
    hxxx_iterator_init(&ctx, (*pp_pes)->p_buffer, (*pp_pes)->i_buffer, 0);
    const uint8_t *p_nal; size_t i_nal;
    while(hxxx_annexb_iterate_next(&ctx, &p_nal, &i_nal))
    {
        if(i_nal < 2)
            return;
        uint8_t type = hevc_getNALType(p_nal);
        if(type < HEVC_NAL_VPS)
            break;
        switch(type)
        {
            case HEVC_NAL_AUD:
                i_au = 0;
                i_aucurrent = i_nal + (p_nal - (*pp_pes)->p_buffer);
                break;
            case HEVC_NAL_VPS:
            case HEVC_NAL_PPS:
            case HEVC_NAL_SPS:
                i_extra = 0;
                break;
            default:
                break;
        }
    }

    if(i_extra && i_aucurrent) /* strip existing AU for now */
    {
        (*pp_pes)->p_buffer += i_aucurrent;
        (*pp_pes)->i_buffer -= i_aucurrent;
        i_au = sizeof(audata);
    }

    AnnexBInject(pp_pes, p_extra, i_extra, audata, i_au);
}

static void PES_RepackH264(block_t **pp_pes,
                                    const uint8_t *p_extra, size_t i_extra)
{
    const uint8_t audata[] = { 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0 };
    size_t i_au = sizeof(audata);
    size_t i_aucurrent = 0;
    hxxx_iterator_ctx_t ctx;
    hxxx_iterator_init(&ctx, (*pp_pes)->p_buffer, (*pp_pes)->i_buffer, 0);
    const uint8_t *p_nal; size_t i_nal;
    while(hxxx_annexb_iterate_next(&ctx, &p_nal, &i_nal))
    {
        if(i_nal < 2)
            return;
        uint8_t type = p_nal[0]&0x1f;
        if(type < H264_NAL_SEI)
            break;
        switch(type)
        {
            case H264_NAL_AU_DELIMITER:
                i_au = 0;
                i_aucurrent = i_nal + (p_nal - (*pp_pes)->p_buffer);
                break;
            case H264_NAL_SPS:
            case H264_NAL_PPS:
                i_extra = 0;
                break;
            default:
                break;
        }
    }

    if(i_extra && i_aucurrent) /* strip existing AU for now */
    {
        (*pp_pes)->p_buffer += i_aucurrent;
        (*pp_pes)->i_buffer -= i_aucurrent;
        i_au = sizeof(audata);
    }

    AnnexBInject(pp_pes, p_extra, i_extra, audata, i_au);
}

static void PES_RepackMP4V(block_t **pp_pes,
                           const uint8_t *p_extra, size_t i_extra)
{
    hxxx_iterator_ctx_t ctx;
    hxxx_iterator_init(&ctx, (*pp_pes)->p_buffer, (*pp_pes)->i_buffer, 0);
    const uint8_t *p_nal; size_t i_nal;
    while(hxxx_annexb_iterate_next(&ctx, &p_nal, &i_nal))
    {
        if(i_nal < 2)
            return;
        if(p_nal[0] >= 0x30) /* > VOLS */
            break;
        if(p_nal[0] >= 0x20 && p_nal[0] == p_extra[3]) /* same VOL */
            i_extra = 0;
    }

    AnnexBInject(pp_pes, p_extra, i_extra, NULL, 0);
}

block_t * PES_Repack(vlc_fourcc_t i_codec,
                     const uint8_t *p_extra, size_t i_extra,
                     block_t **pp_pes)
{
    /* safety check for annexb extra */
    if(i_extra < 4 ||
       (memcmp(p_extra, annexb_startcode4, 4) &&
        memcmp(&p_extra[1], annexb_startcode3, 3)))
        i_extra = 0;

    switch(i_codec)
    {
        case VLC_CODEC_VVC:
            PES_RepackVVC(pp_pes, p_extra, i_extra);
            break;
        case VLC_CODEC_HEVC:
            PES_RepackHEVC(pp_pes, p_extra, i_extra);
            break;
        case VLC_CODEC_H264:
            PES_RepackH264(pp_pes, p_extra, i_extra);
            break;
        case VLC_CODEC_MP4V:
            PES_RepackMP4V(pp_pes, p_extra, i_extra);
            break;
        default:
            break;
    }
    return *pp_pes;
}

Messung
CHZG
839610093

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© 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.