diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/AppDelegate.h b/mediapipe/examples/ios/posetrackingsolutiongpu/AppDelegate.h new file mode 100644 index 000000000..6b0377ef2 --- /dev/null +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/AppDelegate.h @@ -0,0 +1,21 @@ +// Copyright 2019 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +@interface AppDelegate : UIResponder + +@property(strong, nonatomic) UIWindow *window; + +@end diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/AppDelegate.mm b/mediapipe/examples/ios/posetrackingsolutiongpu/AppDelegate.mm new file mode 100644 index 000000000..3e08df40f --- /dev/null +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/AppDelegate.mm @@ -0,0 +1,61 @@ +// Copyright 2019 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "AppDelegate.h" + +#import "CommonViewController.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for + // certain types of temporary interruptions (such as an incoming phone call or SMS message) or + // when the user quits the application and it begins the transition to the background state. Use + // this method to pause ongoing tasks, disable timers, and invalidate graphics rendering + // callbacks. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store + // enough application state information to restore your application to its current state in case + // it is terminated later. If your application supports background execution, this method is + // called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the active state; here you can undo + // many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If + // the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also + // applicationDidEnterBackground:. +} + +@end diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/40_c_1x.png b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/40_c_1x.png new file mode 100644 index 000000000..ed44f758e Binary files /dev/null and b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/40_c_1x.png differ diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/40_c_2x.png b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/40_c_2x.png new file mode 100644 index 000000000..5855920a6 Binary files /dev/null and b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/40_c_2x.png differ diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/40_c_3x.png b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/40_c_3x.png new file mode 100644 index 000000000..c96e2f0aa Binary files /dev/null and b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/40_c_3x.png differ diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/60_c_iphone_2x.png b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/60_c_iphone_2x.png new file mode 100644 index 000000000..3037b13eb Binary files /dev/null and b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/60_c_iphone_2x.png differ diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/60_c_iphone_3x.png b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/60_c_iphone_3x.png new file mode 100644 index 000000000..1e905ec27 Binary files /dev/null and b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/60_c_iphone_3x.png differ diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/76_c_Ipad.png b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/76_c_Ipad.png new file mode 100644 index 000000000..8e4073050 Binary files /dev/null and b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/76_c_Ipad.png differ diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/76_c_Ipad_2x.png b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/76_c_Ipad_2x.png new file mode 100644 index 000000000..d28effc39 Binary files /dev/null and b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/76_c_Ipad_2x.png differ diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/Contents.json b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..3ed9f5238 --- /dev/null +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,106 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "filename" : "40_c_2x.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "filename" : "40_c_3x.png", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "filename" : "60_c_iphone_2x.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "filename" : "60_c_iphone_3x.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "filename" : "40_c_1x.png", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "filename" : "76_c_Ipad.png", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "filename" : "76_c_Ipad_2x.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} + diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/Contents.json b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/Contents.json new file mode 100644 index 000000000..7afcdfaf8 --- /dev/null +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/Assets.xcassets/Contents.json @@ -0,0 +1,7 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} + diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/BUILD b/mediapipe/examples/ios/posetrackingsolutiongpu/BUILD index bb33bf9a5..dbd69fad7 100644 --- a/mediapipe/examples/ios/posetrackingsolutiongpu/BUILD +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/BUILD @@ -66,7 +66,7 @@ objc_library( "//mediapipe/modules/pose_landmark:pose_landmark_full.tflite", ], deps = [ - "//mediapipe/examples/ios/common:CommonMediaPipeAppLibrary", + ":CommonMediaPipeAppLibrary", "//mediapipe/objc/solutions/posetracking_gpu:posetracking_gpu_solution", ] + select({ "//mediapipe:ios_i386": [], @@ -77,3 +77,42 @@ objc_library( ], }), ) + +objc_library( + name = "CommonMediaPipeAppLibrary", + srcs = [ + "AppDelegate.mm", + "CommonViewController.mm", + "main.m", + ], + hdrs = [ + "AppDelegate.h", + "CommonViewController.h", + ], + data = [ + "Base.lproj/LaunchScreen.storyboard", + "Base.lproj/Main.storyboard", + ], + sdk_frameworks = [ + "AVFoundation", + "CoreGraphics", + "CoreMedia", + "UIKit", + ], + visibility = [ + "//mediapipe:__subpackages__", + ], + deps = [ + "//mediapipe/objc:mediapipe_framework_ios", + "//mediapipe/objc:mediapipe_input_sources_ios", + "//mediapipe/objc:mediapipe_layer_renderer", + ], +) + +exports_files(["Info.plist"]) + +filegroup( + name = "AppIcon", + srcs = glob(["Assets.xcassets/AppIcon.appiconset/*"]), + visibility = ["//mediapipe:__subpackages__"], +) diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/Base.lproj/LaunchScreen.storyboard b/mediapipe/examples/ios/posetrackingsolutiongpu/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..bfa361294 --- /dev/null +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/Base.lproj/Main.storyboard b/mediapipe/examples/ios/posetrackingsolutiongpu/Base.lproj/Main.storyboard new file mode 100644 index 000000000..fcf71c0e2 --- /dev/null +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/Base.lproj/Main.storyboard @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/CommonViewController.h b/mediapipe/examples/ios/posetrackingsolutiongpu/CommonViewController.h new file mode 100644 index 000000000..d7cb1121a --- /dev/null +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/CommonViewController.h @@ -0,0 +1,67 @@ +// Copyright 2019 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +#import "mediapipe/objc/MPPCameraInputSource.h" +#import "mediapipe/objc/MPPGraph.h" +#import "mediapipe/objc/MPPLayerRenderer.h" +#import "mediapipe/objc/MPPPlayerInputSource.h" +#import "mediapipe/objc/MPPTimestampConverter.h" + +typedef NS_ENUM(NSInteger, MediaPipeDemoSourceMode) { + MediaPipeDemoSourceCamera, + MediaPipeDemoSourceVideo +}; + +@interface CommonViewController : UIViewController + +// The MediaPipe graph currently in use. Initialized in viewDidLoad, started in +// viewWillAppear: and sent video frames on videoQueue. +@property(nonatomic) MPPGraph* mediapipeGraph; + +// Handles camera access via AVCaptureSession library. +@property(nonatomic) MPPCameraInputSource* cameraSource; + +// Provides data from a video. +@property(nonatomic) MPPPlayerInputSource* videoSource; + +// Helps to convert timestamp. +@property(nonatomic) MPPTimestampConverter* timestampConverter; + +// The data source for the demo. +@property(nonatomic) MediaPipeDemoSourceMode sourceMode; + +// Inform the user when camera is unavailable. +@property(nonatomic) IBOutlet UILabel* noCameraLabel; + +// Display the camera preview frames. +@property(strong, nonatomic) IBOutlet UIView* liveView; + +// Render frames in a layer. +@property(nonatomic) MPPLayerRenderer* renderer; + +// Process camera frames on this queue. +@property(nonatomic) dispatch_queue_t videoQueue; + +// Graph name. +@property(nonatomic) NSString* graphName; + +// Graph input stream. +@property(nonatomic) const char* graphInputStream; + +// Graph output stream. +@property(nonatomic) const char* graphOutputStream; + +@end diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/CommonViewController.mm b/mediapipe/examples/ios/posetrackingsolutiongpu/CommonViewController.mm new file mode 100644 index 000000000..f6c47eacf --- /dev/null +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/CommonViewController.mm @@ -0,0 +1,201 @@ +// Copyright 2019 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "CommonViewController.h" + +static const char* kVideoQueueLabel = "com.google.mediapipe.example.videoQueue"; + +@implementation CommonViewController + +// This provides a hook to replace the basic ViewController with a subclass when it's created from a +// storyboard, without having to change the storyboard itself. ++ (instancetype)allocWithZone:(struct _NSZone*)zone { + NSString* subclassName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MainViewController"]; + if (subclassName.length > 0) { + Class customClass = NSClassFromString(subclassName); + Class baseClass = [CommonViewController class]; + NSAssert([customClass isSubclassOfClass:baseClass], @"%@ must be a subclass of %@", customClass, + baseClass); + if (self == baseClass) return [customClass allocWithZone:zone]; + } + return [super allocWithZone:zone]; +} + +#pragma mark - Cleanup methods + +- (void)dealloc { + self.mediapipeGraph.delegate = nil; + [self.mediapipeGraph cancel]; + // Ignore errors since we're cleaning up. + [self.mediapipeGraph closeAllInputStreamsWithError:nil]; + [self.mediapipeGraph waitUntilDoneWithError:nil]; +} + +#pragma mark - MediaPipe graph methods + ++ (MPPGraph*)loadGraphFromResource:(NSString*)resource { + // Load the graph config resource. + NSError* configLoadError = nil; + NSBundle* bundle = [NSBundle bundleForClass:[self class]]; + if (!resource || resource.length == 0) { + return nil; + } + NSURL* graphURL = [bundle URLForResource:resource withExtension:@"binarypb"]; + NSData* data = [NSData dataWithContentsOfURL:graphURL options:0 error:&configLoadError]; + if (!data) { + NSLog(@"Failed to load MediaPipe graph config: %@", configLoadError); + return nil; + } + + // Parse the graph config resource into mediapipe::CalculatorGraphConfig proto object. + mediapipe::CalculatorGraphConfig config; + config.ParseFromArray(data.bytes, data.length); + + // Create MediaPipe graph with mediapipe::CalculatorGraphConfig proto object. + MPPGraph* newGraph = [[MPPGraph alloc] initWithGraphConfig:config]; + return newGraph; +} + +#pragma mark - UIViewController methods + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.renderer = [[MPPLayerRenderer alloc] init]; + self.renderer.layer.frame = self.liveView.layer.bounds; + [self.liveView.layer addSublayer:self.renderer.layer]; + self.renderer.frameScaleMode = MPPFrameScaleModeFillAndCrop; + + self.timestampConverter = [[MPPTimestampConverter alloc] init]; + + dispatch_queue_attr_t qosAttribute = dispatch_queue_attr_make_with_qos_class( + DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INTERACTIVE, /*relative_priority=*/0); + self.videoQueue = dispatch_queue_create(kVideoQueueLabel, qosAttribute); + + self.graphName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"GraphName"]; + self.graphInputStream = + [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"GraphInputStream"] UTF8String]; + self.graphOutputStream = + [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"GraphOutputStream"] UTF8String]; + + self.mediapipeGraph = [[self class] loadGraphFromResource:self.graphName]; + [self.mediapipeGraph addFrameOutputStream:self.graphOutputStream + outputPacketType:MPPPacketTypePixelBuffer]; + + self.mediapipeGraph.delegate = self; +} + +// In this application, there is only one ViewController which has no navigation to other view +// controllers, and there is only one View with live display showing the result of running the +// MediaPipe graph on the live video feed. If more view controllers are needed later, the graph +// setup/teardown and camera start/stop logic should be updated appropriately in response to the +// appearance/disappearance of this ViewController, as viewWillAppear: can be invoked multiple times +// depending on the application navigation flow in that case. +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + switch (self.sourceMode) { + case MediaPipeDemoSourceVideo: { + NSString* videoName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"VideoName"]; + AVAsset* video = [AVAsset assetWithURL:[[NSBundle mainBundle] URLForResource:videoName + withExtension:@"mov"]]; + self.videoSource = [[MPPPlayerInputSource alloc] initWithAVAsset:video]; + [self.videoSource setDelegate:self queue:self.videoQueue]; + dispatch_async(self.videoQueue, ^{ + [self.videoSource start]; + }); + break; + } + case MediaPipeDemoSourceCamera: { + self.cameraSource = [[MPPCameraInputSource alloc] init]; + [self.cameraSource setDelegate:self queue:self.videoQueue]; + self.cameraSource.sessionPreset = AVCaptureSessionPresetHigh; + + NSString* cameraPosition = + [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CameraPosition"]; + if (cameraPosition.length > 0 && [cameraPosition isEqualToString:@"back"]) { + self.cameraSource.cameraPosition = AVCaptureDevicePositionBack; + } else { + self.cameraSource.cameraPosition = AVCaptureDevicePositionFront; + // When using the front camera, mirror the input for a more natural look. + _cameraSource.videoMirrored = YES; + } + + // The frame's native format is rotated with respect to the portrait orientation. + _cameraSource.orientation = AVCaptureVideoOrientationPortrait; + + [self.cameraSource requestCameraAccessWithCompletionHandler:^void(BOOL granted) { + if (granted) { + dispatch_async(dispatch_get_main_queue(), ^{ + self.noCameraLabel.hidden = YES; + }); + [self startGraphAndCamera]; + } + }]; + + break; + } + } +} + +- (void)startGraphAndCamera { + // Start running self.mediapipeGraph. + NSError* error; + if (![self.mediapipeGraph startWithError:&error]) { + NSLog(@"Failed to start graph: %@", error); + } + else if (![self.mediapipeGraph waitUntilIdleWithError:&error]) { + NSLog(@"Failed to complete graph initial run: %@", error); + } + + // Start fetching frames from the camera. + dispatch_async(self.videoQueue, ^{ + [self.cameraSource start]; + }); +} + +#pragma mark - MPPInputSourceDelegate methods + +// Must be invoked on self.videoQueue. +- (void)processVideoFrame:(CVPixelBufferRef)imageBuffer + timestamp:(CMTime)timestamp + fromSource:(MPPInputSource*)source { + if (source != self.cameraSource && source != self.videoSource) { + NSLog(@"Unknown source: %@", source); + return; + } + + [self.mediapipeGraph sendPixelBuffer:imageBuffer + intoStream:self.graphInputStream + packetType:MPPPacketTypePixelBuffer + timestamp:[self.timestampConverter timestampForMediaTime:timestamp]]; +} + +#pragma mark - MPPGraphDelegate methods + +// Receives CVPixelBufferRef from the MediaPipe graph. Invoked on a MediaPipe worker thread. +- (void)mediapipeGraph:(MPPGraph*)graph + didOutputPixelBuffer:(CVPixelBufferRef)pixelBuffer + fromStream:(const std::string&)streamName { + if (streamName == self.graphOutputStream) { + // Display the captured image on the screen. + CVPixelBufferRetain(pixelBuffer); + dispatch_async(dispatch_get_main_queue(), ^{ + [self.renderer renderPixelBuffer:pixelBuffer]; + CVPixelBufferRelease(pixelBuffer); + }); + } +} + +@end diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/Info.plist b/mediapipe/examples/ios/posetrackingsolutiongpu/Info.plist index 71e2e429e..35d4990ac 100644 --- a/mediapipe/examples/ios/posetrackingsolutiongpu/Info.plist +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/Info.plist @@ -2,6 +2,44 @@ + + NSCameraUsageDescription + This app uses the camera to demonstrate live video processing. + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + + CameraPosition back MainViewController diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/PoseTrackingViewController.h b/mediapipe/examples/ios/posetrackingsolutiongpu/PoseTrackingViewController.h index f5dc4674a..3bcfa7391 100644 --- a/mediapipe/examples/ios/posetrackingsolutiongpu/PoseTrackingViewController.h +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/PoseTrackingViewController.h @@ -14,7 +14,7 @@ #import -#import "mediapipe/examples/ios/common/CommonViewController.h" +#import "CommonViewController.h" @interface PoseTrackingViewController : CommonViewController diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/PoseTrackingViewController.mm b/mediapipe/examples/ios/posetrackingsolutiongpu/PoseTrackingViewController.mm index 0f082031c..c80f19283 100644 --- a/mediapipe/examples/ios/posetrackingsolutiongpu/PoseTrackingViewController.mm +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/PoseTrackingViewController.mm @@ -15,6 +15,7 @@ #import "PoseTrackingViewController.h" #include "mediapipe/framework/formats/landmark.pb.h" +#include "mediapipe/objc/solutions/posetracking_gpu/PoseTrackingOptions.h" static const char* kLandmarksOutputStream = "pose_landmarks"; @@ -23,10 +24,19 @@ static const char* kLandmarksOutputStream = "pose_landmarks"; #pragma mark - UIViewController methods - (void)viewDidLoad { + + [super viewDidLoad]; - + PoseTrackingOptions* options = [ [PoseTrackingOptions alloc] initWithShowLandmarks:true cameraRotation:0]; [self.mediapipeGraph addFrameOutputStream:kLandmarksOutputStream outputPacketType:MPPPacketTypeRaw]; + [self.mediapipeGraph addFrameOutputStream:"throttled_input_video" + outputPacketType:MPPPacketTypePixelBuffer]; + if (options.showLandmarks){ + self.graphOutputStream = "output_video"; + }else{ + self.graphOutputStream = "throttled_input_video"; + } } #pragma mark - MPPGraphDelegate methods diff --git a/mediapipe/examples/ios/posetrackingsolutiongpu/main.m b/mediapipe/examples/ios/posetrackingsolutiongpu/main.m new file mode 100644 index 000000000..7ffe5ea5d --- /dev/null +++ b/mediapipe/examples/ios/posetrackingsolutiongpu/main.m @@ -0,0 +1,22 @@ +// Copyright 2019 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +}