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 *****************************************************************************/
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>
34 struct vlc_renderer_item_t
40 char *psz_demux_filter
;
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
);
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
,
62 assert(psz_uri
!= NULL
);
63 vlc_renderer_item_t
*p_item
= NULL
;
65 vlc_UrlParse(&url
, psz_uri
);
67 if (url
.psz_protocol
== NULL
|| url
.psz_host
== NULL
)
70 p_item
= calloc(1, sizeof(vlc_renderer_item_t
));
71 if (unlikely(p_item
== NULL
))
74 if ((p_item
->psz_type
= strdup(psz_type
)) == NULL
)
78 p_item
->psz_name
= strdup(psz_name
);
79 else if (asprintf(&p_item
->psz_name
, "%s (%s)", url
.psz_protocol
,
81 p_item
->psz_name
= NULL
;
82 if (p_item
->psz_name
== NULL
)
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)
91 if (psz_icon_uri
&& (p_item
->psz_icon_uri
= strdup(psz_icon_uri
)) == NULL
)
94 if (psz_demux_filter
&& (p_item
->psz_demux_filter
= strdup(psz_demux_filter
)) == NULL
)
97 p_item
->i_flags
= i_flags
;
98 atomic_init(&p_item
->refs
, 1);
110 vlc_renderer_item_name(const vlc_renderer_item_t
*p_item
)
112 assert(p_item
!= NULL
);
114 return p_item
->psz_name
;
118 vlc_renderer_item_type(const vlc_renderer_item_t
*p_item
)
120 assert(p_item
!= NULL
);
122 return p_item
->psz_type
;
126 vlc_renderer_item_sout(const vlc_renderer_item_t
*p_item
)
128 assert(p_item
!= NULL
);
130 return p_item
->psz_sout
;
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
;
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);
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);
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
);
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
)
206 struct vlc_rd_probe
*p_tab
= vlc_probe(p_obj
, "renderer probe", &i_count
);
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
))
220 free(ppsz_longnames
);
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
;
232 *pppsz_names
= ppsz_names
;
233 *pppsz_longnames
= ppsz_longnames
;
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");
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'",
263 free(p_rd
->psz_name
);
264 config_ChainDestroy(p_rd
->p_cfg
);
265 vlc_object_release(p_rd
);