├── 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 | 
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 |
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 |
--------------------------------------------------------------------------------