VLCRendererDiscoverer.m 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*****************************************************************************
  2. * VLCRendererDiscoverer.m
  3. *****************************************************************************
  4. * Copyright © 2018 VLC authors, VideoLAN
  5. * Copyright © 2018 Videolabs
  6. *
  7. * Authors: Soomin Lee<bubu@mikan.io>
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU Lesser General Public License as published by
  11. * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with this program; if not, write to the Free Software Foundation,
  21. * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22. *****************************************************************************/
  23. #import "VLCRendererDiscoverer.h"
  24. #import "VLCLibrary.h"
  25. #import "VLCEventManager.h"
  26. #import "VLCLibVLCBridging.h"
  27. @interface VLCRendererDiscoverer()
  28. {
  29. libvlc_renderer_discoverer_t *_rendererDiscoverer;
  30. NSMutableArray<VLCRendererItem *> *_rendererItems;
  31. }
  32. @end
  33. #pragma mark - LibVLC event callbacks
  34. static void HandleRendererDiscovererItemAdded(const libvlc_event_t *event, void *self)
  35. {
  36. @autoreleasepool {
  37. VLCRendererItem *renderer = [[VLCRendererItem alloc] initWithRendererItem:event->u.renderer_discoverer_item_added.item];
  38. [[VLCEventManager sharedManager] callOnMainThreadObject:(__bridge id)(self)
  39. withMethod:@selector(itemAdded:)
  40. withArgumentAsObject:renderer];
  41. }
  42. }
  43. static void HandleRendererDiscovererItemDeleted(const libvlc_event_t *event, void *self)
  44. {
  45. @autoreleasepool {
  46. VLCRendererItem *renderer = [[VLCRendererItem alloc] initWithRendererItem:event->u.renderer_discoverer_item_deleted.item];
  47. [[VLCEventManager sharedManager] callOnMainThreadObject:(__bridge id)(self)
  48. withMethod:@selector(itemDeleted:)
  49. withArgumentAsObject:renderer];
  50. }
  51. }
  52. #pragma mark - VLCRendererDiscovererDescription
  53. @implementation VLCRendererDiscovererDescription
  54. - (instancetype)initWithName:(NSString *)name longName:(NSString *)longName
  55. {
  56. self = [super init];
  57. if (self) {
  58. NSAssert(!name, @"VLCRendererDiscovererDescription: name is NULL");
  59. _name = name;
  60. NSAssert(!longName, @"VLCRendererDiscovererDescription: longName is NULL");
  61. _longName = longName;
  62. }
  63. return self;
  64. }
  65. @end
  66. #pragma mark - VLCRendererDiscoverer
  67. @implementation VLCRendererDiscoverer
  68. - (instancetype)initWithName:(NSString *)name
  69. {
  70. self = [super init];
  71. if (self) {
  72. NSAssert(!name, @"VLCRendererDiscoverer: name is NULL");
  73. _name = name;
  74. _rendererDiscoverer = libvlc_renderer_discoverer_new([VLCLibrary sharedLibrary].instance, [name UTF8String]);
  75. if (!_rendererDiscoverer) {
  76. NSAssert(_rendererDiscoverer, @"Failed to create renderer with name %@", name);
  77. return nil;
  78. }
  79. _rendererItems = [[NSMutableArray alloc] init];
  80. libvlc_event_manager_t *p_em = libvlc_renderer_discoverer_event_manager(_rendererDiscoverer);
  81. if (p_em) {
  82. libvlc_event_attach(p_em, libvlc_RendererDiscovererItemAdded,
  83. HandleRendererDiscovererItemAdded, (__bridge void *)(self));
  84. libvlc_event_attach(p_em, libvlc_RendererDiscovererItemDeleted,
  85. HandleRendererDiscovererItemDeleted, (__bridge void *)(self));
  86. }
  87. }
  88. return self;
  89. }
  90. - (BOOL)start
  91. {
  92. return libvlc_renderer_discoverer_start(_rendererDiscoverer) == 0;
  93. }
  94. - (void)stop
  95. {
  96. libvlc_renderer_discoverer_stop(_rendererDiscoverer);
  97. }
  98. - (void)dealloc
  99. {
  100. libvlc_event_manager_t *p_em = libvlc_renderer_discoverer_event_manager(_rendererDiscoverer);
  101. if (p_em) {
  102. libvlc_event_detach(p_em, libvlc_RendererDiscovererItemAdded,
  103. HandleRendererDiscovererItemAdded, (__bridge void *)(self));
  104. libvlc_event_detach(p_em, libvlc_RendererDiscovererItemDeleted,
  105. HandleRendererDiscovererItemDeleted, (__bridge void *)(self));
  106. }
  107. if (_rendererDiscoverer) {
  108. libvlc_renderer_discoverer_release(_rendererDiscoverer);
  109. }
  110. }
  111. + (NSArray<VLCRendererDiscovererDescription *> *)list
  112. {
  113. size_t i_nb_services = 0;
  114. libvlc_rd_description_t **pp_services = NULL;
  115. i_nb_services = libvlc_renderer_discoverer_list_get([VLCLibrary sharedLibrary].instance, &pp_services);
  116. if (i_nb_services == 0) {
  117. return NULL;
  118. }
  119. NSMutableArray *list = [[NSMutableArray alloc] init];
  120. for (size_t i = 0; i < i_nb_services; ++i) {
  121. [list addObject:[[VLCRendererDiscovererDescription alloc] initWithName:[NSString stringWithUTF8String:pp_services[i]->psz_name]
  122. longName:[NSString stringWithUTF8String:pp_services[i]->psz_longname]]];
  123. }
  124. if (pp_services) {
  125. libvlc_renderer_discoverer_list_release(pp_services, i_nb_services);
  126. }
  127. return [list copy];
  128. }
  129. - (VLCRendererItem *)discoveredItemsContainItem:(VLCRendererItem *)item
  130. {
  131. for (VLCRendererItem *rendererItem in _rendererItems) {
  132. BOOL hasSameName = [rendererItem.name isEqualToString:item.name];
  133. BOOL hasSameType = [rendererItem.type isEqualToString:item.type];
  134. if (hasSameName && hasSameType) {
  135. return rendererItem;
  136. }
  137. }
  138. return nil;
  139. }
  140. - (NSArray<VLCRendererItem *> *)renderers
  141. {
  142. return [_rendererItems copy];
  143. }
  144. #pragma mark - Handling libvlc event callbacks
  145. - (void)itemAdded:(VLCRendererItem *)item
  146. {
  147. VLCRendererItem *rendererItem = [self discoveredItemsContainItem:item];
  148. if (!rendererItem) {
  149. [_rendererItems addObject:item];
  150. [_delegate rendererDiscovererItemAdded:self item:rendererItem];
  151. }
  152. }
  153. - (void)itemDeleted:(VLCRendererItem *)item
  154. {
  155. VLCRendererItem *rendererItem = [self discoveredItemsContainItem:item];
  156. if (rendererItem) {
  157. [_rendererItems removeObject:rendererItem];
  158. [_delegate rendererDiscovererItemDeleted:self item:rendererItem];
  159. }
  160. }
  161. @end