Commit a995ddee authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

sd: add proper item tree support

This adds explicit tree support to the SD callback and the
corresponding playlist back-end.
parent 11448014
...@@ -43,8 +43,8 @@ extern "C" { ...@@ -43,8 +43,8 @@ extern "C" {
struct services_discovery_owner_t struct services_discovery_owner_t
{ {
void *sys; /**< Private data for the owner callbacks */ void *sys; /**< Private data for the owner callbacks */
void (*item_added)(struct services_discovery_t *sd, input_item_t *item, void (*item_added)(struct services_discovery_t *sd, input_item_t *parent,
const char *category); input_item_t *item, const char *category);
void (*item_removed)(struct services_discovery_t *sd, input_item_t *item); void (*item_removed)(struct services_discovery_t *sd, input_item_t *item);
}; };
...@@ -147,23 +147,41 @@ VLC_USED; ...@@ -147,23 +147,41 @@ VLC_USED;
VLC_API void vlc_sd_Destroy( services_discovery_t * ); VLC_API void vlc_sd_Destroy( services_discovery_t * );
/**
* Added top-level service callback.
*
* This is a convenience wrapper for services_discovery_AddSubItem().
* It covers the most comomn case wherby the added item is a top-level service,
* i.e. it has no parent node.
*/
static inline void services_discovery_AddItem(services_discovery_t *sd,
input_item_t *item)
{
return sd->owner.item_added(sd, NULL, item, NULL);
}
/** /**
* Added service callback. * Added service callback.
* *
* A services discovery module invokes this function when it "discovers" a new * A services discovery module invokes this function when it "discovers" a new
* service, i.e. a new input item. * service, i.e. a new input item.
* *
* @note The function does not take ownership of the input item; it might * @note This callback does not take ownership of the input item; it might
* however add one of more references. The caller is responsible for releasing * however (and most probably will) add one of more references to the item.
* its reference to the input item. *
* The caller is responsible for releasing its own reference(s) eventually.
* Keeping a reference is necessary to call services_discovery_RemoveItem() or
* to alter the item later. However, if the caller will never remove nor alter
* the item, it can drop its reference(s) immediately.
* *
* @param sd services discoverer / services discovery module instance * @param sd services discoverer / services discovery module instance
* @param item input item to add * @param item input item to add
*/ */
static inline void services_discovery_AddItem(services_discovery_t *sd, static inline void services_discovery_AddSubItem(services_discovery_t *sd,
input_item_t *item) input_item_t *parent,
input_item_t *item)
{ {
return sd->owner.item_added(sd, item, NULL); return sd->owner.item_added(sd, parent, item, NULL);
} }
/** /**
...@@ -177,7 +195,7 @@ static inline void services_discovery_AddItemCat(services_discovery_t *sd, ...@@ -177,7 +195,7 @@ static inline void services_discovery_AddItemCat(services_discovery_t *sd,
input_item_t *item, input_item_t *item,
const char *category) const char *category)
{ {
return sd->owner.item_added(sd, item, category); return sd->owner.item_added(sd, item, NULL, category);
} }
/** /**
......
...@@ -58,6 +58,7 @@ struct libvlc_media_discoverer_t ...@@ -58,6 +58,7 @@ struct libvlc_media_discoverer_t
**************************************************************************/ **************************************************************************/
static void services_discovery_item_added( services_discovery_t *sd, static void services_discovery_item_added( services_discovery_t *sd,
input_item_t *parent,
input_item_t *p_item, input_item_t *p_item,
const char *psz_cat ) const char *psz_cat )
{ {
...@@ -68,6 +69,11 @@ static void services_discovery_item_added( services_discovery_t *sd, ...@@ -68,6 +69,11 @@ static void services_discovery_item_added( services_discovery_t *sd,
p_md = libvlc_media_new_from_input_item( p_mdis->p_libvlc_instance, p_md = libvlc_media_new_from_input_item( p_mdis->p_libvlc_instance,
p_item ); p_item );
if( parent != NULL )
{
/* Flatten items list for now. TODO: tree support. */
}
else
/* If we have a category, that mean we have to group the items having /* If we have a category, that mean we have to group the items having
* that category in a media_list. */ * that category in a media_list. */
if( psz_cat ) if( psz_cat )
......
...@@ -40,11 +40,14 @@ struct vlc_sd_internal_t ...@@ -40,11 +40,14 @@ struct vlc_sd_internal_t
/* A new item has been added to a certain sd */ /* A new item has been added to a certain sd */
static void playlist_sd_item_added(services_discovery_t *sd, static void playlist_sd_item_added(services_discovery_t *sd,
input_item_t *p_input, const char *psz_cat) input_item_t *parent, input_item_t *p_input,
const char *psz_cat)
{ {
assert(parent == NULL || psz_cat == NULL);
vlc_sd_internal_t *sds = sd->owner.sys; vlc_sd_internal_t *sds = sd->owner.sys;
playlist_t *playlist = (playlist_t *)sd->obj.parent; playlist_t *playlist = (playlist_t *)sd->obj.parent;
playlist_item_t *parent; playlist_item_t *node;
const char *longname = (sd->description != NULL) ? sd->description : "?"; const char *longname = (sd->description != NULL) ? sd->description : "?";
msg_Dbg(sd, "adding %s", p_input->psz_name ? p_input->psz_name : "(null)"); msg_Dbg(sd, "adding %s", p_input->psz_name ? p_input->psz_name : "(null)");
...@@ -55,18 +58,21 @@ static void playlist_sd_item_added(services_discovery_t *sd, ...@@ -55,18 +58,21 @@ static void playlist_sd_item_added(services_discovery_t *sd,
PLAYLIST_END, PLAYLIST_END,
PLAYLIST_RO_FLAG|PLAYLIST_SKIP_FLAG); PLAYLIST_RO_FLAG|PLAYLIST_SKIP_FLAG);
/* If p_parent is in root category (this is clearly a hack) and we have a cat */ if (parent != NULL)
node = playlist_ItemGetByInput(playlist, parent);
else
if (psz_cat == NULL) if (psz_cat == NULL)
parent = sds->node; node = sds->node;
else else
{ { /* Parent is NULL (root) and category is specified.
parent = playlist_ChildSearchName(sds->node, psz_cat); * This is clearly a hack. TODO: remove this. */
if (parent == NULL) node = playlist_ChildSearchName(sds->node, psz_cat);
parent = playlist_NodeCreate(playlist, psz_cat, sds->node, if (node == NULL)
PLAYLIST_END, PLAYLIST_RO_FLAG); node = playlist_NodeCreate(playlist, psz_cat, sds->node,
PLAYLIST_END, PLAYLIST_RO_FLAG);
} }
playlist_NodeAddInput(playlist, p_input, parent, 0, PLAYLIST_END); playlist_NodeAddInput(playlist, p_input, node, 0, PLAYLIST_END);
playlist_Unlock(playlist); playlist_Unlock(playlist);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment