Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  rist.c   Sprache: C

 

/*****************************************************************************
 * rist.c: RIST (Reliable Internet Stream Transport) output module
 *****************************************************************************
 * Copyright (C) 2021, SipRadius LLC
 *
 * Authors: Sergio Ammirata <sergio@ammirata.net>
 *
 * 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_configuration.h>
#include <vlc_interrupt.h>
#include <vlc_plugin.h>
#include <vlc_sout.h>
#include <vlc_block.h>
#include <vlc_rand.h>
#ifndef _WIN32
#include <sys/time.h>
#endif

#define RIST_CFG_PREFIX "sout-rist-"
#include "../access/rist.h"

#if !defined RIST_DEFAULT_RECOVERY_LENGTH_MIN
# define RIST_DEFAULT_RECOVERY_LENGTH_MIN RIST_DEFAULT_RECOVERY_LENGHT_MIN
#endif

static const char *const ppsz_sout_options[] = {
    RIST_CFG_MAX_PACKET_SIZE,
    RIST_URL_PARAM_VIRT_SRC_PORT,
    RIST_URL_PARAM_VIRT_DST_PORT,
    RIST_CFG_LATENCY,
    "multipeer-mode",
    RIST_CFG_URL2,
    RIST_CFG_URL3,
    RIST_CFG_URL4,
    RIST_URL_PARAM_BANDWIDTH,
    RIST_CFG_RETRY_INTERVAL,
    RIST_URL_PARAM_REORDER_BUFFER,
    RIST_CFG_MAX_RETRIES,
    RIST_URL_PARAM_VERBOSE_LEVEL,
    RIST_URL_PARAM_CNAME,
    RIST_URL_PARAM_PROFILE,
    RIST_URL_PARAM_SECRET,
    RIST_URL_PARAM_AES_TYPE,
    RIST_URL_PARAM_SRP_USERNAME,
    RIST_URL_PARAM_SRP_PASSWORD,
    NULL
};

typedef struct
{
    struct rist_ctx    *sender_ctx;
    int                gre_src_port;
    int                gre_dst_port;
    uint32_t           i_recovery_buffer;
    size_t             i_max_packet_size;
    struct rist_logging_settings logging_settings;
} sout_access_out_sys_t;

static int cb_stats(void *arg, const struct rist_stats *stats_container)
{
    sout_access_out_t *p_access = (sout_access_out_t*)arg;
    sout_access_out_sys_t *p_sys = p_access->p_sys;

    msg_Dbg(p_access, "[RIST-STATS]: %s", stats_container->stats_json);

    const struct rist_stats_sender_peer *stats_sender_peer = &stats_container->stats.sender_peer;
    msg_Dbg(p_access, "[RIST-STATS]: name %s, id %"PRIu32", bitrate %zu, sent %"PRIu64", received %"PRIu64", retransmitted %"PRIu64", Q %.2f, rtt %"PRIu32"ms",
        stats_sender_peer->cname,
        stats_sender_peer->peer_id,
        stats_sender_peer->bandwidth,
        stats_sender_peer->sent,
        stats_sender_peer->received,
        stats_sender_peer->retransmitted,
        stats_sender_peer->quality,
        stats_sender_peer->rtt
    );

    if (stats_sender_peer->rtt > p_sys->i_recovery_buffer)
    {
        msg_Err(p_access, "The RTT between us and the receiver is higher than the configured recovery buffer size, %"PRIu32" > %"PRIu32" ms, you should increase the recovery buffer size",
            stats_sender_peer->rtt, p_sys->i_recovery_buffer);
    }

    rist_stats_free(stats_container);
    return 0;
}

static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
{
    sout_access_out_sys_t *p_sys = p_access->p_sys;
    size_t i_len = 0;

    struct rist_data_block rist_buffer = { 0 };
    rist_buffer.virt_src_port = p_sys->gre_src_port;
    rist_buffer.virt_dst_port = p_sys->gre_dst_port;

    while( p_buffer )
    {
        block_t *p_next;

        while( p_buffer->i_buffer )
        {
            size_t i_write = __MIN( p_buffer->i_buffer, p_sys->i_max_packet_size );
            rist_buffer.payload = p_buffer->p_buffer;
            rist_buffer.payload_len = i_write;

            int written = rist_sender_data_write(p_sys->sender_ctx, &rist_buffer);
            if( written < 0 )
            {
                msg_Warn( p_access, "rist_sender_data_write failed (chunk=%zu)", i_write );
                block_ChainRelease( p_buffer );
                return -1;
            }

            i_len += (size_t)written;
            p_buffer->p_buffer += i_write;
            p_buffer->i_buffer -= i_write;
        }

        p_next = p_buffer->p_next;
        block_Release( p_buffer );
        p_buffer = p_next;
    }

    /* i_len <= chain_len * RIST_MAX_PACKET_SIZE (10000); always fits in ssize_t. */
    return (ssize_t)i_len;
}

static int Control( sout_access_out_t *p_access, int i_query, va_list args )
{
    VLC_UNUSED( p_access );

    int i_ret = VLC_SUCCESS;

    switch( i_query )
    {
        case ACCESS_OUT_CONTROLS_PACE:
            *va_arg( args, bool * ) = false;
            break;

        default:
            i_ret = VLC_EGENERIC;
            break;
    }

    return i_ret;
}

static void Close( vlc_object_t * p_this )
{
    sout_access_out_t     *p_access = (sout_access_out_t*)p_this;
    sout_access_out_sys_t *p_sys = p_access->p_sys;

    rist_destroy(p_sys->sender_ctx);
    p_sys->sender_ctx = NULL;
}

static int Open( vlc_object_t *p_this )
{
    sout_access_out_t       *p_access = (sout_access_out_t*)p_this;
    sout_access_out_sys_t   *p_sys = NULL;

    if (var_Create ( p_access, "dst-port", VLC_VAR_INTEGER )
     || var_Create ( p_access, "src-port", VLC_VAR_INTEGER )
     || var_Create ( p_access, "dst-addr", VLC_VAR_STRING )
     || var_Create ( p_access, "src-addr", VLC_VAR_STRING ) )
    {
        msg_Err( p_access, "Valid network information is required." );
        return VLC_EGENERIC;
    }

    config_ChainParse( p_access, RIST_CFG_PREFIX, ppsz_sout_options, p_access->p_cfg );

    p_sys = vlc_obj_calloc( p_this, 1, sizeof( *p_sys ) );
    if( unlikely( p_sys == NULL ) )
        return VLC_ENOMEM;

    p_access->p_sys = p_sys;


    p_sys->gre_src_port = var_InheritInteger(p_access, RIST_CFG_PREFIX RIST_URL_PARAM_VIRT_SRC_PORT);
    p_sys->gre_dst_port = var_InheritInteger(p_access, RIST_CFG_PREFIX RIST_URL_PARAM_VIRT_DST_PORT);
    if (p_sys->gre_dst_port % 2 != 0) {
        msg_Err( p_access, "Virtual destination port must be an even number." );
        return VLC_EGENERIC;
    }

    p_sys->i_max_packet_size = rist_get_max_packet_size(VLC_OBJECT(p_access));

    int i_rist_profile = var_InheritInteger(p_access, RIST_CFG_PREFIX RIST_URL_PARAM_PROFILE);
    int i_verbose_level = var_InheritInteger(p_access, RIST_CFG_PREFIX RIST_URL_PARAM_VERBOSE_LEVEL);


    //disable global logging: see comment in access/rist.c
    struct rist_logging_settings rist_global_logging_settings = LOGGING_SETTINGS_INITIALIZER;
    if (rist_logging_set_global(&rist_global_logging_settings) != 0) {
        msg_Err(p_access,"Could not set logging\n");
        return VLC_EGENERIC;
    }

    struct rist_logging_settings *logging_settings = &p_sys->logging_settings;
    logging_settings->log_socket = -1;
    logging_settings->log_stream = NULL;
    logging_settings->log_level = i_verbose_level;
    logging_settings->log_cb = log_cb;
    logging_settings->log_cb_arg = p_access;

    if (rist_sender_create(&p_sys->sender_ctx, i_rist_profile, 0, logging_settings) != 0) {
        msg_Err( p_access, "Could not create rist sender context\n");
        return VLC_EGENERIC;
    }

    // Enable stats data
    if (rist_stats_callback_set(p_sys->sender_ctx, 1000, cb_stats, (void *)p_access) == -1) {
        msg_Err(p_access, "Could not enable stats callback");
        goto failed;
    }

    int i_multipeer_mode = var_InheritInteger(p_access, RIST_CFG_PREFIX "multipeer-mode");
    int i_recovery_length = var_InheritInteger(p_access, RIST_CFG_PREFIX RIST_CFG_LATENCY);
    p_sys->i_recovery_buffer = i_recovery_length;

    if ( !rist_add_peers(VLC_OBJECT(p_access), p_sys->sender_ctx, p_access->psz_path, i_multipeer_mode, p_sys->gre_dst_port + 1, i_recovery_length) )
        goto failed;

    if (rist_start(p_sys->sender_ctx) == -1) {
        msg_Err( p_access, "Could not start rist sender\n");
        goto failed;
    }

    p_access->pf_write = Write;
    p_access->pf_control = Control;

    return VLC_SUCCESS;

failed:
    rist_destroy(p_sys->sender_ctx);
    p_sys->sender_ctx = NULL;
    return VLC_EGENERIC;
}

#define SRC_PORT_TEXT N_("Virtual Source Port")
#define SRC_PORT_LONGTEXT N_( \
    "Source port to be used inside the reduced-mode of the main profile" )

#define DST_PORT_TEXT N_("Virtual Destination Port")
#define DST_PORT_LONGTEXT N_( \
    "Destination port to be used inside the reduced-mode of the main profile" )

/* The default target payload size */
#define RIST_DEFAULT_TARGET_PAYLOAD_SIZE 1316

/* Multipeer mode */
#define RIST_DEFAULT_MULTIPEER_MODE 0
#define RIST_MULTIPEER_MODE_TEXT N_("Multipeer mode")
#define RIST_MULTIPEER_MODE_LONGTEXT N_( \
    "This allows you to select between duplicate or load balanced modes when " \
    "sending data to multiple peers (several network paths)" )
static const int multipeer_mode_type[] = { 0, 5, };
static const char *const multipeer_mode_type_names[] = {
    N_("Duplicate"), N_("Load balanced"),
};

/* Module descriptor */
vlc_module_begin()

    set_shortname( N_("RIST") )
    set_description( N_("RIST stream output") )
    set_subcategory( SUBCAT_SOUT_ACO )

    add_integer( RIST_CFG_PREFIX RIST_CFG_MAX_PACKET_SIZE, RIST_DEFAULT_TARGET_PAYLOAD_SIZE,
            N_("RIST target payload size (bytes)"), NULL )
    add_integer( RIST_CFG_PREFIX RIST_URL_PARAM_VIRT_SRC_PORT, RIST_DEFAULT_VIRT_SRC_PORT,
            SRC_PORT_TEXT, SRC_PORT_LONGTEXT )
    add_integer( RIST_CFG_PREFIX RIST_URL_PARAM_VIRT_DST_PORT, RIST_DEFAULT_VIRT_DST_PORT,
            DST_PORT_TEXT, DST_PORT_LONGTEXT )
    add_integer( RIST_CFG_PREFIX "multipeer-mode", RIST_DEFAULT_MULTIPEER_MODE,
            RIST_MULTIPEER_MODE_TEXT, RIST_MULTIPEER_MODE_LONGTEXT )
        change_integer_list( multipeer_mode_type, multipeer_mode_type_names )
    add_string( RIST_CFG_PREFIX RIST_CFG_URL2, NULL, RIST_URL2_TEXT, NULL )
    add_string( RIST_CFG_PREFIX RIST_CFG_URL3, NULL, RIST_URL3_TEXT, NULL )
    add_string( RIST_CFG_PREFIX RIST_CFG_URL4, NULL, RIST_URL4_TEXT, NULL )
    add_integer( RIST_CFG_PREFIX RIST_URL_PARAM_BANDWIDTH, RIST_DEFAULT_RECOVERY_MAXBITRATE,
            RIST_MAX_BITRATE_TEXT, RIST_MAX_BITRATE_LONGTEXT )
    add_integer( RIST_CFG_PREFIX RIST_CFG_RETRY_INTERVAL, RIST_DEFAULT_RECOVERY_RTT_MIN,
        RIST_RETRY_INTERVAL_TEXT, NULL )
    add_integer( RIST_CFG_PREFIX RIST_URL_PARAM_REORDER_BUFFER, RIST_DEFAULT_RECOVERY_REORDER_BUFFER,
        RIST_REORDER_BUFFER_TEXT, NULL )
    add_integer( RIST_CFG_PREFIX RIST_CFG_MAX_RETRIES, RIST_DEFAULT_MAX_RETRIES,
        RIST_MAX_RETRIES_TEXT, NULL )
    add_integer( RIST_CFG_PREFIX RIST_URL_PARAM_VERBOSE_LEVEL, RIST_DEFAULT_VERBOSE_LEVEL,
            RIST_VERBOSE_LEVEL_TEXT, RIST_VERBOSE_LEVEL_LONGTEXT )
        change_integer_list( verbose_level_type, verbose_level_type_names )
    add_integer( RIST_CFG_PREFIX RIST_CFG_LATENCY, RIST_DEFAULT_RECOVERY_LENGTH_MIN,
            BUFFER_TEXT, BUFFER_LONGTEXT )
    add_string( RIST_CFG_PREFIX RIST_URL_PARAM_CNAME, NULL, RIST_CNAME_TEXT,
            RIST_CNAME_LONGTEXT )
    add_integer( RIST_CFG_PREFIX RIST_URL_PARAM_PROFILE, RIST_DEFAULT_PROFILE,
            RIST_PROFILE_TEXT, RIST_PROFILE_LONGTEXT )
    add_password( RIST_CFG_PREFIX RIST_URL_PARAM_SECRET, "",
            RIST_SHARED_SECRET_TEXT, NULL )
    add_integer( RIST_CFG_PREFIX RIST_URL_PARAM_AES_TYPE, 0,
            RIST_ENCRYPTION_TYPE_TEXT, NULL )
        change_integer_list( rist_encryption_type, rist_encryption_type_names )
    add_string( RIST_CFG_PREFIX RIST_URL_PARAM_SRP_USERNAME, "",
            RIST_SRP_USERNAME_TEXT, NULL )
    add_password( RIST_CFG_PREFIX RIST_URL_PARAM_SRP_PASSWORD, "",
            RIST_SRP_PASSWORD_TEXT, NULL )

    set_capability( "sout access", 10 )
    add_shortcut( "librist", "rist", "tr06" )

    set_callbacks( Open, Close )

vlc_module_end ()

Messung
CHZG
839610093

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






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104848
#Domains=416959