mp4: check STCO size before allocation
[vlc.git] / src / misc / renderer_discovery.c
blob6162c879aaf6efe5a95e2bf8b3ef14cd9d5fbcf9
1 /*****************************************************************************
2 * renderer_discovery.c : Renderer Discovery functions
3 *****************************************************************************
4 * Copyright(C) 2016 VLC authors and VideoLAN
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 *(at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
25 #include <assert.h>
27 #include <vlc_common.h>
28 #include <vlc_atomic.h>
29 #include <vlc_renderer_discovery.h>
30 #include <vlc_probe.h>
31 #include <vlc_modules.h>
32 #include <libvlc.h>
34 struct vlc_renderer_item_t
36 char *psz_name;
37 char *psz_type;
38 char *psz_sout;
39 char *psz_icon_uri;
40 char *psz_demux_filter;
41 int i_flags;
42 atomic_uint refs;
45 static void
46 item_free(vlc_renderer_item_t *p_item)
48 free(p_item->psz_name);
49 free(p_item->psz_type);
50 free(p_item->psz_sout);
51 free(p_item->psz_icon_uri);
52 free(p_item->psz_demux_filter);
53 free(p_item);
56 vlc_renderer_item_t *
57 vlc_renderer_item_new(const char *psz_type, const char *psz_name,
58 const char *psz_uri, const char *psz_extra_sout,
59 const char *psz_demux_filter, const char *psz_icon_uri,
60 int i_flags)
62 assert(psz_uri != NULL);
63 vlc_renderer_item_t *p_item = NULL;
64 vlc_url_t url;
65 vlc_UrlParse(&url, psz_uri);
67 if (url.psz_protocol == NULL || url.psz_host == NULL)
68 goto error;
70 p_item = calloc(1, sizeof(vlc_renderer_item_t));
71 if (unlikely(p_item == NULL))
72 goto error;
74 if ((p_item->psz_type = strdup(psz_type)) == NULL)
75 goto error;
77 if (psz_name != NULL)
78 p_item->psz_name = strdup(psz_name);
79 else if (asprintf(&p_item->psz_name, "%s (%s)", url.psz_protocol,
80 url.psz_host) == -1)
81 p_item->psz_name = NULL;
82 if (p_item->psz_name == NULL)
83 goto error;
85 if (asprintf(&p_item->psz_sout, "%s{ip=%s,port=%d%s%s}",
86 url.psz_protocol, url.psz_host, url.i_port,
87 psz_extra_sout != NULL ? "," : "",
88 psz_extra_sout != NULL ? psz_extra_sout : "") == -1)
89 goto error;
91 if (psz_icon_uri && (p_item->psz_icon_uri = strdup(psz_icon_uri)) == NULL)
92 goto error;
94 if (psz_demux_filter && (p_item->psz_demux_filter = strdup(psz_demux_filter)) == NULL)
95 goto error;
97 p_item->i_flags = i_flags;
98 atomic_init(&p_item->refs, 1);
99 vlc_UrlClean(&url);
100 return p_item;
102 error:
103 vlc_UrlClean(&url);
104 if (p_item != NULL)
105 item_free(p_item);
106 return NULL;
109 const char *
110 vlc_renderer_item_name(const vlc_renderer_item_t *p_item)
112 assert(p_item != NULL);
114 return p_item->psz_name;
117 const char *
118 vlc_renderer_item_type(const vlc_renderer_item_t *p_item)
120 assert(p_item != NULL);
122 return p_item->psz_type;
125 const char *
126 vlc_renderer_item_sout(const vlc_renderer_item_t *p_item)
128 assert(p_item != NULL);
130 return p_item->psz_sout;
133 const char *
134 vlc_renderer_item_icon_uri(const vlc_renderer_item_t *p_item)
136 assert(p_item != NULL);
138 return p_item->psz_icon_uri;
141 const char *
142 vlc_renderer_item_demux_filter(const vlc_renderer_item_t *p_item)
144 assert(p_item != NULL);
146 return p_item->psz_demux_filter;
150 vlc_renderer_item_flags(const vlc_renderer_item_t *p_item)
152 assert(p_item != NULL);
154 return p_item->i_flags;
157 vlc_renderer_item_t *
158 vlc_renderer_item_hold(vlc_renderer_item_t *p_item)
160 assert(p_item != NULL);
162 atomic_fetch_add(&p_item->refs, 1);
163 return p_item;
166 void
167 vlc_renderer_item_release(vlc_renderer_item_t *p_item)
169 assert(p_item != NULL);
171 int refs = atomic_fetch_sub(&p_item->refs, 1);
172 assert(refs != 0 );
173 if( refs != 1 )
174 return;
175 item_free(p_item);
178 struct vlc_rd_probe
180 char *psz_name;
181 char *psz_longname;
185 vlc_rd_probe_add(vlc_probe_t *probe, const char *psz_name,
186 const char *psz_longname)
188 struct vlc_rd_probe names = { strdup(psz_name), strdup(psz_longname) };
190 if (unlikely(names.psz_name == NULL || names.psz_longname == NULL
191 || vlc_probe_add(probe, &names, sizeof(names))))
193 free(names.psz_name);
194 free(names.psz_longname);
195 return VLC_ENOMEM;
197 return VLC_PROBE_CONTINUE;
200 #undef vlc_rd_get_names
202 vlc_rd_get_names(vlc_object_t *p_obj, char ***pppsz_names,
203 char ***pppsz_longnames)
205 size_t i_count;
206 struct vlc_rd_probe *p_tab = vlc_probe(p_obj, "renderer probe", &i_count);
208 if (i_count == 0)
210 free(p_tab);
211 return VLC_EGENERIC;
214 char **ppsz_names = vlc_alloc(i_count + 1, sizeof(char *));
215 char **ppsz_longnames = vlc_alloc(i_count + 1, sizeof(char *));
217 if (unlikely(ppsz_names == NULL || ppsz_longnames == NULL))
219 free(ppsz_names);
220 free(ppsz_longnames);
221 free(p_tab);
222 return VLC_EGENERIC;
225 for (size_t i = 0; i < i_count; i++)
227 ppsz_names[i] = p_tab[i].psz_name;
228 ppsz_longnames[i] = p_tab[i].psz_longname;
230 ppsz_names[i_count] = ppsz_longnames[i_count] = NULL;
231 free(p_tab);
232 *pppsz_names = ppsz_names;
233 *pppsz_longnames = ppsz_longnames;
234 return VLC_SUCCESS;
237 void vlc_rd_release(vlc_renderer_discovery_t *p_rd)
239 module_unneed(p_rd, p_rd->p_module);
240 config_ChainDestroy(p_rd->p_cfg);
241 free(p_rd->psz_name);
242 vlc_object_release(p_rd);
245 vlc_renderer_discovery_t *
246 vlc_rd_new(vlc_object_t *p_obj, const char *psz_name,
247 const struct vlc_renderer_discovery_owner *restrict owner)
249 vlc_renderer_discovery_t *p_rd;
251 p_rd = vlc_custom_create(p_obj, sizeof(*p_rd), "renderer discovery");
252 if(!p_rd)
253 return NULL;
254 free(config_ChainCreate(&p_rd->psz_name, &p_rd->p_cfg, psz_name));
256 p_rd->owner = *owner;
257 p_rd->p_module = module_need(p_rd, "renderer_discovery",
258 p_rd->psz_name, true);
259 if (p_rd->p_module == NULL)
261 msg_Err(p_rd, "no suitable renderer discovery module for '%s'",
262 psz_name);
263 free(p_rd->psz_name);
264 config_ChainDestroy(p_rd->p_cfg);
265 vlc_object_release(p_rd);
266 p_rd = NULL;
269 return p_rd;