media_discoverer.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:11k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * media_discoverer.c: libvlc new API media discoverer functions
  3.  *****************************************************************************
  4.  * Copyright (C) 2007 the VideoLAN team
  5.  * $Id: 94b4b0aef6787fbf4526b6f113e16421a55bf991 $
  6.  *
  7.  * Authors: Pierre d'Herbemont <pdherbemont # 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. #include <assert.h>
  24. #include <vlc/libvlc.h>
  25. #include <vlc/libvlc_media.h>
  26. #include <vlc/libvlc_media_list.h>
  27. #include <vlc/libvlc_media_discoverer.h>
  28. #include <vlc/libvlc_events.h>
  29. #include <vlc_services_discovery.h>
  30. #include "libvlc_internal.h"
  31. #include "media_internal.h" // libvlc_media_new_from_input_item()
  32. #include "media_list_internal.h" // _libvlc_media_list_add_media()
  33. struct libvlc_media_discoverer_t
  34. {
  35.     libvlc_event_manager_t * p_event_manager;
  36.     libvlc_instance_t *      p_libvlc_instance;
  37.     services_discovery_t *   p_sd;
  38.     libvlc_media_list_t *    p_mlist;
  39.     bool                     running;
  40.     vlc_dictionary_t         catname_to_submedialist;
  41. };
  42. /*
  43.  * Private functions
  44.  */
  45. /**************************************************************************
  46.  *       services_discovery_item_added (Private) (VLC event callback)
  47.  **************************************************************************/
  48. static void services_discovery_item_added( const vlc_event_t * p_event,
  49.                                            void * user_data )
  50. {
  51.     input_item_t * p_item = p_event->u.services_discovery_item_added.p_new_item;
  52.     const char * psz_cat = p_event->u.services_discovery_item_added.psz_category;
  53.     libvlc_media_t * p_md;
  54.     libvlc_media_discoverer_t * p_mdis = user_data;
  55.     libvlc_media_list_t * p_mlist = p_mdis->p_mlist;
  56.     p_md = libvlc_media_new_from_input_item(
  57.             p_mdis->p_libvlc_instance,
  58.             p_item, NULL );
  59.     /* If we have a category, that mean we have to group the items having
  60.      * that category in a media_list. */
  61.     if( psz_cat )
  62.     {
  63.         p_mlist = vlc_dictionary_value_for_key( &p_mdis->catname_to_submedialist, psz_cat );
  64.         if( p_mlist == kVLCDictionaryNotFound )
  65.         {
  66.             libvlc_media_t * p_catmd;
  67.             p_catmd = libvlc_media_new_as_node( p_mdis->p_libvlc_instance, psz_cat, NULL );
  68.             p_mlist = libvlc_media_subitems( p_catmd, NULL );
  69.             p_mlist->b_read_only = true;
  70.             /* Insert the newly created mlist in our dictionary */
  71.             vlc_dictionary_insert( &p_mdis->catname_to_submedialist, psz_cat, p_mlist );
  72.             /* Insert the md into the root list */
  73.             libvlc_media_list_lock( p_mdis->p_mlist );
  74.             _libvlc_media_list_add_media( p_mdis->p_mlist, p_catmd, NULL );
  75.             libvlc_media_list_unlock( p_mdis->p_mlist );
  76.             /* We don't release the mlist cause the dictionary
  77.              * doesn't retain the object. But we release the md. */
  78.             libvlc_media_release( p_catmd );
  79.         }
  80.     }
  81.     else
  82.     {
  83.         libvlc_media_list_lock( p_mlist );
  84.         _libvlc_media_list_add_media( p_mlist, p_md, NULL );
  85.         libvlc_media_list_unlock( p_mlist );
  86.     }
  87. }
  88. /**************************************************************************
  89.  *       services_discovery_item_removed (Private) (VLC event callback)
  90.  **************************************************************************/
  91. static void services_discovery_item_removed( const vlc_event_t * p_event,
  92.                                              void * user_data )
  93. {
  94.     input_item_t * p_item = p_event->u.services_discovery_item_added.p_new_item;
  95.     libvlc_media_t * p_md;
  96.     libvlc_media_discoverer_t * p_mdis = user_data;
  97.     int i, count = libvlc_media_list_count( p_mdis->p_mlist, NULL );
  98.     libvlc_media_list_lock( p_mdis->p_mlist );
  99.     for( i = 0; i < count; i++ )
  100.     {
  101.         p_md = libvlc_media_list_item_at_index( p_mdis->p_mlist, i, NULL );
  102.         if( p_md->p_input_item == p_item )
  103.         {
  104.             _libvlc_media_list_remove_index( p_mdis->p_mlist, i, NULL );
  105.             break;
  106.         }
  107.     }
  108.     libvlc_media_list_unlock( p_mdis->p_mlist );
  109. }
  110. /**************************************************************************
  111.  *       services_discovery_started (Private) (VLC event callback)
  112.  **************************************************************************/
  113. static void services_discovery_started( const vlc_event_t * p_event,
  114.                                         void * user_data )
  115. {
  116.     VLC_UNUSED(p_event);
  117.     libvlc_media_discoverer_t * p_mdis = user_data;
  118.     libvlc_event_t event;
  119.     p_mdis->running = true;
  120.     event.type = libvlc_MediaDiscovererStarted;
  121.     libvlc_event_send( p_mdis->p_event_manager, &event );
  122. }
  123. /**************************************************************************
  124.  *       services_discovery_ended (Private) (VLC event callback)
  125.  **************************************************************************/
  126. static void services_discovery_ended( const vlc_event_t * p_event,
  127.                                       void * user_data )
  128. {
  129.     VLC_UNUSED(p_event);
  130.     libvlc_media_discoverer_t * p_mdis = user_data;
  131.     libvlc_event_t event;
  132.     p_mdis->running = false;
  133.     event.type = libvlc_MediaDiscovererEnded;
  134.     libvlc_event_send( p_mdis->p_event_manager, &event );
  135. }
  136. /*
  137.  * Public libvlc functions
  138.  */
  139. /**************************************************************************
  140.  *       new (Public)
  141.  *
  142.  * Init an object.
  143.  **************************************************************************/
  144. libvlc_media_discoverer_t *
  145. libvlc_media_discoverer_new_from_name( libvlc_instance_t * p_inst,
  146.                                        const char * psz_name,
  147.                                        libvlc_exception_t * p_e )
  148. {
  149.     libvlc_media_discoverer_t * p_mdis;
  150.     p_mdis = malloc(sizeof(libvlc_media_discoverer_t));
  151.     if( !p_mdis )
  152.     {
  153.         libvlc_exception_raise( p_e, "Not enough memory" );
  154.         return NULL;
  155.     }
  156.     p_mdis->p_libvlc_instance = p_inst;
  157.     p_mdis->p_mlist = libvlc_media_list_new( p_inst, NULL );
  158.     p_mdis->p_mlist->b_read_only = true;
  159.     p_mdis->running = false;
  160.     vlc_dictionary_init( &p_mdis->catname_to_submedialist, 0 );
  161.     p_mdis->p_event_manager = libvlc_event_manager_new( p_mdis,
  162.             p_inst, NULL );
  163.     libvlc_event_manager_register_event_type( p_mdis->p_event_manager,
  164.             libvlc_MediaDiscovererStarted, NULL );
  165.     libvlc_event_manager_register_event_type( p_mdis->p_event_manager,
  166.             libvlc_MediaDiscovererEnded, NULL );
  167.     p_mdis->p_sd = vlc_sd_Create( (vlc_object_t*)p_inst->p_libvlc_int );
  168.     if( !p_mdis->p_sd )
  169.     {
  170.         libvlc_media_list_release( p_mdis->p_mlist );
  171.         libvlc_exception_raise( p_e, "Can't find the services_discovery module named '%s'", psz_name );
  172.         free( p_mdis );
  173.         return NULL;
  174.     }
  175.     vlc_event_attach( services_discovery_EventManager( p_mdis->p_sd ),
  176.                       vlc_ServicesDiscoveryItemAdded,
  177.                       services_discovery_item_added,
  178.                       p_mdis );
  179.     vlc_event_attach( services_discovery_EventManager( p_mdis->p_sd ),
  180.                       vlc_ServicesDiscoveryItemRemoved,
  181.                       services_discovery_item_removed,
  182.                       p_mdis );
  183.     vlc_event_attach( services_discovery_EventManager( p_mdis->p_sd ),
  184.                       vlc_ServicesDiscoveryStarted,
  185.                       services_discovery_started,
  186.                       p_mdis );
  187.     vlc_event_attach( services_discovery_EventManager( p_mdis->p_sd ),
  188.                       vlc_ServicesDiscoveryEnded,
  189.                       services_discovery_ended,
  190.                       p_mdis );
  191.     /* Here we go */
  192.     if( !vlc_sd_Start( p_mdis->p_sd, psz_name ) )
  193.     {
  194.         libvlc_media_list_release( p_mdis->p_mlist );
  195.         libvlc_exception_raise( p_e, "Can't start the services_discovery module named '%s'", psz_name );
  196.         free( p_mdis );
  197.         return NULL;
  198.     }
  199.     return p_mdis;
  200. }
  201. /**************************************************************************
  202.  * release (Public)
  203.  **************************************************************************/
  204. void
  205. libvlc_media_discoverer_release( libvlc_media_discoverer_t * p_mdis )
  206. {
  207.     int i;
  208.     libvlc_media_list_release( p_mdis->p_mlist );
  209.     vlc_sd_StopAndDestroy( p_mdis->p_sd );
  210.     /* Free catname_to_submedialist and all the mlist */
  211.     char ** all_keys = vlc_dictionary_all_keys( &p_mdis->catname_to_submedialist );
  212.     for( i = 0; all_keys[i]; i++ )
  213.     {
  214.         libvlc_media_list_t * p_catmlist = vlc_dictionary_value_for_key( &p_mdis->catname_to_submedialist, all_keys[i] );
  215.         libvlc_media_list_release( p_catmlist );
  216.         free( all_keys[i] );
  217.     }
  218.     free( all_keys );
  219.     vlc_dictionary_clear( &p_mdis->catname_to_submedialist, NULL, NULL );
  220.     libvlc_event_manager_release( p_mdis->p_event_manager );
  221.     free( p_mdis );
  222. }
  223. /**************************************************************************
  224.  * localized_name (Public)
  225.  **************************************************************************/
  226. char *
  227. libvlc_media_discoverer_localized_name( libvlc_media_discoverer_t * p_mdis )
  228. {
  229.     return services_discovery_GetLocalizedName( p_mdis->p_sd );
  230. }
  231. /**************************************************************************
  232.  * media_list (Public)
  233.  **************************************************************************/
  234. libvlc_media_list_t *
  235. libvlc_media_discoverer_media_list( libvlc_media_discoverer_t * p_mdis )
  236. {
  237.     libvlc_media_list_retain( p_mdis->p_mlist );
  238.     return p_mdis->p_mlist;
  239. }
  240. /**************************************************************************
  241.  * event_manager (Public)
  242.  **************************************************************************/
  243. libvlc_event_manager_t *
  244. libvlc_media_discoverer_event_manager( libvlc_media_discoverer_t * p_mdis )
  245. {
  246.     return p_mdis->p_event_manager;
  247. }
  248. /**************************************************************************
  249.  * running (Public)
  250.  **************************************************************************/
  251. int
  252. libvlc_media_discoverer_is_running( libvlc_media_discoverer_t * p_mdis )
  253. {
  254.     return p_mdis->running;
  255. }