Commit fab59c05 authored by Clément Stenac's avatar Clément Stenac

* ALL: Better announce system

  - The SAP handler now runs in a separate thread.
  - RTP sessions can be announced with sap (sdp=sap://,name=...)
	TODO: Make this more configurable
  - Better SDP generation (the timestamp problem is not resolved)
	About this, there is a problem : as, for a RTP session, the URI
        is the complete SDP, if the session is recreated, as the URI has 
        changed, a new item is added to the playlist
  - Experimental flow control algorithm :
       It does not follow the "Recommended" implementation, as it needs
       to count the sessions (to achieve this, we should make this work
       together with the SAP listener)
       It is disabled by default (use --sap-flow-control to enable).
       When it is disabled, sap announcement interval is set by --sap-interval

* src/misc/net.c : created net_ReadNonBlock
* sap.c : Fixed memory problem


parent 60c63d39
......@@ -348,6 +348,8 @@ SOURCES_libvlc_common = \
src/audio_output/output.c \
src/audio_output/intf.c \
src/stream_output/stream_output.c \
src/stream_output/announce.c \
src/stream_output/sap.c \
src/misc/charset.c \
src/misc/httpd.c \
src/misc/mtime.c \
......
$Id: NEWS,v 1.86 2004/03/02 23:49:38 hartman Exp $
$Id$
Changes between 0.7.1 and 0.7.2:
--------------------------------
Core support:
* Bookmarks feature
* Support for video output embedded in interfaces
Codecs:
Playlist:
Input:
Stream output:
* Improved session announcement system
Interfaces:
* Skins
- Ability to embed video output
* wxWindows
- new design and set of icons
- new streaming wizard
- Ability to embed video output
Changes between 0.7.1 and 0.7.1a:
---------------------------------
......
......@@ -2,7 +2,7 @@
* network.h: interface to communicate with network plug-ins
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: network.h,v 1.10 2004/01/21 10:22:31 fenrir Exp $
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Laurent Aimar <fenrir@via.ecp.fr>
......@@ -173,6 +173,9 @@ VLC_EXPORT( void, net_Close, ( int fd ) );
#define net_Read(a,b,c,d,e) __net_Read(VLC_OBJECT(a),b,c,d,e)
VLC_EXPORT( int, __net_Read, ( vlc_object_t *p_this, int fd, uint8_t *p_data, int i_data, vlc_bool_t b_retry ) );
#define net_ReadNonBlock(a,b,c,d,e) __net_ReadNonBlock(VLC_OBJECT(a),b,c,d,e)
VLC_EXPORT( int, __net_ReadNonBlock, ( vlc_object_t *p_this, int fd, uint8_t *p_data, int i_data, mtime_t i_wait ) );
#define net_Write(a,b,c,d) __net_Write(VLC_OBJECT(a),b,c,d)
VLC_EXPORT( int, __net_Write, ( vlc_object_t *p_this, int fd, uint8_t *p_data, int i_data ) );
......
......@@ -181,6 +181,108 @@ struct sout_instance_t
sout_instance_sys_t *p_sys;
};
/* Announce handler structures */
/* Session and method descriptors */
struct sap_session_t;
struct session_descriptor_t
{
char *psz_name;
char *psz_uri;
int i_port;
int i_ttl;
int i_payload; /* SAP Payload type */
sap_session_t *p_sap; /* If we have a sap session, remember it */
char *psz_sdp;
};
#define METHOD_TYPE_SAP 1
#define METHOD_TYPE_SLP 2
struct announce_method_t
{
int i_type;
/* For SAP */
int i_ip_version;
char *psz_ipv6_scope;
char *psz_address; /* If we use a custom address */
};
/* SAP Specific structures */
/* 100ms */
#define SAP_IDLE ((mtime_t)(0.100*CLOCK_FREQ))
#define SAP_MAX_BUFFER 65534
#define MIN_INTERVAL 2
#define MAX_INTERVAL 300
/* A SAP announce address. For each of these, we run the
* control flow algorithm */
struct sap_address_t
{
char *psz_address;
int i_port;
int i_rfd; /* Read socket */
int i_wfd; /* Write socket */
/* Used for flow control */
mtime_t t1;
vlc_bool_t b_enabled;
vlc_bool_t b_ready;
int i_interval;
int i_buff;
int i_limit;
};
/* A SAP session descriptor, enqueued in the SAP handler queue */
struct sap_session_t
{
char *psz_sdp;
char *psz_data;
int i_length;
sap_address_t *p_address;
/* Last and next send */
mtime_t i_last;
mtime_t i_next;
};
/* The SAP handler, running in a separate thread */
struct sap_handler_t
{
VLC_COMMON_MEMBERS /* needed to create a thread */
sap_session_t **pp_sessions;
sap_address_t **pp_addresses;
vlc_bool_t b_control;
int i_sessions;
int i_addresses;
int i_current_session;
int (*pf_add) ( sap_handler_t*, session_descriptor_t *,announce_method_t*);
int (*pf_del) ( sap_handler_t*, session_descriptor_t *);
};
/* The main announce handler object */
struct announce_handler_t
{
VLC_COMMON_MEMBERS
sap_handler_t *p_sap;
};
/* End */
static inline sout_cfg_t *sout_cfg_find( sout_cfg_t *p_cfg, char *psz_name )
{
while( p_cfg && strcmp( p_cfg->psz_name, psz_name ) )
......@@ -205,6 +307,9 @@ static inline char *sout_cfg_find_value( sout_cfg_t *p_cfg, char *psz_name )
return NULL;
}
/*****************************************************************************
* Prototypes
*****************************************************************************/
......@@ -232,3 +337,25 @@ VLC_EXPORT( char *, sout_cfg_parser, ( char **, sout_cfg_t **, char
VLC_EXPORT( sout_stream_t *, sout_stream_new, ( sout_instance_t *, char *psz_chain ) );
VLC_EXPORT( void, sout_stream_delete, ( sout_stream_t *p_stream ) );
/* Announce system */
VLC_EXPORT( int, sout_AnnounceRegister, (sout_instance_t *,session_descriptor_t*, announce_method_t* ) );
VLC_EXPORT(session_descriptor_t*,sout_AnnounceRegisterSDP, (sout_instance_t *,char *, announce_method_t* ) );
VLC_EXPORT( int, sout_AnnounceUnRegister, (sout_instance_t *,session_descriptor_t* ) );
VLC_EXPORT(session_descriptor_t*,sout_AnnounceSessionCreate, () );
VLC_EXPORT(void, sout_AnnounceSessionDestroy, (session_descriptor_t *) );
VLC_EXPORT(announce_method_t*, sout_AnnounceMethodCreate, (int) );
#define announce_HandlerCreate(a) __announce_HandlerCreate(VLC_OBJECT(a))
announce_handler_t* __announce_HandlerCreate( vlc_object_t *);
/* Private functions for the announce handler */
int announce_HandlerDestroy( announce_handler_t * );
int announce_Register( announce_handler_t *p_announce,
session_descriptor_t *p_session,
announce_method_t *p_method );
int announce_UnRegister( announce_handler_t *p_announce,
session_descriptor_t *p_session );
sap_handler_t *announce_SAPHandlerCreate( announce_handler_t *p_announce );
void announce_SAPHandlerDestroy( sap_handler_t *p_sap );
......@@ -2,7 +2,7 @@
* vlc.h: global header for vlc
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: vlc.h,v 1.30 2004/01/25 18:17:08 zorglub Exp $
* $Id$
*
* 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
......@@ -19,6 +19,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/**
* \defgroup libvlc Libvlc
* This is libvlc.
*
* @{
*/
#ifndef _VLC_VLC_H
#define _VLC_VLC_H 1
......@@ -33,6 +41,9 @@ typedef int vlc_bool_t;
typedef struct vlc_list_t vlc_list_t;
typedef struct vlc_object_t vlc_object_t;
/**
* VLC value structure
*/
typedef union
{
int i_int;
......@@ -56,6 +67,9 @@ typedef union
} vlc_value_t;
/**
* VLC list structure
*/
struct vlc_list_t
{
int i_count;
......@@ -102,7 +116,9 @@ struct vlc_list_t
#define PLAYLIST_END -666
/** Playlist commands */
/**
* Playlist commands
*/
typedef enum {
PLAYLIST_PLAY, /**< Starts playing. No arg. */
PLAYLIST_PAUSE, /**< Toggles playlist pause. No arg. */
......@@ -122,16 +138,94 @@ typedef enum {
/*****************************************************************************
* Exported libvlc API
*****************************************************************************/
/**
* Retrieve libvlc version
*
* \return a string containing the libvlc version
*/
char const * VLC_Version ( void );
char const * VLC_Error ( int );
/**
* Return an error string
*
* \param i_err an error code
* \return an error string
*/
char const * VLC_Error ( int i_err );
/**
* Initialize libvlc
*
* This function allocates a vlc_t structure and returns a negative value
* in case of failure. Also, the thread system is initialized
*
* \return vlc object id or an error code
*/
int VLC_Create ( void );
/**
* Initialize a vlc_t structure
*
* This function initializes a previously allocated vlc_t structure:
* - CPU detection
* - gettext initialization
* - message queue, module bank and playlist initialization
* - configuration and commandline parsing
*
* \param i_object a vlc object id
* \param i_argc the number of arguments
* \param ppsz_argv an array of arguments
* \return VLC_SUCCESS on success
*/
int VLC_Init ( int, int, char *[] );
/**
* Ask vlc to die
*
* This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
* task. It is your duty to call VLC_End and VLC_Destroy afterwards.
*
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
*/
int VLC_Die ( int );
/**
* Stop playing and destroy everything.
*
* This function requests the running threads to finish, waits for their
* termination, and destroys their structure.
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
*/
int VLC_Destroy ( int );
/**
* Set a VLC variable
*
* This function sets a variable of VLC
*
* \param i_object a vlc object id
* \param psz_var a vlc variable name
* \param value a vlc_value_t structure
* \return VLC_SUCCESS on success
*/
int VLC_Set ( int, char const *, vlc_value_t );
/**
* Get a VLC variable
*
* This function gets the value of a variable of VLC
* It stores it in the p_value argument
*
* \param i_object a vlc object id
* \param psz_var a vlc variable name
* \param p_value a pointer to a vlc_value_t structure
* \return VLC_SUCCESS on success
*/
int VLC_Get ( int, char const *, vlc_value_t * );
int VLC_AddIntf ( int, char const *, vlc_bool_t );
int VLC_AddTarget ( int, char const *, const char **, int, int, int );
......
......@@ -272,8 +272,13 @@ typedef struct sout_access_out_t sout_access_out_t;
typedef struct sout_mux_t sout_mux_t;
typedef struct sout_stream_t sout_stream_t;
typedef struct sout_cfg_t sout_cfg_t;
/*typedef struct sap_session_t sap_session_t;
typedef struct slp_session_t slp_session_t;*/
typedef struct sap_session_t sap_session_t;
typedef struct sap_address_t sap_address_t;
typedef struct session_descriptor_t session_descriptor_t;
typedef struct announce_method_t announce_method_t;
typedef struct announce_handler_t announce_handler_t;
typedef struct sap_handler_t sap_handler_t;
//typedef struct slp_session_t slp_session_t;
/* Decoders */
typedef struct decoder_t decoder_t;
......
......@@ -48,6 +48,7 @@
#define VLC_OBJECT_ENCODER (-14)
#define VLC_OBJECT_DIALOGS (-15)
#define VLC_OBJECT_VLM (-16)
#define VLC_OBJECT_ANNOUNCE (-17)
#define VLC_OBJECT_GENERIC (-666)
......
/*****************************************************************************
* sap.c : SAP interface module
*****************************************************************************
......@@ -527,6 +526,7 @@ static void Run( intf_thread_t *p_intf )
msg_Warn( p_intf, "ditching sap packet" );
}
memset( buffer, 0, MAX_SAP_BUFFER );
}
}
......@@ -972,7 +972,7 @@ static sess_descr_t * parse_sdp( intf_thread_t * p_intf, char *p_packet )
if( p_packet[1] != '=' )
{
msg_Warn( p_intf, "packet invalid" );
msg_Warn( p_intf, "invalid packet") ;
free_sd( sd );
return NULL;
}
......
......@@ -138,12 +138,12 @@ char * SDPGenerateUDP(char * psz_name_arg,char * psz_url_arg)
/*****************************************************************************
* sout_SAPNew: Creates a SAP Session
*****************************************************************************/
sap_session_t * sout_SAPNew ( sout_instance_t *p_sout,
sap_session_t2 * sout_SAPNew ( sout_instance_t *p_sout,
char * psz_sdp_arg,
int ip_version,
char * psz_v6_scope )
{
sap_session_t *p_sap; /* The SAP structure */
sap_session_t2 *p_sap; /* The SAP structure */
char *sap_ipv6_addr = NULL; /* IPv6 built address */
vlc_value_t val;
......@@ -151,7 +151,7 @@ sap_session_t * sout_SAPNew ( sout_instance_t *p_sout,
var_Create( p_sout, "ipv4", VLC_VAR_BOOL );
/* Allocate the SAP structure */
p_sap = (sap_session_t *) malloc( sizeof ( sap_session_t ) ) ;
p_sap = (sap_session_t2 *) malloc( sizeof ( sap_session_t2 ) ) ;
if ( !p_sap )
{
msg_Err( p_sout, "out of memory" );
......@@ -214,7 +214,7 @@ sap_session_t * sout_SAPNew ( sout_instance_t *p_sout,
/*****************************************************************************
* sout_SAPDelete: Deletes a SAP Session
*****************************************************************************/
void sout_SAPDelete( sout_instance_t *p_sout, sap_session_t * p_sap )
void sout_SAPDelete( sout_instance_t *p_sout, sap_session_t2 * p_sap )
{
int i_ret;
......@@ -243,7 +243,7 @@ void sout_SAPDelete( sout_instance_t *p_sout, sap_session_t * p_sap )
/*****************************************************************************
* sout_SAPSend: Sends a SAP packet
*****************************************************************************/
void sout_SAPSend( sout_instance_t *p_sout, sap_session_t * p_sap )
void sout_SAPSend( sout_instance_t *p_sout, sap_session_t2 * p_sap )
{
char *psz_msg; /* SDP content */
char *psz_head; /* SAP header */
......
......@@ -51,7 +51,7 @@
/*****************************************************************************
* sap_session_t: SAP Session descriptor
*****************************************************************************/
struct sap_session_t
struct sap_session_t2
{
char * psz_sdp;
module_t p_network;
......@@ -60,7 +60,7 @@ struct sap_session_t
int i_ip_version;
};
typedef struct sap_session_t sap_session_t;
typedef struct sap_session_t2 sap_session_t2;
/*****************************************************************************
* slp_session_t: SLP Session descriptor
*****************************************************************************/
......@@ -75,12 +75,13 @@ typedef struct slp_session_t slp_session_t;
/*****************************************************************************
* Prototypes
*****************************************************************************/
sap_session_t2 * sout_SAPNew (sout_instance_t *, char * psz_sdp_arg,
int ip_version,
char * psz_v6_scope );
char * SDPGenerateUDP(char * ,char *);
sap_session_t * sout_SAPNew (sout_instance_t *,
char* , int, char *);
void sout_SAPDelete (sout_instance_t *,sap_session_t*);
void sout_SAPSend (sout_instance_t *,sap_session_t *);
void sout_SAPDelete (sout_instance_t *,sap_session_t2*);
void sout_SAPSend (sout_instance_t *,sap_session_t2 *);
int sout_SLPReg (sout_instance_t *,char *,char *);
int sout_SLPDereg (sout_instance_t *,char *,char *);
......
......@@ -76,9 +76,14 @@ struct sout_stream_sys_t
int64_t i_sdp_id;
int i_sdp_version;
char *psz_sdp;
vlc_mutex_t lock_sdp;
char *psz_session_name;
/* sap */
vlc_bool_t b_export_sap;
session_descriptor_t *p_session;
httpd_host_t *p_httpd_host;
httpd_file_t *p_httpd_file;
......@@ -155,6 +160,7 @@ struct sout_stream_id_t
static int AccessOutGrabberWrite( sout_access_out_t *, block_t * );
static int SapSetup( sout_stream_t *p_stream );
static int HttpSetup( sout_stream_t *p_stream, vlc_url_t * );
static int RtspSetup( sout_stream_t *p_stream, vlc_url_t * );
......@@ -181,6 +187,7 @@ static int Open( vlc_object_t *p_this )
p_sys = malloc( sizeof( sout_stream_sys_t ) );
p_sys->psz_destination = sout_cfg_find_value( p_stream->p_cfg, "dst" );
p_sys->psz_session_name = sout_cfg_find_value( p_stream->p_cfg, "name" );
if( ( val = sout_cfg_find_value( p_stream->p_cfg, "port" ) ) )
{
p_sys->i_port = atoi( val );
......@@ -190,6 +197,18 @@ static int Open( vlc_object_t *p_this )
p_sys->i_port = 1234;
}
if( !p_sys->psz_session_name )
{
if( p_sys->psz_destination )
{
p_sys->psz_session_name = strdup( p_sys->psz_destination );
}
else
{
p_sys->psz_session_name = strdup( "NONE" );
}
}
if( !p_sys->psz_destination || *p_sys->psz_destination == '\0' )
{
val = sout_cfg_find_value( p_stream->p_cfg, "sdp" );
......@@ -227,6 +246,10 @@ static int Open( vlc_object_t *p_this )
p_sys->i_sdp_id = mdate();
p_sys->i_sdp_version = 1;
p_sys->psz_sdp = NULL;
p_sys->b_export_sap = VLC_FALSE;
p_sys->p_session = NULL;
p_sys->p_httpd_host = NULL;
p_sys->p_httpd_file = NULL;
p_sys->p_rtsp_host = NULL;
......@@ -320,15 +343,15 @@ static int Open( vlc_object_t *p_this )
sprintf( p_sys->psz_sdp,
"v=0\n"
"o=- "I64Fd" %d IN IP4 127.0.0.1\n"
"s=NONE\n"
"s=%s\n"
"c=IN IP4 %s/%d\n"
"m=video %d RTP/AVP %d\n"
"a=rtpmap:%d %s\n",
p_sys->i_sdp_id, p_sys->i_sdp_version,
p_sys->psz_session_name,
p_sys->psz_destination, p_sys->i_ttl,
p_sys->i_port, p_sys->i_payload_type,
p_sys->i_payload_type, psz_rtpmap );
fprintf( stderr, "sdp=%s", p_sys->psz_sdp );
/* create the rtp context */
......@@ -367,6 +390,11 @@ static int Open( vlc_object_t *p_this )
msg_Err( p_stream, "cannot export sdp as rtsp" );
}
}
else if( url.psz_protocol && !strcasecmp( url.psz_protocol, "sap" ) )
{
p_sys->b_export_sap = VLC_TRUE;
SapSetup( p_stream );
}
else
{
msg_Warn( p_stream, "unknow protocol for SDP (%s)",
......@@ -426,7 +454,13 @@ static void Close( vlc_object_t * p_this )
{
httpd_HostDelete( p_sys->p_rtsp_host );
}
#if 0
if( p_sys->psz_session_name )
{
free( p_sys->psz_session_name );
p_sys->psz_session_name = NULL;
}
#endif
if( p_sys->psz_sdp )
{
free( p_sys->psz_sdp );
......@@ -446,9 +480,10 @@ static char *SDPGenerate( sout_stream_t *p_stream, char *psz_destination, vlc_bo
i_size = strlen( "v=0\n" ) +
strlen( "o=- * * IN IP4 127.0.0.1\n" ) +
strlen( "s=NONE\n" ) +
strlen( "s=\n" ) +
strlen( "c=IN IP4 */*\n" ) +
strlen( psz_destination ? psz_destination : "0.0.0.0") +
strlen( p_sys->psz_session_name ) +
20 + 10 + 10 + 1;
for( i = 0; i < p_sys->i_es; i++ )
{
......@@ -473,7 +508,7 @@ static char *SDPGenerate( sout_stream_t *p_stream, char *psz_destination, vlc_bo
p += sprintf( p, "v=0\n" );
p += sprintf( p, "o=- "I64Fd" %d IN IP4 127.0.0.1\n",
p_sys->i_sdp_id, p_sys->i_sdp_version );
p += sprintf( p, "s=NONE\n" );
p += sprintf( p, "s=%s\n", p_sys->psz_session_name );
p += sprintf( p, "c=IN IP4 %s/%d\n", psz_destination ? psz_destination : "0.0.0.0",
p_sys->i_ttl );
......@@ -746,6 +781,12 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
p_sys->i_sdp_version++;
fprintf( stderr, "sdp=%s", p_sys->psz_sdp );
/* Update the SAP announce */
if( p_sys->b_export_sap )
{
SapSetup( p_stream );
}
}
return id;
......@@ -784,6 +825,12 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
vlc_mutex_destroy( &id->lock_rtsp );
if( id->rtsp_access ) free( id->rtsp_access );
/* Update the SAP announce */
if( p_sys->b_export_sap )
{
SapSetup( p_stream );
}
free( id );
return VLC_SUCCESS;
}
......@@ -899,6 +946,37 @@ static int AccessOutGrabberWrite( sout_access_out_t *p_access,
return VLC_SUCCESS;
}
/****************************************************************************
* SAP:
****************************************************************************/
static int SapSetup( sout_stream_t *p_stream )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
sout_instance_t *p_sout = p_stream->p_sout;
announce_method_t *p_method = (announce_method_t *)
malloc(sizeof(announce_method_t));
/* Remove the previous session */
if( p_sys->p_session != NULL)
{
sout_AnnounceUnRegister( p_sout, p_sys->p_session);
sout_AnnounceSessionDestroy( p_sys->p_session );
p_sys->p_session = NULL;
}
p_method->i_type = METHOD_TYPE_SAP;
p_method->psz_address = NULL; /* FIXME */
p_method->i_ip_version = 4; /* FIXME ! */
if( p_sys->i_es > 0 && p_sys->psz_sdp && *p_sys->psz_sdp )
{
p_sys->p_session = sout_AnnounceRegisterSDP( p_sout, p_sys->psz_sdp,
p_method );
}
free( p_method );
return VLC_SUCCESS;
}
/****************************************************************************
* HTTP:
****************************************************************************/
......
......@@ -30,9 +30,12 @@
#include <vlc/vlc.h>
#include <vlc/sout.h>
#include "announce.h"
#include "network.h"
#define DEFAULT_IPV6_SCOPE "8"
#define DEFAULT_IPV6_SCOPE '8'
#define DEFAULT_PORT 1234
/*****************************************************************************
* Exported prototypes
......@@ -59,7 +62,7 @@ struct sout_stream_sys_t
{
sout_mux_t *p_mux;
slp_session_t *p_slp;
sap_session_t *p_sap;
session_descriptor_t *p_session;
};
/*****************************************************************************
......@@ -70,15 +73,14 @@ static int Open( vlc_object_t *p_this )
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_instance_t *p_sout = p_stream->p_sout;
slp_session_t *p_slp = NULL;
sap_session_t *p_sap = NULL;
session_descriptor_t *p_session = NULL;
char *psz_mux = sout_cfg_find_value( p_stream->p_cfg, "mux" );
char *psz_access = sout_cfg_find_value( p_stream->p_cfg, "access" );
char *psz_url = sout_cfg_find_value( p_stream->p_cfg, "url" );
char *psz_ipv = sout_cfg_find_value( p_stream->p_cfg, "sap_ipv" );
char *psz_v6_scope = sout_cfg_find_value( p_stream->p_cfg, "sap_v6scope" );
char *psz_sdp = NULL;
vlc_url_t *p_url;
sout_cfg_t *p_sap_cfg = sout_cfg_find( p_stream->p_cfg, "sap" );
#ifdef HAVE_SLP_H
sout_cfg_t *p_slp_cfg = sout_cfg_find( p_stream->p_cfg, "slp" );
......@@ -89,6 +91,9 @@ static int Open( vlc_object_t *p_this )
char *psz_mux_byext = NULL;
p_stream->p_sys = malloc( sizeof( sout_stream_sys_t) );
p_stream->p_sys->p_session = NULL;
msg_Dbg( p_this, "creating `%s/%s://%s'",
psz_access, psz_mux, psz_url );
......@@ -240,29 +245,92 @@ static int Open( vlc_object_t *p_this )
msg_Dbg( p_stream, "mux opened" );
/* *** Create the SAP Session structure *** */
if( psz_access &&
p_sap_cfg &&
( strstr( psz_access, "udp" ) || strstr( psz_access , "rtp" ) ) )
if( psz_access && p_sap_cfg && ( strstr( psz_access, "udp" ) ||
strstr( psz_access , "rtp" ) ) )
{
msg_Info( p_this, "SAP Enabled");
session_descriptor_t *p_session= sout_AnnounceSessionCreate();
announce_method_t *p_method = sout_AnnounceMethodCreate(
METHOD_TYPE_SAP);
if( psz_ipv == NULL )
/* Parse user input */
if( p_sap_cfg->psz_value )
{
char *psz_sap = p_sap_cfg->psz_value;
/* subconfig */
if( ! strncmp(psz_sap, "sap{", 4 ) )
{
sout_cfg_t *p_cfg;
char *psz_curr,*psz_null;
sout_cfg_parser( &psz_null, &p_cfg, psz_sap );
psz_curr = sout_cfg_find_value( p_cfg,"name");
if( psz_curr != NULL)
{
p_session->psz_name = strdup( psz_curr );
}
else
{
p_session->psz_name = strdup( psz_url );
}
psz_curr = sout_cfg_find_value( p_cfg,"ip_version");
if( psz_curr != NULL)
{
p_method->i_ip_version = atoi( psz_curr ) != 0 ?
atoi(psz_curr) :
4;