announce.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:10k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * announce.c : announce handler
  3.  *****************************************************************************
  4.  * Copyright (C) 2002-2004 VideoLAN
  5.  * $Id: announce.c 9201 2004-11-06 16:51:46Z yoann $
  6.  *
  7.  * Authors: Cl閙ent Stenac <zorglub@videolan.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <stdlib.h>                                                /* free() */
  27. #include <stdio.h>                                              /* sprintf() */
  28. #include <string.h>                                            /* strerror() */
  29. #include <vlc/vlc.h>
  30. #include <vlc/sout.h>
  31. /*****************************************************************************
  32.  * Local prototypes
  33.  *****************************************************************************/
  34. #define FREE( p ) if( p ) { free( p ); (p) = NULL; }
  35. /****************************************************************************
  36.  * Sout-side functions
  37.  ****************************************************************************/
  38. /**
  39.  *  Register a new session with the announce handler
  40.  *
  41.  * param p_sout a sout instance structure
  42.  * param p_session a session descriptor
  43.  * param p_method an announce method descriptor
  44.  * return VLC_SUCCESS or an error
  45.  */
  46. int sout_AnnounceRegister( sout_instance_t *p_sout,
  47.                        session_descriptor_t *p_session,
  48.                        announce_method_t *p_method )
  49. {
  50.     int i_ret;
  51.     announce_handler_t *p_announce = (announce_handler_t*)
  52.                               vlc_object_find( p_sout,
  53.                                               VLC_OBJECT_ANNOUNCE,
  54.                                               FIND_ANYWHERE );
  55.     if( !p_announce )
  56.     {
  57.         msg_Dbg( p_sout, "No announce handler found, creating one" );
  58.         p_announce = announce_HandlerCreate( p_sout );
  59.         if( !p_announce )
  60.         {
  61.             msg_Err( p_sout, "Creation failed" );
  62.             return VLC_ENOMEM;
  63.         }
  64.         vlc_object_yield( p_announce );
  65.         msg_Dbg( p_sout,"Creation done" );
  66.     }
  67.     i_ret = announce_Register( p_announce, p_session, p_method );
  68.     vlc_object_release( p_announce );
  69.     return i_ret;
  70. }
  71. /**
  72.  *  Register a new session with the announce handler, using a pregenerated SDP
  73.  *
  74.  * param p_sout a sout instance structure
  75.  * param psz_sdp the SDP to register
  76.  * param p_method an announce method descriptor
  77.  * return the new session descriptor structure
  78.  */
  79. session_descriptor_t *sout_AnnounceRegisterSDP( sout_instance_t *p_sout,
  80.                           char *psz_sdp, announce_method_t *p_method )
  81. {
  82.     session_descriptor_t *p_session;
  83.     announce_handler_t *p_announce = (announce_handler_t*)
  84.                                      vlc_object_find( p_sout,
  85.                                               VLC_OBJECT_ANNOUNCE,
  86.                                               FIND_ANYWHERE );
  87.     if( !p_announce )
  88.     {
  89.         msg_Dbg( p_sout, "no announce handler found, creating one" );
  90.         p_announce = announce_HandlerCreate( p_sout );
  91.         if( !p_announce )
  92.         {
  93.             msg_Err( p_sout, "Creation failed" );
  94.             return NULL;
  95.         }
  96.         vlc_object_yield( p_announce );
  97.     }
  98.     if( p_method->i_type != METHOD_TYPE_SAP )
  99.     {
  100.         msg_Warn( p_sout,"forcing SAP announcement");
  101.     }
  102.     p_session = sout_AnnounceSessionCreate();
  103.     p_session->psz_sdp = strdup( psz_sdp );
  104.     announce_Register( p_announce, p_session, p_method );
  105.     vlc_object_release( p_announce );
  106.     return p_session;
  107. }
  108. /**
  109.  *  UnRegister an existing session
  110.  *
  111.  * param p_sout a sout instance structure
  112.  * param p_session the session descriptor
  113.  * return VLC_SUCCESS or an error
  114.  */
  115. int sout_AnnounceUnRegister( sout_instance_t *p_sout,
  116.                              session_descriptor_t *p_session )
  117. {
  118.     int i_ret;
  119.     announce_handler_t *p_announce = (announce_handler_t*)
  120.                               vlc_object_find( p_sout,
  121.                                               VLC_OBJECT_ANNOUNCE,
  122.                                               FIND_ANYWHERE );
  123.     if( !p_announce )
  124.     {
  125.         msg_Dbg( p_sout, "Unable to remove announce: no announce handler" );
  126.         return VLC_ENOOBJ;
  127.     }
  128.     i_ret  = announce_UnRegister( p_announce, p_session );
  129.     vlc_object_release( p_announce );
  130.     return i_ret;
  131. }
  132. /**
  133.  * Create and initialize a session descriptor
  134.  *
  135.  * return a new session descriptor
  136.  */
  137. session_descriptor_t * sout_AnnounceSessionCreate()
  138. {
  139.     session_descriptor_t *p_session;
  140.     p_session = (session_descriptor_t *)malloc( sizeof(session_descriptor_t));
  141.     if( p_session)
  142.     {
  143.         p_session->p_sap = NULL;
  144.         p_session->psz_sdp = NULL;
  145.         p_session->psz_name = NULL;
  146.         p_session->psz_uri = NULL;
  147.         p_session->i_port = 0;
  148.         p_session->psz_group = NULL;
  149.     }
  150.     return p_session;
  151. }
  152. /**
  153.  * Destroy a session descriptor and free all
  154.  *
  155.  * param p_session the session to destroy
  156.  * return Nothing
  157.  */
  158. void sout_AnnounceSessionDestroy( session_descriptor_t *p_session )
  159. {
  160.     if( p_session )
  161.     {
  162.         FREE( p_session->psz_name );
  163.         FREE( p_session->psz_group );
  164.         FREE( p_session->psz_uri );
  165.         FREE( p_session->psz_sdp );
  166.         FREE( p_session );
  167.     }
  168. }
  169. /**
  170.  * Create and initialize an announcement method structure
  171.  *
  172.  * param i_type METHOD_TYPE_SAP or METHOD_TYPE_SLP
  173.  * return a new announce_method structure
  174.  */
  175. announce_method_t * sout_AnnounceMethodCreate( int i_type )
  176. {
  177.     announce_method_t *p_method;
  178.     p_method = (announce_method_t *)malloc( sizeof(announce_method_t) );
  179.     if( p_method )
  180.     {
  181.         p_method->i_type = i_type;
  182.         if( i_type == METHOD_TYPE_SAP )
  183.         {
  184.             /* Default values */
  185.             p_method->psz_address = NULL;
  186.             p_method->i_ip_version = 4 ;
  187.             p_method->psz_ipv6_scope = strdup("8");
  188.         }
  189.     }
  190.     return p_method;
  191. }
  192. /************************************************************************
  193.  * Announce handler functions (private)
  194.  ************************************************************************/
  195. /**
  196.  * Create the announce handler object
  197.  *
  198.  * param p_this a vlc_object structure
  199.  * return the new announce handler or NULL on error
  200.  */
  201. announce_handler_t *__announce_HandlerCreate( vlc_object_t *p_this )
  202. {
  203.     announce_handler_t *p_announce;
  204.     p_announce = vlc_object_create( p_this, VLC_OBJECT_ANNOUNCE );
  205.     if( !p_announce )
  206.     {
  207.         msg_Err( p_this, "out of memory" );
  208.         return NULL;
  209.     }
  210.     p_announce->p_sap = NULL;
  211.     vlc_object_attach( p_announce, p_this->p_vlc);
  212.     return p_announce;
  213. }
  214. /**
  215.  * Destroy a  announce handler object
  216.  *
  217.  * param p_announce the announce handler to destroy
  218.  * return VLC_SUCCESS or an error
  219.  */
  220. int announce_HandlerDestroy( announce_handler_t *p_announce )
  221. {
  222.     if( p_announce->p_sap )
  223.     {
  224.         p_announce->p_sap->b_die = VLC_TRUE;
  225.         /* Wait for the SAP thread to exit */
  226.         vlc_thread_join( p_announce->p_sap );
  227.         announce_SAPHandlerDestroy( p_announce->p_sap );
  228.     }
  229.     /* Free the structure */
  230.     vlc_object_destroy( p_announce );
  231.     return VLC_SUCCESS;
  232. }
  233. /* Register an announce */
  234. int announce_Register( announce_handler_t *p_announce,
  235.                        session_descriptor_t *p_session,
  236.                        announce_method_t *p_method )
  237. {
  238.     msg_Dbg( p_announce, "registering announce");
  239.     if( p_method->i_type == METHOD_TYPE_SAP )
  240.     {
  241.         /* Do we already have a SAP announce handler ? */
  242.         if( !p_announce->p_sap )
  243.         {
  244.             sap_handler_t *p_sap = announce_SAPHandlerCreate( p_announce );
  245.             msg_Dbg( p_announce, "creating SAP announce handler");
  246.             if( !p_sap )
  247.             {
  248.                 msg_Err( p_announce, "SAP handler creation failed" );
  249.                 return VLC_ENOOBJ;
  250.             }
  251.             p_announce->p_sap = p_sap;
  252.         }
  253.         /* this will set p_session->p_sap for later deletion */
  254.         msg_Dbg( p_announce, "adding SAP session");
  255.         p_announce->p_sap->pf_add( p_announce->p_sap, p_session, p_method );
  256.     }
  257.     else if( p_method->i_type == METHOD_TYPE_SLP )
  258.     {
  259.         msg_Dbg( p_announce, "SLP unsupported at the moment" );
  260.         return VLC_EGENERIC;
  261.     }
  262.     else
  263.     {
  264.         msg_Dbg( p_announce, "Announce type unsupported" );
  265.         return VLC_EGENERIC;
  266.     }
  267.     return VLC_SUCCESS;;
  268. }
  269. /* Unregister an announce */
  270. int announce_UnRegister( announce_handler_t *p_announce,
  271.                   session_descriptor_t *p_session )
  272. {
  273.     msg_Dbg( p_announce, "unregistering announce" );
  274.     if( p_session->p_sap != NULL ) /* SAP Announce */
  275.     {
  276.         if( !p_announce->p_sap )
  277.         {
  278.             msg_Err( p_announce, "can't remove announce, no SAP handler");
  279.             return VLC_ENOOBJ;
  280.         }
  281.         p_announce->p_sap->pf_del( p_announce->p_sap, p_session );
  282.     }
  283.     return VLC_SUCCESS;
  284. }