]> git.sesse.net Git - vlc/blob - src/stream_output/announce.c
A bit of headers cleanup
[vlc] / src / stream_output / announce.c
1 /*****************************************************************************
2  * announce.c : announce handler
3  *****************************************************************************
4  * Copyright (C) 2002-2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                                /* free() */
28 #include <stdio.h>                                              /* sprintf() */
29 #include <string.h>                                            /* strerror() */
30
31 #include <vlc/vlc.h>
32 #include <vlc_sout.h>
33 #include "stream_output.h"
34
35 /****************************************************************************
36  * Sout-side functions
37  ****************************************************************************/
38
39 /**
40  *  Register a new session with the announce handler
41  *
42  * \param p_sout a sout instance structure
43  * \param p_session a session descriptor
44  * \param p_method an announce method descriptor
45  * \return VLC_SUCCESS or an error
46  */
47 int sout_AnnounceRegister( sout_instance_t *p_sout,
48                        session_descriptor_t *p_session,
49                        announce_method_t *p_method )
50 {
51     int i_ret;
52     announce_handler_t *p_announce = (announce_handler_t*)
53                               vlc_object_find( p_sout,
54                                               VLC_OBJECT_ANNOUNCE,
55                                               FIND_ANYWHERE );
56
57     if( !p_announce )
58     {
59         msg_Dbg( p_sout, "No announce handler found, creating one" );
60         p_announce = announce_HandlerCreate( p_sout );
61         if( !p_announce )
62         {
63             msg_Err( p_sout, "Creation failed" );
64             return VLC_ENOMEM;
65         }
66         vlc_object_yield( p_announce );
67         msg_Dbg( p_sout, "creation done" );
68     }
69
70     i_ret = announce_Register( p_announce, p_session, p_method );
71     vlc_object_release( p_announce );
72
73     return i_ret;
74 }
75
76 /**
77  *  Register a new session with the announce handler, using a pregenerated SDP
78  *
79  * \param p_sout a sout instance structure
80  * \param psz_sdp the SDP to register
81  * \param psz_uri session URI (needed for SAP address auto detection
82  * \param p_method an announce method descriptor
83  * \return the new session descriptor structure
84  */
85 session_descriptor_t *sout_AnnounceRegisterSDP( sout_instance_t *p_sout,
86                           const char *psz_sdp, const char *psz_uri,
87                           announce_method_t *p_method )
88 {
89     session_descriptor_t *p_session;
90     announce_handler_t *p_announce = (announce_handler_t*)
91                                      vlc_object_find( p_sout,
92                                               VLC_OBJECT_ANNOUNCE,
93                                               FIND_ANYWHERE );
94     if( !p_announce )
95     {
96         msg_Dbg( p_sout, "no announce handler found, creating one" );
97         p_announce = announce_HandlerCreate( p_sout );
98         if( !p_announce )
99         {
100             msg_Err( p_sout, "Creation failed" );
101             return NULL;
102         }
103         vlc_object_yield( p_announce );
104     }
105
106     if( p_method->i_type != METHOD_TYPE_SAP )
107     {
108         msg_Warn( p_sout, "forcing SAP announcement");
109     }
110
111     p_session = sout_AnnounceSessionCreate();
112     p_session->psz_sdp = strdup( psz_sdp );
113     p_session->psz_uri = strdup( psz_uri );
114     announce_Register( p_announce, p_session, p_method );
115
116     vlc_object_release( p_announce );
117     return p_session;
118 }
119
120 /**
121  *  UnRegister an existing session
122  *
123  * \param p_sout a sout instance structure
124  * \param p_session the session descriptor
125  * \return VLC_SUCCESS or an error
126  */
127 int sout_AnnounceUnRegister( sout_instance_t *p_sout,
128                              session_descriptor_t *p_session )
129 {
130     int i_ret;
131     announce_handler_t *p_announce = (announce_handler_t*)
132                               vlc_object_find( p_sout,
133                                               VLC_OBJECT_ANNOUNCE,
134                                               FIND_ANYWHERE );
135     if( !p_announce )
136     {
137         msg_Dbg( p_sout, "unable to remove announce: no announce handler" );
138         return VLC_ENOOBJ;
139     }
140     i_ret  = announce_UnRegister( p_announce, p_session );
141
142     vlc_object_release( p_announce );
143
144     return i_ret;
145 }
146
147 /**
148  * Create and initialize a session descriptor
149  *
150  * \return a new session descriptor
151  */
152 session_descriptor_t * sout_AnnounceSessionCreate(void)
153 {
154     session_descriptor_t *p_session;
155
156     p_session = (session_descriptor_t *)malloc( sizeof(session_descriptor_t));
157     if (p_session == NULL)
158         return NULL;
159
160     memset (p_session, 0, sizeof (*p_session));
161     return p_session;
162 }
163
164 /**
165  * Destroy a session descriptor and free all
166  *
167  * \param p_session the session to destroy
168  * \return Nothing
169  */
170 void sout_AnnounceSessionDestroy( session_descriptor_t *p_session )
171 {
172     if( p_session )
173     {
174         FREENULL( p_session->psz_name );
175         FREENULL( p_session->psz_group );
176         FREENULL( p_session->psz_uri );
177         FREENULL( p_session->psz_sdp );
178         free( p_session );
179     }
180 }
181
182 /**
183  * Create and initialize an announcement method structure
184  *
185  * \param i_type METHOD_TYPE_SAP
186  * \return a new announce_method structure
187  */
188 announce_method_t * sout_AnnounceMethodCreate( int i_type )
189 {
190     announce_method_t *p_method;
191
192     p_method = (announce_method_t *)malloc( sizeof(announce_method_t) );
193     if( p_method == NULL )
194         return NULL;
195
196     p_method->i_type = i_type;
197     return p_method;
198 }
199
200 /************************************************************************
201  * Announce handler functions (private)
202  ************************************************************************/
203
204 /**
205  * Create the announce handler object
206  *
207  * \param p_this a vlc_object structure
208  * \return the new announce handler or NULL on error
209  */
210 announce_handler_t *__announce_HandlerCreate( vlc_object_t *p_this )
211 {
212     announce_handler_t *p_announce;
213
214     p_announce = vlc_object_create( p_this, VLC_OBJECT_ANNOUNCE );
215
216     if( !p_announce )
217     {
218         msg_Err( p_this, "out of memory" );
219         return NULL;
220     }
221
222     p_announce->p_sap = NULL;
223     vlc_object_attach( p_announce, p_this->p_libvlc);
224
225     return p_announce;
226 }
227
228 /**
229  * Destroy a  announce handler object
230  *
231  * \param p_announce the announce handler to destroy
232  * \return VLC_SUCCESS or an error
233  */
234 int announce_HandlerDestroy( announce_handler_t *p_announce )
235 {
236
237     if( p_announce->p_sap )
238     {
239         p_announce->p_sap->b_die = VLC_TRUE;
240         /* Wait for the SAP thread to exit */
241         vlc_thread_join( p_announce->p_sap );
242         announce_SAPHandlerDestroy( p_announce->p_sap );
243     }
244
245     /* Free the structure */
246     vlc_object_destroy( p_announce );
247
248     return VLC_SUCCESS;
249 }
250
251 /* Register an announce */
252 int announce_Register( announce_handler_t *p_announce,
253                        session_descriptor_t *p_session,
254                        announce_method_t *p_method )
255 {
256
257     msg_Dbg( p_announce, "registering announce");
258     if( p_method->i_type == METHOD_TYPE_SAP )
259     {
260         /* Do we already have a SAP announce handler ? */
261         if( !p_announce->p_sap )
262         {
263             sap_handler_t *p_sap = announce_SAPHandlerCreate( p_announce );
264             msg_Dbg( p_announce, "creating SAP announce handler");
265             if( !p_sap )
266             {
267                 msg_Err( p_announce, "SAP handler creation failed" );
268                 return VLC_ENOOBJ;
269             }
270             p_announce->p_sap = p_sap;
271         }
272         /* this will set p_session->p_sap for later deletion */
273         msg_Dbg( p_announce, "adding SAP session");
274         p_announce->p_sap->pf_add( p_announce->p_sap, p_session );
275     }
276     else
277     {
278         msg_Dbg( p_announce, "announce type unsupported" );
279         return VLC_EGENERIC;
280     }
281     return VLC_SUCCESS;;
282 }
283
284
285 /* Unregister an announce */
286 int announce_UnRegister( announce_handler_t *p_announce,
287                   session_descriptor_t *p_session )
288 {
289     msg_Dbg( p_announce, "unregistering announce" );
290     if( p_session->p_sap != NULL ) /* SAP Announce */
291     {
292         if( !p_announce->p_sap )
293         {
294             msg_Err( p_announce, "can't remove announce, no SAP handler");
295             return VLC_ENOOBJ;
296         }
297         p_announce->p_sap->pf_del( p_announce->p_sap, p_session );
298     }
299     return VLC_SUCCESS;
300 }