├── iphone-usb-camera.jpg ├── Thirdparties ├── libs │ ├── ios │ │ ├── libjpeg.a │ │ ├── libuvc.a │ │ └── libusb-1.0.a │ └── macos │ │ ├── libuvc.a │ │ ├── libjpeg.a │ │ └── libusb-1.0.a └── libuvc │ └── include │ ├── libuvc │ ├── libuvc_config.h │ ├── libuvc_internal.h │ └── libuvc.h │ └── utlist.h ├── LiveView ├── Assets.xcassets │ ├── Contents.json │ ├── AccentColor.colorset │ │ └── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── LiveView.entitlements ├── AppDelegate.swift ├── ViewController.swift └── Base.lproj │ └── Main.storyboard ├── LiveView-iOS ├── Assets.xcassets │ ├── Contents.json │ ├── AccentColor.colorset │ │ └── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── debian │ └── control ├── LiveViewUSB.entitlements ├── Info.plist ├── AppDelegate.swift ├── Base.lproj │ └── LaunchScreen.storyboard ├── SceneDelegate.swift └── ViewController.swift ├── LiveView.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── project.pbxproj ├── README.md ├── LiveViewKit ├── LiveViewKit.docc │ └── LiveViewKit.md ├── LiveViewKit.h ├── LVContext.h ├── LiveView.swift └── LVContext.m └── .gitignore /iphone-usb-camera.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danylokos/LiveView/HEAD/iphone-usb-camera.jpg -------------------------------------------------------------------------------- /Thirdparties/libs/ios/libjpeg.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danylokos/LiveView/HEAD/Thirdparties/libs/ios/libjpeg.a -------------------------------------------------------------------------------- /Thirdparties/libs/ios/libuvc.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danylokos/LiveView/HEAD/Thirdparties/libs/ios/libuvc.a -------------------------------------------------------------------------------- /Thirdparties/libs/macos/libuvc.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danylokos/LiveView/HEAD/Thirdparties/libs/macos/libuvc.a -------------------------------------------------------------------------------- /Thirdparties/libs/ios/libusb-1.0.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danylokos/LiveView/HEAD/Thirdparties/libs/ios/libusb-1.0.a -------------------------------------------------------------------------------- /Thirdparties/libs/macos/libjpeg.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danylokos/LiveView/HEAD/Thirdparties/libs/macos/libjpeg.a -------------------------------------------------------------------------------- /LiveView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Thirdparties/libs/macos/libusb-1.0.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danylokos/LiveView/HEAD/Thirdparties/libs/macos/libusb-1.0.a -------------------------------------------------------------------------------- /LiveView-iOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /LiveView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LiveView/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /LiveView-iOS/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LiveView 2 | 3 | This is a demo app that uses IOKit (libusb, libvnc) to interact with USB camera on a jailbroken iPhone 4 | 5 | More details in [the blog post](http://danylokos.github.io/0x05). 6 | 7 | ![iPhone USB Camera setup](./iphone-usb-camera.jpg) 8 | -------------------------------------------------------------------------------- /LiveView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LiveViewKit/LiveViewKit.docc/LiveViewKit.md: -------------------------------------------------------------------------------- 1 | # ``LiveViewKit`` 2 | 3 | Summary 4 | 5 | ## Overview 6 | 7 | Text 8 | 9 | ## Topics 10 | 11 | ### Group 12 | 13 | - ``Symbol`` -------------------------------------------------------------------------------- /LiveView-iOS/debian/control: -------------------------------------------------------------------------------- 1 | Package: org.kostyshyn.LiveView 2 | Name: LiveView 3 | Depends: firmware(>=14.0) 4 | Version: PLACEHOLDER 5 | Architecture: iphoneos-arm 6 | Author: Danylo Kostyshyn 7 | Maintainer: Danylo Kostyshyn 8 | Section: Utilities 9 | Description: Demo app that uses IOKit (libusb, libvnc) to interact with a USB camera on a jailbroken iPhone 10 | Homepage: https://github.com/danylokos/LiveView 11 | -------------------------------------------------------------------------------- /LiveView/LiveView.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.device.usb 8 | 9 | com.apple.security.files.user-selected.read-only 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /LiveViewKit/LiveViewKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // LiveViewKit.h 3 | // LiveViewKit 4 | // 5 | // Created by Danylo Kostyshyn on 25.01.2022. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for LiveViewKit. 11 | FOUNDATION_EXPORT double LiveViewKitVersionNumber; 12 | 13 | //! Project version string for LiveViewKit. 14 | FOUNDATION_EXPORT const unsigned char LiveViewKitVersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | #import "LVContext.h" 19 | -------------------------------------------------------------------------------- /LiveView-iOS/LiveViewUSB.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | get-task-allow 6 | 7 | platform-application 8 | 9 | com.apple.security.exception.iokit-user-client-class 10 | 11 | AppleUSBHostDeviceUserClient 12 | AppleUSBHostInterfaceUserClient 13 | 14 | com.apple.system.diagnostics.iokit-properties 15 | 16 | 17 | -------------------------------------------------------------------------------- /LiveView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // LiveView 4 | // 5 | // Created by Danylo Kostyshyn on 25.01.2022. 6 | // 7 | 8 | import Cocoa 9 | 10 | @main 11 | class AppDelegate: NSObject, NSApplicationDelegate { 12 | 13 | func applicationDidFinishLaunching(_ aNotification: Notification) { 14 | // Insert code here to initialize your application 15 | } 16 | 17 | func applicationWillTerminate(_ aNotification: Notification) { 18 | // Insert code here to tear down your application 19 | } 20 | 21 | func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { 22 | return true 23 | } 24 | 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /LiveView-iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Thirdparties/libuvc/include/libuvc/libuvc_config.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBUVC_CONFIG_H 2 | #define LIBUVC_CONFIG_H 3 | 4 | #define LIBUVC_VERSION_MAJOR 0 5 | #define LIBUVC_VERSION_MINOR 0 6 | #define LIBUVC_VERSION_PATCH 6 7 | #define LIBUVC_VERSION_STR "0.0.6" 8 | #define LIBUVC_VERSION_INT \ 9 | ((0 << 16) | \ 10 | (0 << 8) | \ 11 | (6)) 12 | 13 | /** @brief Test whether libuvc is new enough 14 | * This macro evaluates true if and only if the current version is 15 | * at least as new as the version specified. 16 | */ 17 | #define LIBUVC_VERSION_GTE(major, minor, patch) \ 18 | (LIBUVC_VERSION_INT >= (((major) << 16) | ((minor) << 8) | (patch))) 19 | 20 | #define LIBUVC_HAS_JPEG 1 21 | 22 | #endif // !def(LIBUVC_CONFIG_H) 23 | -------------------------------------------------------------------------------- /LiveViewKit/LVContext.h: -------------------------------------------------------------------------------- 1 | // 2 | // LVContext.h 3 | // LiveViewKit 4 | // 5 | // Created by Danylo Kostyshyn on 30.01.2022. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | struct LVFrameDesc { 12 | uint16_t width; 13 | uint16_t height; 14 | uint32_t fps; 15 | }; 16 | typedef struct LVFrameDesc LVFrameDesc; 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @class LVContext; 21 | @protocol LVContextDelegate 22 | - (void)context:(LVContext *)context logMessage:(char * _Nullable)message; 23 | - (void)context:(LVContext *)context didUpdateFrameDescriptions:(LVFrameDesc *)frameDescs count:(uint8_t)count; 24 | - (void)context:(LVContext *)context didReceiveFrameData:(uint8_t *)data width:(size_t)width height:(size_t)height; 25 | @end 26 | 27 | @interface LVContext : NSObject 28 | @property (weak, nonatomic) id delegate; 29 | + (instancetype)sharedInstance; 30 | - (void)start; 31 | - (void)reload; 32 | - (void)changeFrameDesc:(LVFrameDesc)frameDesc; 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /LiveViewKit/LiveView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LiveViewDemo.swift 3 | // LiveViewKit 4 | // 5 | // Created by Danylo Kostyshyn on 25.01.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | public func image(from data: UnsafePointer, size: (Int, Int)) -> CGImage? { 11 | defer { 12 | data.deallocate() 13 | } 14 | let (width, height) = size 15 | let numComponents = 3 16 | let colorspace = CGColorSpaceCreateDeviceRGB() 17 | guard 18 | let rgbData = CFDataCreate(nil, data, Int(height * width) * numComponents), 19 | let provider = CGDataProvider(data: rgbData), 20 | let imageRef = CGImage( 21 | width: Int(width), 22 | height: Int(height), 23 | bitsPerComponent: 8, 24 | bitsPerPixel: 8 * numComponents, 25 | bytesPerRow: Int(width) * numComponents, 26 | space: colorspace, 27 | bitmapInfo: CGBitmapInfo(rawValue: 0), 28 | provider: provider, 29 | decode: nil, 30 | shouldInterpolate: false, 31 | intent: .defaultIntent 32 | ) else { return nil } 33 | return imageRef 34 | } 35 | -------------------------------------------------------------------------------- /LiveView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "scale" : "1x", 6 | "size" : "16x16" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "1x", 16 | "size" : "32x32" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "2x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "1x", 26 | "size" : "128x128" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "2x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "1x", 36 | "size" : "256x256" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "2x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "1x", 46 | "size" : "512x512" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "2x", 51 | "size" : "512x512" 52 | } 53 | ], 54 | "info" : { 55 | "author" : "xcode", 56 | "version" : 1 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /LiveView-iOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // LiveView-iOS 4 | // 5 | // Created by Danylo Kostyshyn on 25.01.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 14 | // Override point for customization after application launch. 15 | return true 16 | } 17 | 18 | // MARK: UISceneSession Lifecycle 19 | 20 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 21 | // Called when a new scene session is being created. 22 | // Use this method to select a configuration to create the new scene with. 23 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 24 | } 25 | 26 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 27 | // Called when the user discards a scene session. 28 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 29 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 30 | } 31 | 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /LiveView-iOS/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /LiveView-iOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /LiveView-iOS/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // LiveView-iOS 4 | // 5 | // Created by Danylo Kostyshyn on 25.01.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 11 | 12 | var window: UIWindow? 13 | 14 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 15 | guard let windowScene = (scene as? UIWindowScene) else { return } 16 | window = UIWindow(windowScene: windowScene) 17 | window?.rootViewController = ViewController() 18 | window?.makeKeyAndVisible() 19 | } 20 | 21 | func sceneDidDisconnect(_ scene: UIScene) { 22 | // Called as the scene is being released by the system. 23 | // This occurs shortly after the scene enters the background, or when its session is discarded. 24 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 25 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 26 | } 27 | 28 | func sceneDidBecomeActive(_ scene: UIScene) { 29 | // Called when the scene has moved from an inactive state to an active state. 30 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 31 | } 32 | 33 | func sceneWillResignActive(_ scene: UIScene) { 34 | // Called when the scene will move from an active state to an inactive state. 35 | // This may occur due to temporary interruptions (ex. an incoming phone call). 36 | } 37 | 38 | func sceneWillEnterForeground(_ scene: UIScene) { 39 | // Called as the scene transitions from the background to the foreground. 40 | // Use this method to undo the changes made on entering the background. 41 | } 42 | 43 | func sceneDidEnterBackground(_ scene: UIScene) { 44 | // Called as the scene transitions from the foreground to the background. 45 | // Use this method to save data, release shared resources, and store enough scene-specific state information 46 | // to restore the scene back to its current state. 47 | } 48 | 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/macos,xcode,swift 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=macos,xcode,swift 4 | 5 | ### macOS ### 6 | # General 7 | .DS_Store 8 | .AppleDouble 9 | .LSOverride 10 | 11 | # Icon must end with two \r 12 | Icon 13 | 14 | 15 | # Thumbnails 16 | ._* 17 | 18 | # Files that might appear in the root of a volume 19 | .DocumentRevisions-V100 20 | .fseventsd 21 | .Spotlight-V100 22 | .TemporaryItems 23 | .Trashes 24 | .VolumeIcon.icns 25 | .com.apple.timemachine.donotpresent 26 | 27 | # Directories potentially created on remote AFP share 28 | .AppleDB 29 | .AppleDesktop 30 | Network Trash Folder 31 | Temporary Items 32 | .apdisk 33 | 34 | ### Swift ### 35 | # Xcode 36 | # 37 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 38 | 39 | ## User settings 40 | xcuserdata/ 41 | 42 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 43 | *.xcscmblueprint 44 | *.xccheckout 45 | 46 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 47 | build/ 48 | DerivedData/ 49 | *.moved-aside 50 | *.pbxuser 51 | !default.pbxuser 52 | *.mode1v3 53 | !default.mode1v3 54 | *.mode2v3 55 | !default.mode2v3 56 | *.perspectivev3 57 | !default.perspectivev3 58 | 59 | ## Obj-C/Swift specific 60 | *.hmap 61 | 62 | ## App packaging 63 | *.ipa 64 | *.dSYM.zip 65 | *.dSYM 66 | 67 | ## Playgrounds 68 | timeline.xctimeline 69 | playground.xcworkspace 70 | 71 | # Swift Package Manager 72 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 73 | # Packages/ 74 | # Package.pins 75 | # Package.resolved 76 | # *.xcodeproj 77 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 78 | # hence it is not needed unless you have added a package configuration file to your project 79 | # .swiftpm 80 | 81 | .build/ 82 | 83 | # CocoaPods 84 | # We recommend against adding the Pods directory to your .gitignore. However 85 | # you should judge for yourself, the pros and cons are mentioned at: 86 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 87 | # Pods/ 88 | # Add this line if you want to avoid checking in source code from the Xcode workspace 89 | # *.xcworkspace 90 | 91 | # Carthage 92 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 93 | # Carthage/Checkouts 94 | 95 | Carthage/Build/ 96 | 97 | # Accio dependency management 98 | Dependencies/ 99 | .accio/ 100 | 101 | # fastlane 102 | # It is recommended to not store the screenshots in the git repo. 103 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 104 | # For more information about the recommended setup visit: 105 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 106 | 107 | fastlane/report.xml 108 | fastlane/Preview.html 109 | fastlane/screenshots/**/*.png 110 | fastlane/test_output 111 | 112 | # Code Injection 113 | # After new code Injection tools there's a generated folder /iOSInjectionProject 114 | # https://github.com/johnno1962/injectionforxcode 115 | 116 | iOSInjectionProject/ 117 | 118 | ### Xcode ### 119 | 120 | ## Xcode 8 and earlier 121 | 122 | ### Xcode Patch ### 123 | *.xcodeproj/* 124 | !*.xcodeproj/project.pbxproj 125 | !*.xcodeproj/xcshareddata/ 126 | !*.xcworkspace/contents.xcworkspacedata 127 | /*.gcno 128 | **/xcshareddata/WorkspaceSettings.xcsettings 129 | 130 | # End of https://www.toptal.com/developers/gitignore/api/macos,xcode,swift -------------------------------------------------------------------------------- /LiveView/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // LiveView 4 | // 5 | // Created by Danylo Kostyshyn on 25.01.2022. 6 | // 7 | 8 | import Cocoa 9 | import LiveViewKit 10 | 11 | class ViewController: NSViewController { 12 | 13 | private lazy var context: LVContext = { 14 | let context = LVContext.sharedInstance() 15 | context.delegate = self 16 | return context 17 | }() 18 | 19 | private let scrollView = NSTextView.scrollableTextView() 20 | private var textView: NSTextView { scrollView.documentView as! NSTextView } 21 | private let imageView = NSImageView() 22 | 23 | override func viewDidLoad() { 24 | super.viewDidLoad() 25 | 26 | // Do any additional setup after loading the view. 27 | configureViews() 28 | context.start() 29 | } 30 | 31 | func configureButtonsView() -> NSView { 32 | let buttonConfigs = [ 33 | ("arrow.clockwise.circle", #selector(reload(_:))), 34 | ("command.circle", #selector(changeFrameDesc(_:))), 35 | ] 36 | let buttons: [NSButton] = buttonConfigs.map { (iconName, sel) in 37 | let image = NSImage(systemSymbolName: iconName, accessibilityDescription: nil)! 38 | let button = NSButton(image: image, target: self, action: sel) 39 | return button 40 | } 41 | let stackView = NSStackView(views: buttons) 42 | return stackView 43 | } 44 | 45 | func configureViews() { 46 | let buttonsContainer = configureButtonsView() 47 | 48 | textView.textColor = NSColor.textColor 49 | 50 | view.addSubview(scrollView) 51 | view.addSubview(imageView) 52 | view.addSubview(buttonsContainer) 53 | 54 | scrollView.translatesAutoresizingMaskIntoConstraints = false 55 | imageView.translatesAutoresizingMaskIntoConstraints = false 56 | buttonsContainer.translatesAutoresizingMaskIntoConstraints = false 57 | let constraints = [ 58 | scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), 59 | scrollView.topAnchor.constraint(equalTo: view.topAnchor), 60 | scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor), 61 | imageView.leadingAnchor.constraint(equalTo: scrollView.trailingAnchor), 62 | imageView.topAnchor.constraint(equalTo: view.topAnchor), 63 | imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor), 64 | imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor), 65 | buttonsContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 5.0), 66 | buttonsContainer.topAnchor.constraint(equalTo: view.topAnchor, constant: 5.0) 67 | ] 68 | NSLayoutConstraint.activate(constraints) 69 | } 70 | 71 | override var representedObject: Any? { 72 | didSet { 73 | // Update the view, if already loaded. 74 | } 75 | } 76 | 77 | } 78 | 79 | extension ViewController { 80 | 81 | @objc func reload(_ sender: NSButton) { 82 | context.reload() 83 | } 84 | 85 | @objc func changeFrameDesc(_ sender: NSButton) { 86 | let frameDesc = LVFrameDesc(width: 1920, height: 1080, fps: 30) 87 | context.change(frameDesc) 88 | } 89 | 90 | } 91 | 92 | extension ViewController { 93 | 94 | func appendLog(_ str: String) { 95 | let attrs: [NSAttributedString.Key: Any] = [.foregroundColor: NSColor.textColor] 96 | textView.textStorage?.append(NSAttributedString(string: str, attributes: attrs)) 97 | textView.scrollToEndOfDocument(nil) 98 | } 99 | 100 | } 101 | 102 | extension ViewController: LVContextDelegate { 103 | 104 | func context(_ context: LVContext, logMessage message: UnsafeMutablePointer?) { 105 | guard let cStr = message else { return } 106 | let str = String(cString: cStr) 107 | print(str, terminator: "") 108 | DispatchQueue.main.async { 109 | self.appendLog(str) 110 | } 111 | } 112 | 113 | func context(_ context: LVContext, didUpdateFrameDescriptions frameDescs: UnsafeMutablePointer, count: UInt8) { 114 | let frameDescs = (0.., width: Int, height: Int) { 121 | DispatchQueue.main.async { 122 | let imageRef = image(from: data, size: (width, height)) 123 | self.imageView.image = imageRef.flatMap { NSImage(cgImage: $0, size: NSZeroSize) } 124 | } 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /LiveView-iOS/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // LiveView-iOS 4 | // 5 | // Created by Danylo Kostyshyn on 25.01.2022. 6 | // 7 | 8 | import UIKit 9 | import LiveViewKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | private lazy var context: LVContext = { 14 | let context = LVContext.sharedInstance() 15 | context.delegate = self 16 | return context 17 | }() 18 | 19 | private let textView = UITextView() 20 | private let imageView = UIImageView() 21 | 22 | private var frameDescs = [LVFrameDesc]() 23 | 24 | override func viewDidLoad() { 25 | super.viewDidLoad() 26 | 27 | UIApplication.shared.isIdleTimerDisabled = true // Disable screen dimming 28 | configureViews() 29 | context.start() 30 | } 31 | 32 | func configureButtonsContainer() -> UIView { 33 | let buttonConfigs = [ 34 | ("arrow.clockwise.circle", #selector(reload(_:))), 35 | ("doc.circle", #selector(toggleLogs(_:))), 36 | ("command.circle", #selector(changeFrameDesc(_:))), 37 | ("camera.circle", #selector(takePhoto(_:))) 38 | ] 39 | let largeConfig = UIImage.SymbolConfiguration(pointSize: 50, weight: .regular, scale: .large) 40 | let buttons: [UIButton] = buttonConfigs.map { (iconName, sel) in 41 | let button = UIButton(type: .system) 42 | button.setImage(UIImage(systemName: iconName, withConfiguration: largeConfig), for: .normal) 43 | button.imageEdgeInsets = UIEdgeInsets(top: 5.0, left: 5.0, bottom: 5.0, right: 5.0) 44 | button.addTarget(self, action: sel, for: .touchUpInside) 45 | return button 46 | } 47 | let stackView = UIStackView(arrangedSubviews: buttons) 48 | stackView.axis = .vertical 49 | stackView.spacing = 5 50 | return stackView 51 | } 52 | 53 | func configureViews() { 54 | let buttonsView = configureButtonsContainer() 55 | 56 | imageView.contentMode = .scaleAspectFill 57 | textView.alpha = 0.5 58 | textView.isEditable = false 59 | 60 | view.addSubview(imageView) 61 | view.addSubview(textView) 62 | view.addSubview(buttonsView) 63 | 64 | imageView.translatesAutoresizingMaskIntoConstraints = false 65 | textView.translatesAutoresizingMaskIntoConstraints = false 66 | buttonsView.translatesAutoresizingMaskIntoConstraints = false 67 | 68 | let constraints = [ 69 | imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor), 70 | imageView.topAnchor.constraint(equalTo: view.topAnchor), 71 | imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor), 72 | imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor), 73 | textView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), 74 | textView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), 75 | textView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), 76 | textView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), 77 | buttonsView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 5.0), 78 | buttonsView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -5.0) 79 | ] 80 | NSLayoutConstraint.activate(constraints) 81 | } 82 | 83 | func appendLog(_ str: String) { 84 | textView.textStorage.append(NSAttributedString(string: str)) 85 | let range = NSMakeRange(textView.text.count - 1, 0) 86 | textView.scrollRangeToVisible(range) 87 | } 88 | 89 | } 90 | 91 | extension ViewController { 92 | 93 | @objc func reload(_ sender: UIButton) { 94 | context.reload() 95 | } 96 | 97 | @objc func toggleLogs(_ sender: UIButton) { 98 | textView.isHidden.toggle() 99 | } 100 | 101 | @objc func takePhoto(_ sender: UIButton) { 102 | guard let image = imageView.image else { return } 103 | UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) 104 | } 105 | 106 | @objc func changeFrameDesc(_ sender: UIButton) { 107 | let controller = UIAlertController( 108 | title: "Configure", 109 | message: "Change frame description", 110 | preferredStyle: .actionSheet 111 | ) 112 | // Skip first - `default` description, sort by width 113 | frameDescs.dropFirst().sorted { $0.width < $1.width }.forEach { frameDesc in 114 | controller.addAction( 115 | UIAlertAction( 116 | title: "\(frameDesc.width)x\(frameDesc.height) @ \(frameDesc.fps)fps", 117 | style: .default, 118 | handler: { _ in 119 | self.context.change(frameDesc) 120 | }) 121 | )} 122 | controller.addAction(UIAlertAction(title: "Cancel", style: .cancel)) 123 | present(controller, animated: true) 124 | } 125 | 126 | } 127 | 128 | extension ViewController: LVContextDelegate { 129 | 130 | func context(_ context: LVContext, logMessage message: UnsafeMutablePointer?) { 131 | guard let cStr = message else { return } 132 | let str = String(cString: cStr) 133 | print(str, terminator: "") 134 | DispatchQueue.main.async { 135 | self.appendLog(str) 136 | } 137 | } 138 | 139 | func context(_ context: LVContext, didUpdateFrameDescriptions 140 | frameDescs: UnsafeMutablePointer, count: UInt8) { 141 | DispatchQueue.main.async { 142 | self.frameDescs = (0.., width: Int, height: Int) { 150 | DispatchQueue.main.async { 151 | let imageRef = image(from: data, size: (width, height)) 152 | self.imageView.image = imageRef.flatMap{ UIImage(cgImage: $0) } 153 | } 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /LiveViewKit/LVContext.m: -------------------------------------------------------------------------------- 1 | // 2 | // LVContext.m 3 | // LiveViewKit 4 | // 5 | // Created by Danylo Kostyshyn on 30.01.2022. 6 | // 7 | 8 | #import "LVContext.h" 9 | 10 | #include "libuvc/libuvc.h" 11 | #include 12 | #include 13 | 14 | #define printf(...) {\ 15 | char str[200];\ 16 | sprintf(str, __VA_ARGS__);\ 17 | [self.delegate context:self logMessage:str]; \ 18 | } 19 | 20 | #define uvc_perror(res, msg) {\ 21 | printf("%s: %s (%d)\n", msg, uvc_strerror(res), res);\ 22 | } 23 | 24 | @interface LVContext () { 25 | uvc_context_t *ctx; 26 | uvc_device_t *dev; 27 | uvc_device_handle_t *devh; 28 | uvc_stream_ctrl_t ctrl; 29 | uvc_error_t res; 30 | } 31 | @property (strong, nonatomic) NSThread *uvcThread; 32 | @end 33 | 34 | @implementation LVContext 35 | 36 | + (instancetype)sharedInstance { 37 | static dispatch_once_t onceToken; 38 | static LVContext *context; 39 | dispatch_once(&onceToken, ^{ 40 | context = [[LVContext alloc] init]; 41 | }); 42 | return context; 43 | } 44 | 45 | - (instancetype)init { 46 | self = [super init]; 47 | if (self) { 48 | [self uvcInit]; 49 | } 50 | return self; 51 | } 52 | 53 | - (void)start { 54 | [self uvcOpenDevice]; 55 | if (devh) { 56 | [self uvcGetFrameDescriptors]; 57 | [self uvcStartStreaming]; 58 | } 59 | } 60 | 61 | - (void)reload { 62 | if (devh) { 63 | [self uvcStopStreaming]; 64 | } 65 | if (devh && dev) { 66 | [self uvcCloseDevice]; 67 | } 68 | if (ctx) { 69 | [self uvcDeinit]; 70 | } 71 | 72 | // clear-out the vars 73 | ctx = NULL; 74 | dev = NULL; 75 | devh = NULL; 76 | 77 | [self uvcInit]; 78 | [self start]; 79 | } 80 | 81 | - (void)changeFrameDesc:(LVFrameDesc)frameDesc { 82 | if (devh) { 83 | [self uvcStopStreaming]; 84 | [self uvcStartStreamingWithFrameDesc:frameDesc]; 85 | } 86 | } 87 | 88 | - (int)uvcInit { 89 | /* Initialize a UVC service context. Libuvc will set up its own libusb 90 | * context. Replace NULL with a libusb_context pointer to run libuvc 91 | * from an existing libusb context. */ 92 | res = uvc_init(&ctx, NULL); 93 | 94 | if (res < 0) { 95 | uvc_perror(res, "uvc_init"); 96 | return res; 97 | } 98 | 99 | printf("UVC initialized\n"); 100 | return 0; 101 | } 102 | 103 | - (int)uvcOpenDevice { 104 | /* Locates the first attached UVC device, stores in dev */ 105 | res = uvc_find_device(ctx, &dev, 0, 0, NULL); /* filter devices: vendor_id, product_id, "serial_num" */ 106 | 107 | if (res < 0) { 108 | uvc_perror(res, "uvc_find_device"); /* no devices found */ 109 | return res; 110 | } 111 | printf("Device found\n"); 112 | 113 | /* Try to open the device: requires exclusive access */ 114 | res = uvc_open(dev, &devh); 115 | 116 | if (res < 0) { 117 | uvc_perror(res, "uvc_open"); /* unable to open device */ 118 | return res; 119 | } 120 | 121 | printf("Device opened\n"); 122 | 123 | /* Print out a message containing all the information that libuvc 124 | * knows about the device */ 125 | uvc_print_diag(devh, stdout); 126 | 127 | return 0; 128 | } 129 | 130 | - (const uvc_format_desc_t *)uvcGetUncompressedFormatDesc { 131 | const uvc_format_desc_t *format_desc = uvc_get_format_descs(devh); 132 | while (format_desc && format_desc->bDescriptorSubtype != UVC_VS_FORMAT_UNCOMPRESSED) { 133 | format_desc = format_desc->next; 134 | } 135 | 136 | if (format_desc == NULL) { 137 | printf("Can't find uncompressed format\n"); 138 | return NULL; 139 | } 140 | 141 | return format_desc; 142 | } 143 | 144 | - (int)uvcGetFrameDescriptors { 145 | // Select uncompressed format 146 | const uvc_format_desc_t *format_desc = [self uvcGetUncompressedFormatDesc]; 147 | 148 | // format_desc->bNumFrameDescriptors returns 0 149 | uint8_t bNumFrameDescriptors = 0; 150 | const uvc_frame_desc_t *frame_desc = format_desc->frame_descs; 151 | while (frame_desc) { 152 | frame_desc = frame_desc->next; 153 | bNumFrameDescriptors += 1; 154 | } 155 | 156 | LVFrameDesc *frameDescs = calloc(bNumFrameDescriptors, sizeof(LVFrameDesc)); 157 | frame_desc = format_desc->frame_descs; 158 | int idx = 0; 159 | while (frame_desc) { 160 | LVFrameDesc desc; 161 | desc.width = frame_desc->wWidth; 162 | desc.height = frame_desc->wHeight; 163 | desc.fps = 10000000 / frame_desc->dwDefaultFrameInterval; 164 | frameDescs[idx++] = desc; 165 | frame_desc = frame_desc->next; 166 | } 167 | [self.delegate context:self didUpdateFrameDescriptions:frameDescs count:bNumFrameDescriptors]; 168 | 169 | return 0; 170 | } 171 | 172 | - (int)uvcStartStreaming { 173 | const uvc_format_desc_t *format_desc = [self uvcGetUncompressedFormatDesc]; 174 | 175 | LVFrameDesc frameDesc; 176 | frameDesc.width = 640; 177 | frameDesc.height = 480; 178 | frameDesc.fps = 30; 179 | 180 | const uvc_frame_desc_t *frame_desc = format_desc->frame_descs; 181 | if (frame_desc) { 182 | frameDesc.width = frame_desc->wWidth; 183 | frameDesc.height = frame_desc->wHeight; 184 | frameDesc.fps = 10000000 / frame_desc->dwDefaultFrameInterval; 185 | } 186 | 187 | return [self uvcStartStreamingWithFrameDesc:frameDesc]; 188 | } 189 | 190 | - (int)uvcStartStreamingWithFrameDesc:(LVFrameDesc)frameDesc { 191 | const uvc_format_desc_t *format_desc = [self uvcGetUncompressedFormatDesc]; 192 | enum uvc_frame_format frame_format = UVC_FRAME_FORMAT_YUYV; 193 | 194 | // Defaults 195 | int width = frameDesc.width; 196 | int height = frameDesc.height; 197 | int fps = frameDesc.fps; 198 | 199 | printf("\nFormat: (%4s) %dx%d %dfps\n", format_desc->fourccFormat, width, height, fps); 200 | 201 | /* Try to negotiate first stream profile */ 202 | res = uvc_get_stream_ctrl_format_size(devh, &ctrl, /* result stored in ctrl */ 203 | frame_format, 204 | width, height, fps); /* width, height, fps */ 205 | 206 | /* Print out the result */ 207 | uvc_print_stream_ctrl(&ctrl, stdout); 208 | 209 | if (res < 0) { 210 | uvc_perror(res, "get_mode"); /* device doesn't provide a matching stream */ 211 | return res; 212 | } 213 | /* Start the video stream. The library will call user function cb: 214 | * cb(frame, (void *) 12345) 215 | */ 216 | res = uvc_start_streaming(devh, &ctrl, uvc_frame_cb, (__bridge void *)self, 0); 217 | 218 | if (res < 0) { 219 | uvc_perror(res, "start_streaming"); /* unable to start stream */ 220 | return res; 221 | } 222 | 223 | printf("Streaming...\n"); 224 | 225 | /* enable auto exposure - see uvc_set_ae_mode documentation */ 226 | printf("Enabling auto exposure ...\n"); 227 | const uint8_t UVC_AUTO_EXPOSURE_MODE_AUTO = 2; 228 | res = uvc_set_ae_mode(devh, UVC_AUTO_EXPOSURE_MODE_AUTO); 229 | if (res == UVC_SUCCESS) { 230 | printf(" ... enabled auto exposure\n"); 231 | } else if (res == UVC_ERROR_PIPE) { 232 | /* this error indicates that the camera does not support the full AE mode; 233 | * try again, using aperture priority mode (fixed aperture, variable exposure time) */ 234 | printf(" ... full AE not supported, trying aperture priority mode\n"); 235 | const uint8_t UVC_AUTO_EXPOSURE_MODE_APERTURE_PRIORITY = 8; 236 | res = uvc_set_ae_mode(devh, UVC_AUTO_EXPOSURE_MODE_APERTURE_PRIORITY); 237 | if (res < 0) { 238 | uvc_perror(res, " ... uvc_set_ae_mode failed to enable aperture priority mode"); 239 | } else { 240 | printf(" ... enabled aperture priority auto exposure mode\n"); 241 | } 242 | } else { 243 | uvc_perror(res, " ... uvc_set_ae_mode failed to enable auto exposure mode"); 244 | } 245 | 246 | return 0; 247 | } 248 | 249 | - (int)uvcStopStreaming { 250 | /* End the stream. Blocks until last callback is serviced */ 251 | uvc_stop_streaming(devh); 252 | printf("Done streaming.\n"); 253 | return 0; 254 | } 255 | 256 | - (int)uvcCloseDevice { 257 | /* Release our handle on the device */ 258 | uvc_close(devh); 259 | printf("Device closed\n"); 260 | 261 | /* Release the device descriptor */ 262 | uvc_unref_device(dev); 263 | return 0; 264 | } 265 | 266 | - (int)uvcDeinit { 267 | /* Close the UVC context. This closes and cleans up any existing device handles, 268 | * and it closes the libusb context if one was not provided. */ 269 | uvc_exit(ctx); 270 | printf("UVC exited\n"); 271 | return 0; 272 | } 273 | 274 | /* This callback function runs once per frame. Use it to perform any 275 | * quick processing you need, or have it put the frame into your application's 276 | * input queue. If this function takes too long, you'll start losing frames. */ 277 | void uvc_frame_cb(uvc_frame_t *frame, void *ptr) { 278 | LVContext *lvContext = (__bridge LVContext *)(ptr); 279 | [lvContext processFrame:frame]; 280 | } 281 | 282 | - (void)processFrame:(uvc_frame_t *)frame { 283 | uvc_frame_t *rgb; 284 | uvc_error_t ret; 285 | /* FILE *fp; 286 | * static int jpeg_count = 0; 287 | * static const char *H264_FILE = "iOSDevLog.h264"; 288 | * static const char *MJPEG_FILE = ".jpeg"; 289 | * char filename[16]; */ 290 | 291 | /* We'll convert the image from YUV/JPEG to rgb, so allocate space */ 292 | rgb = uvc_allocate_frame(frame->width * frame->height * 3); 293 | if (!rgb) { 294 | printf("unable to allocate rgb frame!\n"); 295 | return; 296 | } 297 | 298 | // printf("callback! frame_format = %d, width = %d, height = %d, length = %lu\n", 299 | // frame->frame_format, frame->width, frame->height, frame->data_bytes); 300 | 301 | switch (frame->frame_format) { 302 | case UVC_FRAME_FORMAT_H264: 303 | /* use `ffplay H264_FILE` to play */ 304 | /* fp = fopen(H264_FILE, "a"); 305 | * fwrite(frame->data, 1, frame->data_bytes, fp); 306 | * fclose(fp); */ 307 | break; 308 | case UVC_COLOR_FORMAT_MJPEG: 309 | /* sprintf(filename, "%d%s", jpeg_count++, MJPEG_FILE); 310 | * fp = fopen(filename, "w"); 311 | * fwrite(frame->data, 1, frame->data_bytes, fp); 312 | * fclose(fp); */ 313 | break; 314 | case UVC_COLOR_FORMAT_YUYV: 315 | /* Do the rgb conversion */ 316 | ret = uvc_any2rgb(frame, rgb); 317 | if (ret) { 318 | uvc_perror(ret, "uvc_any2rgb"); 319 | uvc_free_frame(rgb); 320 | return; 321 | } 322 | break; 323 | default: 324 | break; 325 | } 326 | 327 | if (frame->sequence % 30 == 0) { 328 | printf(" * got image %u\n", frame->sequence); 329 | } 330 | 331 | uint8_t *frame_data = malloc(rgb->data_bytes); 332 | memcpy(frame_data, rgb->data, rgb->data_bytes); 333 | 334 | [self.delegate context:self 335 | didReceiveFrameData:frame_data 336 | width:rgb->width 337 | height:rgb->height]; 338 | 339 | uvc_free_frame(rgb); 340 | } 341 | 342 | @end 343 | -------------------------------------------------------------------------------- /Thirdparties/libuvc/include/libuvc/libuvc_internal.h: -------------------------------------------------------------------------------- 1 | /** @file libuvc_internal.h 2 | * @brief Implementation-specific UVC constants and structures. 3 | * @cond include_hidden 4 | */ 5 | #ifndef LIBUVC_INTERNAL_H 6 | #define LIBUVC_INTERNAL_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "utlist.h" 16 | 17 | /** Converts an unaligned four-byte little-endian integer into an int32 */ 18 | #define DW_TO_INT(p) ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24)) 19 | /** Converts an unaligned two-byte little-endian integer into an int16 */ 20 | #define SW_TO_SHORT(p) ((p)[0] | ((p)[1] << 8)) 21 | /** Converts an int16 into an unaligned two-byte little-endian integer */ 22 | #define SHORT_TO_SW(s, p) \ 23 | (p)[0] = (s); \ 24 | (p)[1] = (s) >> 8; 25 | /** Converts an int32 into an unaligned four-byte little-endian integer */ 26 | #define INT_TO_DW(i, p) \ 27 | (p)[0] = (i); \ 28 | (p)[1] = (i) >> 8; \ 29 | (p)[2] = (i) >> 16; \ 30 | (p)[3] = (i) >> 24; 31 | 32 | /** Selects the nth item in a doubly linked list. n=-1 selects the last item. */ 33 | #define DL_NTH(head, out, n) \ 34 | do { \ 35 | int dl_nth_i = 0; \ 36 | LDECLTYPE(head) dl_nth_p = (head); \ 37 | if ((n) < 0) { \ 38 | while (dl_nth_p && dl_nth_i > (n)) { \ 39 | dl_nth_p = dl_nth_p->prev; \ 40 | dl_nth_i--; \ 41 | } \ 42 | } else { \ 43 | while (dl_nth_p && dl_nth_i < (n)) { \ 44 | dl_nth_p = dl_nth_p->next; \ 45 | dl_nth_i++; \ 46 | } \ 47 | } \ 48 | (out) = dl_nth_p; \ 49 | } while (0); 50 | 51 | #ifdef UVC_DEBUGGING 52 | #include 53 | #ifdef __ANDROID__ 54 | #include 55 | #define UVC_DEBUG(format, ...) __android_log_print(ANDROID_LOG_DEBUG, "libuvc", "[%s:%d/%s] " format "\n", basename(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__) 56 | #define UVC_ENTER() __android_log_print(ANDROID_LOG_DEBUG, "libuvc", "[%s:%d] begin %s\n", basename(__FILE__), __LINE__, __FUNCTION__) 57 | #define UVC_EXIT(code) __android_log_print(ANDROID_LOG_DEBUG, "libuvc", "[%s:%d] end %s (%d)\n", basename(__FILE__), __LINE__, __FUNCTION__, code) 58 | #define UVC_EXIT_VOID() __android_log_print(ANDROID_LOG_DEBUG, "libuvc", "[%s:%d] end %s\n", basename(__FILE__), __LINE__, __FUNCTION__) 59 | #else 60 | #define UVC_DEBUG(format, ...) fprintf(stderr, "[%s:%d/%s] " format "\n", basename(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__) 61 | #define UVC_ENTER() fprintf(stderr, "[%s:%d] begin %s\n", basename(__FILE__), __LINE__, __FUNCTION__) 62 | #define UVC_EXIT(code) fprintf(stderr, "[%s:%d] end %s (%d)\n", basename(__FILE__), __LINE__, __FUNCTION__, code) 63 | #define UVC_EXIT_VOID() fprintf(stderr, "[%s:%d] end %s\n", basename(__FILE__), __LINE__, __FUNCTION__) 64 | #endif 65 | #else 66 | #define UVC_DEBUG(format, ...) 67 | #define UVC_ENTER() 68 | #define UVC_EXIT_VOID() 69 | #define UVC_EXIT(code) 70 | #endif 71 | 72 | /* http://stackoverflow.com/questions/19452971/array-size-macro-that-rejects-pointers */ 73 | #define IS_INDEXABLE(arg) (sizeof(arg[0])) 74 | #define IS_ARRAY(arg) (IS_INDEXABLE(arg) && (((void *) &arg) == ((void *) arg))) 75 | #define ARRAYSIZE(arr) (sizeof(arr) / (IS_ARRAY(arr) ? sizeof(arr[0]) : 0)) 76 | 77 | /** Video interface subclass code (A.2) */ 78 | enum uvc_int_subclass_code { 79 | UVC_SC_UNDEFINED = 0x00, 80 | UVC_SC_VIDEOCONTROL = 0x01, 81 | UVC_SC_VIDEOSTREAMING = 0x02, 82 | UVC_SC_VIDEO_INTERFACE_COLLECTION = 0x03 83 | }; 84 | 85 | /** Video interface protocol code (A.3) */ 86 | enum uvc_int_proto_code { 87 | UVC_PC_PROTOCOL_UNDEFINED = 0x00 88 | }; 89 | 90 | /** VideoControl interface descriptor subtype (A.5) */ 91 | enum uvc_vc_desc_subtype { 92 | UVC_VC_DESCRIPTOR_UNDEFINED = 0x00, 93 | UVC_VC_HEADER = 0x01, 94 | UVC_VC_INPUT_TERMINAL = 0x02, 95 | UVC_VC_OUTPUT_TERMINAL = 0x03, 96 | UVC_VC_SELECTOR_UNIT = 0x04, 97 | UVC_VC_PROCESSING_UNIT = 0x05, 98 | UVC_VC_EXTENSION_UNIT = 0x06 99 | }; 100 | 101 | /** UVC endpoint descriptor subtype (A.7) */ 102 | enum uvc_ep_desc_subtype { 103 | UVC_EP_UNDEFINED = 0x00, 104 | UVC_EP_GENERAL = 0x01, 105 | UVC_EP_ENDPOINT = 0x02, 106 | UVC_EP_INTERRUPT = 0x03 107 | }; 108 | 109 | /** VideoControl interface control selector (A.9.1) */ 110 | enum uvc_vc_ctrl_selector { 111 | UVC_VC_CONTROL_UNDEFINED = 0x00, 112 | UVC_VC_VIDEO_POWER_MODE_CONTROL = 0x01, 113 | UVC_VC_REQUEST_ERROR_CODE_CONTROL = 0x02 114 | }; 115 | 116 | /** Terminal control selector (A.9.2) */ 117 | enum uvc_term_ctrl_selector { 118 | UVC_TE_CONTROL_UNDEFINED = 0x00 119 | }; 120 | 121 | /** Selector unit control selector (A.9.3) */ 122 | enum uvc_su_ctrl_selector { 123 | UVC_SU_CONTROL_UNDEFINED = 0x00, 124 | UVC_SU_INPUT_SELECT_CONTROL = 0x01 125 | }; 126 | 127 | /** Extension unit control selector (A.9.6) */ 128 | enum uvc_xu_ctrl_selector { 129 | UVC_XU_CONTROL_UNDEFINED = 0x00 130 | }; 131 | 132 | /** VideoStreaming interface control selector (A.9.7) */ 133 | enum uvc_vs_ctrl_selector { 134 | UVC_VS_CONTROL_UNDEFINED = 0x00, 135 | UVC_VS_PROBE_CONTROL = 0x01, 136 | UVC_VS_COMMIT_CONTROL = 0x02, 137 | UVC_VS_STILL_PROBE_CONTROL = 0x03, 138 | UVC_VS_STILL_COMMIT_CONTROL = 0x04, 139 | UVC_VS_STILL_IMAGE_TRIGGER_CONTROL = 0x05, 140 | UVC_VS_STREAM_ERROR_CODE_CONTROL = 0x06, 141 | UVC_VS_GENERATE_KEY_FRAME_CONTROL = 0x07, 142 | UVC_VS_UPDATE_FRAME_SEGMENT_CONTROL = 0x08, 143 | UVC_VS_SYNC_DELAY_CONTROL = 0x09 144 | }; 145 | 146 | /** Status packet type (2.4.2.2) */ 147 | enum uvc_status_type { 148 | UVC_STATUS_TYPE_CONTROL = 1, 149 | UVC_STATUS_TYPE_STREAMING = 2 150 | }; 151 | 152 | /** Payload header flags (2.4.3.3) */ 153 | #define UVC_STREAM_EOH (1 << 7) 154 | #define UVC_STREAM_ERR (1 << 6) 155 | #define UVC_STREAM_STI (1 << 5) 156 | #define UVC_STREAM_RES (1 << 4) 157 | #define UVC_STREAM_SCR (1 << 3) 158 | #define UVC_STREAM_PTS (1 << 2) 159 | #define UVC_STREAM_EOF (1 << 1) 160 | #define UVC_STREAM_FID (1 << 0) 161 | 162 | /** Control capabilities (4.1.2) */ 163 | #define UVC_CONTROL_CAP_GET (1 << 0) 164 | #define UVC_CONTROL_CAP_SET (1 << 1) 165 | #define UVC_CONTROL_CAP_DISABLED (1 << 2) 166 | #define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3) 167 | #define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4) 168 | 169 | struct uvc_streaming_interface; 170 | struct uvc_device_info; 171 | 172 | /** VideoStream interface */ 173 | typedef struct uvc_streaming_interface { 174 | struct uvc_device_info *parent; 175 | struct uvc_streaming_interface *prev, *next; 176 | /** Interface number */ 177 | uint8_t bInterfaceNumber; 178 | /** Video formats that this interface provides */ 179 | struct uvc_format_desc *format_descs; 180 | /** USB endpoint to use when communicating with this interface */ 181 | uint8_t bEndpointAddress; 182 | uint8_t bTerminalLink; 183 | uint8_t bStillCaptureMethod; 184 | } uvc_streaming_interface_t; 185 | 186 | /** VideoControl interface */ 187 | typedef struct uvc_control_interface { 188 | struct uvc_device_info *parent; 189 | struct uvc_input_terminal *input_term_descs; 190 | // struct uvc_output_terminal *output_term_descs; 191 | struct uvc_selector_unit *selector_unit_descs; 192 | struct uvc_processing_unit *processing_unit_descs; 193 | struct uvc_extension_unit *extension_unit_descs; 194 | uint16_t bcdUVC; 195 | uint32_t dwClockFrequency; 196 | uint8_t bEndpointAddress; 197 | /** Interface number */ 198 | uint8_t bInterfaceNumber; 199 | } uvc_control_interface_t; 200 | 201 | struct uvc_stream_ctrl; 202 | 203 | struct uvc_device { 204 | struct uvc_context *ctx; 205 | int ref; 206 | libusb_device *usb_dev; 207 | }; 208 | 209 | typedef struct uvc_device_info { 210 | /** Configuration descriptor for USB device */ 211 | struct libusb_config_descriptor *config; 212 | /** VideoControl interface provided by device */ 213 | uvc_control_interface_t ctrl_if; 214 | /** VideoStreaming interfaces on the device */ 215 | uvc_streaming_interface_t *stream_ifs; 216 | } uvc_device_info_t; 217 | 218 | /* 219 | set a high number of transfer buffers. This uses a lot of ram, but 220 | avoids problems with scheduling delays on slow boards causing missed 221 | transfers. A better approach may be to make the transfer thread FIFO 222 | scheduled (if we have root). 223 | Default number of transfer buffers can be overwritten by defining 224 | this macro. 225 | */ 226 | #ifndef LIBUVC_NUM_TRANSFER_BUFS 227 | #if defined(__APPLE__) && defined(__MACH__) 228 | #define LIBUVC_NUM_TRANSFER_BUFS 20 229 | #else 230 | #define LIBUVC_NUM_TRANSFER_BUFS 100 231 | #endif 232 | #endif 233 | 234 | #define LIBUVC_XFER_META_BUF_SIZE ( 4 * 1024 ) 235 | 236 | struct uvc_stream_handle { 237 | struct uvc_device_handle *devh; 238 | struct uvc_stream_handle *prev, *next; 239 | struct uvc_streaming_interface *stream_if; 240 | 241 | /** if true, stream is running (streaming video to host) */ 242 | uint8_t running; 243 | /** Current control block */ 244 | struct uvc_stream_ctrl cur_ctrl; 245 | 246 | /* listeners may only access hold*, and only when holding a 247 | * lock on cb_mutex (probably signaled with cb_cond) */ 248 | uint8_t fid; 249 | uint32_t seq, hold_seq; 250 | uint32_t pts, hold_pts; 251 | uint32_t last_scr, hold_last_scr; 252 | size_t got_bytes, hold_bytes; 253 | uint8_t *outbuf, *holdbuf; 254 | pthread_mutex_t cb_mutex; 255 | pthread_cond_t cb_cond; 256 | pthread_t cb_thread; 257 | uint32_t last_polled_seq; 258 | uvc_frame_callback_t *user_cb; 259 | void *user_ptr; 260 | struct libusb_transfer *transfers[LIBUVC_NUM_TRANSFER_BUFS]; 261 | uint8_t *transfer_bufs[LIBUVC_NUM_TRANSFER_BUFS]; 262 | struct uvc_frame frame; 263 | enum uvc_frame_format frame_format; 264 | struct timespec capture_time_finished; 265 | 266 | /* raw metadata buffer if available */ 267 | uint8_t *meta_outbuf, *meta_holdbuf; 268 | size_t meta_got_bytes, meta_hold_bytes; 269 | }; 270 | 271 | /** Handle on an open UVC device 272 | * 273 | * @todo move most of this into a uvc_device struct? 274 | */ 275 | struct uvc_device_handle { 276 | struct uvc_device *dev; 277 | struct uvc_device_handle *prev, *next; 278 | /** Underlying USB device handle */ 279 | libusb_device_handle *usb_devh; 280 | struct uvc_device_info *info; 281 | struct libusb_transfer *status_xfer; 282 | uint8_t status_buf[32]; 283 | /** Function to call when we receive status updates from the camera */ 284 | uvc_status_callback_t *status_cb; 285 | void *status_user_ptr; 286 | /** Function to call when we receive button events from the camera */ 287 | uvc_button_callback_t *button_cb; 288 | void *button_user_ptr; 289 | 290 | uvc_stream_handle_t *streams; 291 | /** Whether the camera is an iSight that sends one header per frame */ 292 | uint8_t is_isight; 293 | uint32_t claimed; 294 | }; 295 | 296 | /** Context within which we communicate with devices */ 297 | struct uvc_context { 298 | /** Underlying context for USB communication */ 299 | struct libusb_context *usb_ctx; 300 | /** True iff libuvc initialized the underlying USB context */ 301 | uint8_t own_usb_ctx; 302 | /** List of open devices in this context */ 303 | uvc_device_handle_t *open_devices; 304 | pthread_t handler_thread; 305 | int kill_handler_thread; 306 | }; 307 | 308 | uvc_error_t uvc_query_stream_ctrl( 309 | uvc_device_handle_t *devh, 310 | uvc_stream_ctrl_t *ctrl, 311 | uint8_t probe, 312 | enum uvc_req_code req); 313 | 314 | void uvc_start_handler_thread(uvc_context_t *ctx); 315 | uvc_error_t uvc_claim_if(uvc_device_handle_t *devh, int idx); 316 | uvc_error_t uvc_release_if(uvc_device_handle_t *devh, int idx); 317 | 318 | #endif // !def(LIBUVC_INTERNAL_H) 319 | /** @endcond */ 320 | 321 | -------------------------------------------------------------------------------- /Thirdparties/libuvc/include/libuvc/libuvc.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBUVC_H 2 | #define LIBUVC_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include // FILE 9 | #include 10 | #include 11 | #include 12 | 13 | struct libusb_context; 14 | struct libusb_device_handle; 15 | 16 | /** UVC error types, based on libusb errors 17 | * @ingroup diag 18 | */ 19 | typedef enum uvc_error { 20 | /** Success (no error) */ 21 | UVC_SUCCESS = 0, 22 | /** Input/output error */ 23 | UVC_ERROR_IO = -1, 24 | /** Invalid parameter */ 25 | UVC_ERROR_INVALID_PARAM = -2, 26 | /** Access denied */ 27 | UVC_ERROR_ACCESS = -3, 28 | /** No such device */ 29 | UVC_ERROR_NO_DEVICE = -4, 30 | /** Entity not found */ 31 | UVC_ERROR_NOT_FOUND = -5, 32 | /** Resource busy */ 33 | UVC_ERROR_BUSY = -6, 34 | /** Operation timed out */ 35 | UVC_ERROR_TIMEOUT = -7, 36 | /** Overflow */ 37 | UVC_ERROR_OVERFLOW = -8, 38 | /** Pipe error */ 39 | UVC_ERROR_PIPE = -9, 40 | /** System call interrupted */ 41 | UVC_ERROR_INTERRUPTED = -10, 42 | /** Insufficient memory */ 43 | UVC_ERROR_NO_MEM = -11, 44 | /** Operation not supported */ 45 | UVC_ERROR_NOT_SUPPORTED = -12, 46 | /** Device is not UVC-compliant */ 47 | UVC_ERROR_INVALID_DEVICE = -50, 48 | /** Mode not supported */ 49 | UVC_ERROR_INVALID_MODE = -51, 50 | /** Resource has a callback (can't use polling and async) */ 51 | UVC_ERROR_CALLBACK_EXISTS = -52, 52 | /** Undefined error */ 53 | UVC_ERROR_OTHER = -99 54 | } uvc_error_t; 55 | 56 | /** Color coding of stream, transport-independent 57 | * @ingroup streaming 58 | */ 59 | enum uvc_frame_format { 60 | UVC_FRAME_FORMAT_UNKNOWN = 0, 61 | /** Any supported format */ 62 | UVC_FRAME_FORMAT_ANY = 0, 63 | UVC_FRAME_FORMAT_UNCOMPRESSED, 64 | UVC_FRAME_FORMAT_COMPRESSED, 65 | /** YUYV/YUV2/YUV422: YUV encoding with one luminance value per pixel and 66 | * one UV (chrominance) pair for every two pixels. 67 | */ 68 | UVC_FRAME_FORMAT_YUYV, 69 | UVC_FRAME_FORMAT_UYVY, 70 | /** 24-bit RGB */ 71 | UVC_FRAME_FORMAT_RGB, 72 | UVC_FRAME_FORMAT_BGR, 73 | /** Motion-JPEG (or JPEG) encoded images */ 74 | UVC_FRAME_FORMAT_MJPEG, 75 | UVC_FRAME_FORMAT_H264, 76 | /** Greyscale images */ 77 | UVC_FRAME_FORMAT_GRAY8, 78 | UVC_FRAME_FORMAT_GRAY16, 79 | /* Raw colour mosaic images */ 80 | UVC_FRAME_FORMAT_BY8, 81 | UVC_FRAME_FORMAT_BA81, 82 | UVC_FRAME_FORMAT_SGRBG8, 83 | UVC_FRAME_FORMAT_SGBRG8, 84 | UVC_FRAME_FORMAT_SRGGB8, 85 | UVC_FRAME_FORMAT_SBGGR8, 86 | /** YUV420: NV12 */ 87 | UVC_FRAME_FORMAT_NV12, 88 | /** Number of formats understood */ 89 | UVC_FRAME_FORMAT_COUNT, 90 | }; 91 | 92 | /* UVC_COLOR_FORMAT_* have been replaced with UVC_FRAME_FORMAT_*. Please use 93 | * UVC_FRAME_FORMAT_* instead of using these. */ 94 | #define UVC_COLOR_FORMAT_UNKNOWN UVC_FRAME_FORMAT_UNKNOWN 95 | #define UVC_COLOR_FORMAT_UNCOMPRESSED UVC_FRAME_FORMAT_UNCOMPRESSED 96 | #define UVC_COLOR_FORMAT_COMPRESSED UVC_FRAME_FORMAT_COMPRESSED 97 | #define UVC_COLOR_FORMAT_YUYV UVC_FRAME_FORMAT_YUYV 98 | #define UVC_COLOR_FORMAT_UYVY UVC_FRAME_FORMAT_UYVY 99 | #define UVC_COLOR_FORMAT_RGB UVC_FRAME_FORMAT_RGB 100 | #define UVC_COLOR_FORMAT_BGR UVC_FRAME_FORMAT_BGR 101 | #define UVC_COLOR_FORMAT_MJPEG UVC_FRAME_FORMAT_MJPEG 102 | #define UVC_COLOR_FORMAT_GRAY8 UVC_FRAME_FORMAT_GRAY8 103 | #define UVC_COLOR_FORMAT_GRAY16 UVC_FRAME_FORMAT_GRAY16 104 | #define UVC_COLOR_FORMAT_NV12 UVC_FRAME_FORMAT_NV12 105 | 106 | /** VideoStreaming interface descriptor subtype (A.6) */ 107 | enum uvc_vs_desc_subtype { 108 | UVC_VS_UNDEFINED = 0x00, 109 | UVC_VS_INPUT_HEADER = 0x01, 110 | UVC_VS_OUTPUT_HEADER = 0x02, 111 | UVC_VS_STILL_IMAGE_FRAME = 0x03, 112 | UVC_VS_FORMAT_UNCOMPRESSED = 0x04, 113 | UVC_VS_FRAME_UNCOMPRESSED = 0x05, 114 | UVC_VS_FORMAT_MJPEG = 0x06, 115 | UVC_VS_FRAME_MJPEG = 0x07, 116 | UVC_VS_FORMAT_MPEG2TS = 0x0a, 117 | UVC_VS_FORMAT_DV = 0x0c, 118 | UVC_VS_COLORFORMAT = 0x0d, 119 | UVC_VS_FORMAT_FRAME_BASED = 0x10, 120 | UVC_VS_FRAME_FRAME_BASED = 0x11, 121 | UVC_VS_FORMAT_STREAM_BASED = 0x12 122 | }; 123 | 124 | struct uvc_format_desc; 125 | struct uvc_frame_desc; 126 | 127 | typedef struct uvc_still_frame_res { 128 | struct uvc_still_frame_res *prev, *next; 129 | uint8_t bResolutionIndex; 130 | /** Image width */ 131 | uint16_t wWidth; 132 | /** Image height */ 133 | uint16_t wHeight; 134 | } uvc_still_frame_res_t; 135 | 136 | typedef struct uvc_still_frame_desc { 137 | struct uvc_format_desc *parent; 138 | struct uvc_still_frame_desc *prev, *next; 139 | /** Type of frame, such as JPEG frame or uncompressed frme */ 140 | enum uvc_vs_desc_subtype bDescriptorSubtype; 141 | /** Index of the frame within the list of specs available for this format */ 142 | uint8_t bEndPointAddress; 143 | uvc_still_frame_res_t* imageSizePatterns; 144 | uint8_t bNumCompressionPattern; 145 | /* indication of compression level, the higher, the more compression is applied to image */ 146 | uint8_t* bCompression; 147 | } uvc_still_frame_desc_t; 148 | 149 | /** Frame descriptor 150 | * 151 | * A "frame" is a configuration of a streaming format 152 | * for a particular image size at one of possibly several 153 | * available frame rates. 154 | */ 155 | typedef struct uvc_frame_desc { 156 | struct uvc_format_desc *parent; 157 | struct uvc_frame_desc *prev, *next; 158 | /** Type of frame, such as JPEG frame or uncompressed frme */ 159 | enum uvc_vs_desc_subtype bDescriptorSubtype; 160 | /** Index of the frame within the list of specs available for this format */ 161 | uint8_t bFrameIndex; 162 | uint8_t bmCapabilities; 163 | /** Image width */ 164 | uint16_t wWidth; 165 | /** Image height */ 166 | uint16_t wHeight; 167 | /** Bitrate of corresponding stream at minimal frame rate */ 168 | uint32_t dwMinBitRate; 169 | /** Bitrate of corresponding stream at maximal frame rate */ 170 | uint32_t dwMaxBitRate; 171 | /** Maximum number of bytes for a video frame */ 172 | uint32_t dwMaxVideoFrameBufferSize; 173 | /** Default frame interval (in 100ns units) */ 174 | uint32_t dwDefaultFrameInterval; 175 | /** Minimum frame interval for continuous mode (100ns units) */ 176 | uint32_t dwMinFrameInterval; 177 | /** Maximum frame interval for continuous mode (100ns units) */ 178 | uint32_t dwMaxFrameInterval; 179 | /** Granularity of frame interval range for continuous mode (100ns) */ 180 | uint32_t dwFrameIntervalStep; 181 | /** Frame intervals */ 182 | uint8_t bFrameIntervalType; 183 | /** number of bytes per line */ 184 | uint32_t dwBytesPerLine; 185 | /** Available frame rates, zero-terminated (in 100ns units) */ 186 | uint32_t *intervals; 187 | } uvc_frame_desc_t; 188 | 189 | /** Format descriptor 190 | * 191 | * A "format" determines a stream's image type (e.g., raw YUYV or JPEG) 192 | * and includes many "frame" configurations. 193 | */ 194 | typedef struct uvc_format_desc { 195 | struct uvc_streaming_interface *parent; 196 | struct uvc_format_desc *prev, *next; 197 | /** Type of image stream, such as JPEG or uncompressed. */ 198 | enum uvc_vs_desc_subtype bDescriptorSubtype; 199 | /** Identifier of this format within the VS interface's format list */ 200 | uint8_t bFormatIndex; 201 | uint8_t bNumFrameDescriptors; 202 | /** Format specifier */ 203 | union { 204 | uint8_t guidFormat[16]; 205 | uint8_t fourccFormat[4]; 206 | }; 207 | /** Format-specific data */ 208 | union { 209 | /** BPP for uncompressed stream */ 210 | uint8_t bBitsPerPixel; 211 | /** Flags for JPEG stream */ 212 | uint8_t bmFlags; 213 | }; 214 | /** Default {uvc_frame_desc} to choose given this format */ 215 | uint8_t bDefaultFrameIndex; 216 | uint8_t bAspectRatioX; 217 | uint8_t bAspectRatioY; 218 | uint8_t bmInterlaceFlags; 219 | uint8_t bCopyProtect; 220 | uint8_t bVariableSize; 221 | /** Available frame specifications for this format */ 222 | struct uvc_frame_desc *frame_descs; 223 | struct uvc_still_frame_desc *still_frame_desc; 224 | } uvc_format_desc_t; 225 | 226 | /** UVC request code (A.8) */ 227 | enum uvc_req_code { 228 | UVC_RC_UNDEFINED = 0x00, 229 | UVC_SET_CUR = 0x01, 230 | UVC_GET_CUR = 0x81, 231 | UVC_GET_MIN = 0x82, 232 | UVC_GET_MAX = 0x83, 233 | UVC_GET_RES = 0x84, 234 | UVC_GET_LEN = 0x85, 235 | UVC_GET_INFO = 0x86, 236 | UVC_GET_DEF = 0x87 237 | }; 238 | 239 | enum uvc_device_power_mode { 240 | UVC_VC_VIDEO_POWER_MODE_FULL = 0x000b, 241 | UVC_VC_VIDEO_POWER_MODE_DEVICE_DEPENDENT = 0x001b, 242 | }; 243 | 244 | /** Camera terminal control selector (A.9.4) */ 245 | enum uvc_ct_ctrl_selector { 246 | UVC_CT_CONTROL_UNDEFINED = 0x00, 247 | UVC_CT_SCANNING_MODE_CONTROL = 0x01, 248 | UVC_CT_AE_MODE_CONTROL = 0x02, 249 | UVC_CT_AE_PRIORITY_CONTROL = 0x03, 250 | UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL = 0x04, 251 | UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL = 0x05, 252 | UVC_CT_FOCUS_ABSOLUTE_CONTROL = 0x06, 253 | UVC_CT_FOCUS_RELATIVE_CONTROL = 0x07, 254 | UVC_CT_FOCUS_AUTO_CONTROL = 0x08, 255 | UVC_CT_IRIS_ABSOLUTE_CONTROL = 0x09, 256 | UVC_CT_IRIS_RELATIVE_CONTROL = 0x0a, 257 | UVC_CT_ZOOM_ABSOLUTE_CONTROL = 0x0b, 258 | UVC_CT_ZOOM_RELATIVE_CONTROL = 0x0c, 259 | UVC_CT_PANTILT_ABSOLUTE_CONTROL = 0x0d, 260 | UVC_CT_PANTILT_RELATIVE_CONTROL = 0x0e, 261 | UVC_CT_ROLL_ABSOLUTE_CONTROL = 0x0f, 262 | UVC_CT_ROLL_RELATIVE_CONTROL = 0x10, 263 | UVC_CT_PRIVACY_CONTROL = 0x11, 264 | UVC_CT_FOCUS_SIMPLE_CONTROL = 0x12, 265 | UVC_CT_DIGITAL_WINDOW_CONTROL = 0x13, 266 | UVC_CT_REGION_OF_INTEREST_CONTROL = 0x14 267 | }; 268 | 269 | /** Processing unit control selector (A.9.5) */ 270 | enum uvc_pu_ctrl_selector { 271 | UVC_PU_CONTROL_UNDEFINED = 0x00, 272 | UVC_PU_BACKLIGHT_COMPENSATION_CONTROL = 0x01, 273 | UVC_PU_BRIGHTNESS_CONTROL = 0x02, 274 | UVC_PU_CONTRAST_CONTROL = 0x03, 275 | UVC_PU_GAIN_CONTROL = 0x04, 276 | UVC_PU_POWER_LINE_FREQUENCY_CONTROL = 0x05, 277 | UVC_PU_HUE_CONTROL = 0x06, 278 | UVC_PU_SATURATION_CONTROL = 0x07, 279 | UVC_PU_SHARPNESS_CONTROL = 0x08, 280 | UVC_PU_GAMMA_CONTROL = 0x09, 281 | UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL = 0x0a, 282 | UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL = 0x0b, 283 | UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL = 0x0c, 284 | UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL = 0x0d, 285 | UVC_PU_DIGITAL_MULTIPLIER_CONTROL = 0x0e, 286 | UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL = 0x0f, 287 | UVC_PU_HUE_AUTO_CONTROL = 0x10, 288 | UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL = 0x11, 289 | UVC_PU_ANALOG_LOCK_STATUS_CONTROL = 0x12, 290 | UVC_PU_CONTRAST_AUTO_CONTROL = 0x13 291 | }; 292 | 293 | /** USB terminal type (B.1) */ 294 | enum uvc_term_type { 295 | UVC_TT_VENDOR_SPECIFIC = 0x0100, 296 | UVC_TT_STREAMING = 0x0101 297 | }; 298 | 299 | /** Input terminal type (B.2) */ 300 | enum uvc_it_type { 301 | UVC_ITT_VENDOR_SPECIFIC = 0x0200, 302 | UVC_ITT_CAMERA = 0x0201, 303 | UVC_ITT_MEDIA_TRANSPORT_INPUT = 0x0202 304 | }; 305 | 306 | /** Output terminal type (B.3) */ 307 | enum uvc_ot_type { 308 | UVC_OTT_VENDOR_SPECIFIC = 0x0300, 309 | UVC_OTT_DISPLAY = 0x0301, 310 | UVC_OTT_MEDIA_TRANSPORT_OUTPUT = 0x0302 311 | }; 312 | 313 | /** External terminal type (B.4) */ 314 | enum uvc_et_type { 315 | UVC_EXTERNAL_VENDOR_SPECIFIC = 0x0400, 316 | UVC_COMPOSITE_CONNECTOR = 0x0401, 317 | UVC_SVIDEO_CONNECTOR = 0x0402, 318 | UVC_COMPONENT_CONNECTOR = 0x0403 319 | }; 320 | 321 | /** Context, equivalent to libusb's contexts. 322 | * 323 | * May either own a libusb context or use one that's already made. 324 | * 325 | * Always create these with uvc_get_context. 326 | */ 327 | struct uvc_context; 328 | typedef struct uvc_context uvc_context_t; 329 | 330 | /** UVC device. 331 | * 332 | * Get this from uvc_get_device_list() or uvc_find_device(). 333 | */ 334 | struct uvc_device; 335 | typedef struct uvc_device uvc_device_t; 336 | 337 | /** Handle on an open UVC device. 338 | * 339 | * Get one of these from uvc_open(). Once you uvc_close() 340 | * it, it's no longer valid. 341 | */ 342 | struct uvc_device_handle; 343 | typedef struct uvc_device_handle uvc_device_handle_t; 344 | 345 | /** Handle on an open UVC stream. 346 | * 347 | * Get one of these from uvc_stream_open*(). 348 | * Once you uvc_stream_close() it, it will no longer be valid. 349 | */ 350 | struct uvc_stream_handle; 351 | typedef struct uvc_stream_handle uvc_stream_handle_t; 352 | 353 | /** Representation of the interface that brings data into the UVC device */ 354 | typedef struct uvc_input_terminal { 355 | struct uvc_input_terminal *prev, *next; 356 | /** Index of the terminal within the device */ 357 | uint8_t bTerminalID; 358 | /** Type of terminal (e.g., camera) */ 359 | enum uvc_it_type wTerminalType; 360 | uint16_t wObjectiveFocalLengthMin; 361 | uint16_t wObjectiveFocalLengthMax; 362 | uint16_t wOcularFocalLength; 363 | /** Camera controls (meaning of bits given in {uvc_ct_ctrl_selector}) */ 364 | uint64_t bmControls; 365 | } uvc_input_terminal_t; 366 | 367 | typedef struct uvc_output_terminal { 368 | struct uvc_output_terminal *prev, *next; 369 | /** @todo */ 370 | } uvc_output_terminal_t; 371 | 372 | /** Represents post-capture processing functions */ 373 | typedef struct uvc_processing_unit { 374 | struct uvc_processing_unit *prev, *next; 375 | /** Index of the processing unit within the device */ 376 | uint8_t bUnitID; 377 | /** Index of the terminal from which the device accepts images */ 378 | uint8_t bSourceID; 379 | /** Processing controls (meaning of bits given in {uvc_pu_ctrl_selector}) */ 380 | uint64_t bmControls; 381 | } uvc_processing_unit_t; 382 | 383 | /** Represents selector unit to connect other units */ 384 | typedef struct uvc_selector_unit { 385 | struct uvc_selector_unit *prev, *next; 386 | /** Index of the selector unit within the device */ 387 | uint8_t bUnitID; 388 | } uvc_selector_unit_t; 389 | 390 | /** Custom processing or camera-control functions */ 391 | typedef struct uvc_extension_unit { 392 | struct uvc_extension_unit *prev, *next; 393 | /** Index of the extension unit within the device */ 394 | uint8_t bUnitID; 395 | /** GUID identifying the extension unit */ 396 | uint8_t guidExtensionCode[16]; 397 | /** Bitmap of available controls (manufacturer-dependent) */ 398 | uint64_t bmControls; 399 | } uvc_extension_unit_t; 400 | 401 | enum uvc_status_class { 402 | UVC_STATUS_CLASS_CONTROL = 0x10, 403 | UVC_STATUS_CLASS_CONTROL_CAMERA = 0x11, 404 | UVC_STATUS_CLASS_CONTROL_PROCESSING = 0x12, 405 | }; 406 | 407 | enum uvc_status_attribute { 408 | UVC_STATUS_ATTRIBUTE_VALUE_CHANGE = 0x00, 409 | UVC_STATUS_ATTRIBUTE_INFO_CHANGE = 0x01, 410 | UVC_STATUS_ATTRIBUTE_FAILURE_CHANGE = 0x02, 411 | UVC_STATUS_ATTRIBUTE_UNKNOWN = 0xff 412 | }; 413 | 414 | /** A callback function to accept status updates 415 | * @ingroup device 416 | */ 417 | typedef void(uvc_status_callback_t)(enum uvc_status_class status_class, 418 | int event, 419 | int selector, 420 | enum uvc_status_attribute status_attribute, 421 | void *data, size_t data_len, 422 | void *user_ptr); 423 | 424 | /** A callback function to accept button events 425 | * @ingroup device 426 | */ 427 | typedef void(uvc_button_callback_t)(int button, 428 | int state, 429 | void *user_ptr); 430 | 431 | /** Structure representing a UVC device descriptor. 432 | * 433 | * (This isn't a standard structure.) 434 | */ 435 | typedef struct uvc_device_descriptor { 436 | /** Vendor ID */ 437 | uint16_t idVendor; 438 | /** Product ID */ 439 | uint16_t idProduct; 440 | /** UVC compliance level, e.g. 0x0100 (1.0), 0x0110 */ 441 | uint16_t bcdUVC; 442 | /** Serial number (null if unavailable) */ 443 | const char *serialNumber; 444 | /** Device-reported manufacturer name (or null) */ 445 | const char *manufacturer; 446 | /** Device-reporter product name (or null) */ 447 | const char *product; 448 | } uvc_device_descriptor_t; 449 | 450 | /** An image frame received from the UVC device 451 | * @ingroup streaming 452 | */ 453 | typedef struct uvc_frame { 454 | /** Image data for this frame */ 455 | void *data; 456 | /** Size of image data buffer */ 457 | size_t data_bytes; 458 | /** Width of image in pixels */ 459 | uint32_t width; 460 | /** Height of image in pixels */ 461 | uint32_t height; 462 | /** Pixel data format */ 463 | enum uvc_frame_format frame_format; 464 | /** Number of bytes per horizontal line (undefined for compressed format) */ 465 | size_t step; 466 | /** Frame number (may skip, but is strictly monotonically increasing) */ 467 | uint32_t sequence; 468 | /** Estimate of system time when the device started capturing the image */ 469 | struct timeval capture_time; 470 | /** Estimate of system time when the device finished receiving the image */ 471 | struct timespec capture_time_finished; 472 | /** Handle on the device that produced the image. 473 | * @warning You must not call any uvc_* functions during a callback. */ 474 | uvc_device_handle_t *source; 475 | /** Is the data buffer owned by the library? 476 | * If 1, the data buffer can be arbitrarily reallocated by frame conversion 477 | * functions. 478 | * If 0, the data buffer will not be reallocated or freed by the library. 479 | * Set this field to zero if you are supplying the buffer. 480 | */ 481 | uint8_t library_owns_data; 482 | /** Metadata for this frame if available */ 483 | void *metadata; 484 | /** Size of metadata buffer */ 485 | size_t metadata_bytes; 486 | } uvc_frame_t; 487 | 488 | /** A callback function to handle incoming assembled UVC frames 489 | * @ingroup streaming 490 | */ 491 | typedef void(uvc_frame_callback_t)(struct uvc_frame *frame, void *user_ptr); 492 | 493 | /** Streaming mode, includes all information needed to select stream 494 | * @ingroup streaming 495 | */ 496 | typedef struct uvc_stream_ctrl { 497 | uint16_t bmHint; 498 | uint8_t bFormatIndex; 499 | uint8_t bFrameIndex; 500 | uint32_t dwFrameInterval; 501 | uint16_t wKeyFrameRate; 502 | uint16_t wPFrameRate; 503 | uint16_t wCompQuality; 504 | uint16_t wCompWindowSize; 505 | uint16_t wDelay; 506 | uint32_t dwMaxVideoFrameSize; 507 | uint32_t dwMaxPayloadTransferSize; 508 | uint32_t dwClockFrequency; 509 | uint8_t bmFramingInfo; 510 | uint8_t bPreferredVersion; 511 | uint8_t bMinVersion; 512 | uint8_t bMaxVersion; 513 | uint8_t bInterfaceNumber; 514 | } uvc_stream_ctrl_t; 515 | 516 | typedef struct uvc_still_ctrl { 517 | /* Video format index from a format descriptor */ 518 | uint8_t bFormatIndex; 519 | /* Video frame index from a frame descriptor */ 520 | uint8_t bFrameIndex; 521 | /* Compression index from a frame descriptor */ 522 | uint8_t bCompressionIndex; 523 | /* Maximum still image size in bytes. */ 524 | uint32_t dwMaxVideoFrameSize; 525 | /* Maximum number of byte per payload*/ 526 | uint32_t dwMaxPayloadTransferSize; 527 | uint8_t bInterfaceNumber; 528 | } uvc_still_ctrl_t; 529 | 530 | uvc_error_t uvc_init(uvc_context_t **ctx, struct libusb_context *usb_ctx); 531 | void uvc_exit(uvc_context_t *ctx); 532 | 533 | uvc_error_t uvc_get_device_list( 534 | uvc_context_t *ctx, 535 | uvc_device_t ***list); 536 | void uvc_free_device_list(uvc_device_t **list, uint8_t unref_devices); 537 | 538 | uvc_error_t uvc_get_device_descriptor( 539 | uvc_device_t *dev, 540 | uvc_device_descriptor_t **desc); 541 | void uvc_free_device_descriptor( 542 | uvc_device_descriptor_t *desc); 543 | 544 | uint8_t uvc_get_bus_number(uvc_device_t *dev); 545 | uint8_t uvc_get_device_address(uvc_device_t *dev); 546 | 547 | uvc_error_t uvc_find_device( 548 | uvc_context_t *ctx, 549 | uvc_device_t **dev, 550 | int vid, int pid, const char *sn); 551 | 552 | uvc_error_t uvc_find_devices( 553 | uvc_context_t *ctx, 554 | uvc_device_t ***devs, 555 | int vid, int pid, const char *sn); 556 | 557 | #if LIBUSB_API_VERSION >= 0x01000107 558 | uvc_error_t uvc_wrap( 559 | int sys_dev, 560 | uvc_context_t *context, 561 | uvc_device_handle_t **devh); 562 | #endif 563 | 564 | uvc_error_t uvc_open( 565 | uvc_device_t *dev, 566 | uvc_device_handle_t **devh); 567 | void uvc_close(uvc_device_handle_t *devh); 568 | 569 | uvc_device_t *uvc_get_device(uvc_device_handle_t *devh); 570 | struct libusb_device_handle *uvc_get_libusb_handle(uvc_device_handle_t *devh); 571 | 572 | void uvc_ref_device(uvc_device_t *dev); 573 | void uvc_unref_device(uvc_device_t *dev); 574 | 575 | void uvc_set_status_callback(uvc_device_handle_t *devh, 576 | uvc_status_callback_t cb, 577 | void *user_ptr); 578 | 579 | void uvc_set_button_callback(uvc_device_handle_t *devh, 580 | uvc_button_callback_t cb, 581 | void *user_ptr); 582 | 583 | const uvc_input_terminal_t *uvc_get_camera_terminal(uvc_device_handle_t *devh); 584 | const uvc_input_terminal_t *uvc_get_input_terminals(uvc_device_handle_t *devh); 585 | const uvc_output_terminal_t *uvc_get_output_terminals(uvc_device_handle_t *devh); 586 | const uvc_selector_unit_t *uvc_get_selector_units(uvc_device_handle_t *devh); 587 | const uvc_processing_unit_t *uvc_get_processing_units(uvc_device_handle_t *devh); 588 | const uvc_extension_unit_t *uvc_get_extension_units(uvc_device_handle_t *devh); 589 | 590 | uvc_error_t uvc_get_stream_ctrl_format_size( 591 | uvc_device_handle_t *devh, 592 | uvc_stream_ctrl_t *ctrl, 593 | enum uvc_frame_format format, 594 | int width, int height, 595 | int fps 596 | ); 597 | 598 | uvc_error_t uvc_get_still_ctrl_format_size( 599 | uvc_device_handle_t *devh, 600 | uvc_stream_ctrl_t *ctrl, 601 | uvc_still_ctrl_t *still_ctrl, 602 | int width, int height); 603 | 604 | uvc_error_t uvc_trigger_still( 605 | uvc_device_handle_t *devh, 606 | uvc_still_ctrl_t *still_ctrl); 607 | 608 | const uvc_format_desc_t *uvc_get_format_descs(uvc_device_handle_t* ); 609 | 610 | uvc_error_t uvc_probe_stream_ctrl( 611 | uvc_device_handle_t *devh, 612 | uvc_stream_ctrl_t *ctrl); 613 | 614 | uvc_error_t uvc_probe_still_ctrl( 615 | uvc_device_handle_t *devh, 616 | uvc_still_ctrl_t *still_ctrl); 617 | 618 | uvc_error_t uvc_start_streaming( 619 | uvc_device_handle_t *devh, 620 | uvc_stream_ctrl_t *ctrl, 621 | uvc_frame_callback_t *cb, 622 | void *user_ptr, 623 | uint8_t flags); 624 | 625 | uvc_error_t uvc_start_iso_streaming( 626 | uvc_device_handle_t *devh, 627 | uvc_stream_ctrl_t *ctrl, 628 | uvc_frame_callback_t *cb, 629 | void *user_ptr); 630 | 631 | void uvc_stop_streaming(uvc_device_handle_t *devh); 632 | 633 | uvc_error_t uvc_stream_open_ctrl(uvc_device_handle_t *devh, uvc_stream_handle_t **strmh, uvc_stream_ctrl_t *ctrl); 634 | uvc_error_t uvc_stream_ctrl(uvc_stream_handle_t *strmh, uvc_stream_ctrl_t *ctrl); 635 | uvc_error_t uvc_stream_start(uvc_stream_handle_t *strmh, 636 | uvc_frame_callback_t *cb, 637 | void *user_ptr, 638 | uint8_t flags); 639 | uvc_error_t uvc_stream_start_iso(uvc_stream_handle_t *strmh, 640 | uvc_frame_callback_t *cb, 641 | void *user_ptr); 642 | uvc_error_t uvc_stream_get_frame( 643 | uvc_stream_handle_t *strmh, 644 | uvc_frame_t **frame, 645 | int32_t timeout_us 646 | ); 647 | uvc_error_t uvc_stream_stop(uvc_stream_handle_t *strmh); 648 | void uvc_stream_close(uvc_stream_handle_t *strmh); 649 | 650 | int uvc_get_ctrl_len(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl); 651 | int uvc_get_ctrl(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl, void *data, int len, enum uvc_req_code req_code); 652 | int uvc_set_ctrl(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl, void *data, int len); 653 | 654 | uvc_error_t uvc_get_power_mode(uvc_device_handle_t *devh, enum uvc_device_power_mode *mode, enum uvc_req_code req_code); 655 | uvc_error_t uvc_set_power_mode(uvc_device_handle_t *devh, enum uvc_device_power_mode mode); 656 | 657 | /* AUTO-GENERATED control accessors! Update them with the output of `ctrl-gen.py decl`. */ 658 | uvc_error_t uvc_get_scanning_mode(uvc_device_handle_t *devh, uint8_t* mode, enum uvc_req_code req_code); 659 | uvc_error_t uvc_set_scanning_mode(uvc_device_handle_t *devh, uint8_t mode); 660 | 661 | uvc_error_t uvc_get_ae_mode(uvc_device_handle_t *devh, uint8_t* mode, enum uvc_req_code req_code); 662 | uvc_error_t uvc_set_ae_mode(uvc_device_handle_t *devh, uint8_t mode); 663 | 664 | uvc_error_t uvc_get_ae_priority(uvc_device_handle_t *devh, uint8_t* priority, enum uvc_req_code req_code); 665 | uvc_error_t uvc_set_ae_priority(uvc_device_handle_t *devh, uint8_t priority); 666 | 667 | uvc_error_t uvc_get_exposure_abs(uvc_device_handle_t *devh, uint32_t* time, enum uvc_req_code req_code); 668 | uvc_error_t uvc_set_exposure_abs(uvc_device_handle_t *devh, uint32_t time); 669 | 670 | uvc_error_t uvc_get_exposure_rel(uvc_device_handle_t *devh, int8_t* step, enum uvc_req_code req_code); 671 | uvc_error_t uvc_set_exposure_rel(uvc_device_handle_t *devh, int8_t step); 672 | 673 | uvc_error_t uvc_get_focus_abs(uvc_device_handle_t *devh, uint16_t* focus, enum uvc_req_code req_code); 674 | uvc_error_t uvc_set_focus_abs(uvc_device_handle_t *devh, uint16_t focus); 675 | 676 | uvc_error_t uvc_get_focus_rel(uvc_device_handle_t *devh, int8_t* focus_rel, uint8_t* speed, enum uvc_req_code req_code); 677 | uvc_error_t uvc_set_focus_rel(uvc_device_handle_t *devh, int8_t focus_rel, uint8_t speed); 678 | 679 | uvc_error_t uvc_get_focus_simple_range(uvc_device_handle_t *devh, uint8_t* focus, enum uvc_req_code req_code); 680 | uvc_error_t uvc_set_focus_simple_range(uvc_device_handle_t *devh, uint8_t focus); 681 | 682 | uvc_error_t uvc_get_focus_auto(uvc_device_handle_t *devh, uint8_t* state, enum uvc_req_code req_code); 683 | uvc_error_t uvc_set_focus_auto(uvc_device_handle_t *devh, uint8_t state); 684 | 685 | uvc_error_t uvc_get_iris_abs(uvc_device_handle_t *devh, uint16_t* iris, enum uvc_req_code req_code); 686 | uvc_error_t uvc_set_iris_abs(uvc_device_handle_t *devh, uint16_t iris); 687 | 688 | uvc_error_t uvc_get_iris_rel(uvc_device_handle_t *devh, uint8_t* iris_rel, enum uvc_req_code req_code); 689 | uvc_error_t uvc_set_iris_rel(uvc_device_handle_t *devh, uint8_t iris_rel); 690 | 691 | uvc_error_t uvc_get_zoom_abs(uvc_device_handle_t *devh, uint16_t* focal_length, enum uvc_req_code req_code); 692 | uvc_error_t uvc_set_zoom_abs(uvc_device_handle_t *devh, uint16_t focal_length); 693 | 694 | uvc_error_t uvc_get_zoom_rel(uvc_device_handle_t *devh, int8_t* zoom_rel, uint8_t* digital_zoom, uint8_t* speed, enum uvc_req_code req_code); 695 | uvc_error_t uvc_set_zoom_rel(uvc_device_handle_t *devh, int8_t zoom_rel, uint8_t digital_zoom, uint8_t speed); 696 | 697 | uvc_error_t uvc_get_pantilt_abs(uvc_device_handle_t *devh, int32_t* pan, int32_t* tilt, enum uvc_req_code req_code); 698 | uvc_error_t uvc_set_pantilt_abs(uvc_device_handle_t *devh, int32_t pan, int32_t tilt); 699 | 700 | uvc_error_t uvc_get_pantilt_rel(uvc_device_handle_t *devh, int8_t* pan_rel, uint8_t* pan_speed, int8_t* tilt_rel, uint8_t* tilt_speed, enum uvc_req_code req_code); 701 | uvc_error_t uvc_set_pantilt_rel(uvc_device_handle_t *devh, int8_t pan_rel, uint8_t pan_speed, int8_t tilt_rel, uint8_t tilt_speed); 702 | 703 | uvc_error_t uvc_get_roll_abs(uvc_device_handle_t *devh, int16_t* roll, enum uvc_req_code req_code); 704 | uvc_error_t uvc_set_roll_abs(uvc_device_handle_t *devh, int16_t roll); 705 | 706 | uvc_error_t uvc_get_roll_rel(uvc_device_handle_t *devh, int8_t* roll_rel, uint8_t* speed, enum uvc_req_code req_code); 707 | uvc_error_t uvc_set_roll_rel(uvc_device_handle_t *devh, int8_t roll_rel, uint8_t speed); 708 | 709 | uvc_error_t uvc_get_privacy(uvc_device_handle_t *devh, uint8_t* privacy, enum uvc_req_code req_code); 710 | uvc_error_t uvc_set_privacy(uvc_device_handle_t *devh, uint8_t privacy); 711 | 712 | uvc_error_t uvc_get_digital_window(uvc_device_handle_t *devh, uint16_t* window_top, uint16_t* window_left, uint16_t* window_bottom, uint16_t* window_right, uint16_t* num_steps, uint16_t* num_steps_units, enum uvc_req_code req_code); 713 | uvc_error_t uvc_set_digital_window(uvc_device_handle_t *devh, uint16_t window_top, uint16_t window_left, uint16_t window_bottom, uint16_t window_right, uint16_t num_steps, uint16_t num_steps_units); 714 | 715 | uvc_error_t uvc_get_digital_roi(uvc_device_handle_t *devh, uint16_t* roi_top, uint16_t* roi_left, uint16_t* roi_bottom, uint16_t* roi_right, uint16_t* auto_controls, enum uvc_req_code req_code); 716 | uvc_error_t uvc_set_digital_roi(uvc_device_handle_t *devh, uint16_t roi_top, uint16_t roi_left, uint16_t roi_bottom, uint16_t roi_right, uint16_t auto_controls); 717 | 718 | uvc_error_t uvc_get_backlight_compensation(uvc_device_handle_t *devh, uint16_t* backlight_compensation, enum uvc_req_code req_code); 719 | uvc_error_t uvc_set_backlight_compensation(uvc_device_handle_t *devh, uint16_t backlight_compensation); 720 | 721 | uvc_error_t uvc_get_brightness(uvc_device_handle_t *devh, int16_t* brightness, enum uvc_req_code req_code); 722 | uvc_error_t uvc_set_brightness(uvc_device_handle_t *devh, int16_t brightness); 723 | 724 | uvc_error_t uvc_get_contrast(uvc_device_handle_t *devh, uint16_t* contrast, enum uvc_req_code req_code); 725 | uvc_error_t uvc_set_contrast(uvc_device_handle_t *devh, uint16_t contrast); 726 | 727 | uvc_error_t uvc_get_contrast_auto(uvc_device_handle_t *devh, uint8_t* contrast_auto, enum uvc_req_code req_code); 728 | uvc_error_t uvc_set_contrast_auto(uvc_device_handle_t *devh, uint8_t contrast_auto); 729 | 730 | uvc_error_t uvc_get_gain(uvc_device_handle_t *devh, uint16_t* gain, enum uvc_req_code req_code); 731 | uvc_error_t uvc_set_gain(uvc_device_handle_t *devh, uint16_t gain); 732 | 733 | uvc_error_t uvc_get_power_line_frequency(uvc_device_handle_t *devh, uint8_t* power_line_frequency, enum uvc_req_code req_code); 734 | uvc_error_t uvc_set_power_line_frequency(uvc_device_handle_t *devh, uint8_t power_line_frequency); 735 | 736 | uvc_error_t uvc_get_hue(uvc_device_handle_t *devh, int16_t* hue, enum uvc_req_code req_code); 737 | uvc_error_t uvc_set_hue(uvc_device_handle_t *devh, int16_t hue); 738 | 739 | uvc_error_t uvc_get_hue_auto(uvc_device_handle_t *devh, uint8_t* hue_auto, enum uvc_req_code req_code); 740 | uvc_error_t uvc_set_hue_auto(uvc_device_handle_t *devh, uint8_t hue_auto); 741 | 742 | uvc_error_t uvc_get_saturation(uvc_device_handle_t *devh, uint16_t* saturation, enum uvc_req_code req_code); 743 | uvc_error_t uvc_set_saturation(uvc_device_handle_t *devh, uint16_t saturation); 744 | 745 | uvc_error_t uvc_get_sharpness(uvc_device_handle_t *devh, uint16_t* sharpness, enum uvc_req_code req_code); 746 | uvc_error_t uvc_set_sharpness(uvc_device_handle_t *devh, uint16_t sharpness); 747 | 748 | uvc_error_t uvc_get_gamma(uvc_device_handle_t *devh, uint16_t* gamma, enum uvc_req_code req_code); 749 | uvc_error_t uvc_set_gamma(uvc_device_handle_t *devh, uint16_t gamma); 750 | 751 | uvc_error_t uvc_get_white_balance_temperature(uvc_device_handle_t *devh, uint16_t* temperature, enum uvc_req_code req_code); 752 | uvc_error_t uvc_set_white_balance_temperature(uvc_device_handle_t *devh, uint16_t temperature); 753 | 754 | uvc_error_t uvc_get_white_balance_temperature_auto(uvc_device_handle_t *devh, uint8_t* temperature_auto, enum uvc_req_code req_code); 755 | uvc_error_t uvc_set_white_balance_temperature_auto(uvc_device_handle_t *devh, uint8_t temperature_auto); 756 | 757 | uvc_error_t uvc_get_white_balance_component(uvc_device_handle_t *devh, uint16_t* blue, uint16_t* red, enum uvc_req_code req_code); 758 | uvc_error_t uvc_set_white_balance_component(uvc_device_handle_t *devh, uint16_t blue, uint16_t red); 759 | 760 | uvc_error_t uvc_get_white_balance_component_auto(uvc_device_handle_t *devh, uint8_t* white_balance_component_auto, enum uvc_req_code req_code); 761 | uvc_error_t uvc_set_white_balance_component_auto(uvc_device_handle_t *devh, uint8_t white_balance_component_auto); 762 | 763 | uvc_error_t uvc_get_digital_multiplier(uvc_device_handle_t *devh, uint16_t* multiplier_step, enum uvc_req_code req_code); 764 | uvc_error_t uvc_set_digital_multiplier(uvc_device_handle_t *devh, uint16_t multiplier_step); 765 | 766 | uvc_error_t uvc_get_digital_multiplier_limit(uvc_device_handle_t *devh, uint16_t* multiplier_step, enum uvc_req_code req_code); 767 | uvc_error_t uvc_set_digital_multiplier_limit(uvc_device_handle_t *devh, uint16_t multiplier_step); 768 | 769 | uvc_error_t uvc_get_analog_video_standard(uvc_device_handle_t *devh, uint8_t* video_standard, enum uvc_req_code req_code); 770 | uvc_error_t uvc_set_analog_video_standard(uvc_device_handle_t *devh, uint8_t video_standard); 771 | 772 | uvc_error_t uvc_get_analog_video_lock_status(uvc_device_handle_t *devh, uint8_t* status, enum uvc_req_code req_code); 773 | uvc_error_t uvc_set_analog_video_lock_status(uvc_device_handle_t *devh, uint8_t status); 774 | 775 | uvc_error_t uvc_get_input_select(uvc_device_handle_t *devh, uint8_t* selector, enum uvc_req_code req_code); 776 | uvc_error_t uvc_set_input_select(uvc_device_handle_t *devh, uint8_t selector); 777 | /* end AUTO-GENERATED control accessors */ 778 | 779 | void uvc_perror(uvc_error_t err, const char *msg); 780 | const char* uvc_strerror(uvc_error_t err); 781 | void uvc_print_diag(uvc_device_handle_t *devh, FILE *stream); 782 | void uvc_print_stream_ctrl(uvc_stream_ctrl_t *ctrl, FILE *stream); 783 | 784 | uvc_frame_t *uvc_allocate_frame(size_t data_bytes); 785 | void uvc_free_frame(uvc_frame_t *frame); 786 | 787 | uvc_error_t uvc_duplicate_frame(uvc_frame_t *in, uvc_frame_t *out); 788 | 789 | uvc_error_t uvc_yuyv2rgb(uvc_frame_t *in, uvc_frame_t *out); 790 | uvc_error_t uvc_uyvy2rgb(uvc_frame_t *in, uvc_frame_t *out); 791 | uvc_error_t uvc_any2rgb(uvc_frame_t *in, uvc_frame_t *out); 792 | 793 | uvc_error_t uvc_yuyv2bgr(uvc_frame_t *in, uvc_frame_t *out); 794 | uvc_error_t uvc_uyvy2bgr(uvc_frame_t *in, uvc_frame_t *out); 795 | uvc_error_t uvc_any2bgr(uvc_frame_t *in, uvc_frame_t *out); 796 | 797 | uvc_error_t uvc_yuyv2y(uvc_frame_t *in, uvc_frame_t *out); 798 | uvc_error_t uvc_yuyv2uv(uvc_frame_t *in, uvc_frame_t *out); 799 | 800 | #ifdef LIBUVC_HAS_JPEG 801 | uvc_error_t uvc_mjpeg2rgb(uvc_frame_t *in, uvc_frame_t *out); 802 | uvc_error_t uvc_mjpeg2gray(uvc_frame_t *in, uvc_frame_t *out); 803 | #endif 804 | 805 | #ifdef __cplusplus 806 | } 807 | #endif 808 | 809 | #endif // !def(LIBUVC_H) 810 | 811 | -------------------------------------------------------------------------------- /LiveView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 771E488B27A08A81000F220D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 771E488A27A08A81000F220D /* AppDelegate.swift */; }; 11 | 771E488D27A08A81000F220D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 771E488C27A08A81000F220D /* ViewController.swift */; }; 12 | 771E488F27A08A83000F220D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 771E488E27A08A83000F220D /* Assets.xcassets */; }; 13 | 771E489227A08A83000F220D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 771E489027A08A83000F220D /* Main.storyboard */; }; 14 | 771E48B627A0905F000F220D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 771E48B527A0905F000F220D /* AppDelegate.swift */; }; 15 | 771E48B827A0905F000F220D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 771E48B727A0905F000F220D /* SceneDelegate.swift */; }; 16 | 771E48BA27A0905F000F220D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 771E48B927A0905F000F220D /* ViewController.swift */; }; 17 | 771E48BF27A09061000F220D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 771E48BE27A09061000F220D /* Assets.xcassets */; }; 18 | 771E48C227A09061000F220D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 771E48C027A09061000F220D /* LaunchScreen.storyboard */; }; 19 | 771E48E627A0CAE6000F220D /* LiveViewKit.docc in Sources */ = {isa = PBXBuildFile; fileRef = 771E48E527A0CAE6000F220D /* LiveViewKit.docc */; }; 20 | 771E48F427A0CAE6000F220D /* LiveViewKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 771E48E427A0CAE6000F220D /* LiveViewKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | 771E48F727A0CAE6000F220D /* LiveViewKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 771E48E227A0CAE6000F220D /* LiveViewKit.framework */; }; 22 | 771E48F827A0CAE6000F220D /* LiveViewKit.framework in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 771E48E227A0CAE6000F220D /* LiveViewKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 23 | 771E490127A0CD5A000F220D /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 771E490027A0CD5A000F220D /* CoreFoundation.framework */; }; 24 | 771E490727A0CDD7000F220D /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 771E490627A0CDD7000F220D /* IOKit.framework */; }; 25 | 771E490E27A0CE2E000F220D /* LiveViewKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 771E48E227A0CAE6000F220D /* LiveViewKit.framework */; }; 26 | 771E491027A0CEE7000F220D /* LiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 771E490F27A0CEE7000F220D /* LiveView.swift */; }; 27 | 77E20A3C27A6E10100A8DE8A /* LVContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 77E20A3A27A6E10100A8DE8A /* LVContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; 28 | 77E20A3D27A6E10100A8DE8A /* LVContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 77E20A3B27A6E10100A8DE8A /* LVContext.m */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXContainerItemProxy section */ 32 | 771E48F527A0CAE6000F220D /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 771E487F27A08A81000F220D /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 771E48E127A0CAE6000F220D; 37 | remoteInfo = LiveViewKit; 38 | }; 39 | 771E490C27A0CE29000F220D /* PBXContainerItemProxy */ = { 40 | isa = PBXContainerItemProxy; 41 | containerPortal = 771E487F27A08A81000F220D /* Project object */; 42 | proxyType = 1; 43 | remoteGlobalIDString = 771E48E127A0CAE6000F220D; 44 | remoteInfo = LiveViewKit; 45 | }; 46 | /* End PBXContainerItemProxy section */ 47 | 48 | /* Begin PBXCopyFilesBuildPhase section */ 49 | 771E48A727A08B89000F220D /* Embed Libraries */ = { 50 | isa = PBXCopyFilesBuildPhase; 51 | buildActionMask = 2147483647; 52 | dstPath = ""; 53 | dstSubfolderSpec = 10; 54 | files = ( 55 | ); 56 | name = "Embed Libraries"; 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | 771E48D427A09128000F220D /* Embed Libraries */ = { 60 | isa = PBXCopyFilesBuildPhase; 61 | buildActionMask = 2147483647; 62 | dstPath = ""; 63 | dstSubfolderSpec = 10; 64 | files = ( 65 | 771E48F827A0CAE6000F220D /* LiveViewKit.framework in Embed Libraries */, 66 | ); 67 | name = "Embed Libraries"; 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | /* End PBXCopyFilesBuildPhase section */ 71 | 72 | /* Begin PBXFileReference section */ 73 | 771E488727A08A81000F220D /* LiveView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LiveView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | 771E488A27A08A81000F220D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 75 | 771E488C27A08A81000F220D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 76 | 771E488E27A08A83000F220D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 77 | 771E489127A08A83000F220D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 78 | 771E489327A08A83000F220D /* LiveView.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LiveView.entitlements; sourceTree = ""; }; 79 | 771E48B327A0905F000F220D /* LiveView-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "LiveView-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 80 | 771E48B527A0905F000F220D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 81 | 771E48B727A0905F000F220D /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 82 | 771E48B927A0905F000F220D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 83 | 771E48BE27A09061000F220D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 84 | 771E48C127A09061000F220D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 85 | 771E48C327A09061000F220D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 86 | 771E48E227A0CAE6000F220D /* LiveViewKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LiveViewKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 87 | 771E48E427A0CAE6000F220D /* LiveViewKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveViewKit.h; sourceTree = ""; }; 88 | 771E48E527A0CAE6000F220D /* LiveViewKit.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = LiveViewKit.docc; sourceTree = ""; }; 89 | 771E490027A0CD5A000F220D /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; 90 | 771E490627A0CDD7000F220D /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; 91 | 771E490F27A0CEE7000F220D /* LiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveView.swift; sourceTree = ""; }; 92 | 77E20A3A27A6E10100A8DE8A /* LVContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LVContext.h; sourceTree = ""; }; 93 | 77E20A3B27A6E10100A8DE8A /* LVContext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LVContext.m; sourceTree = ""; }; 94 | /* End PBXFileReference section */ 95 | 96 | /* Begin PBXFrameworksBuildPhase section */ 97 | 771E488427A08A81000F220D /* Frameworks */ = { 98 | isa = PBXFrameworksBuildPhase; 99 | buildActionMask = 2147483647; 100 | files = ( 101 | 771E490E27A0CE2E000F220D /* LiveViewKit.framework in Frameworks */, 102 | ); 103 | runOnlyForDeploymentPostprocessing = 0; 104 | }; 105 | 771E48B027A0905F000F220D /* Frameworks */ = { 106 | isa = PBXFrameworksBuildPhase; 107 | buildActionMask = 2147483647; 108 | files = ( 109 | 771E48F727A0CAE6000F220D /* LiveViewKit.framework in Frameworks */, 110 | ); 111 | runOnlyForDeploymentPostprocessing = 0; 112 | }; 113 | 771E48DF27A0CAE6000F220D /* Frameworks */ = { 114 | isa = PBXFrameworksBuildPhase; 115 | buildActionMask = 2147483647; 116 | files = ( 117 | 771E490127A0CD5A000F220D /* CoreFoundation.framework in Frameworks */, 118 | 771E490727A0CDD7000F220D /* IOKit.framework in Frameworks */, 119 | ); 120 | runOnlyForDeploymentPostprocessing = 0; 121 | }; 122 | /* End PBXFrameworksBuildPhase section */ 123 | 124 | /* Begin PBXGroup section */ 125 | 771E487E27A08A81000F220D = { 126 | isa = PBXGroup; 127 | children = ( 128 | 771E488927A08A81000F220D /* LiveView */, 129 | 771E48B427A0905F000F220D /* LiveView-iOS */, 130 | 771E48E327A0CAE6000F220D /* LiveViewKit */, 131 | 771E488827A08A81000F220D /* Products */, 132 | 771E489D27A08B89000F220D /* Frameworks */, 133 | ); 134 | sourceTree = ""; 135 | }; 136 | 771E488827A08A81000F220D /* Products */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | 771E488727A08A81000F220D /* LiveView.app */, 140 | 771E48B327A0905F000F220D /* LiveView-iOS.app */, 141 | 771E48E227A0CAE6000F220D /* LiveViewKit.framework */, 142 | ); 143 | name = Products; 144 | sourceTree = ""; 145 | }; 146 | 771E488927A08A81000F220D /* LiveView */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 771E488A27A08A81000F220D /* AppDelegate.swift */, 150 | 771E488C27A08A81000F220D /* ViewController.swift */, 151 | 771E488E27A08A83000F220D /* Assets.xcassets */, 152 | 771E489027A08A83000F220D /* Main.storyboard */, 153 | 771E489327A08A83000F220D /* LiveView.entitlements */, 154 | ); 155 | path = LiveView; 156 | sourceTree = ""; 157 | }; 158 | 771E489D27A08B89000F220D /* Frameworks */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 771E490627A0CDD7000F220D /* IOKit.framework */, 162 | 771E490027A0CD5A000F220D /* CoreFoundation.framework */, 163 | ); 164 | name = Frameworks; 165 | sourceTree = ""; 166 | }; 167 | 771E48B427A0905F000F220D /* LiveView-iOS */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 771E48B527A0905F000F220D /* AppDelegate.swift */, 171 | 771E48B727A0905F000F220D /* SceneDelegate.swift */, 172 | 771E48B927A0905F000F220D /* ViewController.swift */, 173 | 771E48BE27A09061000F220D /* Assets.xcassets */, 174 | 771E48C027A09061000F220D /* LaunchScreen.storyboard */, 175 | 771E48C327A09061000F220D /* Info.plist */, 176 | ); 177 | path = "LiveView-iOS"; 178 | sourceTree = ""; 179 | }; 180 | 771E48E327A0CAE6000F220D /* LiveViewKit */ = { 181 | isa = PBXGroup; 182 | children = ( 183 | 771E490F27A0CEE7000F220D /* LiveView.swift */, 184 | 77E20A3A27A6E10100A8DE8A /* LVContext.h */, 185 | 77E20A3B27A6E10100A8DE8A /* LVContext.m */, 186 | 771E48E427A0CAE6000F220D /* LiveViewKit.h */, 187 | 771E48E527A0CAE6000F220D /* LiveViewKit.docc */, 188 | ); 189 | path = LiveViewKit; 190 | sourceTree = ""; 191 | }; 192 | /* End PBXGroup section */ 193 | 194 | /* Begin PBXHeadersBuildPhase section */ 195 | 771E48DD27A0CAE6000F220D /* Headers */ = { 196 | isa = PBXHeadersBuildPhase; 197 | buildActionMask = 2147483647; 198 | files = ( 199 | 77E20A3C27A6E10100A8DE8A /* LVContext.h in Headers */, 200 | 771E48F427A0CAE6000F220D /* LiveViewKit.h in Headers */, 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | }; 204 | /* End PBXHeadersBuildPhase section */ 205 | 206 | /* Begin PBXNativeTarget section */ 207 | 771E488627A08A81000F220D /* LiveView */ = { 208 | isa = PBXNativeTarget; 209 | buildConfigurationList = 771E489627A08A83000F220D /* Build configuration list for PBXNativeTarget "LiveView" */; 210 | buildPhases = ( 211 | 771E488327A08A81000F220D /* Sources */, 212 | 771E488427A08A81000F220D /* Frameworks */, 213 | 771E488527A08A81000F220D /* Resources */, 214 | 771E48A727A08B89000F220D /* Embed Libraries */, 215 | ); 216 | buildRules = ( 217 | ); 218 | dependencies = ( 219 | 771E490D27A0CE29000F220D /* PBXTargetDependency */, 220 | ); 221 | name = LiveView; 222 | productName = LiveView; 223 | productReference = 771E488727A08A81000F220D /* LiveView.app */; 224 | productType = "com.apple.product-type.application"; 225 | }; 226 | 771E48B227A0905F000F220D /* LiveView-iOS */ = { 227 | isa = PBXNativeTarget; 228 | buildConfigurationList = 771E48C627A09061000F220D /* Build configuration list for PBXNativeTarget "LiveView-iOS" */; 229 | buildPhases = ( 230 | 771E48AF27A0905F000F220D /* Sources */, 231 | 771E48B027A0905F000F220D /* Frameworks */, 232 | 771E48B127A0905F000F220D /* Resources */, 233 | 771E48D427A09128000F220D /* Embed Libraries */, 234 | 7781F6D427A74D8C00F2850C /* ShellScript */, 235 | ); 236 | buildRules = ( 237 | ); 238 | dependencies = ( 239 | 771E48F627A0CAE6000F220D /* PBXTargetDependency */, 240 | ); 241 | name = "LiveView-iOS"; 242 | productName = "LiveView-iOS"; 243 | productReference = 771E48B327A0905F000F220D /* LiveView-iOS.app */; 244 | productType = "com.apple.product-type.application"; 245 | }; 246 | 771E48E127A0CAE6000F220D /* LiveViewKit */ = { 247 | isa = PBXNativeTarget; 248 | buildConfigurationList = 771E48F927A0CAE6000F220D /* Build configuration list for PBXNativeTarget "LiveViewKit" */; 249 | buildPhases = ( 250 | 771E48DD27A0CAE6000F220D /* Headers */, 251 | 771E48DE27A0CAE6000F220D /* Sources */, 252 | 771E48DF27A0CAE6000F220D /* Frameworks */, 253 | 771E48E027A0CAE6000F220D /* Resources */, 254 | ); 255 | buildRules = ( 256 | ); 257 | dependencies = ( 258 | ); 259 | name = LiveViewKit; 260 | productName = LiveViewKit; 261 | productReference = 771E48E227A0CAE6000F220D /* LiveViewKit.framework */; 262 | productType = "com.apple.product-type.framework"; 263 | }; 264 | /* End PBXNativeTarget section */ 265 | 266 | /* Begin PBXProject section */ 267 | 771E487F27A08A81000F220D /* Project object */ = { 268 | isa = PBXProject; 269 | attributes = { 270 | BuildIndependentTargetsInParallel = 1; 271 | LastSwiftUpdateCheck = 1320; 272 | LastUpgradeCheck = 1320; 273 | TargetAttributes = { 274 | 771E488627A08A81000F220D = { 275 | CreatedOnToolsVersion = 13.2; 276 | LastSwiftMigration = 1320; 277 | }; 278 | 771E48B227A0905F000F220D = { 279 | CreatedOnToolsVersion = 13.2; 280 | LastSwiftMigration = 1320; 281 | }; 282 | 771E48E127A0CAE6000F220D = { 283 | CreatedOnToolsVersion = 13.2; 284 | LastSwiftMigration = 1320; 285 | }; 286 | }; 287 | }; 288 | buildConfigurationList = 771E488227A08A81000F220D /* Build configuration list for PBXProject "LiveView" */; 289 | compatibilityVersion = "Xcode 13.0"; 290 | developmentRegion = en; 291 | hasScannedForEncodings = 0; 292 | knownRegions = ( 293 | en, 294 | Base, 295 | ); 296 | mainGroup = 771E487E27A08A81000F220D; 297 | productRefGroup = 771E488827A08A81000F220D /* Products */; 298 | projectDirPath = ""; 299 | projectRoot = ""; 300 | targets = ( 301 | 771E488627A08A81000F220D /* LiveView */, 302 | 771E48B227A0905F000F220D /* LiveView-iOS */, 303 | 771E48E127A0CAE6000F220D /* LiveViewKit */, 304 | ); 305 | }; 306 | /* End PBXProject section */ 307 | 308 | /* Begin PBXResourcesBuildPhase section */ 309 | 771E488527A08A81000F220D /* Resources */ = { 310 | isa = PBXResourcesBuildPhase; 311 | buildActionMask = 2147483647; 312 | files = ( 313 | 771E488F27A08A83000F220D /* Assets.xcassets in Resources */, 314 | 771E489227A08A83000F220D /* Main.storyboard in Resources */, 315 | ); 316 | runOnlyForDeploymentPostprocessing = 0; 317 | }; 318 | 771E48B127A0905F000F220D /* Resources */ = { 319 | isa = PBXResourcesBuildPhase; 320 | buildActionMask = 2147483647; 321 | files = ( 322 | 771E48C227A09061000F220D /* LaunchScreen.storyboard in Resources */, 323 | 771E48BF27A09061000F220D /* Assets.xcassets in Resources */, 324 | ); 325 | runOnlyForDeploymentPostprocessing = 0; 326 | }; 327 | 771E48E027A0CAE6000F220D /* Resources */ = { 328 | isa = PBXResourcesBuildPhase; 329 | buildActionMask = 2147483647; 330 | files = ( 331 | ); 332 | runOnlyForDeploymentPostprocessing = 0; 333 | }; 334 | /* End PBXResourcesBuildPhase section */ 335 | 336 | /* Begin PBXShellScriptBuildPhase section */ 337 | 7781F6D427A74D8C00F2850C /* ShellScript */ = { 338 | isa = PBXShellScriptBuildPhase; 339 | buildActionMask = 2147483647; 340 | files = ( 341 | ); 342 | inputFileListPaths = ( 343 | ); 344 | inputPaths = ( 345 | ); 346 | outputFileListPaths = ( 347 | ); 348 | outputPaths = ( 349 | ); 350 | runOnlyForDeploymentPostprocessing = 0; 351 | shellPath = /bin/sh; 352 | shellScript = "# Create .deb package\n\nversion=1.0\nbuildno=1\n\nPKG_ID=org.kostyshyn.LiveView\nPKG_NAME=$PKG_ID-$version-$buildno.deb\nDPKG_DIR=$TARGET_BUILD_DIR/dpkg\nAPP_BUNDLE=$TARGET_BUILD_DIR/$CONTENTS_FOLDER_PATH\nENTITLEMENTS=$SRCROOT/LiveView-iOS/LiveViewUSB.entitlements\n\n# sign\nldid -S$ENTITLEMENTS $APP_BUNDLE/$EXECUTABLE_NAME\n\n# copy\nrm -rf $DPKG_DIR\nmkdir -p $DPKG_DIR/$PKG_ID/{DEBIAN,Applications}\ncat $SRCROOT/LiveView-iOS/debian/control | sed \"s/Version: PLACEHOLDER/Version: $version-$buildno/\" > $DPKG_DIR/$PKG_ID/debian/control\ncp -r $APP_BUNDLE $DPKG_DIR/$PKG_ID/Applications/ \n\n# create deb\ncd $DPKG_DIR\ndpkg-deb -Zgzip -b $PKG_ID $TARGET_BUILD_DIR/$PKG_NAME\n\n# install\n#scp -P 2222 $TARGET_BUILD_DIR/$PKG_NAME root@localhost:~/\n#ssh root@localhost -p 2222 \"dpkg -i $PKG_NAME && uicache\"\n"; 353 | }; 354 | /* End PBXShellScriptBuildPhase section */ 355 | 356 | /* Begin PBXSourcesBuildPhase section */ 357 | 771E488327A08A81000F220D /* Sources */ = { 358 | isa = PBXSourcesBuildPhase; 359 | buildActionMask = 2147483647; 360 | files = ( 361 | 771E488D27A08A81000F220D /* ViewController.swift in Sources */, 362 | 771E488B27A08A81000F220D /* AppDelegate.swift in Sources */, 363 | ); 364 | runOnlyForDeploymentPostprocessing = 0; 365 | }; 366 | 771E48AF27A0905F000F220D /* Sources */ = { 367 | isa = PBXSourcesBuildPhase; 368 | buildActionMask = 2147483647; 369 | files = ( 370 | 771E48BA27A0905F000F220D /* ViewController.swift in Sources */, 371 | 771E48B627A0905F000F220D /* AppDelegate.swift in Sources */, 372 | 771E48B827A0905F000F220D /* SceneDelegate.swift in Sources */, 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | }; 376 | 771E48DE27A0CAE6000F220D /* Sources */ = { 377 | isa = PBXSourcesBuildPhase; 378 | buildActionMask = 2147483647; 379 | files = ( 380 | 771E491027A0CEE7000F220D /* LiveView.swift in Sources */, 381 | 77E20A3D27A6E10100A8DE8A /* LVContext.m in Sources */, 382 | 771E48E627A0CAE6000F220D /* LiveViewKit.docc in Sources */, 383 | ); 384 | runOnlyForDeploymentPostprocessing = 0; 385 | }; 386 | /* End PBXSourcesBuildPhase section */ 387 | 388 | /* Begin PBXTargetDependency section */ 389 | 771E48F627A0CAE6000F220D /* PBXTargetDependency */ = { 390 | isa = PBXTargetDependency; 391 | target = 771E48E127A0CAE6000F220D /* LiveViewKit */; 392 | targetProxy = 771E48F527A0CAE6000F220D /* PBXContainerItemProxy */; 393 | }; 394 | 771E490D27A0CE29000F220D /* PBXTargetDependency */ = { 395 | isa = PBXTargetDependency; 396 | target = 771E48E127A0CAE6000F220D /* LiveViewKit */; 397 | targetProxy = 771E490C27A0CE29000F220D /* PBXContainerItemProxy */; 398 | }; 399 | /* End PBXTargetDependency section */ 400 | 401 | /* Begin PBXVariantGroup section */ 402 | 771E489027A08A83000F220D /* Main.storyboard */ = { 403 | isa = PBXVariantGroup; 404 | children = ( 405 | 771E489127A08A83000F220D /* Base */, 406 | ); 407 | name = Main.storyboard; 408 | sourceTree = ""; 409 | }; 410 | 771E48C027A09061000F220D /* LaunchScreen.storyboard */ = { 411 | isa = PBXVariantGroup; 412 | children = ( 413 | 771E48C127A09061000F220D /* Base */, 414 | ); 415 | name = LaunchScreen.storyboard; 416 | sourceTree = ""; 417 | }; 418 | /* End PBXVariantGroup section */ 419 | 420 | /* Begin XCBuildConfiguration section */ 421 | 771E489427A08A83000F220D /* Debug */ = { 422 | isa = XCBuildConfiguration; 423 | buildSettings = { 424 | ALWAYS_SEARCH_USER_PATHS = NO; 425 | CLANG_ANALYZER_NONNULL = YES; 426 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 427 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 428 | CLANG_CXX_LIBRARY = "libc++"; 429 | CLANG_ENABLE_MODULES = YES; 430 | CLANG_ENABLE_OBJC_ARC = YES; 431 | CLANG_ENABLE_OBJC_WEAK = YES; 432 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 433 | CLANG_WARN_BOOL_CONVERSION = YES; 434 | CLANG_WARN_COMMA = YES; 435 | CLANG_WARN_CONSTANT_CONVERSION = YES; 436 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 437 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 438 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 439 | CLANG_WARN_EMPTY_BODY = YES; 440 | CLANG_WARN_ENUM_CONVERSION = YES; 441 | CLANG_WARN_INFINITE_RECURSION = YES; 442 | CLANG_WARN_INT_CONVERSION = YES; 443 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 444 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 445 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 446 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 447 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 448 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 449 | CLANG_WARN_STRICT_PROTOTYPES = YES; 450 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 451 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 452 | CLANG_WARN_UNREACHABLE_CODE = YES; 453 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 454 | COPY_PHASE_STRIP = NO; 455 | DEBUG_INFORMATION_FORMAT = dwarf; 456 | ENABLE_STRICT_OBJC_MSGSEND = YES; 457 | ENABLE_TESTABILITY = YES; 458 | GCC_C_LANGUAGE_STANDARD = gnu11; 459 | GCC_DYNAMIC_NO_PIC = NO; 460 | GCC_NO_COMMON_BLOCKS = YES; 461 | GCC_OPTIMIZATION_LEVEL = 0; 462 | GCC_PREPROCESSOR_DEFINITIONS = ( 463 | "DEBUG=1", 464 | "$(inherited)", 465 | ); 466 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 467 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 468 | GCC_WARN_UNDECLARED_SELECTOR = YES; 469 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 470 | GCC_WARN_UNUSED_FUNCTION = YES; 471 | GCC_WARN_UNUSED_VARIABLE = YES; 472 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 473 | MACOSX_DEPLOYMENT_TARGET = 11.6; 474 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 475 | MTL_FAST_MATH = YES; 476 | ONLY_ACTIVE_ARCH = YES; 477 | SDKROOT = macosx; 478 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 479 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 480 | }; 481 | name = Debug; 482 | }; 483 | 771E489527A08A83000F220D /* Release */ = { 484 | isa = XCBuildConfiguration; 485 | buildSettings = { 486 | ALWAYS_SEARCH_USER_PATHS = NO; 487 | CLANG_ANALYZER_NONNULL = YES; 488 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 489 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 490 | CLANG_CXX_LIBRARY = "libc++"; 491 | CLANG_ENABLE_MODULES = YES; 492 | CLANG_ENABLE_OBJC_ARC = YES; 493 | CLANG_ENABLE_OBJC_WEAK = YES; 494 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 495 | CLANG_WARN_BOOL_CONVERSION = YES; 496 | CLANG_WARN_COMMA = YES; 497 | CLANG_WARN_CONSTANT_CONVERSION = YES; 498 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 499 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 500 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 501 | CLANG_WARN_EMPTY_BODY = YES; 502 | CLANG_WARN_ENUM_CONVERSION = YES; 503 | CLANG_WARN_INFINITE_RECURSION = YES; 504 | CLANG_WARN_INT_CONVERSION = YES; 505 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 506 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 507 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 508 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 509 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 510 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 511 | CLANG_WARN_STRICT_PROTOTYPES = YES; 512 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 513 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 514 | CLANG_WARN_UNREACHABLE_CODE = YES; 515 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 516 | COPY_PHASE_STRIP = NO; 517 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 518 | ENABLE_NS_ASSERTIONS = NO; 519 | ENABLE_STRICT_OBJC_MSGSEND = YES; 520 | GCC_C_LANGUAGE_STANDARD = gnu11; 521 | GCC_NO_COMMON_BLOCKS = YES; 522 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 523 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 524 | GCC_WARN_UNDECLARED_SELECTOR = YES; 525 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 526 | GCC_WARN_UNUSED_FUNCTION = YES; 527 | GCC_WARN_UNUSED_VARIABLE = YES; 528 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 529 | MACOSX_DEPLOYMENT_TARGET = 11.6; 530 | MTL_ENABLE_DEBUG_INFO = NO; 531 | MTL_FAST_MATH = YES; 532 | SDKROOT = macosx; 533 | SWIFT_COMPILATION_MODE = wholemodule; 534 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 535 | }; 536 | name = Release; 537 | }; 538 | 771E489727A08A83000F220D /* Debug */ = { 539 | isa = XCBuildConfiguration; 540 | buildSettings = { 541 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 542 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 543 | CLANG_ENABLE_MODULES = YES; 544 | CODE_SIGN_ENTITLEMENTS = LiveView/LiveView.entitlements; 545 | CODE_SIGN_STYLE = Automatic; 546 | COMBINE_HIDPI_IMAGES = YES; 547 | CURRENT_PROJECT_VERSION = 1; 548 | DEVELOPMENT_TEAM = DBR2MMCRF5; 549 | ENABLE_HARDENED_RUNTIME = YES; 550 | GENERATE_INFOPLIST_FILE = YES; 551 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 552 | INFOPLIST_KEY_NSMainStoryboardFile = Main; 553 | INFOPLIST_KEY_NSPrincipalClass = NSApplication; 554 | LD_RUNPATH_SEARCH_PATHS = ( 555 | "$(inherited)", 556 | "@executable_path/../Frameworks", 557 | ); 558 | MARKETING_VERSION = 1.0; 559 | PRODUCT_BUNDLE_IDENTIFIER = org.kostyshyn.LiveView; 560 | PRODUCT_NAME = "$(TARGET_NAME)"; 561 | SWIFT_EMIT_LOC_STRINGS = YES; 562 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 563 | SWIFT_VERSION = 5.0; 564 | }; 565 | name = Debug; 566 | }; 567 | 771E489827A08A83000F220D /* Release */ = { 568 | isa = XCBuildConfiguration; 569 | buildSettings = { 570 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 571 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 572 | CLANG_ENABLE_MODULES = YES; 573 | CODE_SIGN_ENTITLEMENTS = LiveView/LiveView.entitlements; 574 | CODE_SIGN_STYLE = Automatic; 575 | COMBINE_HIDPI_IMAGES = YES; 576 | CURRENT_PROJECT_VERSION = 1; 577 | DEVELOPMENT_TEAM = DBR2MMCRF5; 578 | ENABLE_HARDENED_RUNTIME = YES; 579 | GENERATE_INFOPLIST_FILE = YES; 580 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 581 | INFOPLIST_KEY_NSMainStoryboardFile = Main; 582 | INFOPLIST_KEY_NSPrincipalClass = NSApplication; 583 | LD_RUNPATH_SEARCH_PATHS = ( 584 | "$(inherited)", 585 | "@executable_path/../Frameworks", 586 | ); 587 | MARKETING_VERSION = 1.0; 588 | PRODUCT_BUNDLE_IDENTIFIER = org.kostyshyn.LiveView; 589 | PRODUCT_NAME = "$(TARGET_NAME)"; 590 | SWIFT_EMIT_LOC_STRINGS = YES; 591 | SWIFT_VERSION = 5.0; 592 | }; 593 | name = Release; 594 | }; 595 | 771E48C427A09061000F220D /* Debug */ = { 596 | isa = XCBuildConfiguration; 597 | buildSettings = { 598 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 599 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 600 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 601 | CLANG_ENABLE_MODULES = YES; 602 | CODE_SIGN_STYLE = Automatic; 603 | CURRENT_PROJECT_VERSION = 1; 604 | DEVELOPMENT_TEAM = DBR2MMCRF5; 605 | ENABLE_BITCODE = NO; 606 | GENERATE_INFOPLIST_FILE = YES; 607 | INFOPLIST_FILE = "LiveView-iOS/Info.plist"; 608 | INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Save photo"; 609 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 610 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 611 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 612 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 613 | LD_RUNPATH_SEARCH_PATHS = ( 614 | "$(inherited)", 615 | "@executable_path/Frameworks", 616 | ); 617 | MARKETING_VERSION = 1.0; 618 | PRODUCT_BUNDLE_IDENTIFIER = "org.kostyshyn.LiveView-iOS"; 619 | PRODUCT_NAME = "$(TARGET_NAME)"; 620 | SDKROOT = iphoneos; 621 | SWIFT_EMIT_LOC_STRINGS = YES; 622 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 623 | SWIFT_VERSION = 5.0; 624 | TARGETED_DEVICE_FAMILY = "1,2"; 625 | }; 626 | name = Debug; 627 | }; 628 | 771E48C527A09061000F220D /* Release */ = { 629 | isa = XCBuildConfiguration; 630 | buildSettings = { 631 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 632 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 633 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 634 | CLANG_ENABLE_MODULES = YES; 635 | CODE_SIGN_STYLE = Automatic; 636 | CURRENT_PROJECT_VERSION = 1; 637 | DEVELOPMENT_TEAM = DBR2MMCRF5; 638 | ENABLE_BITCODE = NO; 639 | GENERATE_INFOPLIST_FILE = YES; 640 | INFOPLIST_FILE = "LiveView-iOS/Info.plist"; 641 | INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Save photo"; 642 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 643 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 644 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 645 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 646 | LD_RUNPATH_SEARCH_PATHS = ( 647 | "$(inherited)", 648 | "@executable_path/Frameworks", 649 | ); 650 | MARKETING_VERSION = 1.0; 651 | PRODUCT_BUNDLE_IDENTIFIER = "org.kostyshyn.LiveView-iOS"; 652 | PRODUCT_NAME = "$(TARGET_NAME)"; 653 | SDKROOT = iphoneos; 654 | SWIFT_EMIT_LOC_STRINGS = YES; 655 | SWIFT_VERSION = 5.0; 656 | TARGETED_DEVICE_FAMILY = "1,2"; 657 | VALIDATE_PRODUCT = YES; 658 | }; 659 | name = Release; 660 | }; 661 | 771E48FA27A0CAE6000F220D /* Debug */ = { 662 | isa = XCBuildConfiguration; 663 | buildSettings = { 664 | CLANG_ENABLE_MODULES = YES; 665 | CODE_SIGN_STYLE = Automatic; 666 | CURRENT_PROJECT_VERSION = 1; 667 | DEFINES_MODULE = YES; 668 | DEVELOPMENT_TEAM = DBR2MMCRF5; 669 | DYLIB_COMPATIBILITY_VERSION = 1; 670 | DYLIB_CURRENT_VERSION = 1; 671 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 672 | ENABLE_BITCODE = NO; 673 | GENERATE_INFOPLIST_FILE = YES; 674 | HEADER_SEARCH_PATHS = "$(SRCROOT)/Thirdparties/libuvc/include"; 675 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 676 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 677 | LD_RUNPATH_SEARCH_PATHS = ( 678 | "$(inherited)", 679 | "@executable_path/Frameworks", 680 | "@loader_path/Frameworks", 681 | ); 682 | "LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" = "$(SRCROOT)/Thirdparties/libs/ios"; 683 | "LIBRARY_SEARCH_PATHS[sdk=macosx*]" = "$(SRCROOT)/Thirdparties/libs/macos"; 684 | MARKETING_VERSION = 1.0; 685 | OTHER_LDFLAGS = ( 686 | "-luvc", 687 | "-lusb-1.0", 688 | "-ljpeg", 689 | ); 690 | PRODUCT_BUNDLE_IDENTIFIER = org.kostyshyn.LiveViewKit; 691 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 692 | SDKROOT = iphoneos; 693 | SKIP_INSTALL = YES; 694 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx"; 695 | SWIFT_EMIT_LOC_STRINGS = YES; 696 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 697 | SWIFT_VERSION = 5.0; 698 | TARGETED_DEVICE_FAMILY = "1,2"; 699 | VERSIONING_SYSTEM = "apple-generic"; 700 | VERSION_INFO_PREFIX = ""; 701 | }; 702 | name = Debug; 703 | }; 704 | 771E48FB27A0CAE6000F220D /* Release */ = { 705 | isa = XCBuildConfiguration; 706 | buildSettings = { 707 | CLANG_ENABLE_MODULES = YES; 708 | CODE_SIGN_STYLE = Automatic; 709 | CURRENT_PROJECT_VERSION = 1; 710 | DEFINES_MODULE = YES; 711 | DEVELOPMENT_TEAM = DBR2MMCRF5; 712 | DYLIB_COMPATIBILITY_VERSION = 1; 713 | DYLIB_CURRENT_VERSION = 1; 714 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 715 | ENABLE_BITCODE = NO; 716 | GENERATE_INFOPLIST_FILE = YES; 717 | HEADER_SEARCH_PATHS = "$(SRCROOT)/Thirdparties/libuvc/include"; 718 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 719 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 720 | LD_RUNPATH_SEARCH_PATHS = ( 721 | "$(inherited)", 722 | "@executable_path/Frameworks", 723 | "@loader_path/Frameworks", 724 | ); 725 | "LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" = "$(SRCROOT)/Thirdparties/libs/ios"; 726 | "LIBRARY_SEARCH_PATHS[sdk=macosx*]" = "$(SRCROOT)/Thirdparties/libs/macos"; 727 | MARKETING_VERSION = 1.0; 728 | OTHER_LDFLAGS = ( 729 | "-luvc", 730 | "-lusb-1.0", 731 | "-ljpeg", 732 | ); 733 | PRODUCT_BUNDLE_IDENTIFIER = org.kostyshyn.LiveViewKit; 734 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 735 | SDKROOT = iphoneos; 736 | SKIP_INSTALL = YES; 737 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx"; 738 | SWIFT_EMIT_LOC_STRINGS = YES; 739 | SWIFT_VERSION = 5.0; 740 | TARGETED_DEVICE_FAMILY = "1,2"; 741 | VALIDATE_PRODUCT = YES; 742 | VERSIONING_SYSTEM = "apple-generic"; 743 | VERSION_INFO_PREFIX = ""; 744 | }; 745 | name = Release; 746 | }; 747 | /* End XCBuildConfiguration section */ 748 | 749 | /* Begin XCConfigurationList section */ 750 | 771E488227A08A81000F220D /* Build configuration list for PBXProject "LiveView" */ = { 751 | isa = XCConfigurationList; 752 | buildConfigurations = ( 753 | 771E489427A08A83000F220D /* Debug */, 754 | 771E489527A08A83000F220D /* Release */, 755 | ); 756 | defaultConfigurationIsVisible = 0; 757 | defaultConfigurationName = Release; 758 | }; 759 | 771E489627A08A83000F220D /* Build configuration list for PBXNativeTarget "LiveView" */ = { 760 | isa = XCConfigurationList; 761 | buildConfigurations = ( 762 | 771E489727A08A83000F220D /* Debug */, 763 | 771E489827A08A83000F220D /* Release */, 764 | ); 765 | defaultConfigurationIsVisible = 0; 766 | defaultConfigurationName = Release; 767 | }; 768 | 771E48C627A09061000F220D /* Build configuration list for PBXNativeTarget "LiveView-iOS" */ = { 769 | isa = XCConfigurationList; 770 | buildConfigurations = ( 771 | 771E48C427A09061000F220D /* Debug */, 772 | 771E48C527A09061000F220D /* Release */, 773 | ); 774 | defaultConfigurationIsVisible = 0; 775 | defaultConfigurationName = Release; 776 | }; 777 | 771E48F927A0CAE6000F220D /* Build configuration list for PBXNativeTarget "LiveViewKit" */ = { 778 | isa = XCConfigurationList; 779 | buildConfigurations = ( 780 | 771E48FA27A0CAE6000F220D /* Debug */, 781 | 771E48FB27A0CAE6000F220D /* Release */, 782 | ); 783 | defaultConfigurationIsVisible = 0; 784 | defaultConfigurationName = Release; 785 | }; 786 | /* End XCConfigurationList section */ 787 | }; 788 | rootObject = 771E487F27A08A81000F220D /* Project object */; 789 | } 790 | -------------------------------------------------------------------------------- /Thirdparties/libuvc/include/utlist.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2007-2010, Troy D. Hanson http://uthash.sourceforge.net 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 12 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 13 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 14 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 15 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 16 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 18 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 19 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 20 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 | */ 23 | 24 | #ifndef UTLIST_H 25 | #define UTLIST_H 26 | 27 | #define UTLIST_VERSION 1.9.1 28 | 29 | /* 30 | * This file contains macros to manipulate singly and doubly-linked lists. 31 | * 32 | * 1. LL_ macros: singly-linked lists. 33 | * 2. DL_ macros: doubly-linked lists. 34 | * 3. CDL_ macros: circular doubly-linked lists. 35 | * 36 | * To use singly-linked lists, your structure must have a "next" pointer. 37 | * To use doubly-linked lists, your structure must "prev" and "next" pointers. 38 | * Either way, the pointer to the head of the list must be initialized to NULL. 39 | * 40 | * ----------------.EXAMPLE ------------------------- 41 | * struct item { 42 | * int id; 43 | * struct item *prev, *next; 44 | * } 45 | * 46 | * struct item *list = NULL: 47 | * 48 | * int main() { 49 | * struct item *item; 50 | * ... allocate and populate item ... 51 | * DL_APPEND(list, item); 52 | * } 53 | * -------------------------------------------------- 54 | * 55 | * For doubly-linked lists, the append and delete macros are O(1) 56 | * For singly-linked lists, append and delete are O(n) but prepend is O(1) 57 | * The sort macro is O(n log(n)) for all types of single/double/circular lists. 58 | */ 59 | 60 | /* These macros use decltype or the earlier __typeof GNU extension. 61 | As decltype is only available in newer compilers (VS2010 or gcc 4.3+ 62 | when compiling c++ code), this code uses whatever method is needed 63 | or, for VS2008 where neither is available, uses casting workarounds. */ 64 | #ifdef _MSC_VER /* MS compiler */ 65 | #if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ 66 | #define LDECLTYPE(x) decltype(x) 67 | #else /* VS2008 or older (or VS2010 in C mode) */ 68 | #define NO_DECLTYPE 69 | #define LDECLTYPE(x) char* 70 | #endif 71 | #else /* GNU, Sun and other compilers */ 72 | #define LDECLTYPE(x) __typeof(x) 73 | #endif 74 | 75 | /* for VS2008 we use some workarounds to get around the lack of decltype, 76 | * namely, we always reassign our tmp variable to the list head if we need 77 | * to dereference its prev/next pointers, and save/restore the real head.*/ 78 | #ifdef NO_DECLTYPE 79 | #define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } 80 | #define _NEXT(elt,list) ((char*)((list)->next)) 81 | #define _NEXTASGN(elt,list,to) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } 82 | #define _PREV(elt,list) ((char*)((list)->prev)) 83 | #define _PREVASGN(elt,list,to) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } 84 | #define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } 85 | #define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } 86 | #else 87 | #define _SV(elt,list) 88 | #define _NEXT(elt,list) ((elt)->next) 89 | #define _NEXTASGN(elt,list,to) ((elt)->next)=(to) 90 | #define _PREV(elt,list) ((elt)->prev) 91 | #define _PREVASGN(elt,list,to) ((elt)->prev)=(to) 92 | #define _RS(list) 93 | #define _CASTASGN(a,b) (a)=(b) 94 | #endif 95 | 96 | /****************************************************************************** 97 | * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * 98 | * Unwieldy variable names used here to avoid shadowing passed-in variables. * 99 | *****************************************************************************/ 100 | #define LL_SORT(list, cmp) \ 101 | do { \ 102 | LDECLTYPE(list) _ls_p; \ 103 | LDECLTYPE(list) _ls_q; \ 104 | LDECLTYPE(list) _ls_e; \ 105 | LDECLTYPE(list) _ls_tail; \ 106 | LDECLTYPE(list) _ls_oldhead; \ 107 | LDECLTYPE(list) _tmp; \ 108 | int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ 109 | if (list) { \ 110 | _ls_insize = 1; \ 111 | _ls_looping = 1; \ 112 | while (_ls_looping) { \ 113 | _CASTASGN(_ls_p,list); \ 114 | _CASTASGN(_ls_oldhead,list); \ 115 | list = NULL; \ 116 | _ls_tail = NULL; \ 117 | _ls_nmerges = 0; \ 118 | while (_ls_p) { \ 119 | _ls_nmerges++; \ 120 | _ls_q = _ls_p; \ 121 | _ls_psize = 0; \ 122 | for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ 123 | _ls_psize++; \ 124 | _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); \ 125 | if (!_ls_q) break; \ 126 | } \ 127 | _ls_qsize = _ls_insize; \ 128 | while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ 129 | if (_ls_psize == 0) { \ 130 | _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \ 131 | } else if (_ls_qsize == 0 || !_ls_q) { \ 132 | _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \ 133 | } else if (cmp(_ls_p,_ls_q) <= 0) { \ 134 | _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \ 135 | } else { \ 136 | _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \ 137 | } \ 138 | if (_ls_tail) { \ 139 | _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \ 140 | } else { \ 141 | _CASTASGN(list,_ls_e); \ 142 | } \ 143 | _ls_tail = _ls_e; \ 144 | } \ 145 | _ls_p = _ls_q; \ 146 | } \ 147 | _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL); _RS(list); \ 148 | if (_ls_nmerges <= 1) { \ 149 | _ls_looping=0; \ 150 | } \ 151 | _ls_insize *= 2; \ 152 | } \ 153 | } else _tmp=NULL; /* quiet gcc unused variable warning */ \ 154 | } while (0) 155 | 156 | #define DL_SORT(list, cmp) \ 157 | do { \ 158 | LDECLTYPE(list) _ls_p; \ 159 | LDECLTYPE(list) _ls_q; \ 160 | LDECLTYPE(list) _ls_e; \ 161 | LDECLTYPE(list) _ls_tail; \ 162 | LDECLTYPE(list) _ls_oldhead; \ 163 | LDECLTYPE(list) _tmp; \ 164 | int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ 165 | if (list) { \ 166 | _ls_insize = 1; \ 167 | _ls_looping = 1; \ 168 | while (_ls_looping) { \ 169 | _CASTASGN(_ls_p,list); \ 170 | _CASTASGN(_ls_oldhead,list); \ 171 | list = NULL; \ 172 | _ls_tail = NULL; \ 173 | _ls_nmerges = 0; \ 174 | while (_ls_p) { \ 175 | _ls_nmerges++; \ 176 | _ls_q = _ls_p; \ 177 | _ls_psize = 0; \ 178 | for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ 179 | _ls_psize++; \ 180 | _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); \ 181 | if (!_ls_q) break; \ 182 | } \ 183 | _ls_qsize = _ls_insize; \ 184 | while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ 185 | if (_ls_psize == 0) { \ 186 | _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \ 187 | } else if (_ls_qsize == 0 || !_ls_q) { \ 188 | _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \ 189 | } else if (cmp(_ls_p,_ls_q) <= 0) { \ 190 | _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \ 191 | } else { \ 192 | _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \ 193 | } \ 194 | if (_ls_tail) { \ 195 | _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \ 196 | } else { \ 197 | _CASTASGN(list,_ls_e); \ 198 | } \ 199 | _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail); _RS(list); \ 200 | _ls_tail = _ls_e; \ 201 | } \ 202 | _ls_p = _ls_q; \ 203 | } \ 204 | _CASTASGN(list->prev, _ls_tail); \ 205 | _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL); _RS(list); \ 206 | if (_ls_nmerges <= 1) { \ 207 | _ls_looping=0; \ 208 | } \ 209 | _ls_insize *= 2; \ 210 | } \ 211 | } else _tmp=NULL; /* quiet gcc unused variable warning */ \ 212 | } while (0) 213 | 214 | #define CDL_SORT(list, cmp) \ 215 | do { \ 216 | LDECLTYPE(list) _ls_p; \ 217 | LDECLTYPE(list) _ls_q; \ 218 | LDECLTYPE(list) _ls_e; \ 219 | LDECLTYPE(list) _ls_tail; \ 220 | LDECLTYPE(list) _ls_oldhead; \ 221 | LDECLTYPE(list) _tmp; \ 222 | LDECLTYPE(list) _tmp2; \ 223 | int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ 224 | if (list) { \ 225 | _ls_insize = 1; \ 226 | _ls_looping = 1; \ 227 | while (_ls_looping) { \ 228 | _CASTASGN(_ls_p,list); \ 229 | _CASTASGN(_ls_oldhead,list); \ 230 | list = NULL; \ 231 | _ls_tail = NULL; \ 232 | _ls_nmerges = 0; \ 233 | while (_ls_p) { \ 234 | _ls_nmerges++; \ 235 | _ls_q = _ls_p; \ 236 | _ls_psize = 0; \ 237 | for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ 238 | _ls_psize++; \ 239 | _SV(_ls_q,list); \ 240 | if (_NEXT(_ls_q,list) == _ls_oldhead) { \ 241 | _ls_q = NULL; \ 242 | } else { \ 243 | _ls_q = _NEXT(_ls_q,list); \ 244 | } \ 245 | _RS(list); \ 246 | if (!_ls_q) break; \ 247 | } \ 248 | _ls_qsize = _ls_insize; \ 249 | while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ 250 | if (_ls_psize == 0) { \ 251 | _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \ 252 | if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ 253 | } else if (_ls_qsize == 0 || !_ls_q) { \ 254 | _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \ 255 | if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ 256 | } else if (cmp(_ls_p,_ls_q) <= 0) { \ 257 | _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \ 258 | if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ 259 | } else { \ 260 | _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \ 261 | if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ 262 | } \ 263 | if (_ls_tail) { \ 264 | _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \ 265 | } else { \ 266 | _CASTASGN(list,_ls_e); \ 267 | } \ 268 | _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail); _RS(list); \ 269 | _ls_tail = _ls_e; \ 270 | } \ 271 | _ls_p = _ls_q; \ 272 | } \ 273 | _CASTASGN(list->prev,_ls_tail); \ 274 | _CASTASGN(_tmp2,list); \ 275 | _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp2); _RS(list); \ 276 | if (_ls_nmerges <= 1) { \ 277 | _ls_looping=0; \ 278 | } \ 279 | _ls_insize *= 2; \ 280 | } \ 281 | } else _tmp=NULL; /* quiet gcc unused variable warning */ \ 282 | } while (0) 283 | 284 | /****************************************************************************** 285 | * singly linked list macros (non-circular) * 286 | *****************************************************************************/ 287 | #define LL_PREPEND(head,add) \ 288 | do { \ 289 | (add)->next = head; \ 290 | head = add; \ 291 | } while (0) 292 | 293 | #define LL_APPEND(head,add) \ 294 | do { \ 295 | LDECLTYPE(head) _tmp; \ 296 | (add)->next=NULL; \ 297 | if (head) { \ 298 | _tmp = head; \ 299 | while (_tmp->next) { _tmp = _tmp->next; } \ 300 | _tmp->next=(add); \ 301 | } else { \ 302 | (head)=(add); \ 303 | } \ 304 | } while (0) 305 | 306 | #define LL_DELETE(head,del) \ 307 | do { \ 308 | LDECLTYPE(head) _tmp; \ 309 | if ((head) == (del)) { \ 310 | (head)=(head)->next; \ 311 | } else { \ 312 | _tmp = head; \ 313 | while (_tmp->next && (_tmp->next != (del))) { \ 314 | _tmp = _tmp->next; \ 315 | } \ 316 | if (_tmp->next) { \ 317 | _tmp->next = ((del)->next); \ 318 | } \ 319 | } \ 320 | } while (0) 321 | 322 | /* Here are VS2008 replacements for LL_APPEND and LL_DELETE */ 323 | #define LL_APPEND_VS2008(head,add) \ 324 | do { \ 325 | if (head) { \ 326 | (add)->next = head; /* use add->next as a temp variable */ \ 327 | while ((add)->next->next) { (add)->next = (add)->next->next; } \ 328 | (add)->next->next=(add); \ 329 | } else { \ 330 | (head)=(add); \ 331 | } \ 332 | (add)->next=NULL; \ 333 | } while (0) 334 | 335 | #define LL_DELETE_VS2008(head,del) \ 336 | do { \ 337 | if ((head) == (del)) { \ 338 | (head)=(head)->next; \ 339 | } else { \ 340 | char *_tmp = (char*)(head); \ 341 | while (head->next && (head->next != (del))) { \ 342 | head = head->next; \ 343 | } \ 344 | if (head->next) { \ 345 | head->next = ((del)->next); \ 346 | } \ 347 | { \ 348 | char **_head_alias = (char**)&(head); \ 349 | *_head_alias = _tmp; \ 350 | } \ 351 | } \ 352 | } while (0) 353 | #ifdef NO_DECLTYPE 354 | #undef LL_APPEND 355 | #define LL_APPEND LL_APPEND_VS2008 356 | #undef LL_DELETE 357 | #define LL_DELETE LL_DELETE_VS2008 358 | #endif 359 | /* end VS2008 replacements */ 360 | 361 | #define LL_FOREACH(head,el) \ 362 | for(el=head;el;el=el->next) 363 | 364 | #define LL_FOREACH_SAFE(head,el,tmp) \ 365 | for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) 366 | 367 | #define LL_SEARCH_SCALAR(head,out,field,val) \ 368 | do { \ 369 | LL_FOREACH(head,out) { \ 370 | if ((out)->field == (val)) break; \ 371 | } \ 372 | } while(0) 373 | 374 | #define LL_SEARCH(head,out,elt,cmp) \ 375 | do { \ 376 | LL_FOREACH(head,out) { \ 377 | if ((cmp(out,elt))==0) break; \ 378 | } \ 379 | } while(0) 380 | 381 | /****************************************************************************** 382 | * doubly linked list macros (non-circular) * 383 | *****************************************************************************/ 384 | #define DL_PREPEND(head,add) \ 385 | do { \ 386 | (add)->next = head; \ 387 | if (head) { \ 388 | (add)->prev = (head)->prev; \ 389 | (head)->prev = (add); \ 390 | } else { \ 391 | (add)->prev = (add); \ 392 | } \ 393 | (head) = (add); \ 394 | } while (0) 395 | 396 | #define DL_APPEND(head,add) \ 397 | do { \ 398 | if (head) { \ 399 | (add)->prev = (head)->prev; \ 400 | (head)->prev->next = (add); \ 401 | (head)->prev = (add); \ 402 | (add)->next = NULL; \ 403 | } else { \ 404 | (head)=(add); \ 405 | (head)->prev = (head); \ 406 | (head)->next = NULL; \ 407 | } \ 408 | } while (0); 409 | 410 | #define DL_DELETE(head,del) \ 411 | do { \ 412 | if ((del)->prev == (del)) { \ 413 | (head)=NULL; \ 414 | } else if ((del)==(head)) { \ 415 | (del)->next->prev = (del)->prev; \ 416 | (head) = (del)->next; \ 417 | } else { \ 418 | (del)->prev->next = (del)->next; \ 419 | if ((del)->next) { \ 420 | (del)->next->prev = (del)->prev; \ 421 | } else { \ 422 | (head)->prev = (del)->prev; \ 423 | } \ 424 | } \ 425 | } while (0); 426 | 427 | 428 | #define DL_FOREACH(head,el) \ 429 | for(el=head;el;el=el->next) 430 | 431 | /* this version is safe for deleting the elements during iteration */ 432 | #define DL_FOREACH_SAFE(head,el,tmp) \ 433 | for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) 434 | 435 | /* these are identical to their singly-linked list counterparts */ 436 | #define DL_SEARCH_SCALAR LL_SEARCH_SCALAR 437 | #define DL_SEARCH LL_SEARCH 438 | 439 | /****************************************************************************** 440 | * circular doubly linked list macros * 441 | *****************************************************************************/ 442 | #define CDL_PREPEND(head,add) \ 443 | do { \ 444 | if (head) { \ 445 | (add)->prev = (head)->prev; \ 446 | (add)->next = (head); \ 447 | (head)->prev = (add); \ 448 | (add)->prev->next = (add); \ 449 | } else { \ 450 | (add)->prev = (add); \ 451 | (add)->next = (add); \ 452 | } \ 453 | (head)=(add); \ 454 | } while (0) 455 | 456 | #define CDL_DELETE(head,del) \ 457 | do { \ 458 | if ( ((head)==(del)) && ((head)->next == (head))) { \ 459 | (head) = 0L; \ 460 | } else { \ 461 | (del)->next->prev = (del)->prev; \ 462 | (del)->prev->next = (del)->next; \ 463 | if ((del) == (head)) (head)=(del)->next; \ 464 | } \ 465 | } while (0); 466 | 467 | #define CDL_FOREACH(head,el) \ 468 | for(el=head;el;el=(el->next==head ? 0L : el->next)) 469 | 470 | #define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ 471 | for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \ 472 | (el) && ((tmp2)=(el)->next, 1); \ 473 | ((el) = (((el)==(tmp1)) ? 0L : (tmp2)))) 474 | 475 | #define CDL_SEARCH_SCALAR(head,out,field,val) \ 476 | do { \ 477 | CDL_FOREACH(head,out) { \ 478 | if ((out)->field == (val)) break; \ 479 | } \ 480 | } while(0) 481 | 482 | #define CDL_SEARCH(head,out,elt,cmp) \ 483 | do { \ 484 | CDL_FOREACH(head,out) { \ 485 | if ((cmp(out,elt))==0) break; \ 486 | } \ 487 | } while(0) 488 | 489 | #endif /* UTLIST_H */ 490 | 491 | -------------------------------------------------------------------------------- /LiveView/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | Default 529 | 530 | 531 | 532 | 533 | 534 | 535 | Left to Right 536 | 537 | 538 | 539 | 540 | 541 | 542 | Right to Left 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | Default 554 | 555 | 556 | 557 | 558 | 559 | 560 | Left to Right 561 | 562 | 563 | 564 | 565 | 566 | 567 | Right to Left 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | --------------------------------------------------------------------------------