Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  adaptive.cpp   Sprache: C

 

/*****************************************************************************
 * adaptive.cpp: Adaptive streaming module
 *****************************************************************************
 * Copyright © 2015 - VideoLAN and VLC Authors
 *
 * 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.
 *****************************************************************************/


/*****************************************************************************
 * Preamble
 *****************************************************************************/


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

#include <stdint.h>

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

#include "SharedResources.hpp"
#include "logic/BufferingLogic.hpp"
#include "xml/DOMParser.h"

#include "../dash/DASHManager.h"
#include "../dash/DASHStream.hpp"
#include "../dash/mpd/IsoffMainParser.h"

#include "../hls/HLSManager.hpp"
#include "../hls/HLSStreams.hpp"
#include "../hls/playlist/Parser.hpp"
#include "../hls/playlist/M3U8.hpp"
#include "../smooth/SmoothManager.hpp"
#include "../smooth/SmoothStream.hpp"
#include "../smooth/playlist/SmoothParser.hpp"

using namespace adaptive::http;
using namespace adaptive::logic;
using namespace adaptive::playlist;
using namespace adaptive::xml;
using namespace dash::mpd;
using namespace dash;
using namespace hls;
using namespace hls::playlist;
using namespace smooth;
using namespace smooth::playlist;

/*****************************************************************************
 * Module descriptor
 *****************************************************************************/

static int  Open    (vlc_object_t *);
static void Close   (vlc_object_t *);

#define ADAPT_WIDTH_TEXT N_("Maximum device width")
#define ADAPT_HEIGHT_TEXT N_("Maximum device height")

#define ADAPT_BW_TEXT N_("Fixed Bandwidth in KiB/s")
#define ADAPT_BW_LONGTEXT N_("Preferred bandwidth for non adaptive streams")

#define ADAPT_BUFFER_TEXT N_("Live Playback delay (ms)")
#define ADAPT_BUFFER_LONGTEXT N_("Tradeoff between stability and real time")

#define ADAPT_MAXBUFFER_TEXT N_("Max buffering (ms)")

#define ADAPT_LOGIC_TEXT N_("Adaptive Logic")

#define ADAPT_ACCESS_TEXT N_("Use regular HTTP modules")
#define ADAPT_ACCESS_LONGTEXT N_("Connect using HTTP access instead of custom HTTP code")

#define ADAPT_LOWLATENCY_TEXT N_("Low latency")
#define ADAPT_LOWLATENCY_LONGTEXT N_("Overrides low latency parameters")

static const AbstractAdaptationLogic::LogicType pi_logics[] = {
                                AbstractAdaptationLogic::LogicType::Default,
                                AbstractAdaptationLogic::LogicType::Predictive,
                                AbstractAdaptationLogic::LogicType::NearOptimal,
                                AbstractAdaptationLogic::LogicType::RateBased,
                                AbstractAdaptationLogic::LogicType::FixedRate,
                                AbstractAdaptationLogic::LogicType::AlwaysLowest,
                                AbstractAdaptationLogic::LogicType::AlwaysBest};

static const char *const ppsz_logics_values[] = {
                                "",
                                "predictive",
                                "nearoptimal",
                                "rate",
                                "fixedrate",
                                "lowest",
                                "highest"};

static const char *const ppsz_logics[] = { N_("Default"),
                                           N_("Predictive"),
                                           N_("Near Optimal"),
                                           N_("Bandwidth Adaptive"),
                                           N_("Fixed Bandwidth"),
                                           N_("Lowest Bandwidth/Quality"),
                                           N_("Highest Bandwidth/Quality")};

static_assert( ARRAY_SIZE( pi_logics ) == ARRAY_SIZE( ppsz_logics ),
    "pi_logics and ppsz_logics shall have the same number of elements" );

static_assert( ARRAY_SIZE( pi_logics ) == ARRAY_SIZE( ppsz_logics_values ),
    "pi_logics and ppsz_logics_values shall have the same number of elements" );

static const int rgi_latency[] = { -1, 1, 0 };

static const char *const ppsz_latency[] = { N_("Auto"),
                                            N_("Force"),
                                            N_("Disable") };

vlc_module_begin ()
        set_shortname( N_("Adaptive"))
        set_description( N_("Unified adaptive streaming for DASH/HLS") )
        set_capability( "demux", 12 )
        set_subcategory( SUBCAT_INPUT_DEMUX )
        add_string( "adaptive-logic",  "", ADAPT_LOGIC_TEXT, nullptr )
            change_string_list( ppsz_logics_values, ppsz_logics )
        add_integer( "adaptive-maxwidth",  0,
                     ADAPT_WIDTH_TEXT,  nullptr )
        add_integer( "adaptive-maxheight", 0,
                     ADAPT_HEIGHT_TEXT, nullptr )
        add_integer( "adaptive-bw",     250, ADAPT_BW_TEXT,     ADAPT_BW_LONGTEXT )
        add_bool   ( "adaptive-use-access", false, ADAPT_ACCESS_TEXT, ADAPT_ACCESS_LONGTEXT )
        add_integer( "adaptive-livedelay",
                     MS_FROM_VLC_TICK(AbstractBufferingLogic::DEFAULT_LIVE_BUFFERING),
                     ADAPT_BUFFER_TEXT, ADAPT_BUFFER_LONGTEXT )
        add_integer( "adaptive-maxbuffer",
                     MS_FROM_VLC_TICK(AbstractBufferingLogic::DEFAULT_MAX_BUFFERING),
                     ADAPT_MAXBUFFER_TEXT, nullptr )
        add_integer( "adaptive-lowlatency", -1, ADAPT_LOWLATENCY_TEXT, ADAPT_LOWLATENCY_LONGTEXT )
            change_integer_list(rgi_latency, ppsz_latency)
        set_callbacks( Open, Close )
vlc_module_end ()

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/

static PlaylistManager * HandleDash(demux_t *, DOMParser &,
                                    const std::string &, AbstractAdaptationLogic::LogicType);
static PlaylistManager * HandleSmooth(demux_t *, DOMParser &,
                                      const std::string &, AbstractAdaptationLogic::LogicType);
static PlaylistManager * HandleHLS(demux_t *,
                                   const std::string &, AbstractAdaptationLogic::LogicType);

/*****************************************************************************
 * Open:
 *****************************************************************************/

static int Open(vlc_object_t *p_obj)
{
    demux_t *p_demux = (demux_t*) p_obj;

    if(!p_demux->s->psz_url)
        return VLC_EGENERIC;

    std::string mimeType;

    char *psz_mime = stream_ContentType(p_demux->s);
    if(psz_mime)
    {
        mimeType = std::string(psz_mime);
        free(psz_mime);
    }

    PlaylistManager *p_manager = nullptr;

    char *psz_logic = var_InheritString(p_obj, "adaptive-logic");
    AbstractAdaptationLogic::LogicType logic = AbstractAdaptationLogic::LogicType::Default;
    if( psz_logic )
    {
        bool b_found = false;
        for(size_t i=0;i<ARRAY_SIZE(pi_logics); i++)
        {
            if(!strcmp(psz_logic, ppsz_logics_values[i]))
            {
                logic = pi_logics[i];
                b_found = true;
                break;
            }
        }
        if(!b_found)
            msg_Err(p_demux, "Unknown adaptive-logic value '%s'", psz_logic);
        free( psz_logic );
    }

    std::string playlisturl(p_demux->s->psz_url);

    bool dashmime = DASHManager::mimeMatched(mimeType);
    bool smoothmime = SmoothManager::mimeMatched(mimeType);

    if(!dashmime && !smoothmime && HLSManager::isHTTPLiveStreaming(p_demux->s))
    {
        p_manager = HandleHLS(p_demux, playlisturl, logic);
    }
    else
    {
        /* Handle XML Based ones */
        DOMParser xmlParser; /* Share that xml reader */
        if(dashmime)
        {
            p_manager = HandleDash(p_demux, xmlParser, playlisturl, logic);
        }
        else if(smoothmime)
        {
            p_manager = HandleSmooth(p_demux, xmlParser, playlisturl, logic);
        }
        else
        {
            /* We need to probe content */
            const uint8_t *p_peek;
            const ssize_t i_peek = vlc_stream_Peek(p_demux->s, &p_peek, 2048);
            if(i_peek > 0)
            {
                stream_t *peekstream = vlc_stream_MemoryNew(p_demux, const_cast<uint8_t *>(p_peek), (size_t)i_peek, true);
                if(peekstream)
                {
                    if(xmlParser.reset(peekstream) && xmlParser.parse(false))
                    {
                        if(DASHManager::isDASH(xmlParser.getRootNode()))
                        {
                            p_manager = HandleDash(p_demux, xmlParser, playlisturl, logic);
                        }
                        else if(SmoothManager::isSmoothStreaming(xmlParser.getRootNode()))
                        {
                            p_manager = HandleSmooth(p_demux, xmlParser, playlisturl, logic);
                        }
                    }
                    vlc_stream_Delete(peekstream);
                }
            }
        }
    }

    if(!p_manager || !p_manager->init(p_demux->b_preparsing))
    {
        delete p_manager;
        return VLC_EGENERIC;
    }

    /* disable annoying stuff */
    if(VLC_SUCCESS == var_Create( p_demux, "lua", VLC_VAR_BOOL))
        var_SetBool(p_demux, "lua", false);

    p_demux->p_sys         = p_manager;
    p_demux->pf_demux      = p_manager->demux_callback;
    p_demux->pf_control    = p_manager->control_callback;

    msg_Dbg(p_obj,"opening playlist file (%s)", p_demux->psz_location);

    return VLC_SUCCESS;
}

/*****************************************************************************
 * Close:
 *****************************************************************************/

static void Close(vlc_object_t *p_obj)
{
    demux_t         *p_demux       = (demux_t*) p_obj;
    PlaylistManager *p_manager  = reinterpret_cast<PlaylistManager *>(p_demux->p_sys);

    p_manager->stop();
    delete p_manager;
}

/*****************************************************************************
 *
 *****************************************************************************/

static PlaylistManager * HandleDash(demux_t *p_demux, DOMParser &xmlParser,
                                    const std::string & playlisturl,
                                    AbstractAdaptationLogic::LogicType logic)
{
    if(!xmlParser.reset(p_demux->s) || !xmlParser.parse(true))
    {
        msg_Err(p_demux, "Cannot parse MPD");
        return nullptr;
    }
    IsoffMainParser mpdparser(xmlParser.getRootNode(), VLC_OBJECT(p_demux),
                              p_demux->s, playlisturl);
    MPD *p_playlist = mpdparser.parse();
    if(p_playlist == nullptr)
    {
        msg_Err( p_demux, "Cannot create/unknown MPD for profile");
        return nullptr;
    }

    SharedResources *resources =
            SharedResources::createDefault(VLC_OBJECT(p_demux), playlisturl);
    DASHStreamFactory *factory = new (std::nothrow) DASHStreamFactory;
    DASHManager *manager = nullptr;
    if(!resources || !factory ||
       !(manager = new (std::nothrow) DASHManager(p_demux, resources,
                                                  p_playlist, factory, logic)))
    {
        delete resources;
        delete factory;
        delete p_playlist;
    }
    return manager;
}

static PlaylistManager * HandleSmooth(demux_t *p_demux, DOMParser &xmlParser,
                                    const std::string & playlisturl,
                                    AbstractAdaptationLogic::LogicType logic)
{
    if(!xmlParser.reset(p_demux->s) || !xmlParser.parse(true))
    {
        msg_Err(p_demux, "Cannot parse Manifest");
        return nullptr;
    }
    ManifestParser mparser(xmlParser.getRootNode(), VLC_OBJECT(p_demux),
                           p_demux->s, playlisturl);
    Manifest *p_playlist = mparser.parse();
    if(p_playlist == nullptr)
    {
        msg_Err( p_demux, "Cannot create Manifest");
        return nullptr;
    }

    SharedResources *resources =
            SharedResources::createDefault(VLC_OBJECT(p_demux), playlisturl);
    SmoothStreamFactory *factory = new (std::nothrow) SmoothStreamFactory;
    SmoothManager *manager = nullptr;
    if(!resources || !factory ||
       !(manager = new (std::nothrow) SmoothManager(p_demux, resources,
                                                    p_playlist, factory, logic)))
    {
        delete resources;
        delete factory;
        delete p_playlist;
    }
    return manager;
}

static PlaylistManager * HandleHLS(demux_t *p_demux,
                                   const std::string & playlisturl,
                                   AbstractAdaptationLogic::LogicType logic)
{
    SharedResources *resources =
            SharedResources::createDefault(VLC_OBJECT(p_demux), playlisturl);
    if(!resources)
        return nullptr;

    M3U8Parser parser(resources);
    M3U8 *p_playlist = parser.parse(VLC_OBJECT(p_demux),p_demux->s, playlisturl);
    if(!p_playlist)
    {
        msg_Err( p_demux, "Could not parse playlist" );
        delete resources;
        return nullptr;
    }

    HLSStreamFactory *factory = new (std::nothrow) HLSStreamFactory;
    HLSManager *manager = nullptr;
    if(!factory ||
       !(manager = new (std::nothrow) HLSManager(p_demux, resources,
                                                 p_playlist, factory, logic)))
    {
        delete p_playlist;
        delete factory;
        delete resources;
    }
    return manager;
}

Messung
CHZG
849610093

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






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104856
#Domains=417772