• Non ci sono risultati.

Appendice A - Implementazione dello schema di migrazione coordinato con la rete

N/A
N/A
Protected

Academic year: 2021

Condividi "Appendice A - Implementazione dello schema di migrazione coordinato con la rete"

Copied!
9
0
0

Testo completo

(1)

Appendice A - Implementazione dello schema di

migrazione coordinato con la rete

Di seguito si riportano le modifiche apportate al codice sorgente C del software VLC

(versione 0.7.2). In particolare sono stati modificati 2 file:

• /modules/access/http.c: implementa il modulo di accesso alla rete mediante il protocollo

HTTP. Su questo file è stata implementato il trigger della migrazione basato sul time-out

lettura socket (vedi funzione Read), nonchè la migrazione stessa (vedi funzione

Migrazione). Tra le altre modifiche, sono stati inseriti nuovi campi nel menù grafico

dell’applicazione, le quali possono essere impostate in preferences

modules/access/access_http.

• /src/input/input.c: funziona da interfaccia tra il modulo di accesso alla rete e il decoder

MPEG. Su questo file è stato implementato il trigger basato sull’underflowing del buffer

del decoder, basato sull’algoritmo di pagina 45

File /modules/access/http

.

c

/***************************************************************************** * http.c: HTTP input module ***************************************************************************** * Copyright (C) 2001-2004 VideoLAN * $Id: http.c 7522 2004-04-27 16:35:15Z sam $ *

* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr> *

* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 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 General Public License for more details.

*

* You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software

* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ #include <stdlib.h> #include <vlc/vlc.h> #include <vlc/input.h> #include "vlc_playlist.h" #include "network.h"

(2)

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

*****************************************************************************/ static int Open ( vlc_object_t * );

static void Close( vlc_object_t * );

#define PROXY_TEXT N_("HTTP proxy") #define PROXY_LONGTEXT N_( \

"You can specify an HTTP proxy to use. It must be of the form " \

"http://myproxy.mydomain:myport/. If none is specified, the HTTP_PROXY " \ "environment variable will be tried." )

#define BKPSRV_TEXT N_("Backup Server ")

#define BKPSRV_LONGTEXT N_("You must specify the URL of backup server") #define TIMEOUT_TEXT N_("Socket reading timeout value in ms")

#define TIMEOUT_LONGTEXT N_( \

"Allows you to modify the default socket reading timeout value for http

streams. This " \

"value should be set in millisecond units." ) #define CACHING_TEXT N_("Caching value in ms") #define CACHING_LONGTEXT N_( \

"Allows you to modify the default caching value for http streams. This " \ "value should be set in millisecond units." )

#define USER_TEXT N_("HTTP user name")

#define USER_LONGTEXT N_("Allows you to modify the user name that will " \ "be used for the connection (Basic authentication only).")

#define PASS_TEXT N_("HTTP password")

#define PASS_LONGTEXT N_("Allows you to modify the password that will be " \ "used for the connection.")

#define RB_TEXT N_("HTTP user RB")

#define RB_LONGTEXT N_("Allows you to modify the user RB that will be " \ "used for the connection.")

vlc_module_begin();

set_description( _("HTTP input") ); set_capability( "access", 0 );

add_string( "http-proxy", NULL, NULL, PROXY_TEXT, PROXY_LONGTEXT, VLC_FALSE );

add_string( "http-user", NULL, NULL, USER_TEXT, USER_LONGTEXT, VLC_FALSE ); add_string( "http-pwd", NULL , NULL, PASS_TEXT, PASS_LONGTEXT, VLC_FALSE ); add_string( "http-user-RB", COPYRIGHT_MESSAGE , NULL, RB_TEXT,

RB_LONGTEXT, VLC_FALSE );

// Le impostazioni che appaiono qui possono essere impostate a tempo di // esecuzione nel menù grafico dell’applicativo VLC, seguendo il percorso // preferences modules/access/access_http

// Inserisce nel menu il campo per l’URL di backup

add_string( "Backup Server", NULL, NULL, BKPSRV_TEXT, BKPSRV_LONGTEXT, VLC_FALSE );

// Inserisce nel menu campo per stabilire time-out lettura socket // E’ possibile stabilire valore di default in msec (500)

add_integer( "socket-timeout", 500, NULL,

TIMEOUT_TEXT, TIMEOUT_LONGTEXT, VLC_TRUE );

// Inserisce nel menu campo per stabilire lunghezza temporale del buffer

add_integer( "http-caching", 4 * DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );

add_shortcut( "http" ); add_shortcut( "http4" );

(3)

add_shortcut( "http6" );

set_callbacks( Open, Close ); vlc_module_end(); /***************************************************************************** * Local prototypes *****************************************************************************/ struct access_sys_t { int fd; /* From uri */ vlc_url_t url; char *psz_user; char *psz_passwd; char *psz_user_RB; /* Proxy */ vlc_bool_t b_proxy; vlc_url_t proxy;

// Allocazione variabili per la migrazione //

vlc_bool_t migrate; // Booleano che stabilisce se la migrazione può avere luogo vlc_url_t bkp_srv; // Struttura che definisce l’URL backup

mtime_t timeout; // Definisce lunghezza del timeout

float startup; // /* */ int i_code; char *psz_protocol; int i_version; char *psz_mime; char *psz_location; vlc_bool_t b_chunked; int64_t i_chunk; int64_t i_tell; int64_t i_size; };

static void Seek( input_thread_t *, off_t );

static ssize_t Read( input_thread_t *, byte_t *, size_t ); static void ParseURL( access_sys_t *, char *psz_url );

static int Connect( input_thread_t *, vlc_bool_t *, off_t *, off_t ); static char *b64_encode( unsigned char *src );

static vlc_bool_t Migrazione ( input_thread_t * );

/***************************************************************************** Open: questa funzione viene richiamata dalla funzione Inithread del modulo input allo scopo di inizializzare il modulo di accesso alla rete

*****************************************************************************/ static int Open ( vlc_object_t *p_this )

{

input_thread_t *p_input = (input_thread_t*)p_this; access_sys_t *p_sys;

vlc_value_t val;

/* Create private struct */

p_sys = p_input->p_access_data = malloc( sizeof( access_sys_t ) ); memset( p_sys, 0, sizeof( access_sys_t ) );

p_sys->fd = -1;

p_sys->b_proxy = VLC_FALSE; p_sys->i_version = 1; p_sys->psz_mime = NULL;

(4)

p_sys->psz_location = NULL;

p_sys->psz_user_RB = NULL;

/* First set ipv4/ipv6 */

var_Create( p_input, "ipv4", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_input, "ipv6", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); if( *p_input->psz_access ) { **** OMISSIS **** } val.b_bool = VLC_TRUE;

var_Set( p_input, "ipv4", val ); val.b_bool = VLC_FALSE;

var_Set( p_input, "ipv6", val );

/* Definisce struttura del server primario*/ ParseURL( p_sys, p_input->psz_name);

if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' ) {

msg_Warn( p_input, "invalid host" ); goto error; } if( p_sys->url.i_port <= 0 ) { p_sys->url.i_port = 80; }

/** Definizione variabili per la migrazione **/

var_Create( p_input, "Backup Server", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_Get( p_input, "Backup Server", &val );

// Controlla se nel menù è stato inserito URL backup

if( val.psz_string && *val.psz_string ) {

// Se è presente inizializza struttura bck_srv che definisce URL backup

vlc_UrlParse( &p_sys->bck_srv, val.psz_string, 0 );

if( p_sys->bkp_srv.psz_host == NULL || *p_sys->bkp_srv.psz_host == '\0' ) { msg_Err( p_input, "Controller Server not valid" );

p_sys->migrate = VLC_FALSE; }

else{

p_sys->migrate = VLC_TRUE; // Abilita la migrazione

p_sys->startup = 0.05; // Posizione relativa dello streaming prima // della quale non può avvenire migrazione

// Imposta time-out in lettura con valore impostato nel menù

var_Create( p_input, "socket-timeout", VLC_VAR_INTEGER, VLC_VAR_DOINHERIT );

var_Get( p_input, "socket-timeout", &val ); p_sys->timeout = val.i_int * 1000;

if( p_sys->bkp_srv.i_port <= 0 ) p_sys->bkp_srv.i_port = 80;

msg_Dbg(p_input,"Backup Server: Server %s Port %d",p_sys->ctrl_srv.psz_host,p_sys->ctrl_srv.i_port);

} }

if( !p_sys->psz_user || *p_sys->psz_user == '\0' ) {

**** OMISSIS **** }

(5)

/* Do user RB */ **** OMISSIS **** /* Check proxy */ **** OMISSIS ****

/* Connessione al server primario*/

if( Connect( p_input, &p_input->stream.b_seekable,

&p_input->stream.p_selected_area->i_size, 0 ) ) {

**** OMISSIS **** }

if( ( p_sys->i_code == 301 || p_sys->i_code == 302 || p_sys->i_code == 303 || p_sys->i_code == 307 ) && p_sys->psz_location && *p_sys->psz_location ) {

**** OMISSIS **** }

/* Finish to set up p_input */

**** OMISSIS ****

/* Imposta lunghezza del playout buffer*/

var_Create( p_input, "http-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Get( p_input, "http-caching", &val );

p_input->i_pts_delay = val.i_int * 1000; return VLC_SUCCESS; error: **** OMISSIS **** } /***************************************************************************** * Read: questa funzione viene richiamata periodicamente dalla funzione runthread del modulo input per leggere I dati dal socket di rete ed inviarli al buffer del decoder

*****************************************************************************/ static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) {

access_sys_t *p_sys = p_input->p_access_data; int i_read;

if( p_sys->fd < 0 ) {

return -1; }

if( p_sys->i_size > 0 && i_len + p_sys->i_tell > p_sys->i_size ) { **** OMISSIS **** } if( p_sys->b_chunked ) { **** OMISSIS **** }

// Controlla se modulo input ha chiesto la migrazione per l’underflow del // buffer al decoder if (p_input->b_startmigrate) { Migrazione(p_input); } Lettura:

(6)

// Legge dati dal buffer. Se non c’è alcun dato nel bufferaspetto un tempo // massimo pari a timeout. I_read è il numero di byte letti dal socket. i_read = net_ReadNonBlock( p_input, p_sys->fd, p_buffer, i_len, timeout);

// Ha letto dati dal socket li elabora poi li invia al decoder buffer if( i_read > 0 )

{

**** OMISSIS **** }

// Nessun dato letto dal socket, cioè si è esaurito il timeout: viene fatta // intervenire la migrazione

if (i_read == 0) {

msg_Info(p_input,"No data read from socket"); p_input->b_startmigrate = VLC_TRUE;

if (Migrazione (p_input)) goto Lettura; // Se la migrazione ha successo // ritenta nuova lettura

} return i_read; } /***************************************************************************** * Migrazione: viene chiamata dalla funzione Read qualora debba intervenire la migrazione del server

*****************************************************************************/ static vlc_bool_t Migrazione( input_thread_t * p_input)

{

access_sys_t *p_sys = p_input->p_access_data;

// Primo byte dello streaming non ancora ricevuto. In caso di migrazione richiede // al nuovo server di iniziare il servizio da questo punto

off_t i_pos = p_sys->i_tell;

// Evita la migrazione in caso lo streaming sia all’inizio

float pos = (float)p_sys->i_tell / (float)p_sys->i_size ; if (pos < p_sys->startup)

{

msg_Info(p_input,"Stream relative position: %f",pos); p_input->b_startmigrate = VLC_FALSE;

return VLC_FALSE; }

// Inizia la migrazione

msg_Dbg(p_input,"Stream relative position: %f. Starting migration",pos); msg_Dbg( p_input, "Closing network socket to Primary Server...");

net_Close( p_sys->fd ); p_sys->fd = -1;

msg_Dbg( p_input, "Network socket to primary server closed");

// Sostituisce la struttura del server primario con il secondario

p_sys->url = p_sys->bkpsrv;

msg_Dbg( p_input, "Connecting to Backup Server...");

// Si connette con il server di backup chiedendo di iniziare il servizio da // dove si è interrotto il primario

if( Connect( p_input, &p_input->stream.b_seekable,

&p_input->stream.p_selected_area->i_size, i_pos ) )

(7)

msg_Err( p_input, "Connection to Backup Server Failed" );

return VLC_FALSE; } msg_Dbg(p_input,"Migration completed"); p_input->b_startmigrate = VLC_FALSE; return VLC_TRUE; }

File /src/input/input

.

c

/***************************************************************************** * input.c: input thread

* Read a stream, demultiplex and parse it before sending it to * decoders.

***************************************************************************** * Copyright (C) 1998-2004 VideoLAN

* $Id: input.c 7611 2004-05-06 23:14:23Z hartman $ *

* Authors: Christophe Massiot <massiot@via.ecp.fr> *

* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 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 General Public License for more details.

*

* You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software

* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ #include <stdlib.h> #include <vlc/vlc.h> #include <vlc/input.h> #include <vlc/decoder.h> #include <vlc/vout.h> #ifdef HAVE_SYS_TIMES_H # include <sys/times.h> #endif

#include "stream_output.h" #include "vlc_interface.h" #include "codecs.h" #include "vlc_meta.h" #include "../../modules/demux/util/sub.h" /***************************************************************************** * Local prototypes *****************************************************************************/ struct input_thread_sys_t { **** OMISSIS **** };

static int RunThread ( input_thread_t *p_input ); static int InitThread ( input_thread_t *p_input ); static void ErrorThread( input_thread_t *p_input ); static void EndThread ( input_thread_t *p_input );

(8)

static void ParseOption( input_thread_t *p_input, const char *psz_option ); static void DecodeUrl ( char * );

/***************************************************************************** * Callbacks

*****************************************************************************/ /***************************************************************************** * Inithread: Inizializza il thread che si occupa della lettura dei dati dalla rete per inviarli al buffer del decoder. Richiama la funzione Open del modullo http.c per inizializzare l’accesso alla rete.

*****************************************************************************/ static int InitThread( input_thread_t *p_input )

{

**** OMISSIS **** }

/***************************************************************************** * RunThread: prima chiama la funzione InitThread pr inizializzre il thread. Quindi esegue loop principale. Ad ogni ciclo chiama la funzione Read del modulo http.c per leggere dati dal socket ed inviarli al buffer del decoder.

*****************************************************************************/ static int RunThread( input_thread_t *p_input )

{

vlc_value_t val;

mtime_t i_update_next = -1;

/* Signal right now, otherwise we'll get stuck in a peek */ vlc_thread_ready( p_input );

if( InitThread( p_input ) ) { **** OMISSIS **** } /* initialization is complete */ **** OMISSIS ****

float bufdimean = 0; // Lunghezza media del buffer del decoder ptrdiff_t bufdim; // Lunghezza corrente del buffer del decoder

float k = 0.05; // Parametro k (equazione 1)

int down = 0; // conta quante volte consecutive bufdim < bufdimean

int N = 4; // Parametro N (condizione 2)

// Ciclo principale

while( !p_input->b_die && !p_input->b_error && !p_input->b_eof ) {

unsigned int i, i_count; p_input->c_loops++;

vlc_mutex_lock( &p_input->stream.stream_lock ); if( p_input->stream.p_new_program )

{

**** OMISSIS **** }

if( p_input->stream.p_new_area ) {

**** OMISSIS **** }

if( p_input->stream.p_selected_area->i_seek != NO_SEEK ) {

**** OMISSIS **** }

(9)

if( p_input->stream.p_removed_es ) {

**** OMISSIS **** }

if( p_input->stream.p_newly_selected_es ) {

**** OMISSIS **** }

if( p_input->stream.b_new_mute != MUTE_NO_CHANGE ) {

**** OMISSIS **** }

vlc_mutex_unlock( &p_input->stream.stream_lock ); /* Read and demultiplex some data. */

// Richiama funzione Read di http.c per leggere dati da socket

i_count = p_input->pf_demux( p_input );

// Rileva attuale dimensione del buffer

bufdim = p_input->p_last_data - p_input->p_current_data;

// In caso di migrazione reinizializza il valore di bufdimean

if (p_input->b_startmigrate) bufdimean = bufdim;

// Altrimenti aggiorna stima della lunghezza media (equazione 1)

else bufdimean = k * bufdim + (1-k)*bufdimean;

// Verifica condizione 2: se è verificata incrementa contatore

if (bufdim < 0.3*bufdimean) down++; // Altrimenti azzera il contatore

else down = 0;

// Verifica se la condizione 2 si è presentata per N volte consecutive

if (down > N) {

// Richiede migrazione per underflowing del buffer

msg_Info(p_input,"Buffer Underflowing"); p_input->b_startmigrate = VLC_TRUE; bufdimean = 0; } if( i_count == 0 ) { **** OMISSIS **** }

else if( i_count < 0 ) {

p_input->b_error = 1; }

if( !p_input->b_error && !p_input->b_eof && i_update_next < mdate() ) { **** OMISSIS **** } } if( p_input->b_error || p_input->b_eof ) { ErrorThread( p_input ); } EndThread( p_input ); return 0; }

Riferimenti

Documenti correlati

L’attività didattica sarà valida per i corsi di studio di Filologia e critica letteraria, Lingue e letterature moderne euroamericane, all’interno dei percorsi di studio in

Our aim is to capture some of the existing differences in the fi­ nancial structure and portfolios compositions of European countries in an equilibrium model

Secondly, the legal dimension of the Convention’s approach towards gender equality is examined within the framework of the elaboration of a draft Constitutional

More specifically, ADS are defined as providing Air Navigation Service Providers (ANSPs), airspace users (AUs), and airports with information on the intended movement of

Two phylogenetic analyses were performed: the first, based on LSU sequences, to focus on the position of Neopaxillus species in the Crepidotoid clade (the clade contains

We believe that future studies in Latin popu- lations are necessary to determine the prevalence of HLA alleles, their potential association with genetic susceptibility to RRP,

Tra tutte le attività, tuttavia, quella forse più feconda di significati ed effetti, legati anche ai contenuti di questa pubblicazione, è stata la realizzazione della Mappa di

Il webinar approfondirà il dibattito sui recenti cambiamenti dei decreti sicurezza e sul nuo- vo patto su asilo e migrazioni presentato dalla Commissione europea, per capire