[vlc-commits] raop: remove obsolete and unmaintained plugin

Rémi Denis-Courmont git at videolan.org
Sun Oct 8 11:31:13 CEST 2017


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Oct  8 12:16:53 2017 +0300| [10c2c932afe8e980575b1896405b7bee5e78043b] | committer: Rémi Denis-Courmont

raop: remove obsolete and unmaintained plugin

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=10c2c932afe8e980575b1896405b7bee5e78043b
---

 NEWS                           |    1 +
 modules/MODULES_LIST           |    1 -
 modules/stream_out/Makefile.am |    8 -
 modules/stream_out/raop.c      | 1637 ----------------------------------------
 po/POTFILES.in                 |    1 -
 5 files changed, 1 insertion(+), 1647 deletions(-)

diff --git a/NEWS b/NEWS
index 31c61baab1..2d3f04e628 100644
--- a/NEWS
+++ b/NEWS
@@ -308,6 +308,7 @@ Removed modules
  * Audioqueue: use audiounit
  * SDL video output module
  * DirectFB video output module
+ * RAOP stream output module
 
 
 Changes between 2.2.5 and 2.2.5.1:
diff --git a/modules/MODULES_LIST b/modules/MODULES_LIST
index 5fb499eda2..b896aa183b 100644
--- a/modules/MODULES_LIST
+++ b/modules/MODULES_LIST
@@ -387,7 +387,6 @@ $Id$
  * stream_out_es: stream out module outputing ES
  * stream_out_gather: stream out module gathering inputs for seemless transitions
  * stream_out_mosaic_bridge: stream output module to make a mosaic. To be used with VLM
- * stream_out_raop: Remote Audio Output Protocol (AirTunes) stream out
  * stream_out_record: record stream output module
  * stream_out_rtp: rtp stream output module
  * stream_out_setid: Set the ID/Lang of an ES when streaming
diff --git a/modules/stream_out/Makefile.am b/modules/stream_out/Makefile.am
index 8a536d302e..8a1b42d34d 100644
--- a/modules/stream_out/Makefile.am
+++ b/modules/stream_out/Makefile.am
@@ -59,14 +59,6 @@ libstream_out_rtp_plugin_la_CFLAGS += -DHAVE_SRTP $(SRTP_CFLAGS) \
 libstream_out_rtp_plugin_la_LIBADD += $(SRTP_LIBS) $(GCRYPT_LIBS)
 endif
 
-# RAOP plugin
-libstream_out_raop_plugin_la_SOURCES = stream_out/raop.c
-libstream_out_raop_plugin_la_CFLAGS = $(AM_CFLAGS) $(GCRYPT_CFLAGS)
-libstream_out_raop_plugin_la_LIBADD = $(GCRYPT_LIBS) -lgpg-error $(SOCKET_LIBS) $(LIBS_stream_out_raop)
-if HAVE_GCRYPT
-sout_LTLIBRARIES += libstream_out_raop_plugin.la
-endif
-
 # Chromaprint plugin
 libstream_out_chromaprint_plugin_la_SOURCES = stream_out/chromaprint.c stream_out/chromaprint_data.h dummy.cpp
 libstream_out_chromaprint_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(CHROMAPRINT_CFLAGS)
diff --git a/modules/stream_out/raop.c b/modules/stream_out/raop.c
deleted file mode 100644
index 0903fc9ac0..0000000000
--- a/modules/stream_out/raop.c
+++ /dev/null
@@ -1,1637 +0,0 @@
-/*****************************************************************************
- * raop.c: Remote Audio Output Protocol streaming support
- *****************************************************************************
- * Copyright (C) 2008 VLC authors and VideoLAN
- * $Id$
- *
- * Author: Michael Hanselmann
- *
- * 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 <assert.h>
-
-#include <gcrypt.h>
-
-#include <vlc_common.h>
-#include <vlc_plugin.h>
-#include <vlc_sout.h>
-#include <vlc_block.h>
-#include <vlc_network.h>
-#include <vlc_strings.h>
-#include <vlc_charset.h>
-#include <vlc_fs.h>
-#include <vlc_gcrypt.h>
-#include <vlc_es.h>
-#include <vlc_http.h>
-#include <vlc_memory.h>
-#include <vlc_memstream.h>
-
-#define RAOP_PORT 5000
-#define RAOP_USER_AGENT "VLC " VERSION
-
-
-static const char ps_raop_rsa_pubkey[] =
-    "\xe7\xd7\x44\xf2\xa2\xe2\x78\x8b\x6c\x1f\x55\xa0\x8e\xb7\x05\x44"
-    "\xa8\xfa\x79\x45\xaa\x8b\xe6\xc6\x2c\xe5\xf5\x1c\xbd\xd4\xdc\x68"
-    "\x42\xfe\x3d\x10\x83\xdd\x2e\xde\xc1\xbf\xd4\x25\x2d\xc0\x2e\x6f"
-    "\x39\x8b\xdf\x0e\x61\x48\xea\x84\x85\x5e\x2e\x44\x2d\xa6\xd6\x26"
-    "\x64\xf6\x74\xa1\xf3\x04\x92\x9a\xde\x4f\x68\x93\xef\x2d\xf6\xe7"
-    "\x11\xa8\xc7\x7a\x0d\x91\xc9\xd9\x80\x82\x2e\x50\xd1\x29\x22\xaf"
-    "\xea\x40\xea\x9f\x0e\x14\xc0\xf7\x69\x38\xc5\xf3\x88\x2f\xc0\x32"
-    "\x3d\xd9\xfe\x55\x15\x5f\x51\xbb\x59\x21\xc2\x01\x62\x9f\xd7\x33"
-    "\x52\xd5\xe2\xef\xaa\xbf\x9b\xa0\x48\xd7\xb8\x13\xa2\xb6\x76\x7f"
-    "\x6c\x3c\xcf\x1e\xb4\xce\x67\x3d\x03\x7b\x0d\x2e\xa3\x0c\x5f\xff"
-    "\xeb\x06\xf8\xd0\x8a\xdd\xe4\x09\x57\x1a\x9c\x68\x9f\xef\x10\x72"
-    "\x88\x55\xdd\x8c\xfb\x9a\x8b\xef\x5c\x89\x43\xef\x3b\x5f\xaa\x15"
-    "\xdd\xe6\x98\xbe\xdd\xf3\x59\x96\x03\xeb\x3e\x6f\x61\x37\x2b\xb6"
-    "\x28\xf6\x55\x9f\x59\x9a\x78\xbf\x50\x06\x87\xaa\x7f\x49\x76\xc0"
-    "\x56\x2d\x41\x29\x56\xf8\x98\x9e\x18\xa6\x35\x5b\xd8\x15\x97\x82"
-    "\x5e\x0f\xc8\x75\x34\x3e\xc7\x82\x11\x76\x25\xcd\xbf\x98\x44\x7b";
-
-static const char ps_raop_rsa_exp[] = "\x01\x00\x01";
-
-static const char psz_delim_space[] = " ";
-static const char psz_delim_colon[] = ":";
-static const char psz_delim_equal[] = "=";
-static const char psz_delim_semicolon[] = ";";
-
-
-/*****************************************************************************
- * Prototypes
- *****************************************************************************/
-static int Open( vlc_object_t * );
-static void Close( vlc_object_t * );
-
-static sout_stream_id_sys_t *Add( sout_stream_t *, const es_format_t * );
-static void Del( sout_stream_t *, sout_stream_id_sys_t * );
-static int Send( sout_stream_t *, sout_stream_id_sys_t *, block_t* );
-
-static int VolumeCallback( vlc_object_t *p_this, char const *psz_cmd,
-                           vlc_value_t oldval, vlc_value_t newval,
-                           void *p_data );
-
-typedef enum
-{
-    JACK_TYPE_NONE = 0,
-    JACK_TYPE_ANALOG,
-    JACK_TYPE_DIGITAL,
-} jack_type_t;
-
-struct sout_stream_sys_t
-{
-    /* Input parameters */
-    char *psz_host;
-    char *psz_password;
-    int i_volume;
-
-    /* Plugin status */
-    sout_stream_id_sys_t *p_audio_stream;
-    bool b_alac_warning;
-    bool b_volume_callback;
-
-    /* Connection state */
-    int i_control_fd;
-    int i_stream_fd;
-
-    uint8_t ps_aes_key[16];
-    uint8_t ps_aes_iv[16];
-    gcry_cipher_hd_t aes_ctx;
-
-    char *psz_url;
-    char *psz_client_instance;
-    char *psz_session;
-    char *psz_last_status_line;
-
-    int i_cseq;
-    int i_server_port;
-    int i_audio_latency;
-    int i_jack_type;
-
-    vlc_http_auth_t auth;
-
-    /* Send buffer */
-    size_t i_sendbuf_len;
-    uint8_t *p_sendbuf;
-};
-
-struct sout_stream_id_sys_t
-{
-    es_format_t fmt;
-};
-
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-#define SOUT_CFG_PREFIX "sout-raop-"
-
-#define HOST_TEXT N_("Host")
-#define HOST_LONGTEXT N_("Hostname or IP address of target device")
-
-#define VOLUME_TEXT N_("Volume")
-#define VOLUME_LONGTEXT N_("Output volume for analog output: 0 for silence, " \
-                           "1..255 from almost silent to very loud.")
-
-#define PASSWORD_TEXT N_("Password")
-#define PASSWORD_LONGTEXT N_("Password for target device.")
-
-#define PASSWORD_FILE_TEXT N_("Password file")
-#define PASSWORD_FILE_LONGTEXT N_("Read password for target device from file.")
-
-vlc_module_begin();
-    set_shortname( N_("RAOP") )
-    set_description( N_("Remote Audio Output Protocol stream output") )
-    set_capability( "sout stream", 0 )
-    add_shortcut( "raop" )
-    set_category( CAT_SOUT )
-    set_subcategory( SUBCAT_SOUT_STREAM )
-    add_string( SOUT_CFG_PREFIX "host", "",
-                HOST_TEXT, HOST_LONGTEXT, false )
-    add_password( SOUT_CFG_PREFIX "password", NULL,
-                  PASSWORD_TEXT, PASSWORD_LONGTEXT, false )
-    add_loadfile( SOUT_CFG_PREFIX "password-file", NULL,
-              PASSWORD_FILE_TEXT, PASSWORD_FILE_LONGTEXT, false )
-    add_integer_with_range( SOUT_CFG_PREFIX "volume", 100, 0, 255,
-                            VOLUME_TEXT, VOLUME_LONGTEXT, false )
-    set_callbacks( Open, Close )
-vlc_module_end()
-
-static const char *const ppsz_sout_options[] = {
-    "host",
-    "password",
-    "password-file",
-    "volume",
-    NULL
-};
-
-
-/*****************************************************************************
- * Utilities:
- *****************************************************************************/
-static void FreeSys( vlc_object_t *p_this, sout_stream_sys_t *p_sys )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-
-    if ( p_sys->i_control_fd >= 0 )
-        net_Close( p_sys->i_control_fd );
-    if ( p_sys->i_stream_fd >= 0 )
-        net_Close( p_sys->i_stream_fd );
-    if ( p_sys->b_volume_callback )
-        var_DelCallback( p_stream, SOUT_CFG_PREFIX "volume",
-                         VolumeCallback, NULL );
-
-    gcry_cipher_close( p_sys->aes_ctx );
-
-    free( p_sys->p_sendbuf );
-    free( p_sys->psz_host );
-    free( p_sys->psz_password );
-    free( p_sys->psz_url );
-    free( p_sys->psz_session );
-    free( p_sys->psz_client_instance );
-    free( p_sys->psz_last_status_line );
-    vlc_http_auth_Deinit( &p_sys->auth );
-    free( p_sys );
-}
-
-static void FreeId( sout_stream_id_sys_t *id )
-{
-    free( id );
-}
-
-static void RemoveBase64Padding( char *str )
-{
-    char *ps_pos = strchr( str, '=' );
-    if ( ps_pos != NULL )
-        *ps_pos = '\0';
-}
-
-static int CheckForGcryptErrorWithLine( sout_stream_t *p_stream,
-                                        gcry_error_t i_gcrypt_err,
-                                        unsigned int i_line )
-{
-    if ( i_gcrypt_err != GPG_ERR_NO_ERROR )
-    {
-        msg_Err( p_stream, "gcrypt error (line %d): %s", i_line,
-                 gpg_strerror( i_gcrypt_err ) );
-        return 1;
-    }
-
-    return 0;
-}
-
-/* Wrapper to pass line number for easier debugging */
-#define CheckForGcryptError( p_this, i_gcrypt_err ) \
-    CheckForGcryptErrorWithLine( p_this, i_gcrypt_err, __LINE__ )
-
-/* MGF1 is specified in RFC2437, section 10.2.1. Variables are named after the
- * specification.
- */
-static int MGF1( vlc_object_t *p_this,
-                 unsigned char *mask, size_t l,
-                 const unsigned char *Z, const size_t zLen,
-                 const int Hash )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    gcry_error_t i_gcrypt_err;
-    gcry_md_hd_t md_handle = NULL;
-    unsigned int hLen;
-    unsigned char *ps_md;
-    uint32_t counter = 0;
-    uint8_t C[4];
-    size_t i_copylen;
-    int i_err = VLC_SUCCESS;
-
-    assert( mask != NULL );
-    assert( Z != NULL );
-
-    hLen = gcry_md_get_algo_dlen( Hash );
-
-    i_gcrypt_err = gcry_md_open( &md_handle, Hash, 0 );
-    if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-    {
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-
-    while ( l > 0 )
-    {
-        /* 3. For counter from 0 to \lceil{l / hLen}\rceil-1, do the following:
-         * a. Convert counter to an octet string C of length 4 with the
-         *    primitive I2OSP: C = I2OSP (counter, 4)
-         */
-        C[0] = (counter >> 24) & 0xff;
-        C[1] = (counter >> 16) & 0xff;
-        C[2] = (counter >> 8) & 0xff;
-        C[3] = counter & 0xff;
-        ++counter;
-
-        /* b. Concatenate the hash of the seed Z and C to the octet string T:
-         *    T = T || Hash (Z || C)
-         */
-        gcry_md_reset( md_handle );
-        gcry_md_write( md_handle, Z, zLen );
-        gcry_md_write( md_handle, C, 4 );
-        ps_md = gcry_md_read( md_handle, Hash );
-
-        /* 4. Output the leading l octets of T as the octet string mask. */
-        i_copylen = __MIN( l, hLen );
-        memcpy( mask, ps_md, i_copylen );
-        mask += i_copylen;
-        l -= i_copylen;
-    }
-
-error:
-    gcry_md_close( md_handle );
-
-    return i_err;
-}
-
-/* EME-OAEP-ENCODE is specified in RFC2437, section 9.1.1.1. Variables are
- * named after the specification.
- */
-static int AddOaepPadding( vlc_object_t *p_this,
-                           unsigned char *EM, const size_t emLenWithPrefix,
-                           const unsigned char *M, const size_t mLen,
-                           const unsigned char *P, const size_t pLen )
-{
-    const int Hash = GCRY_MD_SHA1;
-    const unsigned int hLen = gcry_md_get_algo_dlen( Hash );
-    unsigned char *seed = NULL;
-    unsigned char *DB = NULL;
-    unsigned char *dbMask = NULL;
-    unsigned char *seedMask = NULL;
-    size_t emLen;
-    size_t psLen;
-    size_t i;
-    int i_err = VLC_SUCCESS;
-
-    /* Space for 0x00 prefix in EM. */
-    emLen = emLenWithPrefix - 1;
-
-    /* Step 2:
-     * If ||M|| > emLen-2hLen-1 then output "message too long" and stop.
-     */
-    if ( mLen > (emLen - (2 * hLen) - 1) )
-    {
-        msg_Err( p_this , "Message too long" );
-        goto error;
-    }
-
-    /* Step 3:
-     * Generate an octet string PS consisting of emLen-||M||-2hLen-1 zero
-     * octets. The length of PS may be 0.
-     */
-    psLen = emLen - mLen - (2 * hLen) - 1;
-
-    /*
-     * Step 5:
-     * Concatenate pHash, PS, the message M, and other padding to form a data
-     * block DB as: DB = pHash || PS || 01 || M
-     */
-    DB = calloc( 1, hLen + psLen + 1 + mLen );
-    dbMask = calloc( 1, emLen - hLen );
-    seedMask = calloc( 1, hLen );
-
-    if ( DB == NULL || dbMask == NULL || seedMask == NULL )
-    {
-        i_err = VLC_ENOMEM;
-        goto error;
-    }
-
-    /* Step 4:
-     * Let pHash = Hash(P), an octet string of length hLen.
-     */
-    gcry_md_hash_buffer( Hash, DB, P, pLen );
-
-    /* Step 3:
-     * Generate an octet string PS consisting of emLen-||M||-2hLen-1 zero
-     * octets. The length of PS may be 0.
-     */
-    memset( DB + hLen, 0, psLen );
-
-    /* Step 5:
-     * Concatenate pHash, PS, the message M, and other padding to form a data
-     * block DB as: DB = pHash || PS || 01 || M
-     */
-    DB[hLen + psLen] = 0x01;
-    memcpy( DB + hLen + psLen + 1, M, mLen );
-
-    /* Step 6:
-     * Generate a random octet string seed of length hLen
-     */
-    seed = gcry_random_bytes( hLen, GCRY_STRONG_RANDOM );
-    if ( seed == NULL )
-    {
-        i_err = VLC_ENOMEM;
-        goto error;
-    }
-
-    /* Step 7:
-     * Let dbMask = MGF(seed, emLen-hLen).
-     */
-    i_err = MGF1( p_this, dbMask, emLen - hLen, seed, hLen, Hash );
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-
-    /* Step 8:
-     * Let maskedDB = DB \xor dbMask.
-     */
-    for ( i = 0; i < (emLen - hLen); ++i )
-        DB[i] ^= dbMask[i];
-
-    /* Step 9:
-     * Let seedMask = MGF(maskedDB, hLen).
-     */
-    i_err = MGF1( p_this, seedMask, hLen, DB, emLen - hLen, Hash );
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-
-    /* Step 10:
-     * Let maskedSeed = seed \xor seedMask.
-     */
-    for ( i = 0; i < hLen; ++i )
-        seed[i] ^= seedMask[i];
-
-    /* Step 11:
-     * Let EM = maskedSeed || maskedDB.
-     */
-    assert( (1 + hLen + (hLen + psLen + 1 + mLen)) == emLenWithPrefix );
-    EM[0] = 0x00;
-    memcpy( EM + 1, seed, hLen );
-    memcpy( EM + 1 + hLen, DB, hLen + psLen + 1 + mLen );
-
-    /* Step 12:
-     * Output EM.
-     */
-
-error:
-    free( DB );
-    free( dbMask );
-    free( seedMask );
-    free( seed );
-
-    return i_err;
-}
-
-static int EncryptAesKeyBase64( vlc_object_t *p_this, char **result )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    gcry_error_t i_gcrypt_err;
-    gcry_sexp_t sexp_rsa_params = NULL;
-    gcry_sexp_t sexp_input = NULL;
-    gcry_sexp_t sexp_encrypted = NULL;
-    gcry_sexp_t sexp_token_a = NULL;
-    gcry_mpi_t mpi_pubkey = NULL;
-    gcry_mpi_t mpi_exp = NULL;
-    gcry_mpi_t mpi_input = NULL;
-    gcry_mpi_t mpi_output = NULL;
-    unsigned char ps_padded_key[256];
-    unsigned char *ps_value;
-    size_t i_value_size;
-    int i_err;
-
-    /* Add RSA-OAES-SHA1 padding */
-    i_err = AddOaepPadding( p_this,
-                            ps_padded_key, sizeof( ps_padded_key ),
-                            p_sys->ps_aes_key, sizeof( p_sys->ps_aes_key ),
-                            NULL, 0 );
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-    i_err = VLC_EGENERIC;
-
-    /* Read public key */
-    i_gcrypt_err = gcry_mpi_scan( &mpi_pubkey, GCRYMPI_FMT_USG,
-                                  ps_raop_rsa_pubkey,
-                                  sizeof( ps_raop_rsa_pubkey ) - 1, NULL );
-    if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-        goto error;
-
-    /* Read exponent */
-    i_gcrypt_err = gcry_mpi_scan( &mpi_exp, GCRYMPI_FMT_USG, ps_raop_rsa_exp,
-                                  sizeof( ps_raop_rsa_exp ) - 1, NULL );
-    if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-        goto error;
-
-    /* If the input data starts with a set bit (0x80), gcrypt thinks it's a
-     * signed integer and complains. Prefixing it with a zero byte (\0)
-     * works, but involves more work. Converting it to an MPI in our code is
-     * cleaner.
-     */
-    i_gcrypt_err = gcry_mpi_scan( &mpi_input, GCRYMPI_FMT_USG,
-                                  ps_padded_key, sizeof( ps_padded_key ),
-                                  NULL);
-    if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-        goto error;
-
-    /* Build S-expression with RSA parameters */
-    i_gcrypt_err = gcry_sexp_build( &sexp_rsa_params, NULL,
-                                    "(public-key(rsa(n %m)(e %m)))",
-                                    mpi_pubkey, mpi_exp );
-    if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-        goto error;
-
-    /* Build S-expression for data */
-    i_gcrypt_err = gcry_sexp_build( &sexp_input, NULL, "(data(value %m))",
-                                    mpi_input );
-    if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-        goto error;
-
-    /* Encrypt data */
-    i_gcrypt_err = gcry_pk_encrypt( &sexp_encrypted, sexp_input,
-                                    sexp_rsa_params );
-    if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-        goto error;
-
-    /* Extract encrypted data */
-    sexp_token_a = gcry_sexp_find_token( sexp_encrypted, "a", 0 );
-    if ( !sexp_token_a )
-    {
-        msg_Err( p_this , "Token 'a' not found in result S-expression" );
-        goto error;
-    }
-
-    mpi_output = gcry_sexp_nth_mpi( sexp_token_a, 1, GCRYMPI_FMT_USG );
-    if ( !mpi_output )
-    {
-        msg_Err( p_this, "Unable to extract MPI from result" );
-        goto error;
-    }
-
-    /* Copy encrypted data into char array */
-    i_gcrypt_err = gcry_mpi_aprint( GCRYMPI_FMT_USG, &ps_value, &i_value_size,
-                                    mpi_output );
-    if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-    {
-        goto error;
-    }
-
-    /* Encode in Base64 */
-    *result = vlc_b64_encode_binary( ps_value, i_value_size );
-    i_err = VLC_SUCCESS;
-
-error:
-    gcry_sexp_release( sexp_rsa_params );
-    gcry_sexp_release( sexp_input );
-    gcry_sexp_release( sexp_encrypted );
-    gcry_sexp_release( sexp_token_a );
-    gcry_mpi_release( mpi_pubkey );
-    gcry_mpi_release( mpi_exp );
-    gcry_mpi_release( mpi_input );
-    gcry_mpi_release( mpi_output );
-
-    return i_err;
-}
-
-static char *ReadPasswordFile( vlc_object_t *p_this, const char *psz_path )
-{
-    FILE *p_file = NULL;
-    char *psz_password = NULL;
-    char *psz_newline;
-    char ps_buffer[256];
-
-    p_file = vlc_fopen( psz_path, "rt" );
-    if ( p_file == NULL )
-    {
-        msg_Err( p_this, "Unable to open password file '%s': %s", psz_path,
-                 vlc_strerror_c(errno) );
-        goto error;
-    }
-
-    /* Read one line only */
-    if ( fgets( ps_buffer, sizeof( ps_buffer ), p_file ) == NULL )
-    {
-        if ( ferror( p_file ) )
-        {
-            msg_Err( p_this, "Error reading '%s': %s", psz_path,
-                     vlc_strerror_c(errno) );
-            goto error;
-        }
-
-        /* Nothing was read, but there was no error either. Maybe the file is
-         * empty. Not all implementations of fgets(3) write \0 to the output
-         * buffer in this case.
-         */
-        ps_buffer[0] = '\0';
-
-    } else {
-        /* Replace first newline with '\0' */
-        psz_newline = strchr( ps_buffer, '\n' );
-        if ( psz_newline != NULL )
-            *psz_newline = '\0';
-    }
-
-    if ( *ps_buffer == '\0' ) {
-        msg_Err( p_this, "No password could be read from '%s'", psz_path );
-        goto error;
-    }
-
-    psz_password = strdup( ps_buffer );
-
-error:
-    if ( p_file != NULL )
-        fclose( p_file );
-
-    return psz_password;
-}
-
-/* Splits the value of a received header.
- *
- * Example: "Transport: RTP/AVP/TCP;unicast;mode=record;server_port=6000"
- */
-static int SplitHeader( char **ppsz_next, char **ppsz_name,
-                        char **ppsz_value )
-{
-    /* Find semicolon (separator between assignments) */
-    *ppsz_name = strsep( ppsz_next, psz_delim_semicolon );
-    if ( *ppsz_name )
-    {
-        /* Skip spaces */
-        *ppsz_name += strspn( *ppsz_name, psz_delim_space );
-
-        /* Get value */
-        *ppsz_value = *ppsz_name;
-        strsep( ppsz_value, psz_delim_equal );
-    }
-    else
-        *ppsz_value = NULL;
-
-    return !!*ppsz_name;
-}
-
-static void FreeHeader( void *p_value, void *p_data )
-{
-    VLC_UNUSED( p_data );
-    free( p_value );
-}
-
-static int ReadStatusLine( vlc_object_t *p_this )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    char *psz_line = NULL;
-    char *psz_token;
-    char *psz_next;
-    int i_result = VLC_EGENERIC;
-
-    p_sys->psz_last_status_line = net_Gets( p_this, p_sys->i_control_fd );
-    if ( !p_sys->psz_last_status_line )
-        goto error;
-
-    /* Create working copy */
-    psz_line = strdup( p_sys->psz_last_status_line );
-    psz_next = psz_line;
-
-    /* Protocol field */
-    psz_token = strsep( &psz_next, psz_delim_space );
-    if ( !psz_token || strncmp( psz_token, "RTSP/1.", 7 ) != 0 )
-    {
-        msg_Err( p_this, "Unknown protocol (%s)",
-                 p_sys->psz_last_status_line );
-        goto error;
-    }
-
-    /* Status field */
-    psz_token = strsep( &psz_next, psz_delim_space );
-    if ( !psz_token )
-    {
-        msg_Err( p_this, "Request failed (%s)",
-                 p_sys->psz_last_status_line );
-        goto error;
-    }
-
-    i_result = atoi( psz_token );
-
-error:
-    free( psz_line );
-
-    return i_result;
-}
-
-static int ReadHeader( vlc_object_t *p_this,
-                       vlc_dictionary_t *p_resp_headers,
-                       int *done )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    char *psz_original = NULL;
-    char *psz_line = NULL;
-    char *psz_token;
-    char *psz_next;
-    char *psz_name;
-    char *psz_value;
-    int i_err = VLC_SUCCESS;
-
-    psz_line = net_Gets( p_this, p_sys->i_control_fd );
-    if ( !psz_line )
-    {
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-
-    /* Empty line for response end */
-    if ( psz_line[0] == '\0' )
-        *done = 1;
-    else
-    {
-        psz_original = strdup( psz_line );
-        psz_next = psz_line;
-
-        psz_token = strsep( &psz_next, psz_delim_colon );
-        if ( !psz_token || psz_next[0] != ' ' )
-        {
-            msg_Err( p_this, "Invalid header format (%s)", psz_original );
-            i_err = VLC_EGENERIC;
-            goto error;
-        }
-
-        psz_name = psz_token;
-        psz_value = psz_next + 1;
-
-        vlc_dictionary_insert( p_resp_headers, psz_name, strdup( psz_value ) );
-    }
-
-error:
-    free( psz_original );
-    free( psz_line );
-
-    return i_err;
-}
-
-static void WriteAuxHeaders( struct vlc_memstream *restrict stream,
-                             vlc_dictionary_t *p_req_headers )
-{
-    char **ppsz_keys = vlc_dictionary_all_keys( p_req_headers );
-
-    if( unlikely( !ppsz_keys ) )
-        return;
-
-    for( size_t i = 0; ppsz_keys[i] != NULL; i++ )
-    {
-        char *name = ppsz_keys[i];
-        char *value = vlc_dictionary_value_for_key( p_req_headers, name );
-
-        vlc_memstream_printf( stream, "%s: %s\r\n", name, value );
-        free( name );
-    }
-
-    free( ppsz_keys );
-}
-
-static int SendRequest( vlc_object_t *p_this, const char *psz_method,
-                        const char *psz_content_type, const char *psz_body,
-                        vlc_dictionary_t *p_req_headers )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    struct vlc_memstream stream;
-    ssize_t val;
-
-    vlc_memstream_open( &stream );
-
-    vlc_memstream_printf( &stream, "%s %s RTSP/1.0\r\n", psz_method,
-                          p_sys->psz_url );
-    vlc_memstream_puts( &stream, "User-Agent: " RAOP_USER_AGENT "\r\n" );
-    vlc_memstream_printf( &stream, "Client-Instance: %s\r\n",
-                          p_sys->psz_client_instance );
-    vlc_memstream_printf( &stream, "CSeq: %u\r\n", ++p_sys->i_cseq );
-
-    if( psz_content_type != NULL )
-        vlc_memstream_printf( &stream, "Content-Type: %s\r\n",
-                              psz_content_type );
-
-    WriteAuxHeaders( &stream, p_req_headers );
-
-    if( psz_body != NULL )
-    {
-        size_t i_body_length = strlen( psz_body );
-
-        vlc_memstream_printf( &stream, "Content-Length: %zu\r\n",
-                              i_body_length );
-        vlc_memstream_puts( &stream, "\r\n" );
-        vlc_memstream_write( &stream, psz_body, i_body_length );
-    }
-    else
-        vlc_memstream_puts( &stream, "\r\n" );
-
-    if( vlc_memstream_close( &stream ) )
-        return VLC_ENOMEM;
-
-    val = net_Write( p_this, p_sys->i_control_fd, stream.ptr, stream.length );
-    free( stream.ptr );
-
-    if( val < (ssize_t)stream.length )
-        return VLC_EGENERIC;
-    return VLC_SUCCESS;
-}
-
-static int ParseAuthenticateHeader( vlc_object_t *p_this,
-                                    vlc_dictionary_t *p_resp_headers )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    char *psz_auth;
-    int i_err = VLC_SUCCESS;
-
-    psz_auth = vlc_dictionary_value_for_key( p_resp_headers,
-                                             "WWW-Authenticate" );
-    if ( psz_auth == NULL )
-    {
-        msg_Err( p_this, "HTTP 401 response missing "
-                         "WWW-Authenticate header" );
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-
-    vlc_http_auth_ParseWwwAuthenticateHeader( p_this, &p_sys->auth, psz_auth );
-
-error:
-    return i_err;
-}
-
-static int ExecRequest( vlc_object_t *p_this, const char *psz_method,
-                        const char *psz_content_type, const char *psz_body,
-                        vlc_dictionary_t *p_req_headers,
-                        vlc_dictionary_t *p_resp_headers )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    char *psz_authorization = NULL;
-    int headers_done;
-    int i_err = VLC_SUCCESS;
-    int i_status;
-    int i_auth_state;
-
-    if ( p_sys->i_control_fd < 0 )
-    {
-        msg_Err( p_this, "Control connection not open" );
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-
-    i_auth_state = 0;
-    while ( 1 )
-    {
-        /* Send header only when Digest authentication is used */
-        if ( p_sys->psz_password != NULL && p_sys->auth.psz_nonce != NULL )
-        {
-            FREENULL( psz_authorization );
-
-            psz_authorization =
-                vlc_http_auth_FormatAuthorizationHeader( p_this, &p_sys->auth,
-                                                         psz_method,
-                                                         p_sys->psz_url, "",
-                                                         p_sys->psz_password );
-            if ( psz_authorization == NULL )
-            {
-                i_err = VLC_EGENERIC;
-                goto error;
-            }
-
-            vlc_dictionary_insert( p_req_headers, "Authorization",
-                                   psz_authorization );
-        }
-
-        /* Send request */
-        i_err = SendRequest( p_this, psz_method, psz_content_type, psz_body,
-                             p_req_headers);
-        if ( i_err != VLC_SUCCESS )
-            goto error;
-
-        /* Read status line */
-        i_status = ReadStatusLine( p_this );
-        if ( i_status < 0 )
-        {
-            i_err = i_status;
-            goto error;
-        }
-
-        vlc_dictionary_clear( p_resp_headers, FreeHeader, NULL );
-
-        /* Read headers */
-        headers_done = 0;
-        while ( !headers_done )
-        {
-            i_err = ReadHeader( p_this, p_resp_headers, &headers_done );
-            if ( i_err != VLC_SUCCESS )
-                goto error;
-        }
-
-        if ( i_status == 200 )
-            /* Request successful */
-            break;
-        else if ( i_status == 401 )
-        {
-            /* Authorization required */
-            if ( i_auth_state == 1 || p_sys->psz_password == NULL )
-            {
-                msg_Err( p_this, "Access denied, password invalid" );
-                i_err = VLC_EGENERIC;
-                goto error;
-            }
-
-            i_err = ParseAuthenticateHeader( p_this, p_resp_headers );
-            if ( i_err != VLC_SUCCESS )
-                goto error;
-
-            i_auth_state = 1;
-        }
-        else
-        {
-            msg_Err( p_this, "Request failed (%s), status is %d",
-                     p_sys->psz_last_status_line, i_status );
-            i_err = VLC_EGENERIC;
-            goto error;
-        }
-    }
-
-error:
-    FREENULL( p_sys->psz_last_status_line );
-    free( psz_authorization );
-
-    return i_err;
-}
-
-static int AnnounceSDP( vlc_object_t *p_this, char *psz_local,
-                        uint32_t i_session_id )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    vlc_dictionary_t req_headers;
-    vlc_dictionary_t resp_headers;
-    unsigned char ps_sac[16];
-    char *psz_sdp = NULL;
-    char *psz_sac_base64 = NULL;
-    char *psz_aes_key_base64 = NULL;
-    char *psz_aes_iv_base64 = NULL;
-    int i_err = VLC_SUCCESS;
-    int i_rc;
-
-    vlc_dictionary_init( &req_headers, 0 );
-    vlc_dictionary_init( &resp_headers, 0 );
-
-    /* Encrypt AES key and encode it in Base64 */
-    i_rc = EncryptAesKeyBase64( p_this, &psz_aes_key_base64 );
-    if ( i_rc != VLC_SUCCESS || psz_aes_key_base64 == NULL )
-    {
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-    RemoveBase64Padding( psz_aes_key_base64 );
-
-    /* Encode AES IV in Base64 */
-    psz_aes_iv_base64 = vlc_b64_encode_binary( p_sys->ps_aes_iv,
-                                               sizeof( p_sys->ps_aes_iv ) );
-    if ( psz_aes_iv_base64 == NULL )
-    {
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-    RemoveBase64Padding( psz_aes_iv_base64 );
-
-    /* Random bytes for Apple-Challenge header */
-    gcry_randomize( ps_sac, sizeof( ps_sac ), GCRY_STRONG_RANDOM );
-
-    psz_sac_base64 = vlc_b64_encode_binary( ps_sac, sizeof( ps_sac ) );
-    if ( psz_sac_base64 == NULL )
-    {
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-    RemoveBase64Padding( psz_sac_base64 );
-
-    /* Build SDP
-     * Note: IPv6 addresses also use "IP4". Make sure not to include the
-     * scope ID.
-     */
-    i_rc = asprintf( &psz_sdp,
-                     "v=0\r\n"
-                     "o=iTunes %u 0 IN IP4 %s\r\n"
-                     "s=iTunes\r\n"
-                     "c=IN IP4 %s\r\n"
-                     "t=0 0\r\n"
-                     "m=audio 0 RTP/AVP 96\r\n"
-                     "a=rtpmap:96 AppleLossless\r\n"
-                     "a=fmtp:96 4096 0 16 40 10 14 2 255 0 0 44100\r\n"
-                     "a=rsaaeskey:%s\r\n"
-                     "a=aesiv:%s\r\n",
-                     i_session_id, psz_local, p_sys->psz_host,
-                     psz_aes_key_base64, psz_aes_iv_base64 );
-
-    if ( i_rc < 0 )
-    {
-        i_err = VLC_ENOMEM;
-        goto error;
-    }
-
-    /* Build and send request */
-    vlc_dictionary_insert( &req_headers, "Apple-Challenge", psz_sac_base64 );
-
-    i_err = ExecRequest( p_this, "ANNOUNCE", "application/sdp", psz_sdp,
-                         &req_headers, &resp_headers);
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-
-error:
-    vlc_dictionary_clear( &req_headers, NULL, NULL );
-    vlc_dictionary_clear( &resp_headers, FreeHeader, NULL );
-
-    free( psz_sdp );
-    free( psz_sac_base64 );
-    free( psz_aes_key_base64 );
-    free( psz_aes_iv_base64 );
-
-    return i_err;
-}
-
-static int SendSetup( vlc_object_t *p_this )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    vlc_dictionary_t req_headers;
-    vlc_dictionary_t resp_headers;
-    int i_err = VLC_SUCCESS;
-    char *psz_tmp;
-    char *psz_next;
-    char *psz_name;
-    char *psz_value;
-
-    vlc_dictionary_init( &req_headers, 0 );
-    vlc_dictionary_init( &resp_headers, 0 );
-
-    vlc_dictionary_insert( &req_headers, "Transport",
-                           ((void*)"RTP/AVP/TCP;unicast;interleaved=0-1;"
-                            "mode=record") );
-
-    i_err = ExecRequest( p_this, "SETUP", NULL, NULL,
-                         &req_headers, &resp_headers );
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-
-    psz_tmp = vlc_dictionary_value_for_key( &resp_headers, "Session" );
-    if ( !psz_tmp )
-    {
-        msg_Err( p_this, "Missing 'Session' header during setup" );
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-
-    free( p_sys->psz_session );
-    p_sys->psz_session = strdup( psz_tmp );
-
-    /* Get server_port */
-    psz_next = vlc_dictionary_value_for_key( &resp_headers, "Transport" );
-    while ( SplitHeader( &psz_next, &psz_name, &psz_value ) )
-    {
-        if ( psz_value && strcmp( psz_name, "server_port" ) == 0 )
-        {
-            p_sys->i_server_port = atoi( psz_value );
-            break;
-        }
-    }
-
-    if ( !p_sys->i_server_port )
-    {
-        msg_Err( p_this, "Missing 'server_port' during setup" );
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-
-    /* Get jack type */
-    psz_next = vlc_dictionary_value_for_key( &resp_headers,
-                                             "Audio-Jack-Status" );
-    while ( SplitHeader( &psz_next, &psz_name, &psz_value ) )
-    {
-        if ( strcmp( psz_name, "type" ) != 0 )
-            continue;
-
-        if ( strcmp( psz_value, "analog" ) == 0 )
-            p_sys->i_jack_type = JACK_TYPE_ANALOG;
-
-        else if ( strcmp( psz_value, "digital" ) == 0 )
-            p_sys->i_jack_type = JACK_TYPE_DIGITAL;
-
-        break;
-    }
-
-error:
-    vlc_dictionary_clear( &req_headers, NULL, NULL );
-    vlc_dictionary_clear( &resp_headers, FreeHeader, NULL );
-
-    return i_err;
-}
-
-static int SendRecord( vlc_object_t *p_this )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    vlc_dictionary_t req_headers;
-    vlc_dictionary_t resp_headers;
-    int i_err = VLC_SUCCESS;
-    char *psz_value;
-
-    vlc_dictionary_init( &req_headers, 0 );
-    vlc_dictionary_init( &resp_headers, 0 );
-
-    vlc_dictionary_insert( &req_headers, "Range", (void *)"npt=0-" );
-    vlc_dictionary_insert( &req_headers, "RTP-Info",
-                           (void *)"seq=0;rtptime=0" );
-    vlc_dictionary_insert( &req_headers, "Session",
-                           (void *)p_sys->psz_session );
-
-    i_err = ExecRequest( p_this, "RECORD", NULL, NULL,
-                         &req_headers, &resp_headers );
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-
-    psz_value = vlc_dictionary_value_for_key( &resp_headers, "Audio-Latency" );
-    if ( psz_value )
-        p_sys->i_audio_latency = atoi( psz_value );
-    else
-        p_sys->i_audio_latency = 0;
-
-error:
-    vlc_dictionary_clear( &req_headers, NULL, NULL );
-    vlc_dictionary_clear( &resp_headers, FreeHeader, NULL );
-
-    return i_err;
-}
-
-static int SendFlush( vlc_object_t *p_this )
-{
-    VLC_UNUSED( p_this );
-    vlc_dictionary_t resp_headers;
-    vlc_dictionary_t req_headers;
-    int i_err = VLC_SUCCESS;
-
-    vlc_dictionary_init( &req_headers, 0 );
-    vlc_dictionary_init( &resp_headers, 0 );
-
-    vlc_dictionary_insert( &req_headers, "RTP-Info",
-                           (void *)"seq=0;rtptime=0" );
-
-    i_err = ExecRequest( p_this, "FLUSH", NULL, NULL,
-                         &req_headers, &resp_headers );
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-
-error:
-    vlc_dictionary_clear( &req_headers, NULL, NULL );
-    vlc_dictionary_clear( &resp_headers, FreeHeader, NULL );
-
-    return i_err;
-}
-
-static int SendTeardown( vlc_object_t *p_this )
-{
-    vlc_dictionary_t resp_headers;
-    vlc_dictionary_t req_headers;
-    int i_err = VLC_SUCCESS;
-
-    vlc_dictionary_init( &req_headers, 0 );
-    vlc_dictionary_init( &resp_headers, 0 );
-
-    i_err = ExecRequest( p_this, "TEARDOWN", NULL, NULL,
-                         &req_headers, &resp_headers );
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-
-error:
-    vlc_dictionary_clear( &req_headers, NULL, NULL );
-    vlc_dictionary_clear( &resp_headers, FreeHeader, NULL );
-
-    return i_err;
-}
-
-static int UpdateVolume( vlc_object_t *p_this )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    vlc_dictionary_t req_headers;
-    vlc_dictionary_t resp_headers;
-    char *psz_parameters = NULL;
-    double d_volume;
-    int i_err = VLC_SUCCESS;
-    int i_rc;
-
-    vlc_dictionary_init( &req_headers, 0 );
-    vlc_dictionary_init( &resp_headers, 0 );
-
-    /* Our volume is 0..255, RAOP is -144..0 (-144 off, -30..0 on) */
-
-    /* Limit range */
-    p_sys->i_volume = VLC_CLIP( p_sys->i_volume, 0, 255 );
-
-    if ( p_sys->i_volume == 0 )
-        d_volume = -144.0;
-    else
-        d_volume = -30 + ( ( (double)p_sys->i_volume ) * 30.0 / 255.0 );
-
-    /* Format without using locales */
-    i_rc = us_asprintf( &psz_parameters, "volume: %0.6f\r\n", d_volume );
-    if ( i_rc < 0 )
-    {
-        i_err = VLC_ENOMEM;
-        goto error;
-    }
-
-    vlc_dictionary_insert( &req_headers, "Session",
-                           (void *)p_sys->psz_session );
-
-    i_err = ExecRequest( p_this, "SET_PARAMETER",
-                         "text/parameters", psz_parameters,
-                         &req_headers, &resp_headers );
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-
-error:
-    vlc_dictionary_clear( &req_headers, NULL, NULL );
-    vlc_dictionary_clear( &resp_headers, FreeHeader, NULL );
-    free( psz_parameters );
-
-    return i_err;
-}
-
-static void LogInfo( vlc_object_t *p_this )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    const char *psz_jack_name;
-
-    msg_Info( p_this, "Audio latency: %d", p_sys->i_audio_latency );
-
-    switch ( p_sys->i_jack_type )
-    {
-        case JACK_TYPE_ANALOG:
-            psz_jack_name = "analog";
-            break;
-
-        case JACK_TYPE_DIGITAL:
-            psz_jack_name = "digital";
-            break;
-
-        case JACK_TYPE_NONE:
-        default:
-            psz_jack_name = "none";
-            break;
-    }
-
-    msg_Info( p_this, "Jack type: %s", psz_jack_name );
-}
-
-static void SendAudio( sout_stream_t *p_stream, block_t *p_buffer )
-{
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    gcry_error_t i_gcrypt_err;
-    block_t *p_next;
-    size_t i_len;
-    size_t i_payload_len;
-    size_t i_realloc_len;
-    int rc;
-
-    const uint8_t header[16] = {
-        0x24, 0x00, 0x00, 0x00,
-        0xf0, 0xff, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00,
-    };
-
-    while ( p_buffer )
-    {
-        i_len = sizeof( header ) + p_buffer->i_buffer;
-
-        /* Buffer resize needed? */
-        if ( i_len > p_sys->i_sendbuf_len || p_sys->p_sendbuf == NULL )
-        {
-            /* Grow in blocks of 4K */
-            i_realloc_len = (1 + (i_len / 4096)) * 4096;
-
-            p_sys->p_sendbuf = realloc_or_free( p_sys->p_sendbuf, i_realloc_len );
-            if ( p_sys->p_sendbuf == NULL )
-                goto error;
-
-            p_sys->i_sendbuf_len = i_realloc_len;
-        }
-
-        /* Fill buffer */
-        memcpy( p_sys->p_sendbuf, header, sizeof( header ) );
-        memcpy( p_sys->p_sendbuf + sizeof( header ),
-                p_buffer->p_buffer, p_buffer->i_buffer );
-
-        /* Calculate payload length and update header */
-        i_payload_len = i_len - 4;
-        if ( i_payload_len > 0xffff )
-        {
-            msg_Err( p_stream, "Buffer is too long (%u bytes)",
-                     (unsigned int)i_payload_len );
-            goto error;
-        }
-
-        p_sys->p_sendbuf[2] = ( i_payload_len >> 8 ) & 0xff;
-        p_sys->p_sendbuf[3] = i_payload_len & 0xff;
-
-        /* Reset cipher */
-        i_gcrypt_err = gcry_cipher_reset( p_sys->aes_ctx );
-        if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-            goto error;
-
-        /* Set IV */
-        i_gcrypt_err = gcry_cipher_setiv( p_sys->aes_ctx, p_sys->ps_aes_iv,
-                                          sizeof( p_sys->ps_aes_iv ) );
-        if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-            goto error;
-
-        /* Encrypt in place. Only full blocks of 16 bytes are encrypted,
-         * the rest (0-15 bytes) is left unencrypted.
-         */
-        i_gcrypt_err =
-            gcry_cipher_encrypt( p_sys->aes_ctx,
-                                 p_sys->p_sendbuf + sizeof( header ),
-                                 ( p_buffer->i_buffer / 16 ) * 16,
-                                 NULL, 0 );
-        if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-            goto error;
-
-        /* Send data */
-        rc = net_Write( p_stream, p_sys->i_stream_fd, p_sys->p_sendbuf, i_len );
-        if ( rc < 0 )
-            goto error;
-
-        p_next = p_buffer->p_next;
-        block_Release( p_buffer );
-        p_buffer = p_next;
-    }
-
-error:
-    block_ChainRelease( p_buffer );
-    return;
-}
-
-
-/*****************************************************************************
- * Open:
- *****************************************************************************/
-static int Open( vlc_object_t *p_this )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys;
-    char psz_local[NI_MAXNUMERICHOST];
-    char *psz_pwfile = NULL;
-    gcry_error_t i_gcrypt_err;
-    int i_err = VLC_SUCCESS;
-    uint32_t i_session_id;
-    uint64_t i_client_instance;
-
-    vlc_gcrypt_init();
-
-    config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
-                       p_stream->p_cfg );
-
-    p_sys = calloc( 1, sizeof( *p_sys ) );
-    if ( p_sys == NULL )
-        return VLC_ENOMEM;
-
-    p_stream->pf_add = Add;
-    p_stream->pf_del = Del;
-    p_stream->pf_send = Send;
-    p_stream->p_sys = p_sys;
-    p_stream->pace_nocontrol = true;
-
-    p_sys->i_control_fd = -1;
-    p_sys->i_stream_fd = -1;
-    p_sys->i_volume = var_GetInteger( p_stream, SOUT_CFG_PREFIX "volume");
-    p_sys->i_jack_type = JACK_TYPE_NONE;
-
-    vlc_http_auth_Init( &p_sys->auth );
-
-    p_sys->psz_host = var_GetNonEmptyString( p_stream,
-                                             SOUT_CFG_PREFIX "host" );
-    if ( p_sys->psz_host == NULL )
-    {
-        msg_Err( p_this, "Missing host" );
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-
-    p_sys->psz_password = var_GetNonEmptyString( p_stream,
-                                                 SOUT_CFG_PREFIX "password" );
-    if ( p_sys->psz_password == NULL )
-    {
-        /* Try password file instead */
-        psz_pwfile = var_GetNonEmptyString( p_stream,
-                                            SOUT_CFG_PREFIX "password-file" );
-        if ( psz_pwfile != NULL )
-        {
-            p_sys->psz_password = ReadPasswordFile( p_this, psz_pwfile );
-            if ( p_sys->psz_password == NULL )
-            {
-                i_err = VLC_EGENERIC;
-                goto error;
-            }
-        }
-    }
-
-    if ( p_sys->psz_password != NULL )
-        msg_Info( p_this, "Using password authentication" );
-
-    var_AddCallback( p_stream, SOUT_CFG_PREFIX "volume",
-                     VolumeCallback, NULL );
-    p_sys->b_volume_callback = true;
-
-    /* Open control connection */
-    p_sys->i_control_fd = net_ConnectTCP( p_stream, p_sys->psz_host,
-                                          RAOP_PORT );
-    if ( p_sys->i_control_fd < 0 )
-    {
-        msg_Err( p_this, "Cannot establish control connection to %s:%d (%s)",
-                 p_sys->psz_host, RAOP_PORT, vlc_strerror_c(errno) );
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-
-    /* Get local IP address */
-    if ( net_GetSockAddress( p_sys->i_control_fd, psz_local, NULL ) )
-    {
-        msg_Err( p_this, "cannot get local IP address" );
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-
-    /* Random session ID */
-    gcry_randomize( &i_session_id, sizeof( i_session_id ),
-                    GCRY_STRONG_RANDOM );
-
-    /* Random client instance */
-    gcry_randomize( &i_client_instance, sizeof( i_client_instance ),
-                    GCRY_STRONG_RANDOM );
-    if ( asprintf( &p_sys->psz_client_instance, "%016"PRIX64,
-                   i_client_instance ) < 0 )
-    {
-        i_err = VLC_ENOMEM;
-        goto error;
-    }
-
-    /* Build session URL */
-    if ( asprintf( &p_sys->psz_url, "rtsp://%s/%u",
-                   psz_local, i_session_id ) < 0 )
-    {
-        i_err = VLC_ENOMEM;
-        goto error;
-    }
-
-    /* Generate AES key and IV */
-    gcry_randomize( p_sys->ps_aes_key, sizeof( p_sys->ps_aes_key ),
-                    GCRY_STRONG_RANDOM );
-    gcry_randomize( p_sys->ps_aes_iv, sizeof( p_sys->ps_aes_iv ),
-                    GCRY_STRONG_RANDOM );
-
-    /* Setup AES */
-    i_gcrypt_err = gcry_cipher_open( &p_sys->aes_ctx, GCRY_CIPHER_AES,
-                                     GCRY_CIPHER_MODE_CBC, 0 );
-    if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-    {
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-
-    /* Set key */
-    i_gcrypt_err = gcry_cipher_setkey( p_sys->aes_ctx, p_sys->ps_aes_key,
-                                       sizeof( p_sys->ps_aes_key ) );
-    if ( CheckForGcryptError( p_stream, i_gcrypt_err ) )
-    {
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-
-    /* Protocol handshake */
-    i_err = AnnounceSDP( p_this, psz_local, i_session_id );
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-
-    i_err = SendSetup( p_this );
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-
-    i_err = SendRecord( p_this );
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-
-    i_err = UpdateVolume( p_this );
-    if ( i_err != VLC_SUCCESS )
-        goto error;
-
-    LogInfo( p_this );
-
-    /* Open stream connection */
-    p_sys->i_stream_fd = net_ConnectTCP( p_stream, p_sys->psz_host,
-                                         p_sys->i_server_port );
-    if ( p_sys->i_stream_fd < 0 )
-    {
-        msg_Err( p_this, "Cannot establish stream connection to %s:%d (%s)",
-                 p_sys->psz_host, p_sys->i_server_port,
-                 vlc_strerror_c(errno)  );
-        i_err = VLC_EGENERIC;
-        goto error;
-    }
-
-error:
-    free( psz_pwfile );
-
-    if ( i_err != VLC_SUCCESS )
-        FreeSys( p_this, p_sys );
-
-    return i_err;
-}
-
-
-/*****************************************************************************
- * Close:
- *****************************************************************************/
-static void Close( vlc_object_t *p_this )
-{
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-
-    SendFlush( p_this );
-    SendTeardown( p_this );
-
-    FreeSys( p_this, p_sys );
-}
-
-
-/*****************************************************************************
- * Add:
- *****************************************************************************/
-static sout_stream_id_sys_t *Add( sout_stream_t *p_stream, const es_format_t *p_fmt )
-{
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-    sout_stream_id_sys_t *id = NULL;
-
-    id = calloc( 1, sizeof( *id ) );
-    if ( id == NULL )
-        goto error;
-
-    es_format_Copy( &id->fmt, p_fmt );
-
-    switch ( id->fmt.i_cat )
-    {
-    case AUDIO_ES:
-        if ( id->fmt.i_codec == VLC_CODEC_ALAC )
-        {
-            if ( p_sys->p_audio_stream )
-            {
-                msg_Warn( p_stream, "Only the first Apple Lossless audio "
-                                    "stream is used" );
-            }
-            else if ( id->fmt.audio.i_rate != 44100 ||
-                      id->fmt.audio.i_channels != 2 )
-            {
-                msg_Err( p_stream, "The Apple Lossless audio stream must be "
-                                   "encoded with 44100 Hz and 2 channels" );
-            }
-            else
-            {
-                /* Use this stream */
-                p_sys->p_audio_stream = id;
-            }
-        }
-        else if ( !p_sys->b_alac_warning )
-        {
-            msg_Err( p_stream, "Apple Lossless is the only codec supported. "
-                               "Use the \"transcode\" module for conversion "
-                               "(e.g. \"transcode{acodec=alac,"
-                               "channels=2}\")." );
-            p_sys->b_alac_warning = true;
-        }
-
-        break;
-
-    default:
-        /* Leave other stream types alone */
-        break;
-    }
-
-    return id;
-
-error:
-    FreeId( id );
-
-    return NULL;
-}
-
-
-/*****************************************************************************
- * Del:
- *****************************************************************************/
-static void Del( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
-{
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-
-    if ( p_sys->p_audio_stream == id )
-        p_sys->p_audio_stream = NULL;
-
-    FreeId( id );
-}
-
-
-/*****************************************************************************
- * Send:
- *****************************************************************************/
-static int Send( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
-                 block_t *p_buffer )
-{
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-
-    if ( id->fmt.i_cat == AUDIO_ES && id == p_sys->p_audio_stream )
-    {
-        /* SendAudio takes care of releasing the buffers */
-        SendAudio( p_stream, p_buffer );
-    }
-    else
-    {
-        block_ChainRelease( p_buffer );
-    }
-
-    return VLC_SUCCESS;
-}
-
-
-/*****************************************************************************
- * VolumeCallback: called when the volume is changed on the fly.
- *****************************************************************************/
-static int VolumeCallback( vlc_object_t *p_this, char const *psz_cmd,
-                           vlc_value_t oldval, vlc_value_t newval,
-                           void *p_data )
-{
-    VLC_UNUSED(psz_cmd);
-    VLC_UNUSED(oldval);
-    VLC_UNUSED(p_data);
-    VLC_UNUSED(newval);
-    sout_stream_t *p_stream = (sout_stream_t*)p_this;
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
-
-    /* TODO: Implement volume change */
-    VLC_UNUSED(p_sys);
-
-    return VLC_SUCCESS;
-}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 767a9d25fc..5b4c5cbfc0 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1034,7 +1034,6 @@ modules/stream_out/duplicate.c
 modules/stream_out/es.c
 modules/stream_out/gather.c
 modules/stream_out/mosaic_bridge.c
-modules/stream_out/raop.c
 modules/stream_out/record.c
 modules/stream_out/rtcp.c
 modules/stream_out/rtp.c



More information about the vlc-commits mailing list