macosx: Add renderer discovery classes
authorMarvin Scholz <epirat07@gmail.com>
Thu, 16 Jun 2016 21:54:17 +0000 (23:54 +0200)
committerFelix Paul Kühne <fkuehne@videolan.org>
Fri, 17 Jun 2016 15:09:55 +0000 (17:09 +0200)
This adds two wrapper classes:

- VLCRendererDiscovery
  Wraps libvlc’s vlc_renderer_discovery and allows a delegate
  to receive add and delete notifications for renderer items.

- VLCRendererItem
  Wraps libvlc’s vlc_renderer_item, is used by VLCRendererDiscovery
  to conveniently wrap the vlc_renderer_item to use them easier in
  Objective C.

Signed-off-by: Felix Paul Kühne <fkuehne@videolan.org>
modules/gui/macosx/VLCRendererDiscovery.h [new file with mode: 0644]
modules/gui/macosx/VLCRendererDiscovery.m [new file with mode: 0644]
modules/gui/macosx/VLCRendererItem.h [new file with mode: 0644]
modules/gui/macosx/VLCRendererItem.m [new file with mode: 0644]

diff --git a/modules/gui/macosx/VLCRendererDiscovery.h b/modules/gui/macosx/VLCRendererDiscovery.h
new file mode 100644 (file)
index 0000000..b45278a
--- /dev/null
@@ -0,0 +1,124 @@
+/*****************************************************************************
+ * VLCRendererDiscovery.h: Wrapper class for vlc_renderer_discovery
+ *****************************************************************************
+ * Copyright (C) 2016 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Marvin Scholz <epirat07 at gmail dot com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Foundation/Foundation.h>
+
+#import "VLCRendererItem.h"
+
+@protocol VLCRendererDiscoveryDelegate;
+
+/**
+ \c VLCRendererDiscovery is a simple wrapper class for libvlc’s
+ \c vlc_renderer_discovery. It's initialized with the renderer name and
+ manages the underlying renderer discovery.
+ */
+@interface VLCRendererDiscovery : NSObject
+
+/**
+ The delegate that is called when a \c VLCRendererItem is added or deleted
+ */
+@property (weak) id<VLCRendererDiscoveryDelegate> delegate;
+
+/**
+ The name of the renderer discovery module
+ */
+@property (readonly) NSString *name;
+
+/**
+ The longname of the renderer discovery module
+ */
+@property (readonly) NSString *longName;
+
+/**
+ Array of \c VLCRendererItems that the module discovered
+ */
+@property (readonly) NSMutableArray<VLCRendererItem*> *rendererItems;
+
+/**
+ Indicates if the discovery has been started
+ */
+@property (readonly) bool discoveryStarted;
+
+/**
+ Initialize the class with a renderer name and (optional) longname retrieved with
+ the \c vlc_rd_get_names function.
+
+ \note In case the renderer discovery service creation fails, nil is returned.
+
+ \param name        Renderer name as C string
+ \param longname    Renderer longname as C string
+
+ \returns   Initialized class that already created the underlying
+            \c vlc_renderer_discovery structure or nil on failure.
+ */
+- (instancetype)initWithName:(const char*)name andLongname:(const char*)longname;
+
+/**
+ Starts the renderer discovery
+
+ \return YES if the renderer was successfully started, NO otherwise.
+
+ \sa -stopDiscovery
+ */
+- (bool)startDiscovery;
+
+/**
+ Stops the renderer discovery
+
+ \note Stopping an already stopped renderer discovery has no effect.
+
+ \sa -startDiscovery
+ */
+- (void)stopDiscovery;
+
+@end
+
+#pragma mark Delegate Protocol
+/**
+ \c VLCRendererDiscoveryDelegate protocol defines the required methods
+ to be implemented by a \c VLCRendererDiscovery delegate.
+ */
+@protocol VLCRendererDiscoveryDelegate
+@required
+
+/**
+ Invoked when a \c VLCRendererItem was added
+
+ \param item    The renderer item that was added
+ \param sender  The \c VLCRendererDiscovery object that added the Item.
+
+ \sa -removedRendererItem:from:
+ */
+- (void)addedRendererItem:(VLCRendererItem *)item from:(VLCRendererDiscovery *)sender;
+
+/**
+ Invoked when a \c VLCRendererItem was removed
+
+ \param item    The renderer item that was removed
+ \param sender  The \c VLCRendererDiscovery object that removed the Item.
+
+ \sa -addedRendererItem:from:
+ */
+- (void)removedRendererItem:(VLCRendererItem *)item from:(VLCRendererDiscovery *)sender;
+
+@end
diff --git a/modules/gui/macosx/VLCRendererDiscovery.m b/modules/gui/macosx/VLCRendererDiscovery.m
new file mode 100644 (file)
index 0000000..96050e8
--- /dev/null
@@ -0,0 +1,152 @@
+/*****************************************************************************
+ * VLCRendererDiscovery.m: Wrapper class for vlc_renderer_discovery
+ *****************************************************************************
+ * Copyright (C) 2016 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Marvin Scholz <epirat07 at gmail dot com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "VLCRendererDiscovery.h"
+
+#import "intf.h"
+
+#include <vlc_common.h>
+#include <vlc_renderer_discovery.h>
+
+@interface VLCRendererDiscovery ()
+{
+    intf_thread_t          *p_intf;
+    vlc_renderer_discovery *p_rd;
+}
+
+- (void)handleEvent:(const vlc_event_t *)event;
+@end
+
+// C callback event handler function for vlc_event_manager
+static void renderer_event_received(const vlc_event_t *p_event, void *user_data)
+{
+    VLCRendererDiscovery *target = (__bridge VLCRendererDiscovery*)user_data;
+    [target handleEvent:p_event];
+}
+
+@implementation VLCRendererDiscovery
+
+- (instancetype)initWithName:(const char*)name andLongname:(const char*)longname
+{
+    self = [super init];
+
+    if (self) {
+        if (!name)
+            [NSException raise:NSInvalidArgumentException
+                        format:@"name must not be nil"];
+
+        // Create renderer object
+        p_intf = getIntf();
+        p_rd = vlc_rd_new(VLC_OBJECT(p_intf), name);
+
+        if (p_rd) {
+            _name = [NSString stringWithUTF8String:name];
+            _longName = (!longname) ? nil : [NSString stringWithUTF8String:longname];
+            _discoveryStarted = false;
+        } else {
+            msg_Err(p_intf, "Could not create '%s' renderer discovery service", name);
+            self = nil;
+        }
+    }
+    return self;
+}
+
+- (void)dealloc
+{
+    if (_discoveryStarted)
+        [self stopDiscovery];
+    if (p_rd != NULL)
+        vlc_rd_release(p_rd);
+}
+
+- (bool)startDiscovery
+{
+    msg_Dbg(p_intf, "Starting renderer discovery service %s", _name.UTF8String);
+    [self attachEventHandlers];
+    int ret = vlc_rd_start(p_rd);
+    if (ret == VLC_SUCCESS) {
+        _discoveryStarted = true;
+        return true;
+    } else {
+        msg_Err(p_intf, "Could not start '%s' renderer discovery", _name.UTF8String);
+        [self detachEventHandler];
+        return false;
+    }
+}
+
+- (void)stopDiscovery
+{
+    if (_discoveryStarted) {
+        [self detachEventHandler];
+        vlc_rd_stop(p_rd);
+        _discoveryStarted = false;
+    }
+}
+
+- (void)attachEventHandlers
+{
+    vlc_event_manager_t *em = vlc_rd_event_manager(p_rd);
+    vlc_event_attach(em, vlc_RendererDiscoveryItemAdded, renderer_event_received, (__bridge void *)self);
+    vlc_event_attach(em, vlc_RendererDiscoveryItemRemoved, renderer_event_received, (__bridge void *)self);
+}
+
+- (void)detachEventHandler
+{
+    vlc_event_manager_t *em = vlc_rd_event_manager(p_rd);
+    vlc_event_detach(em, vlc_RendererDiscoveryItemAdded, renderer_event_received, (__bridge void *)self);
+    vlc_event_detach(em, vlc_RendererDiscoveryItemRemoved, renderer_event_received, (__bridge void *)self);
+}
+
+- (void)handleEvent:(const vlc_event_t *)event
+{
+    if (event->type == vlc_RendererDiscoveryItemAdded) {
+        vlc_renderer_item *base_item =  event->u.renderer_discovery_item_added.p_new_item;
+        VLCRendererItem *item = [[VLCRendererItem alloc] initWithRendererItem:base_item];
+        [_rendererItems addObject:item];
+        if (_delegate)
+            [_delegate addedRendererItem:item from:self];
+        return;
+    }
+    if (event->type == vlc_RendererDiscoveryItemRemoved) {
+        vlc_renderer_item *base_item =  event->u.renderer_discovery_item_removed.p_item;
+
+        VLCRendererItem *result_item = nil;
+        for (VLCRendererItem *item in _rendererItems) {
+            if (item.rendererItem == base_item) {
+                result_item = item;
+                return;
+            }
+        }
+        if (result_item) {
+            [_rendererItems removeObject:result_item];
+            if (_delegate)
+                [_delegate removedRendererItem:result_item from:self];
+        } else {
+            msg_Err(p_intf, "VLCRendererDiscovery could not find item to remove!");
+        }
+        return;
+    }
+    msg_Err(p_intf, "VLCRendererDiscovery received event of unhandled type");
+}
+
+@end
diff --git a/modules/gui/macosx/VLCRendererItem.h b/modules/gui/macosx/VLCRendererItem.h
new file mode 100644 (file)
index 0000000..e46618a
--- /dev/null
@@ -0,0 +1,85 @@
+/*****************************************************************************
+ * VLCRendererItem.h: Wrapper class for vlc_renderer_item
+ *****************************************************************************
+ * Copyright (C) 2016 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Marvin Scholz <epirat07 at gmail dot com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Foundation/Foundation.h>
+
+#include <vlc_common.h>
+#include <vlc_playlist.h>
+
+/**
+ \c VLCRendererItem is a simple wrapper class for libvlc’s
+ \c vlc_renderer_item. It's initialized with the renderer item and
+ manages it's lifetime.
+ */
+@interface VLCRendererItem : NSObject
+
+/**
+ Initialize the object with a renderer item, typically received from
+ a \c vlc_renderer_discovery event.
+ */
+- (instancetype)initWithRendererItem:(vlc_renderer_item*)item;
+
+/**
+ The underlying \c vlc_renderer_item item
+ */
+@property (readonly) vlc_renderer_item* rendererItem;
+
+/**
+ The name of the renderer item
+ */
+- (NSString*)name;
+
+/**
+ The iconURI of the renderer item
+ */
+- (NSString*)iconURI;
+
+/**
+ Flags indicating capabilities of the renderer item
+
+ Compare it to:
+    \li \c VLC_RENDERER_CAN_AUDIO
+    \li \c VLC_RENDERER_CAN_VIDEO
+ */
+- (int)capabilityFlags;
+
+/**
+ Checks if the Item’s sout string is equivalent to the given
+ sout string. If output is YES, it's checked if it's an
+ output sout as well.
+
+ \param sout    The sout c string to compare with
+ \param output  Indicates wether to check if sout is an output
+
+ \return YES if souts match the given sout and output, NO otherwise
+ */
+- (bool)isSoutEqualTo:(const char*)sout asOutput:(bool)output;
+
+/**
+ Sets the passed playlist’s sout to the sout of the \c VLCRendererItem.
+
+ \param playlist The playlist for which to set the sout
+ */
+- (void)setSoutForPlaylist:(playlist_t*)playlist;
+
+@end
diff --git a/modules/gui/macosx/VLCRendererItem.m b/modules/gui/macosx/VLCRendererItem.m
new file mode 100644 (file)
index 0000000..8d4f894
--- /dev/null
@@ -0,0 +1,95 @@
+/*****************************************************************************
+ * VLCRendererItem.m: Wrapper class for vlc_renderer_item
+ *****************************************************************************
+ * Copyright (C) 2016 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Marvin Scholz <epirat07 at gmail dot com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "VLCRendererItem.h"
+#import "StringUtility.h"
+
+#include <vlc_common.h>
+#include <vlc_renderer_discovery.h>
+
+@implementation VLCRendererItem
+
+- (instancetype)initWithRendererItem:(vlc_renderer_item*)item
+{
+    self = [super init];
+    if (self) {
+        if (!item)
+            [NSException raise:NSInvalidArgumentException
+                        format:@"item must not be nil"];
+        _rendererItem = vlc_renderer_item_hold(item);
+    }
+    return self;
+}
+
+- (void)dealloc
+{
+    vlc_renderer_item_release(_rendererItem);
+}
+
+- (NSString*)name
+{
+    const char *name = vlc_renderer_item_name(_rendererItem);
+    if (!name)
+        return nil;
+    return [NSString stringWithUTF8String:name];
+}
+
+- (NSString*)iconURI
+{
+    const char *uri = vlc_renderer_item_icon_uri(_rendererItem);
+    if (!uri)
+        return nil;
+    return [NSString stringWithUTF8String:uri];
+}
+
+- (int)capabilityFlags
+{
+    return vlc_renderer_item_flags(_rendererItem);
+}
+
+- (bool)isSoutEqualTo:(const char*)sout asOutput:(bool)output
+{
+    NSString *temp_sout;
+    NSString *prefix;
+    NSString *self_sout;
+
+    prefix = (output) ? @"#" : @"";
+    self_sout = [prefix stringByAppendingString:toNSStr(vlc_renderer_item_sout(_rendererItem))];
+    temp_sout = toNSStr(sout);
+
+    return [temp_sout isEqualToString:self_sout];
+}
+
+- (void)setSoutForPlaylist:(playlist_t*)playlist
+{
+    NSString *sout;
+    const char *item_sout = vlc_renderer_item_sout(_rendererItem);
+
+    if (!playlist || !item_sout)
+        return;
+
+    sout = [[NSString alloc] initWithFormat:@"#%s", item_sout];
+    var_SetString(playlist , "sout", sout.UTF8String);
+}
+
+@end