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